From 77ecb4d0c65d8ce984818e50f533439cc4ce570d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aur=C3=A9lien=20COUDERC?= Date: Tue, 9 Mar 2021 22:53:11 +0100 Subject: [PATCH] Import okular_20.12.3.orig.tar.xz [dgit import orig okular_20.12.3.orig.tar.xz] --- .clang-tidy | 9 + .git-blame-ignore-revs | 2 + .gitignore | 5 + .gitlab-ci.yml | 55 + .krazy | 1 + AUTHORS | 4 + CMakeLists.txt | 516 + COPYING | 339 + COPYING.DOC | 397 + COPYING.LIB | 481 + Mainpage.dox | 907 ++ Messages.sh | 5 + Okular5Config.cmake.in | 14 + OkularConfigureChecks.cmake | 22 + README.clang-format | 14 + README.internals.png | Bin 0 -> 33807 bytes TODO | 274 + _clang-format | 88 + aboutdata.h | 46 + autotests/CMakeLists.txt | 135 + autotests/addremoveannotationtest.cpp | 190 + autotests/annotationstest.cpp | 160 + autotests/annotationtoolbartest.cpp | 405 + autotests/calculatetexttest.cpp | 113 + autotests/closedialoghelper.cpp | 50 + autotests/closedialoghelper.h | 39 + autotests/data/1500x300.png | Bin 0 -> 303461 bytes autotests/data/300x1500.png | Bin 0 -> 71065 bytes autotests/data/RequestFullScreen.pdf | Bin 0 -> 4903 bytes autotests/data/additionalFormActions.pdf | Bin 0 -> 45857 bytes autotests/data/checkbox_ro.pdf | Bin 0 -> 41601 bytes autotests/data/contents.epub | Bin 0 -> 3158 bytes autotests/data/file1-docdata.xml | 427 + autotests/data/file1.pdf | Bin 0 -> 15605 bytes autotests/data/file1.pdf.gz | Bin 0 -> 15351 bytes autotests/data/file2.pdf | Bin 0 -> 188546 bytes autotests/data/formSamples.pdf | Bin 0 -> 27196 bytes autotests/data/formattest.pdf | Bin 0 -> 37060 bytes autotests/data/imageSizes.md | 77 + autotests/data/kjsfunctionstest.pdf | Bin 0 -> 83477 bytes autotests/data/pdf_with_links.pdf | Bin 0 -> 13957 bytes autotests/data/pdf_with_signature.pdf | Bin 0 -> 74044 bytes autotests/data/potato.jpg | Bin 0 -> 34999 bytes autotests/data/protected.pdf | Bin 0 -> 16476 bytes autotests/data/simple-multipage.pdf | Bin 0 -> 18473 bytes autotests/data/simple-multipage.tex | 82 + autotests/data/simpleCalculate.pdf | Bin 0 -> 39797 bytes autotests/data/synctextest.tex | 104 + autotests/data/tocreload.pdf | Bin 0 -> 17245 bytes autotests/data/visibilitytest.pdf | 718 ++ autotests/documenttest.cpp | 131 + autotests/editannotationcontentstest.cpp | 528 + autotests/editdrawingtooldialogtest.cpp | 48 + autotests/editdrawingtooldialogtest.h | 26 + autotests/editformstest.cpp | 423 + autotests/formattest.cpp | 187 + autotests/generatorstest.cpp | 75 + autotests/kjsfunctionstest.cpp | 359 + autotests/mainshelltest.cpp | 702 ++ autotests/markdowntest.cpp | 128 + autotests/modifyannotationpropertiestest.cpp | 168 + autotests/parttest.cpp | 2075 ++++ autotests/searchtest.cpp | 432 + autotests/shelltest.cpp | 87 + autotests/signatureformtest.cpp | 61 + autotests/testingutils.cpp | 54 + autotests/testingutils.h | 53 + autotests/translateannotationtest.cpp | 216 + autotests/urldetecttest.cpp | 58 + autotests/visibilitytest.cpp | 167 + cmake/modules/COPYING-CMAKE-SCRIPTS | 22 + cmake/modules/FindCHM.cmake | 33 + cmake/modules/FindDiscount.cmake | 41 + cmake/modules/FindDjVuLibre.cmake | 39 + cmake/modules/FindEPub.cmake | 35 + cmake/modules/FindLibSpectre.cmake | 50 + cmake/modules/FindLibZip.cmake | 34 + conf/okular.kcfg | 401 + conf/okular_core.kcfg | 110 + conf/settings.kcfgc | 10 + conf/settings_core.kcfgc | 8 + conf/settings_mobile.kcfgc | 10 + config-okular.h.cmake | 8 + core/action.cpp | 601 ++ core/action.h | 592 ++ core/annotations.cpp | 3079 ++++++ core/annotations.h | 1753 ++++ core/annotations_p.h | 83 + core/area.cpp | 501 + core/area.h | 966 ++ core/audioplayer.cpp | 247 + core/audioplayer.h | 86 + core/audioplayer_p.h | 46 + core/bookmarkmanager.cpp | 728 ++ core/bookmarkmanager.h | 211 + core/chooseenginedialog.cpp | 58 + core/chooseenginedialog_p.h | 34 + core/chooseenginewidget.ui | 42 + core/debug.cpp | 12 + core/debug_p.h | 18 + core/document.cpp | 5475 +++++++++++ core/document.h | 1470 +++ core/document_p.h | 364 + core/documentcommands.cpp | 650 ++ core/documentcommands_p.h | 263 + core/fileprinter.cpp | 715 ++ core/fileprinter.h | 219 + core/fontinfo.cpp | 142 + core/fontinfo.h | 166 + core/form.cpp | 344 + core/form.h | 475 + core/form_p.h | 48 + core/generator.cpp | 795 ++ core/generator.h | 811 ++ core/generator_p.cpp | 169 + core/generator_p.h | 192 + core/global.h | 83 + core/misc.cpp | 89 + core/misc.h | 85 + core/movie.cpp | 167 + core/movie.h | 160 + core/observer.cpp | 54 + core/observer.h | 128 + core/okularGenerator.desktop | 72 + core/page.cpp | 1067 ++ core/page.h | 422 + core/page_p.h | 179 + core/pagecontroller.cpp | 44 + core/pagecontroller_p.h | 46 + core/pagesize.cpp | 112 + core/pagesize.h | 83 + core/pagetransition.cpp | 133 + core/pagetransition.h | 139 + core/printoptionswidget.cpp | 36 + core/printoptionswidget.h | 56 + core/rotationjob.cpp | 129 + core/rotationjob_p.h | 85 + core/script/builtin.js | 334 + core/script/builtin.qrc | 5 + core/script/event.cpp | 251 + core/script/event_p.h | 124 + core/script/executor_kjs.cpp | 138 + core/script/executor_kjs_p.h | 39 + core/script/kjs_app.cpp | 424 + core/script/kjs_app_p.h | 33 + core/script/kjs_console.cpp | 147 + core/script/kjs_console_p.h | 28 + core/script/kjs_data.cpp | 90 + core/script/kjs_data_p.h | 30 + core/script/kjs_display.cpp | 64 + core/script/kjs_display_p.h | 32 + core/script/kjs_document.cpp | 334 + core/script/kjs_document_p.h | 30 + core/script/kjs_event.cpp | 151 + core/script/kjs_event_p.h | 30 + core/script/kjs_field.cpp | 319 + core/script/kjs_field_p.h | 32 + core/script/kjs_fullscreen.cpp | 76 + core/script/kjs_fullscreen_p.h | 28 + core/script/kjs_ocg.cpp | 83 + core/script/kjs_ocg_p.h | 30 + core/script/kjs_spell.cpp | 42 + core/script/kjs_spell_p.h | 28 + core/script/kjs_util.cpp | 187 + core/script/kjs_util_p.h | 28 + core/scripter.cpp | 88 + core/scripter.h | 49 + core/signatureutils.cpp | 156 + core/signatureutils.h | 244 + core/sound.cpp | 117 + core/sound.h | 127 + core/sourcereference.cpp | 104 + core/sourcereference.h | 63 + core/sourcereference_p.h | 23 + .../patches/00-disable-SYNCTEX_INLINE.diff | 17 + .../patches/04-gcc-specify-printf-format.diff | 77 + .../patches/06-mingw-_synctex_error.diff | 36 + core/synctex/patches/08-fix_cpp_comments.diff | 37 + core/synctex/patches/10-fix-typo.diff | 17 + .../11-fix-unused-parameters-warnings.diff | 49 + .../patches/12-omit-no-file-warning.diff | 17 + .../patches/13-fix-Wundef-warnings.diff | 326 + .../14-fix-misc-compiler-warnings.diff | 62 + .../15-prevent-leaks-and-segfault.diff | 54 + .../16-use-windows-ansi-api-path-find.diff | 19 + core/synctex/patches/series | 11 + core/synctex/synctex_parser.c | 8659 +++++++++++++++++ core/synctex/synctex_parser.h | 423 + core/synctex/synctex_parser_advanced.h | 484 + core/synctex/synctex_parser_local.h | 45 + core/synctex/synctex_parser_readme.md | 246 + core/synctex/synctex_parser_utils.c | 603 ++ core/synctex/synctex_parser_utils.h | 161 + core/synctex/synctex_parser_version.txt | 1 + core/textdocumentgenerator.cpp | 566 ++ core/textdocumentgenerator.h | 230 + core/textdocumentgenerator_p.h | 253 + core/textdocumentsettings.cpp | 73 + core/textdocumentsettings.h | 125 + core/textdocumentsettings_p.h | 49 + core/texteditors_p.h | 35 + core/textpage.cpp | 1891 ++++ core/textpage.h | 211 + core/textpage_p.h | 79 + core/tile.h | 56 + core/tilesmanager.cpp | 675 ++ core/tilesmanager_p.h | 210 + core/utils.cpp | 160 + core/utils.h | 59 + core/utils_p.h | 26 + core/view.cpp | 74 + core/view.h | 114 + core/view_p.h | 36 + doc/CMakeLists.txt | 5 + doc/annotation-properties.png | Bin 0 -> 15095 bytes doc/annotations.png | Bin 0 -> 42525 bytes doc/bookmark-management.png | Bin 0 -> 45777 bytes doc/bookmarks.png | Bin 0 -> 226 bytes doc/configure-annotations.png | Bin 0 -> 23450 bytes doc/configure-backends.png | Bin 0 -> 14312 bytes doc/configure-editor.png | Bin 0 -> 23685 bytes doc/configure.png | Bin 0 -> 32098 bytes doc/embedded-files-bar.png | Bin 0 -> 3186 bytes doc/enhance-lowcontrast.png | Bin 0 -> 3753 bytes doc/enhance-shape.png | Bin 0 -> 4090 bytes doc/enhance-solid.png | Bin 0 -> 6491 bytes doc/enhance-thinline.png | Bin 0 -> 8225 bytes doc/forms-bar.png | Bin 0 -> 3694 bytes doc/index.docbook | 2952 ++++++ doc/mainwindow.png | Bin 0 -> 28233 bytes doc/man-okular.1.docbook | 136 + doc/presentation.png | Bin 0 -> 53804 bytes doc/signatures-bar.png | Bin 0 -> 2942 bytes doc/signatures-panel.png | Bin 0 -> 22494 bytes doc/tool-draw-arrow.png | Bin 0 -> 400 bytes doc/tool-draw-ellipse.png | Bin 0 -> 582 bytes doc/tool-draw-freehand.png | Bin 0 -> 621 bytes doc/tool-draw-highlight.png | Bin 0 -> 466 bytes doc/tool-draw-line.png | Bin 0 -> 376 bytes doc/tool-draw-polyline.png | Bin 0 -> 475 bytes doc/tool-draw-rectangle.png | Bin 0 -> 352 bytes doc/tool-edit-comment.png | Bin 0 -> 364 bytes doc/tool-edit-line-width.png | Bin 0 -> 350 bytes doc/tool-edit-opacity.png | Bin 0 -> 558 bytes doc/tool-favorite.png | Bin 0 -> 518 bytes doc/tool-fill-color.png | Bin 0 -> 621 bytes doc/tool-font-face.png | Bin 0 -> 578 bytes doc/tool-format-text-color.png | Bin 0 -> 407 bytes doc/tool-format-text-strikethrough.png | Bin 0 -> 581 bytes doc/tool-format-text-underline-squiggle.png | Bin 0 -> 538 bytes doc/tool-format-text-underline.png | Bin 0 -> 405 bytes doc/tool-note.png | Bin 0 -> 359 bytes doc/tool-pin.png | Bin 0 -> 431 bytes doc/tool-settings-configure.png | Bin 0 -> 416 bytes doc/tool-tag.png | Bin 0 -> 513 bytes doc/tool-tool-text.png | Bin 0 -> 351 bytes doc/tool-window-pin.png | Bin 0 -> 431 bytes generators/CMakeLists.txt | 154 + generators/chm/CMakeLists.txt | 46 + generators/chm/Messages.sh | 2 + generators/chm/autotests/chmgeneratortest.cpp | 101 + generators/chm/autotests/data/test.chm | Bin 0 -> 17472 bytes generators/chm/generator_chm.cpp | 402 + generators/chm/generator_chm.h | 73 + generators/chm/kio-msits/CMakeLists.txt | 23 + generators/chm/kio-msits/kio_mits_debug.cpp | 21 + generators/chm/kio-msits/kio_mits_debug.h | 26 + generators/chm/kio-msits/ms-its.protocol | 70 + generators/chm/kio-msits/msits.cpp | 287 + generators/chm/kio-msits/msits.h | 71 + generators/chm/lib/bitfiddle.h | 164 + generators/chm/lib/ebook.cpp | 47 + generators/chm/lib/ebook.h | 230 + generators/chm/lib/ebook_chm.cpp | 1006 ++ generators/chm/lib/ebook_chm.h | 335 + generators/chm/lib/ebook_chm_encoding.cpp | 141 + generators/chm/lib/ebook_chm_encoding.h | 30 + generators/chm/lib/ebook_epub.cpp | 358 + generators/chm/lib/ebook_epub.h | 205 + generators/chm/lib/ebook_search.cpp | 215 + generators/chm/lib/ebook_search.h | 83 + generators/chm/lib/ebook_url.h | 13 + generators/chm/lib/helper_entitydecoder.cpp | 222 + generators/chm/lib/helper_entitydecoder.h | 45 + generators/chm/lib/helper_search_index.cpp | 448 + generators/chm/lib/helper_search_index.h | 146 + .../lib/helperxmlhandler_epubcontainer.cpp | 33 + .../chm/lib/helperxmlhandler_epubcontainer.h | 34 + .../chm/lib/helperxmlhandler_epubcontent.cpp | 87 + .../chm/lib/helperxmlhandler_epubcontent.h | 55 + .../chm/lib/helperxmlhandler_epubtoc.cpp | 108 + generators/chm/lib/helperxmlhandler_epubtoc.h | 47 + generators/chm/lib/libchmurlfactory.h | 108 + generators/chm/libokularGenerator_chmlib.json | 209 + generators/chm/okularApplication_chm.desktop | 224 + generators/chm/okularChm.desktop | 66 + .../chm/org.kde.mobile.okular_chm.desktop | 215 + .../chm/org.kde.okular-chm.metainfo.xml | 91 + generators/comicbook/CMakeLists.txt | 43 + generators/comicbook/Messages.sh | 2 + .../comicbook/autotests/comicbooktest.cpp | 59 + .../comicbook/autotests/data/rotated_cb.cbz | Bin 0 -> 22493 bytes generators/comicbook/debug_comicbook.h | 17 + generators/comicbook/directory.cpp | 66 + generators/comicbook/directory.h | 56 + generators/comicbook/document.cpp | 256 + generators/comicbook/document.h | 58 + generators/comicbook/generator_comicbook.cpp | 90 + generators/comicbook/generator_comicbook.h | 40 + .../libokularGenerator_comicbook.json | 173 + .../okularApplication_comicbook.desktop | 205 + generators/comicbook/okularComicbook.desktop | 66 + .../org.kde.mobile.okular_comicbook.desktop | 202 + .../org.kde.okular-comicbook.metainfo.xml | 94 + generators/comicbook/qnatsort.cpp | 160 + generators/comicbook/qnatsort.h | 54 + generators/comicbook/unrar.cpp | 294 + generators/comicbook/unrar.h | 85 + generators/comicbook/unrarflavours.cpp | 129 + generators/comicbook/unrarflavours.h | 87 + generators/djvu/CMakeLists.txt | 26 + generators/djvu/Messages.sh | 2 + generators/djvu/TODO | 10 + generators/djvu/generator_djvu.cpp | 396 + generators/djvu/generator_djvu.h | 59 + generators/djvu/kdjvu.cpp | 1061 ++ generators/djvu/kdjvu.h | 304 + generators/djvu/libokularGenerator_djvu.json | 169 + .../djvu/okularApplication_djvu.desktop | 226 + generators/djvu/okularDjvu.desktop | 66 + .../djvu/org.kde.mobile.okular_djvu.desktop | 217 + .../djvu/org.kde.okular-djvu.metainfo.xml | 91 + generators/dvi/CMakeLists.txt | 62 + generators/dvi/Messages.sh | 2 + generators/dvi/TeXFont.cpp | 8 + generators/dvi/TeXFont.h | 51 + generators/dvi/TeXFontDefinition.cpp | 242 + generators/dvi/TeXFontDefinition.h | 162 + generators/dvi/TeXFont_PFB.cpp | 284 + generators/dvi/TeXFont_PFB.h | 41 + generators/dvi/TeXFont_PK.cpp | 729 ++ generators/dvi/TeXFont_PK.h | 41 + generators/dvi/TeXFont_TFM.cpp | 144 + generators/dvi/TeXFont_TFM.h | 48 + generators/dvi/anchor.h | 69 + generators/dvi/bigEndianByteReader.cpp | 111 + generators/dvi/bigEndianByteReader.h | 62 + generators/dvi/config.h | 1 + generators/dvi/debug_dvi.h | 19 + generators/dvi/dvi.h | 68 + generators/dvi/dviFile.cpp | 438 + generators/dvi/dviFile.h | 166 + generators/dvi/dviPageInfo.cpp | 24 + generators/dvi/dviPageInfo.h | 49 + generators/dvi/dviRenderer.cpp | 740 ++ generators/dvi/dviRenderer.h | 346 + generators/dvi/dviRenderer_dr.cpp | 47 + generators/dvi/dviRenderer_draw.cpp | 675 ++ generators/dvi/dviRenderer_prescan.cpp | 781 ++ generators/dvi/dviexport.cpp | 292 + generators/dvi/dviexport.h | 138 + generators/dvi/dvisourcesplitter.cpp | 104 + generators/dvi/dvisourcesplitter.h | 43 + generators/dvi/fontEncoding.cpp | 93 + generators/dvi/fontEncoding.h | 89 + generators/dvi/fontEncodingPool.cpp | 41 + generators/dvi/fontEncodingPool.h | 33 + generators/dvi/fontMap.cpp | 161 + generators/dvi/fontMap.h | 119 + generators/dvi/fontpool.cpp | 466 + generators/dvi/fontpool.h | 219 + generators/dvi/generator_dvi.cpp | 515 + generators/dvi/generator_dvi.h | 69 + generators/dvi/glyph.cpp | 39 + generators/dvi/glyph.h | 47 + generators/dvi/hyperlink.h | 82 + generators/dvi/length.cpp | 73 + generators/dvi/length.h | 306 + generators/dvi/libokularGenerator_dvi.json | 169 + generators/dvi/okularApplication_dvi.desktop | 226 + generators/dvi/okularDvi.desktop | 66 + .../dvi/org.kde.mobile.okular_dvi.desktop | 217 + .../dvi/org.kde.okular-dvi.metainfo.xml | 93 + generators/dvi/pageNumber.h | 78 + generators/dvi/pageSize.cpp | 330 + generators/dvi/pageSize.h | 280 + generators/dvi/prebookmark.h | 58 + generators/dvi/psgs.cpp | 353 + generators/dvi/psgs.h | 110 + generators/dvi/psheader.cpp | 129 + generators/dvi/simplePageSize.cpp | 48 + generators/dvi/simplePageSize.h | 202 + generators/dvi/special.cpp | 682 ++ generators/dvi/textBox.h | 68 + generators/dvi/util.cpp | 114 + generators/dvi/vf.cpp | 183 + generators/dvi/xdvi.h | 22 + generators/epub/CMakeLists.txt | 37 + generators/epub/Messages.sh | 2 + generators/epub/README | 10 + generators/epub/autotests/data/test.epub | Bin 0 -> 357713 bytes .../epub/autotests/epubgeneratortest.cpp | 79 + generators/epub/converter.cpp | 450 + generators/epub/converter.h | 41 + generators/epub/data/CMakeLists.txt | 5 + generators/epub/data/okular-epub-movie.png | Bin 0 -> 12616 bytes .../epub/data/okular-epub-sound-icon.png | Bin 0 -> 2194 bytes generators/epub/epubdocument.cpp | 129 + generators/epub/epubdocument.h | 52 + generators/epub/generator_epub.cpp | 36 + generators/epub/generator_epub.h | 26 + generators/epub/libokularGenerator_epub.json | 169 + .../epub/okularApplication_epub.desktop | 224 + generators/epub/okularEPub.desktop | 66 + .../epub/org.kde.mobile.okular_epub.desktop | 215 + .../epub/org.kde.okular-epub.metainfo.xml | 91 + generators/fax/CMakeLists.txt | 20 + generators/fax/Messages.sh | 2 + generators/fax/fax_debug.cpp | 21 + generators/fax/fax_debug.h | 26 + generators/fax/faxdocument.cpp | 295 + generators/fax/faxdocument.h | 63 + generators/fax/faxexpand.cpp | 720 ++ generators/fax/faxexpand.h | 124 + generators/fax/faxinit.cpp | 118 + generators/fax/generator_fax.cpp | 104 + generators/fax/generator_fax.h | 43 + generators/fax/libokularGenerator_fax.json | 170 + generators/fax/okularApplication_fax.desktop | 172 + generators/fax/okularFax.desktop | 66 + .../fax/org.kde.mobile.okular_fax.desktop | 163 + .../fax/org.kde.okular-fax.metainfo.xml | 92 + generators/fictionbook/16-apps-okular-fb2.png | Bin 0 -> 969 bytes generators/fictionbook/32-apps-okular-fb2.png | Bin 0 -> 1045 bytes generators/fictionbook/48-apps-okular-fb2.png | Bin 0 -> 1395 bytes generators/fictionbook/CMakeLists.txt | 27 + generators/fictionbook/Messages.sh | 2 + generators/fictionbook/converter.cpp | 870 ++ generators/fictionbook/converter.h | 77 + generators/fictionbook/document.cpp | 91 + generators/fictionbook/document.h | 41 + generators/fictionbook/generator_fb.cpp | 31 + generators/fictionbook/generator_fb.h | 27 + .../fictionbook/hi32-app-okular-fb2.svg | 200 + .../fictionbook/libokularGenerator_fb.json | 169 + .../fictionbook/okularApplication_fb.desktop | 224 + generators/fictionbook/okularFb.desktop | 66 + .../org.kde.mobile.okular_fb.desktop | 215 + .../org.kde.okular-fb.metainfo.xml | 91 + generators/kimgio/CMakeLists.txt | 26 + generators/kimgio/Messages.sh | 3 + generators/kimgio/generator_kimgio.cpp | 162 + generators/kimgio/generator_kimgio.h | 53 + .../kimgio/libokularGenerator_kimgio.json | 270 + .../kimgio/okularApplication_kimgio.desktop | 172 + generators/kimgio/okularKimgio.desktop | 66 + .../org.kde.mobile.okular_kimgio.desktop | 163 + .../kimgio/org.kde.okular-kimgio.metainfo.xml | 114 + .../tests/data/testExifOrientation-0.jpg | Bin 0 -> 447 bytes .../data/testExifOrientation-0mirror.jpg | Bin 0 -> 457 bytes .../tests/data/testExifOrientation-180.jpg | Bin 0 -> 463 bytes .../data/testExifOrientation-180mirror.jpg | Bin 0 -> 456 bytes .../tests/data/testExifOrientation-270.jpg | Bin 0 -> 456 bytes .../data/testExifOrientation-270mirror.jpg | Bin 0 -> 447 bytes .../tests/data/testExifOrientation-90.jpg | Bin 0 -> 456 bytes .../data/testExifOrientation-90mirror.jpg | Bin 0 -> 462 bytes .../tests/data/testExifOrientation-noexif.jpg | Bin 0 -> 347 bytes .../data/testExifOrientation-unspecified.jpg | Bin 0 -> 367 bytes generators/kimgio/tests/kimgiotest.cpp | 116 + generators/markdown/CMakeLists.txt | 25 + generators/markdown/Messages.sh | 2 + generators/markdown/converter.cpp | 239 + generators/markdown/converter.h | 60 + generators/markdown/debug_md.h | 19 + generators/markdown/generator_md.cpp | 66 + generators/markdown/generator_md.h | 32 + .../markdown/libokularGenerator_md.json | 133 + .../markdown/okularApplication_md.desktop | 211 + generators/markdown/okularMd.desktop | 66 + .../markdown/org.kde.mobile.okular_md.desktop | 201 + .../markdown/org.kde.okular-md.metainfo.xml | 89 + generators/mobipocket/CMakeLists.txt | 19 + generators/mobipocket/Messages.sh | 2 + generators/mobipocket/converter.cpp | 117 + generators/mobipocket/converter.h | 34 + generators/mobipocket/generator_mobi.cpp | 31 + generators/mobipocket/generator_mobi.h | 28 + .../mobipocket/libokularGenerator_mobi.json | 169 + generators/mobipocket/mobidocument.cpp | 123 + generators/mobipocket/mobidocument.h | 48 + .../mobipocket/okularApplication_mobi.desktop | 219 + generators/mobipocket/okularMobi.desktop | 66 + .../org.kde.mobile.okular_mobi.desktop | 163 + .../org.kde.okular-mobipocket.metainfo.xml | 114 + generators/plucker/CMakeLists.txt | 32 + generators/plucker/Messages.sh | 2 + generators/plucker/generator_plucker.cpp | 190 + generators/plucker/generator_plucker.h | 57 + .../plucker/libokularGenerator_plucker.json | 169 + .../plucker/okularApplication_plucker.desktop | 224 + generators/plucker/okularPlucker.desktop | 66 + .../org.kde.mobile.okular_plucker.desktop | 215 + .../org.kde.okular-plucker.metainfo.xml | 91 + generators/plucker/unpluck/config.cpp | 326 + generators/plucker/unpluck/image.cpp | 469 + generators/plucker/unpluck/image.h | 22 + generators/plucker/unpluck/qunpluck.cpp | 1095 +++ generators/plucker/unpluck/qunpluck.h | 98 + generators/plucker/unpluck/unpluck.cpp | 947 ++ generators/plucker/unpluck/unpluck.h | 300 + generators/plucker/unpluck/unpluckint.h | 143 + generators/plucker/unpluck/util.cpp | 215 + generators/poppler/CMakeLists.txt | 49 + generators/poppler/Messages.sh | 4 + generators/poppler/annots.cpp | 759 ++ generators/poppler/annots.h | 43 + generators/poppler/conf/CMakeLists.txt | 3 + generators/poppler/conf/pdfsettings.kcfg | 18 + generators/poppler/conf/pdfsettings.kcfgc | 4 + generators/poppler/conf/pdfsettingswidget.ui | 49 + .../poppler/config-okular-poppler.h.cmake | 3 + generators/poppler/debug_pdf.h | 17 + generators/poppler/formfields.cpp | 460 + generators/poppler/formfields.h | 153 + generators/poppler/generator_pdf.cpp | 1865 ++++ generators/poppler/generator_pdf.h | 154 + .../poppler/libokularGenerator_poppler.json | 171 + .../poppler/okularApplication_pdf.desktop | 224 + generators/poppler/okularPoppler.desktop | 66 + .../poppler/org.kde.mobile.okular_pdf.desktop | 215 + .../org.kde.okular-poppler.metainfo.xml | 94 + generators/poppler/pdfsignatureutils.cpp | 240 + generators/poppler/pdfsignatureutils.h | 67 + generators/poppler/popplerembeddedfile.h | 60 + generators/spectre/16-apps-okular-gv.png | Bin 0 -> 160 bytes generators/spectre/32-apps-okular-gv.png | Bin 0 -> 259 bytes generators/spectre/CMakeLists.txt | 36 + generators/spectre/DESIGN | 12 + generators/spectre/Messages.sh | 4 + generators/spectre/conf/CMakeLists.txt | 3 + generators/spectre/conf/gssettings.kcfg | 16 + generators/spectre/conf/gssettings.kcfgc | 4 + generators/spectre/conf/gssettingswidget.ui | 61 + generators/spectre/generator_ghostview.cpp | 293 + generators/spectre/generator_ghostview.h | 76 + .../spectre/libokularGenerator_ghostview.json | 170 + .../okularApplication_ghostview.desktop | 219 + generators/spectre/okularGhostview.desktop | 67 + .../org.kde.mobile.okular_ghostview.desktop | 210 + .../org.kde.okular-spectre.metainfo.xml | 98 + generators/spectre/rendererthread.cpp | 127 + generators/spectre/rendererthread.h | 80 + generators/spectre/spectre_debug.cpp | 21 + generators/spectre/spectre_debug.h | 26 + generators/tiff/CMakeLists.txt | 22 + generators/tiff/Messages.sh | 2 + generators/tiff/generator_tiff.cpp | 410 + generators/tiff/generator_tiff.h | 50 + generators/tiff/libokularGenerator_tiff.json | 169 + .../tiff/okularApplication_tiff.desktop | 172 + generators/tiff/okularTiff.desktop | 66 + .../tiff/org.kde.mobile.okular_tiff.desktop | 163 + .../tiff/org.kde.okular-tiff.metainfo.xml | 91 + generators/txt/CMakeLists.txt | 24 + generators/txt/Messages.sh | 2 + generators/txt/converter.cpp | 41 + generators/txt/converter.h | 30 + generators/txt/debug_txt.h | 18 + generators/txt/document.cpp | 70 + generators/txt/document.h | 30 + generators/txt/generator_txt.cpp | 31 + generators/txt/generator_txt.h | 29 + generators/txt/libokularGenerator_txt.json | 169 + generators/txt/okularApplication_txt.desktop | 220 + generators/txt/okularTxt.desktop | 66 + .../txt/org.kde.mobile.okular_txt.desktop | 211 + .../txt/org.kde.okular-txt.metainfo.xml | 90 + generators/xps/.emacs-dirvars | 12 + generators/xps/CMakeLists.txt | 22 + generators/xps/Messages.sh | 2 + generators/xps/generator_xps.cpp | 2163 ++++ generators/xps/generator_xps.h | 341 + generators/xps/libokularGenerator_xps.json | 250 + generators/xps/okularApplication_xps.desktop | 224 + generators/xps/okularXps.desktop | 66 + .../xps/org.kde.mobile.okular_xps.desktop | 215 + .../xps/org.kde.okular-xps.metainfo.xml | 91 + hooks/pre-commit | 10 + icons/128-apps-okular.png | Bin 0 -> 11390 bytes icons/150-apps-okular.png | Bin 0 -> 16098 bytes icons/16-apps-okular.png | Bin 0 -> 662 bytes icons/22-apps-okular.png | Bin 0 -> 1118 bytes icons/310-apps-okular.png | Bin 0 -> 41485 bytes icons/32-apps-okular.png | Bin 0 -> 1910 bytes icons/44-apps-okular.png | Bin 0 -> 3004 bytes icons/48-apps-okular.png | Bin 0 -> 3324 bytes icons/64-apps-okular.png | Bin 0 -> 4617 bytes icons/CMakeLists.txt | 1 + icons/hisc-apps-okular.svgz | Bin 0 -> 14568 bytes icons/small/hi16-apps-okular.svgz | Bin 0 -> 4116 bytes icons/small/hi22-apps-okular.svgz | Bin 0 -> 10975 bytes interfaces/configinterface.h | 78 + interfaces/guiinterface.h | 69 + interfaces/printinterface.h | 73 + interfaces/saveinterface.h | 93 + interfaces/viewerinterface.h | 103 + kdocumentviewer.h | 60 + metainfo.yaml | 16 + mobile/CMakeLists.txt | 4 + mobile/android/AndroidManifest.xml | 48 + mobile/android/res/drawable/icon.png | Bin 0 -> 11390 bytes mobile/android/res/values/libs.xml | 25 + mobile/android/res/values/strings.xml | 3 + mobile/android/src/OpenFileActivity.java | 70 + mobile/app/CMakeLists.txt | 13 + mobile/app/Messages.sh | 2 + mobile/app/android.cpp | 63 + mobile/app/android.h | 55 + mobile/app/app.qrc | 12 + mobile/app/main.cpp | 73 + .../app/org.kde.okular.kirigami.appdata.xml | 282 + mobile/app/package/contents/ui/Bookmarks.qml | 28 + mobile/app/package/contents/ui/MainView.qml | 67 + .../app/package/contents/ui/OkularDrawer.qml | 115 + .../package/contents/ui/TableOfContents.qml | 50 + mobile/app/package/contents/ui/Thumbnails.qml | 45 + .../package/contents/ui/ThumbnailsBase.qml | 76 + .../app/package/contents/ui/TreeDelegate.qml | 83 + mobile/app/package/contents/ui/main.qml | 80 + mobile/app/package/metadata.desktop | 124 + mobile/components/CMakeLists.txt | 49 + mobile/components/DocumentView.qml | 292 + mobile/components/Messages.sh | 2 + mobile/components/documentitem.cpp | 274 + mobile/components/documentitem.h | 185 + mobile/components/okularplugin.cpp | 44 + mobile/components/okularplugin.h | 34 + mobile/components/okularsingleton.cpp | 50 + mobile/components/okularsingleton.h | 37 + mobile/components/pageitem.cpp | 435 + mobile/components/pageitem.h | 177 + mobile/components/private/PageView.qml | 108 + mobile/components/qmldir | 3 + mobile/components/settings.h | 1 + mobile/components/test.qml | 50 + mobile/components/testDocumentView.qml | 35 + mobile/components/thumbnailitem.cpp | 30 + mobile/components/thumbnailitem.h | 34 + okular.categories | 16 + okular.upd | 14 + okular_part.desktop | 66 + part/CMakeLists.txt | 2 + part/annotationactionhandler.cpp | 766 ++ part/annotationactionhandler.h | 52 + part/annotationmodel.cpp | 407 + part/annotationmodel.h | 51 + part/annotationpopup.cpp | 167 + part/annotationpopup.h | 87 + part/annotationpropertiesdialog.cpp | 181 + part/annotationpropertiesdialog.h | 49 + part/annotationproxymodels.cpp | 640 ++ part/annotationproxymodels.h | 147 + part/annotationtools.cpp | 236 + part/annotationtools.h | 126 + part/annotationwidgets.cpp | 855 ++ part/annotationwidgets.h | 286 + part/annotwindow.cpp | 425 + part/annotwindow.h | 77 + part/bookmarklist.cpp | 440 + part/bookmarklist.h | 63 + part/certificateviewer.cpp | 325 + part/certificateviewer.h | 65 + part/data/CMakeLists.txt | 57 + part/data/README.Icons | 13 + part/data/checkmark.png | Bin 0 -> 1303 bytes part/data/circle.png | Bin 0 -> 2036 bytes part/data/comment.png | Bin 0 -> 2205 bytes part/data/cross.png | Bin 0 -> 2200 bytes part/data/drawingtools.xml | 41 + part/data/help.png | Bin 0 -> 1717 bytes part/data/insert.png | Bin 0 -> 1711 bytes part/data/key.png | Bin 0 -> 1967 bytes part/data/newparagraph.png | Bin 0 -> 1927 bytes part/data/note.png | Bin 0 -> 1114 bytes part/data/okular.knsrc | 2 + part/data/paperclip.png | Bin 0 -> 1741 bytes part/data/paragraph.png | Bin 0 -> 2384 bytes part/data/pushpin.png | Bin 0 -> 5138 bytes part/data/rightarrow.png | Bin 0 -> 1553 bytes part/data/rightpointer.png | Bin 0 -> 1573 bytes part/data/sources/checkmark.svgz | Bin 0 -> 1509 bytes part/data/sources/circle.svgz | Bin 0 -> 2173 bytes part/data/sources/comment.svgz | Bin 0 -> 3922 bytes part/data/sources/cross.svgz | Bin 0 -> 1918 bytes part/data/sources/ghns.svg | 3106 ++++++ part/data/sources/help.svgz | Bin 0 -> 3098 bytes part/data/sources/insert.svgz | Bin 0 -> 3551 bytes part/data/sources/key.svgz | Bin 0 -> 4252 bytes part/data/sources/newparagraph.svgz | Bin 0 -> 3652 bytes part/data/sources/note.svgz | Bin 0 -> 2424 bytes part/data/sources/paragraph.svgz | Bin 0 -> 4731 bytes part/data/sources/rightarrow.svgz | Bin 0 -> 2989 bytes part/data/sources/rightpointer.svgz | Bin 0 -> 3299 bytes part/data/sources/star.svgz | Bin 0 -> 4110 bytes part/data/sources/tool-base-okular.svgz | Bin 0 -> 10758 bytes part/data/sources/tool-ellipse-okular.svgz | Bin 0 -> 18082 bytes .../tool-highlighter-okular-colorizable.svgz | Bin 0 -> 15084 bytes .../data/sources/tool-highlighter-okular.svgz | Bin 0 -> 22446 bytes .../sources/tool-ink-okular-colorizable.svgz | Bin 0 -> 5130 bytes part/data/sources/tool-ink-okular.svgz | Bin 0 -> 22334 bytes part/data/sources/tool-line-okular.svgz | Bin 0 -> 18071 bytes .../tool-note-inline-okular-colorizable.svgz | Bin 0 -> 5028 bytes .../data/sources/tool-note-inline-okular.svgz | Bin 0 -> 22703 bytes .../sources/tool-note-okular-colorizable.svgz | Bin 0 -> 13509 bytes part/data/sources/tool-note-okular.svgz | Bin 0 -> 30485 bytes part/data/sources/tool-polygon-okular.svgz | Bin 0 -> 18142 bytes part/data/sources/tool-stamp-okular.svgz | Bin 0 -> 25597 bytes .../tool-typewriter-okular-colorizable.svgz | Bin 0 -> 2611 bytes part/data/sources/tool-underline-okular.svgz | Bin 0 -> 18176 bytes part/data/sources/uparrow.svgz | Bin 0 -> 3070 bytes part/data/sources/upleftarrow.svgz | Bin 0 -> 3301 bytes part/data/stamps.svg | 538 + part/data/star.png | Bin 0 -> 2725 bytes part/data/tool-base-okular.png | Bin 0 -> 870 bytes part/data/tool-base-okular@2x.png | Bin 0 -> 2342 bytes .../tool-highlighter-okular-colorizable.png | Bin 0 -> 2148 bytes ...tool-highlighter-okular-colorizable@2x.png | Bin 0 -> 5188 bytes part/data/tool-ink-okular-colorizable.png | Bin 0 -> 1770 bytes part/data/tool-ink-okular-colorizable@2x.png | Bin 0 -> 3744 bytes .../tool-note-inline-okular-colorizable.png | Bin 0 -> 515 bytes ...tool-note-inline-okular-colorizable@2x.png | Bin 0 -> 945 bytes part/data/tool-note-inline.png | Bin 0 -> 1478 bytes part/data/tool-note-okular-colorizable.png | Bin 0 -> 670 bytes part/data/tool-note-okular-colorizable@2x.png | Bin 0 -> 1524 bytes part/data/tool-note.png | Bin 0 -> 2393 bytes .../tool-typewriter-okular-colorizable.png | Bin 0 -> 397 bytes .../tool-typewriter-okular-colorizable@2x.png | Bin 0 -> 727 bytes part/data/tool_hl_orange.png | Bin 0 -> 1527 bytes part/data/tool_hl_pink.png | Bin 0 -> 1552 bytes part/data/tool_hl_yellow.png | Bin 0 -> 1552 bytes part/data/tool_ink_green.png | Bin 0 -> 1473 bytes part/data/tool_note.png | Bin 0 -> 1592 bytes part/data/tools.xml | 133 + part/data/toolsQuick.xml | 39 + part/data/uparrow.png | Bin 0 -> 1744 bytes part/data/upleftarrow.png | Bin 0 -> 1866 bytes part/debug_ui.cpp | 12 + part/debug_ui.h | 18 + part/dlgaccessibility.cpp | 71 + part/dlgaccessibility.h | 35 + part/dlgaccessibilitybase.ui | 466 + part/dlgannotations.cpp | 26 + part/dlgannotations.h | 23 + part/dlgannotationsbase.ui | 109 + part/dlgdebug.cpp | 33 + part/dlgdebug.h | 23 + part/dlgeditor.cpp | 70 + part/dlgeditor.h | 34 + part/dlgeditorbase.ui | 103 + part/dlggeneral.cpp | 55 + part/dlggeneral.h | 33 + part/dlggeneralbase.ui | 488 + part/dlgperformance.cpp | 65 + part/dlgperformance.h | 32 + part/dlgperformancebase.ui | 355 + part/dlgpresentation.cpp | 65 + part/dlgpresentation.h | 32 + part/dlgpresentationbase.ui | 379 + part/drawingtoolactions.cpp | 249 + part/drawingtoolactions.h | 47 + part/editannottooldialog.cpp | 473 + part/editannottooldialog.h | 63 + part/editdrawingtooldialog.cpp | 142 + part/editdrawingtooldialog.h | 41 + part/embeddedfilesdialog.cpp | 192 + part/embeddedfilesdialog.h | 50 + part/extensions.cpp | 112 + part/extensions.h | 60 + part/fileprinterpreview.cpp | 179 + part/fileprinterpreview.h | 49 + part/findbar.cpp | 201 + part/findbar.h | 62 + part/formwidgets.cpp | 1218 +++ part/formwidgets.h | 349 + part/guiutils.cpp | 371 + part/guiutils.h | 102 + part/ktreeviewsearchline.cpp | 411 + part/ktreeviewsearchline.h | 230 + part/latexrenderer.cpp | 199 + part/latexrenderer.h | 46 + part/layers.cpp | 86 + part/layers.h | 55 + part/magnifierview.cpp | 189 + part/magnifierview.h | 59 + part/minibar.cpp | 561 ++ part/minibar.h | 183 + part/okmenutitle.cpp | 64 + part/okmenutitle.h | 32 + part/pageitemdelegate.cpp | 79 + part/pageitemdelegate.h | 36 + part/pagepainter.cpp | 1226 +++ part/pagepainter.h | 184 + part/pagesizelabel.cpp | 36 + part/pagesizelabel.h | 40 + part/pageview.cpp | 5163 ++++++++++ part/pageview.h | 293 + part/pageviewannotator.cpp | 1419 +++ part/pageviewannotator.h | 170 + part/pageviewmouseannotation.cpp | 645 ++ part/pageviewmouseannotation.h | 176 + part/pageviewutils.cpp | 386 + part/pageviewutils.h | 129 + part/part-viewermode.rc | 72 + part/part.cpp | 3499 +++++++ part/part.h | 439 + part/part.rc | 134 + part/preferencesdialog.cpp | 63 + part/preferencesdialog.h | 58 + part/presentationsearchbar.cpp | 141 + part/presentationsearchbar.h | 47 + part/presentationwidget.cpp | 2243 +++++ part/presentationwidget.h | 194 + part/priorities.h | 21 + part/propertiesdialog.cpp | 506 + part/propertiesdialog.h | 96 + part/revisionviewer.cpp | 86 + part/revisionviewer.h | 33 + part/searchlineedit.cpp | 309 + part/searchlineedit.h | 97 + part/searchwidget.cpp | 102 + part/searchwidget.h | 49 + part/side_reviews.cpp | 309 + part/side_reviews.h | 78 + part/sidebar.cpp | 192 + part/sidebar.h | 57 + part/signatureguiutils.cpp | 146 + part/signatureguiutils.h | 39 + part/signaturemodel.cpp | 265 + part/signaturemodel.h | 44 + part/signaturepanel.cpp | 132 + part/signaturepanel.h | 52 + part/signaturepropertiesdialog.cpp | 132 + part/signaturepropertiesdialog.h | 39 + part/snapshottaker.cpp | 45 + part/snapshottaker.h | 37 + part/textdocumentsettings.ui | 13 + part/thumbnaillist.cpp | 1000 ++ part/thumbnaillist.h | 100 + part/toc.cpp | 228 + part/toc.h | 76 + part/tocmodel.cpp | 470 + part/tocmodel.h | 79 + part/toggleactionmenu.cpp | 131 + part/toggleactionmenu.h | 147 + part/tts.cpp | 108 + part/tts.h | 41 + part/url_utils.h | 42 + part/videowidget.cpp | 418 + part/videowidget.h | 66 + part/widgetannottools.cpp | 170 + part/widgetannottools.h | 33 + part/widgetconfigurationtoolsbase.cpp | 101 + part/widgetconfigurationtoolsbase.h | 52 + part/widgetdrawingtools.cpp | 203 + part/widgetdrawingtools.h | 32 + part/xmlgui_helper.cpp | 117 + part/xmlgui_helper.h | 15 + po/ar/okular.po | 5726 +++++++++++ po/ar/okular_chm.po | 63 + po/ar/okular_comicbook.po | 59 + po/ar/okular_djvu.po | 139 + po/ar/okular_dvi.po | 729 ++ po/ar/okular_epub.po | 57 + po/ar/okular_fax.po | 46 + po/ar/okular_fictionbook.po | 85 + po/ar/okular_ghostview.po | 95 + po/ar/okular_kimgio.po | 70 + po/ar/okular_mobi.po | 62 + po/ar/okular_plucker.po | 48 + po/ar/okular_poppler.po | 226 + po/ar/okular_txt.po | 45 + po/ar/okular_xps.po | 60 + po/ast/okular_chm.po | 40 + po/ast/okular_fax.po | 33 + po/ast/okular_plucker.po | 33 + po/ast/okular_xps.po | 33 + po/bg/okular.po | 5871 +++++++++++ po/bg/okular_chm.po | 60 + po/bg/okular_comicbook.po | 59 + po/bg/okular_djvu.po | 136 + po/bg/okular_dvi.po | 801 ++ po/bg/okular_epub.po | 55 + po/bg/okular_fax.po | 45 + po/bg/okular_fictionbook.po | 81 + po/bg/okular_ghostview.po | 92 + po/bg/okular_kimgio.po | 68 + po/bg/okular_mobi.po | 63 + po/bg/okular_plucker.po | 46 + po/bg/okular_poppler.po | 223 + po/bg/okular_txt.po | 50 + po/bg/okular_xps.po | 58 + po/bg/org.kde.active.documentviewer.po | 72 + po/bs/okular.po | 5881 +++++++++++ po/bs/okular_chm.po | 62 + po/bs/okular_comicbook.po | 60 + po/bs/okular_djvu.po | 110 + po/bs/okular_dvi.po | 581 ++ po/bs/okular_epub.po | 58 + po/bs/okular_fax.po | 48 + po/bs/okular_fictionbook.po | 83 + po/bs/okular_ghostview.po | 94 + po/bs/okular_kimgio.po | 70 + po/bs/okular_mobi.po | 66 + po/bs/okular_plucker.po | 48 + po/bs/okular_poppler.po | 204 + po/bs/okular_txt.po | 53 + po/bs/okular_xps.po | 60 + po/bs/org.kde.active.documentviewer.po | 75 + po/ca/docs/okular/bookmark-management.png | Bin 0 -> 107512 bytes po/ca/docs/okular/configure-annotations.png | Bin 0 -> 83947 bytes po/ca/docs/okular/configure-backends.png | Bin 0 -> 39470 bytes po/ca/docs/okular/configure-editor.png | Bin 0 -> 41522 bytes po/ca/docs/okular/configure.png | Bin 0 -> 112117 bytes po/ca/docs/okular/index.docbook | 4233 ++++++++ po/ca/docs/okular/mainwindow.png | Bin 0 -> 112812 bytes po/ca/docs/okular/man-okular.1.docbook | 237 + po/ca/docs/okular/presentation.png | Bin 0 -> 60119 bytes po/ca/okular.po | 5282 ++++++++++ po/ca/okular_chm.po | 47 + po/ca/okular_comicbook.po | 63 + po/ca/okular_djvu.po | 99 + po/ca/okular_dvi.po | 593 ++ po/ca/okular_epub.po | 59 + po/ca/okular_fax.po | 37 + po/ca/okular_fictionbook.po | 84 + po/ca/okular_ghostview.po | 96 + po/ca/okular_kimgio.po | 72 + po/ca/okular_markdown.po | 56 + po/ca/okular_mobi.po | 55 + po/ca/okular_plucker.po | 48 + po/ca/okular_poppler.po | 193 + po/ca/okular_tiff.po | 31 + po/ca/okular_txt.po | 54 + po/ca/okular_xps.po | 60 + po/ca/org.kde.active.documentviewer.po | 59 + po/ca@valencia/okular.po | 5275 ++++++++++ po/ca@valencia/okular_chm.po | 47 + po/ca@valencia/okular_comicbook.po | 63 + po/ca@valencia/okular_djvu.po | 99 + po/ca@valencia/okular_dvi.po | 593 ++ po/ca@valencia/okular_epub.po | 59 + po/ca@valencia/okular_fax.po | 37 + po/ca@valencia/okular_fictionbook.po | 84 + po/ca@valencia/okular_ghostview.po | 96 + po/ca@valencia/okular_kimgio.po | 72 + po/ca@valencia/okular_markdown.po | 56 + po/ca@valencia/okular_mobi.po | 55 + po/ca@valencia/okular_plucker.po | 48 + po/ca@valencia/okular_poppler.po | 193 + po/ca@valencia/okular_tiff.po | 31 + po/ca@valencia/okular_txt.po | 54 + po/ca@valencia/okular_xps.po | 60 + .../org.kde.active.documentviewer.po | 59 + po/cs/okular.po | 5206 ++++++++++ po/cs/okular_chm.po | 42 + po/cs/okular_comicbook.po | 47 + po/cs/okular_djvu.po | 94 + po/cs/okular_dvi.po | 561 ++ po/cs/okular_epub.po | 43 + po/cs/okular_fax.po | 32 + po/cs/okular_fictionbook.po | 68 + po/cs/okular_ghostview.po | 76 + po/cs/okular_kimgio.po | 40 + po/cs/okular_markdown.po | 53 + po/cs/okular_mobi.po | 50 + po/cs/okular_plucker.po | 33 + po/cs/okular_poppler.po | 191 + po/cs/okular_tiff.po | 28 + po/cs/okular_txt.po | 38 + po/cs/okular_xps.po | 33 + po/cs/org.kde.active.documentviewer.po | 55 + po/da/okular.po | 5955 ++++++++++++ po/da/okular_chm.po | 60 + po/da/okular_comicbook.po | 58 + po/da/okular_djvu.po | 140 + po/da/okular_dvi.po | 847 ++ po/da/okular_epub.po | 55 + po/da/okular_fax.po | 45 + po/da/okular_fictionbook.po | 93 + po/da/okular_ghostview.po | 92 + po/da/okular_kimgio.po | 70 + po/da/okular_markdown.po | 53 + po/da/okular_mobi.po | 61 + po/da/okular_plucker.po | 46 + po/da/okular_poppler.po | 225 + po/da/okular_txt.po | 50 + po/da/okular_xps.po | 58 + po/da/org.kde.active.documentviewer.po | 72 + po/de/docs/okular/annotation-properties.png | Bin 0 -> 20683 bytes po/de/docs/okular/configure-annotations.png | Bin 0 -> 76371 bytes po/de/docs/okular/configure-editor.png | Bin 0 -> 40359 bytes po/de/docs/okular/configure.png | Bin 0 -> 77447 bytes po/de/docs/okular/embedded-files-bar.png | Bin 0 -> 6156 bytes po/de/docs/okular/index.docbook | 4229 ++++++++ po/de/docs/okular/mainwindow.png | Bin 0 -> 77668 bytes po/de/docs/okular/man-okular.1.docbook | 237 + po/de/okular.po | 5849 +++++++++++ po/de/okular_chm.po | 59 + po/de/okular_comicbook.po | 58 + po/de/okular_djvu.po | 136 + po/de/okular_dvi.po | 845 ++ po/de/okular_epub.po | 53 + po/de/okular_fax.po | 42 + po/de/okular_fictionbook.po | 94 + po/de/okular_ghostview.po | 120 + po/de/okular_kimgio.po | 67 + po/de/okular_markdown.po | 53 + po/de/okular_mobi.po | 62 + po/de/okular_plucker.po | 43 + po/de/okular_poppler.po | 291 + po/de/okular_tiff.po | 28 + po/de/okular_txt.po | 51 + po/de/okular_xps.po | 55 + po/de/org.kde.active.documentviewer.po | 84 + po/el/okular.po | 6045 ++++++++++++ po/el/okular_chm.po | 66 + po/el/okular_comicbook.po | 62 + po/el/okular_djvu.po | 140 + po/el/okular_dvi.po | 797 ++ po/el/okular_epub.po | 58 + po/el/okular_fax.po | 45 + po/el/okular_fictionbook.po | 82 + po/el/okular_ghostview.po | 94 + po/el/okular_kimgio.po | 73 + po/el/okular_markdown.po | 53 + po/el/okular_mobi.po | 64 + po/el/okular_plucker.po | 46 + po/el/okular_poppler.po | 230 + po/el/okular_tiff.po | 28 + po/el/okular_txt.po | 50 + po/el/okular_xps.po | 59 + po/el/org.kde.active.documentviewer.po | 81 + po/en_GB/okular.po | 5946 +++++++++++ po/en_GB/okular_chm.po | 63 + po/en_GB/okular_comicbook.po | 60 + po/en_GB/okular_djvu.po | 139 + po/en_GB/okular_dvi.po | 773 ++ po/en_GB/okular_epub.po | 56 + po/en_GB/okular_fax.po | 44 + po/en_GB/okular_fictionbook.po | 81 + po/en_GB/okular_ghostview.po | 92 + po/en_GB/okular_kimgio.po | 71 + po/en_GB/okular_markdown.po | 53 + po/en_GB/okular_mobi.po | 62 + po/en_GB/okular_plucker.po | 45 + po/en_GB/okular_poppler.po | 231 + po/en_GB/okular_tiff.po | 28 + po/en_GB/okular_txt.po | 49 + po/en_GB/okular_xps.po | 58 + po/en_GB/org.kde.active.documentviewer.po | 80 + po/eo/okular.po | 5783 +++++++++++ po/eo/okular_chm.po | 60 + po/eo/okular_comicbook.po | 49 + po/eo/okular_djvu.po | 140 + po/eo/okular_dvi.po | 814 ++ po/eo/okular_epub.po | 55 + po/eo/okular_fax.po | 44 + po/eo/okular_fictionbook.po | 99 + po/eo/okular_ghostview.po | 105 + po/eo/okular_kimgio.po | 69 + po/eo/okular_mobi.po | 54 + po/eo/okular_plucker.po | 40 + po/eo/okular_poppler.po | 216 + po/eo/okular_xps.po | 58 + po/es/docs/okular/configure.png | Bin 0 -> 66468 bytes po/es/docs/okular/embedded-files-bar.png | Bin 0 -> 4657 bytes po/es/docs/okular/index.docbook | 4274 ++++++++ po/es/docs/okular/man-okular.1.docbook | 237 + po/es/okular.po | 5735 +++++++++++ po/es/okular_chm.po | 62 + po/es/okular_comicbook.po | 60 + po/es/okular_djvu.po | 136 + po/es/okular_dvi.po | 755 ++ po/es/okular_epub.po | 57 + po/es/okular_fax.po | 45 + po/es/okular_fictionbook.po | 81 + po/es/okular_ghostview.po | 93 + po/es/okular_kimgio.po | 70 + po/es/okular_markdown.po | 55 + po/es/okular_mobi.po | 66 + po/es/okular_plucker.po | 46 + po/es/okular_poppler.po | 229 + po/es/okular_tiff.po | 30 + po/es/okular_txt.po | 51 + po/es/okular_xps.po | 58 + po/es/org.kde.active.documentviewer.po | 84 + po/et/docs/okular/man-okular.1.docbook | 289 + po/et/okular.po | 5848 +++++++++++ po/et/okular_chm.po | 62 + po/et/okular_comicbook.po | 57 + po/et/okular_djvu.po | 139 + po/et/okular_dvi.po | 781 ++ po/et/okular_epub.po | 56 + po/et/okular_fax.po | 45 + po/et/okular_fictionbook.po | 96 + po/et/okular_ghostview.po | 124 + po/et/okular_kimgio.po | 71 + po/et/okular_markdown.po | 53 + po/et/okular_mobi.po | 63 + po/et/okular_plucker.po | 46 + po/et/okular_poppler.po | 245 + po/et/okular_txt.po | 50 + po/et/okular_xps.po | 58 + po/et/org.kde.active.documentviewer.po | 77 + po/eu/okular.po | 5548 +++++++++++ po/eu/okular_chm.po | 64 + po/eu/okular_comicbook.po | 62 + po/eu/okular_djvu.po | 141 + po/eu/okular_dvi.po | 755 ++ po/eu/okular_epub.po | 59 + po/eu/okular_fax.po | 47 + po/eu/okular_fictionbook.po | 85 + po/eu/okular_ghostview.po | 96 + po/eu/okular_kimgio.po | 75 + po/eu/okular_markdown.po | 57 + po/eu/okular_mobi.po | 67 + po/eu/okular_plucker.po | 47 + po/eu/okular_poppler.po | 231 + po/eu/okular_tiff.po | 31 + po/eu/okular_txt.po | 41 + po/eu/okular_xps.po | 59 + po/eu/org.kde.active.documentviewer.po | 61 + po/fa/okular.po | 5647 +++++++++++ po/fi/okular.po | 5826 +++++++++++ po/fi/okular_chm.po | 70 + po/fi/okular_comicbook.po | 64 + po/fi/okular_djvu.po | 143 + po/fi/okular_dvi.po | 750 ++ po/fi/okular_epub.po | 60 + po/fi/okular_fax.po | 48 + po/fi/okular_fictionbook.po | 87 + po/fi/okular_ghostview.po | 99 + po/fi/okular_kimgio.po | 74 + po/fi/okular_markdown.po | 53 + po/fi/okular_mobi.po | 64 + po/fi/okular_plucker.po | 51 + po/fi/okular_poppler.po | 236 + po/fi/okular_tiff.po | 28 + po/fi/okular_txt.po | 51 + po/fi/okular_xps.po | 64 + po/fi/org.kde.active.documentviewer.po | 83 + po/fr/docs/okular/annotation-properties.png | Bin 0 -> 21873 bytes po/fr/docs/okular/annotations.png | Bin 0 -> 203447 bytes po/fr/docs/okular/bookmark-management.png | Bin 0 -> 138393 bytes po/fr/docs/okular/configure-annotations.png | Bin 0 -> 110207 bytes po/fr/docs/okular/configure-backends.png | Bin 0 -> 52664 bytes po/fr/docs/okular/configure-editor.png | Bin 0 -> 41332 bytes po/fr/docs/okular/configure.png | Bin 0 -> 133957 bytes po/fr/docs/okular/forms-bar.png | Bin 0 -> 5463 bytes po/fr/docs/okular/index.docbook | 3505 +++++++ po/fr/docs/okular/mainwindow.png | Bin 0 -> 102095 bytes po/fr/docs/okular/man-okular.1.docbook | 291 + po/fr/docs/okular/presentation.png | Bin 0 -> 55325 bytes po/fr/okular.po | 5852 +++++++++++ po/fr/okular_chm.po | 68 + po/fr/okular_comicbook.po | 67 + po/fr/okular_djvu.po | 141 + po/fr/okular_dvi.po | 815 ++ po/fr/okular_epub.po | 60 + po/fr/okular_fax.po | 50 + po/fr/okular_fictionbook.po | 104 + po/fr/okular_ghostview.po | 97 + po/fr/okular_kimgio.po | 78 + po/fr/okular_markdown.po | 57 + po/fr/okular_mobi.po | 68 + po/fr/okular_plucker.po | 51 + po/fr/okular_poppler.po | 239 + po/fr/okular_tiff.po | 25 + po/fr/okular_txt.po | 53 + po/fr/okular_xps.po | 67 + po/fr/org.kde.active.documentviewer.po | 87 + po/ga/okular.po | 5738 +++++++++++ po/ga/okular_chm.po | 62 + po/ga/okular_comicbook.po | 58 + po/ga/okular_djvu.po | 148 + po/ga/okular_dvi.po | 572 ++ po/ga/okular_epub.po | 56 + po/ga/okular_fax.po | 45 + po/ga/okular_fictionbook.po | 97 + po/ga/okular_ghostview.po | 119 + po/ga/okular_kimgio.po | 67 + po/ga/okular_mobi.po | 65 + po/ga/okular_plucker.po | 54 + po/ga/okular_poppler.po | 261 + po/ga/okular_xps.po | 83 + po/ga/org.kde.active.documentviewer.po | 69 + po/gl/docs/okular/index.docbook | 2107 ++++ po/gl/okular.po | 5837 +++++++++++ po/gl/okular_chm.po | 64 + po/gl/okular_comicbook.po | 60 + po/gl/okular_djvu.po | 136 + po/gl/okular_dvi.po | 740 ++ po/gl/okular_epub.po | 56 + po/gl/okular_fax.po | 48 + po/gl/okular_fictionbook.po | 81 + po/gl/okular_ghostview.po | 94 + po/gl/okular_kimgio.po | 71 + po/gl/okular_markdown.po | 52 + po/gl/okular_mobi.po | 64 + po/gl/okular_plucker.po | 46 + po/gl/okular_poppler.po | 235 + po/gl/okular_txt.po | 49 + po/gl/okular_xps.po | 58 + po/gl/org.kde.active.documentviewer.po | 85 + po/he/okular.po | 5433 +++++++++++ po/hi/okular.po | 5539 +++++++++++ po/hi/okular_chm.po | 57 + po/hi/okular_djvu.po | 153 + po/hi/okular_dvi.po | 664 ++ po/hi/okular_fictionbook.po | 84 + po/hi/okular_ghostview.po | 103 + po/hi/okular_kimgio.po | 73 + po/hi/okular_plucker.po | 34 + po/hi/okular_poppler.po | 216 + po/hi/okular_xps.po | 58 + po/hr/okular.po | 5743 +++++++++++ po/hr/okular_chm.po | 63 + po/hr/okular_comicbook.po | 62 + po/hr/okular_djvu.po | 139 + po/hr/okular_dvi.po | 607 ++ po/hr/okular_epub.po | 57 + po/hr/okular_fax.po | 49 + po/hr/okular_fictionbook.po | 83 + po/hr/okular_ghostview.po | 96 + po/hr/okular_kimgio.po | 71 + po/hr/okular_mobi.po | 66 + po/hr/okular_plucker.po | 49 + po/hr/okular_poppler.po | 224 + po/hr/okular_xps.po | 61 + po/hu/okular.po | 5969 ++++++++++++ po/hu/okular_chm.po | 62 + po/hu/okular_comicbook.po | 61 + po/hu/okular_djvu.po | 136 + po/hu/okular_dvi.po | 732 ++ po/hu/okular_epub.po | 57 + po/hu/okular_fax.po | 46 + po/hu/okular_fictionbook.po | 82 + po/hu/okular_ghostview.po | 92 + po/hu/okular_kimgio.po | 70 + po/hu/okular_markdown.po | 53 + po/hu/okular_mobi.po | 65 + po/hu/okular_plucker.po | 46 + po/hu/okular_poppler.po | 227 + po/hu/okular_tiff.po | 28 + po/hu/okular_txt.po | 51 + po/hu/okular_xps.po | 58 + po/hu/org.kde.active.documentviewer.po | 72 + po/ia/okular.po | 5781 +++++++++++ po/ia/okular_chm.po | 61 + po/ia/okular_comicbook.po | 59 + po/ia/okular_djvu.po | 135 + po/ia/okular_dvi.po | 743 ++ po/ia/okular_epub.po | 55 + po/ia/okular_fax.po | 45 + po/ia/okular_fictionbook.po | 80 + po/ia/okular_ghostview.po | 92 + po/ia/okular_kimgio.po | 69 + po/ia/okular_markdown.po | 54 + po/ia/okular_mobi.po | 63 + po/ia/okular_plucker.po | 45 + po/ia/okular_poppler.po | 225 + po/ia/okular_tiff.po | 28 + po/ia/okular_txt.po | 50 + po/ia/okular_xps.po | 57 + po/ia/org.kde.active.documentviewer.po | 81 + po/id/okular.po | 5372 ++++++++++ po/is/okular.po | 5841 +++++++++++ po/is/okular_chm.po | 62 + po/is/okular_comicbook.po | 61 + po/is/okular_djvu.po | 138 + po/is/okular_dvi.po | 738 ++ po/is/okular_epub.po | 58 + po/is/okular_fax.po | 48 + po/is/okular_fictionbook.po | 83 + po/is/okular_ghostview.po | 94 + po/is/okular_kimgio.po | 70 + po/is/okular_mobi.po | 66 + po/is/okular_plucker.po | 48 + po/is/okular_poppler.po | 225 + po/is/okular_xps.po | 60 + po/is/org.kde.active.documentviewer.po | 72 + po/it/docs/okular/annotation-properties.png | Bin 0 -> 14835 bytes po/it/docs/okular/annotations.png | Bin 0 -> 85212 bytes po/it/docs/okular/bookmark-management.png | Bin 0 -> 42239 bytes po/it/docs/okular/configure-annotations.png | Bin 0 -> 29100 bytes po/it/docs/okular/configure-backends.png | Bin 0 -> 18125 bytes po/it/docs/okular/configure-editor.png | Bin 0 -> 21564 bytes po/it/docs/okular/configure.png | Bin 0 -> 30645 bytes po/it/docs/okular/embedded-files-bar.png | Bin 0 -> 2978 bytes po/it/docs/okular/forms-bar.png | Bin 0 -> 3870 bytes po/it/docs/okular/index.docbook | 4286 ++++++++ po/it/docs/okular/mainwindow.png | Bin 0 -> 34133 bytes po/it/docs/okular/man-okular.1.docbook | 237 + po/it/docs/okular/presentation.png | Bin 0 -> 14722 bytes po/it/docs/okular/signatures-bar.png | Bin 0 -> 3062 bytes po/it/docs/okular/signatures-panel.png | Bin 0 -> 5010 bytes po/it/okular.po | 5981 ++++++++++++ po/it/okular_chm.po | 62 + po/it/okular_comicbook.po | 61 + po/it/okular_djvu.po | 138 + po/it/okular_dvi.po | 843 ++ po/it/okular_epub.po | 55 + po/it/okular_fax.po | 45 + po/it/okular_fictionbook.po | 95 + po/it/okular_ghostview.po | 122 + po/it/okular_kimgio.po | 70 + po/it/okular_markdown.po | 53 + po/it/okular_mobi.po | 63 + po/it/okular_plucker.po | 45 + po/it/okular_poppler.po | 234 + po/it/okular_tiff.po | 28 + po/it/okular_txt.po | 49 + po/it/okular_xps.po | 57 + po/it/org.kde.active.documentviewer.po | 80 + po/ja/docs/okular/configure.png | Bin 0 -> 87667 bytes po/ja/docs/okular/embedded-files-bar.png | Bin 0 -> 5576 bytes po/ja/docs/okular/index.docbook | 1908 ++++ po/ja/okular.po | 5471 +++++++++++ po/ja/okular_chm.po | 41 + po/ja/okular_comicbook.po | 48 + po/ja/okular_djvu.po | 96 + po/ja/okular_dvi.po | 625 ++ po/ja/okular_epub.po | 44 + po/ja/okular_fax.po | 34 + po/ja/okular_fictionbook.po | 69 + po/ja/okular_ghostview.po | 78 + po/ja/okular_kimgio.po | 41 + po/ja/okular_markdown.po | 50 + po/ja/okular_mobi.po | 51 + po/ja/okular_plucker.po | 34 + po/ja/okular_poppler.po | 186 + po/ja/okular_txt.po | 35 + po/ja/okular_xps.po | 34 + po/ja/org.kde.active.documentviewer.po | 52 + po/kk/okular.po | 5954 ++++++++++++ po/kk/okular_chm.po | 59 + po/kk/okular_comicbook.po | 57 + po/kk/okular_djvu.po | 135 + po/kk/okular_dvi.po | 821 ++ po/kk/okular_epub.po | 55 + po/kk/okular_fax.po | 45 + po/kk/okular_fictionbook.po | 80 + po/kk/okular_ghostview.po | 91 + po/kk/okular_kimgio.po | 67 + po/kk/okular_mobi.po | 61 + po/kk/okular_plucker.po | 45 + po/kk/okular_poppler.po | 221 + po/kk/okular_txt.po | 52 + po/kk/okular_xps.po | 57 + po/kk/org.kde.active.documentviewer.po | 72 + po/km/okular.po | 5708 +++++++++++ po/km/okular_chm.po | 62 + po/km/okular_comicbook.po | 59 + po/km/okular_djvu.po | 138 + po/km/okular_dvi.po | 779 ++ po/km/okular_epub.po | 58 + po/km/okular_fax.po | 47 + po/km/okular_fictionbook.po | 85 + po/km/okular_ghostview.po | 94 + po/km/okular_kimgio.po | 70 + po/km/okular_mobi.po | 65 + po/km/okular_plucker.po | 48 + po/km/okular_poppler.po | 228 + po/km/okular_xps.po | 59 + po/ko/okular.po | 5709 +++++++++++ po/ko/okular_chm.po | 62 + po/ko/okular_comicbook.po | 57 + po/ko/okular_djvu.po | 135 + po/ko/okular_dvi.po | 701 ++ po/ko/okular_epub.po | 55 + po/ko/okular_fax.po | 44 + po/ko/okular_fictionbook.po | 80 + po/ko/okular_ghostview.po | 91 + po/ko/okular_kimgio.po | 69 + po/ko/okular_markdown.po | 53 + po/ko/okular_mobi.po | 60 + po/ko/okular_plucker.po | 45 + po/ko/okular_poppler.po | 227 + po/ko/okular_tiff.po | 28 + po/ko/okular_txt.po | 49 + po/ko/okular_xps.po | 57 + po/ko/org.kde.active.documentviewer.po | 80 + po/lt/okular.po | 5809 +++++++++++ po/lt/okular_chm.po | 62 + po/lt/okular_comicbook.po | 60 + po/lt/okular_djvu.po | 137 + po/lt/okular_dvi.po | 635 ++ po/lt/okular_epub.po | 57 + po/lt/okular_fax.po | 46 + po/lt/okular_fictionbook.po | 82 + po/lt/okular_ghostview.po | 92 + po/lt/okular_kimgio.po | 70 + po/lt/okular_markdown.po | 55 + po/lt/okular_mobi.po | 65 + po/lt/okular_plucker.po | 47 + po/lt/okular_poppler.po | 228 + po/lt/okular_tiff.po | 30 + po/lt/okular_txt.po | 53 + po/lt/okular_xps.po | 57 + po/lt/org.kde.active.documentviewer.po | 76 + po/lv/okular.po | 5619 +++++++++++ po/lv/okular_chm.po | 62 + po/lv/okular_comicbook.po | 59 + po/lv/okular_djvu.po | 141 + po/lv/okular_dvi.po | 794 ++ po/lv/okular_epub.po | 58 + po/lv/okular_fax.po | 46 + po/lv/okular_fictionbook.po | 85 + po/lv/okular_ghostview.po | 95 + po/lv/okular_kimgio.po | 70 + po/lv/okular_mobi.po | 66 + po/lv/okular_plucker.po | 48 + po/lv/okular_poppler.po | 229 + po/lv/okular_xps.po | 60 + po/ml/okular.po | 5119 ++++++++++ po/ml/okular_chm.po | 41 + po/ml/okular_comicbook.po | 45 + po/ml/okular_djvu.po | 96 + po/ml/okular_dvi.po | 468 + po/ml/okular_epub.po | 44 + po/ml/okular_fax.po | 34 + po/ml/okular_fictionbook.po | 69 + po/ml/okular_ghostview.po | 75 + po/ml/okular_kimgio.po | 41 + po/ml/okular_markdown.po | 54 + po/ml/okular_mobi.po | 50 + po/ml/okular_plucker.po | 34 + po/ml/okular_poppler.po | 182 + po/ml/okular_txt.po | 39 + po/ml/okular_xps.po | 34 + po/ml/org.kde.active.documentviewer.po | 56 + po/mr/okular.po | 5953 +++++++++++ po/mr/okular_chm.po | 59 + po/mr/okular_comicbook.po | 57 + po/mr/okular_djvu.po | 135 + po/mr/okular_dvi.po | 491 + po/mr/okular_epub.po | 56 + po/mr/okular_fax.po | 45 + po/mr/okular_fictionbook.po | 82 + po/mr/okular_ghostview.po | 91 + po/mr/okular_kimgio.po | 67 + po/mr/okular_mobi.po | 63 + po/mr/okular_plucker.po | 45 + po/mr/okular_poppler.po | 221 + po/mr/okular_xps.po | 57 + po/mr/org.kde.active.documentviewer.po | 72 + po/nb/okular.po | 5175 ++++++++++ po/nb/okular_chm.po | 42 + po/nb/okular_comicbook.po | 47 + po/nb/okular_djvu.po | 97 + po/nb/okular_dvi.po | 569 ++ po/nb/okular_epub.po | 45 + po/nb/okular_fax.po | 35 + po/nb/okular_fictionbook.po | 70 + po/nb/okular_ghostview.po | 78 + po/nb/okular_kimgio.po | 42 + po/nb/okular_mobi.po | 53 + po/nb/okular_plucker.po | 35 + po/nb/okular_poppler.po | 188 + po/nb/okular_txt.po | 40 + po/nb/okular_xps.po | 35 + po/nb/org.kde.active.documentviewer.po | 57 + po/nds/okular.po | 6006 ++++++++++++ po/nds/okular_chm.po | 62 + po/nds/okular_comicbook.po | 60 + po/nds/okular_djvu.po | 141 + po/nds/okular_dvi.po | 805 ++ po/nds/okular_epub.po | 56 + po/nds/okular_fax.po | 47 + po/nds/okular_fictionbook.po | 97 + po/nds/okular_ghostview.po | 106 + po/nds/okular_kimgio.po | 70 + po/nds/okular_mobi.po | 63 + po/nds/okular_plucker.po | 48 + po/nds/okular_poppler.po | 225 + po/nds/okular_txt.po | 50 + po/nds/okular_xps.po | 60 + po/nds/org.kde.active.documentviewer.po | 72 + po/nl/docs/okular/index.docbook | 4228 ++++++++ po/nl/docs/okular/man-okular.1.docbook | 237 + po/nl/okular.po | 5818 +++++++++++ po/nl/okular_chm.po | 63 + po/nl/okular_comicbook.po | 61 + po/nl/okular_djvu.po | 143 + po/nl/okular_dvi.po | 779 ++ po/nl/okular_epub.po | 57 + po/nl/okular_fax.po | 47 + po/nl/okular_fictionbook.po | 82 + po/nl/okular_ghostview.po | 94 + po/nl/okular_kimgio.po | 71 + po/nl/okular_markdown.po | 53 + po/nl/okular_mobi.po | 65 + po/nl/okular_plucker.po | 47 + po/nl/okular_poppler.po | 230 + po/nl/okular_tiff.po | 28 + po/nl/okular_txt.po | 50 + po/nl/okular_xps.po | 60 + po/nl/org.kde.active.documentviewer.po | 80 + po/nn/okular.po | 5249 ++++++++++ po/nn/okular_chm.po | 46 + po/nn/okular_comicbook.po | 48 + po/nn/okular_djvu.po | 99 + po/nn/okular_dvi.po | 570 ++ po/nn/okular_epub.po | 46 + po/nn/okular_fax.po | 36 + po/nn/okular_fictionbook.po | 71 + po/nn/okular_ghostview.po | 80 + po/nn/okular_kimgio.po | 44 + po/nn/okular_markdown.po | 55 + po/nn/okular_mobi.po | 54 + po/nn/okular_plucker.po | 36 + po/nn/okular_poppler.po | 192 + po/nn/okular_tiff.po | 30 + po/nn/okular_txt.po | 40 + po/nn/okular_xps.po | 36 + po/nn/org.kde.active.documentviewer.po | 57 + po/pa/okular.po | 5522 +++++++++++ po/pa/okular_chm.po | 60 + po/pa/okular_comicbook.po | 59 + po/pa/okular_djvu.po | 136 + po/pa/okular_dvi.po | 564 ++ po/pa/okular_epub.po | 56 + po/pa/okular_fax.po | 46 + po/pa/okular_fictionbook.po | 75 + po/pa/okular_ghostview.po | 87 + po/pa/okular_kimgio.po | 68 + po/pa/okular_mobi.po | 62 + po/pa/okular_plucker.po | 46 + po/pa/okular_poppler.po | 218 + po/pa/okular_txt.po | 50 + po/pa/okular_xps.po | 58 + po/pa/org.kde.active.documentviewer.po | 72 + po/pl/docs/okular/annotation-properties.png | Bin 0 -> 33200 bytes po/pl/docs/okular/annotations.png | Bin 0 -> 173424 bytes po/pl/docs/okular/bookmark-management.png | Bin 0 -> 123761 bytes po/pl/docs/okular/configure-annotations.png | Bin 0 -> 88716 bytes po/pl/docs/okular/configure-backends.png | Bin 0 -> 40127 bytes po/pl/docs/okular/configure-editor.png | Bin 0 -> 52208 bytes po/pl/docs/okular/configure.png | Bin 0 -> 95722 bytes po/pl/docs/okular/embedded-files-bar.png | Bin 0 -> 5414 bytes po/pl/docs/okular/forms-bar.png | Bin 0 -> 6981 bytes po/pl/docs/okular/index.docbook | 3533 +++++++ po/pl/docs/okular/mainwindow.png | Bin 0 -> 92664 bytes po/pl/docs/okular/presentation.png | Bin 0 -> 25321 bytes po/pl/docs/okular/rating.png | Bin 0 -> 744 bytes po/pl/docs/okular/tool-ellipse-okular.png | Bin 0 -> 1100 bytes po/pl/docs/okular/tool-highlighter-okular.png | Bin 0 -> 1536 bytes po/pl/docs/okular/tool-ink-okular.png | Bin 0 -> 1710 bytes po/pl/docs/okular/tool-line-okular.png | Bin 0 -> 849 bytes po/pl/docs/okular/tool-note-inline-okular.png | Bin 0 -> 803 bytes po/pl/docs/okular/tool-note-okular.png | Bin 0 -> 973 bytes po/pl/docs/okular/tool-polygon-okular.png | Bin 0 -> 664 bytes po/pl/docs/okular/tool-stamp-okular.png | Bin 0 -> 1074 bytes po/pl/docs/okular/tool-underline-okular.png | Bin 0 -> 629 bytes po/pl/okular.po | 5824 +++++++++++ po/pl/okular_chm.po | 65 + po/pl/okular_comicbook.po | 66 + po/pl/okular_djvu.po | 141 + po/pl/okular_dvi.po | 776 ++ po/pl/okular_epub.po | 61 + po/pl/okular_fax.po | 46 + po/pl/okular_fictionbook.po | 85 + po/pl/okular_ghostview.po | 96 + po/pl/okular_kimgio.po | 75 + po/pl/okular_markdown.po | 55 + po/pl/okular_mobi.po | 65 + po/pl/okular_plucker.po | 48 + po/pl/okular_poppler.po | 235 + po/pl/okular_tiff.po | 29 + po/pl/okular_txt.po | 52 + po/pl/okular_xps.po | 60 + po/pl/org.kde.active.documentviewer.po | 81 + po/pt/docs/okular/index.docbook | 3385 +++++++ po/pt/docs/okular/man-okular.1.docbook | 208 + po/pt/okular.po | 5283 ++++++++++ po/pt/okular_chm.po | 43 + po/pt/okular_comicbook.po | 44 + po/pt/okular_djvu.po | 136 + po/pt/okular_dvi.po | 601 ++ po/pt/okular_epub.po | 51 + po/pt/okular_fax.po | 41 + po/pt/okular_fictionbook.po | 81 + po/pt/okular_ghostview.po | 93 + po/pt/okular_kimgio.po | 43 + po/pt/okular_markdown.po | 49 + po/pt/okular_mobi.po | 59 + po/pt/okular_plucker.po | 42 + po/pt/okular_poppler.po | 193 + po/pt/okular_tiff.po | 23 + po/pt/okular_txt.po | 46 + po/pt/okular_xps.po | 58 + po/pt/org.kde.active.documentviewer.po | 54 + .../docs/okular/annotation-properties.png | Bin 0 -> 27339 bytes po/pt_BR/docs/okular/annotations.png | Bin 0 -> 157230 bytes po/pt_BR/docs/okular/bookmark-management.png | Bin 0 -> 92367 bytes .../docs/okular/configure-annotations.png | Bin 0 -> 75159 bytes po/pt_BR/docs/okular/configure-backends.png | Bin 0 -> 39087 bytes po/pt_BR/docs/okular/configure-editor.png | Bin 0 -> 41786 bytes po/pt_BR/docs/okular/configure.png | Bin 0 -> 82781 bytes po/pt_BR/docs/okular/embedded-files-bar.png | Bin 0 -> 7237 bytes po/pt_BR/docs/okular/forms-bar.png | Bin 0 -> 7195 bytes po/pt_BR/docs/okular/index.docbook | 3878 ++++++++ po/pt_BR/docs/okular/mainwindow.png | Bin 0 -> 65796 bytes po/pt_BR/docs/okular/man-okular.1.docbook | 237 + po/pt_BR/docs/okular/presentation.png | Bin 0 -> 19792 bytes po/pt_BR/docs/okular/signatures-bar.png | Bin 0 -> 5499 bytes po/pt_BR/docs/okular/signatures-panel.png | Bin 0 -> 16383 bytes po/pt_BR/okular.po | 5314 ++++++++++ po/pt_BR/okular_chm.po | 63 + po/pt_BR/okular_comicbook.po | 62 + po/pt_BR/okular_djvu.po | 138 + po/pt_BR/okular_dvi.po | 599 ++ po/pt_BR/okular_epub.po | 57 + po/pt_BR/okular_fax.po | 48 + po/pt_BR/okular_fictionbook.po | 82 + po/pt_BR/okular_ghostview.po | 93 + po/pt_BR/okular_kimgio.po | 71 + po/pt_BR/okular_markdown.po | 54 + po/pt_BR/okular_mobi.po | 65 + po/pt_BR/okular_plucker.po | 47 + po/pt_BR/okular_poppler.po | 194 + po/pt_BR/okular_tiff.po | 28 + po/pt_BR/okular_txt.po | 51 + po/pt_BR/okular_xps.po | 59 + po/pt_BR/org.kde.active.documentviewer.po | 60 + po/ro/okular.po | 5690 +++++++++++ po/ro/okular_chm.po | 61 + po/ro/okular_comicbook.po | 54 + po/ro/okular_djvu.po | 134 + po/ro/okular_dvi.po | 583 ++ po/ro/okular_epub.po | 56 + po/ro/okular_fax.po | 45 + po/ro/okular_fictionbook.po | 81 + po/ro/okular_ghostview.po | 92 + po/ro/okular_kimgio.po | 74 + po/ro/okular_mobi.po | 65 + po/ro/okular_plucker.po | 47 + po/ro/okular_poppler.po | 224 + po/ro/okular_txt.po | 50 + po/ro/okular_xps.po | 59 + po/ro/org.kde.active.documentviewer.po | 72 + po/ru/docs/okular/annotation-properties.png | Bin 0 -> 8122 bytes po/ru/docs/okular/annotations.png | Bin 0 -> 77550 bytes po/ru/docs/okular/bookmark-management.png | Bin 0 -> 62206 bytes po/ru/docs/okular/configure-annotations.png | Bin 0 -> 30738 bytes po/ru/docs/okular/configure-backends.png | Bin 0 -> 15204 bytes po/ru/docs/okular/configure-editor.png | Bin 0 -> 17698 bytes po/ru/docs/okular/configure.png | Bin 0 -> 30190 bytes po/ru/docs/okular/embedded-files-bar.png | Bin 0 -> 3731 bytes po/ru/docs/okular/enhance-lowcontrast.png | Bin 0 -> 3714 bytes po/ru/docs/okular/enhance-shape.png | Bin 0 -> 3884 bytes po/ru/docs/okular/enhance-solid.png | Bin 0 -> 6140 bytes po/ru/docs/okular/enhance-thinline.png | Bin 0 -> 7796 bytes po/ru/docs/okular/forms-bar.png | Bin 0 -> 3939 bytes po/ru/docs/okular/mainwindow.png | Bin 0 -> 33236 bytes po/ru/docs/okular/man-okular.1.docbook | 237 + po/ru/docs/okular/presentation.png | Bin 0 -> 10524 bytes po/ru/docs/okular/rating.png | Bin 0 -> 681 bytes po/ru/docs/okular/tool-ellipse-okular.png | Bin 0 -> 1100 bytes po/ru/docs/okular/tool-highlighter-okular.png | Bin 0 -> 1536 bytes po/ru/docs/okular/tool-ink-okular.png | Bin 0 -> 1710 bytes po/ru/docs/okular/tool-line-okular.png | Bin 0 -> 849 bytes po/ru/docs/okular/tool-note-inline-okular.png | Bin 0 -> 803 bytes po/ru/docs/okular/tool-note-okular.png | Bin 0 -> 973 bytes po/ru/docs/okular/tool-polygon-okular.png | Bin 0 -> 664 bytes po/ru/docs/okular/tool-stamp-okular.png | Bin 0 -> 1068 bytes po/ru/docs/okular/tool-underline-okular.png | Bin 0 -> 629 bytes po/ru/okular.po | 5829 +++++++++++ po/ru/okular_chm.po | 67 + po/ru/okular_comicbook.po | 65 + po/ru/okular_djvu.po | 145 + po/ru/okular_dvi.po | 803 ++ po/ru/okular_epub.po | 61 + po/ru/okular_fax.po | 50 + po/ru/okular_fictionbook.po | 86 + po/ru/okular_ghostview.po | 97 + po/ru/okular_kimgio.po | 75 + po/ru/okular_markdown.po | 55 + po/ru/okular_mobi.po | 69 + po/ru/okular_plucker.po | 50 + po/ru/okular_poppler.po | 234 + po/ru/okular_tiff.po | 29 + po/ru/okular_txt.po | 54 + po/ru/okular_xps.po | 62 + po/ru/org.kde.active.documentviewer.po | 76 + po/sk/okular.po | 5702 +++++++++++ po/sk/okular_chm.po | 61 + po/sk/okular_comicbook.po | 58 + po/sk/okular_djvu.po | 106 + po/sk/okular_dvi.po | 572 ++ po/sk/okular_epub.po | 54 + po/sk/okular_fax.po | 43 + po/sk/okular_fictionbook.po | 80 + po/sk/okular_ghostview.po | 90 + po/sk/okular_kimgio.po | 68 + po/sk/okular_markdown.po | 52 + po/sk/okular_mobi.po | 63 + po/sk/okular_plucker.po | 44 + po/sk/okular_poppler.po | 208 + po/sk/okular_tiff.po | 26 + po/sk/okular_txt.po | 48 + po/sk/okular_xps.po | 56 + po/sk/org.kde.active.documentviewer.po | 79 + po/sl/okular.po | 5317 ++++++++++ po/sl/okular_chm.po | 65 + po/sl/okular_comicbook.po | 49 + po/sl/okular_djvu.po | 138 + po/sl/okular_dvi.po | 727 ++ po/sl/okular_epub.po | 56 + po/sl/okular_fax.po | 47 + po/sl/okular_fictionbook.po | 81 + po/sl/okular_ghostview.po | 93 + po/sl/okular_kimgio.po | 71 + po/sl/okular_markdown.po | 57 + po/sl/okular_mobi.po | 63 + po/sl/okular_plucker.po | 46 + po/sl/okular_poppler.po | 230 + po/sl/okular_tiff.po | 29 + po/sl/okular_txt.po | 51 + po/sl/okular_xps.po | 58 + po/sl/org.kde.active.documentviewer.po | 81 + po/sr/okular.po | 5414 +++++++++++ po/sr/okular_chm.po | 47 + po/sr/okular_comicbook.po | 48 + po/sr/okular_djvu.po | 103 + po/sr/okular_dvi.po | 570 ++ po/sr/okular_epub.po | 46 + po/sr/okular_fax.po | 36 + po/sr/okular_fictionbook.po | 75 + po/sr/okular_ghostview.po | 84 + po/sr/okular_kimgio.po | 48 + po/sr/okular_markdown.po | 55 + po/sr/okular_mobi.po | 51 + po/sr/okular_plucker.po | 40 + po/sr/okular_poppler.po | 194 + po/sr/okular_txt.po | 39 + po/sr/okular_xps.po | 40 + po/sv/docs/okular/configure.png | Bin 0 -> 24678 bytes po/sv/docs/okular/index.docbook | 4298 ++++++++ po/sv/docs/okular/man-okular.1.docbook | 237 + po/sv/okular.po | 5780 +++++++++++ po/sv/okular_chm.po | 62 + po/sv/okular_comicbook.po | 58 + po/sv/okular_djvu.po | 136 + po/sv/okular_dvi.po | 763 ++ po/sv/okular_epub.po | 56 + po/sv/okular_fax.po | 46 + po/sv/okular_fictionbook.po | 81 + po/sv/okular_ghostview.po | 92 + po/sv/okular_kimgio.po | 70 + po/sv/okular_markdown.po | 53 + po/sv/okular_mobi.po | 64 + po/sv/okular_plucker.po | 46 + po/sv/okular_poppler.po | 207 + po/sv/okular_tiff.po | 28 + po/sv/okular_txt.po | 50 + po/sv/okular_xps.po | 58 + po/sv/org.kde.active.documentviewer.po | 83 + po/tr/okular.po | 5840 +++++++++++ po/tr/okular_chm.po | 61 + po/tr/okular_comicbook.po | 60 + po/tr/okular_djvu.po | 138 + po/tr/okular_dvi.po | 583 ++ po/tr/okular_epub.po | 57 + po/tr/okular_fax.po | 47 + po/tr/okular_fictionbook.po | 82 + po/tr/okular_ghostview.po | 94 + po/tr/okular_kimgio.po | 69 + po/tr/okular_mobi.po | 63 + po/tr/okular_plucker.po | 47 + po/tr/okular_poppler.po | 218 + po/tr/okular_txt.po | 52 + po/tr/okular_xps.po | 59 + po/tr/org.kde.active.documentviewer.po | 81 + po/ug/okular.po | 5327 ++++++++++ po/ug/okular_chm.po | 43 + po/ug/okular_comicbook.po | 50 + po/ug/okular_djvu.po | 129 + po/ug/okular_dvi.po | 476 + po/ug/okular_epub.po | 43 + po/ug/okular_fax.po | 36 + po/ug/okular_fictionbook.po | 74 + po/ug/okular_ghostview.po | 77 + po/ug/okular_kimgio.po | 52 + po/ug/okular_mobi.po | 52 + po/ug/okular_plucker.po | 39 + po/ug/okular_poppler.po | 190 + po/ug/okular_txt.po | 38 + po/ug/okular_xps.po | 57 + po/ug/org.kde.active.documentviewer.po | 66 + po/uk/docs/okular/annotation-properties.png | Bin 0 -> 15842 bytes po/uk/docs/okular/annotations.png | Bin 0 -> 53343 bytes po/uk/docs/okular/bookmark-management.png | Bin 0 -> 47884 bytes po/uk/docs/okular/configure-annotations.png | Bin 0 -> 25713 bytes po/uk/docs/okular/configure-backends.png | Bin 0 -> 15673 bytes po/uk/docs/okular/configure-editor.png | Bin 0 -> 14596 bytes po/uk/docs/okular/configure.png | Bin 0 -> 37889 bytes po/uk/docs/okular/embedded-files-bar.png | Bin 0 -> 5124 bytes po/uk/docs/okular/forms-bar.png | Bin 0 -> 4833 bytes po/uk/docs/okular/index.docbook | 4265 ++++++++ po/uk/docs/okular/mainwindow.png | Bin 0 -> 30048 bytes po/uk/docs/okular/man-okular.1.docbook | 235 + po/uk/docs/okular/signatures-bar.png | Bin 0 -> 2924 bytes po/uk/docs/okular/signatures-panel.png | Bin 0 -> 9941 bytes po/uk/okular.po | 5863 +++++++++++ po/uk/okular_chm.po | 66 + po/uk/okular_comicbook.po | 61 + po/uk/okular_djvu.po | 139 + po/uk/okular_dvi.po | 761 ++ po/uk/okular_epub.po | 58 + po/uk/okular_fax.po | 48 + po/uk/okular_fictionbook.po | 84 + po/uk/okular_ghostview.po | 96 + po/uk/okular_kimgio.po | 73 + po/uk/okular_markdown.po | 56 + po/uk/okular_mobi.po | 65 + po/uk/okular_plucker.po | 49 + po/uk/okular_poppler.po | 234 + po/uk/okular_tiff.po | 31 + po/uk/okular_txt.po | 53 + po/uk/okular_xps.po | 61 + po/uk/org.kde.active.documentviewer.po | 86 + po/wa/okular.po | 5768 +++++++++++ po/wa/okular_chm.po | 59 + po/wa/okular_comicbook.po | 59 + po/wa/okular_djvu.po | 135 + po/wa/okular_epub.po | 56 + po/wa/okular_fax.po | 45 + po/wa/okular_fictionbook.po | 82 + po/wa/okular_ghostview.po | 89 + po/wa/okular_kimgio.po | 72 + po/wa/okular_mobi.po | 65 + po/wa/okular_plucker.po | 45 + po/wa/okular_poppler.po | 222 + po/wa/okular_xps.po | 57 + po/zh_CN/okular.po | 5182 ++++++++++ po/zh_CN/okular_chm.po | 42 + po/zh_CN/okular_comicbook.po | 49 + po/zh_CN/okular_djvu.po | 97 + po/zh_CN/okular_dvi.po | 538 + po/zh_CN/okular_epub.po | 49 + po/zh_CN/okular_fax.po | 38 + po/zh_CN/okular_fictionbook.po | 69 + po/zh_CN/okular_ghostview.po | 78 + po/zh_CN/okular_kimgio.po | 40 + po/zh_CN/okular_markdown.po | 53 + po/zh_CN/okular_mobi.po | 55 + po/zh_CN/okular_plucker.po | 33 + po/zh_CN/okular_poppler.po | 192 + po/zh_CN/okular_tiff.po | 28 + po/zh_CN/okular_txt.po | 42 + po/zh_CN/okular_xps.po | 35 + po/zh_CN/org.kde.active.documentviewer.po | 60 + po/zh_TW/okular.po | 5298 ++++++++++ po/zh_TW/okular_chm.po | 43 + po/zh_TW/okular_comicbook.po | 47 + po/zh_TW/okular_djvu.po | 98 + po/zh_TW/okular_dvi.po | 532 + po/zh_TW/okular_epub.po | 45 + po/zh_TW/okular_fax.po | 34 + po/zh_TW/okular_fictionbook.po | 71 + po/zh_TW/okular_ghostview.po | 78 + po/zh_TW/okular_kimgio.po | 43 + po/zh_TW/okular_markdown.po | 53 + po/zh_TW/okular_mobi.po | 50 + po/zh_TW/okular_plucker.po | 36 + po/zh_TW/okular_poppler.po | 192 + po/zh_TW/okular_txt.po | 38 + po/zh_TW/okular_xps.po | 36 + po/zh_TW/org.kde.active.documentviewer.po | 60 + shell/CMakeLists.txt | 35 + shell/main.cpp | 110 + shell/okular_main.cpp | 182 + shell/okular_main.h | 31 + shell/org.kde.okular.appdata.xml | 326 + shell/org.kde.okular.desktop | 174 + shell/shell.cpp | 852 ++ shell/shell.h | 198 + shell/shell.rc | 27 + shell/shellutils.cpp | 141 + shell/shellutils.h | 38 + 1891 files changed, 611479 insertions(+) create mode 100644 .clang-tidy create mode 100644 .git-blame-ignore-revs create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .krazy create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 COPYING.DOC create mode 100644 COPYING.LIB create mode 100644 Mainpage.dox create mode 100644 Messages.sh create mode 100644 Okular5Config.cmake.in create mode 100644 OkularConfigureChecks.cmake create mode 100644 README.clang-format create mode 100644 README.internals.png create mode 100644 TODO create mode 100644 _clang-format create mode 100644 aboutdata.h create mode 100644 autotests/CMakeLists.txt create mode 100644 autotests/addremoveannotationtest.cpp create mode 100644 autotests/annotationstest.cpp create mode 100644 autotests/annotationtoolbartest.cpp create mode 100644 autotests/calculatetexttest.cpp create mode 100644 autotests/closedialoghelper.cpp create mode 100644 autotests/closedialoghelper.h create mode 100644 autotests/data/1500x300.png create mode 100644 autotests/data/300x1500.png create mode 100644 autotests/data/RequestFullScreen.pdf create mode 100644 autotests/data/additionalFormActions.pdf create mode 100644 autotests/data/checkbox_ro.pdf create mode 100644 autotests/data/contents.epub create mode 100644 autotests/data/file1-docdata.xml create mode 100644 autotests/data/file1.pdf create mode 100644 autotests/data/file1.pdf.gz create mode 100644 autotests/data/file2.pdf create mode 100644 autotests/data/formSamples.pdf create mode 100644 autotests/data/formattest.pdf create mode 100644 autotests/data/imageSizes.md create mode 100644 autotests/data/kjsfunctionstest.pdf create mode 100644 autotests/data/pdf_with_links.pdf create mode 100644 autotests/data/pdf_with_signature.pdf create mode 100644 autotests/data/potato.jpg create mode 100644 autotests/data/protected.pdf create mode 100755 autotests/data/simple-multipage.pdf create mode 100755 autotests/data/simple-multipage.tex create mode 100644 autotests/data/simpleCalculate.pdf create mode 100644 autotests/data/synctextest.tex create mode 100644 autotests/data/tocreload.pdf create mode 100644 autotests/data/visibilitytest.pdf create mode 100644 autotests/documenttest.cpp create mode 100644 autotests/editannotationcontentstest.cpp create mode 100644 autotests/editdrawingtooldialogtest.cpp create mode 100644 autotests/editdrawingtooldialogtest.h create mode 100644 autotests/editformstest.cpp create mode 100644 autotests/formattest.cpp create mode 100644 autotests/generatorstest.cpp create mode 100644 autotests/kjsfunctionstest.cpp create mode 100644 autotests/mainshelltest.cpp create mode 100644 autotests/markdowntest.cpp create mode 100644 autotests/modifyannotationpropertiestest.cpp create mode 100644 autotests/parttest.cpp create mode 100644 autotests/searchtest.cpp create mode 100644 autotests/shelltest.cpp create mode 100644 autotests/signatureformtest.cpp create mode 100644 autotests/testingutils.cpp create mode 100644 autotests/testingutils.h create mode 100644 autotests/translateannotationtest.cpp create mode 100644 autotests/urldetecttest.cpp create mode 100644 autotests/visibilitytest.cpp create mode 100644 cmake/modules/COPYING-CMAKE-SCRIPTS create mode 100644 cmake/modules/FindCHM.cmake create mode 100644 cmake/modules/FindDiscount.cmake create mode 100644 cmake/modules/FindDjVuLibre.cmake create mode 100644 cmake/modules/FindEPub.cmake create mode 100644 cmake/modules/FindLibSpectre.cmake create mode 100644 cmake/modules/FindLibZip.cmake create mode 100644 conf/okular.kcfg create mode 100644 conf/okular_core.kcfg create mode 100644 conf/settings.kcfgc create mode 100644 conf/settings_core.kcfgc create mode 100644 conf/settings_mobile.kcfgc create mode 100644 config-okular.h.cmake create mode 100644 core/action.cpp create mode 100644 core/action.h create mode 100644 core/annotations.cpp create mode 100644 core/annotations.h create mode 100644 core/annotations_p.h create mode 100644 core/area.cpp create mode 100644 core/area.h create mode 100644 core/audioplayer.cpp create mode 100644 core/audioplayer.h create mode 100644 core/audioplayer_p.h create mode 100644 core/bookmarkmanager.cpp create mode 100644 core/bookmarkmanager.h create mode 100644 core/chooseenginedialog.cpp create mode 100644 core/chooseenginedialog_p.h create mode 100644 core/chooseenginewidget.ui create mode 100644 core/debug.cpp create mode 100644 core/debug_p.h create mode 100644 core/document.cpp create mode 100644 core/document.h create mode 100644 core/document_p.h create mode 100644 core/documentcommands.cpp create mode 100644 core/documentcommands_p.h create mode 100644 core/fileprinter.cpp create mode 100644 core/fileprinter.h create mode 100644 core/fontinfo.cpp create mode 100644 core/fontinfo.h create mode 100644 core/form.cpp create mode 100644 core/form.h create mode 100644 core/form_p.h create mode 100644 core/generator.cpp create mode 100644 core/generator.h create mode 100644 core/generator_p.cpp create mode 100644 core/generator_p.h create mode 100644 core/global.h create mode 100644 core/misc.cpp create mode 100644 core/misc.h create mode 100644 core/movie.cpp create mode 100644 core/movie.h create mode 100644 core/observer.cpp create mode 100644 core/observer.h create mode 100644 core/okularGenerator.desktop create mode 100644 core/page.cpp create mode 100644 core/page.h create mode 100644 core/page_p.h create mode 100644 core/pagecontroller.cpp create mode 100644 core/pagecontroller_p.h create mode 100644 core/pagesize.cpp create mode 100644 core/pagesize.h create mode 100644 core/pagetransition.cpp create mode 100644 core/pagetransition.h create mode 100644 core/printoptionswidget.cpp create mode 100644 core/printoptionswidget.h create mode 100644 core/rotationjob.cpp create mode 100644 core/rotationjob_p.h create mode 100644 core/script/builtin.js create mode 100644 core/script/builtin.qrc create mode 100644 core/script/event.cpp create mode 100644 core/script/event_p.h create mode 100644 core/script/executor_kjs.cpp create mode 100644 core/script/executor_kjs_p.h create mode 100644 core/script/kjs_app.cpp create mode 100644 core/script/kjs_app_p.h create mode 100644 core/script/kjs_console.cpp create mode 100644 core/script/kjs_console_p.h create mode 100644 core/script/kjs_data.cpp create mode 100644 core/script/kjs_data_p.h create mode 100644 core/script/kjs_display.cpp create mode 100644 core/script/kjs_display_p.h create mode 100644 core/script/kjs_document.cpp create mode 100644 core/script/kjs_document_p.h create mode 100644 core/script/kjs_event.cpp create mode 100644 core/script/kjs_event_p.h create mode 100644 core/script/kjs_field.cpp create mode 100644 core/script/kjs_field_p.h create mode 100644 core/script/kjs_fullscreen.cpp create mode 100644 core/script/kjs_fullscreen_p.h create mode 100644 core/script/kjs_ocg.cpp create mode 100644 core/script/kjs_ocg_p.h create mode 100644 core/script/kjs_spell.cpp create mode 100644 core/script/kjs_spell_p.h create mode 100644 core/script/kjs_util.cpp create mode 100644 core/script/kjs_util_p.h create mode 100644 core/scripter.cpp create mode 100644 core/scripter.h create mode 100644 core/signatureutils.cpp create mode 100644 core/signatureutils.h create mode 100644 core/sound.cpp create mode 100644 core/sound.h create mode 100644 core/sourcereference.cpp create mode 100644 core/sourcereference.h create mode 100644 core/sourcereference_p.h create mode 100644 core/synctex/patches/00-disable-SYNCTEX_INLINE.diff create mode 100644 core/synctex/patches/04-gcc-specify-printf-format.diff create mode 100644 core/synctex/patches/06-mingw-_synctex_error.diff create mode 100644 core/synctex/patches/08-fix_cpp_comments.diff create mode 100644 core/synctex/patches/10-fix-typo.diff create mode 100644 core/synctex/patches/11-fix-unused-parameters-warnings.diff create mode 100644 core/synctex/patches/12-omit-no-file-warning.diff create mode 100644 core/synctex/patches/13-fix-Wundef-warnings.diff create mode 100644 core/synctex/patches/14-fix-misc-compiler-warnings.diff create mode 100644 core/synctex/patches/15-prevent-leaks-and-segfault.diff create mode 100644 core/synctex/patches/16-use-windows-ansi-api-path-find.diff create mode 100644 core/synctex/patches/series create mode 100644 core/synctex/synctex_parser.c create mode 100644 core/synctex/synctex_parser.h create mode 100644 core/synctex/synctex_parser_advanced.h create mode 100644 core/synctex/synctex_parser_local.h create mode 100644 core/synctex/synctex_parser_readme.md create mode 100644 core/synctex/synctex_parser_utils.c create mode 100644 core/synctex/synctex_parser_utils.h create mode 100644 core/synctex/synctex_parser_version.txt create mode 100644 core/textdocumentgenerator.cpp create mode 100644 core/textdocumentgenerator.h create mode 100644 core/textdocumentgenerator_p.h create mode 100644 core/textdocumentsettings.cpp create mode 100644 core/textdocumentsettings.h create mode 100644 core/textdocumentsettings_p.h create mode 100644 core/texteditors_p.h create mode 100644 core/textpage.cpp create mode 100644 core/textpage.h create mode 100644 core/textpage_p.h create mode 100644 core/tile.h create mode 100644 core/tilesmanager.cpp create mode 100644 core/tilesmanager_p.h create mode 100644 core/utils.cpp create mode 100644 core/utils.h create mode 100644 core/utils_p.h create mode 100644 core/view.cpp create mode 100644 core/view.h create mode 100644 core/view_p.h create mode 100644 doc/CMakeLists.txt create mode 100644 doc/annotation-properties.png create mode 100644 doc/annotations.png create mode 100644 doc/bookmark-management.png create mode 100644 doc/bookmarks.png create mode 100644 doc/configure-annotations.png create mode 100644 doc/configure-backends.png create mode 100644 doc/configure-editor.png create mode 100644 doc/configure.png create mode 100644 doc/embedded-files-bar.png create mode 100644 doc/enhance-lowcontrast.png create mode 100644 doc/enhance-shape.png create mode 100644 doc/enhance-solid.png create mode 100644 doc/enhance-thinline.png create mode 100644 doc/forms-bar.png create mode 100644 doc/index.docbook create mode 100644 doc/mainwindow.png create mode 100644 doc/man-okular.1.docbook create mode 100644 doc/presentation.png create mode 100644 doc/signatures-bar.png create mode 100644 doc/signatures-panel.png create mode 100644 doc/tool-draw-arrow.png create mode 100644 doc/tool-draw-ellipse.png create mode 100644 doc/tool-draw-freehand.png create mode 100644 doc/tool-draw-highlight.png create mode 100644 doc/tool-draw-line.png create mode 100644 doc/tool-draw-polyline.png create mode 100644 doc/tool-draw-rectangle.png create mode 100644 doc/tool-edit-comment.png create mode 100644 doc/tool-edit-line-width.png create mode 100644 doc/tool-edit-opacity.png create mode 100644 doc/tool-favorite.png create mode 100644 doc/tool-fill-color.png create mode 100644 doc/tool-font-face.png create mode 100644 doc/tool-format-text-color.png create mode 100644 doc/tool-format-text-strikethrough.png create mode 100644 doc/tool-format-text-underline-squiggle.png create mode 100644 doc/tool-format-text-underline.png create mode 100644 doc/tool-note.png create mode 100644 doc/tool-pin.png create mode 100644 doc/tool-settings-configure.png create mode 100644 doc/tool-tag.png create mode 100644 doc/tool-tool-text.png create mode 100644 doc/tool-window-pin.png create mode 100644 generators/CMakeLists.txt create mode 100644 generators/chm/CMakeLists.txt create mode 100644 generators/chm/Messages.sh create mode 100644 generators/chm/autotests/chmgeneratortest.cpp create mode 100644 generators/chm/autotests/data/test.chm create mode 100644 generators/chm/generator_chm.cpp create mode 100644 generators/chm/generator_chm.h create mode 100644 generators/chm/kio-msits/CMakeLists.txt create mode 100644 generators/chm/kio-msits/kio_mits_debug.cpp create mode 100644 generators/chm/kio-msits/kio_mits_debug.h create mode 100644 generators/chm/kio-msits/ms-its.protocol create mode 100644 generators/chm/kio-msits/msits.cpp create mode 100644 generators/chm/kio-msits/msits.h create mode 100644 generators/chm/lib/bitfiddle.h create mode 100644 generators/chm/lib/ebook.cpp create mode 100644 generators/chm/lib/ebook.h create mode 100644 generators/chm/lib/ebook_chm.cpp create mode 100644 generators/chm/lib/ebook_chm.h create mode 100644 generators/chm/lib/ebook_chm_encoding.cpp create mode 100644 generators/chm/lib/ebook_chm_encoding.h create mode 100644 generators/chm/lib/ebook_epub.cpp create mode 100644 generators/chm/lib/ebook_epub.h create mode 100644 generators/chm/lib/ebook_search.cpp create mode 100644 generators/chm/lib/ebook_search.h create mode 100644 generators/chm/lib/ebook_url.h create mode 100644 generators/chm/lib/helper_entitydecoder.cpp create mode 100644 generators/chm/lib/helper_entitydecoder.h create mode 100644 generators/chm/lib/helper_search_index.cpp create mode 100644 generators/chm/lib/helper_search_index.h create mode 100644 generators/chm/lib/helperxmlhandler_epubcontainer.cpp create mode 100644 generators/chm/lib/helperxmlhandler_epubcontainer.h create mode 100644 generators/chm/lib/helperxmlhandler_epubcontent.cpp create mode 100644 generators/chm/lib/helperxmlhandler_epubcontent.h create mode 100644 generators/chm/lib/helperxmlhandler_epubtoc.cpp create mode 100644 generators/chm/lib/helperxmlhandler_epubtoc.h create mode 100644 generators/chm/lib/libchmurlfactory.h create mode 100644 generators/chm/libokularGenerator_chmlib.json create mode 100755 generators/chm/okularApplication_chm.desktop create mode 100644 generators/chm/okularChm.desktop create mode 100644 generators/chm/org.kde.mobile.okular_chm.desktop create mode 100644 generators/chm/org.kde.okular-chm.metainfo.xml create mode 100644 generators/comicbook/CMakeLists.txt create mode 100755 generators/comicbook/Messages.sh create mode 100644 generators/comicbook/autotests/comicbooktest.cpp create mode 100644 generators/comicbook/autotests/data/rotated_cb.cbz create mode 100644 generators/comicbook/debug_comicbook.h create mode 100644 generators/comicbook/directory.cpp create mode 100644 generators/comicbook/directory.h create mode 100644 generators/comicbook/document.cpp create mode 100644 generators/comicbook/document.h create mode 100644 generators/comicbook/generator_comicbook.cpp create mode 100644 generators/comicbook/generator_comicbook.h create mode 100644 generators/comicbook/libokularGenerator_comicbook.json create mode 100755 generators/comicbook/okularApplication_comicbook.desktop create mode 100644 generators/comicbook/okularComicbook.desktop create mode 100644 generators/comicbook/org.kde.mobile.okular_comicbook.desktop create mode 100644 generators/comicbook/org.kde.okular-comicbook.metainfo.xml create mode 100644 generators/comicbook/qnatsort.cpp create mode 100644 generators/comicbook/qnatsort.h create mode 100644 generators/comicbook/unrar.cpp create mode 100644 generators/comicbook/unrar.h create mode 100644 generators/comicbook/unrarflavours.cpp create mode 100644 generators/comicbook/unrarflavours.h create mode 100644 generators/djvu/CMakeLists.txt create mode 100644 generators/djvu/Messages.sh create mode 100644 generators/djvu/TODO create mode 100644 generators/djvu/generator_djvu.cpp create mode 100644 generators/djvu/generator_djvu.h create mode 100644 generators/djvu/kdjvu.cpp create mode 100644 generators/djvu/kdjvu.h create mode 100644 generators/djvu/libokularGenerator_djvu.json create mode 100755 generators/djvu/okularApplication_djvu.desktop create mode 100644 generators/djvu/okularDjvu.desktop create mode 100644 generators/djvu/org.kde.mobile.okular_djvu.desktop create mode 100644 generators/djvu/org.kde.okular-djvu.metainfo.xml create mode 100644 generators/dvi/CMakeLists.txt create mode 100644 generators/dvi/Messages.sh create mode 100644 generators/dvi/TeXFont.cpp create mode 100644 generators/dvi/TeXFont.h create mode 100644 generators/dvi/TeXFontDefinition.cpp create mode 100644 generators/dvi/TeXFontDefinition.h create mode 100644 generators/dvi/TeXFont_PFB.cpp create mode 100644 generators/dvi/TeXFont_PFB.h create mode 100644 generators/dvi/TeXFont_PK.cpp create mode 100644 generators/dvi/TeXFont_PK.h create mode 100644 generators/dvi/TeXFont_TFM.cpp create mode 100644 generators/dvi/TeXFont_TFM.h create mode 100644 generators/dvi/anchor.h create mode 100644 generators/dvi/bigEndianByteReader.cpp create mode 100644 generators/dvi/bigEndianByteReader.h create mode 100644 generators/dvi/config.h create mode 100644 generators/dvi/debug_dvi.h create mode 100644 generators/dvi/dvi.h create mode 100644 generators/dvi/dviFile.cpp create mode 100644 generators/dvi/dviFile.h create mode 100644 generators/dvi/dviPageInfo.cpp create mode 100644 generators/dvi/dviPageInfo.h create mode 100644 generators/dvi/dviRenderer.cpp create mode 100644 generators/dvi/dviRenderer.h create mode 100644 generators/dvi/dviRenderer_dr.cpp create mode 100644 generators/dvi/dviRenderer_draw.cpp create mode 100644 generators/dvi/dviRenderer_prescan.cpp create mode 100644 generators/dvi/dviexport.cpp create mode 100644 generators/dvi/dviexport.h create mode 100644 generators/dvi/dvisourcesplitter.cpp create mode 100644 generators/dvi/dvisourcesplitter.h create mode 100644 generators/dvi/fontEncoding.cpp create mode 100644 generators/dvi/fontEncoding.h create mode 100644 generators/dvi/fontEncodingPool.cpp create mode 100644 generators/dvi/fontEncodingPool.h create mode 100644 generators/dvi/fontMap.cpp create mode 100644 generators/dvi/fontMap.h create mode 100644 generators/dvi/fontpool.cpp create mode 100644 generators/dvi/fontpool.h create mode 100644 generators/dvi/generator_dvi.cpp create mode 100644 generators/dvi/generator_dvi.h create mode 100644 generators/dvi/glyph.cpp create mode 100644 generators/dvi/glyph.h create mode 100644 generators/dvi/hyperlink.h create mode 100644 generators/dvi/length.cpp create mode 100644 generators/dvi/length.h create mode 100644 generators/dvi/libokularGenerator_dvi.json create mode 100755 generators/dvi/okularApplication_dvi.desktop create mode 100644 generators/dvi/okularDvi.desktop create mode 100644 generators/dvi/org.kde.mobile.okular_dvi.desktop create mode 100644 generators/dvi/org.kde.okular-dvi.metainfo.xml create mode 100644 generators/dvi/pageNumber.h create mode 100644 generators/dvi/pageSize.cpp create mode 100644 generators/dvi/pageSize.h create mode 100644 generators/dvi/prebookmark.h create mode 100644 generators/dvi/psgs.cpp create mode 100644 generators/dvi/psgs.h create mode 100644 generators/dvi/psheader.cpp create mode 100644 generators/dvi/simplePageSize.cpp create mode 100644 generators/dvi/simplePageSize.h create mode 100644 generators/dvi/special.cpp create mode 100644 generators/dvi/textBox.h create mode 100644 generators/dvi/util.cpp create mode 100644 generators/dvi/vf.cpp create mode 100644 generators/dvi/xdvi.h create mode 100644 generators/epub/CMakeLists.txt create mode 100755 generators/epub/Messages.sh create mode 100644 generators/epub/README create mode 100644 generators/epub/autotests/data/test.epub create mode 100644 generators/epub/autotests/epubgeneratortest.cpp create mode 100644 generators/epub/converter.cpp create mode 100644 generators/epub/converter.h create mode 100644 generators/epub/data/CMakeLists.txt create mode 100644 generators/epub/data/okular-epub-movie.png create mode 100644 generators/epub/data/okular-epub-sound-icon.png create mode 100644 generators/epub/epubdocument.cpp create mode 100644 generators/epub/epubdocument.h create mode 100644 generators/epub/generator_epub.cpp create mode 100644 generators/epub/generator_epub.h create mode 100644 generators/epub/libokularGenerator_epub.json create mode 100755 generators/epub/okularApplication_epub.desktop create mode 100644 generators/epub/okularEPub.desktop create mode 100644 generators/epub/org.kde.mobile.okular_epub.desktop create mode 100644 generators/epub/org.kde.okular-epub.metainfo.xml create mode 100644 generators/fax/CMakeLists.txt create mode 100644 generators/fax/Messages.sh create mode 100644 generators/fax/fax_debug.cpp create mode 100644 generators/fax/fax_debug.h create mode 100644 generators/fax/faxdocument.cpp create mode 100644 generators/fax/faxdocument.h create mode 100644 generators/fax/faxexpand.cpp create mode 100644 generators/fax/faxexpand.h create mode 100644 generators/fax/faxinit.cpp create mode 100644 generators/fax/generator_fax.cpp create mode 100644 generators/fax/generator_fax.h create mode 100644 generators/fax/libokularGenerator_fax.json create mode 100755 generators/fax/okularApplication_fax.desktop create mode 100644 generators/fax/okularFax.desktop create mode 100644 generators/fax/org.kde.mobile.okular_fax.desktop create mode 100644 generators/fax/org.kde.okular-fax.metainfo.xml create mode 100644 generators/fictionbook/16-apps-okular-fb2.png create mode 100644 generators/fictionbook/32-apps-okular-fb2.png create mode 100644 generators/fictionbook/48-apps-okular-fb2.png create mode 100644 generators/fictionbook/CMakeLists.txt create mode 100644 generators/fictionbook/Messages.sh create mode 100644 generators/fictionbook/converter.cpp create mode 100644 generators/fictionbook/converter.h create mode 100644 generators/fictionbook/document.cpp create mode 100644 generators/fictionbook/document.h create mode 100644 generators/fictionbook/generator_fb.cpp create mode 100644 generators/fictionbook/generator_fb.h create mode 100644 generators/fictionbook/hi32-app-okular-fb2.svg create mode 100644 generators/fictionbook/libokularGenerator_fb.json create mode 100755 generators/fictionbook/okularApplication_fb.desktop create mode 100644 generators/fictionbook/okularFb.desktop create mode 100644 generators/fictionbook/org.kde.mobile.okular_fb.desktop create mode 100644 generators/fictionbook/org.kde.okular-fb.metainfo.xml create mode 100644 generators/kimgio/CMakeLists.txt create mode 100644 generators/kimgio/Messages.sh create mode 100644 generators/kimgio/generator_kimgio.cpp create mode 100644 generators/kimgio/generator_kimgio.h create mode 100644 generators/kimgio/libokularGenerator_kimgio.json create mode 100755 generators/kimgio/okularApplication_kimgio.desktop create mode 100644 generators/kimgio/okularKimgio.desktop create mode 100755 generators/kimgio/org.kde.mobile.okular_kimgio.desktop create mode 100644 generators/kimgio/org.kde.okular-kimgio.metainfo.xml create mode 100644 generators/kimgio/tests/data/testExifOrientation-0.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-0mirror.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-180.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-180mirror.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-270.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-270mirror.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-90.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-90mirror.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-noexif.jpg create mode 100644 generators/kimgio/tests/data/testExifOrientation-unspecified.jpg create mode 100644 generators/kimgio/tests/kimgiotest.cpp create mode 100644 generators/markdown/CMakeLists.txt create mode 100644 generators/markdown/Messages.sh create mode 100644 generators/markdown/converter.cpp create mode 100644 generators/markdown/converter.h create mode 100644 generators/markdown/debug_md.h create mode 100644 generators/markdown/generator_md.cpp create mode 100644 generators/markdown/generator_md.h create mode 100644 generators/markdown/libokularGenerator_md.json create mode 100644 generators/markdown/okularApplication_md.desktop create mode 100644 generators/markdown/okularMd.desktop create mode 100644 generators/markdown/org.kde.mobile.okular_md.desktop create mode 100644 generators/markdown/org.kde.okular-md.metainfo.xml create mode 100644 generators/mobipocket/CMakeLists.txt create mode 100755 generators/mobipocket/Messages.sh create mode 100644 generators/mobipocket/converter.cpp create mode 100644 generators/mobipocket/converter.h create mode 100644 generators/mobipocket/generator_mobi.cpp create mode 100644 generators/mobipocket/generator_mobi.h create mode 100644 generators/mobipocket/libokularGenerator_mobi.json create mode 100644 generators/mobipocket/mobidocument.cpp create mode 100644 generators/mobipocket/mobidocument.h create mode 100755 generators/mobipocket/okularApplication_mobi.desktop create mode 100644 generators/mobipocket/okularMobi.desktop create mode 100755 generators/mobipocket/org.kde.mobile.okular_mobi.desktop create mode 100644 generators/mobipocket/org.kde.okular-mobipocket.metainfo.xml create mode 100644 generators/plucker/CMakeLists.txt create mode 100644 generators/plucker/Messages.sh create mode 100644 generators/plucker/generator_plucker.cpp create mode 100644 generators/plucker/generator_plucker.h create mode 100644 generators/plucker/libokularGenerator_plucker.json create mode 100755 generators/plucker/okularApplication_plucker.desktop create mode 100644 generators/plucker/okularPlucker.desktop create mode 100644 generators/plucker/org.kde.mobile.okular_plucker.desktop create mode 100644 generators/plucker/org.kde.okular-plucker.metainfo.xml create mode 100644 generators/plucker/unpluck/config.cpp create mode 100644 generators/plucker/unpluck/image.cpp create mode 100644 generators/plucker/unpluck/image.h create mode 100644 generators/plucker/unpluck/qunpluck.cpp create mode 100644 generators/plucker/unpluck/qunpluck.h create mode 100644 generators/plucker/unpluck/unpluck.cpp create mode 100644 generators/plucker/unpluck/unpluck.h create mode 100644 generators/plucker/unpluck/unpluckint.h create mode 100644 generators/plucker/unpluck/util.cpp create mode 100644 generators/poppler/CMakeLists.txt create mode 100644 generators/poppler/Messages.sh create mode 100644 generators/poppler/annots.cpp create mode 100644 generators/poppler/annots.h create mode 100644 generators/poppler/conf/CMakeLists.txt create mode 100644 generators/poppler/conf/pdfsettings.kcfg create mode 100644 generators/poppler/conf/pdfsettings.kcfgc create mode 100644 generators/poppler/conf/pdfsettingswidget.ui create mode 100644 generators/poppler/config-okular-poppler.h.cmake create mode 100644 generators/poppler/debug_pdf.h create mode 100644 generators/poppler/formfields.cpp create mode 100644 generators/poppler/formfields.h create mode 100644 generators/poppler/generator_pdf.cpp create mode 100644 generators/poppler/generator_pdf.h create mode 100644 generators/poppler/libokularGenerator_poppler.json create mode 100755 generators/poppler/okularApplication_pdf.desktop create mode 100644 generators/poppler/okularPoppler.desktop create mode 100644 generators/poppler/org.kde.mobile.okular_pdf.desktop create mode 100644 generators/poppler/org.kde.okular-poppler.metainfo.xml create mode 100644 generators/poppler/pdfsignatureutils.cpp create mode 100644 generators/poppler/pdfsignatureutils.h create mode 100644 generators/poppler/popplerembeddedfile.h create mode 100644 generators/spectre/16-apps-okular-gv.png create mode 100644 generators/spectre/32-apps-okular-gv.png create mode 100644 generators/spectre/CMakeLists.txt create mode 100644 generators/spectre/DESIGN create mode 100644 generators/spectre/Messages.sh create mode 100644 generators/spectre/conf/CMakeLists.txt create mode 100644 generators/spectre/conf/gssettings.kcfg create mode 100644 generators/spectre/conf/gssettings.kcfgc create mode 100644 generators/spectre/conf/gssettingswidget.ui create mode 100644 generators/spectre/generator_ghostview.cpp create mode 100644 generators/spectre/generator_ghostview.h create mode 100644 generators/spectre/libokularGenerator_ghostview.json create mode 100755 generators/spectre/okularApplication_ghostview.desktop create mode 100644 generators/spectre/okularGhostview.desktop create mode 100644 generators/spectre/org.kde.mobile.okular_ghostview.desktop create mode 100644 generators/spectre/org.kde.okular-spectre.metainfo.xml create mode 100644 generators/spectre/rendererthread.cpp create mode 100644 generators/spectre/rendererthread.h create mode 100644 generators/spectre/spectre_debug.cpp create mode 100644 generators/spectre/spectre_debug.h create mode 100644 generators/tiff/CMakeLists.txt create mode 100644 generators/tiff/Messages.sh create mode 100644 generators/tiff/generator_tiff.cpp create mode 100644 generators/tiff/generator_tiff.h create mode 100644 generators/tiff/libokularGenerator_tiff.json create mode 100755 generators/tiff/okularApplication_tiff.desktop create mode 100644 generators/tiff/okularTiff.desktop create mode 100644 generators/tiff/org.kde.mobile.okular_tiff.desktop create mode 100644 generators/tiff/org.kde.okular-tiff.metainfo.xml create mode 100644 generators/txt/CMakeLists.txt create mode 100644 generators/txt/Messages.sh create mode 100644 generators/txt/converter.cpp create mode 100644 generators/txt/converter.h create mode 100644 generators/txt/debug_txt.h create mode 100644 generators/txt/document.cpp create mode 100644 generators/txt/document.h create mode 100644 generators/txt/generator_txt.cpp create mode 100644 generators/txt/generator_txt.h create mode 100644 generators/txt/libokularGenerator_txt.json create mode 100644 generators/txt/okularApplication_txt.desktop create mode 100644 generators/txt/okularTxt.desktop create mode 100644 generators/txt/org.kde.mobile.okular_txt.desktop create mode 100644 generators/txt/org.kde.okular-txt.metainfo.xml create mode 100644 generators/xps/.emacs-dirvars create mode 100644 generators/xps/CMakeLists.txt create mode 100644 generators/xps/Messages.sh create mode 100644 generators/xps/generator_xps.cpp create mode 100644 generators/xps/generator_xps.h create mode 100644 generators/xps/libokularGenerator_xps.json create mode 100755 generators/xps/okularApplication_xps.desktop create mode 100644 generators/xps/okularXps.desktop create mode 100644 generators/xps/org.kde.mobile.okular_xps.desktop create mode 100644 generators/xps/org.kde.okular-xps.metainfo.xml create mode 100755 hooks/pre-commit create mode 100644 icons/128-apps-okular.png create mode 100644 icons/150-apps-okular.png create mode 100644 icons/16-apps-okular.png create mode 100644 icons/22-apps-okular.png create mode 100644 icons/310-apps-okular.png create mode 100644 icons/32-apps-okular.png create mode 100644 icons/44-apps-okular.png create mode 100644 icons/48-apps-okular.png create mode 100644 icons/64-apps-okular.png create mode 100644 icons/CMakeLists.txt create mode 100644 icons/hisc-apps-okular.svgz create mode 100644 icons/small/hi16-apps-okular.svgz create mode 100644 icons/small/hi22-apps-okular.svgz create mode 100644 interfaces/configinterface.h create mode 100644 interfaces/guiinterface.h create mode 100644 interfaces/printinterface.h create mode 100644 interfaces/saveinterface.h create mode 100644 interfaces/viewerinterface.h create mode 100644 kdocumentviewer.h create mode 100644 metainfo.yaml create mode 100644 mobile/CMakeLists.txt create mode 100644 mobile/android/AndroidManifest.xml create mode 100644 mobile/android/res/drawable/icon.png create mode 100644 mobile/android/res/values/libs.xml create mode 100644 mobile/android/res/values/strings.xml create mode 100644 mobile/android/src/OpenFileActivity.java create mode 100644 mobile/app/CMakeLists.txt create mode 100644 mobile/app/Messages.sh create mode 100644 mobile/app/android.cpp create mode 100644 mobile/app/android.h create mode 100644 mobile/app/app.qrc create mode 100644 mobile/app/main.cpp create mode 100644 mobile/app/org.kde.okular.kirigami.appdata.xml create mode 100644 mobile/app/package/contents/ui/Bookmarks.qml create mode 100644 mobile/app/package/contents/ui/MainView.qml create mode 100644 mobile/app/package/contents/ui/OkularDrawer.qml create mode 100644 mobile/app/package/contents/ui/TableOfContents.qml create mode 100644 mobile/app/package/contents/ui/Thumbnails.qml create mode 100644 mobile/app/package/contents/ui/ThumbnailsBase.qml create mode 100644 mobile/app/package/contents/ui/TreeDelegate.qml create mode 100644 mobile/app/package/contents/ui/main.qml create mode 100644 mobile/app/package/metadata.desktop create mode 100644 mobile/components/CMakeLists.txt create mode 100644 mobile/components/DocumentView.qml create mode 100644 mobile/components/Messages.sh create mode 100644 mobile/components/documentitem.cpp create mode 100644 mobile/components/documentitem.h create mode 100644 mobile/components/okularplugin.cpp create mode 100644 mobile/components/okularplugin.h create mode 100644 mobile/components/okularsingleton.cpp create mode 100644 mobile/components/okularsingleton.h create mode 100644 mobile/components/pageitem.cpp create mode 100644 mobile/components/pageitem.h create mode 100644 mobile/components/private/PageView.qml create mode 100644 mobile/components/qmldir create mode 100644 mobile/components/settings.h create mode 100644 mobile/components/test.qml create mode 100644 mobile/components/testDocumentView.qml create mode 100644 mobile/components/thumbnailitem.cpp create mode 100644 mobile/components/thumbnailitem.h create mode 100644 okular.categories create mode 100644 okular.upd create mode 100644 okular_part.desktop create mode 100644 part/CMakeLists.txt create mode 100644 part/annotationactionhandler.cpp create mode 100644 part/annotationactionhandler.h create mode 100644 part/annotationmodel.cpp create mode 100644 part/annotationmodel.h create mode 100644 part/annotationpopup.cpp create mode 100644 part/annotationpopup.h create mode 100644 part/annotationpropertiesdialog.cpp create mode 100644 part/annotationpropertiesdialog.h create mode 100644 part/annotationproxymodels.cpp create mode 100644 part/annotationproxymodels.h create mode 100644 part/annotationtools.cpp create mode 100644 part/annotationtools.h create mode 100644 part/annotationwidgets.cpp create mode 100644 part/annotationwidgets.h create mode 100644 part/annotwindow.cpp create mode 100644 part/annotwindow.h create mode 100644 part/bookmarklist.cpp create mode 100644 part/bookmarklist.h create mode 100644 part/certificateviewer.cpp create mode 100644 part/certificateviewer.h create mode 100644 part/data/CMakeLists.txt create mode 100644 part/data/README.Icons create mode 100644 part/data/checkmark.png create mode 100644 part/data/circle.png create mode 100644 part/data/comment.png create mode 100644 part/data/cross.png create mode 100644 part/data/drawingtools.xml create mode 100644 part/data/help.png create mode 100644 part/data/insert.png create mode 100644 part/data/key.png create mode 100644 part/data/newparagraph.png create mode 100644 part/data/note.png create mode 100644 part/data/okular.knsrc create mode 100644 part/data/paperclip.png create mode 100644 part/data/paragraph.png create mode 100644 part/data/pushpin.png create mode 100644 part/data/rightarrow.png create mode 100644 part/data/rightpointer.png create mode 100644 part/data/sources/checkmark.svgz create mode 100644 part/data/sources/circle.svgz create mode 100644 part/data/sources/comment.svgz create mode 100644 part/data/sources/cross.svgz create mode 100644 part/data/sources/ghns.svg create mode 100644 part/data/sources/help.svgz create mode 100644 part/data/sources/insert.svgz create mode 100644 part/data/sources/key.svgz create mode 100644 part/data/sources/newparagraph.svgz create mode 100644 part/data/sources/note.svgz create mode 100644 part/data/sources/paragraph.svgz create mode 100644 part/data/sources/rightarrow.svgz create mode 100644 part/data/sources/rightpointer.svgz create mode 100644 part/data/sources/star.svgz create mode 100644 part/data/sources/tool-base-okular.svgz create mode 100644 part/data/sources/tool-ellipse-okular.svgz create mode 100644 part/data/sources/tool-highlighter-okular-colorizable.svgz create mode 100644 part/data/sources/tool-highlighter-okular.svgz create mode 100644 part/data/sources/tool-ink-okular-colorizable.svgz create mode 100644 part/data/sources/tool-ink-okular.svgz create mode 100644 part/data/sources/tool-line-okular.svgz create mode 100644 part/data/sources/tool-note-inline-okular-colorizable.svgz create mode 100644 part/data/sources/tool-note-inline-okular.svgz create mode 100644 part/data/sources/tool-note-okular-colorizable.svgz create mode 100644 part/data/sources/tool-note-okular.svgz create mode 100644 part/data/sources/tool-polygon-okular.svgz create mode 100644 part/data/sources/tool-stamp-okular.svgz create mode 100644 part/data/sources/tool-typewriter-okular-colorizable.svgz create mode 100644 part/data/sources/tool-underline-okular.svgz create mode 100644 part/data/sources/uparrow.svgz create mode 100644 part/data/sources/upleftarrow.svgz create mode 100644 part/data/stamps.svg create mode 100644 part/data/star.png create mode 100644 part/data/tool-base-okular.png create mode 100644 part/data/tool-base-okular@2x.png create mode 100644 part/data/tool-highlighter-okular-colorizable.png create mode 100644 part/data/tool-highlighter-okular-colorizable@2x.png create mode 100644 part/data/tool-ink-okular-colorizable.png create mode 100644 part/data/tool-ink-okular-colorizable@2x.png create mode 100644 part/data/tool-note-inline-okular-colorizable.png create mode 100644 part/data/tool-note-inline-okular-colorizable@2x.png create mode 100644 part/data/tool-note-inline.png create mode 100644 part/data/tool-note-okular-colorizable.png create mode 100644 part/data/tool-note-okular-colorizable@2x.png create mode 100644 part/data/tool-note.png create mode 100644 part/data/tool-typewriter-okular-colorizable.png create mode 100644 part/data/tool-typewriter-okular-colorizable@2x.png create mode 100644 part/data/tool_hl_orange.png create mode 100644 part/data/tool_hl_pink.png create mode 100644 part/data/tool_hl_yellow.png create mode 100644 part/data/tool_ink_green.png create mode 100644 part/data/tool_note.png create mode 100644 part/data/tools.xml create mode 100644 part/data/toolsQuick.xml create mode 100644 part/data/uparrow.png create mode 100644 part/data/upleftarrow.png create mode 100644 part/debug_ui.cpp create mode 100644 part/debug_ui.h create mode 100644 part/dlgaccessibility.cpp create mode 100644 part/dlgaccessibility.h create mode 100644 part/dlgaccessibilitybase.ui create mode 100644 part/dlgannotations.cpp create mode 100644 part/dlgannotations.h create mode 100644 part/dlgannotationsbase.ui create mode 100644 part/dlgdebug.cpp create mode 100644 part/dlgdebug.h create mode 100644 part/dlgeditor.cpp create mode 100644 part/dlgeditor.h create mode 100644 part/dlgeditorbase.ui create mode 100644 part/dlggeneral.cpp create mode 100644 part/dlggeneral.h create mode 100644 part/dlggeneralbase.ui create mode 100644 part/dlgperformance.cpp create mode 100644 part/dlgperformance.h create mode 100644 part/dlgperformancebase.ui create mode 100644 part/dlgpresentation.cpp create mode 100644 part/dlgpresentation.h create mode 100644 part/dlgpresentationbase.ui create mode 100644 part/drawingtoolactions.cpp create mode 100644 part/drawingtoolactions.h create mode 100644 part/editannottooldialog.cpp create mode 100644 part/editannottooldialog.h create mode 100644 part/editdrawingtooldialog.cpp create mode 100644 part/editdrawingtooldialog.h create mode 100644 part/embeddedfilesdialog.cpp create mode 100644 part/embeddedfilesdialog.h create mode 100644 part/extensions.cpp create mode 100644 part/extensions.h create mode 100644 part/fileprinterpreview.cpp create mode 100644 part/fileprinterpreview.h create mode 100644 part/findbar.cpp create mode 100644 part/findbar.h create mode 100644 part/formwidgets.cpp create mode 100644 part/formwidgets.h create mode 100644 part/guiutils.cpp create mode 100644 part/guiutils.h create mode 100644 part/ktreeviewsearchline.cpp create mode 100644 part/ktreeviewsearchline.h create mode 100644 part/latexrenderer.cpp create mode 100644 part/latexrenderer.h create mode 100644 part/layers.cpp create mode 100644 part/layers.h create mode 100644 part/magnifierview.cpp create mode 100644 part/magnifierview.h create mode 100644 part/minibar.cpp create mode 100644 part/minibar.h create mode 100644 part/okmenutitle.cpp create mode 100644 part/okmenutitle.h create mode 100644 part/pageitemdelegate.cpp create mode 100644 part/pageitemdelegate.h create mode 100644 part/pagepainter.cpp create mode 100644 part/pagepainter.h create mode 100644 part/pagesizelabel.cpp create mode 100644 part/pagesizelabel.h create mode 100644 part/pageview.cpp create mode 100644 part/pageview.h create mode 100644 part/pageviewannotator.cpp create mode 100644 part/pageviewannotator.h create mode 100644 part/pageviewmouseannotation.cpp create mode 100644 part/pageviewmouseannotation.h create mode 100644 part/pageviewutils.cpp create mode 100644 part/pageviewutils.h create mode 100644 part/part-viewermode.rc create mode 100644 part/part.cpp create mode 100644 part/part.h create mode 100644 part/part.rc create mode 100644 part/preferencesdialog.cpp create mode 100644 part/preferencesdialog.h create mode 100644 part/presentationsearchbar.cpp create mode 100644 part/presentationsearchbar.h create mode 100644 part/presentationwidget.cpp create mode 100644 part/presentationwidget.h create mode 100644 part/priorities.h create mode 100644 part/propertiesdialog.cpp create mode 100644 part/propertiesdialog.h create mode 100644 part/revisionviewer.cpp create mode 100644 part/revisionviewer.h create mode 100644 part/searchlineedit.cpp create mode 100644 part/searchlineedit.h create mode 100644 part/searchwidget.cpp create mode 100644 part/searchwidget.h create mode 100644 part/side_reviews.cpp create mode 100644 part/side_reviews.h create mode 100644 part/sidebar.cpp create mode 100644 part/sidebar.h create mode 100644 part/signatureguiutils.cpp create mode 100644 part/signatureguiutils.h create mode 100644 part/signaturemodel.cpp create mode 100644 part/signaturemodel.h create mode 100644 part/signaturepanel.cpp create mode 100644 part/signaturepanel.h create mode 100644 part/signaturepropertiesdialog.cpp create mode 100644 part/signaturepropertiesdialog.h create mode 100644 part/snapshottaker.cpp create mode 100644 part/snapshottaker.h create mode 100644 part/textdocumentsettings.ui create mode 100644 part/thumbnaillist.cpp create mode 100644 part/thumbnaillist.h create mode 100644 part/toc.cpp create mode 100644 part/toc.h create mode 100644 part/tocmodel.cpp create mode 100644 part/tocmodel.h create mode 100644 part/toggleactionmenu.cpp create mode 100644 part/toggleactionmenu.h create mode 100644 part/tts.cpp create mode 100644 part/tts.h create mode 100644 part/url_utils.h create mode 100644 part/videowidget.cpp create mode 100644 part/videowidget.h create mode 100644 part/widgetannottools.cpp create mode 100644 part/widgetannottools.h create mode 100644 part/widgetconfigurationtoolsbase.cpp create mode 100644 part/widgetconfigurationtoolsbase.h create mode 100644 part/widgetdrawingtools.cpp create mode 100644 part/widgetdrawingtools.h create mode 100644 part/xmlgui_helper.cpp create mode 100644 part/xmlgui_helper.h create mode 100644 po/ar/okular.po create mode 100644 po/ar/okular_chm.po create mode 100644 po/ar/okular_comicbook.po create mode 100644 po/ar/okular_djvu.po create mode 100644 po/ar/okular_dvi.po create mode 100644 po/ar/okular_epub.po create mode 100644 po/ar/okular_fax.po create mode 100644 po/ar/okular_fictionbook.po create mode 100644 po/ar/okular_ghostview.po create mode 100644 po/ar/okular_kimgio.po create mode 100644 po/ar/okular_mobi.po create mode 100644 po/ar/okular_plucker.po create mode 100644 po/ar/okular_poppler.po create mode 100644 po/ar/okular_txt.po create mode 100644 po/ar/okular_xps.po create mode 100644 po/ast/okular_chm.po create mode 100644 po/ast/okular_fax.po create mode 100644 po/ast/okular_plucker.po create mode 100644 po/ast/okular_xps.po create mode 100644 po/bg/okular.po create mode 100644 po/bg/okular_chm.po create mode 100644 po/bg/okular_comicbook.po create mode 100644 po/bg/okular_djvu.po create mode 100644 po/bg/okular_dvi.po create mode 100644 po/bg/okular_epub.po create mode 100644 po/bg/okular_fax.po create mode 100644 po/bg/okular_fictionbook.po create mode 100644 po/bg/okular_ghostview.po create mode 100644 po/bg/okular_kimgio.po create mode 100644 po/bg/okular_mobi.po create mode 100644 po/bg/okular_plucker.po create mode 100644 po/bg/okular_poppler.po create mode 100644 po/bg/okular_txt.po create mode 100644 po/bg/okular_xps.po create mode 100644 po/bg/org.kde.active.documentviewer.po create mode 100644 po/bs/okular.po create mode 100644 po/bs/okular_chm.po create mode 100644 po/bs/okular_comicbook.po create mode 100644 po/bs/okular_djvu.po create mode 100644 po/bs/okular_dvi.po create mode 100644 po/bs/okular_epub.po create mode 100644 po/bs/okular_fax.po create mode 100644 po/bs/okular_fictionbook.po create mode 100644 po/bs/okular_ghostview.po create mode 100644 po/bs/okular_kimgio.po create mode 100644 po/bs/okular_mobi.po create mode 100644 po/bs/okular_plucker.po create mode 100644 po/bs/okular_poppler.po create mode 100644 po/bs/okular_txt.po create mode 100644 po/bs/okular_xps.po create mode 100644 po/bs/org.kde.active.documentviewer.po create mode 100644 po/ca/docs/okular/bookmark-management.png create mode 100644 po/ca/docs/okular/configure-annotations.png create mode 100644 po/ca/docs/okular/configure-backends.png create mode 100644 po/ca/docs/okular/configure-editor.png create mode 100644 po/ca/docs/okular/configure.png create mode 100644 po/ca/docs/okular/index.docbook create mode 100644 po/ca/docs/okular/mainwindow.png create mode 100644 po/ca/docs/okular/man-okular.1.docbook create mode 100644 po/ca/docs/okular/presentation.png create mode 100644 po/ca/okular.po create mode 100644 po/ca/okular_chm.po create mode 100644 po/ca/okular_comicbook.po create mode 100644 po/ca/okular_djvu.po create mode 100644 po/ca/okular_dvi.po create mode 100644 po/ca/okular_epub.po create mode 100644 po/ca/okular_fax.po create mode 100644 po/ca/okular_fictionbook.po create mode 100644 po/ca/okular_ghostview.po create mode 100644 po/ca/okular_kimgio.po create mode 100644 po/ca/okular_markdown.po create mode 100644 po/ca/okular_mobi.po create mode 100644 po/ca/okular_plucker.po create mode 100644 po/ca/okular_poppler.po create mode 100644 po/ca/okular_tiff.po create mode 100644 po/ca/okular_txt.po create mode 100644 po/ca/okular_xps.po create mode 100644 po/ca/org.kde.active.documentviewer.po create mode 100644 po/ca@valencia/okular.po create mode 100644 po/ca@valencia/okular_chm.po create mode 100644 po/ca@valencia/okular_comicbook.po create mode 100644 po/ca@valencia/okular_djvu.po create mode 100644 po/ca@valencia/okular_dvi.po create mode 100644 po/ca@valencia/okular_epub.po create mode 100644 po/ca@valencia/okular_fax.po create mode 100644 po/ca@valencia/okular_fictionbook.po create mode 100644 po/ca@valencia/okular_ghostview.po create mode 100644 po/ca@valencia/okular_kimgio.po create mode 100644 po/ca@valencia/okular_markdown.po create mode 100644 po/ca@valencia/okular_mobi.po create mode 100644 po/ca@valencia/okular_plucker.po create mode 100644 po/ca@valencia/okular_poppler.po create mode 100644 po/ca@valencia/okular_tiff.po create mode 100644 po/ca@valencia/okular_txt.po create mode 100644 po/ca@valencia/okular_xps.po create mode 100644 po/ca@valencia/org.kde.active.documentviewer.po create mode 100644 po/cs/okular.po create mode 100644 po/cs/okular_chm.po create mode 100644 po/cs/okular_comicbook.po create mode 100644 po/cs/okular_djvu.po create mode 100644 po/cs/okular_dvi.po create mode 100644 po/cs/okular_epub.po create mode 100644 po/cs/okular_fax.po create mode 100644 po/cs/okular_fictionbook.po create mode 100644 po/cs/okular_ghostview.po create mode 100644 po/cs/okular_kimgio.po create mode 100644 po/cs/okular_markdown.po create mode 100644 po/cs/okular_mobi.po create mode 100644 po/cs/okular_plucker.po create mode 100644 po/cs/okular_poppler.po create mode 100644 po/cs/okular_tiff.po create mode 100644 po/cs/okular_txt.po create mode 100644 po/cs/okular_xps.po create mode 100644 po/cs/org.kde.active.documentviewer.po create mode 100644 po/da/okular.po create mode 100644 po/da/okular_chm.po create mode 100644 po/da/okular_comicbook.po create mode 100644 po/da/okular_djvu.po create mode 100644 po/da/okular_dvi.po create mode 100644 po/da/okular_epub.po create mode 100644 po/da/okular_fax.po create mode 100644 po/da/okular_fictionbook.po create mode 100644 po/da/okular_ghostview.po create mode 100644 po/da/okular_kimgio.po create mode 100644 po/da/okular_markdown.po create mode 100644 po/da/okular_mobi.po create mode 100644 po/da/okular_plucker.po create mode 100644 po/da/okular_poppler.po create mode 100644 po/da/okular_txt.po create mode 100644 po/da/okular_xps.po create mode 100644 po/da/org.kde.active.documentviewer.po create mode 100644 po/de/docs/okular/annotation-properties.png create mode 100644 po/de/docs/okular/configure-annotations.png create mode 100644 po/de/docs/okular/configure-editor.png create mode 100644 po/de/docs/okular/configure.png create mode 100644 po/de/docs/okular/embedded-files-bar.png create mode 100644 po/de/docs/okular/index.docbook create mode 100644 po/de/docs/okular/mainwindow.png create mode 100644 po/de/docs/okular/man-okular.1.docbook create mode 100644 po/de/okular.po create mode 100644 po/de/okular_chm.po create mode 100644 po/de/okular_comicbook.po create mode 100644 po/de/okular_djvu.po create mode 100644 po/de/okular_dvi.po create mode 100644 po/de/okular_epub.po create mode 100644 po/de/okular_fax.po create mode 100644 po/de/okular_fictionbook.po create mode 100644 po/de/okular_ghostview.po create mode 100644 po/de/okular_kimgio.po create mode 100644 po/de/okular_markdown.po create mode 100644 po/de/okular_mobi.po create mode 100644 po/de/okular_plucker.po create mode 100644 po/de/okular_poppler.po create mode 100644 po/de/okular_tiff.po create mode 100644 po/de/okular_txt.po create mode 100644 po/de/okular_xps.po create mode 100644 po/de/org.kde.active.documentviewer.po create mode 100644 po/el/okular.po create mode 100644 po/el/okular_chm.po create mode 100644 po/el/okular_comicbook.po create mode 100644 po/el/okular_djvu.po create mode 100644 po/el/okular_dvi.po create mode 100644 po/el/okular_epub.po create mode 100644 po/el/okular_fax.po create mode 100644 po/el/okular_fictionbook.po create mode 100644 po/el/okular_ghostview.po create mode 100644 po/el/okular_kimgio.po create mode 100644 po/el/okular_markdown.po create mode 100644 po/el/okular_mobi.po create mode 100644 po/el/okular_plucker.po create mode 100644 po/el/okular_poppler.po create mode 100644 po/el/okular_tiff.po create mode 100644 po/el/okular_txt.po create mode 100644 po/el/okular_xps.po create mode 100644 po/el/org.kde.active.documentviewer.po create mode 100644 po/en_GB/okular.po create mode 100644 po/en_GB/okular_chm.po create mode 100644 po/en_GB/okular_comicbook.po create mode 100644 po/en_GB/okular_djvu.po create mode 100644 po/en_GB/okular_dvi.po create mode 100644 po/en_GB/okular_epub.po create mode 100644 po/en_GB/okular_fax.po create mode 100644 po/en_GB/okular_fictionbook.po create mode 100644 po/en_GB/okular_ghostview.po create mode 100644 po/en_GB/okular_kimgio.po create mode 100644 po/en_GB/okular_markdown.po create mode 100644 po/en_GB/okular_mobi.po create mode 100644 po/en_GB/okular_plucker.po create mode 100644 po/en_GB/okular_poppler.po create mode 100644 po/en_GB/okular_tiff.po create mode 100644 po/en_GB/okular_txt.po create mode 100644 po/en_GB/okular_xps.po create mode 100644 po/en_GB/org.kde.active.documentviewer.po create mode 100644 po/eo/okular.po create mode 100644 po/eo/okular_chm.po create mode 100644 po/eo/okular_comicbook.po create mode 100644 po/eo/okular_djvu.po create mode 100644 po/eo/okular_dvi.po create mode 100644 po/eo/okular_epub.po create mode 100644 po/eo/okular_fax.po create mode 100644 po/eo/okular_fictionbook.po create mode 100644 po/eo/okular_ghostview.po create mode 100644 po/eo/okular_kimgio.po create mode 100644 po/eo/okular_mobi.po create mode 100644 po/eo/okular_plucker.po create mode 100644 po/eo/okular_poppler.po create mode 100644 po/eo/okular_xps.po create mode 100644 po/es/docs/okular/configure.png create mode 100644 po/es/docs/okular/embedded-files-bar.png create mode 100644 po/es/docs/okular/index.docbook create mode 100644 po/es/docs/okular/man-okular.1.docbook create mode 100644 po/es/okular.po create mode 100644 po/es/okular_chm.po create mode 100644 po/es/okular_comicbook.po create mode 100644 po/es/okular_djvu.po create mode 100644 po/es/okular_dvi.po create mode 100644 po/es/okular_epub.po create mode 100644 po/es/okular_fax.po create mode 100644 po/es/okular_fictionbook.po create mode 100644 po/es/okular_ghostview.po create mode 100644 po/es/okular_kimgio.po create mode 100644 po/es/okular_markdown.po create mode 100644 po/es/okular_mobi.po create mode 100644 po/es/okular_plucker.po create mode 100644 po/es/okular_poppler.po create mode 100644 po/es/okular_tiff.po create mode 100644 po/es/okular_txt.po create mode 100644 po/es/okular_xps.po create mode 100644 po/es/org.kde.active.documentviewer.po create mode 100644 po/et/docs/okular/man-okular.1.docbook create mode 100644 po/et/okular.po create mode 100644 po/et/okular_chm.po create mode 100644 po/et/okular_comicbook.po create mode 100644 po/et/okular_djvu.po create mode 100644 po/et/okular_dvi.po create mode 100644 po/et/okular_epub.po create mode 100644 po/et/okular_fax.po create mode 100644 po/et/okular_fictionbook.po create mode 100644 po/et/okular_ghostview.po create mode 100644 po/et/okular_kimgio.po create mode 100644 po/et/okular_markdown.po create mode 100644 po/et/okular_mobi.po create mode 100644 po/et/okular_plucker.po create mode 100644 po/et/okular_poppler.po create mode 100644 po/et/okular_txt.po create mode 100644 po/et/okular_xps.po create mode 100644 po/et/org.kde.active.documentviewer.po create mode 100644 po/eu/okular.po create mode 100644 po/eu/okular_chm.po create mode 100644 po/eu/okular_comicbook.po create mode 100644 po/eu/okular_djvu.po create mode 100644 po/eu/okular_dvi.po create mode 100644 po/eu/okular_epub.po create mode 100644 po/eu/okular_fax.po create mode 100644 po/eu/okular_fictionbook.po create mode 100644 po/eu/okular_ghostview.po create mode 100644 po/eu/okular_kimgio.po create mode 100644 po/eu/okular_markdown.po create mode 100644 po/eu/okular_mobi.po create mode 100644 po/eu/okular_plucker.po create mode 100644 po/eu/okular_poppler.po create mode 100644 po/eu/okular_tiff.po create mode 100644 po/eu/okular_txt.po create mode 100644 po/eu/okular_xps.po create mode 100644 po/eu/org.kde.active.documentviewer.po create mode 100644 po/fa/okular.po create mode 100644 po/fi/okular.po create mode 100644 po/fi/okular_chm.po create mode 100644 po/fi/okular_comicbook.po create mode 100644 po/fi/okular_djvu.po create mode 100644 po/fi/okular_dvi.po create mode 100644 po/fi/okular_epub.po create mode 100644 po/fi/okular_fax.po create mode 100644 po/fi/okular_fictionbook.po create mode 100644 po/fi/okular_ghostview.po create mode 100644 po/fi/okular_kimgio.po create mode 100644 po/fi/okular_markdown.po create mode 100644 po/fi/okular_mobi.po create mode 100644 po/fi/okular_plucker.po create mode 100644 po/fi/okular_poppler.po create mode 100644 po/fi/okular_tiff.po create mode 100644 po/fi/okular_txt.po create mode 100644 po/fi/okular_xps.po create mode 100644 po/fi/org.kde.active.documentviewer.po create mode 100644 po/fr/docs/okular/annotation-properties.png create mode 100644 po/fr/docs/okular/annotations.png create mode 100644 po/fr/docs/okular/bookmark-management.png create mode 100644 po/fr/docs/okular/configure-annotations.png create mode 100644 po/fr/docs/okular/configure-backends.png create mode 100644 po/fr/docs/okular/configure-editor.png create mode 100644 po/fr/docs/okular/configure.png create mode 100644 po/fr/docs/okular/forms-bar.png create mode 100644 po/fr/docs/okular/index.docbook create mode 100644 po/fr/docs/okular/mainwindow.png create mode 100644 po/fr/docs/okular/man-okular.1.docbook create mode 100644 po/fr/docs/okular/presentation.png create mode 100644 po/fr/okular.po create mode 100644 po/fr/okular_chm.po create mode 100644 po/fr/okular_comicbook.po create mode 100644 po/fr/okular_djvu.po create mode 100644 po/fr/okular_dvi.po create mode 100644 po/fr/okular_epub.po create mode 100644 po/fr/okular_fax.po create mode 100644 po/fr/okular_fictionbook.po create mode 100644 po/fr/okular_ghostview.po create mode 100644 po/fr/okular_kimgio.po create mode 100644 po/fr/okular_markdown.po create mode 100644 po/fr/okular_mobi.po create mode 100644 po/fr/okular_plucker.po create mode 100644 po/fr/okular_poppler.po create mode 100644 po/fr/okular_tiff.po create mode 100644 po/fr/okular_txt.po create mode 100644 po/fr/okular_xps.po create mode 100644 po/fr/org.kde.active.documentviewer.po create mode 100644 po/ga/okular.po create mode 100644 po/ga/okular_chm.po create mode 100644 po/ga/okular_comicbook.po create mode 100644 po/ga/okular_djvu.po create mode 100644 po/ga/okular_dvi.po create mode 100644 po/ga/okular_epub.po create mode 100644 po/ga/okular_fax.po create mode 100644 po/ga/okular_fictionbook.po create mode 100644 po/ga/okular_ghostview.po create mode 100644 po/ga/okular_kimgio.po create mode 100644 po/ga/okular_mobi.po create mode 100644 po/ga/okular_plucker.po create mode 100644 po/ga/okular_poppler.po create mode 100644 po/ga/okular_xps.po create mode 100644 po/ga/org.kde.active.documentviewer.po create mode 100644 po/gl/docs/okular/index.docbook create mode 100644 po/gl/okular.po create mode 100644 po/gl/okular_chm.po create mode 100644 po/gl/okular_comicbook.po create mode 100644 po/gl/okular_djvu.po create mode 100644 po/gl/okular_dvi.po create mode 100644 po/gl/okular_epub.po create mode 100644 po/gl/okular_fax.po create mode 100644 po/gl/okular_fictionbook.po create mode 100644 po/gl/okular_ghostview.po create mode 100644 po/gl/okular_kimgio.po create mode 100644 po/gl/okular_markdown.po create mode 100644 po/gl/okular_mobi.po create mode 100644 po/gl/okular_plucker.po create mode 100644 po/gl/okular_poppler.po create mode 100644 po/gl/okular_txt.po create mode 100644 po/gl/okular_xps.po create mode 100644 po/gl/org.kde.active.documentviewer.po create mode 100644 po/he/okular.po create mode 100644 po/hi/okular.po create mode 100644 po/hi/okular_chm.po create mode 100644 po/hi/okular_djvu.po create mode 100644 po/hi/okular_dvi.po create mode 100644 po/hi/okular_fictionbook.po create mode 100644 po/hi/okular_ghostview.po create mode 100644 po/hi/okular_kimgio.po create mode 100644 po/hi/okular_plucker.po create mode 100644 po/hi/okular_poppler.po create mode 100644 po/hi/okular_xps.po create mode 100644 po/hr/okular.po create mode 100644 po/hr/okular_chm.po create mode 100644 po/hr/okular_comicbook.po create mode 100644 po/hr/okular_djvu.po create mode 100644 po/hr/okular_dvi.po create mode 100644 po/hr/okular_epub.po create mode 100644 po/hr/okular_fax.po create mode 100644 po/hr/okular_fictionbook.po create mode 100644 po/hr/okular_ghostview.po create mode 100644 po/hr/okular_kimgio.po create mode 100644 po/hr/okular_mobi.po create mode 100644 po/hr/okular_plucker.po create mode 100644 po/hr/okular_poppler.po create mode 100644 po/hr/okular_xps.po create mode 100644 po/hu/okular.po create mode 100644 po/hu/okular_chm.po create mode 100644 po/hu/okular_comicbook.po create mode 100644 po/hu/okular_djvu.po create mode 100644 po/hu/okular_dvi.po create mode 100644 po/hu/okular_epub.po create mode 100644 po/hu/okular_fax.po create mode 100644 po/hu/okular_fictionbook.po create mode 100644 po/hu/okular_ghostview.po create mode 100644 po/hu/okular_kimgio.po create mode 100644 po/hu/okular_markdown.po create mode 100644 po/hu/okular_mobi.po create mode 100644 po/hu/okular_plucker.po create mode 100644 po/hu/okular_poppler.po create mode 100644 po/hu/okular_tiff.po create mode 100644 po/hu/okular_txt.po create mode 100644 po/hu/okular_xps.po create mode 100644 po/hu/org.kde.active.documentviewer.po create mode 100644 po/ia/okular.po create mode 100644 po/ia/okular_chm.po create mode 100644 po/ia/okular_comicbook.po create mode 100644 po/ia/okular_djvu.po create mode 100644 po/ia/okular_dvi.po create mode 100644 po/ia/okular_epub.po create mode 100644 po/ia/okular_fax.po create mode 100644 po/ia/okular_fictionbook.po create mode 100644 po/ia/okular_ghostview.po create mode 100644 po/ia/okular_kimgio.po create mode 100644 po/ia/okular_markdown.po create mode 100644 po/ia/okular_mobi.po create mode 100644 po/ia/okular_plucker.po create mode 100644 po/ia/okular_poppler.po create mode 100644 po/ia/okular_tiff.po create mode 100644 po/ia/okular_txt.po create mode 100644 po/ia/okular_xps.po create mode 100644 po/ia/org.kde.active.documentviewer.po create mode 100644 po/id/okular.po create mode 100644 po/is/okular.po create mode 100644 po/is/okular_chm.po create mode 100644 po/is/okular_comicbook.po create mode 100644 po/is/okular_djvu.po create mode 100644 po/is/okular_dvi.po create mode 100644 po/is/okular_epub.po create mode 100644 po/is/okular_fax.po create mode 100644 po/is/okular_fictionbook.po create mode 100644 po/is/okular_ghostview.po create mode 100644 po/is/okular_kimgio.po create mode 100644 po/is/okular_mobi.po create mode 100644 po/is/okular_plucker.po create mode 100644 po/is/okular_poppler.po create mode 100644 po/is/okular_xps.po create mode 100644 po/is/org.kde.active.documentviewer.po create mode 100644 po/it/docs/okular/annotation-properties.png create mode 100644 po/it/docs/okular/annotations.png create mode 100644 po/it/docs/okular/bookmark-management.png create mode 100644 po/it/docs/okular/configure-annotations.png create mode 100644 po/it/docs/okular/configure-backends.png create mode 100644 po/it/docs/okular/configure-editor.png create mode 100644 po/it/docs/okular/configure.png create mode 100644 po/it/docs/okular/embedded-files-bar.png create mode 100644 po/it/docs/okular/forms-bar.png create mode 100644 po/it/docs/okular/index.docbook create mode 100644 po/it/docs/okular/mainwindow.png create mode 100644 po/it/docs/okular/man-okular.1.docbook create mode 100644 po/it/docs/okular/presentation.png create mode 100644 po/it/docs/okular/signatures-bar.png create mode 100644 po/it/docs/okular/signatures-panel.png create mode 100644 po/it/okular.po create mode 100644 po/it/okular_chm.po create mode 100644 po/it/okular_comicbook.po create mode 100644 po/it/okular_djvu.po create mode 100644 po/it/okular_dvi.po create mode 100644 po/it/okular_epub.po create mode 100644 po/it/okular_fax.po create mode 100644 po/it/okular_fictionbook.po create mode 100644 po/it/okular_ghostview.po create mode 100644 po/it/okular_kimgio.po create mode 100644 po/it/okular_markdown.po create mode 100644 po/it/okular_mobi.po create mode 100644 po/it/okular_plucker.po create mode 100644 po/it/okular_poppler.po create mode 100644 po/it/okular_tiff.po create mode 100644 po/it/okular_txt.po create mode 100644 po/it/okular_xps.po create mode 100644 po/it/org.kde.active.documentviewer.po create mode 100644 po/ja/docs/okular/configure.png create mode 100644 po/ja/docs/okular/embedded-files-bar.png create mode 100644 po/ja/docs/okular/index.docbook create mode 100644 po/ja/okular.po create mode 100644 po/ja/okular_chm.po create mode 100644 po/ja/okular_comicbook.po create mode 100644 po/ja/okular_djvu.po create mode 100644 po/ja/okular_dvi.po create mode 100644 po/ja/okular_epub.po create mode 100644 po/ja/okular_fax.po create mode 100644 po/ja/okular_fictionbook.po create mode 100644 po/ja/okular_ghostview.po create mode 100644 po/ja/okular_kimgio.po create mode 100644 po/ja/okular_markdown.po create mode 100644 po/ja/okular_mobi.po create mode 100644 po/ja/okular_plucker.po create mode 100644 po/ja/okular_poppler.po create mode 100644 po/ja/okular_txt.po create mode 100644 po/ja/okular_xps.po create mode 100644 po/ja/org.kde.active.documentviewer.po create mode 100644 po/kk/okular.po create mode 100644 po/kk/okular_chm.po create mode 100644 po/kk/okular_comicbook.po create mode 100644 po/kk/okular_djvu.po create mode 100644 po/kk/okular_dvi.po create mode 100644 po/kk/okular_epub.po create mode 100644 po/kk/okular_fax.po create mode 100644 po/kk/okular_fictionbook.po create mode 100644 po/kk/okular_ghostview.po create mode 100644 po/kk/okular_kimgio.po create mode 100644 po/kk/okular_mobi.po create mode 100644 po/kk/okular_plucker.po create mode 100644 po/kk/okular_poppler.po create mode 100644 po/kk/okular_txt.po create mode 100644 po/kk/okular_xps.po create mode 100644 po/kk/org.kde.active.documentviewer.po create mode 100644 po/km/okular.po create mode 100644 po/km/okular_chm.po create mode 100644 po/km/okular_comicbook.po create mode 100644 po/km/okular_djvu.po create mode 100644 po/km/okular_dvi.po create mode 100644 po/km/okular_epub.po create mode 100644 po/km/okular_fax.po create mode 100644 po/km/okular_fictionbook.po create mode 100644 po/km/okular_ghostview.po create mode 100644 po/km/okular_kimgio.po create mode 100644 po/km/okular_mobi.po create mode 100644 po/km/okular_plucker.po create mode 100644 po/km/okular_poppler.po create mode 100644 po/km/okular_xps.po create mode 100644 po/ko/okular.po create mode 100644 po/ko/okular_chm.po create mode 100644 po/ko/okular_comicbook.po create mode 100644 po/ko/okular_djvu.po create mode 100644 po/ko/okular_dvi.po create mode 100644 po/ko/okular_epub.po create mode 100644 po/ko/okular_fax.po create mode 100644 po/ko/okular_fictionbook.po create mode 100644 po/ko/okular_ghostview.po create mode 100644 po/ko/okular_kimgio.po create mode 100644 po/ko/okular_markdown.po create mode 100644 po/ko/okular_mobi.po create mode 100644 po/ko/okular_plucker.po create mode 100644 po/ko/okular_poppler.po create mode 100644 po/ko/okular_tiff.po create mode 100644 po/ko/okular_txt.po create mode 100644 po/ko/okular_xps.po create mode 100644 po/ko/org.kde.active.documentviewer.po create mode 100644 po/lt/okular.po create mode 100644 po/lt/okular_chm.po create mode 100644 po/lt/okular_comicbook.po create mode 100644 po/lt/okular_djvu.po create mode 100644 po/lt/okular_dvi.po create mode 100644 po/lt/okular_epub.po create mode 100644 po/lt/okular_fax.po create mode 100644 po/lt/okular_fictionbook.po create mode 100644 po/lt/okular_ghostview.po create mode 100644 po/lt/okular_kimgio.po create mode 100644 po/lt/okular_markdown.po create mode 100644 po/lt/okular_mobi.po create mode 100644 po/lt/okular_plucker.po create mode 100644 po/lt/okular_poppler.po create mode 100644 po/lt/okular_tiff.po create mode 100644 po/lt/okular_txt.po create mode 100644 po/lt/okular_xps.po create mode 100644 po/lt/org.kde.active.documentviewer.po create mode 100644 po/lv/okular.po create mode 100644 po/lv/okular_chm.po create mode 100644 po/lv/okular_comicbook.po create mode 100644 po/lv/okular_djvu.po create mode 100644 po/lv/okular_dvi.po create mode 100644 po/lv/okular_epub.po create mode 100644 po/lv/okular_fax.po create mode 100644 po/lv/okular_fictionbook.po create mode 100644 po/lv/okular_ghostview.po create mode 100644 po/lv/okular_kimgio.po create mode 100644 po/lv/okular_mobi.po create mode 100644 po/lv/okular_plucker.po create mode 100644 po/lv/okular_poppler.po create mode 100644 po/lv/okular_xps.po create mode 100644 po/ml/okular.po create mode 100644 po/ml/okular_chm.po create mode 100644 po/ml/okular_comicbook.po create mode 100644 po/ml/okular_djvu.po create mode 100644 po/ml/okular_dvi.po create mode 100644 po/ml/okular_epub.po create mode 100644 po/ml/okular_fax.po create mode 100644 po/ml/okular_fictionbook.po create mode 100644 po/ml/okular_ghostview.po create mode 100644 po/ml/okular_kimgio.po create mode 100644 po/ml/okular_markdown.po create mode 100644 po/ml/okular_mobi.po create mode 100644 po/ml/okular_plucker.po create mode 100644 po/ml/okular_poppler.po create mode 100644 po/ml/okular_txt.po create mode 100644 po/ml/okular_xps.po create mode 100644 po/ml/org.kde.active.documentviewer.po create mode 100644 po/mr/okular.po create mode 100644 po/mr/okular_chm.po create mode 100644 po/mr/okular_comicbook.po create mode 100644 po/mr/okular_djvu.po create mode 100644 po/mr/okular_dvi.po create mode 100644 po/mr/okular_epub.po create mode 100644 po/mr/okular_fax.po create mode 100644 po/mr/okular_fictionbook.po create mode 100644 po/mr/okular_ghostview.po create mode 100644 po/mr/okular_kimgio.po create mode 100644 po/mr/okular_mobi.po create mode 100644 po/mr/okular_plucker.po create mode 100644 po/mr/okular_poppler.po create mode 100644 po/mr/okular_xps.po create mode 100644 po/mr/org.kde.active.documentviewer.po create mode 100644 po/nb/okular.po create mode 100644 po/nb/okular_chm.po create mode 100644 po/nb/okular_comicbook.po create mode 100644 po/nb/okular_djvu.po create mode 100644 po/nb/okular_dvi.po create mode 100644 po/nb/okular_epub.po create mode 100644 po/nb/okular_fax.po create mode 100644 po/nb/okular_fictionbook.po create mode 100644 po/nb/okular_ghostview.po create mode 100644 po/nb/okular_kimgio.po create mode 100644 po/nb/okular_mobi.po create mode 100644 po/nb/okular_plucker.po create mode 100644 po/nb/okular_poppler.po create mode 100644 po/nb/okular_txt.po create mode 100644 po/nb/okular_xps.po create mode 100644 po/nb/org.kde.active.documentviewer.po create mode 100644 po/nds/okular.po create mode 100644 po/nds/okular_chm.po create mode 100644 po/nds/okular_comicbook.po create mode 100644 po/nds/okular_djvu.po create mode 100644 po/nds/okular_dvi.po create mode 100644 po/nds/okular_epub.po create mode 100644 po/nds/okular_fax.po create mode 100644 po/nds/okular_fictionbook.po create mode 100644 po/nds/okular_ghostview.po create mode 100644 po/nds/okular_kimgio.po create mode 100644 po/nds/okular_mobi.po create mode 100644 po/nds/okular_plucker.po create mode 100644 po/nds/okular_poppler.po create mode 100644 po/nds/okular_txt.po create mode 100644 po/nds/okular_xps.po create mode 100644 po/nds/org.kde.active.documentviewer.po create mode 100644 po/nl/docs/okular/index.docbook create mode 100644 po/nl/docs/okular/man-okular.1.docbook create mode 100644 po/nl/okular.po create mode 100644 po/nl/okular_chm.po create mode 100644 po/nl/okular_comicbook.po create mode 100644 po/nl/okular_djvu.po create mode 100644 po/nl/okular_dvi.po create mode 100644 po/nl/okular_epub.po create mode 100644 po/nl/okular_fax.po create mode 100644 po/nl/okular_fictionbook.po create mode 100644 po/nl/okular_ghostview.po create mode 100644 po/nl/okular_kimgio.po create mode 100644 po/nl/okular_markdown.po create mode 100644 po/nl/okular_mobi.po create mode 100644 po/nl/okular_plucker.po create mode 100644 po/nl/okular_poppler.po create mode 100644 po/nl/okular_tiff.po create mode 100644 po/nl/okular_txt.po create mode 100644 po/nl/okular_xps.po create mode 100644 po/nl/org.kde.active.documentviewer.po create mode 100644 po/nn/okular.po create mode 100644 po/nn/okular_chm.po create mode 100644 po/nn/okular_comicbook.po create mode 100644 po/nn/okular_djvu.po create mode 100644 po/nn/okular_dvi.po create mode 100644 po/nn/okular_epub.po create mode 100644 po/nn/okular_fax.po create mode 100644 po/nn/okular_fictionbook.po create mode 100644 po/nn/okular_ghostview.po create mode 100644 po/nn/okular_kimgio.po create mode 100644 po/nn/okular_markdown.po create mode 100644 po/nn/okular_mobi.po create mode 100644 po/nn/okular_plucker.po create mode 100644 po/nn/okular_poppler.po create mode 100644 po/nn/okular_tiff.po create mode 100644 po/nn/okular_txt.po create mode 100644 po/nn/okular_xps.po create mode 100644 po/nn/org.kde.active.documentviewer.po create mode 100644 po/pa/okular.po create mode 100644 po/pa/okular_chm.po create mode 100644 po/pa/okular_comicbook.po create mode 100644 po/pa/okular_djvu.po create mode 100644 po/pa/okular_dvi.po create mode 100644 po/pa/okular_epub.po create mode 100644 po/pa/okular_fax.po create mode 100644 po/pa/okular_fictionbook.po create mode 100644 po/pa/okular_ghostview.po create mode 100644 po/pa/okular_kimgio.po create mode 100644 po/pa/okular_mobi.po create mode 100644 po/pa/okular_plucker.po create mode 100644 po/pa/okular_poppler.po create mode 100644 po/pa/okular_txt.po create mode 100644 po/pa/okular_xps.po create mode 100644 po/pa/org.kde.active.documentviewer.po create mode 100644 po/pl/docs/okular/annotation-properties.png create mode 100644 po/pl/docs/okular/annotations.png create mode 100644 po/pl/docs/okular/bookmark-management.png create mode 100644 po/pl/docs/okular/configure-annotations.png create mode 100644 po/pl/docs/okular/configure-backends.png create mode 100644 po/pl/docs/okular/configure-editor.png create mode 100644 po/pl/docs/okular/configure.png create mode 100644 po/pl/docs/okular/embedded-files-bar.png create mode 100644 po/pl/docs/okular/forms-bar.png create mode 100644 po/pl/docs/okular/index.docbook create mode 100644 po/pl/docs/okular/mainwindow.png create mode 100644 po/pl/docs/okular/presentation.png create mode 100644 po/pl/docs/okular/rating.png create mode 100644 po/pl/docs/okular/tool-ellipse-okular.png create mode 100644 po/pl/docs/okular/tool-highlighter-okular.png create mode 100644 po/pl/docs/okular/tool-ink-okular.png create mode 100644 po/pl/docs/okular/tool-line-okular.png create mode 100644 po/pl/docs/okular/tool-note-inline-okular.png create mode 100644 po/pl/docs/okular/tool-note-okular.png create mode 100644 po/pl/docs/okular/tool-polygon-okular.png create mode 100644 po/pl/docs/okular/tool-stamp-okular.png create mode 100644 po/pl/docs/okular/tool-underline-okular.png create mode 100644 po/pl/okular.po create mode 100644 po/pl/okular_chm.po create mode 100644 po/pl/okular_comicbook.po create mode 100644 po/pl/okular_djvu.po create mode 100644 po/pl/okular_dvi.po create mode 100644 po/pl/okular_epub.po create mode 100644 po/pl/okular_fax.po create mode 100644 po/pl/okular_fictionbook.po create mode 100644 po/pl/okular_ghostview.po create mode 100644 po/pl/okular_kimgio.po create mode 100644 po/pl/okular_markdown.po create mode 100644 po/pl/okular_mobi.po create mode 100644 po/pl/okular_plucker.po create mode 100644 po/pl/okular_poppler.po create mode 100644 po/pl/okular_tiff.po create mode 100644 po/pl/okular_txt.po create mode 100644 po/pl/okular_xps.po create mode 100644 po/pl/org.kde.active.documentviewer.po create mode 100644 po/pt/docs/okular/index.docbook create mode 100644 po/pt/docs/okular/man-okular.1.docbook create mode 100644 po/pt/okular.po create mode 100644 po/pt/okular_chm.po create mode 100644 po/pt/okular_comicbook.po create mode 100644 po/pt/okular_djvu.po create mode 100644 po/pt/okular_dvi.po create mode 100644 po/pt/okular_epub.po create mode 100644 po/pt/okular_fax.po create mode 100644 po/pt/okular_fictionbook.po create mode 100644 po/pt/okular_ghostview.po create mode 100644 po/pt/okular_kimgio.po create mode 100644 po/pt/okular_markdown.po create mode 100644 po/pt/okular_mobi.po create mode 100644 po/pt/okular_plucker.po create mode 100644 po/pt/okular_poppler.po create mode 100644 po/pt/okular_tiff.po create mode 100644 po/pt/okular_txt.po create mode 100644 po/pt/okular_xps.po create mode 100644 po/pt/org.kde.active.documentviewer.po create mode 100644 po/pt_BR/docs/okular/annotation-properties.png create mode 100644 po/pt_BR/docs/okular/annotations.png create mode 100644 po/pt_BR/docs/okular/bookmark-management.png create mode 100644 po/pt_BR/docs/okular/configure-annotations.png create mode 100644 po/pt_BR/docs/okular/configure-backends.png create mode 100644 po/pt_BR/docs/okular/configure-editor.png create mode 100644 po/pt_BR/docs/okular/configure.png create mode 100644 po/pt_BR/docs/okular/embedded-files-bar.png create mode 100644 po/pt_BR/docs/okular/forms-bar.png create mode 100644 po/pt_BR/docs/okular/index.docbook create mode 100644 po/pt_BR/docs/okular/mainwindow.png create mode 100644 po/pt_BR/docs/okular/man-okular.1.docbook create mode 100644 po/pt_BR/docs/okular/presentation.png create mode 100644 po/pt_BR/docs/okular/signatures-bar.png create mode 100644 po/pt_BR/docs/okular/signatures-panel.png create mode 100644 po/pt_BR/okular.po create mode 100644 po/pt_BR/okular_chm.po create mode 100644 po/pt_BR/okular_comicbook.po create mode 100644 po/pt_BR/okular_djvu.po create mode 100644 po/pt_BR/okular_dvi.po create mode 100644 po/pt_BR/okular_epub.po create mode 100644 po/pt_BR/okular_fax.po create mode 100644 po/pt_BR/okular_fictionbook.po create mode 100644 po/pt_BR/okular_ghostview.po create mode 100644 po/pt_BR/okular_kimgio.po create mode 100644 po/pt_BR/okular_markdown.po create mode 100644 po/pt_BR/okular_mobi.po create mode 100644 po/pt_BR/okular_plucker.po create mode 100644 po/pt_BR/okular_poppler.po create mode 100644 po/pt_BR/okular_tiff.po create mode 100644 po/pt_BR/okular_txt.po create mode 100644 po/pt_BR/okular_xps.po create mode 100644 po/pt_BR/org.kde.active.documentviewer.po create mode 100644 po/ro/okular.po create mode 100644 po/ro/okular_chm.po create mode 100644 po/ro/okular_comicbook.po create mode 100644 po/ro/okular_djvu.po create mode 100644 po/ro/okular_dvi.po create mode 100644 po/ro/okular_epub.po create mode 100644 po/ro/okular_fax.po create mode 100644 po/ro/okular_fictionbook.po create mode 100644 po/ro/okular_ghostview.po create mode 100644 po/ro/okular_kimgio.po create mode 100644 po/ro/okular_mobi.po create mode 100644 po/ro/okular_plucker.po create mode 100644 po/ro/okular_poppler.po create mode 100644 po/ro/okular_txt.po create mode 100644 po/ro/okular_xps.po create mode 100644 po/ro/org.kde.active.documentviewer.po create mode 100644 po/ru/docs/okular/annotation-properties.png create mode 100644 po/ru/docs/okular/annotations.png create mode 100644 po/ru/docs/okular/bookmark-management.png create mode 100644 po/ru/docs/okular/configure-annotations.png create mode 100644 po/ru/docs/okular/configure-backends.png create mode 100644 po/ru/docs/okular/configure-editor.png create mode 100644 po/ru/docs/okular/configure.png create mode 100644 po/ru/docs/okular/embedded-files-bar.png create mode 100644 po/ru/docs/okular/enhance-lowcontrast.png create mode 100644 po/ru/docs/okular/enhance-shape.png create mode 100644 po/ru/docs/okular/enhance-solid.png create mode 100644 po/ru/docs/okular/enhance-thinline.png create mode 100644 po/ru/docs/okular/forms-bar.png create mode 100644 po/ru/docs/okular/mainwindow.png create mode 100644 po/ru/docs/okular/man-okular.1.docbook create mode 100644 po/ru/docs/okular/presentation.png create mode 100644 po/ru/docs/okular/rating.png create mode 100644 po/ru/docs/okular/tool-ellipse-okular.png create mode 100644 po/ru/docs/okular/tool-highlighter-okular.png create mode 100644 po/ru/docs/okular/tool-ink-okular.png create mode 100644 po/ru/docs/okular/tool-line-okular.png create mode 100644 po/ru/docs/okular/tool-note-inline-okular.png create mode 100644 po/ru/docs/okular/tool-note-okular.png create mode 100644 po/ru/docs/okular/tool-polygon-okular.png create mode 100644 po/ru/docs/okular/tool-stamp-okular.png create mode 100644 po/ru/docs/okular/tool-underline-okular.png create mode 100644 po/ru/okular.po create mode 100644 po/ru/okular_chm.po create mode 100644 po/ru/okular_comicbook.po create mode 100644 po/ru/okular_djvu.po create mode 100644 po/ru/okular_dvi.po create mode 100644 po/ru/okular_epub.po create mode 100644 po/ru/okular_fax.po create mode 100644 po/ru/okular_fictionbook.po create mode 100644 po/ru/okular_ghostview.po create mode 100644 po/ru/okular_kimgio.po create mode 100644 po/ru/okular_markdown.po create mode 100644 po/ru/okular_mobi.po create mode 100644 po/ru/okular_plucker.po create mode 100644 po/ru/okular_poppler.po create mode 100644 po/ru/okular_tiff.po create mode 100644 po/ru/okular_txt.po create mode 100644 po/ru/okular_xps.po create mode 100644 po/ru/org.kde.active.documentviewer.po create mode 100644 po/sk/okular.po create mode 100644 po/sk/okular_chm.po create mode 100644 po/sk/okular_comicbook.po create mode 100644 po/sk/okular_djvu.po create mode 100644 po/sk/okular_dvi.po create mode 100644 po/sk/okular_epub.po create mode 100644 po/sk/okular_fax.po create mode 100644 po/sk/okular_fictionbook.po create mode 100644 po/sk/okular_ghostview.po create mode 100644 po/sk/okular_kimgio.po create mode 100644 po/sk/okular_markdown.po create mode 100644 po/sk/okular_mobi.po create mode 100644 po/sk/okular_plucker.po create mode 100644 po/sk/okular_poppler.po create mode 100644 po/sk/okular_tiff.po create mode 100644 po/sk/okular_txt.po create mode 100644 po/sk/okular_xps.po create mode 100644 po/sk/org.kde.active.documentviewer.po create mode 100644 po/sl/okular.po create mode 100644 po/sl/okular_chm.po create mode 100644 po/sl/okular_comicbook.po create mode 100644 po/sl/okular_djvu.po create mode 100644 po/sl/okular_dvi.po create mode 100644 po/sl/okular_epub.po create mode 100644 po/sl/okular_fax.po create mode 100644 po/sl/okular_fictionbook.po create mode 100644 po/sl/okular_ghostview.po create mode 100644 po/sl/okular_kimgio.po create mode 100644 po/sl/okular_markdown.po create mode 100644 po/sl/okular_mobi.po create mode 100644 po/sl/okular_plucker.po create mode 100644 po/sl/okular_poppler.po create mode 100644 po/sl/okular_tiff.po create mode 100644 po/sl/okular_txt.po create mode 100644 po/sl/okular_xps.po create mode 100644 po/sl/org.kde.active.documentviewer.po create mode 100644 po/sr/okular.po create mode 100644 po/sr/okular_chm.po create mode 100644 po/sr/okular_comicbook.po create mode 100644 po/sr/okular_djvu.po create mode 100644 po/sr/okular_dvi.po create mode 100644 po/sr/okular_epub.po create mode 100644 po/sr/okular_fax.po create mode 100644 po/sr/okular_fictionbook.po create mode 100644 po/sr/okular_ghostview.po create mode 100644 po/sr/okular_kimgio.po create mode 100644 po/sr/okular_markdown.po create mode 100644 po/sr/okular_mobi.po create mode 100644 po/sr/okular_plucker.po create mode 100644 po/sr/okular_poppler.po create mode 100644 po/sr/okular_txt.po create mode 100644 po/sr/okular_xps.po create mode 100644 po/sv/docs/okular/configure.png create mode 100644 po/sv/docs/okular/index.docbook create mode 100644 po/sv/docs/okular/man-okular.1.docbook create mode 100644 po/sv/okular.po create mode 100644 po/sv/okular_chm.po create mode 100644 po/sv/okular_comicbook.po create mode 100644 po/sv/okular_djvu.po create mode 100644 po/sv/okular_dvi.po create mode 100644 po/sv/okular_epub.po create mode 100644 po/sv/okular_fax.po create mode 100644 po/sv/okular_fictionbook.po create mode 100644 po/sv/okular_ghostview.po create mode 100644 po/sv/okular_kimgio.po create mode 100644 po/sv/okular_markdown.po create mode 100644 po/sv/okular_mobi.po create mode 100644 po/sv/okular_plucker.po create mode 100644 po/sv/okular_poppler.po create mode 100644 po/sv/okular_tiff.po create mode 100644 po/sv/okular_txt.po create mode 100644 po/sv/okular_xps.po create mode 100644 po/sv/org.kde.active.documentviewer.po create mode 100644 po/tr/okular.po create mode 100644 po/tr/okular_chm.po create mode 100644 po/tr/okular_comicbook.po create mode 100644 po/tr/okular_djvu.po create mode 100644 po/tr/okular_dvi.po create mode 100644 po/tr/okular_epub.po create mode 100644 po/tr/okular_fax.po create mode 100644 po/tr/okular_fictionbook.po create mode 100644 po/tr/okular_ghostview.po create mode 100644 po/tr/okular_kimgio.po create mode 100644 po/tr/okular_mobi.po create mode 100644 po/tr/okular_plucker.po create mode 100644 po/tr/okular_poppler.po create mode 100644 po/tr/okular_txt.po create mode 100644 po/tr/okular_xps.po create mode 100644 po/tr/org.kde.active.documentviewer.po create mode 100644 po/ug/okular.po create mode 100644 po/ug/okular_chm.po create mode 100644 po/ug/okular_comicbook.po create mode 100644 po/ug/okular_djvu.po create mode 100644 po/ug/okular_dvi.po create mode 100644 po/ug/okular_epub.po create mode 100644 po/ug/okular_fax.po create mode 100644 po/ug/okular_fictionbook.po create mode 100644 po/ug/okular_ghostview.po create mode 100644 po/ug/okular_kimgio.po create mode 100644 po/ug/okular_mobi.po create mode 100644 po/ug/okular_plucker.po create mode 100644 po/ug/okular_poppler.po create mode 100644 po/ug/okular_txt.po create mode 100644 po/ug/okular_xps.po create mode 100644 po/ug/org.kde.active.documentviewer.po create mode 100644 po/uk/docs/okular/annotation-properties.png create mode 100644 po/uk/docs/okular/annotations.png create mode 100644 po/uk/docs/okular/bookmark-management.png create mode 100644 po/uk/docs/okular/configure-annotations.png create mode 100644 po/uk/docs/okular/configure-backends.png create mode 100644 po/uk/docs/okular/configure-editor.png create mode 100644 po/uk/docs/okular/configure.png create mode 100644 po/uk/docs/okular/embedded-files-bar.png create mode 100644 po/uk/docs/okular/forms-bar.png create mode 100644 po/uk/docs/okular/index.docbook create mode 100644 po/uk/docs/okular/mainwindow.png create mode 100644 po/uk/docs/okular/man-okular.1.docbook create mode 100644 po/uk/docs/okular/signatures-bar.png create mode 100644 po/uk/docs/okular/signatures-panel.png create mode 100644 po/uk/okular.po create mode 100644 po/uk/okular_chm.po create mode 100644 po/uk/okular_comicbook.po create mode 100644 po/uk/okular_djvu.po create mode 100644 po/uk/okular_dvi.po create mode 100644 po/uk/okular_epub.po create mode 100644 po/uk/okular_fax.po create mode 100644 po/uk/okular_fictionbook.po create mode 100644 po/uk/okular_ghostview.po create mode 100644 po/uk/okular_kimgio.po create mode 100644 po/uk/okular_markdown.po create mode 100644 po/uk/okular_mobi.po create mode 100644 po/uk/okular_plucker.po create mode 100644 po/uk/okular_poppler.po create mode 100644 po/uk/okular_tiff.po create mode 100644 po/uk/okular_txt.po create mode 100644 po/uk/okular_xps.po create mode 100644 po/uk/org.kde.active.documentviewer.po create mode 100644 po/wa/okular.po create mode 100644 po/wa/okular_chm.po create mode 100644 po/wa/okular_comicbook.po create mode 100644 po/wa/okular_djvu.po create mode 100644 po/wa/okular_epub.po create mode 100644 po/wa/okular_fax.po create mode 100644 po/wa/okular_fictionbook.po create mode 100644 po/wa/okular_ghostview.po create mode 100644 po/wa/okular_kimgio.po create mode 100644 po/wa/okular_mobi.po create mode 100644 po/wa/okular_plucker.po create mode 100644 po/wa/okular_poppler.po create mode 100644 po/wa/okular_xps.po create mode 100644 po/zh_CN/okular.po create mode 100644 po/zh_CN/okular_chm.po create mode 100644 po/zh_CN/okular_comicbook.po create mode 100644 po/zh_CN/okular_djvu.po create mode 100644 po/zh_CN/okular_dvi.po create mode 100644 po/zh_CN/okular_epub.po create mode 100644 po/zh_CN/okular_fax.po create mode 100644 po/zh_CN/okular_fictionbook.po create mode 100644 po/zh_CN/okular_ghostview.po create mode 100644 po/zh_CN/okular_kimgio.po create mode 100644 po/zh_CN/okular_markdown.po create mode 100644 po/zh_CN/okular_mobi.po create mode 100644 po/zh_CN/okular_plucker.po create mode 100644 po/zh_CN/okular_poppler.po create mode 100644 po/zh_CN/okular_tiff.po create mode 100644 po/zh_CN/okular_txt.po create mode 100644 po/zh_CN/okular_xps.po create mode 100644 po/zh_CN/org.kde.active.documentviewer.po create mode 100644 po/zh_TW/okular.po create mode 100644 po/zh_TW/okular_chm.po create mode 100644 po/zh_TW/okular_comicbook.po create mode 100644 po/zh_TW/okular_djvu.po create mode 100644 po/zh_TW/okular_dvi.po create mode 100644 po/zh_TW/okular_epub.po create mode 100644 po/zh_TW/okular_fax.po create mode 100644 po/zh_TW/okular_fictionbook.po create mode 100644 po/zh_TW/okular_ghostview.po create mode 100644 po/zh_TW/okular_kimgio.po create mode 100644 po/zh_TW/okular_markdown.po create mode 100644 po/zh_TW/okular_mobi.po create mode 100644 po/zh_TW/okular_plucker.po create mode 100644 po/zh_TW/okular_poppler.po create mode 100644 po/zh_TW/okular_txt.po create mode 100644 po/zh_TW/okular_xps.po create mode 100644 po/zh_TW/org.kde.active.documentviewer.po create mode 100644 shell/CMakeLists.txt create mode 100644 shell/main.cpp create mode 100644 shell/okular_main.cpp create mode 100644 shell/okular_main.h create mode 100644 shell/org.kde.okular.appdata.xml create mode 100755 shell/org.kde.okular.desktop create mode 100644 shell/shell.cpp create mode 100644 shell/shell.h create mode 100644 shell/shell.rc create mode 100644 shell/shellutils.cpp create mode 100644 shell/shellutils.h diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..8f8896f --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,9 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,performance-*,bugprone-*,readability-inconsistent-declaration-parameter-name,readability-string-compare,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-make-unique,modernize-make-shared,modernize-use-override,modernize-use-equals-delete,modernize-use-emplace,modernize-loop-convert,modernize-use-nullptr,-bugprone-macro-parentheses,-bugprone-narrowing-conversions,-bugprone-branch-clone,-bugprone-incorrect-roundings,-bugprone-suspicious-include,-bugprone-reserved-identifier,-performance-no-automatic-move' +WarningsAsErrors: '*' +HeaderFilterRegex: '.*/okular/.*' +AnalyzeTemporaryDtors: false +FormatStyle: none +User: user +... + diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..4a447ea --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# _clang_format added +19d98d6a74079a42bcc5cb0e899d239a4bdb6e20 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12c5572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +CMakeLists.txt.user* +*.kdev4 +*.swp +/build*/ +.cmake/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..73e8f0d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,55 @@ +variables: + DEBIAN_FRONTEND: "noninteractive" + +include: + - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-before.yml + - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-applications-linux.yml + +build_ubuntu_20_04: + stage: build + image: ubuntu:focal + only: + - merge_requests + before_script: + - sed -i -e 's/# deb-src/deb-src/g' /etc/apt/sources.list + - apt-get update + - apt-get install --yes eatmydata + - eatmydata apt-get build-dep --yes --no-install-recommends okular + - eatmydata apt-get install --yes --no-install-recommends ninja-build + script: + - mkdir -p build && cd build + - cmake -DOKULAR_UI=desktop -G Ninja .. + - ninja + - rm -rf * + - cmake -DOKULAR_UI=mobile -G Ninja .. + - ninja + +build_clazy_clang_tidy: + stage: build + image: debian:testing + only: + - merge_requests + before_script: + - echo 'deb-src http://deb.debian.org/debian unstable main' >> /etc/apt/sources.list + - apt-get update + - apt-get install --yes eatmydata + - eatmydata apt-get build-dep --yes --no-install-recommends okular + - eatmydata apt-get install --yes --no-install-recommends ninja-build clazy clang clang-tidy libkf5crash-dev libkf5purpose-dev libegl-dev jq + + script: + - srcdir=`pwd` && mkdir -p /tmp/okular_build && cd /tmp/okular_build && CC=clang CXX=clazy CXXFLAGS="-Werror -Wno-deprecated-declarations" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G Ninja $srcdir && cat compile_commands.json | jq '[.[] | select(.file | contains("'"$srcdir"'"))]' > compile_commands.aux.json && cat compile_commands.aux.json | jq '[.[] | select(.file | contains("/synctex/")| not)]' > compile_commands.json && cp "$srcdir/.clang-tidy" . + - CLAZY_IGNORE_DIRS="settings_core.[cpp|h]|settings.[cpp.h]|pdfsettings.h|gssettings.h" CLAZY_CHECKS="level0,level1,level2,no-ctor-missing-parent-argument,isempty-vs-count,qhash-with-char-pointer-key,raw-environment-function,qproperty-type-mismatch" ninja + - run-clang-tidy + +clang_format: + stage: build + image: debian:testing + only: + - merge_requests + - master + before_script: + - apt-get update + - apt-get install --yes --no-install-recommends git clang-format-11 + script: + - find . \( -name "*.cpp" -or -name "*.h" -or -name "*.c" -or -name "*.cc" \) -exec clang-format-11 -i {} \; + - git diff --exit-code diff --git a/.krazy b/.krazy new file mode 100644 index 0000000..10e868b --- /dev/null +++ b/.krazy @@ -0,0 +1 @@ +SKIP /generators/chm/kio-msits\|/generators/chm/lib\|/generators/dvi/\|/generators/plucker/unpluck/|/generators/poppler/synctex/ diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..55b672e --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Albert Astals Cid +Enrico Ros +Wilco Greven +Christophe Devriese diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e3f88cd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,516 @@ +cmake_minimum_required(VERSION 3.16) + +# KDE Application Version, managed by release script +set (RELEASE_SERVICE_VERSION_MAJOR "20") +set (RELEASE_SERVICE_VERSION_MINOR "12") +set (RELEASE_SERVICE_VERSION_MICRO "3") +set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") + +project(okular VERSION ${RELEASE_SERVICE_VERSION}) + +set(QT_REQUIRED_VERSION "5.12.0") # Remember to update the QT_DEPRECATED_WARNINGS_SINCE below +set(KF5_REQUIRED_VERSION "5.68.0") # Remember to update the KF_DEPRECATED_WARNINGS_SINCE below + +set(OKULAR_UI "desktop" CACHE STRING "Which Okular user interface to build. Possible values: desktop, mobile, both. Default: desktop") + +if(OKULAR_UI STREQUAL "desktop" OR OKULAR_UI STREQUAL "both") + set(BUILD_DESKTOP ON) +else() + set(BUILD_DESKTOP OFF) +endif() +if(OKULAR_UI STREQUAL "mobile" OR OKULAR_UI STREQUAL "both") + set(BUILD_MOBILE ON) +else() + set(BUILD_MOBILE OFF) +endif() + +if (ANDROID) + set(QT_REQUIRED_VERSION "5.13.0") +endif() + +find_package(ECM ${KF5_REQUIRED_VERSION} CONFIG REQUIRED) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) + +include(ECMInstallIcons) +include(ECMSetupVersion) +include(ECMOptionalAddSubdirectory) +include(GenerateExportHeader) +include(FeatureSummary) +include(ECMAddAppIcon) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(ECMAddTests) +include(ECMAddAppIcon) +include(CMakePackageConfigHelpers) +include(ECMSetupQtPluginMacroNames) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +ecm_setup_version(${PROJECT_VERSION} + VARIABLE_PREFIX OKULAR + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/core/version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/Okular5ConfigVersion.cmake") + +find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED COMPONENTS Core DBus Test Widgets PrintSupport Svg Qml Quick) +find_package(Qt5 ${QT_REQUIRED_VERSION} OPTIONAL_COMPONENTS TextToSpeech) +if (NOT Qt5TextToSpeech_FOUND) + message(STATUS "Qt5TextToSpeech not found, speech features will be disabled") +else() + add_definitions(-DHAVE_SPEECH) +endif() + +if(ANDROID) + find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED COMPONENTS AndroidExtras) +endif() + +ecm_setup_qtplugin_macro_names( + JSON_ARG2 + "OKULAR_EXPORT_PLUGIN" + CONFIG_CODE_VARIABLE + PACKAGE_SETUP_AUTOMOC_VARIABLES +) + +set(optionalComponents) +if (ANDROID) +# we want to make sure that generally all components are found + + set(optionalComponents "OPTIONAL_COMPONENTS") +endif() + +find_package(KF5 ${KF5_REQUIRED_VERSION} REQUIRED COMPONENTS + Archive + Bookmarks + Completion + Config + ConfigWidgets + CoreAddons + Crash + IconThemes + KIO + Parts + ThreadWeaver + WindowSystem + ${optionalComponents} + DocTools + JS + Wallet +) + +if(KF5Wallet_FOUND) + add_definitions(-DWITH_KWALLET=1) +endif() +if(KF5JS_FOUND) + add_definitions(-DWITH_KJS=1) +endif() + +if(NOT WIN32 AND NOT ANDROID) + find_package(KF5 ${KF5_REQUIRED_VERSION} REQUIRED COMPONENTS + Activities + ) + set_package_properties("KF5Activities" PROPERTIES + DESCRIPTION "Activities interface library" + URL "https://api.kde.org/frameworks/kactivities/html/" + TYPE RECOMMENDED + PURPOSE "Required for Activities integration.") +endif() +find_package(KF5Kirigami2) +set_package_properties(KF5Kirigami2 PROPERTIES + DESCRIPTION "A QtQuick based components set" + PURPOSE "Required at runtime by the mobile app" + TYPE RUNTIME +) +find_package(Phonon4Qt5 CONFIG REQUIRED) +find_package(KF5Purpose) +set_package_properties(KF5Purpose PROPERTIES + DESCRIPTION "A framework for services and actions integration" + PURPOSE "Required for enabling the share menu in Okular" + TYPE OPTIONAL +) +if (KF5Purpose_FOUND) + set(PURPOSE_FOUND 1) +else() + set(PURPOSE_FOUND 0) +endif() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules) + +find_package(ZLIB REQUIRED) + +# This is here instead of in generators since we use if(Poppler_Qt5_FOUND) in autotests/ +find_package(Poppler "0.86.0" COMPONENTS Qt5) +set_package_properties("Poppler" PROPERTIES + TYPE RECOMMENDED + PURPOSE "Support for PDF files in okular.") + +add_definitions(-DQT_USE_QSTRINGBUILDER) +add_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DQT_NO_URL_CAST_FROM_STRING) +add_definitions(-DQT_DEPRECATED_WARNINGS_SINCE=0x050C00) +add_definitions(-DKF_DEPRECATED_WARNINGS_SINCE=0x054400) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${PHONON_INCLUDES} core/synctex ${ZLIB_INCLUDE_DIR} ${CMAKE_BINARY_DIR}/core) + +if(BUILD_MOBILE) + add_subdirectory( mobile ) +endif() +option(BUILD_COVERAGE "Build the project with gcov support" OFF) + +if(BUILD_COVERAGE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") +endif() + +add_subdirectory( icons ) # an own directory for multi-size icons retrieved by KIconThemeLoader +add_subdirectory( part ) +if(BUILD_DESKTOP) + add_subdirectory( shell ) +endif() +add_subdirectory( generators ) +if(BUILD_TESTING) + add_subdirectory( autotests ) +endif() + +if(KF5DocTools_FOUND) + add_subdirectory(doc) +endif() + +include(OkularConfigureChecks.cmake) + +if(NOT WIN32) + set(MATH_LIB m) +else(NOT WIN32) + set(MATH_LIB) +endif(NOT WIN32) + +# okularcore + +set(okularcore_SRCS + core/action.cpp + core/annotations.cpp + core/area.cpp + core/audioplayer.cpp + core/bookmarkmanager.cpp + core/chooseenginedialog.cpp + core/document.cpp + core/documentcommands.cpp + core/fontinfo.cpp + core/form.cpp + core/generator.cpp + core/generator_p.cpp + core/misc.cpp + core/movie.cpp + core/observer.cpp + core/debug.cpp + core/page.cpp + core/pagecontroller.cpp + core/pagesize.cpp + core/pagetransition.cpp + core/rotationjob.cpp + core/scripter.cpp + core/sound.cpp + core/sourcereference.cpp + core/textdocumentgenerator.cpp + core/textdocumentsettings.cpp + core/textpage.cpp + core/tilesmanager.cpp + core/utils.cpp + core/view.cpp + core/fileprinter.cpp + core/printoptionswidget.cpp + core/signatureutils.cpp + core/script/event.cpp + core/synctex/synctex_parser.c + core/synctex/synctex_parser_utils.c +) +qt5_add_resources(okularcore_SRCS + core/script/builtin.qrc +) + +ki18n_wrap_ui(okularcore_SRCS + part/textdocumentsettings.ui +) + +install( FILES + core/action.h + core/annotations.h + core/area.h + core/document.h + core/fontinfo.h + core/form.h + core/generator.h + core/global.h + core/page.h + core/pagesize.h + core/pagetransition.h + core/signatureutils.h + core/sound.h + core/sourcereference.h + core/textdocumentgenerator.h + core/textdocumentsettings.h + core/textpage.h + core/tile.h + core/utils.h + core/fileprinter.h + core/printoptionswidget.h + core/observer.h + ${CMAKE_CURRENT_BINARY_DIR}/core/version.h + ${CMAKE_CURRENT_BINARY_DIR}/core/okularcore_export.h + ${CMAKE_CURRENT_BINARY_DIR}/settings_core.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR}/okular/core COMPONENT Devel) + +install( FILES + interfaces/configinterface.h + interfaces/guiinterface.h + interfaces/printinterface.h + interfaces/saveinterface.h + interfaces/viewerinterface.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR}/okular/interfaces COMPONENT Devel) + +ki18n_wrap_ui(okularcore_SRCS + core/chooseenginewidget.ui +) + +kconfig_add_kcfg_files(okularcore_SRCS conf/settings_core.kcfgc) + +add_library(okularcore SHARED ${okularcore_SRCS}) +generate_export_header(okularcore BASE_NAME okularcore EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/core/okularcore_export.h") + +if (ANDROID) + set(fileName ${CMAKE_BINARY_DIR}/Okular5Core-android-dependencies.xml) + file(WRITE "${fileName}" "\n" + "\n" + "\n") + install(FILES ${fileName} DESTINATION ${KDE_INSTALL_LIBDIR}) +endif() + + +# Special handling for linking okularcore on OSX/Apple +IF(APPLE) + SET(OKULAR_IOKIT "-framework IOKit" CACHE STRING "Apple IOKit framework") +ENDIF(APPLE) + +# Extra library needed by imported synctex code on Windows +if(WIN32) + set(SHLWAPI shlwapi) +endif(WIN32) + +target_link_libraries(okularcore +PRIVATE + ${OKULAR_IOKIT} + ${SHLWAPI} + KF5::Archive + KF5::KIOCore + KF5::KIOWidgets + KF5::I18n + KF5::ThreadWeaver + KF5::Bookmarks + Phonon::phonon4qt5 + ${MATH_LIB} + ${ZLIB_LIBRARIES} +PUBLIC # these are included from the installed headers + KF5::CoreAddons + KF5::XmlGui + KF5::ConfigGui + Qt5::PrintSupport + Qt5::Widgets +) + + +if (KF5Wallet_FOUND) + target_link_libraries(okularcore PRIVATE KF5::Wallet) +endif() +if (KF5JS_FOUND) + target_sources(okularcore PRIVATE + core/script/executor_kjs.cpp + core/script/kjs_app.cpp + core/script/kjs_console.cpp + core/script/kjs_data.cpp + core/script/kjs_display.cpp + core/script/kjs_document.cpp + core/script/kjs_field.cpp + core/script/kjs_fullscreen.cpp + core/script/kjs_field.cpp + core/script/kjs_spell.cpp + core/script/kjs_util.cpp + core/script/kjs_event.cpp + core/script/kjs_ocg.cpp + ) + target_link_libraries(okularcore PRIVATE KF5::JS KF5::JSApi) +endif() + +set_target_properties(okularcore PROPERTIES VERSION 9.0.0 SOVERSION 9 OUTPUT_NAME Okular5Core EXPORT_NAME Core) + +install(TARGETS okularcore EXPORT Okular5Targets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +install(FILES conf/okular.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) +install(FILES conf/okular_core.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) +install(FILES core/okularGenerator.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR}) + +if(BUILD_DESKTOP) + # okularpart + set(okularpart_SRCS + part/preferencesdialog.cpp + part/dlgaccessibility.cpp + part/dlgdebug.cpp + part/dlgeditor.cpp + part/dlggeneral.cpp + part/dlgannotations.cpp + part/dlgperformance.cpp + part/dlgpresentation.cpp + part/editannottooldialog.cpp + part/editdrawingtooldialog.cpp + part/widgetannottools.cpp + part/widgetconfigurationtoolsbase.cpp + part/widgetdrawingtools.cpp + part/part.cpp + part/xmlgui_helper.cpp + part/extensions.cpp + part/embeddedfilesdialog.cpp + part/annotationactionhandler.cpp + part/annotwindow.cpp + part/annotationmodel.cpp + part/annotationpopup.cpp + part/annotationpropertiesdialog.cpp + part/annotationproxymodels.cpp + part/annotationtools.cpp + part/annotationwidgets.cpp + part/bookmarklist.cpp + part/certificateviewer.cpp + part/debug_ui.cpp + part/drawingtoolactions.cpp + part/fileprinterpreview.cpp + part/findbar.cpp + part/formwidgets.cpp + part/guiutils.cpp + part/ktreeviewsearchline.cpp + part/latexrenderer.cpp + part/minibar.cpp + part/okmenutitle.cpp + part/pageitemdelegate.cpp + part/pagepainter.cpp + part/pagesizelabel.cpp + part/pageviewannotator.cpp + part/pageviewmouseannotation.cpp + part/pageview.cpp + part/magnifierview.cpp + part/pageviewutils.cpp + part/presentationsearchbar.cpp + part/presentationwidget.cpp + part/propertiesdialog.cpp + part/revisionviewer.cpp + part/searchlineedit.cpp + part/searchwidget.cpp + part/sidebar.cpp + part/side_reviews.cpp + part/snapshottaker.cpp + part/thumbnaillist.cpp + part/toc.cpp + part/tocmodel.cpp + part/toggleactionmenu.cpp + part/videowidget.cpp + part/layers.cpp + part/signatureguiutils.cpp + part/signaturepropertiesdialog.cpp + part/signaturemodel.cpp + part/signaturepanel.cpp + ) +endif() + +if (Qt5TextToSpeech_FOUND) + set(okularpart_SRCS ${okularpart_SRCS} + part/tts.cpp) +endif() + +ki18n_wrap_ui(okularpart_SRCS + part/dlgaccessibilitybase.ui + part/dlgeditorbase.ui + part/dlggeneralbase.ui + part/dlgannotationsbase.ui + part/dlgperformancebase.ui + part/dlgpresentationbase.ui +) + +kconfig_add_kcfg_files(okularpart_SRCS GENERATE_MOC conf/settings.kcfgc) + +add_library(okularpart SHARED ${okularpart_SRCS}) +generate_export_header(okularpart BASE_NAME okularpart) + +target_link_libraries(okularpart okularcore + ${MATH_LIB} + Qt5::Svg + Phonon::phonon4qt5 + KF5::Archive + KF5::Bookmarks + KF5::I18n + KF5::IconThemes + KF5::ItemViews + KF5::KIOCore + KF5::KIOFileWidgets + KF5::KIOWidgets + KF5::Parts + KF5::Solid + KF5::WindowSystem +) + +if(KF5Wallet_FOUND) + target_link_libraries(okularpart KF5::Wallet) +endif() + +if (KF5Purpose_FOUND) + target_link_libraries(okularpart KF5::PurposeWidgets) +endif() + +set_target_properties(okularpart PROPERTIES PREFIX "") + +if (Qt5TextToSpeech_FOUND) + target_link_libraries(okularpart Qt5::TextToSpeech) +endif() +install(TARGETS okularpart DESTINATION ${KDE_INSTALL_PLUGINDIR}) + + +########### install files ############### + +install(FILES okular.upd DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) + +install( FILES okular_part.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( FILES part/part.rc part/part-viewermode.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/okular ) + +if (${ECM_VERSION} STRGREATER "5.58.0") + install(FILES okular.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}) +else() + install(FILES okular.categories DESTINATION ${KDE_INSTALL_CONFDIR}) +endif() + +########### cmake files ################# + +set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/Okular5") +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/Okular5Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/Okular5Config.cmake" + INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} + PATH_VARS INCLUDE_INSTALL_DIR CMAKE_INSTALL_PREFIX +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/Okular5Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/Okular5ConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel +) + +install(EXPORT Okular5Targets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE Okular5Targets.cmake NAMESPACE Okular::) + +########### summary ################# + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) + +message("-- Building Desktop User Interface: ${BUILD_DESKTOP}") +message("-- Building Mobile Interface: ${BUILD_MOBILE}") +message("") +ki18n_install(po) +if (KF5DocTools_FOUND) + kdoctools_install(po) +endif() diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..8efe11a --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.DOC b/COPYING.DOC new file mode 100644 index 0000000..424035c --- /dev/null +++ b/COPYING.DOC @@ -0,0 +1,397 @@ + GNU Free Documentation License + Version 1.2, November 2002 + + + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +https://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..5bc8fb2 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Mainpage.dox b/Mainpage.dox new file mode 100644 index 0000000..7204a07 --- /dev/null +++ b/Mainpage.dox @@ -0,0 +1,907 @@ +/** +\mainpage Okular, the unified document viewer + +\section okular_overview Overview + +- \ref okular_history +- \ref okular_design +- \ref okular_generators +- Website + +\authors Tobias König + +\licenses \lgpl + +\page okular_history Historical background + +Okular is the successor of kpdf, the PDF viewer in KDE 3. +kpdf was refactored and extended in a Google Summer of Code project to support not only +viewing PDF but also other types of document, e.g. PostScript files, images and many more. + +\page okular_design The Design of Okular + +To support a wide range of document formats, Okular was designed in a modular way, so you +have the following components: + + \li \ref Shell + \li \ref Okular::Part + \li \ref Okular::Document Class + \li \ref Okular::Generator + +The shell is the application which is started by the user as standalone application and +which embeds the part. The part contains all GUI elements of Okular, for example the +content list, the bookmark manager, menus and the graphical view of the document class. +The document class is an abstract presentation of the document content. It contains information +about every page of the document, its size, orientation etc. + +But somehow the document class must retrieve these information from the various types of documents. +This is the task of the Generators. Generators are plugins which are loaded at runtime and which +have the knowledge about the internal structure of the different document types. +They extract the needed information from the documents, convert the data into a common format and +pass them to the document class. + +Currently Generators for the following document types are available: + + \li Portable Document Format (PDF) + \li PostScript + \li Device Independent Format (DVI) + \li DeJaVu Format + \li Comic Books + \li Images (JPEG, PNG, GIF, and many more) + \li TIFF Image Format + \li FictionBook Format + \li Plucker Format + \li OpenDocument Text Format + \li Microsoft's CHM Format + \li Microsoft's XML Document Format + \li Markdown Format + +Now the questions is how can these various formats be represented in a unified way? +Okular provides features like rotation, text search and extraction, zooming and many more, so how +does it match with the different capabilities of the formats? + +\section okular_design_basics Basics of Generators + +Lets start with the smallest commonness of all document formats: + + \li they have pages (one ore more) of a given size + \li pages can be represented as pictures + +So the first thing every Generator must support is to return the number of pages of a document. +Furthermore it must be able to return the picture of a page at a requested size. + +For vector based document formats (e.g. PDF or PostScript) the Generators can render the page for +the requested size, for static documents formats (e.g. images), the Generator must scale the +content according to the requested size, so when you zoom a page in Okular, the Generators are +just asked to return the page for the zoomed size. + +When the document class has retrieved the page pictures from the Generators, it can do further +image manipulation on it, for example rotating them or applying fancy effects. + +\section okular_design_text_support Generators with Text support + +Some document formats however support more functionality than just representing a page as an image. +PDF, PostScript, DVI and DeJaVu for example contains a machine readable representation of the +included text. For those document formats Okular provides additional features like text search, +text extraction and text selection. + +How is that supported by the Generators? + +To access the text from the documents the generators must extract it somehow and make it available +to the document class. However for the text selection feature the document class must also know where +the extracted text is located on the page. For a zoom factor of 100% the absolute position of +the text in the document can be used, however for larger or smaller zoom factors the position +must be recalculated. To make this calculation as easy as possible, the Generators return an +abstract representation (\ref Okular::TextPage) of the text which includes every character together +with its normalized position. Normalized means that the width and height of the page is +in the range of 0 to 1, so a character in the middle of the page is at x=0.5 and y=0.5. + +So when you want to know where this character is located on the page which is zoomed at 300%, you just +multiply the position by 3 * page width (and page height) and get the absolute position for this zoom level. + +This abstract text representation also allows an easy rotation of the coordinates, so that text selection +is available on rotated pages as well. + +\section okular_design_meta_information Meta Information + +Most documents have additional meta information: + + \li Name of the author + \li Date of creation + \li Version number + \li Table of Content + \li Bookmarks + \li Annotations + +These information can be retrieved by the generator as well and will be shown by Okular. + +\page okular_generators How to implement a Generator + +The power of Okular is its extensibility by Generator plugins. This section will describe how to +implement your own plugin for a new document type. + + \li \ref okular_generators_basic + \li \ref okular_generators_with_text + \li \ref okular_generators_threaded + \li \ref okular_generators_extended + +\section okular_generators_basic A Basic Generator + +To provide a short overview and don't reimplementing an existing generator we'll work on a Generator +for the Magic document format, a non existing, pure virtual format :) + +Lets assume we have some helper class (MagicDocument) which provides the following functionality for this +document format: + + \li Loading a document + \li Retrieving number of pages + \li Returning a fixed size picture representation of a page + +The class API looks like this + +\code +class MagicDocument +{ + public: + MagicDocument(); + ~MagicDocument(); + + bool loadDocument( const QString &fileName ); + + int numberOfPages() const; + + QSize pageSize( int pageNumber ) const; + + QImage pictureOfPage( int pageNumber ) const; + + private: + ... +}; +\endcode + +The methods should be self explaining, loadDocument() loads a document file and returns false on error, +numberOfPages() returns the number of pages, pageSize() returns the size of the page and pictureOfPage() +returns the picture representation of the page. + +Our first version of our Generator is a basic one which just provides page pictures to the document class. + +The API of the Generator looks like the following: + +\code +#include "magicdocument.h" + +#include + +class MagicGenerator : public Okular::Generator +{ + public: + MagicGenerator( QObject *parent, const QVariantList &args ); + ~MagicGenerator(); + + bool loadDocument( const QString &fileName, QVector &pages ); + + bool canGeneratePixmap() const; + void generatePixmap( Okular::PixmapRequest *request ); + + protected: + bool doCloseDocument(); + + private: + MagicDocument mMagicDocument; +}; +\endcode + +The implementation of the Generator looks like this: + +\code +#include + +#include "magicgenerator.h" + +OKULAR_EXPORT_PLUGIN(MagicGenerator, "libokularGenerator_magic.json") + +MagicGenerator::MagicGenerator( QObject *parent, const QVariantList &args ) + : Okular::Generator( parent, args ) +{ +} + +MagicGenerator::~MagicGenerator() +{ +} + +bool MagicGenerator::loadDocument( const QString &fileName, QVector &pages ) +{ + if ( !mMagicDocument.loadDocument( fileName ) ) { + emit error( i18n( "Unable to load document" ), -1 ); + return false; + } + + pagesVector.resize( mMagicDocument.numberOfPages() ); + + for ( int i = 0; i < mMagicDocument.numberOfPages(); ++i ) { + const QSize size = mMagicDocument.pageSize( i ); + + Okular::Page * page = new Okular::Page( i, size.width(), size.height(), Okular::Rotation0 ); + pages[ i ] = page; + } + + return true; +} + +bool MagicGenerator::doCloseDocument() +{ + return true; +} + +bool MagicGenerator::canGeneratePixmap() const +{ + return true; +} + +void MagicGenerator::generatePixmap( Okular::PixmapRequest *request ) +{ + QImage image = mMagicDocument.pictureOfPage( request->pageNumber() ); + + image = image.scaled( request->width(), request->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + + request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) ); + + signalPixmapRequestDone( request ); +} + +\endcode + +As you can see implementing a basic Generator is quite easy. The loadDocument() method opens the document file +and extracts the number of pages. For every page in the document it adds an Okular::Page object to the pages vector +which is passed in as method argument. Each page is initialized with its page number, width, height and initial rotation. +These page objects will be stored in the document object and act as a container for the picture representation +of the pages. This code is the same for nearly every Generator. On an failure the error() signal can be emitted +to inform the user about the issue. This code is the same for nearly every Generator. + +In the doCloseDocument() method you should close the document and free all resources you have allocated in openDocument(). + +Now we come to the picture creation methods. The canGeneratorPixmap() method returns whether the Generator is currently +able to handle a new pixmap generation request. For a simple Generator like our one that's always the case as it works +linear, however a multithreaded Generator might return false here if it is still waiting for one of its working +threads to finish. In this case the document class will try to request the pixmap later again. + +The generatePixmap() method does the actual fetching of the picture for a page. The page number, requested width and +height of the page is encapsulated in the passed Okular::PixmapRequest object. +So the task of the Generator is to create a pixmap of the requested page in the requested size and then store this +pixmap in the Okular::Page object which is associated with the page request. +When this task is finished, the Generator has to call signalPixmapRequestDone() with the page request object +as argument. This extra call is needed to allow the Generator to use signals and slots internally and create the +pixmap asynchronously. + +So now you have the code of a working Okular Generator, the next step is to tell Okular about the new plugin. +Like in other places in KDE that is done by .desktop files, which are installed to the services directory. + +Every Generator needs 1 .json, 3 .desktop files, and 1 .xml file: + + \li libokularGenerator_<name>.json + \li okularApplication_<name>.desktop + \li okular<name>.desktop + \li org.kde.mobile.okular_<name>.desktop + \li org.kde.okular-<name>.metainfo.xml + +where <name> should be the name of the document format. So for our Magic Document Generator we +create the following 4 files: + + \li libokularGenerator_magic.json + \li okularApplication_magic.desktop + \li okularMagic.desktop + \li org.kde.mobile.okular_magic.desktop + \li org.kde.okular-magic.metainfo.xml + +where libokularGenerator_magic.json has the following content something like this + +\verbatim +{ + "KPlugin": { + "Authors": [ + { + "Email": "author@hosting.suffix", + "Name": "Proud Author", + } + ], + "Copyright": "© 2042 Proud Author", + "Id": "okular_magic", + "License": "GPL", + "MimeTypes": [ + "text/magic", + "text/x-magic" + ], + "Name": "Magic Backend", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.0" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} +\endverbatim + +The last five fields has the special meaning to Okular + + \li ServiceType Must be 'okular/Generator' for all Okular Generator Plugins + \li MimeType The mimetype or list of mimetypes of the supported document format(s) + \li X-KDE-Priority When multiple Generators for the same mimetype exists, the one with the highest priority is used + \li X-KDE-okularAPIVersion The version of the Generator Plugin API ('1' currently) + \li X-KDE-okularHasInternalSettings Is 'true' when the Generator provides configuration dialogs + +The first .desktop file has the following content: + +\verbatim +[Desktop Entry] +MimeType=application/x-magic; +Terminal=false +Name=okular +GenericName=Document Viewer +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=Magic +\endverbatim + +You can use the file as it is, you just have to adapt the mimetype. This file is needed to allow Okular +to handle multiple mimetypes. + +The second .desktop file looks like this: + +\verbatim +[Desktop Entry] +Icon=okular +Name=okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-magic; +\endverbatim + +where + + \li X-KDE-Library The name of the plugin library + +You can use the file as it is as well, you just have to adapt the mimetype. This file is needed to allow +the Okular part to handle multiple mimetypes. + +The third .desktop file contains data for the mobile version + +\verbatim +[Desktop Entry] +MimeType=application/x-magic; +Name=Reader +GenericName=Document viewer +Comment=Viewer for various types of documents +TryExec=kpackagelauncherqml -a org.kde.mobile.okular +Exec=kpackagelauncherqml -a org.kde.mobile.okular %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=Magic +\endverbatim + +And the last .xml file has the following content + +\verbatim + + + org.kde.okular-md + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Magic + Adds support for reading Magic documents + + application/magic + + https://okular.kde.org + +\endverbatim + +The last piece you need for a complete Generator is a CMakeLists.txt which compiles and installs the +Generator. Our CMakeLists.txt looks like the following: + +\verbatim +add_definitions(-DTRANSLATION_DOMAIN="okular_magic") + +macro_optional_find_package(Okular) + +include_directories( ${OKULAR_INCLUDE_DIR} ${KF5_INCLUDE_DIR} ${QT_INCLUDES} ) + +########### next target ############### + +set( okularGenerator_magic_PART_SRCS generator_magic.cpp ) + +target_link_libraries( okularGenerator_magic PRIVATE okularcore KF5::I18n KF5::KIOCore ) + +install( TARGETS okularGenerator_magic DESTINATION ${PLUGIN_INSTALL_DIR} ) + +########### install files ############### + +install( FILES okularMagic.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_magic.desktop org.kde.mobile.okular_magic.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-magic.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) +\endverbatim + +The macro_optional_find_package(Okular) call is required to make the ${OKULAR_INCLUDE_DIR} and ${OKULAR_LIBRARIES} +variables available. + +Now you can compile the Generator plugin and install it. After a restart of Okular the new plugin is available +and you can open Magic documents. + +\section okular_generators_with_text A Generator with TextPage support + +In this section we want to extend our Generator to support text search, text extraction and selection +as well. As mentioned in \ref okular_design_text_support, the Generator must provide an Okular::TextPage +object for every page which contains readable text. + +Since we use the helper class MagicDocument to read the data from the document we have to extend it first, +so the new API looks as the following: + +\code +class MagicDocument +{ + public: + MagicDocument(); + ~MagicDocument(); + + bool loadDocument( const QString &fileName ); + + int numberOfPages() const; + + QSize pageSize( int pageNumber ) const; + + QImage pictureOfPage( int pageNumber ) const; + + class TextInfo + { + public: + typedef QList List; + + QChar character; + qreal xPos; + qreal yPos; + qreal width; + qreal height; + }; + + TextInfo::List textOfPage( int pageNumber ); + + private: + ... +}; +\endcode + +MagicDocument has the new internal class TextInfo now, which contains a character and +its absolute position on a page. Furthermore MagicDocument provides a method textOfPage() +which returns a list of all TextInfo objects for a page. + +That's really an optimistic API, in reality it is sometimes quite hard to find out +the position of single characters in a document format. + +With the extension of our helper class we can continue on extending our Generator now: + +\code +#include "magicdocument.h" + +#include + +class MagicGenerator : public Okular::Generator +{ + public: + MagicGenerator( QObject *parent, const QVariantList &args ); + ~MagicGenerator(); + + bool loadDocument( const QString &fileName, QVector &pages ); + + bool canGeneratePixmap() const; + void generatePixmap( Okular::PixmapRequest *request ); + + virtual bool canGenerateTextPage() const; + virtual void generateTextPage( Okular::Page *page, enum Okular::GenerationType type = Okular::Synchronous ); + + protected: + bool doCloseDocument(); + + private: + MagicDocument mMagicDocument; +}; +\endcode + +We have extended the MagicGenerator class by two methods canGenerateTextPage() and generateTextPage(). +The first method is equal to canGeneratePixmap(), it returns whether the Generator is currently able to +handle a new text page generation request. For linear Generators that should be always the case, however +when the generation is done in a separated worker thread, this method might return false. +In this case the document class will try to request the text page later again. + +The second method will generate the Okular::TextPage object for the passed page. Depending on the capabilities +of the Generator and the passed type parameter that is done synchronously or asynchronously. + +Let us take a look at the implementation of these methods in our MagicGenerator: + +\code +#include + +... + +MagicGenerator::MagicGenerator( QObject *parent, const QVariantList &args ) + : Okular::Generator( parent, args ) +{ + setFeature( TextExtraction ); +} + +bool MagicGenerator::canGenerateTextPage() const +{ + return true; +} + +void MagicGenerator::generateTextPage( Okular::Page *page, enum Okular::GenerationType ) +{ + MagicDocument::TextInfo::List characters = mMagicDocument.textOfPage( page->number() ); + if ( characters.isEmpty() ) + return; + + Okular::TextPage *textPage = new Okular::TextPage; + for ( int i = 0; i < characters.count(); ++i ) { + qreal left = characters[ i ].xPos / page->width(); + qreal top = characters[ i ].yPos / page->height(); + qreal right = (characters[ i ].xPos + characters[ i ].width) / page->width(); + qreal bottom = (characters[ i ].yPos + characters[ i ].height) / page->height(); + + textPage->append( characters[ i ].character, + new Okular::NormalizedRect( left, top, right, bottom ) ); + } + + page->setTextPage( textPage ); +} +\endcode + +As you can see the generateTextPage method just iterates over the list of characters returned +by our MagicDocument helper class and adds the character and its normalized bounding rect to +the Okular::TextPage object. At the end the text page is assigned to the page. We don't pay +attention to the GenerationType parameter here, if your Generator want to use threads, it should +check here whether the request shall be done asynchronously or synchronously and start the generation +according to that. Additionally we have to tell the Okular::Generator base class that we support +text handling by setting this flag in the constructor. + +In this state we can now search, select and extract text from Magic documents. + +\section okular_generators_threaded A Generator with Thread support + +Sometimes it makes sense to do the generation of page pictures or text pages asynchronously to +improve performance and don't blocking the user interface. This can be done in two ways, either +by using signals and slots or by using threads. Both have there pros and cons: + +
    +
  • Signals and Slots
  • +
      +
    • Pro: Can be used with backend libraries which are not thread safe
    • +
    • Con: Sometime difficult to implement
    • +
    +
  • Threads
  • +
      +
    • Pro: Easy to implement as you can make synchronous calls to the backend libraries
    • +
    • Con: Backend libraries must be thread safe and you must prevent race conditions by using mutexes
    • +
    +
+ +The signal and slots approach can be achieved with a normal Generator by calling Okular::Generator::signalPixmapRequestDone() +from a slot after pixmap generation has been finished. + +When using threads you should use a slightly different API, which hides most of the thread usage, to make +implementing as easy as possible. + +Let's assume the pictureOfPage() and textOfPage methods in our MagicDocument helper class are thread safe, +so we can use them in a multithreaded environment. +So nothing prevents us from changing the MagicGenerator to use threads for better performance. + +The new MagicGenerator API looks like the following: + +\code +#include "magicdocument.h" + +#include + +class MagicGenerator : public Okular::Generator +{ + public: + MagicGenerator( QObject *parent, const QVariantList &args ); + ~MagicGenerator(); + + bool loadDocument( const QString &fileName, QVector &pages ); + + protected: + bool doCloseDocument(); + + virtual QImage image( Okular::PixmapRequest *request ); + + virtual Okular::TextPage* textPage( Okular::Page *page ); + + private: + MagicDocument mMagicDocument; +}; +\endcode + +As you can see the canGeneratePixmap() generatePixmap(), canGenerateTextPage() and generateTextPage() methods have +been removed and replaced by the image() and textPage() methods. + +Before explaining why, we'll take a look at the implementation: + +\code + +MagicGenerator::MagicGenerator( QObject *parent, const QVariantList &args ) + : Okular::Generator( parent, args ) +{ + setFeature( TextExtraction ); + setFeature( Threaded ); +} + +QImage MagicGenerator::image( Okular::PixmapRequest *request ) +{ + QImage image = mMagicDocument.pictureOfPage( request->pageNumber() ); + + return image.scaled( request->width(), request->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); +} + +Okular::TextPage* textPage( Okular::Page *page ) +{ + MagicDocument::TextInfo::List characters = mMagicDocument.textOfPage( page->number() ); + if ( characters.isEmpty() ) + return 0; + + Okular::TextPage *textPage = new Okular::TextPage; + for ( int i = 0; i < characters.count(); ++i ) { + qreal left = characters[ i ].xPos / page->width(); + qreal top = characters[ i ].yPos / page->height(); + qreal right = (characters[ i ].xPos + characters[ i ].width) / page->width(); + qreal bottom = (characters[ i ].yPos + characters[ i ].height) / page->height(); + + textPage->append( characters[ i ].character, + new Okular::NormalizedRect( left, top, right, bottom ) ); + } + + return textPage; +} +\endcode + +So the first obviously thing is that both methods return a value instead of modifying the page directly. +The reason for this is that both methods are executed in its own thread, so the code executed in them can +block as long as it wants, it won't block the GUI anyway. Additionally we have to tell the Okular::Generator +base class that we can handle threads by setting the flag in the constructor. + +With only a small change we made our MagicGenerator multithreaded now! + +\section okular_generators_extended An Extended Generator + +Now we want to create a new generator with some additional functionality: + + \li Support for document information (author, creation date etc.) + \li Support for a table of content + \li Support for printing the document + \li Support for exporting the document as text + +The new Generator shall be able to handle HTML documents. We choose this format as example, because +we can use QTextDocument to load, render and print a HTML page, so a lot of code can be reused. + +The API of our HTMLGenerator looks like the following: + +\code +#include + +#include + +class HTMLGenerator : public Okular::Generator +{ + public: + HTMLGenerator( QObject *parent, const QVariantList &args ); + ~HTMLGenerator(); + + bool loadDocument( const QString &fileName, QVector &pages ); + + bool canGeneratePixmap() const; + void generatePixmap( Okular::PixmapRequest *request ); + + virtual Okular::DocumentInfo generateDocumentInfo( const QSet &keys ) const; + + virtual const Okular::DocumentSynopsis* generateDocumentSynopsis(); + + virtual bool print( KPrinter &printer ); + + virtual Okular::ExportFormat::List exportFormats() const; + + virtual bool exportTo( const QString &fileName, const Okular::ExportFormat &format ); + + protected: + bool doCloseDocument(); + + private: + QTextDocument *mTextDocument; + Okular::DocumentInfo mDocumentInfo; + Okular::DocumentSynopsis mDocumentSynopsis; +}; +\endcode + +The Generator doesn't support text search and selection, as the code would be quite complex, we'll show +how to do it in the next chapter (not yet written) anyway. + +As you can see we have 5 new methods in the class: + + \li generateDocumentInfo() Creates an Okular::DocumentInfo (which is in fact a QDomDocument) + which contains document information like author, creation time etc. + \li generateDocumentSynopsis() Creates an Okular::DocumentSynopsis (which is a QDomDocument as well) + which contains the table of content. + \li print() Prints the document to the passed printer. + \li exportFormats() Returns the supported export formats. + \li exportTo() Exports the document to the given file in the given format. + +Now that you know what the methods are supposed to do, let's take a look at the implementation: + +\code +#include +#include +#include + +#include +#include + +#include "htmlgenerator.h" + +#include + +OKULAR_EXPORT_PLUGIN(HTMLGenerator, "libokularGenerator_html.json") + +HTMLGenerator::HTMLGenerator( QObject *parent, const QVariantList &args ) + : Okular::Generator( parent, args ), + mTextDocument( 0 ) +{ +} + +HTMLGenerator::~HTMLGenerator() +{ + delete mTextDocument; +} + +bool HTMLGenerator::loadDocument( const QString &fileName, QVector &pages ) +{ + QFile file( fileName ); + if ( !file.open( QIODevice::ReadOnly ) ) { + emit error( i18n( "Unable to open file" ), -1 ); + return false; + } + + const QString data = QString::fromUtf8( file.readAll() ); + + file.close(); + + mTextDocument = new QTextDocument; + mTextDocument->setHtml( data ); + mTextDocument->setPageSize( QSizeF( 600, 800 ) ); + + pages.resize( mTextDocument->pageCount() ); + + for ( int i = 0; i < mTextDocument->pageCount(); ++i ) { + Okular::Page * page = new Okular::Page( i, 600, 800, Okular::Rotation0 ); + pages[ i ] = page; + } + + mDocumentInfo.set( "author", "Tobias Koenig", i18n( "Author" ) ); + mDocumentInfo.set( "title", "The Art of Okular Plugin Development", i18n( "Title" ) ); + + Okular::DocumentViewport viewport = ... // get the viewport of the chapter + + QDomElement item = mDocumentSynopsis.createElement( "Chapter 1" ); + item.setAttribute( "Viewport", viewport.toString() ); + mDocumentSynopsis.appendChild( item ); + + viewport = ... // get the viewport of the subchapter + + QDomElement childItem = mDocumentSynopsis.createElement( "SubChapter 1.1" ); + childItem.setAttribute( "Viewport", viewport.toString() ); + item.appendChild( childItem ); + + return true; +} + +bool HTMLGenerator::doCloseDocument() +{ + delete mTextDocument; + mTextDocument = 0; + + return true; +} + +bool HTMLGenerator::canGeneratePixmap() const +{ + return true; +} + +void HTMLGenerator::generatePixmap( Okular::PixmapRequest *request ) +{ + QPixmap *pixmap = new QPixmap( request->width(), request->height() ); + pixmap->fill( Qt::white ); + + QPainter p; + p.begin( pixmap ); + + qreal width = request->width(); + qreal height = request->height(); + + p.scale( width / 600, height / 800 ); + + const QRect rect( 0, request->pageNumber() * 800, 600, 800 ); + p.translate( QPoint( 0, request->pageNumber() * -800 ) ); + d->mDocument->drawContents( &p, rect ); + p.end(); + + request->page()->setPixmap( request->id(), pixmap ); + + signalPixmapRequestDone( request ); +} + +Okular::DocumentInfo HTMLGenerator::generateDocumentInfo( const QSet &keys ) const +{ + return mDocumentInfo; +} + +const Okular::DocumentSynopsis* HTMLGenerator::generateDocumentSynopsis() +{ + if ( !mDocumentSynopsis.hasChildNodes() ) + return 0; + else + return &mDocumentSynopsis; +} + +bool HTMLGenerator::print( KPrinter &printer ) +{ + QPainter p( &printer ); + + for ( int i = 0; i < mTextDocument->pageCount(); ++i ) { + if ( i != 0 ) + printer.newPage(); + + QRect rect( 0, i * 800, 600, 800 ); + p.translate( QPoint( 0, i * -800 ) ); + mTextDocument->drawContents( &p, rect ); + } +} + +Okular::ExportFormat::List HTMLGenerator::exportFormats() const +{ + return Okular::ExportFormat::standardFormat( Okular::ExportFormat::PlainText ); +} + +bool HTMLGenerator::exportTo( const QString &fileName, const Okular::ExportFormat &format ) +{ + QFile file( fileName ); + if ( !fileName.open( QIODevice::WriteOnly ) ) { + emit error( i18n( "Unable to open file" ), -1 ); + return false; + } + + if ( format.mimeType()->name() == QLatin1String( "text/plain" ) ) + file.writeBlock( mTextDocument->toPlainText().toUtf8() ); + + file.close(); + + return true; +} +\endcode + +Let's take a closer look at the single methods. In the loadDocument() method we try to open the +passed file name and read all the content into the QTextDocument object. By calling +QTextDocument::setPageSize(), the whole document is divided into pages of the given size. +In the next step we create Okular::Page objects for every page in the QTextDocument and fill +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] +*/ diff --git a/Messages.sh b/Messages.sh new file mode 100644 index 0000000..db2ec7e --- /dev/null +++ b/Messages.sh @@ -0,0 +1,5 @@ +#!/bin/sh +$EXTRACTRC *.rc */*.rc >> rc.cpp || exit 11 +$EXTRACTRC $(find conf/ -name "*.ui") $(find core/ -name "*.ui") $(find part/ -name "*.ui") $(ls . | grep -E '\.ui') >> rc.cpp || exit 12 +$EXTRACTATTR --attr=tool,name part/data/drawingtools.xml >> rc.cpp || exit 13 +$XGETTEXT $(find conf/ -name "*.cpp" -o -name "*.h") $(find core/ -name "*.cpp" -o -name "*.h") $(find part/ -name "*.cpp" -o -name "*.h") $(find shell/ -name "*.cpp" -o -name "*.h") $(ls . | grep -E '\.cpp$') $(ls . | grep -E '\.h$') -o $podir/okular.pot diff --git a/Okular5Config.cmake.in b/Okular5Config.cmake.in new file mode 100644 index 0000000..6f9046d --- /dev/null +++ b/Okular5Config.cmake.in @@ -0,0 +1,14 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +find_dependency(Qt5Core @QT_REQUIRED_VERSION@) +find_dependency(Qt5PrintSupport @QT_REQUIRED_VERSION@) +find_dependency(Qt5Widgets @QT_REQUIRED_VERSION@) +find_dependency(KF5CoreAddons @KF5_REQUIRED_VERSION@) +find_dependency(KF5Config @KF5_REQUIRED_VERSION@) +find_dependency(KF5XmlGui @KF5_REQUIRED_VERSION@) + +@PACKAGE_SETUP_AUTOMOC_VARIABLES@ + +include("${CMAKE_CURRENT_LIST_DIR}/Okular5Targets.cmake") diff --git a/OkularConfigureChecks.cmake b/OkularConfigureChecks.cmake new file mode 100644 index 0000000..4b99fee --- /dev/null +++ b/OkularConfigureChecks.cmake @@ -0,0 +1,22 @@ + +option( + OKULAR_FORCE_DRM + "Forces okular to check for DRM to decide if you can copy/print protected pdf. (default=no)" + OFF +) +if (OKULAR_FORCE_DRM) + set(_OKULAR_FORCE_DRM 1) +else (OKULAR_FORCE_DRM) + set(_OKULAR_FORCE_DRM 0) +endif (OKULAR_FORCE_DRM) + +# Check whether malloc_trim(3) is supported. +include(CheckSymbolExists) +check_symbol_exists(malloc_trim "malloc.h" HAVE_MALLOC_TRIM) + +# at the end, output the configuration +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/config-okular.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/config-okular.h +) + diff --git a/README.clang-format b/README.clang-format new file mode 100644 index 0000000..19d1038 --- /dev/null +++ b/README.clang-format @@ -0,0 +1,14 @@ +We introduced clang-format mandatory usage in July 2020. +If you want git blame to ignore the revision in which we did the mass change you can do + git config blame.ignoreRevsFile .git-blame-ignore-revs +on your clone + +To get the clang-format warnings locally instead at CI time we recommend you +to copy the hooks/pre-commit to your .git + cp hooks/pre-commit .git/hooks/ + +We are using clang-format 11 on CI. Unfortunately clang-format is not totally +compatible with older versions of itself. If CI gives you trouble but your local +clang-format disagrees, just apply the changes suggested by CI and then commit +with the --no-verify flag. If you get stuck, don't hesitate to ask the reviewer +to help and they will reformat your commits :) diff --git a/README.internals.png b/README.internals.png new file mode 100644 index 0000000000000000000000000000000000000000..8a9769f1b7205555bde44b158f648bdef972fe68 GIT binary patch literal 33807 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�dvn4L_%f1gDU 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 Oc`v0TSs`xx<^KR0K&v7E literal 0 HcmV?d00001 diff --git a/TODO b/TODO new file mode 100644 index 0000000..49925f1 --- /dev/null +++ b/TODO @@ -0,0 +1,274 @@ +TODO - okular +Legend: + ADD - ADDed (new feature) + CHG - CHanGed (existing behavior) + FIX - FIXed (bug or regression) + MRG - MeRGed (code from a branch or a patch) + +Bugs and wishes to close when moving okular to kdegraphics: +-> WISH 91146: Add capability to extract plain text from a pdf file. +-> WISH 91251: "Magic marker" tool for higlighting text +-> WISH 91809: kpdf cant fill in formulars +-> WISH 93416: support for pdf sticky notes +-> BUG 97869: kpdf fails to properly hide the context menu +-> WISH 99352: Cannot change orientation of pdf file +-> WISH 99787: kpdf needs to have a bookmark list +-> WISH 100341: first page at right, in two pages mode +-> WISH 102523: wish: if opening second file, file/open dir should be dirname($current_file) +-> WISH 102704: Handle gzipped and bzipped PDFs +-> WISH 102788: Current page number visible +-> WISH 103051: make notes on pdf files +-> BUG 106546: Search with "/" and ALT+TAB +-> WISH 107998: kpdf horizontal scroll bar +-> WISH 109346: ability to select everything on page(s) and use ctrl+a to select all (text) +-> BUG 110440: Almost all options in Find dialog are always disabled +-> WISH 111651: Usability: Make find-as-you-type widget more distinguishable +-> WISH 114648: An option to deny documents' fullscreen requests is desirable. +-> WISH 115557: Automatically detect and remove white page borders +-> WISH 117045: text search: continue backwards +-> WISH 117449: kpdf should read files from stdin with the - option +-> WISH 117805: Wish: Select pages like kghostview +-> WISH 118872: An option to read all the document with Kttsd +-> WISH 118938: No way to find out the page size(s) +-> WISH 119084: pdf attachment support: saving/opening attachments in pdf... +-> WISH 119455: use poppler library for kpdf +-> WISH 119919: make it possible to disable transition in presentation mode +-> WISH 122863: Show page numbers of chapters/bookmarks in contents tab +-> BUG 130123: kpdf text selection inconsistent with the rest of KDE +-> WISH 131045: Add context menu for URLs +-> WISH 132152: Usability: contents / pdfbookmarks panel is not accessible via keyboard only +-> WISH 134115: specifing to kpdf the first-opened page from command line +-> WISH 134646: remember (and restore) zoom per file not per app +-> WISH 136820: would like a reload button or menu item in KPDF +-> WISH 137905: command-line option for presentation mode +-> WISH 145345: goto page: update slider while editing page number + +In progress [working on]: +-> search: backward text search (BR117045) +-> various backends: fill about data information +-> gui: add config for gfx (yes/no) and text (yes/no/kde) antialias +-> core: provide a binary compatible okularcore library to extend the format capabilities +-> KPDF -> okular conversion of configuration & datafiles {configuration(done), document data(in progress), kwallet passwords(missing)} +-> inverse search (BR113191) + find with an usability expert the "best" way to activate such a link + provide a configuration widget to choose the editor and configure a custom one +-> toc: highlight the row of the current page (BR127358) + (check if there's a better way to do the highlighting - in case just edit TOCModel) +-> annotations: renderers in PagePainter (for the 6 annots) +-> annotations: handlers in PageView for WindowAnnots and others.. +-> annotations: creators in PageViewAnnotator (40% done) +-> annotations: framework (BR67300,BR62793) and tools (BR67300,BR91251) +-> annotations: add the annot pane (cool plz!) +-> rotate the whole document / individual pages (on screen/print?) (BR99352) +-> link: add a Okular::Anchor link class +-> pageview: update layout when toggling the 'ebook atyle alignment' + +More items (first items will enter 'In progress list' first): +-> annotations: "move" and "delete" tools +-> rethink which buttons show in the toolbar (BR139825) +-> annotations: configurabile tools in the toolbar (BR137903) +-> pageview: add vp damaging queue and flush function. add coolfx to smoothmove using damaging +-> annotations: toolbar: display tooltip only the first time +-> annotations: provide nice wizards. Make it easy to deliver/copy/move the xml files (by Uga) +-> GHNS: get hot new ebooks on the supported formats (pdf for now) (enrico) +-> pageview: add scrollbar marks for bookmarks (like kate) +-> pageview: change document viewport after mouse scrolling ended (not every scroll frame) + this will give better mvc consistancy +-> other info on pdfs properties: number of accessed times, time spent on pdf, ... +-> part: collapsing the left panel will hide it (activate hiding action) +-> preload: add a delay when forward loading pages +-> bookmarks: fastmarks (new bookmark concept with tab-like signs, shortcuts, etc) (BR +-> viewport restoring: sometimes it seems to restore the viewport a bit under where it was +-> core: Delay TOC (DocumentSynopsis) generation (and move it on thread) +-> core: add a way to handle "named xpdf links" in Okular::Action instead of resolving all + dests when displaying a page (speedups a lot generation of page with many links) +-> toolbar: move the toolbar to the top of pageview (left panel is really at the left of the toolbar) +-> thumbnailslist: clinking on highlighted rect should bring the viewport to that search result (BR98334) +-> Dom framework to cache document metadata. It should archive those types of data: + (NOTE: already Dom'ed object is marked with 'X') + - Synopsis will go there after 1st generation (so we can edit it too) + - Document info (after the 1st gen) + - Bookmarked pages + - Current Viewport and 10 history steps + - Edited pages (rotated/with_data for example) + - Overlay editing (highlighting/notations/etc..) + - Presentation related overrides (FS mode, individual / global transitions) + - ..more stuff.. but this isn't a problem, since a QDom is flexible by design + The Object will reside into the Document and must not be accessible by Observers in + a direct way. Dom format, relations to other classes and accessing must be specified + in a separated diagram or text file. + - Plus think at storing xml data to an external shared server.. something that + has to do with versioning data.. (shared annotations, bookmarks & co.) +-> add okular manual in PDF format loaded on the first startup or on menu->help->manual + this visually explains basic usage, mouse buttons functions & more.. +-> ADD: click over image allows "save image" [60% done (activerect of type image)] +-> bookview: 3d opengl widget for viewing the document as a real book (turning pages, etc..) +-> wallet: use asynchronous interface (to prevent ui-blocking) +-> restore a location from a given url (like http:/someurl?stringForViewport) (BR99240) +-> automatic online dictionaries / translators (BR80338) +-> sidebar: evaluate wether to make the left toolbox auto-hiding (kicker like) (BR94495) +-> add OCR for building TextPages out of pure graphical (aka scanned) pages +-> presentation: provide a pageX/totalPages indicator in addition to the circle one +-> presentation: implement missing transitions (6/11 done) (BR139284) +-> presentation: save a flag (to the xml) to open a pdf in presentation mode +-> presentation: wheel not visible on black. gradient appreciated on lighter backgrounds. +-> presentation: 2 pages per view, for users reading ebooks with wide screens. +-> goto 'logical' page (usually differs from pdf's page) (req. by Luca Burrelli) +-> move some document related features from part to the document (see find, goto dialog, ...) +-> tools: ruler (BR155737), measure: distance, perimeter, ?area?, color picker +-> export: export to other formats keeping formatting (PS is basically printing. PNG is easy too) +-> export: extract images (have a look at ImageOutputDev.cc and pdfimages.cc from xpdf (not in our xpdf sources)) +-> history as a toolbox child (collecting Doc's viewport changes notifications) +-> take care of TODOs in code +-> cleanup code and update README.png + +Icons needed: +- okular (ToolBAR): 1 continuous, 2 tied-pages, 3 Normal (not scroll only, it + performs other ops), 4 Zoom, 5 Select, 6 Annotation/Review +- okular (Edit Tools): text highlighter, line, polygon, ellipse, text underline +- COMMON (here in ToolBox): Toc, Annotations + +Done (newest features come first): +-> ADD: core: forms support (BR91809) +-> ADD: kspeech TTS interface. speech {document(BR118872) / page / selection} +-> CHG: thumbnails list: refactor to do internal rendering as pageview does +-> ADD: select more than one annotation in the annotation tree (BR155668) +-> ADD: text selection: select all (BR109346) +-> ADD: text selection in wordprocessor style (BR130123) +-> ADD: open gzipped and bzipped documents (BR102704) +-> ADD: thumbnailslist: show Viewport in a blended way, allowing to be dragged (BR135521) +-> CHG: async way to read the fonts, no more blocking properties dialog +-> CHG: use ThreadWeaver for the rotating jobs +-> ADD: save/restore the values of the form fields when closing/opening a documents +-> ADD: "dummy" mode for a very simple interface when the okular part is in eg printing preview +-> ADD: bookmarks: improved interface, with easy handling of the bookmarks of all the documents (BR99787,BR136113) +-> ADD: Reload action to force the reload of the current document (BR136820) +-> CHG: renamed Okular::Link to Okular::Action +-> ADD: presentation: add page counter and a widget to manually set pages on the top bar +-> ADD: basic support for Text and Line DjVu annotations +-> FIX: regression: popup context menu when using right button in selection mode (BR99315) +-> ADD: annotations: add config option for default name change +-> ADD: presentation: add a red pencil that creates ink annotations +-> CHG: support links with shapes different than a rectangle +-> ADD: export: give the generators the ability to export all the text to plain file (if supported), the PDF generator already use this (BR91146) +-> CHG: search: use shortcut for 'find next' action (not the default one) in find-ahead +-> CHG: use shortcuts for next and prev page even in presentation mode (by Tobias Koenig) +-> ADD: bookmarks: go to next/previous actions (showing in thumbnailslist rmb popup too) +-> CHG: open dialog: switch to directory where the already opened (local) file is +-> ADD: toc: add search bar (a 'prune on type' lineedit like in thumbnails widget) (BR99349) +-> FIX: kfile-plugins/pdf: provide internal support and rewrite that plugin (drops xpdf dependancy from kdegraphics) (by ktech) +-> CHG: core: abstract TextPage generation (the last xpdf dependant class!) +-> CHG: create a DocumentInfo structure for passing the font information from generators to the document +-> ADD: presentation: link following (BR98388) +-> ADD: add ebook-friendly alignment option, better layouting (BR100341) +-> FIX: random crash when closing kpdf with kapp->quit() (don't use Settings:: in destructors) +-> FIX: implement links for starting end exiting from presentation mode (pdf FullScreen, Close actions) +-> CHG: cursor wraps on screen for dragging the page/dynZooming +-> FIX: raised scaling performance by 10x times for typ usage, removed odd cases, speedups to viewScroll and dynZoom +-> ADD: annotations: complete xml storage/retrieval of internal annotations +-> CHG: page properties (bookmarks, annotations, ...) storage moved to Page class +-> ADD: sidebar: add shortcut for showing/hiding it (BR99316) +-> ADD: annotations: PDF1.6 reader (PDF's annotations -> our data structures) +-> ADD: Internal data structures for annotations handling. +-> FIX: rmb when no doc displayed to restore menu +-> ADD: Save zoom setting on exit +-> ADD: Put fonts used by the document on the properties dialog +-> ADD: partial implementation of XYZ links +-> ADD: google-like search on thumbnails +-> ADD: use kde wallet for storing passwords of protected files +*> The branch 'kpdf_annotations' was created at this point. [2005-Feb-12] +-> FIX: trigger redraw on 'filter text' on current page (need new highlight engine first) +-> ADD: Obey DRM is now a configuration option +-> FIX: fixed viewport saving/restoring (+performance fix) on presentation mode +-> FIX: leakfix when closing document while thread was running (no more leaks now) +-> FIX: direct hi-performance pixels manipulation for highlighting (instead of the obsoleted setRasterOp) +-> CHG: new search api. supports multiple searches at once, multiple highlights per page +-> ADD: pageView moves smoothly when searching / moving in history +-> ADD: better bookmark rendering in thumbnailslist (show 'clip overlay') +-> CHG: changes and cleanups in pageView's mouse handling functions +-> ADD: KTTSD simple support: speech selection using kspeech api via pure dcop (don't break compatibility) +-> CHG: right click and drag while in 'normal' mode changes to 'selection' mode and selects +-> FIX: complete valgrind check and leakfix (2 leaks were present) [27-Jan-04] +-> ADD: history, forward/back history actions, history links and xml storage (10 steps) +-> ADD: rmb popup on thumbnailslist (the popup shared with pageView: same behavior) +-> ADD: display 'current page' / 'total pages' with analog indicator, active labels, etc +-> CHG: Presentation mode is now Ctrl+Shift+p instead of F9 because it was colliding with Konqueror's toggle sidebar +-> FIX: various in memory unallocator, preload with single pages, pageview +-> FIX: optimized pageView (removed 1 waster req on start, lowered reqs) +-> FIX: memory unloading order and hard swap avoiding +-> CHG: open and open-recent buttons unified in Shell +-> CHG: lens icon for the find-ahead messages +-> ADD: page preloading +-> FIX: smarter memory management / prioritize queries +-> ADD: type ahead search in pageview (type '/' then the word to search..) (JakubS) +-> FIX: scroll page if the searched string is not visible +-> FIX: use a global Viewport over the document (linked views, real link following, location restoring, etc) +-> FIX: wrong zoom buttons order (BR74248) (check consistancy with kdvi/kviewshell/kghostview/.. (not konq)) +-> ADD: presentation: cursor modes: hidden, visible, hidden with delay (Tobias) +-> ADD: presentation: default transition which is used when no transition is defined in document (Tobias) +-> ADD: presentation: support for automatic advance and loop on last page (Tobias) +-> ADD: presentation: add additional presentation page to settings dialog (Tobias) +-> CHG: presentation: the round wheel indicator can be clicked to change page +-> FIX: layout margins on pageView +-> ADD: restore the last active page when a file is opened again +-> ADD: Save bookmarks into a file so you they get recovered when opening the same file again (Albert) +-> FIX: searchline back to work +-> CHG: DocumentInfo is now a DomTree and the properties dialog is dynamically generated (Tobias) +-> ADD: Presentation transitions are loaded from the pdf files as well as fullscreen state (Tobias) +*> Merged on HEAD on 2005-01-02 (The branch is frozen, development continues here) +-> FIX: Fix my update cursor FIX :-D +-> ADD: Make kpdf aware of Find and GoToPage actions +-> FIX: Update cursor correctly when a link moves to a page and the cursor is over a link on that page +-> ADD: Asynchronous PDF Generator implementation (for the user: faster UI, preloading, etc..) +-> FIX: Memory manager (free cache if needed, avoid disk swap and oom) +-> ADD: Presentation View (only the 'glitter' transition implemented for now) +-> FIX: FixPack1 [dyn_zoom repaints, initial panel width, zoom_lineedit focus proxy, searchwidget refactor{thumbs restoring on clear, buttons size, less code}, highlight bookmarked thumbnails] +-> FIX: Some fullScreen loving, if we are on fullscreen put an action on RMB menu ti get out of it, if we were on fullScreen mode on exit bring back correctly if we were also seeing toolbar or menubar +-> FIX: When in non continuous mode and scrolling up a page, set the viewport at the bottom of the page (Albert) +-> ADD: Show the window maximized when the user opens the program for the very first time (Albert) +-> ADD: Use 'Generators' as providers for contents generation +-> ADD: Add properties dialog (Albert) +-> ADD: Support for show/hide menubar in rmb menu, different from HEAD so that supports Konqueror too (Albert) +-> ADD: Watch File option (Albert) +-> ADD: import Marco Martin's "another kpdf icon" (kde-look: 16146) (Albert) +-> ADD: dynamic zoom with mid mouse button (click and drag up-down to zoom in-out) +-> FIX: merge select text & select gfx, two sections on the same pop-up menu +-> ADD: reading aids (inverted display, recolor, black/white, draw link border, draw image border) +-> FIX: zoom preserved when switching modes and flickerless drawing +-> ADD: Printing as PS instead of as image (Albert) +-> ADD: Remember page on session logout and put the document in it on session restore (Albert) +-> ADD: gfx capturing tool +-> ADD: composited renderer framework (in addition to a fast light one) +-> FIX: pageview repaint done internally (speed boost and reduced memory consumption) +-> ADD: KConfigXT settings framework and Accessibility config (acc. code mostly not done) +-> FIX: workaround for scrollview bug 1/2 (painting hidden widgets under certain circumstances) +-> ADD: zoom into a rect defined by mouse (aka zoom to window) +-> FIX: sheet rotation in landscape case +-> ADD: Some dcop functions (goToPage, openDocument and give # of pages) (Albert) +-> MRG: link following ('actionMovie' kind is missing) +-> ADD: text selection (rectangular blocks) in selection mode +-> ADD: autoscroll page with Shift+Up/Dn keys (exact konqueror's behavior) +-> CHG: remake single page mode +-> FIX: zoom buttons in sync with text +-> ADD: continuous mode +-> ADD: multiple pages per view (gui selects 1 or 2 ppv) +-> MRG: the option to open password protected files (from head) +-> MRG: the Table Of Contents (from head) +-> ADD: a 'search bar' with prune-as-you-type feature +-> MRG: Albert's search ported and implemented case sensitive +-> CHG: smart handling of pixmap using an Observer ID (thumbnails are gone, only pixmaps now) +-> FIX: some toolbar/menu changes +-> ADD: outline bottom and right edges (of pages) +-> FIX: centering pages in the view +-> FIX: kpdf output at 100% has exactly the same size as acroread now +-> CHG: qsplitter layouting +-> FIX: zooming works as expected (and added 'fit to page' too) +-> ADD: new go to page dialog +-> GHG: previews sorted by visible areas (prioritize items where the scrollbar is) +-> FIX: previews speedup: 50-100% +-> CHG: use local instead of X memory for thumbnails (..) +-> MRG: merge lots of kpdf_part and part (centralview) code (to simplify/cleanup) +*> The branch 'kpdf_experiments' was created at this point. Code refactoring started. +-> ADD: Completely use xpdf code for rendering that solves most font problems (Albert) +-> MRG: Replace xpdf version with lastest one (3.00) that supports PDF 1.5 (Albert) +-> newest added features are at the top of the list diff --git a/_clang-format b/_clang-format new file mode 100644 index 0000000..7f79f39 --- /dev/null +++ b/_clang-format @@ -0,0 +1,88 @@ +--- +# SPDX-License-Identifier: MIT +# +# Copyright (C) 2019 Christoph Cullmann +# Copyright (C) 2019 Gernot Gebhard +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Style for C++ +Language: Cpp + +# base is WebKit coding style: https://webkit.org/code-style-guidelines/ +# below are only things set that diverge from this style! +BasedOnStyle: WebKit + +# enforce C++11 (e.g. for std::vector> +Standard: Cpp11 + +# 4 spaces indent +TabWidth: 4 + +# 3 * 80 wide lines +ColumnLimit: 240 + +# sort includes inside line separated groups +SortIncludes: true + +# break before braces on function, namespace and class definitions. +BreakBeforeBraces: Linux + +# CrlInstruction *a; +PointerAlignment: Right + +# horizontally aligns arguments after an open bracket. +AlignAfterOpenBracket: Align + +# align trailing comments +AlignTrailingComments: true + +# don't move all parameters to new line +AllowAllParametersOfDeclarationOnNextLine: false + +# no single line functions +AllowShortFunctionsOnASingleLine: None + +# always break before you encounter multi line strings +AlwaysBreakBeforeMultilineStrings: true + +# don't move arguments to own lines if they are not all on the same +BinPackArguments: false + +# don't move parameters to own lines if they are not all on the same +BinPackParameters: false + +# don't break binary ops +BreakBeforeBinaryOperators: None + +# format C++11 braced lists like function calls +Cpp11BracedListStyle: true + +# remove empty lines +KeepEmptyLinesAtTheStartOfBlocks: false + +# no namespace indentation to keep indent level low +NamespaceIndentation: None + +# we use template< without space. +SpaceAfterTemplateKeyword: false + +# macros for which the opening brace stays attached. +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] diff --git a/aboutdata.h b/aboutdata.h new file mode 100644 index 0000000..af73e1e --- /dev/null +++ b/aboutdata.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 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 _ABOUTDATA_H_ +#define _ABOUTDATA_H_ + +#include + +#include "core/version.h" + +#include + +inline KAboutData okularAboutData() +{ + KAboutData about(QStringLiteral("okular"), + i18n("Okular"), + QStringLiteral(OKULAR_VERSION_STRING), + i18n("Okular, a universal document viewer"), + KAboutLicense::GPL, + i18n("(C) 2002 Wilco Greven, Christophe Devriese\n" + "(C) 2004-2005 Enrico Ros\n" + "(C) 2005 Piotr Szymanski\n" + "(C) 2004-2017 Albert Astals Cid\n" + "(C) 2006-2009 Pino Toscano"), + QString(), + QStringLiteral("https://okular.kde.org")); + + about.addAuthor(QStringLiteral("Pino Toscano"), i18n("Former maintainer"), QStringLiteral("pino@kde.org")); + about.addAuthor(QStringLiteral("Tobias Koenig"), i18n("Lots of framework work, ODT and FictionBook backends"), QStringLiteral("tokoe@kde.org")); + about.addAuthor(QStringLiteral("Albert Astals Cid"), i18n("Developer"), QStringLiteral("aacid@kde.org")); + about.addAuthor(QStringLiteral("Piotr Szymanski"), i18n("Created Okular from KPDF codebase"), QStringLiteral("djurban@pld-dc.org")); + about.addAuthor(QStringLiteral("Enrico Ros"), i18n("KPDF developer"), QStringLiteral("eros.kde@email.it")); + about.addCredit(QStringLiteral("Eugene Trounev"), i18n("Annotations artwork"), QStringLiteral("eugene.trounev@gmail.com")); + about.addCredit(QStringLiteral("Jiri Baum - NICTA"), i18n("Table selection tool"), QStringLiteral("jiri@baum.com.au")); + about.addCredit(QStringLiteral("Fabio D'Urso"), i18n("Annotation improvements"), QStringLiteral("fabiodurso@hotmail.it")); + + return about; +} + +#endif diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt new file mode 100644 index 0000000..64b5d7d --- /dev/null +++ b/autotests/CMakeLists.txt @@ -0,0 +1,135 @@ +add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) + +macro(add_conf_unittest _source) + set(_test ${_source} ../part/editdrawingtooldialog.cpp) + get_filename_component(_name ${_source} NAME_WE) + add_executable( ${_name} ${_test} ) + add_test( NAME ${_name} COMMAND ${_name} ) + ecm_mark_as_test(${_name}) + target_link_libraries( ${_name} + Qt5::Test + Qt5::Widgets + Qt5::Xml + KF5::I18n + KF5::Completion + KF5::WidgetsAddons + ) +endmacro () + +add_conf_unittest(editdrawingtooldialogtest.cpp) + +ecm_add_test(shelltest.cpp ../shell/shellutils.cpp + TEST_NAME "shelltest" + LINK_LIBRARIES Qt5::Test okularcore +) + +if(Poppler_Qt5_FOUND) + if (BUILD_DESKTOP) + ecm_add_test(parttest.cpp closedialoghelper.cpp + TEST_NAME "parttest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore okularpart + ) + endif() + + ecm_add_test(visibilitytest.cpp + TEST_NAME "visibilitytest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore + ) + + ecm_add_test(kjsfunctionstest.cpp + TEST_NAME "kjsfunctionstest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore + ) + + ecm_add_test(formattest.cpp + TEST_NAME "formattest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore + ) +endif() + +ecm_add_test(documenttest.cpp + TEST_NAME "documenttest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore KF5::ThreadWeaver +) + +ecm_add_test(searchtest.cpp + TEST_NAME "searchtest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore +) + +ecm_add_test(annotationstest.cpp + TEST_NAME "annotationstest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore +) + +ecm_add_test(urldetecttest.cpp + TEST_NAME "urldetecttest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml KF5::CoreAddons +) + +ecm_add_test(editannotationcontentstest.cpp testingutils.cpp + TEST_NAME "editannotationcontentstest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore +) + +ecm_add_test(addremoveannotationtest.cpp testingutils.cpp + TEST_NAME "addremoveannotationtest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore +) + +ecm_add_test(translateannotationtest.cpp testingutils.cpp + TEST_NAME "translateannotationtest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore +) + +ecm_add_test(modifyannotationpropertiestest.cpp testingutils.cpp + TEST_NAME "modifyannotationpropertiestest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore +) + +ecm_add_test(editformstest.cpp + TEST_NAME "editformstest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore +) + +ecm_add_test(calculatetexttest.cpp + TEST_NAME "calculatetexttest" + LINK_LIBRARIES Qt5::Widgets Qt5::Test okularcore +) + +if(KF5Activities_FOUND AND BUILD_DESKTOP) + ecm_add_test(mainshelltest.cpp ../shell/okular_main.cpp ../shell/shellutils.cpp ../shell/shell.cpp closedialoghelper.cpp + TEST_NAME "mainshelltest" + LINK_LIBRARIES Qt5::Test KF5::Activities okularpart okularcore + ) + target_compile_definitions(mainshelltest PRIVATE OKULAR_BINARY="$") +endif() + +if(BUILD_DESKTOP) + ecm_add_test(annotationtoolbartest.cpp ../shell/okular_main.cpp ../shell/shellutils.cpp ../shell/shell.cpp closedialoghelper.cpp + TEST_NAME "annotationtoolbartest" + LINK_LIBRARIES Qt5::Test okularpart + ) +endif() + +ecm_add_test(generatorstest.cpp + TEST_NAME "generatorstest" + LINK_LIBRARIES Qt5::Test KF5::CoreAddons okularcore +) +target_compile_definitions(generatorstest PRIVATE GENERATORS_BUILD_DIR="${CMAKE_BINARY_DIR}/generators") + +ecm_add_test(signatureformtest.cpp + TEST_NAME "signatureformtest" + LINK_LIBRARIES Qt5::Test okularcore +) + +find_package(Discount "2") + +if(discount_FOUND) + ecm_add_test(markdowntest.cpp ../generators/markdown/converter.cpp + TEST_NAME "markdowntest" + LINK_LIBRARIES Qt5::Test okularcore KF5::I18n discount::Lib + ) +endif() diff --git a/autotests/addremoveannotationtest.cpp b/autotests/addremoveannotationtest.cpp new file mode 100644 index 0000000..cb4f357 --- /dev/null +++ b/autotests/addremoveannotationtest.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../core/annotations.h" +#include "../core/document.h" +#include "../core/page.h" +#include "../settings_core.h" +#include "testingutils.h" + +class AddRemoveAnnotationTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void init(); + void cleanup(); + void testAddAnnotations(); + void testAddAnnotationUndoWithRotate_Bug318091(); + void testRemoveAnnotations(); + +private: + Okular::Document *m_document; +}; + +void AddRemoveAnnotationTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("addannotationtest")); + m_document = new Okular::Document(nullptr); +} + +void AddRemoveAnnotationTest::init() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); +} + +void AddRemoveAnnotationTest::cleanup() +{ + m_document->closeDocument(); +} + +void AddRemoveAnnotationTest::testAddAnnotations() +{ + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Create two distinct text annotations + Okular::Annotation *annot1 = new Okular::TextAnnotation(); + annot1->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + annot1->setContents(QStringLiteral("annot contents")); + + Okular::Annotation *annot2 = new Okular::TextAnnotation(); + annot2->setBoundingRectangle(Okular::NormalizedRect(0.2, 0.2, 0.3, 0.4)); + annot2->setContents(QStringLiteral("annot contents")); + + // The two annotations shold have different properties XML strings + QVERIFY(TestingUtils::getAnnotationXml(annot1) != TestingUtils::getAnnotationXml(annot2)); + + // We start with no annotations in the docuemnt + QVERIFY(m_document->page(0)->annotations().size() == 0); + + // After adding annot1 we should have one annotation in the page and it should be annot1. + m_document->addPageAnnotation(0, annot1); + QVERIFY(m_document->page(0)->annotations().size() == 1); + QCOMPARE(annot1, m_document->page(0)->annotations().first()); + + // Record the properties and name of annot1 just after insertion for later comparisons + QString origLine1Xml = TestingUtils::getAnnotationXml(annot1); + QString annot1Name = annot1->uniqueName(); + QVERIFY(!annot1Name.isEmpty()); + + // Now undo the addition of annot1 and verify that annot1's properties haven't changed + m_document->undo(); + QVERIFY(m_document->page(0)->annotations().empty()); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); + QCOMPARE(TestingUtils::getAnnotationXml(annot1), origLine1Xml); + + // redo addition of annot1 + m_document->redo(); + QVERIFY(m_document->page(0)->annotations().size() == 1); + QVERIFY(annot1 == m_document->page(0)->annotations().first()); + QCOMPARE(TestingUtils::getAnnotationXml(annot1), origLine1Xml); + + // undo once more + m_document->undo(); + QVERIFY(m_document->page(0)->annotations().empty()); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); + QCOMPARE(TestingUtils::getAnnotationXml(annot1), origLine1Xml); + + // Set AnnotationDisposeWatcher dispose function on annot1 so we can detect + // when it is deleted + annot1->setDisposeDataFunction(TestingUtils::AnnotationDisposeWatcher::disposeAnnotation); + TestingUtils::AnnotationDisposeWatcher::resetDisposedAnnotationName(); + QCOMPARE(TestingUtils::AnnotationDisposeWatcher::disposedAnnotationName(), QString()); + + // now add annot2 + m_document->addPageAnnotation(0, annot2); + QString annot2Name = annot2->uniqueName(); + QVERIFY(!annot2Name.isEmpty()); + QVERIFY(annot1Name != annot2Name); + QVERIFY(m_document->page(0)->annotations().size() == 1); + QCOMPARE(annot2, m_document->page(0)->annotations().first()); + + // Check that adding annot2 while annot1 was in the unadded state triggered the deletion of annot1 + QVERIFY(TestingUtils::AnnotationDisposeWatcher::disposedAnnotationName() == annot1Name); +} + +void AddRemoveAnnotationTest::testAddAnnotationUndoWithRotate_Bug318091() +{ + Okular::Annotation *annot = new Okular::TextAnnotation(); + annot->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + annot->setContents(QStringLiteral("annot contents")); + + m_document->addPageAnnotation(0, annot); + QString origAnnotXml = TestingUtils::getAnnotationXml(annot); + + // Now undo annotation addition, rotate the page, and redo to annotation addition + m_document->undo(); + m_document->setRotation(1); + m_document->redo(); + + // Verify that annotation's properties remain unchanged + // In Bug318091 the bounding rectangle was being rotated upon each redo + QString newAnnotXml = TestingUtils::getAnnotationXml(annot); + QCOMPARE(origAnnotXml, newAnnotXml); +} + +void AddRemoveAnnotationTest::testRemoveAnnotations() +{ + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Create two distinct text annotations + Okular::Annotation *annot1 = new Okular::TextAnnotation(); + annot1->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + annot1->setContents(QStringLiteral("annot contents")); + + Okular::Annotation *annot2 = new Okular::TextAnnotation(); + annot2->setBoundingRectangle(Okular::NormalizedRect(0.2, 0.2, 0.3, 0.4)); + annot2->setContents(QStringLiteral("annot contents")); + + // Add annot1 and annot2 to document + m_document->addPageAnnotation(0, annot1); + m_document->addPageAnnotation(0, annot2); + QVERIFY(m_document->page(0)->annotations().size() == 2); + QVERIFY(m_document->page(0)->annotations().contains(annot1)); + QVERIFY(m_document->page(0)->annotations().contains(annot2)); + + // Now remove annot1 + m_document->removePageAnnotation(0, annot1); + QVERIFY(m_document->page(0)->annotations().size() == 1); + QVERIFY(m_document->page(0)->annotations().contains(annot2)); + + // Undo removal of annot1 + m_document->undo(); + QVERIFY(m_document->page(0)->annotations().size() == 2); + QVERIFY(m_document->page(0)->annotations().contains(annot1)); + QVERIFY(m_document->page(0)->annotations().contains(annot2)); + + // Redo removal + m_document->redo(); + QVERIFY(m_document->page(0)->annotations().size() == 1); + QVERIFY(m_document->page(0)->annotations().contains(annot2)); + + // Verify that annot1 is disposed of if document is closed with annot1 in removed state + QString annot1Name = annot1->uniqueName(); + annot1->setDisposeDataFunction(TestingUtils::AnnotationDisposeWatcher::disposeAnnotation); + TestingUtils::AnnotationDisposeWatcher::resetDisposedAnnotationName(); + QVERIFY(TestingUtils::AnnotationDisposeWatcher::disposedAnnotationName().isEmpty()); + m_document->closeDocument(); + QVERIFY(TestingUtils::AnnotationDisposeWatcher::disposedAnnotationName() == annot1Name); +} + +QTEST_MAIN(AddRemoveAnnotationTest) +#include "addremoveannotationtest.moc" diff --git a/autotests/annotationstest.cpp b/autotests/annotationstest.cpp new file mode 100644 index 0000000..f2af379 --- /dev/null +++ b/autotests/annotationstest.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2013 by Peter Grasch * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../core/annotations.h" +#include "../core/document.h" +#include "../core/page.h" +#include "../settings_core.h" + +Q_DECLARE_METATYPE(Okular::Annotation *) +Q_DECLARE_METATYPE(Okular::LineAnnotation *) + +class AnnotationTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testDistance(); + void testDistance_data(); + // void testLine(); + // void testPoly(); + // void testInk(); + // void testHighlight(); + // void testGeom(); + void testTypewriter(); + void cleanupTestCase(); + +private: + Okular::Document *m_document; +}; + +void AnnotationTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("annotationtest")); + m_document = new Okular::Document(nullptr); + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); +} + +void AnnotationTest::cleanupTestCase() +{ + if (m_document->isOpened()) { + const QLinkedList annotations = m_document->page(0)->annotations(); + for (Okular::Annotation *annotation : annotations) { + m_document->removePageAnnotation(0, annotation); + } + } +} + +void AnnotationTest::testDistance() +{ + QFETCH(Okular::Annotation *, annotation); + QFETCH(double, x); + QFETCH(double, y); + QFETCH(int, distance); + Okular::AnnotationObjectRect *rect = new Okular::AnnotationObjectRect(annotation); + QCOMPARE(qRound(rect->distanceSqr(x, y, m_document->page(0)->width(), m_document->page(0)->height())), distance); + delete rect; +} + +void AnnotationTest::testDistance_data() +{ + QTest::addColumn("annotation"); + QTest::addColumn("x"); + QTest::addColumn("y"); + QTest::addColumn("distance"); + + double documentX = m_document->page(0)->width(); + double documentY = m_document->page(0)->height(); + + // lines + Okular::LineAnnotation *line = new Okular::LineAnnotation; + line->setLinePoints(QLinkedList() << Okular::NormalizedPoint(0.1, 0.1) << Okular::NormalizedPoint(0.9, 0.1)); + m_document->addPageAnnotation(0, line); + QTest::newRow("Line: Base point 1") << (Okular::Annotation *)line << 0.1 << 0.1 << 0; + QTest::newRow("Line: Base point 2") << (Okular::Annotation *)line << 0.5 << 0.1 << 0; + QTest::newRow("Line: Off by a lot") << (Okular::Annotation *)line << 0.5 << 0.5 << qRound(pow(0.4 * documentY, 2)); + QTest::newRow("Line: Off by a little") << (Okular::Annotation *)line << 0.1 << 0.1 + (5.0 /* px */ / documentY) << 25; + + // squares (non-filled squares also act as tests for the ink annotation as they share the path-distance code) + for (int i = 0; i < 2; ++i) { + Okular::GeomAnnotation *square = new Okular::GeomAnnotation; + square->setGeometricalType(Okular::GeomAnnotation::InscribedSquare); + square->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.9, 0.9)); + if (i != 0) + square->setGeometricalInnerColor(QColor(0, 0, 0)); + m_document->addPageAnnotation(0, square); + QTest::newRow("Square: Base point 1") << (Okular::Annotation *)square << 0.1 << 0.1 << 0; + QTest::newRow("Square: On edge 1") << (Okular::Annotation *)square << 0.1 << 0.2 << 0; + QTest::newRow("Square: On edge 2") << (Okular::Annotation *)square << 0.2 << 0.1 << 0; + QTest::newRow("Square: Inside") << (Okular::Annotation *)square << 0.2 << 0.2 << ((i == 0) ? qRound(pow(0.1 * documentX, 2) - 1 /* stroke width */) : 0); + QTest::newRow("Square: Outside") << (Okular::Annotation *)square << 0.0 << 0.0 << qRound(pow(0.1 * documentX, 2) + pow(0.1 * documentY, 2)); + } + + // ellipsis + for (int i = 0; i < 2; ++i) { + Okular::GeomAnnotation *ellipse = new Okular::GeomAnnotation; + ellipse->setGeometricalType(Okular::GeomAnnotation::InscribedCircle); + ellipse->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.9, 0.5)); + if (i != 0) + ellipse->setGeometricalInnerColor(QColor(0, 0, 0)); + m_document->addPageAnnotation(0, ellipse); + QTest::newRow("Ellipse: Base point 1") << (Okular::Annotation *)ellipse << 0.1 << 0.3 << 0; + QTest::newRow("Ellipse: Inside") << (Okular::Annotation *)ellipse << 0.2 << 0.3 << qRound((i == 0) ? pow(documentX * 0.1, 2) - 1 /* pen */ : 0); + QTest::newRow("Ellipse: Outside") << (Okular::Annotation *)ellipse << 0.0 << 0.3 << qRound(pow(documentX * 0.1, 2)); + } + + // highlight + Okular::HighlightAnnotation *highlight = new Okular::HighlightAnnotation; + Okular::HighlightAnnotation::Quad q; + q.setPoint(Okular::NormalizedPoint(0.1, 0.1), 0); + q.setPoint(Okular::NormalizedPoint(0.2, 0.1), 1); + q.setPoint(Okular::NormalizedPoint(0.8, 0.9), 2); + q.setPoint(Okular::NormalizedPoint(0.9, 0.9), 3); + highlight->highlightQuads() << q; + m_document->addPageAnnotation(0, highlight); + QTest::newRow("Highlight: Point 1") << (Okular::Annotation *)highlight << 0.1 << 0.1 << 0; + QTest::newRow("Highlight: Point 2") << (Okular::Annotation *)highlight << 0.2 << 0.1 << 0; + QTest::newRow("Highlight: Point 3") << (Okular::Annotation *)highlight << 0.8 << 0.9 << 0; + QTest::newRow("Highlight: Point 4") << (Okular::Annotation *)highlight << 0.9 << 0.9 << 0; + QTest::newRow("Highlight: Inside") << (Okular::Annotation *)highlight << 0.5 << 0.5 << 0; + QTest::newRow("Highlight: Outside") << (Okular::Annotation *)highlight << 1.0 << 0.9 << qRound(pow(documentX * 0.1, 2)); +} + +void AnnotationTest::testTypewriter() +{ + Okular::Annotation *annot = nullptr; + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + annot = ta; + ta->setFlags(ta->flags() | Okular::Annotation::FixedRotation); + ta->setTextType(Okular::TextAnnotation::InPlace); + ta->setInplaceIntent(Okular::TextAnnotation::TypeWriter); + ta->style().setWidth(0.0); + ta->style().setColor(QColor(255, 255, 255, 0)); + + annot->setBoundingRectangle(Okular::NormalizedRect(0.8, 0.1, 0.85, 0.15)); + annot->setContents(QStringLiteral("annot contents")); + + m_document->addPageAnnotation(0, annot); + + QDomNode annotNode = annot->getAnnotationPropertiesDomNode(); + QDomNodeList annotNodeList = annotNode.toElement().elementsByTagName(QStringLiteral("base")); + QDomElement annotEl = annotNodeList.item(0).toElement(); + QCOMPARE(annotEl.attribute(QStringLiteral("color")), QStringLiteral("#00ffffff")); + QCOMPARE(annotEl.attribute(QStringLiteral("flags")), QStringLiteral("4")); + QCOMPARE(annotEl.attribute(QStringLiteral("contents")), QStringLiteral("annot contents")); +} + +QTEST_MAIN(AnnotationTest) +#include "annotationstest.moc" diff --git a/autotests/annotationtoolbartest.cpp b/autotests/annotationtoolbartest.cpp new file mode 100644 index 0000000..cd730df --- /dev/null +++ b/autotests/annotationtoolbartest.cpp @@ -0,0 +1,405 @@ +/*************************************************************************** + * Copyright (C) 2020 by Simone Gaiarin * + * * + * 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. * + ***************************************************************************/ + +// clazy:excludeall=qstring-allocations + +#include + +#include +#include +#include +#include +#include + +#include + +#include "../core/page.h" +#include "../part/pageview.h" +#include "../part/part.h" +#include "../settings.h" +#include "../shell/okular_main.h" +#include "../shell/shell.h" +#include "../shell/shellutils.h" +#include "closedialoghelper.h" + +namespace Okular +{ +class PartTest +{ +public: + Okular::Document *partDocument(Okular::Part *part) const + { + return part->m_document; + } + PageView *pageView(Okular::Part *part) const + { + return part->m_pageView; + } +}; +} + +class AnnotationToolBarTest : public QObject, public Okular::PartTest +{ + Q_OBJECT + +public: + static void initMain(); + static QTabWidget *tabWidget(Shell *s) + { + return s->m_tabWidget; + } + +private slots: + void initTestCase(); + void init(); + void cleanup(); + + void testAnnotationToolBar(); + void testAnnotationToolBar_data(); + void testAnnotationToolBarActionsEnabledState(); + void testAnnotationToolBarActionsEnabledState_data(); + void testAnnotationToolBarConfigActionsEnabledState(); + void testAnnotationToolBarConfigActionsEnabledState_data(); + +private: + bool simulateAddPopupAnnotation(Okular::Part *part, int mouseX, int mouseY); +}; + +Shell *findShell(Shell *ignore = nullptr) +{ + const QWidgetList wList = QApplication::topLevelWidgets(); + for (QWidget *widget : wList) { + Shell *s = qobject_cast(widget); + if (s && s != ignore) + return s; + } + return nullptr; +} + +void AnnotationToolBarTest::initMain() +{ + // Ensure consistent configs/caches and Default UI + QTemporaryDir homeDir; + Q_ASSERT(homeDir.isValid()); + QByteArray homePath = QFile::encodeName(homeDir.path()); + qputenv("USERPROFILE", homePath); + qputenv("HOME", homePath); + qputenv("XDG_DATA_HOME", homePath + "/.local"); + qputenv("XDG_CONFIG_HOME", homePath + "/.kde-unit-test/xdg/config"); +} + +void AnnotationToolBarTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); + // Don't pollute people's okular settings + Okular::Settings::instance(QStringLiteral("annotationtoolbartest")); +} + +void AnnotationToolBarTest::init() +{ + // Default settings for every test + Okular::Settings::self()->setDefaults(); +} + +void AnnotationToolBarTest::cleanup() +{ + Shell *s; + while ((s = findShell())) { + delete s; + } +} + +bool AnnotationToolBarTest::simulateAddPopupAnnotation(Okular::Part *part, int mouseX, int mouseY) +{ + int annotationCount = partDocument(part)->page(0)->annotations().size(); + QTest::mouseMove(pageView(part)->viewport(), QPoint(mouseX, mouseY)); + QTest::mouseClick(pageView(part)->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(mouseX, mouseY)); + bool annotationAdded = partDocument(part)->page(0)->annotations().size() == annotationCount + 1; + return annotationAdded; +} + +void AnnotationToolBarTest::testAnnotationToolBar() +{ + // Using tabs we test that the annotation toolbar works on each Okular::Part + Okular::Settings::self()->setShellOpenFileInTabs(true); + + const QStringList paths = {QStringLiteral(KDESRCDIR "data/file1.pdf"), QStringLiteral(KDESRCDIR "data/file2.pdf")}; + QString serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + QVERIFY(QTest::qWaitForWindowExposed(s)); + + QFETCH(int, tabIndex); + s->m_tabWidget->tabBar()->setCurrentIndex(tabIndex); + Okular::Part *part = dynamic_cast(s->m_tabs[tabIndex].part); + QVERIFY(part); + + QToolBar *annToolBar = s->findChild(QStringLiteral("annotationToolBar")); + QVERIFY(annToolBar); + + // Check config action default enabled states + KSelectAction *aQuickTools = qobject_cast(part->actionCollection()->action(QStringLiteral("annotation_favorites"))); + QAction *aAddToQuickTools = part->actionCollection()->action(QStringLiteral("annotation_bookmark")); + QAction *aAdvancedSettings = part->actionCollection()->action(QStringLiteral("annotation_settings_advanced")); + QAction *aContinuousMode = part->actionCollection()->action(QStringLiteral("annotation_settings_pin")); + QVERIFY(aQuickTools->isEnabled()); + QVERIFY(!aAddToQuickTools->isEnabled()); + QVERIFY(!aAdvancedSettings->isEnabled()); + QVERIFY(aContinuousMode->isEnabled()); + + // Ensure that the 'Quick Annotations' action is correctly populated + // (at least the 'Configure Annotations...' action must be present) + QVERIFY(!aQuickTools->actions().isEmpty()); + + // Test annotation toolbar visibility triggers + QAction *toggleAnnotationToolBar = part->actionCollection()->action(QStringLiteral("mouse_toggle_annotate")); + QAction *aHideToolBar = part->actionCollection()->action(QStringLiteral("hide_annotation_toolbar")); + QVERIFY(toggleAnnotationToolBar); + QVERIFY(aHideToolBar); + toggleAnnotationToolBar->setChecked(false); + QTRY_VERIFY(!annToolBar->isVisible()); + toggleAnnotationToolBar->trigger(); + QTRY_VERIFY2(annToolBar->isVisible(), "Annotation action failed to show."); + toggleAnnotationToolBar->trigger(); + QTRY_VERIFY2(!annToolBar->isVisible(), "Annotation action failed to hide."); + + toggleAnnotationToolBar->setChecked(true); + QTRY_VERIFY(annToolBar->isVisible()); + aHideToolBar->trigger(); + QTRY_VERIFY2(!annToolBar->isVisible(), "Hide toolbar action failed to hide."); + + toggleAnnotationToolBar->setChecked(false); + QTRY_VERIFY(!annToolBar->isVisible()); + QTest::keyClick(part->widget(), Qt::Key_1, Qt::AltModifier); + QTRY_VERIFY2(annToolBar->isVisible(), "ToolBar not shown when triggering annotation using shortcut."); + toggleAnnotationToolBar->setChecked(false); + QTRY_VERIFY(!annToolBar->isVisible()); + QTest::keyClick(part->widget(), Qt::Key_3); + QTRY_VERIFY2(annToolBar->isVisible(), "ToolBar not shown when triggering quick annotation using shortcut."); + + // Click an annotation action to enable it + QAction *aPopupNote = part->actionCollection()->action(QStringLiteral("annotation_popup_note")); + QVERIFY(aPopupNote); + aPopupNote->trigger(); + int mouseX = 350; + int mouseY = 100; + QTRY_COMPARE(Okular::Settings::mouseMode(), static_cast(Okular::Settings::EnumMouseMode::Browse)); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + + // Click again the same annotation action to disable it + aPopupNote->trigger(); + mouseY = 150; + QTRY_COMPARE(Okular::Settings::mouseMode(), static_cast(Okular::Settings::EnumMouseMode::Browse)); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), false); + + // Trigger the action using a shortcut + QTest::keyClick(part->widget(), Qt::Key_7, Qt::AltModifier); + mouseY = 200; + QTRY_COMPARE(Okular::Settings::mouseMode(), static_cast(Okular::Settings::EnumMouseMode::Browse)); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + + // Click Esc to disable all annotations + QTest::keyClick(pageView(part), Qt::Key_Escape); + mouseY = 250; + QTRY_COMPARE(Okular::Settings::mouseMode(), static_cast(Okular::Settings::EnumMouseMode::Browse)); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), false); + + // Trigger the action using a quick annotation shortcut + QTest::keyClick(part->widget(), Qt::Key_6); + QTRY_COMPARE(Okular::Settings::mouseMode(), static_cast(Okular::Settings::EnumMouseMode::Browse)); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + + // Test pin/continuous mode action + QVERIFY(aContinuousMode->isEnabled()); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + aContinuousMode->trigger(); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), true); + QCOMPARE(simulateAddPopupAnnotation(part, mouseX, mouseY), false); + + // Test adding a tool to the quick tool list using the bookmark action + QScopedPointer closeDialogHelper; + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(QDialogButtonBox::Ok)); + QAction *aEllipse = part->actionCollection()->action(QStringLiteral("annotation_ellipse")); + aEllipse->trigger(); + QVERIFY(aEllipse->isChecked()); + int quickActionCount = aQuickTools->actions().size(); + aAddToQuickTools->trigger(); + QCOMPARE(aQuickTools->actions().size(), quickActionCount + 1); + // Test that triggering a Quick Annotation action checks the corresponding built-in annotation action + aQuickTools->actions().at(5)->trigger(); + QVERIFY(aPopupNote->isChecked()); + // Test again for tool just added to the quick tools using the bookmark button + aQuickTools->actions().at(6)->trigger(); + QVERIFY(aEllipse->isChecked()); +} + +void AnnotationToolBarTest::testAnnotationToolBar_data() +{ + QTest::addColumn("tabIndex"); + QTest::addRow("first tab") << 0; + QTest::addRow("second tab") << 1; +} + +void AnnotationToolBarTest::testAnnotationToolBarActionsEnabledState() +{ + QFETCH(QString, document); + + const QStringList paths = {document}; + QString serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + QVERIFY(QTest::qWaitForWindowExposed(s)); + + Okular::Part *part = s->findChild(); + QVERIFY(part); + + KActionCollection *ac = part->actionCollection(); + QAction *aQuickTools = ac->action(QStringLiteral("annotation_favorites")); + QAction *aHighlighter = ac->action(QStringLiteral("annotation_highlighter")); + QAction *aUnderline = ac->action(QStringLiteral("annotation_underline")); + QAction *aSquiggle = ac->action(QStringLiteral("annotation_squiggle")); + QAction *aStrikeout = ac->action(QStringLiteral("annotation_strike_out")); + QAction *aTypewriter = ac->action(QStringLiteral("annotation_typewriter")); + QAction *aInlineNote = ac->action(QStringLiteral("annotation_inline_note")); + QAction *aPopupNote = ac->action(QStringLiteral("annotation_popup_note")); + QAction *aFreehandLine = ac->action(QStringLiteral("annotation_freehand_line")); + QAction *aGeomShapes = ac->action(QStringLiteral("annotation_geometrical_shape")); + QAction *aStamp = ac->action(QStringLiteral("annotation_stamp")); + + QFETCH(bool, aQuickToolsEnabled); + QFETCH(bool, aHighlighterEnabled); + QFETCH(bool, aUnderlineEnabled); + QFETCH(bool, aSquiggleEnabled); + QFETCH(bool, aStrikeoutEnabled); + QFETCH(bool, aTypewriterEnabled); + QFETCH(bool, aInlineNoteEnabled); + QFETCH(bool, aPopupNoteEnabled); + QFETCH(bool, aFreehandLineEnabled); + QFETCH(bool, aGeomShapesEnabled); + QFETCH(bool, aStampEnabled); + + QCOMPARE(aQuickTools->isEnabled(), aQuickToolsEnabled); + QCOMPARE(aHighlighter->isEnabled(), aHighlighterEnabled); + QCOMPARE(aUnderline->isEnabled(), aUnderlineEnabled); + QCOMPARE(aSquiggle->isEnabled(), aSquiggleEnabled); + QCOMPARE(aStrikeout->isEnabled(), aStrikeoutEnabled); + QCOMPARE(aTypewriter->isEnabled(), aTypewriterEnabled); + QCOMPARE(aInlineNote->isEnabled(), aInlineNoteEnabled); + QCOMPARE(aPopupNote->isEnabled(), aPopupNoteEnabled); + QCOMPARE(aFreehandLine->isEnabled(), aFreehandLineEnabled); + QCOMPARE(aGeomShapes->isEnabled(), aGeomShapesEnabled); + QCOMPARE(aStamp->isEnabled(), aStampEnabled); + + // trigger a reparsing of the tools to ensure that the enabled/disabled state is not changed (bug: 424296) + QAction *aMouseSelect = ac->action(QStringLiteral("mouse_select")); + QAction *aMouseNormal = ac->action(QStringLiteral("mouse_drag")); + aMouseSelect->trigger(); + aMouseNormal->trigger(); + + QCOMPARE(aQuickTools->isEnabled(), aQuickToolsEnabled); + QCOMPARE(aHighlighter->isEnabled(), aHighlighterEnabled); + QCOMPARE(aUnderline->isEnabled(), aUnderlineEnabled); + QCOMPARE(aSquiggle->isEnabled(), aSquiggleEnabled); + QCOMPARE(aStrikeout->isEnabled(), aStrikeoutEnabled); + QCOMPARE(aTypewriter->isEnabled(), aTypewriterEnabled); + QCOMPARE(aInlineNote->isEnabled(), aInlineNoteEnabled); + QCOMPARE(aPopupNote->isEnabled(), aPopupNoteEnabled); + QCOMPARE(aFreehandLine->isEnabled(), aFreehandLineEnabled); + QCOMPARE(aGeomShapes->isEnabled(), aGeomShapesEnabled); + QCOMPARE(aStamp->isEnabled(), aStampEnabled); +} + +void AnnotationToolBarTest::testAnnotationToolBarActionsEnabledState_data() +{ + QTest::addColumn("document"); + QTest::addColumn("aQuickToolsEnabled"); + QTest::addColumn("aHighlighterEnabled"); + QTest::addColumn("aUnderlineEnabled"); + QTest::addColumn("aSquiggleEnabled"); + QTest::addColumn("aStrikeoutEnabled"); + QTest::addColumn("aTypewriterEnabled"); + QTest::addColumn("aInlineNoteEnabled"); + QTest::addColumn("aPopupNoteEnabled"); + QTest::addColumn("aFreehandLineEnabled"); + QTest::addColumn("aGeomShapesEnabled"); + QTest::addColumn("aStampEnabled"); + + QTest::addRow("pdf") << QStringLiteral(KDESRCDIR "data/file1.pdf") << true << true << true << true << true << true << true << true << true << true << true; + QTest::addRow("protected-pdf") << QStringLiteral(KDESRCDIR "data/protected.pdf") << false << false << false << false << false << false << false << false << false << false << false; + QTest::addRow("image") << QStringLiteral(KDESRCDIR "data/potato.jpg") << true << false << false << false << false << true << true << true << true << true << true; +} + +void AnnotationToolBarTest::testAnnotationToolBarConfigActionsEnabledState() +{ + const QStringList paths = {QStringLiteral(KDESRCDIR "data/file1.pdf")}; + QString serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + QVERIFY(QTest::qWaitForWindowExposed(s)); + + Okular::Part *part = s->findChild(); + QVERIFY(part); + + KActionCollection *ac = part->actionCollection(); + QAction *aWidth = ac->action(QStringLiteral("annotation_settings_width")); + QAction *aColor = ac->action(QStringLiteral("annotation_settings_color")); + QAction *aInnerColor = ac->action(QStringLiteral("annotation_settings_inner_color")); + QAction *aOpacity = ac->action(QStringLiteral("annotation_settings_opacity")); + QAction *aFont = ac->action(QStringLiteral("annotation_settings_font")); + + QFETCH(QString, annotationActionName); + QFETCH(bool, widthEnabled); + QFETCH(bool, colorEnabled); + QFETCH(bool, innerColorEnabled); + QFETCH(bool, opacityEnabled); + QFETCH(bool, fontEnabled); + + QAction *annotationAction = ac->action(annotationActionName); + annotationAction->trigger(); + + QCOMPARE(aWidth->isEnabled(), widthEnabled); + QCOMPARE(aColor->isEnabled(), colorEnabled); + QCOMPARE(aInnerColor->isEnabled(), innerColorEnabled); + QCOMPARE(aOpacity->isEnabled(), opacityEnabled); + QCOMPARE(aFont->isEnabled(), fontEnabled); +} + +void AnnotationToolBarTest::testAnnotationToolBarConfigActionsEnabledState_data() +{ + QTest::addColumn("annotationActionName"); + QTest::addColumn("widthEnabled"); + QTest::addColumn("colorEnabled"); + QTest::addColumn("innerColorEnabled"); + QTest::addColumn("opacityEnabled"); + QTest::addColumn("fontEnabled"); + + QTest::addRow("annotation_highlighter") << QStringLiteral("annotation_highlighter") << false << true << false << true << false; + QTest::addRow("annotation_underline") << QStringLiteral("annotation_underline") << false << true << false << true << false; + QTest::addRow("annotation_squiggle") << QStringLiteral("annotation_squiggle") << false << true << false << true << false; + QTest::addRow("annotation_strike_out") << QStringLiteral("annotation_strike_out") << false << true << false << true << false; + QTest::addRow("annotation_typewriter") << QStringLiteral("annotation_typewriter") << false << true << false << true << true; + QTest::addRow("annotation_inline_note") << QStringLiteral("annotation_inline_note") << false << true << false << true << true; + QTest::addRow("annotation_popup_note") << QStringLiteral("annotation_popup_note") << false << true << false << true << false; + QTest::addRow("annotation_freehand_line") << QStringLiteral("annotation_freehand_line") << true << true << false << true << false; + QTest::addRow("annotation_line") << QStringLiteral("annotation_straight_line") << true << true << false << true << false; + QTest::addRow("annotation_rectangle") << QStringLiteral("annotation_rectangle") << true << true << true << true << false; +} + +QTEST_MAIN(AnnotationToolBarTest) +#include "annotationtoolbartest.moc" diff --git a/autotests/calculatetexttest.cpp b/autotests/calculatetexttest.cpp new file mode 100644 index 0000000..b3f0f28 --- /dev/null +++ b/autotests/calculatetexttest.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/document.h" +#include +#include +#include +#include +#include + +class CalculateTextTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testSimpleCalculate(); + +private: + Okular::Document *m_document; +}; + +void CalculateTextTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("calculatetexttest")); + m_document = new Okular::Document(nullptr); +} + +void CalculateTextTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +void CalculateTextTest::testSimpleCalculate() +{ + // Force consistent locale + QLocale locale(QStringLiteral("en_US.UTF-8")); + if (locale == QLocale::c()) { + locale = QLocale(QLocale::English, QLocale::UnitedStates); + } + + QLocale::setDefault(locale); + const QString testFile = QStringLiteral(KDESRCDIR "data/simpleCalculate.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + const Okular::Page *page = m_document->page(0); + + QMap fields; + + // Field names in test document are: + // field1, field2, field3, Sum, AVG, Prod, Min, Max + + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + fields.insert(ff->name(), static_cast(ff)); + } + + // Set some values and do calculation + Okular::FormFieldText *field1 = fields[QStringLiteral("field1")]; + QVERIFY(field1); + m_document->editFormText(0, field1, QStringLiteral("10"), 0, 0, 0); + + Okular::FormFieldText *field2 = fields[QStringLiteral("field2")]; + QVERIFY(field2); + m_document->editFormText(0, field2, QStringLiteral("20"), 0, 0, 0); + + Okular::FormFieldText *field3 = fields[QStringLiteral("field3")]; + QVERIFY(field3); + m_document->editFormText(0, field3, QStringLiteral("30"), 0, 0, 0); + + // Verify the results + QCOMPARE(fields[QStringLiteral("Sum")]->text(), QStringLiteral("60")); + QCOMPARE(fields[QStringLiteral("AVG")]->text(), QStringLiteral("20")); + QCOMPARE(fields[QStringLiteral("Prod")]->text(), QStringLiteral("6,000")); + QCOMPARE(fields[QStringLiteral("Min")]->text(), QStringLiteral("10")); + QCOMPARE(fields[QStringLiteral("Max")]->text(), QStringLiteral("30")); + + // Verify that Sum was not recalculated after set without edit + QCOMPARE(fields[QStringLiteral("Sum")]->text(), QStringLiteral("60")); + + // Test that multiplication with zero works + m_document->editFormText(0, field2, QStringLiteral("0"), 0, 0, 0); + QCOMPARE(fields[QStringLiteral("Prod")]->text(), QStringLiteral("0")); + + // Test that updating the field also worked with sum + QCOMPARE(fields[QStringLiteral("Sum")]->text(), QStringLiteral("40")); + + // Test that undo / redo works + QVERIFY(m_document->canUndo()); + m_document->undo(); + QCOMPARE(fields[QStringLiteral("Sum")]->text(), QStringLiteral("60")); + + QVERIFY(m_document->canRedo()); + m_document->redo(); + QCOMPARE(fields[QStringLiteral("Sum")]->text(), QStringLiteral("40")); +} + +QTEST_MAIN(CalculateTextTest) +#include "calculatetexttest.moc" diff --git a/autotests/closedialoghelper.cpp b/autotests/closedialoghelper.cpp new file mode 100644 index 0000000..440e661 --- /dev/null +++ b/autotests/closedialoghelper.cpp @@ -0,0 +1,50 @@ +#include "closedialoghelper.h" + +#include +#include +#include +#include + +namespace TestingUtils +{ +CloseDialogHelper::CloseDialogHelper(Okular::Part *p, QDialogButtonBox::StandardButton b) + : m_widget(p->widget()) + , m_button(b) + , m_clicked(false) +{ + QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog); +} + +CloseDialogHelper::CloseDialogHelper(QWidget *w, QDialogButtonBox::StandardButton b) + : m_widget(w) + , m_button(b) + , m_clicked(false) +{ + QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog); +} + +CloseDialogHelper::CloseDialogHelper(QDialogButtonBox::StandardButton b) + : m_widget(nullptr) + , m_button(b) + , m_clicked(false) +{ + QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog); +} + +CloseDialogHelper::~CloseDialogHelper() +{ + QVERIFY(m_clicked); +} + +void CloseDialogHelper::closeDialog() +{ + QWidget *dialog = (m_widget) ? m_widget->findChild() : qApp->activeModalWidget(); + if (!dialog) { + QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog); + return; + } + QDialogButtonBox *buttonBox = dialog->findChild(); + buttonBox->button(m_button)->click(); + m_clicked = true; +} +} diff --git a/autotests/closedialoghelper.h b/autotests/closedialoghelper.h new file mode 100644 index 0000000..4fbef84 --- /dev/null +++ b/autotests/closedialoghelper.h @@ -0,0 +1,39 @@ +#ifndef CLOSEDIALOGHELPER_H +#define CLOSEDIALOGHELPER_H + +#include +#include + +#include "../part/part.h" + +namespace TestingUtils +{ +/* + * The CloseDialogHelper class is a helper to auto close modals opened in tests. + */ +class CloseDialogHelper : public QObject +{ + Q_OBJECT + +public: + CloseDialogHelper(Okular::Part *p, QDialogButtonBox::StandardButton b); + + CloseDialogHelper(QWidget *w, QDialogButtonBox::StandardButton b); + + // Close a modal dialog, which may not be associated to any other widget + CloseDialogHelper(QDialogButtonBox::StandardButton b); + + ~CloseDialogHelper() override; + +private slots: + void closeDialog(); + +private: + QWidget *m_widget; + QDialogButtonBox::StandardButton m_button; + bool m_clicked; +}; + +} + +#endif // CLOSEDIALOGHELPER_H diff --git a/autotests/data/1500x300.png b/autotests/data/1500x300.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e26b995f154e93a89e91827d16708b8c5c2f89 GIT binary patch literal 303461 zcmV(_K-9m9P)EX>4Tx04R}tkv&MmKpe$iQ^is%3U&~2$WWau6cusQDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|}?mh0_0YbgZG^;BHXu55t z5^*t;T@`y?5x@X~=tWFsmN6$uNpu`v_we!cF3PhypZjz4sX2=QK9P8q8KzCVK|H-_ z8=Uuv!>lN)#OK80CS8#Dk?V@bZ=4G*3p_Jyrc?98VPdh+#!4HrqNx#25l2)_r+gvf zvC4UivsSLM<~{ifLpgnAnd>x1kia6AAVGwJDoQBBMwC{a6bmWZk9Y77yMBpW3b{&P z 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

-LcfQ-bBJrmPtlbL?0-h(yvRaK!jK`= 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�(_Pnm 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%0DVHxq?Yb$m>-%aF}9aTrIjO&uXp8W_P%~^ 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%0A|Zx`Ag#{sGjk%GPowgWTho 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 literal 0 HcmV?d00001 diff --git a/autotests/data/300x1500.png b/autotests/data/300x1500.png new file mode 100644 index 0000000000000000000000000000000000000000..e10cda14f9c00699caa0c7ffbeee4d6dd8418f8f GIT binary patch literal 71065 zcmV*uKtaEWP)EX>4Tx04R}tkv&MmKpe$iQ^is%3U&~2$WWau6cusQDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|}?mh0_0YbgZG^;BHXu55t z5^*t;T@`y?5x@X~=tWFsmN6$uNpu`v_we!cF3PhypZjz4sX2=QK9P8q8KzCVK|H-_ z8=Uuv!>lN)#OK80CS8#Dk?V@bZ=4G*3p_Jyrc?98VPdh+#!4HrqNx#25l2)_r+gvf zvC4UivsSLM<~{ifLpgnAnd>x1kia6AAVGwJDoQBBMwC{a6bmWZk9Y77yMBpW3b{&P z zj1?$*y~Dc$?Y;ebrrF;QQf6|R^V*&%00009a7bBm000hj000hj0c#|))&Kwi2XskI zMF->v5DE|+ay%rW001BWNklWqpj%=mk{>hE#i2nZ%%zoImRYhV*fF&>4 zCLhk(%aUp!0T7wQfdBtL|9b$(f#Wz10LMW9pZ`1#95~Kj`25;`U%|&;{`(Jne1ia< zKR;dSzuyAwG*e@%8Vo zUyV1#__E`xeZJAh|Bh34;N!7BW_S4L^0Iv1?(|fr6?v|XIeVYCKX7@|^Rz!7^8Cu5 z5BarNoF(D>%Hvd@-sm`<0yC}YSsD*Ku9rQIaemIT@w~-t60=aT@rRt71>e&rm|t-=AOqGyRga ziRJhO7}sI^Ai?M6*AH;|%XlL$O9zhQI0*9!46peTQRMJ19PuB{pQR537WE3B&!a7K z{1t@LM)fjP6)4>A6SqHRy@9nj?p%=OW9BO)Os+Ul{DSoZg12Y$BI*z(8OCf3Ux4u$ zs%DMje?pusj;osg2KmRH0WqWqO|hl(vesnr$m|uPm*8;_l-Ad}HF-D&`7)Dqo`%X! z_`D;u8FYjk!jIg2#ntmwSBC8UE_?1n`+IC9yza-I?*;{~(E*hfP{ibVLGWVX;C~ko zAW*l&r9@L<;r_*QqbNZEBJ-Q*d(QNMYzB`yB+m%pIC+ltl8U^PA!C^F6q0r3C}TRH zR!I;FNbTWV8Ywx#&>e=bVjf|1VomCm0^Pk2IdJ{9>G+6u^_mpj7=BG&Q9((*wCB%R?FDI2(L{GLr{Cyh72-))$ zmH?4kU36p6m>GNnz)LKMO!G9bhHq^IamXr|B8 zShROS10f?n89h74r16je?3P5u1u@KS;Y$e5FUM~)D~B5k5iWR7Vj=yVw_LL^4T(Tp z&?}N>rTEZ{eo7zA!!Svl^d{a3d6$UIdm|j8r@x$OXijMPQMWug5n+5o3fW=!s?Ur^ ziG(00c4&O2?i`>PKNJgfwkAkUuIkng?yu;7ExQ>IguCLHi|q;Kb_s59!8mG-Xca5DD3#LPystq1N37;K9yhzvw0sFwtLaZfPiiSCG*J%0aqb1=M>aLd6S@2-S2T_9+VVztJI44UZx z3)R8U{6_lM=WVJMu{unyogGi-PetFs24a>;aKHiSc8QoEK(#rLMn3-#>Zr_bB9<>< zOd()a!p5nxT{dAo01M_Ej~QQ#g~H%Q5yaUc6IB!RSSHGXe%+9PAk_r2ID5Diy*0A) z!Dz4)ktRdHznOv3YjH4Ai&Ss&(q!p_2<0t$w5Rn&`V;4s#mP;4etP0EvMyFOC8bWI zLZ9-C7^b8kTza(lfGFTHQJfw>r}nIcM4c+>Ov<$!m%R|S>4>6T(0(XvOt{By9X~JL zV=Lhvd;BIPq~u%YTRDO=M=Jv6!?h?D7;aGwSD%}L+jKd)V|tsL?KoF|i`plx$HE9$ z8NyfxS9+Ypf4y2p!Q;JiE+wNNQbILWC|+MiOc6VGP+pf~rIoCV3XKX&!L5)>9c@Yo z>I5#3o7qZ_SQj#xaRu%yzuw5XP`kKkeR+pEcwff^UV#bxdGQqV@h?0noO!m#Y&Why z#e_+LwhjrEOJE0k$o1#1@`WrzD2DMkZmEr~3KHeu-I?;Zu1X}tIM>ZyKfa8j^OA&b z#tRt*s&KX}2m0!X%nrC_vv&+|6|8s1ggd)ukACdkCT8~7V~>^+4la#Re?kR}T0(Vs z_misAN?|DZvDZ?_0Y``4Vj7s!9c<0o3tfn{u%H=rV{!ha#F{w6CqMaP$RyQ-cKr9l zd93I_oz;S$Uiljf!%z_b8W>Xj&4e`U=}>5x4_zyxLzqF&(J1^XTYl0KbZuA2eG z69kS%umrtTW1%n%W_Cd=He73!SLFie?>)Xugzjk1*GA3?oDB~pOzzzW4g*7Jb3oqV zh|i5IdLzn^pD9*vZaxcDgws0)eajYIi1eDhdTShMpD60@+q$QQR$yboJ-&bJl#*Eq zv1ezGJ>G+uf#=|eW#lM*o6qhUD+xh5E+%@vi%yKv9-?9mTxfrcaU7sH^e8*QN2RND z;C;DN2VcP-!RA{c&dXy!kYS5CM<8P9yh@*sY&lS00a=yGjkknCzCinCOz}GmlzAzp zY_++j#|sr@->t}U?Y@-~Dcug?Y%U#bqCk%kL}vL{AZmxhN2aKl?O=5F|1fVs0UY1z zxq1{Xr4mH5Mnd6@_}>bbopEThfQl&yq9lRCQ0nBK=^l`;MmamLTxSV$A+Lh8S6q?c zN1WTyqpp|5Jqhng%(e$bNON=ykJMGa3@;|mO_7ONcaj6m=^;r zxKy_+j_p-Jx}(<00oS#$55U|eIeKAHOul;^dxZU%#xADqm82h1z`}#xzU#Q3m=E_@ zpHUw$3yYlVW!gRl(Ql*W#6%K!92PU!gKRB$ATMhXm-J*jCrPRza!_r5feX^tD=>OB zIaR}n?DA72rob2@D}Vw8<$FN=QQZ}CjX(9MiU}TO^|bq}7qdBa_F4H^T6PwSp{S>G zTGEPYU9;B>XrYL{+%pW$MQ+znTb`cVv{0t#alOq3Z#VfMd+hPgiJ3k2*rTF^cHx6% zF2naCaPm`-VslphKEoS&Ei%v7i>j#0=Y?m$qGsl=F~{xn zIDnE1u^hclcdBT7TztSAH0IH`5v7t&N9Q%t{^t32v8cu2H|q&*w88%%qK$?^hl973 z)+RXM;8OOrp`=t$S1pJ%0zT%IHwa-g8*saUu_SBb>ReNqxFDe@d{zoc!QyLY`;oil zG0}eG=0QG_#}M|#od@dHyIg9=-aKU6`!yqRv>Ss9G^s*6)sVL|#pGl$arm-hZ^zu2 zaE~_~f0z^e$4a>A#Vy}^Jlus^)eo>Q4Y*6duq=aYe%;HC>36zNg7O*q**9ngS2UkpOJEp7gx~{$!egK^ z6DCR(CS_a+*a&(Gf=XG0C$7)rmUJN$oirM|Y*1gdnRfZ*>Q05=rVqouW%Gs{x)!Ju zPS^f#4~0^0lA?7BR?s0>1(z z{hvE~KG?yn^F6i<)_xqNXgJ{UiXqhVKAXmY{ybQdPt7ftYqU&s!UErgI1eIrGZ&SS zR+7;}0$a5t9M+0-i1d~sZ0$|dEZK5h7#?z-g;;<>Y-A!neN8%2s?a)>AE^U)(un8OF04*3w6gc0*o`KfEHoclO20a290RBbKpWlgqb)ZRVP04w$^odet1m&nLO z!sa_rx)Y3`PTIr=-6=$8x|rB$-iQw(wc+6lAC{m9KBi3wQKGO=u4<$%qnkOmBWCv4 zV-qubY|3LRp$*RLihX%ZF14hjtOkbS5D7&i@$pjVE%r*4RXGHLCx9rG2C*0$3cyBr z0m`$1?wM#*%mRAv3yz4?_oU&JO{xRABij*;x&_WTb@hQyvUjfL>+aM?U#QSaTK z^9Wkq(Q`ALG-g__c)G)z7XQ5sI_$umd&Zu}P0VcmV2?kggwVj#7^gztSCr)0LdtPT z$5QS%swO_Dc0-MWAp-wc=|~g)8;KiPF&%WUSzZHB?qY$|c~ok8yr5_!Yc6y68Si+s zM@4Hsf*6qZ(mgKV@o=fa>*{kxqbXHXC|Xcn&n#O?z7}lU>0W8>EC%_3RT!rhb!GgN zVR{5~e4fEA$iM4UKVsR_L1f7}Yt422uU~kS-7cY58pA~?i8KSn4jzx=_IA{((>$+s zOXMJ<`C4itXXa{(WGQUJD6&nw$xFw)ew^$8-F<;fxS=o)@O&qj69m)XFu0=a+)GPNrI(J4ope^jqNBPGeO{@|yBL@@cn`SvDjLxZ}J zJ1{uybMDzQ(f;r_v=Ym9zJ?uu;*>{#xy~FM?#n~jq}P;>LXVk<7z>Er`=z`^Eg8#l zpQ$Yjvp?b$Qe#a~P+OD}@gtLvUQh=Oa6o5)FhOVz(&5+0(6XMinmur*OI;{t>wD@5 zl=d*PSv6|$ji?oGS}^(PbwLO_VH<lj!GYoc_Wgd!Y>o{!5^x@^i%;rY+*kcV7?y<)n->-zIxO1up zC0BH*wSYwLF3A&?OP>n#6okjGZLGv$^kTj86W-ME3ndiKBrARx4I%~MilLSbgC-8Z zl8Ckhtq_^;$oLmc4q>hV0+ph4)9I_}7p$5$-B~5+&?u7UZ%Ui-O}9i0vwNgL3vOhE z-GGhBN+^n{WI(`}R~q^#uZb^Ub@LLEH)Hk{G7eYp2(6CP@1SElZ*tT@FGf}?q=+ETNX$rd3NKZXG#sjo6-61s4=Rd{qP?3- z7c=g_qt#wEcDXT?iBl*8idIpPXBGrE`!Md-MN@Rl|E4U8Jkvdx3V7lA9ro;yuVM1C zpz(=2?Z#tVlDg^2VEVVU!b;^5N6hB7WnjGxv~aCIfeHC5Zn4L&$Ao`yY{l8*9hI$8xQ6*=%;;^OJf;_UL zl%Nh+gJ-E#%VKZ2CXJ8`B&%=0YG}|Mh(wC-H57=)eb`3Ljo!q}9((){VrGv$_V_L( zY&vy%l!EtNt6el_2i%W>&YX6ebfI3ZGR<^faAjC%Y89N3r$thk`p?pBaHM4>)DAfd zKJ<7aF>D&yU;_>a3gE-7n=r)T6{4Wc1j2w*hmqRC zXNQxMRCAPQEjmDN?!*W*(`0Vwp!{Wo1egX-Ep9qIaEn4=iC$=1v8WIgf`F+<(J}?? zp=QyM$j>$ip-Nl*#<;a!OBd#A}ikYWbKpb>T|*Ibkm{+<(2 zB=8=m`XGjs$mrjW!#$z{h}dzUR=%wMhLx$W5S0~g%-%!yu1q`RGIF3`4 zLj+1(=E8mwmm;(?9PgDejZUJEK`&oreJ#;>wLE$-lP~&TbGr3<6gmSUf?r~i7Sy@c z_X>p9u zy)NrD52@p3ZX2>F?1C#O)jZJph4>dZIZjkwLT!vxz>D|TX4End=n0>^vLnRHN>Sik zLIDDdrRyI<@VVWc(0+6HQ+JM3hxKk!DgZ18y`(|#W?ssC@NZ^>YtWYsAKBx)&XQfa zPdzYG9G;PdO<`RBi(UeoYF-%`_@eb_R`q3KN1X=@cON#*)nig>w82j`&jp$odbv|f zv!{~OJgDykF+MVR)BE#WgNw1LyQubtF1*wd^>w&C)=W-Cn&YW5pj())bC89|sXSkF z6El14@fMiy?Z&QkyT@NtLQ1+3RGpxm@FUmC^uPlcqtobdSXkjKKb0hoXIV2s81R_B{gOqftsUgRBA%ib4Mw*l0&UhF4XUG zy#rBUGWD|0lislX095E7itCSsX+cb1s68c-t@b5)3Eo!D*1|$EEy!e?v2yvFmeCGy z-rIM?%mz7oY+`1QJ+=}mgv#tcch0vPy&Ud^z^%P6kK%yx#Bpf{h_?@~!b=1|b-iBkDjO7gPSi60E(U{~TU5nK(iT!^!pd zy*wm}25NDEn=Lj#Ns2?$=5blIP&3?R;+P;%xN-v)mC>lbqC7QKGvZ#G){9vp$vmvm zW&R)Ly-`~ll;X^U@*9-bhvlEnQ-Pi^%QKfeU1HmDLvu1;D$%JzU8W43mw;*FH;T}JGyid4B+vVFz_>%_zkVyZbw|Y2hOCS5pZocV4^l-bD zEO1G=hl9!JbYZDGQ)-3H*y-$cB6mIR7MF$aQ7E+s$s3T)Yf;NUn*B@)Gn}-^fe*Oz zb|wSiQbH7sosf(6gw!WG%RIQj^fQ86-gG~~_P{c^u*DYuXU&nBI}_K0U9#xe7z+RJ zvKWvoTxS;|=;6*Q9NUXgWbNNUsj1>Orq=2l z8EJDW@m44)C3FW1HmBQMNZj_N?9HVk8^qI)<@ey2t(*U7bt9lew$@z=F)3P%fab=8 zd+hN>m~f9jICc`)yDA|Ydwe;S9p&Z^=ze@UFc%mEz;KsyCoCvR>d-UjybWETi5VJD zTsqir)$W1A;=0j9cq3MUE?ddXD9T^a{VqKNOwY8o6Z&p4k9#I7{2k7b78Vi(QFG4RjBDR(WmV)QBJrQGpyL&8Di>zpB5`@HY}}> z7crB^+GGXAgIA$(8H48Q_76vPYuMHpHwfU_{Ba?9Y2Jx!vnLR}Y%@V43#zAa*?fyV zfB4#b!X#WCs@7yA5|dfM)k+OZkXxLuqF0#?EBZV}^mAp=U}l)lzenlaK=_Wb zx2!N>a8Ex3%tD)AC~+x<66(jnQKSG?wZxp&-i(HJBaarj-&TtEgiBK7b0TES$xGbSXsJ?y-#a?#2EOQ47_oV|(j`%V5Bd^|WK-Fg zaE}etZm~|AnEA`NevcnM9kx?{5F#pd7vA;Wxn82 zWO>oOD@l9v)X0w2+wFGQd+hPnm~f9x+uS^MU2{nZ8Smvh#72m0`?Q?h0YM;>vv}Sl z;#n9uJP+|6MGBgLU?E9jf=VY+Kx1oguTh~R8J&WjyrRnNc37&5aPD1HEbaPOoj{0- zoBbHYckYv_DFx?OjGEtw3y)hat3&Y*ZcdwlU~Pk!1f=k=qA`SmBqsL*3A_%~b>jh&;roq~IBYKf~|`jx6RVPPNOPVPSG& zKLoDpG!w~ridgJ4g;xBMm1-~7F@w4eQEPJy6QhEF>-WI=<69o_1*B;e zj1VAV$CJEgTfmG69^DmB0!2xe{)bi05w0gnT1=Bs0hB%HWgb21HfQ=0T%M!%P}De_$chw% zkue@x(j)VeksW3W>8M0(p)9}5Esl?jAnT4di9S@sq{(00P(b2PniG$*0Y6FUtavdD zSXNymC`L##N&WN+|1JR-q^^~ZunL9fkStEgsO-rDGeeA5!t!(=a)Pz$UCB;(bgJV zKmt>5(03cB2WcK2e)eCGe#Dtv30e#5U}2QVJk-J@d5}P`5C0R?1SqaMsKp&82@=3jgwI=nX|s$;CqTuUeVbJphova6d0F6fM4OepV&qo$8Ar?J22rs*WXjM z$0lZe?bx)+A5%iHgp3IWI>!F)ZGpKTN3VW~9ES}T4D>=}+8*yrHLy3$hz=Z)6Dg5+ zxjY4HQmkluka=Ht0kzEfNX%M!;f-O(8R6Q$j z4}F7izN^KA_S*bGv^$k8rQRZX&Cg>-G&F($LBSTW7`z1nAu9P$FEaDrvRlL$KhlgBi-y>r#mSH%h^xi z*d{f*D<%&LEkt9&{6)2=!<5(_FCjhR(z6f|r@<5jR9w3NHv1pZ{tG9!o(QB%uVQJ> zgqikY#f`wiwkIV#T|Vnox+Y>KoJ1G8AP1>fl#Yw%KmYdG+83ePFi7XHa&+8a!K5>m zP+ zZiLzl{~LvOOrLCsH#O&@wlkM)OrWKCL=-Nb1xwaTewVb~ujxKmJaXJQ^5PcxPYG$i z4EwGjUA$jS%xq-1$0la>c+ar|=-z67cyyg{Ki?Z(&NX68H{LjP@9dTvREQ<|c&xag zrj;r!SPaQaiD0#)X9(ULW5fy5`VV#!WQGYh)H-Mt7GTT=l6#YXx|L%GuzY#pcfjx; zwb0_JvlCu;05rP@g>$!1(})t9P~;z#ikU_p12w2q?H`jpz5%5dn$~(p(2~_Q+N&Tm zo0Q5>XhMNSG=dolCyW4Wo8)(xnj>bM_hYVyM=A33P%?Xy63@(3S*zcK!>$DGKDL;{ zq9*LY(x3XiLDVHH{4;9uc@I8kQ`tsIohtP+b9h)3-xZJE49@*2m~e9}du(E6kKaiO z?C~~A=$?vU-tSu{pRl3A>Zad_9HD`na6Z$jrM<7XD|C<$Y6v-6Hn!EXUY@n@uF=W5 zG2G-d<$g8vBjhiT#|XKMCFg&0+6j3C`TPEvCE72{3_;b(y{_{cG{C|a+P2=`VQ%QV z|7&_4Cq7cEv%?vN7W-cDWVy_!i;tijqZ(1!g0Ft(Ka0QCVtM?WfqEkOQL9t0C)!uS zcUpi#p_%bR#?|I+IBr}B;Bn8~J6}8V6MhsCj(Z$HLU}lsVnM6Z!eMF} zJ5L_DU_^WkYf<9F>d|dTYy_+GAAQx{1yFos`&l1#orbHjC<(jrgz%|`d}m+~9Lo9| z*A`GP?k2SkM|#Zy%NH3_3{G0*?FJ;S1i0gmHQ}9$Js+iOs1Si;(PIs`od}+ zi;%(L`xEtOkS1njOv#9gf_o(#_x}z>Zbf?`7mEp$DN#jF)l~gUAen^P$ z-t`Mcl1*Fz0$IIV10C@wKmhl{tm|5Qh09E)pp{n~l}Ut_gL#7+g36U>P%9{z@UWdd zbIl8DhGjkRXbXS2CI?+5fCQ9p;mj}cB_b*5nyxrjOH@)z`GB)h~iI{MYO{?tjua%I?E1OnGr4M@5 z(|7v6NkjO@los|2bU3~vU!fj3{-XmUdvCa;NQ7AJgA1(Bsso0@sQ3{68`u8{bwF9&MhA741jLh)^hY@3 z$UH2C2?RrCN_kA-D3||;Uk}>E!Ym_I6{{s5!|Y%D)wBL;D`Hv&Wuepd){?P?F1%PQ z6b65b9<7P}h#!wpk86|V0Fv31U-^a*BYF9lev8>eFZdfymrA$8lW@z{lxLlhj1G^Z{+FEP5#miFL`cCx~n94P;4pS5FJo;6>Sk1xk zMLX$*Z1NzFvZA0p(No;QC|!a%6Af=ts0{6!Lj>MS^)CFAk|;mcGa> z$&i)<@hY;sA2hosdhMX(tG@yh?l6r#wkT|3W{dS!o*$`%Xl>1?f5DAVE;XNAD`H}n zJVZne$vq|FG6+a`hkJCuOSwn-Ky({iQ(9iBN5z;r6huj+;p_CS0x#Bp9m#?JTQ4N1 zn96iHSw>BA0@phcMByBLl6(tC!2*`l^m?sBTMay+`m#rAtrBU;pPWS_0&(dLny4k8 zjmQC?bM|F`S?m+W<)LqsJRPMsCy%y%bS5^!9DMsvMfK&W zN?aod1H5C^c#=HtE{b1pq0sFu38f9x+l$yNu&tMlO89PRZ-uFjUrP9{QTH2}?6HZN zJ>GlloTZ;OP*Fm_bu3o*C@6LGvh$q}mmCv4L*KhfBF=FHubjqdG+KismHx`Efzp;$ zz*t-qsavcC1P7Z(=~xmT?KRE%Eky^Qzw{&Vxv5WIy1qhpaj9;01q?6|aB8BGMoaJv zaP|Gw)5e5*?6HZNx5UbOywTv_Q$phVWtSuEa{BL>L5NF=5TzB=8kE3A z-<`q zGkp!Gw_4vV*0)@6S_ZFbHs(~OG+qj7Kqu(Z6EG(5sIih_eQ9rEi09v7 zLZpb3;P6|Qc8kh;Yau?xIH#0MwboDt$Y>}X75-^?k2mO@wl(4$JV8rMX$bw}`U@P* z9^z#I5W^tr)6r-J6om3^&x`A4oU0RzgBCHV929x*z75$n+SRCVlUfNt_ zDCd}zD3{r2O$fvIib2;e`Ri=gaEqkKmv zKBrd5gs~?_*T?*xF_jf1%_A^QpEM^`$VZ@o(Qw86tG779*en`vpE=DOFO534tkN?=sitv*pyW{boX0}{g&X~t(n`UnCUw`hs8J`S1xS0oQF~*CJ0T}b8Pz)p$Tr*~ib!m| z@nSGThR%s9FHjV`(ps#kFvX{^L-o)rh36P=!@DWg({@jpnhdV76YII$^j*EvUkU+b zO-%R?0Nuurd;C(_`G0$bHjS{yI}kJ3!3Z7vVVWGIT^jg38bPZ)wCTq~11EPqOlYd- z@L@l~+lK^@-=X)VN`l=W5I{ZsBP3-6vJUfV^w!fz@6Re#rfp27ur+12S-_& zWVxUma#3hs#X*Hwe^gk=o)!qpXaiPQ;3%fsRwi(IA{8G9-xy&cdtXx7I;XTixtas z*Q@fWW;BhgeAAQzM{H6pZa5-K33JAMVdn8OQkgd7+T#yk!aep7H>f?{LkZDes-?Oy zfkS|fxZKiy$j1@oPQ71WGg$>6%K{1XG0*Av2@DogP(JUqOZ)l-V3^0P@Q55$IhcJh z&n7DIBHwd3tS9q`ak%%v)uRtrhQVLyh>wXI6e*Z-sTmNJQo=ypf($>Q2xi~VTR3}1zUM(Z*szSJ+^jFFDV{Th^!5SJ za*(hw;SYyPo3h%(%pRN5c%y+gxDM`7LadaGRlqx=zyxQc%oCs3Er>c);de{xg2h@w%gL$mhSanc`;k8T!EBL zKf+ze`WYj|!jXmSKnWm3DU*{08Q?L+Uee`joI6ljl{7Q=yD;I#M0;#dzKNMV_IP_G z9MBZczVKl+;?=DUPYyl&Y6Ol`Cpa0CmyR=*U*R9z9+B1s4FoRwegj^D9e2o<|Cb7-zub+bYn3DowMhH#pcz{w#Wex<= zs2`8vM{=Z$YYxZwvnb6E<=Rn|9_LC#lVL9qRgMmX1-dlakC9w}HZzddv)0z_`>++N zYcF=tV^xctJST@Qq97A+^c{m4#Kwes?D0yCW%BN$wy+w5GqM5=wH2Y)_4{~aN=F)iTgbGlRuV~;bu zog*M=@!{aen3GV4J0Z^1V-0Vcgri-ESb>u4!a^_!bw%&k6nTOV7|mq`-{pt)`KwP{ zRoZ=*ld-UC%rLK!!!LNs6kLYq)T0DaSA>un$;|}<@V9Dr;F01Iy7#hf9uoaw%z|%X z(nttOmWg`p5SBtE4h4mK1d?|+!eN#d_n@RgU49ez(PCO48k@h9B%7`?qBS&nNraO0 z@Q|m)C7AhYOt{A$d;DW!W{-al*1m-);>*6gm9U0li=RXO4HDMH#ih?*DbACUZ(T3# zDyk79gkN%|^^Z^n@)-6-v+JIny#u?Dkiw&MX*1$WU=Q^$PuZ zhQEl%r-ko0>xKX(ofrsY@*YrIFca0NtJ7tzAcKjsL75=~4b+YFA^Cx_+ItUfrC-z3 zK@VcXfa}!A3%EiOgSa?eB4b&3xnudaNK$g|1}7h_hF_2W> zyS+YQMvZt&A@@OYbG;5O*a15MKzZ34I`vX=PHPVqv<18Fgb*s~LU5ZQzi7Y%jfG(m zW<3qCbC47oR8Kl-M;FLeHOZmbKB<{&@KU-u|1rl7XoO^VX45rwtj3CAFtejnBsNeJ zsE`V7y3(c24?V*gL~S7ko#U>NN6aL@F<dn{mh({qatfsth z8znbQWt-L~KC#3s$%(Ht=3#^2>GfRU(K^%;Ob_(*0 zk;pyb1QGjcr6L>QH$1Ift3^&3pz}&B_c!yk>d@AMp+Y?b4Ak(^TssO^%Y|d4X{QB) z8n$Q4{KK_RZO;km-ZxJyy`J_v&SV&;&dV8lJfjU+H4 zSe#N0e&!2pjs-WXqyf_;rw0wMSnCT*ut9OfG58I?= zG&Io=gV@-<&yCOqnfm+fBWSakNsocaVfJ3BX=N0!D~iAS&`F#kViS_Ihw!6=AGh0z z4IMXf-D49od;GF-XK9fiu7qj;HgBE&)NNxCVbJ#GVHc*!8xt(PZslAPH%u<&{u$E) zzJ~311E&HXtW#PcW+oTNP)-b(GQ-Em)pHL3Xu1}dd|Zg9((*iCG=0TG1C}G9mp@&i&fQORn-tW zhm(tD98Tjfnq2F*gpHr_wiY*A6k4y>Df5zK9UQ~qc<}_Y3U~v4K*kO_$Z&n|YxzPY zoC6W`H=2a<7H*42E!E4PS7zb(n6-cD6<{+F00iLi*%^sPTrvxe$)cgXyGh=ub zG#zOurr&+>1^cB}n)dPqJyb@j!qK5msfq!my-2Yq3~WN0qP4avo0z#pDE9d416v9A z*aqXr6Emi7i%#*s`qv@+caF<%mqRhI1aYc7)ogf)=s@iFMXuoKGl<0>;^|EzDu9t- zf$b+^p3a53M9*g|L^bhLneaR4vKNP!+!uJH8Zp=LYWiAfK$z1Oi&Ra1@r^`L*DRps7N8|X?wn=+urom66bnDHa&F~$TCslv;cOO_sh}kR4E!|r?yUnh11{)^Ey&#b zR-r`U{IU`6{qQc0wVOc{oa9eD7M7Vgzo5D^apeNosN*mowl={K%Y&OVN*3(`pGgWq zdRj?UKIHF3ZD0V^to|~68lgSiw3;8$7^FZ(z?r#+WAk-0oU$u{^l~LlL<}h{-$D`O z!)r9(5CvRZ4(iW}ip8_&mT1$LnK{b0G`3}rrn(X3arE=xPvvbH{5-`X=C)~L!aX)L z+{DZtd;IP3(2WNbzpPT8Ke#R$%{9~flH{lZUOYq@b%oQh)ENm=2nwMEnq1{6`vw0m}?N3KDr@ zhKLm-;)hQ@u`CWLiVqXI_JTXYST07hm8bE3-5W(wy(kSMM*=O@g4G0SbqyI-y~gS- zbiaUS(J@o2;)g`LeD^GRnpx%~a2pfu@teo@2h%jRr*~JvT}5V(KS#`P3CRm?jE^TP zSnqn$^-;Oi?%S*+X)9i&<+jWRU6sxmu=xU(dz5}X1jYn3u;C?2Vb{x9^2N~Y@GCaU zzyNI=V(Euu!b4KfO<7^2gocJ-xD!9F!4h0^o0Q`)B@S-)oQd{^>O32y6=UbJ zPXmOntY7QPH0PBeLxWAs+z#${Uez9pm~gWnd;IqCelpHrC!|dm#9qzx6LuzMxe-O} zrc%hX_%>SkU{g`}K1iAo1RRN5E8wT%?&V&{uG~+Bi9+5{W zc{1cK^$;%acC3m*R>j$Xy1G=xN{G4$w=#DY?ic=mC3DV8&JIh)ktH?t8j-n_1&)M? zg#VSLK4sckM9rZf&%PCy%8CpnyI+ut)(n4xu|u}ZF|(a;k3IJIC&bJid+hNJN|*;H z$aQQ}zla$UpiO7+M5fTDS;}rl9H&piCkX%&oi_;_XsSd3FnL39PnM;H!xZ&E8)D%C zSzXtQF>ov+5_))#E%#Q45~8Fk9Y%7@qQD_H@2(f<^&NKJ$El!*ah`lo@NFR0yJdo zFthb;klkc$i)}3sxeU?xyQxX{ z{5W3t2!jdfE~^|_&}>l5n9!Q!$_c60mC?J!gRntm>UuO01m#KIJWid)m?gRyZF zC1Mrj-s5)qp*a&ld0SzZLbDFko~?3P$}7m)DYT-LG0Pn}C3RH5{)Q?OS!8PQ30h;4 z!M*4Qad@2Hr86;6&wSYym3ry@bOnC~>`>vQ0b*eVb$fDLC)IE!1hU>C@M>UH?t*sf z`O2WotkLx)jjgaAQuZYWMWmn*8f3 zv19l|aoVpGB4(8A8&F$dl;^--*>!qGqV^W(`+6FCQEs5(nbSV}!#Rr7POF3iK(_^y z-QJ$7DKzB7mAFub6tDq(hqi_f&9Td=(pm)hixzO8|9=)>MTLrmjB1Elm$MC6S0!Q! zz2?Z?zKaJLn$n9&LICk3w~~6$wwoxbB^RaAUKV!3t)6XVCna+r$YK0*K#}s>mN%NV=C?CbMdjl#i?C3Nz1nY> zT}PaLub%GRmMpgi0j4ULDEpnoLtF2&aLx#%5!WMk#Q|>jwI|4)>ch>oA%|hDi$z|V zjo(PVx}2})y)2zZt?r^0@ZzLL10%vz(?`v<`?!D1yM_3QppQn~f<&W6v_h6Y!^3jm zLQ6`G>2<`9}?Vc{EEa>p~6sH|e#Wu1QjA zDH+7Q#r6u>n8)ZNsxVr~Lsv^3+IZ}p+Dtvp7YW6dvk59Om*`I{-PX?pvZMPN?1~7l zED$+s`g4Oehof)xiy;JI^B9l$x@?K}4_Pjc-_z~Eu5U+p>Z4dA887vo zXEY|w9c9Pr2A9CuVf&GZpl!6DBr$O@0xYtK0OY>NH7%vFYdY33;@Uu)jj#Hon zhXOIP6!hrKeohcA69jNkfw!%$s5)+7MNRteF`ChVw1ddH0c8bRZ4yd_-2uV3k6y~uLPv*|tsdgq^_;+BX%u70mLw~Bz7EC7mMwA9A z{Hq8-^I5@dykwWUP6j`1m|57?5O2j}S>#5Mn6p+pM^5@~6yx*)Le^J{Kz6DYS%)O` zbwtU1`=iboHzHBZ`$dXxA`wdYT<@tudTo_Z4QhpD8Y-qp{aK>m^wP)9+elF`PzB!b zU6+X3w%7nC5n%!bQ?oEgjX`RxbY40Y=wt0bR_nY|uW3V~zaO8!n+sM`(CV240mbBh zojGcO9{r1#hySOi&7|Gv=O5`-|Ky)d$qwr`jZOSn#!;&F2B8psBOnfQ|9a|N*atAv za>5djLA9B8CB#u9nMuuySH$HKL-@Uckq~MRX{rMPMB^jf1!`*&4vNpU;cB*7k;x9R z1{T3|DeEZ64}lX5AUDgdp|9i%%NN}IXm$NZh$+PUhBfJcP6jG@_JV4%suEU&l?ac% z^v5LjcV(e6|B0Zjp12dQc<~ES13n%NmLmR=f%M1dmD5}5s;7l`-OfSj1_ec!*`I(G ztlI}=7WlRh*`ilr^&~y8YW?m3APJAR)Z}Q8Rhcj^-b$2^jn)nM{_HGpu~H*gH}^cMRM`4}W}0VyFHP(g(-jpyd|kLn6$>n+S+{tSK-5C#zKv*rHam`7z>|sI9-6k<0g7Qb-2B(Fd7tM2T zmE79rffbMU8s-)fvc?$pqg6lt)3^7CQ{^d-GnGb(+(2IC@K3fCVzhyneQY{jF+b%m z|BhJ>@t4}p>er;?1FjwrkuQ*_K3FX4Tb|@=G)11I;xaQF)3>Ph5va;E;ecEDJGr_5 zxJ=--QYy}$>LbeG>470X6!`J1j7Cwd2|sLpQiw+@<9uJm$am~iGw(Sg`GmdUwcUJq?Bs3H6{chj1hj0l)7y@p=I? zqko{&ri#=aPQ{gJcA{L!{)JgXc6dl@u&*)c2 z6C8g2#$N%*3xfI6*r zsJ*LFxbguPij)SHVb&=tYG5@PlPyu(yyTP%D}2t;hBz$uxMzYH2r265qp6U@Yf#Hk z@;Ye4M1t$gbcn;ZUKjpm&dPiNOx@CH$&Iv$>`mTcI zY{kg={6VsX1+JYjnjx~YX_M^SW4GHl8Dt^>CpBqYpbiB%f2i(LvN(%&5zEs-DcW2Tftk~Hp=3;)Ic%j34B-WT_;s17+o@ocwmXcf!%ySJA>-6;VappcFFq-Z zZ~Mi-E^ReeqA#!^A!?8~)L_~KYq}v{YqI0}n6pW_b~Cs9Un=W=-Sk-BvY@kdh(Z7% zYm41%rJ#m7DAZhjd$p&;Pa-|(*&Go>jBw_!q7(wPN4UID6w8r%nBq$I-sZXuLS+%h5?xVhG_e36XR#k__#5%hqnY=FL;nm} zLeeRZAj}2V^J?mODL1qdFu5p8{4YzeY!u6Woi-RDZ`*V$M6I zv}(Ua~Ou#GLRfglQDTH{!VreMnt`$1wn)Eezn`l}|izAwMz1lEQ z9#IfL>PlM5;CH&X-gjwTGWbz3x145q9e*TEFTy#;zpaB*%U2q$e*B#)FlyPYU3 zV4O3}R7E2z^_}@^WO_&~RXSFdJWKjo9#v&yr7ds{I3mojx)4Xu)nK!G*`0xWZwyJZ z@&8oc|8=S4YJS7#*#e33q3w+zu6x_6^5Bl zKh7Rj&(|pr0~2_QuvJK)(orkzLV=cL1Afj(Gn52s8h8P%qJnAuD4;ciWRGZ4G>7FU z$?2Ql@&jMlNa_z|G1i_2bQG(|jCu!hsTl);PlY=83o;U8`3LAF<}1k>bsCEohuJr> z+gaKQ+0LfAZvbihSbqyF3(NpP5$l+|PLvg}RrlFWASEeirN-nV74(cr0yVwx0qQk1 zH=mwK@3h9%*{%n2tFz6$;XLo}MgUqpX^eh`=(OUbcTi>ee-&k%Cp*CLCAiO&==Z$t z)61$Fk~9BqEj&1U9^yngitv_^(8X|{u*t;t)KFQ~iF zvP1&`bsHz1^;Uzn@P<*fERVO%_bYiqK5D)F=+CFAR3tiTQu+Z5g;ukYV7*2{VSPWv0Z{LUMSRsSb{E-}KnwuY+EW+#kyHHvo??|7+O zS&o`5;{f?eWt+%8IF20Q0%7h3Ga&!e1?P^tk}*>V|F_a}Xgzn)WN?Ta=Re#=h^c4? z=;iA7o6~h}(gq9TLB5GRo@%9#C>&1Bn0WI(C*tI&p}eKfDWME~KQqt;4e^-Hx9l0` z5v9m?#6X~JWQd3bqtFT^hwwXy84+}|deP-*WR--M1t?R~M^jhlMG(&s_JyzHp{bRH zpJ|&YJy=XfKCuuK1T6{H1p4-fPk?c~icn6qj0d-G4q8RhWphe0OEQ6jX|eryaKr(v=O|nkf52*iMM|LV+_>^Z;zL%(jJNqOF8Y>RTFOZEaT7&` zt{SM`sI+y8ZO;!cfNA2d|MZrm8~1|jUjlztLl6c+!5gqiB)?QUc|WK*9? zq6fVVYP1+9CD|a^@W%x;E7{Ea#AS#Dv-$HLV2sWDH23lNyk;9e`Vo`GnYHKMB89UL zFOHxMw*L(yH+0>%yPKpVwx$#);c4awVs^psm0@C$kZ>aCwMFZ?VLUcJ%OHEEgsrE0 zQR|$JU+0H5PVdQ%!Qg@Y5nr7w$|WOTf#JS}wIjwl6~0AE%x2DgP{KCdKOCjQan;Xy=t`k;X zLT{|E#cOYA@l)03rEJNvBm_=Qj{_%c<-}wQ8u7>ntJJ= zW=JML7WTF<>34YtrmiceC?cb`JnbbKw|Xxz)%2%vXp^{^1M9Q|Wo@r3S95GV_$vz| zG|5^kkAF(N+yegx(r8Hzr(}dUBNUrvNogMkYX$-?ATCOn*vS&hlMG4Y0xNj)_b12x zqI`h&T3h{-D|LtsjZUT7bMAwrHZWh?@+6PE1k&W|0!I2OAL%8OZ9-C?bgWy?fxwkK z4LIFOA)#M5a*E+uciW*fhsx(9{>@7(rBliFaPY?W68~;ECj`o)3*HX|F4J{SCjR0*$3sxBUMECVE(;=~;M)zXxvDby?!V#`Q%~Q4>J>Xv#5B zU-3D=$h=%ku&nh>?ftk%=cpb^qVql{K$NWAsc3%bWq`$jz&?<7cLYfAT3!Q!alIs@ zI8%CmYw}Hl*iz3iOc?~g0M@d;{#{LS^7}hTXQ1!^g>|Qp4#?jRuFF(}p30zuklCD=%NPA_?P^UJ0cPHh{kPST zK2h%4&)Odb7{soAxi)8zkA+%kR?OzlsL)6UgqXMcy(6?A$xE0$N3`vp27x&YLprN1 z{?$?_gAD}G3Mw96WBXt$L3Y=bcSc8MacXo{qMWA1JMPdtnwR!OwL{NvjD)fRr z0ta>_X;&}~4Z#QDIyfa!nGvj!kU(Y(Ct{Y8&#Yu6@Jx(oO{hTAByXj8f^HSi1z~J* zRXRw{#PQbok|I(>@7cGrk9At}2lI-#j71SRcLh=cV>Bw&WeA;EvRu4|n&RjBitZ$6 z+6@`B{|{L7(-*r~YvOyNq#FsQ-<&T%qqXWnLaB z`jucmFZ=HZ@L-h;jdoIo6hw8x%I8LPuoF(>=7NBO30br(Z7l^0PsGGW8UvCFa=$=$-$?E$5zTF|VB%}QwA@`cg#f@RPD)cEzOcda0eYJUpH!W-@n(vz_H6G4EUM4=7^%0sorTGS=07 zXnODB7Mb)51pl9*-CuQ|;|rjB1sLhJ{yJJ=oCh}izE z0<}*&Yk^|)oF<-`}@4$!tD@$sYVusR2vihZi*6)e7|QmlvomvC_D8vYqC+k!1B zXEP{b_LMfy-P@vNy&`ksRjPJMN&hPRS(|$Jk!#89sz4y*_WrAw`7&YWE0xZ~i93#h zmK4K%FMr1B=TZk=9eKOM$#fB$b*-n=s{5SZ@ZL8%RA4vh0uh#Bt-!P#+?R_OY3|lg zGlJx;wI|(ORn!?E4=bH#7MvqKo9(!(6^>_Kxd`M%W+ZY zrc4%3xHJQbx#=%xI`Hq#{#J<*(bC{heIe1aO&pQ$w3zxmQS_5>~)GV8EWOg4Z(w=`*CNlV}Kzr zZ-Xw`5&y;R)qZ0n$iO+zC_7{WDUoA{ftl0Rn$f5UA}Ai>B5zz?34)eDD{ZXQO1W9U{&k_Y7_x1;>_EYIyU2~pL8#w-A zH=qTVm~{YW{PmY8mh9%(fz-q+(BKYdSYYC>ywmTw71=|9`&E$i$VNT?K7RY(T>?ZY^YztY^nKO_5Ea4IY&YVA*J3zIZII^Y^vO2Humy*Iv2Z_g>0eCLb}=RqC`MZzrM-sZUHm-;Nm-FN%bdCpjtfyfa6u%C z0*Hvr;OGHOF?WvqB@37Js-QoFP9EJukQ!+i);6g4Z>=-xJ%W$H`W~Y>NF~9NS*GY- zZAY0!HO;Q2fMS>-rdN%qrWkSbMDm@v?`C<@bVbX6F~T<>2QR5~EP;E?kr= zvK=Fa^=BHxYNVDw8`HzEcT0;0ktr?O__6#AN+kCuUPK)tNb~5<3$Aw{Z^M>~O}vo< z76P_&Hst({QIwHKE?b1&s7Z+QyIrU(@XXY6=dUKq@O%wDq(c3QcL(vO%lwWZ4*k=yD{?w*=pcl`h=8_{xD1gC<*iE4zkz za_ghVY?8qj2WXp!eG1RJpT(Bc)#%FKeGdD)HX>I#&4=4B)Qn86~ zy!B2hdc3uNwjLvbrFDCcF@i>&Jsp&~TcEYA7T5jvMYyyNl|TdD_9|3QADMijgVDRN zv?TPTZ;FsWxbv;6vIZ+V-LtTc1s9oXY|DTp`qR=V{FK_i2cLN~I-sh`xT zZj`L<%ubXfhWk4D7P+qRQ^V2|pqa)iqKsDOm`$HNyS870>6B=B`!!FHe2EGP&LrIW z5Gu&3(ymEr>_BH#m{8M7$;9$9Dj6XIU|5i7Vfc`v5f}U61}p#9%{g;3>j3;mhwh3* zrU%7bbweDcWkZa-bcKNx**3Ct-v2RMS_ZPW=&SnCh=g6yNc#T&EI?3YwwuWn8fQPsLFtg>+r6qkh4T{thh^W-eCLlN5&OPfBr)$Drl-LCN+aIlvr6P;8LG z4Ta~EuChAtD$;@(Tw7$57>RPU)o`dDuAOd8FNQd(MTgN2G%Ka|v6HLv78kcjKjBZW znKucsm_~I_iKJ1i!irgaE?e+UMVCX}*}~$g_3%W!^Ewp@2w&><)L3%UAfQjj|4Qgj z%NWsWT7n46+C0o_&`)x!el!!AWk-zo5;T?1XQ9uP(h$C*+|9a~Lf$vaT?^9ie&d2% z^4BF!MvZ}rR6+!f+UmK#$7bbWaQ-SJ&R-K?Uo-Y7{q_lv;(eC!n8mLl>oC01-I>LSo`;CUi z_5Si&;tZJN6+3!0{E~&RJhvI;ZiZ~+liy}XiOj|=4qaogs->#7g*~uMaartDP^2bp zHophvS{;{zldT)7OLrL_a%8$;T!J9PSmXof2UBli{J|L4iK4finzn8|@e?IQAsedb zFj*I{A=6`Bo0w&q0~y&vL%I{13J40@*Wug>T%gUjdjET$i5d~JX>Qs13-(~6zHWln zEgP4N$bvjFh0-VhbX$&+Iem!&LDgjchYdI?vpLA~2Y5+O+|xSl#(GS)TAi?Y3kM*(-1+*vp*S@UZbv0EzQ=!yYKyz^PS6doA?|A)e2nJ=fccS8Z--< zqPZHlI-Ra1&K=8*IdP)P{&zR`P5ZgvD3jN2ZuyMS(n2)dUv-T2^g zSw6G$mh+Q|AR$j6H!!eMN;)Gq21;2?!6rQpRiIF!IFg*F_(^N{now9Tftdb=*ptAl z4#uu>H32IA%so#%2`0{51T1i~5VSDE!x|^yc>Jr5N?5@ig+}wNQak7|N;Ebu9ppe3 zvQ`>;`{ge?W{&D1MN^a}eNGoUIT(0$7_hfUG(#gRZS9Nc;c@Mna$#a8MpsAcczI%K z_oa&Y@83NRJAY>`;QZkUo%)5cMKHPU2U5>(}k;54PRX zYFwTmc3iN$uLtF;@pmxXMRG;TT{&MyfXJk$BSTb|^es&EP$SkQ%E}A9<;RuUONeeT z@MZcljsFb3CK1ONpYp6S^nOLYbM2)L^(18{G)6%iqy@zgkzrj5s1`2BA5ke7`PU0g zrgSn1W~ctt%`HohU7@alF{4|?+5Y%M6g=e+363;ce~;%RE_<{KsbPU&3|NbxP92cI zv%#ZdTXazfkW2=7BeSlt;$_(Ed1eT}gYIRz?afWx7>@hc2=VpxPYm)%Bu;l!cD)OS z%_$&2F`rhdc;}{eg@2vw{{)vc9XqlgG^;C-DY$PsdD(8%su{y%wK~Mv5PHdTN!rnCzQ9gQ_LA|^w0_iNs~~fVV9uE}f5su?$U5bNZL4RprxWr;yiBR*kKoV! zFtAyJm5NV`Mtbv$(S*`FC6+?$hPL(Mvv*PXJ8f;!|j@(8PWh zDmc8wZnww910bSoI*HyeOb%ldh&_5(Q=;N8x19Pyb#RjiMwX^L)fUD%P3O;^nhEM*Cev1G6|2vAqnvcJSPiIa zy?2}_e(F%%vt@M%c0ela84 z1^Sqj>hRU3nLE@7-&MWjr&Fi?LqRv#;(OZvq$RU%qLJE?E$PvYDg&=Gx`!6K;i(ob zgBl-^sARSb&Cux$x~$w;fppVp9h-IO2Rhn@gCaN(?QD!QAs2h1bU+m(lT^y|ovihS zB`92N;0=cmqz_ytHr@;*eBNi!iV?Vn#EKaLwUjo|>Gz;LFJ(2s9yBUxLzY!W%e@qC z;y$gKG=Ualjk>Em^lqp6?oe=bwgmW~*h~pWZYgXBj4r%2Z2}QE!%+Hkg!teKPfzf; zW=yWRame;KM+$f9rEz>S;r;_BLu;6lFuqd*X2(lyXVad9DVjBm4WOBOUInJfqVl#gWw58BM;f1Ofms|Sj41RnuX zvto9GyVgX)W_cdXa6b;lPaWA{ z1T&uWymGy0_&Y2B-AAkR#pt{R(q?F%ACOQvrJCJ>EG4MfcIQqVTGo;(#u71e0J8_0xjo?yOA z|LU@Z!Ii%J3TfX)+NSbm^?%1*Eb9MmY6Qi?+fixbC$xXFiE`lXDAiUkR7)0p2cZFH zN2ytfK=wK1rc7WT!jFbwSd|!R&=5>w>MuQ1zh@XJr(j+tA6kSNNO zM+zzK-$_~IIN(zUyn63in~e$yZgu2ILI}uEFvca!T><`w4^9pI2}B%Z4q3*cGYxhf zilz9|=IR|E?PZu5w}c|Rww#$!LK5ei`K=^5- z2-%(eNkzLiHDH(vInRAwq7?D5j~OfueD8BuX@AYM8h$M~o5qiS=w%EC`;%CQZ4`dM z5T;CYsOlaJ>>N+05apSzGBaxZi@h@)+e9q|akg&Vlc&xIkFmGFw-uknE zArdWLUu&A1zDTR~iz?ZRKGd2F+r%sg3m`86v{KT$-oVo*O8YtR0-_XByGHXw^ea(0 z90~MeI8Ca5pJpaW6!jn}xOOQ*sWl)W3o>uQF7(*)6iQsQg7Kh($PhAdxLlTBM>R;^ zudI9i)Y3~%%2A}f)%aHACJlPZd&;Bm64m(#eZhk(By$vrT-Z<$_rBres#3XS=e)fF zj4SV*fy7DzZsTFy(|w?9T5g zYp!jh*!&S0WFTU2EJjIV1MI;BjFkTRP1=yFGmMXyCsp^MOo#s_ggckv0@bD)Lv7X=RnSYjgc97dH#82MMA--4~5 zxv5w3c9ndRIm&mc*9h~mM{Mc zWGU;1 zIKDmn0-EEPd`JEX^?(blBSm;BaUZpD?-!ov)^D-bwruO*7w_@Zm=m)M=#AL=Z6BVh zTnqi2#dGi(9^QhXE_`n?<9vvQgco5X|GwmCLjG?7lRORrWac3^PYRhS@iEG?AkWz4 z=)ggiepnU2$kwhkw)bBwjZPJ&KrMr&To|FolQPw8Ry!rPOtim@%vAPt;EmaH`x=@l zejy|Umo>njI`DiK?Gkgai>maISUJ28B{9jv^VAd5DT|lw_|Gvj7bpWlBRU$1aQv;bjrVJ# zaD(+}E|fP6VsJ0_MkcCz?w5B~cB2*{7Y6fe0B9gFs>d6aQSQfA8{3+3|1;7L0K0y) z0U4Tp3r{WDZ?~>?xX(=gApL$1+c7*Xb3hMxT@bD}wL_j&mx&-#3MFEO8>-mvR48?^ z-4Zn-=*Fa0o$)|2iO~MYApS9XF7~ZJ7I!8VX(^B`j{=TUNmD@JG~bdV$}-yt5(+@r zyvr#J~An5Jt)nvv;^ymB+ibIr49E6`u=H3>-}jeZ-i;K7q| z@7VC^g)9(`?1Lz4rDXf*MRiE#l)mXP=eZ2AqQ+M!Ww(X{4L^23rFy01cm15@fud?u zTaL#=7NUy2sm>qB-+|)jqjBF*pW(h!bL-`?isr+Pg2`%asN!VBjT?W!Ow}?-=n#nu zlKs4IHT6Y!vsdXoNt?>ncQ`XgW+zD6T08+txCb^|VPA;4?h@I`zGHi(ce{S0|g=r6j{B_)q;dbLH zB*3Ced!V(%?EIK8$G5sP^+8hE_cYq1SnP_fKmNH214mJ8KkxH=x5uiMvRLyz4otM~ zx7L+6SV%!_VK8dgDpNuCYlt&@!J`al?B@Og`nY40#3qi6?7G=IC6oEc4<+aV2UfTh4s(^rn|%t^5@2n=KCFkH%Ml z?DM?VkKy@&L`K`Gs*fw5a1(q zZ$cjX=%$y*zqCHlc@gNEM{udJytuEV=hAWtR9HGo2=D@>%1S~`rV#n$&BvL~jqG~Q zi(#|hZGETW+d`a?#}bggOX3HKY%&961FY_4cz*0-D^vP-#I(ej|9Eyp$DV)z zI>w)csV7C56yMf}kE@Dm>djD%klA*k;}c1y+=rVp{1v}qqU^Dtt!?t&&E8*h!ECGm zAKqJLKx6NcpveO;9w6yc72=^IBvvp$VpAMP-{9PpqnoC|R0Nhnw}K?fqy2<@v!hix zCE_n~ITHa_xLU&bcrTz-iDILG=imREL&O$lo1_R=3~wjCPTN+{FEjBGh6TTqT-2uJ z6^d4_&1MawBe;Y=+fEvNmIXKV$84aS=z$79JO}87f>7lpBC-Pjppsij)gMB+pp!d9 z1-s%;KP58@p6S#IA>^_jd!d*X4m^snHF#_sm1F$hOH9^<_L0a+2f7g^T;hI`f8DjU znMm^?+3%R6N*r2;sa#Cw}#(DX`1r ziFj!o24J%Qr9RJLv>~nx9o7f8&-)puxh}<0^xaM=X|9*R3UP5!7=*=Zs&yjZgHD3m zaXsKEN`CiC#xD{FfBA*Ui8YAWl!GPDwS>o;RBo)Ad+d`oI~E(4Z=~Vr4*nO^nYoR8 z;qQ7l*M{OiXc+B8WQiWaLI|1tzKJ!ThT|V>C}ZvNJ3w{bPyiOAfAer8b zp!s!p(hD6}hye>%aPI%mt(vR%Z;o!IG$AA2vW zuS1Xm2kSyoF5U31jX#WKYzak))o3BfBp*XEV91O^1LjUaKj6*HrfR2^_5$JTR<-_; zR!MTF!O3y7BFf(UDLj*;1V&SW2({z2F0P)u;j=Wo@t-LycC7oeld}IOi%}Dq=IO-C zfp4RAJyk~lAT3rD2x_fHe`Vh7f=UOU>Q*nZBl$}&A>mir5s;lS3c5J+H3g_J)p{3< z@XzUD|3gU!H)^vZuUa7y(`YQ(!BioY)kl6|n`UejM^g^Rv`Y4x9iUx?8c?=k<))kq z)`r?n!saDed^i?h+WBtUwbT_+G36}n~%+4VejrGqa1QUAnyZ+haZ}lN>Em-e2 zPa%T`MNI;yp9+@)vPJg2Z?{n=cz6+H*kE|MU$*AjqzYhK=2ZnNc6oX}hg?OJUEnYc z!SwEL;{&-?Knj}~q)LpxGi(irlsrl=YSK~c6!l_*n&xH==4jUjy=URo|3Pa!KeWhD z-}!_B7~8U%Gj*}!Axx6Q&xg>D5Nc-77`{uNcW)Wo3t<+jwxY&dTgE`ke;cS#YNjcW z8_=WB5^aaOTO=lg1tYO=ZpsLV08O6@cE1fN07U%AWMwAdq9N{huO!O>j}Y67*tht~ z$A|{PZ$cYofgco!Dm^*cLl7Z*SG=}N@__YCE+Q;@=VL?d_S(=O0O6tqU7W^3I>p=@ z+Omf@j1Vu`<;dTPO7W4NaUL~DCk5+QzoWZmKav7z6E+@ra0skw-7og;dzA^u)BoN- zyvE@X`_EsiUCgi6Hz6~2d826m^}s8heTnt09Rn{Jkdw(AZ#GtRONe>Pr0qCeSqO&m zOFmc>QE2#tp!qiflTCK8ZqUO{Ma`xZ)tpSbGr@F`v}w!v*CGw_UmuuzR^j znTeASWdQGS#exAHZDLc#wKysB{>JF&96d1ILOdm4LN4S9W94J?LTG@;<`;(D5YL@8bN_pD_WwA!)j?>z0?(Rfa}X(` z2c-2VRg9!*JWNWSUTI(Bn{2@oq~3$Or{l8M)33!T_U5Fxcz0HBOpdpaNZjvPbj)S3 zH;7mRyqO=`c00*$w3|x|*8-piHO+ zX8e_pSHt$ORdD;YBI=~3h`)`9oK`3meV9D+iLu}A=5obofgRKEY68d%%ECG*83QJ# zIx<<72T3Rv@5>NK7o~F(6ib62c>T3!uHrQD^tZ&@3G>q}EECVYldfw-=ugMWvTulf z_13TcEaR@lmqfFV|5zpm-bsu+f;|W}^R8P~LxNOG0PZj$s8aBHS`$m5=uY}1M-#t7 z^E_+ZWV4&tA*43@WN3dV)+T&K_=Ohy^qyXyN25yQa3mgBB4zs|#8gegAaimrG%*O{ zg-j89BnAWGz14Ej75tfK$a@xqrVD&f;&A|py9joq@8#?!DeC7?Iu@ldrMNm$!=z^E zJ*GuxRFJzwcG@Lb!bv3kL#}dqOtG5iznr<4c^ZezE+xgLk|c*_eRR86gX6?!_(&I~ zwkutSrD8`04XsRLlb`Wv3nH<7n>M$B#f?Ef^FNf>527=(dm5*<*-Gp3Hdrc+qSK4p zSyLDDtWO-n@*oOBW8f!y-I>Y1j(&h+Q$fEn#pL z3wMGToeZI*4aEhhdDyrJw$VM7eOw7%h$g1;u#8)asMe-cFM8Q7Zt$`ny+15vh=F4n zD%S+{!>&}Qg4VH8TA=@PTN z?aYuio63Kk<0FDJfv%#so~0?Z=9|85vEU87Nz1oepHdT(;x$vrycLWoK#?&Hd|V^H z(BTxhHN#8?o6?S0>w0kH11pHoiH7URxOCNRNVABMBkTbp*(%Z36M=1jekc>Q9OZjlH}8CX`~K7*|YfWG#Z%J`T)>2jmA>^0K5-e z)9%E_puGM+n!bTOudeGhNn_i#ZQHi(#)LzmJ;xkc z*Ewj*(iiJ-T9#6E2iqcsKADnvYUk&(sHvSSNm4w+ugVK0{GS$J{1$XtODt&amzLp8 z?m}_#VU>uoFm8!(br7p!SZt23zxe|l2{y$D`uL#RQThTty`7|Vkc|1c@wE9`Qm!L1 zBq}V5z}HAs2wBaGYCb8$0M&258K~3#rnNHclJ(e~MSaw@Pd?pz+$xA4*1?acGE_p= zahD~X8FRY6d?03N_AFiC`0N&KmKc2|R{R%o(uX6Sn*?Yqe%w$aAafoP5B#>rMmAPS zH9Bpm^ zns_nY_*&Cr)e@)3k`;|G#-9&>wn@GsO-lK(-gsIv(lQaZbS@St9 z0=(G*9|q9knD!DAkZN0O=AIXJNd-~VIH!{*^pt6Xft5tw=n_B*lj?gJ`D}h_lYz;C zyt6RVp4l^fxRf!8{DBTx==|>5*^>RDqZ_hqx9T#YCG(Ch#{65t2mXgD=8RMCJ0-Jr z)X`!*_;>H8=(&DiA2E8?<0jmN$I8QLY~;q@hNtJ~{YjEwe1V&S9%Dm+1AK$Z5U}cw zv~1Cx0tqalm>kIV3_IC^oqeO^p^Be?jo79FSS;qj;4qi9;(^gVI0Ry>N$PlI=^2O6 zVmhjLVRUt%@^W7|Y|!Am+1E!jP08$wl|Ps8F$p##ZpImgTTsbsra5roFU+xixT};SzhW79(7_g z%r+8LEiUz&SQb5E5(dwESq&Alid_F0MY@e72Cqu=pB+ZO$>8OwbuzRh5XHFtWE1HQ zNL5r8a*RQCFSqMCHRv5jG<7BRMJK`JKo@C@ma$?dIR$(->iN80P8>7af1c#W6RHBO zWfE>GlUbA3`?Ar6O|GP4?m1bPu{yx(F5d$zG(O_}XT_)l@wIxvfkO=}e-6RepaKBTYr%+PQg^{B?^qB|rIRVjmXqDJ$!EYKD0L`Ji#F zIz{#KOBt5PF&`nskErql+STa5&H^2?a%GB1Qe@3b_2m^r?Ke)RzG{8m$5m)5on|ac zUHgCZ%*wx5AsaH&aJBG)v zDvHLRBqk)LsmGntidEhTfD0ORtleLR6uxbLQgy0f8P~WakA8^ks`pTdEwr?6*c%eV zg{){yZzuIy77|;}S?5Q0HU8#Cec$hGO8<+Xf1@-?DoAp}IRZmcC; zpZcAgLa=sFbw>85k;ycr48r1CuM$yk#Q8hSXd>6@Tg0tLQH<QtHcoUBs8O3Y2~mVb=S zo%~X$Sa1}yH8!>t_`%3}u{q53$Kpu8))sznQl+Ddw&%Q8qagjLvl_v*(by#&g^!Nf z8FWeiPm#)d3LCzrK8MDqTgXRcTnNocRMs*^)R45-TbBwOiDiEqX!CfvE+2;3#>h+z zu1xO>C3RtOzZ>P>z}fqKd`|G8gqn+aIDFHzofx0nS|^JWBO0pXnylKKsJbd+$Gt)e zVsnJFo@X z1(+yD-)t~b!8ip&L}cVhW@!B7x<*!5WM`BSOH>87^B{Vbz(lmj&3aH;W?DIg9xu(= zIb<*vUq+8m%WRcJPhBJh!DhbJe%}cWl_edP0d<1DCYS;z*kO)fvQ3>&Zp_0-=kx}Co zhISq{^|oa5P~hsMo)!w@MF1?)+pf*nqMrXm_p>zt$R+=mu>bhH{&;A_%n*SYM7dSM ziW8#%PJ_f15y1MZh!z0~Vx^f!)4E>v2VXwxtj%~8fmmVA@|-X>BcmVq4;FD7QNw#i zVyB))R2H#qvDmY6!lXzE5Nb{PjtQ8SyZ6VoTe>iCsz$CE`8lkOyBYpFwn05XRytMe zDAfve-i&g90?Lsw;pD8U``<;P6df~R=H@apU36{vI7##1r9=E-0&M={ zMYP+1pZ3c0D69hxyz}*5*krRomQ{uYNZ4M^;^YS*{OiHOku`8MYH|i2f}1aPvUpPNAyU|fU8SJ^z(u$1WFgc!d@Fe z64H`<6zRoDaceTGh0A`)CmYyV!ePX09=|*E{W-+)z4zW<^{*a|ok0yso-*>75=7Eb zdEulbtm19Wz5tJ;BC^x``cx<%9r&)(_}ku8&i?!(#`>a%N8m5laXt!W{6rAHAu7HX zb^jW(goI3Txi9jkq>j=n*FNRRdk)n}Df35AP6D64A^Yb^*YzXRpD5$F zMoG?0UgP-{+_|(%n5!|Y1V=I5pMs5SzhWda&k5?PR#V93N!+PA@Fixb5V|n}83sbK zcfU_3H}QUd!|n##bE4;0h3w>67z)U5D?}$o1CeY10Tx@_f_#jH`||8kB!P`NDhPKA3eU+;$)n$7IyMpz(*Q5-R^AXJy6`)*1}Cp%^yfOI^*z>Pvw z(Yz4yviJ*;nq5AM+$;u(oBIs&TD(c|GwZKMK}adgU`*|WM6>eYhJ$X5o@%Lw%)zEv z%kW(o!c&o8fhV$*f0ptZ${M!B`uabY+l@&?W^C;@%3hSVG)LOG-Bwl&PH@9bMW$^> z4w`4+sR`@n#w&wRW8hO*WT1`!A$@%pFuH(~tzxC<;P|zPdZP(Bb|-)qj;~;lOyj|j ztjRV<0C!CcD#K?yq1LZ%oeXCcMCm|yy54UBdDc{}Hj?r9I;%_BoW_Fi?Wv2h1C213 zo~20;K*6Rded!|ajS36OZJLKg`(aMk-Hjx-Ul5Wqh`znvk8cLw*U9YjV@GXVq1LeL zi#0ulJU~MDwxDp6s;E)_uwyLg+VUrm#pHU1(7lrx^gy4j8YSTF#)%+i}kuPDcGE6BQ6GQXaPbiH()l*ZKzFP<8Ok!_ku}#&;l)#+%b9;5 zo~$5?oRU>S+`!dX7dB+o$geug=4?zhAs<`ZT{E zc*{2oU5~^XdDzC}DbA965BaexghPCdbU+T;zU~wBwnN*PFya~rf=+AJKS1~0IaHV4 zo|gKJiL-g{=j# zds}_j@(ZEMk;syy)1fguyX`gEYSx=r$B^=5BzSSgD!M{U9>xh=9T8yc)e!RgrwxVQ z27mUHJ3#WX0H&jC)6Cmd?@H`fn~3U&Zn0gf$EggkFSaO7$s#EET_q-bI4XO$->ez1 zdKkUF_l8$mFO!uY=wzao%}8@Wzx6r(1c`5y;Smi7Z_%uUYatR3oukoq>iqf=N9bH} z2?+qsplI&s_AW|-BhC#KVuZRCG0bJ@DrWvYVM(6Mb1g%`m(yATf$B5D0i-sB&^8k{ z(GC)$6Oxd~wpi;&vlFkQmVZL1`d7KmGTNJC&B-`VyA-!U!;(MPOB#8#(*3$6~z59~B~tMs2xqM@NNQO5%QA#|-Ji zC++%8EB~ObcE=R@TXgye8n(dmm>4fdS#Z<;KNT|+OFllA1YZ?|s9+^>UoXjzV&cxT zzgkT#!tRY1_D&bWD!4k<6B6`sRX_OQrB{2%Lnp6EZgPmr^CzjIO39Ww5sZJ*OaUQ+ zlNO)_ePMoy=Sh~aCjdx?_II7MN6i7D*FNXs+CW(e32OjB-HA>TyJ2RWP*wik6)L*x z>$jD9(ox`B*krY()-ULaK~Nfus)cE))Dm4xpZ#v@Lf0i%GJv=wCkZdaeal z8Rv&b{32~9T6*&M0i|6ny9?Qarjmd)mb}P)QvmutlKiMe_fopif1~8)3s)RWjx_TtyFdrPqAsAEWNSp6Q z`q_DmDfOWGexShj7^#`36`MLyOPyqZ1BJZynG+(90q|QAFqz{rsWcI0sWj-4$CInjpE9PU#9O7I($#(eJY$JfQw-mje1jW_t~{J&Bd*F$A^1TMJ( zx~!If=3|3mPvaJ?YpiMs2eNfndIIzGp!ziQ+Ol^ZEKRTR9d$VA5D`-jFmZV{8oLTZ5`m(gM zQGoPaPcV!CcuoJjZ=bg-=!Wq;DT*<#3JL-qe1GA3a3Rv0tdoV`hQY>&ym>kAdodxK z(qQ_*z>W(^bl_s>(XpW4xQjRyz$EVP>&hll{t3K(WK)JH;?-`*wlC;(3Rxg|;#wA1Nd zE{}o0)21BH4)`4=_0DYXAc5nmsC}+(*`QWu%MmL4>l5Us0_}1VT(b}dbYgg*X4}r+ z+f>^~E75`-0U2!~eNME-!p$Ji4?o!vfe&t;F!O&6@AVQwP-Zymk;2yu zjO%u)$b_Z-3?1awB$NF-xiCOFC9tL^MG!qD;PvlfqHcjzYM`~#9bOIVf7_J!;i{iY z7ULGLsnYzzA8Z<#7#@5@Wp!!w_7El28v9_nk~TA>5s{hAP@+x^T>+WY+^BvBl3ET^ zVC0l5YAHzPMk(xYOkI|j)o7$mV%@w?CZD)6=096TAAAEAwMKiwaA-l_@WAKu<1M3( z+Cew7MVDf%(2efHrFBy)exspm=n49eyYj62Q7y0VP8u7CbC7q&H}##{-?;tg@sazN zg?lv{T^*W)OfKg?ID#dfm#C9^SBMnMqim$W=)qga{G?YYBO_+;~;oI1fHr1+v?($h-QTlnR zv8MjZ`9~TH9t&ub!(=Je*a>5rDmhA`(GZe2-po|-p02Q11u#$89VuT}xw?{&*?wjn z7Yg^$SBtZF)rd%`zte(mhXhhk8m)_`Vs#O|{C^3aKaXL+2@A3#kF+_KvBVi^wLs7LV4q(c1 zA6HjEbRwUNPoUH}?6m;j>iS7=4d1|4EXwuh5Y zI@Iy*fjShE zA?)G-mZ!ENW`2abO(?MJp(CTWGLl=vN9dCl98e!UP3);D8aQFIiaBJn0t@(GDGyCU zcLI)S3Nthvk<=wC$rjiQK}07(8;0aPWV8?ws?4fme&Nh7XE(P9dpd10g@1|)J;bC# zV%fBZt)~3wF&%1y&T5c=Ja6|%f$VA>FjO|Kbc{!99+RHl96h_%6jxnUXK-e^97JY*8 z<_j@vQ45}gu{cyg$U)av33eFhiZUX<^W#>DnWmJK&U0kRC6-Yuc?mVKM3WFAyo{PF zzEkCusH#YcnHcFyj7=G&iq<2N#cHx>!7&#fd$_ZE^j1k__q7{KT_zJS&R3Ikt!wpw_J;_Wu_dyl)k=U6lbM`ZBI}T1{?zqSI=npWP-Lger9*bnBZ<^xr;>Paw-c~w-qkApS0-F8mj&A@~f{~D0 zmr|qN#NitL^be$+f-P7fr%R_@tal+}C=2Z!+AdUu%3Trx(RyXGTZMuq&k2iv*`c1(H4oW`2*E5V_C5<&*W^xbKZxNL{8cjmj@tf)y{5+2k?#2iEp;!J87>FsT(wdv4 zlRRZxL!YRSEi4@t%p-xxL1#TX)tJVH)0Tsc+z61nHo3klTz3)E zT6K^7gw2loZ;VJj6Pa%sxq89dhlR<6(s@HLaJ;lPsMT5<#>I2l#JAq58k7BO3Io2i z?8iP9H!wdwd82ySM1!?GXBEQ`#pFzkCIC2DGA>jP0s+Z$A2PkgSceq=Qexs6O*t3( z2}YG4@AESCQ^Z)QKPOs+4F*@}#g(to?`c(~NT~-ca!{4Tyh=3KtAMPua*nPjvHzLL z;0H}S4u*MFPehBAwDm->w2U*lV%g(?XaQJzhU}x<;X{EeIEKtbk{|F!)`n0d_?hS; zmZ-QIO@78h2PeG!cM>lp9@5;JdZ}CJol4)@23*UMz}@=yA^Ey9M^~lWu(J8OJ;9pY zR;zfkebR<3I%Q6z8vtGrB}&A3j?Jm_i*jljGqwh{JG|Dpl~7Q(!Je;zqt6PakVg6y z!aMiSFp9`Shk9^7D)Ln>QiOn>VmIrw-hzl6Imdc|!=W`B_Rmmz=ZnRtR|z#W?12Y) zwigIeXl}0yE@T%qed6*1uGV}2XwvNH4N7V+iPw-0j_ye{7&(R;rWvK?CO_dpKU~G7 zstZGzNRbz@iiKAPN-8CSQc@!0a+kuG`G$p+(6FKT*I3}9Kg}l>teg#4qM^r2j%!VX zyI&ss#=4%`AW-b$jJ~6mM4^-%CNW?ea(^eH!G;V_gKC&0u17MhECyDD#9KJfLpz<= z1z*=FA_zlL+x}7G9_CRi`kT(8AU##A{K!n>2c-dZBXxSOhXd;{D;7FH6vCTuE0W*A z?olXBRuthyVkVJ?#AeexljYbhDgPi`qM57Fve3Zk-l%C9;(WQ;nbmvu)N42XaH=d@ z&5BDV3uEJ$R_+Q4(v|5UL5u+5w480Z4cwxSQiNq+dfzWP7imWKxVX(R@1;{sEHbQQ zX*gJygWybV?g%DvWy71X9{!L`|Lr@_u%_8vhkqA#T&LNmAsV_z7)MHI{Xn}1Jr4DVguiKCivGz% zWPN33CcG07Cx7SFKT;Y7ASQ5xFcxuAf~-k|X$!*gD)dl+e3~COlUKg__5wSdq6$+O zCJ>QK{q{A44Xl>Y)wdnZeM1T%BfBsy7G1Qpo>ie&K!hmhTV1T(4!lFU!>BE$zHtyK zZVGDpojZBV<>*X?G%*@l0PO0hy%Ka0KD_d7O2JrY_*dy z%TDv;Qv7lerNr2(%wP!LPdMNDGkt|$`Llip@p3dsQn-jc1&jVrLrt4)8#@ww$!=#6 zPYyts3vBKZ_44d)(d!NVkewum%#}d~*-z9pyemuUAZCl#K$=*nzE3PBTrxDAU=W={ z;~=B1Cp0&-Jk!>D$Z`uGp9M`+=zgZ>aIC-p&NRjF6ExTN8n8sB;Y@^?sZUlk+G|CY z7E;EgLmEkzWZn+%$}ZKLvQCY;sElTJlOJ9*TKLEx)9+RzArap?^!UAJf*4{TH+Q4T z;q%Ktj_ds)rxYH&3rpc1moP*Tj7a1;b<*S}?)LCR+|z!rM{=O*A^PDgjbDkSE#EcB zT7t3fFiZL?cgEGCpExT&sc$%dB4M@uJ! z)0_U@c*4an%NDc7|0~$Njh1{@%4GMJ@}WLa_lRi^lFADJrJYik8M}bwn`MXaKP^Bh z7HozRO0>*eC4s{Sd%V8$(Mf4Mg+8U7BDfmy(vTUtH#*vZpewR(RRM)IB(l~JtiJxV z)VUrq=y`;mr*833!*I>0!ek+nqZXVfx%LVBc9{TshWeb?VmFU=f8Rx!qs=q+O;YWX z5-dBEpZ4YswxA*3oUz=X+_1ZHM1XC5MshBqEBoTAy$CB44DZ<6)H>?A0wow^TEpuYCyin6M(=`T)ci9P z!>(3U_=g3l*hQeafHPNPqiR!B)})SmF`;C_hIBjXMO1_Js_cREC`}?VH&zf+2HH#2 zZRnBUu7gLk5Y?yo|JcQB?w9r2=aC!=O#EBNa-|z+%tYc3Zwq#JVZ%O_^QT&^3zbV` z`H>kf>acMC`S(*TEL9}`vP3;uJ6WI_R>Tt5n8I1m!FqJF%1!iuoa7mQI$rfs zZhQ~cn`v)ov=c3Up{a^WS1jlxh@qi6L^(0ZA4NO@ikJ2JArZ>t!?mtZ%i-9YJc_GV z@llmap!>-pXlg?lU9LE7JZuhpRV2nB;j9T`5sZlruTU_psZh}f8m7<+%$47KzMqsO z@(5jVmOwV!*t;MExiUOy)+;!gEbB)$wej3vqz?&u9uQAc7}oKjedP=aFCSL@i5z21 zf2)~bex`2u|Au;-oG1Bz^U>q89U1EsSgK8IF}Ky_gCG^Q0cW}76pekHM{3P?-0vSaTX<0LT=79+v3H#ds{QWvGen=tGd-4gcY~u;STaN zVHKqf)Tvq4d_RCW&w+VEeEH0mls=9H=?U~gOY0iMOmpIQfY5Bas0eTiOVdHsgiDBB zJuA+|YD-99$YGpvo4^}+Nu&FLS|Fd=Vtc`X&LAJR2fps7L;*tZNbLHn=zMFy&tAlE zMIl*#$NF;5k3Bg*uv@f@OV$7KI56P<#gMxrb@IWIxpb0XTFik{9{*edd4W(ggvuhA zs}_pr6ENPBJUskqoSqPV(AUk~N@HPBx+-{9DMPCY8eZfy#OVIF%q=@`mn`<`RI#5!HU$E0(d2=fY^A0P7Q4XZeH{A#zRL zk`&FY3{y~uH<`SAG7?HC>ZD5`=il6%AXvdW1Uj)wPvWLRx553)W|yv?LoBltdkSM% z*W5s{+bWaXTmCjv0s9dh|A=WCX*ulOo!g&CsVcpZFQCEn5l%tcFJU%X*qv8n(~Rz3 z7p{p&`qj+*&J86ktmM)!hwhe>hISNDF;_gR!KsUkHu{yjhfc(>9Hb?zsk6rN*G7y{ z4yGC!2Nz~E3t+C&^6$J~AB4u>IzX)_SB_uW3dbP})A=X1ZHOV%_Uzb9BcuwNFWjzy*s;p(;j9p0An-k!s1q=d@eroQ%ilqJlyUIbSq<^BYmr z<$u3i`5@;~ixa+VlMtO&fusR;JZ9r*U7#kOadP^|_r1YH(?>sU7Hgk6J`KoqDn@jka2Fs z`=(khnZH=7w$6@6-z1dpsD4b2ZDq#LNCh@+rh#Y-3DXP|8>3*^@dugSCvp8(nj{dB z;Te7-X5pHx@?x|x6tCYT@hIuDiSv8`CI1*&X7}^h)EyUZOqcPLION1l&B;=o~uq20VIYXT+-}JM;L1( z%_J`}@hYkij%pu{ahS?xz51FD?p(06?09+$k2MYe&mJPZ>GulSbz!Q=7aFEL_a61x zcTMK*nZ1Z>Ij3m9a+otze=J$7Zb`%=v2vWO(|{g9E&NsZ94E}sP^OD>w`yj;Iir2% z)H%NU2TCJ*z$)3ESE`ERhX2pM3Gf-bC8);$%HOch@`CEUa$ji$;2FO{*sHuK8mR08 zC9CN8%+zz(Nw$CK-h%mv-K5|3wa&f9twh(9fu}xjz~7+2oga;Z)K_fvr(vt&&3FM% zEbz!tAPB@}j;1fs%!hd6fX*|7*C=Zo0A`ZB;p|5%OB*@}L5H^GvJ@0JA|9H_DjxrX z>>jlq5#vrp;z$-BRUdskN~I7r$6()MsT1G+WrWs47_v@n^dcA;T!z?XEvAn1cY~P; z=n9st&lA2dbC!hOxyP(M_3Co2?&&umneavDE=Su^$ps3I#o=ReJ0N}NDa6eAr(sdr z=a?SbpQeLrp}f3dD|GBZ4r0`;9gG_!Aq$#?8Ac+=n?#K6RFTotW<&7X<8l@CT*{9g zXXy*AS%yC1-(t#7FEJBOA|A?DKN|=QWI;fssB!EyQkqMYqCS}2KqaM2*b8s^bDhX% zu>i6~vd3|vOi{7PUDZ>ErcQ?dNgJqQwbu1$TF1$Z7SP84g;vBkQYeG~ftL^d>QSK0 zaf|)OY29{%n6ZYRox0C>0VUqu{!h^b^ylxHKp2!EwU#l@yhHB#oP)}`@VeASm&#|f zq`aUl4{Zg3;M+<^;zd6Tm*05Wpw~Si?hW~v(h@HMk`p$Ft;622lX2fJDjrHBY#Ca+ z29ARkOFJRN{cRHDnX&YGhwP8cb4zKe1KLRj<||}#9~nM53dgNoy&SBuoSrbigsSzj zHNz)YWY9i>+z*Ge9f{M(g8O%(0%~Jrcc5d2CYkJ`Kopm4+~rk?`QZ`<>-LG6rQ?Q@ zB4nw2RJR-LOg2hY{&o9ZvLPLRa{6X>@uheS;AkbP;M&mElh8J-pcm3a1(}S3rKKuM zk{_P|t847Uve0wluGvYcOXGJ!FV;8c(uspR2WaiTW-Dqd-gW0xqycy7B<5|~_VG_y zHF6W3^_DiiuOb7oeeC%&E$I93zMy{2CyUhsC}e061)%YefpdConqFeo^w~~o=CFW} z&ruj%g59_AKAd>(OH%;#23Di_uxx%e3NuR2vqxItaWyYxAq|n3m;2K3B0>UI`OQWt zDEz@qZW#G)(Wpe^+Gw)r#ez6wZxq?;%$40=%urHA40)E;w(bJhKecj;OA`(P&-o2T zn*q^(NB=Nug+u68_$)S;y(j_0G%36pt$cat3kop9?7l6ZC=Q#`<3pXI&3MpqKRLY@ zxePHM*!;^3B{#AY+ zhb~M@;j-LNl2TKLmFn){tLGcorsHjOK(VFr?f4@Uc-U2^+uF+p492n z2yFsoqWap(ar&#bXz)1g5fjY>yH-aJ17h8@0I3GpW3s|JzRcyxrESA7zJJiS$|Jj{ z%O@Eb+BWPYu)!Ey+9hvpH#w~bKaEcI0|w1RD6%6WBhftiI8GP!tla4(vF?^@LJ=zk zA9yX27z@<84+Vaj&7xRQ+7sr_y(Ael*wk0*p;bvG);WMCB=_b0H0M4rPINA_SfLOh zA^}SnKctFAq$H)^8JW<{(x_9`CurGilemnX>a{~y=|#cQOr7b&Vi^xjx<>f@Ei?d+ z*i{qF*eG$1dl%17G{PeIyY1r?T$vH^!$QIb4|iC|LmZLwr?-P5Q5fy%$98=Fy3Wx2 zh?HqL9k~Xo`R9KMh;J#tw{%eYxt(nZ-uH)wLGaX|NiMf&eeEn%dGG3>{h?O<#?K~| z=LGV!3q{6f0+{yFPQM1r82OG!v!HL#z~ zM;?r;0h~k8)s;}=oIuq#B76X-7^^7B!MtRom_xlMC#1SWN{cfjgi72k4zT&qY+OEi zKkNldidtL*wL!g`Zg+b0bQN(~Y(@B~1yTV{Zl=8H1z-gQI_u=ux03AkylA}Q^CM*n z<~i_|`NH=;!CCJQx#KhYGlS00-oYAI@D|F~ChB#K`~7Av#>3FwP<^3sVz_+M+yydL*KQ-Y-{$8Ga=gCq3sxmXA8 z;%UPSWAH_5AIS)phE?<&nCTiB7Poa=h_viEl|zb2)bnssyPr6|sI49|ZA4%XH;tV( zNK^BnKUUFb>*^8yWUJcx&7V1ZIOJw6?pMw6J5h0jg8if`)_EK?-u9^q^0E6Q4O3sf zau~(ql^ot=Z*R%b8e_4F-Rfe>-hPZZ{@7sGN&pICh}BMhaFdQtKod*$hV0L{-JoEf z2XzLP*r2iTm${mYkQXfh;g5)Id0K~txu;>(S>;0T{cmXIvvZzPPpw-3 zJ$ZZzy8ltMcwQg3mtn#*A}5O$t}g&->c{x2RCOZ&LUHP)E@u*mOi=jiOG3W@zJLNE zd$8_ri;uzJkrK#vB|)-8Wd~}JKwT2RL53}h7tpU0M@S4k^yPw(mDr27dwiWcB}p9= zb!+Q3EWS)8Ry)HcsHQ==j^2ziCq>mMWn71{Hv^!*;}s^lLO1&njqMM7FBga=6@Axz zd_v!`#()MtqzJp&jUB9~v~B*iJ-{p+tX8yp+R|lIE+bjeIW6!aVf~V95iaJH>kcD| zw%+Mn6bp5p<`n;r9%u85H>e1KZJlroUc%$A8Y98gwbw{A9Gurt46*ixuI-J`6kvc! zK0=f3_eU<-=gNb(0t&yck*NFd9qoTuVZfiZX(NeMf!dAsI67e_b0cwlL5>%_wi;pW zd?_iRe#EBfl@~w2XAMxG$^UJl6`0jD?*zSp;Lisq!>QjXXcp_$H&=o!8t~QNN5xpf z30YPibWe|+IFMz?cW_D_im-PA{1-gw&B3ot3 zPfy41>L}clwHp|VhBsJ@>xLLV)F+xTOxocHcZO zb&%B8F(CP5gT+jIHy%{9KMu%Y{sa=pDqyj9WLH-*>E{6VT$p@111 zmyWPS_*0)uYwLGNb&x!aL1NU5ZvCLx1vukySp=EM7VIL(*r)~llx`WOvW``e4hFZc zD^y+}j{rsrMCqforL`wY+Ag=%c$M7KlL>#p`p47u*e&I-<<|VbR6F)>;Z{b?2(@6f zl^rvfP@}L!gU}{c5W5g2O}KYedI$bpYRIOySP2R7GxGbl{D5Gg?`cZ^uNshZ&}2mb-LdfFEWk&Z-}8 zrkwMQBwF5Ao>Mn6^e>cL$I$z}>Jw10vHUruI;05WTlhjVdP+rm3Ou^U!zTL*^M@>PfpGTlrI5-G{KZNm;77 zEB))fJ3pp|pBc4|Q2AB#l9tR|zRX77k`lF}JQ8ETSF1flex6E$JZW9$Ak7n^?|=5h zNUuE!#{4oCLo3cqg8}GD619jdEDQ&q^7%X?o@___L+`r>-*SgGN}D;C_|u%aP0(_x z-VCE8!s6pb=87sP{c3VeHKX6kCFpi0yIl$t&n`C7$9s+yvavS3FEdG7V~d~=PI-$l z3u8((3axFK&KOzMD~aQqP}SFD6EdzIfv8%`bB{woG#T<8wYl(Z7@%-I^@lwC6gcr^7 zD#po=BjwG+I5JDRP>2=fhuUfgCj1{3sE~*p#I(h__q>ffYw8%` zG=p*N%~BWSQ1}(2Oe3Ms5-L3NJ=OHhr)vqx)w9e2VoWF$(9$DiQES3>@dtcQv8U57S z#y!2d0h@Q-Zu&31(7t660pgW0@K+#9Ci>PP;4Z3d#Dy3T{2@Fy&lcWg;1k$d!$uQG z*=aOI#A^uRx142;yPHVxmW<$BV82S}-9=eN%oh}53DGWPLWYjGnp8ILtHFjjc}3gN zyG>k)sn=jnJ27VYhf+>sFeCz)s_xJ5z)uIGK#{p$x1C+No_xOt%$)`!1-b?s}%@g{&$F*RN-ZOu7`C zDHx+2T+Zlk3;N1F-O%@CeS9__JKAjnzy7c*C9}e%RPvDJ>jss@r4PwewK{Q=WY}%1 zED~eQ%g}p5xCneB+d~9^WF%4%xtj?wv5xC7BKI738G*Q?dcb?GB?PFOI1vDAn}ABG z`2|0Pj5mhM{zQpJ1FS^MC zT<#5*Y@(h${0`Ek;Ia~-3{)%cg-bOw8Ayg zRbVXUW9TLWSc5jP%!7Fx>-^Vy7O28faTo?Nxxre2Ot!Se07+E=uM;IqUxWdhq0!pR+Ck_;lXi$TPP`9}6 zI8cbP0?6H~fIuR$V#d7ER<%G?IW~S#TPhv@DY^lo*H6w9d$$)D@fI)^ zg}oqyxV_89<;%HMBo@I*N+O*=UQ{eG4-YN9<;I!KpL+ zPVM*-^`Z%ct{{r3i{_qSF$gg@r0IHafu|O1Z3(;Coc-CtR})nfs-EII2ES)jQdr_< zHGg#mkh5H*h03K~uC7A)!WZx0&kLp09kT?yr`vR6OYV@bcfZH9ylrUbs=u8j^<3ndC5GhWe&2 zF*QQv4E%%#X7=yYd!H-^x}%0V+Y{%QyANl_%D<}Q6wjv6de%_6&DEVGY!FmY`o&hc zIZpgWzRcmWdzfqg7Lq-nU+C1c|K}@-l;ioRC9ELV|a6kobwqH zPNfV59!gZFTxXxa#fkTan+vn!M6lo^xqza%FA;fS`6z7Q;IRJUJXa7B9J}%)J1kTt ziQ!PU=8R|rRh%o-hVz1a*lMh?KFtwR%SYoAc&O0eY~oT%9?l#m&d{-qab&)ZS@=g! z{~v1XR~KF<2t9Vk!MXVQEi%C*+OtC~5^%)n&Cjw=!VRyFI#xnscFnLeDGjH2tk>{H zR3x&1FM|ry9r}3qqSg?v>6j05$&nlpdrfCVW2C*N2F-}V2U#A~N|K-j8&OmenbtPW+JYl!Z-fo{u%zJP)3et_f{p&8tjzSwt=HxT!pc zL30&R+8Oe+>l^(yZQ^(ig@rke*Dice{26_4qqM)(NO8d7o1WcS-T#fu@+@ZDa$1b( zb9o~s-R7n}m@dh>K9sM48^ACtHF6a-_>(0#+79L%C&>qyG(Ouj@JJw4f&ved0Wne+ z^*%$$CxcduwBR~QdIvH)Tww2O#{4w}b;tq-OFM#7Qn6G?;66qQgR$ zyg>5>+c81zbhL1+n~~Zk#f&^VbKe9IACS#8KmC&{MA_G$4aEVcR_R&jRwH8ZS|Ris zHdJ1!eBY@Z_oE9lbFtV|pLVEmdhW1_sq=QFciy-VYRLSSCe;b&qSRY_w<7r`0ik?*xm)>D|Y=s5k6HKo2z zk!B6o>qwtio%+kW`EgHjB;*Yj%Wc^(1Mc_G1QYvZ9R^aS?(JSrzZqIHV4?uz%|OD6 zIdhWQgia$y4x|7WD#UwYpup$h&Lm?w;Krc66RDibSdNIi$}6uZUPNB=bnZ7%HWt%z zeC}bG9fUQHO(>Jm{n7WF?1@hP(z55*x`V60IU;czg9XfqIaC4^xu&=F86HI$2#gFOOg|UpW|7#TKx1?lKRr z4k;&;N{GP+Rwi_69&ZG$wh~Bh?7mM>At$f~j_}*>1c%HQBQ`C_Pk1`Zp)iW975U?- zA&!kt{AN@ze0?bt#(8z~dET_;3)gP}=SUIV<}pNP*NAAOb7@@~-7py0xl?~M{}Dvh z;i1tHYJ#|*AieZ_uB?~wgzBqrZYbKQ8C!K3{d}9)iKv)dGTb<@K=wi-AGP|D)+0yDRIuw(B_Av2EM7ZQHhuO0r|K;)-omY}=|N729Uz z&2`@I^8@yW-P&4f&N0R@df!k@liTRotPIEGHOce`t7`)D+YXJ*$N8xaE24iIkr8yZa-KDcf{Ij9lQ zS6I9E0jiX~&Z|Qzu0CWM32q=MR{7Mwq8rDbU-0FTnztj4s#s~q`PN`_-qM`9wL0yX zfe`2lBo5L660GQAGJ2di$ovsvEy9q>GsPHS1h6QGChA!X@P;{yyY44Fv?THfL8Xgv z)gG<=^BUl?P2uQguo^w4uj-l|xpUh`jkuG|TGn z(ijykK>V9RI?s~IpG#?w0$r|*t98~Ukkcc^iO{4*zr&!q(`0#$?qzUVshqk3Q_vV8Kq}P56=i?8_>=oFh>9|3pM8h|C7t(A$Y}(K=W*FE ziZC=)`u@cKu`4mCM_uqjEv-kV^#+XRqX7@<;IE1lhD2yCCrA--(m#0l!vrTb)M$On z$fJSFKOK;}*3P$Lr0{989l_2J>|cs{c17*vOUB@XoOWyi(?%k|jrlWjIqi2$v2YgS z)2|$&MLMWH4M=sH&_L@XTv@C-b*?gFj-M4K2@rJ{ZN@!ld56IhbYbul-dYTC7#b-f ztl_n~1Q3t=)K#xZVM-82oGO9yj{34HA~|52)-@YGKFQbpr6YQDwBjrx>(C|O1yX)j zPcOrvPR?OMGE?@fW(h(H(_Im$xDFVp{N!%3*28ume+p}`|Bx$pq+LwobvSUsinA{U zvciPX{cBKd4@rc17{X2uGJ^1nWZG6p2eZfLGD7+}o}9dWeYT3reXsQC4gVM2mQ#Zd zA36={juZlC6*wSc_xo&)Ti~A#!^a2MFV?4w-^4WGhMW{==0jp**wb=1jjRE?S~!hZ zV-pVbu4eetPGURe#HfE)((joq;79<;6r+V~N{d=FtL(5|sDyxXjzf|rW3b(AEtm_q zV;2lHl_qbI6tdEU(&eBEt=ELOmBtv*{#lp2-VRU#)$|WVi#NZV@w~LZGT(E{Q9>?S z5)ShqHoUM2EW!Lh4zm0P5JFmco|u@j_6)1STnV>ASn;wNq{N(BIPv{vq>g zZcm51CN3u;YKjhk=ZwP@w;?qSFsFSrp)6Nji+6FIZ2n5M6(kTDf{!++*sL?WH0MZ0 z(P)9u0o%Yk`Ebg~AdXqNB}z%tg1IMk2@J7bzx!v@%7R{Xqs-%HG8(yzt?|Ie{v<2- zjxS5+;y4o>5u|_n%)A>IaGSnA{$q(T_Z$ zdTU4v`%$u-(|69ZKR3H>Xs9Zi1XG9@vxW%g2T|Q`T>UQ2l#y8^oz@)RUi@FkvrkuO zEbgLvPY>-X;GE_dc8z=gDn^HR;GIwep&X|BAk&pIA&?Xb>^FAi2qrN_YWuqy4Q=!o z*F0bUvf|yQF6WI)*VEHoQFovt7@7g;5igr->uoxSQB&?mMwm&HOR(J6s4d$Wkgr`C zhvYLPW7Y>`3fj9o94Hp1sqYK~&2Q}j8}ekMmtW**pa1?Z@$;WGLJx4P(0PQ!CW>Wi zr(fGCY9$N+@15`Uj!iG;Ep|8Peof&)1!c#ddd=L;{kJ8pB7Wu5yF$(nbz1a`LtbY9 zk^||d>G_sq&)6W?kWT&@BUu3O79@dIRT7qDOPxN;6@5D{%G?BDu!zC@qfGN*`@N@+ z;N@vP*ROk9VIoX49bx9iGZ%Hg@P`yAl#PzfhH-Wi#i0)7fHT|4m30-i^oS^2->=fF z&CJzB1p-s@Vu!lj5vpLM(s$b?gYbChP2{POL&NiGz@|?w3}P>3^h?}*pM~>rgZyp=Ffr@(^_tt+YyChZ znZ1b?weyg@&+`S^3N9p<;0xogwz`>ds<6-#8{y9BPFB&$a~qdK6y(~PF*v(m zw}bCj7KQISH15$|m4Syt(5hj(LV+PvDf!7ZLN3M&vA#&!=7w4n(GSBsxF%h*`bB!> z6?kM*&^sQ}>E0CAht>?Pgl~GD7ILt)9BSXzQNor$>TmJ+Nz6)BWN#f6EbJwONr*Ar zEl#xL*fj3qvS3;K{6~Hd&Ob+yv~5~Zuv=kBQ76f)Vu_bTG?6ZWn zX4~ND4Ul7Vf9rWN@z(Ybwj9?NLs~|pZ@H4HUE#g5T_D0w#7|hIWoUKrpG}a-#R5K{ zMd_oJL|4`Ue8ba-B~6*n4Mal=QKZwdM0_?aT;M1WN05ON4W4}dwMI4A8~I2%U>4_$ zXBvb!3W1o?QNoY+P|{|d;>TF*mHd304EOa#7(xxgvO+bj5^6HZF#-cZ+u(7vWE{@ZJw0_AZ4_8wP-HhA@mkE;iGuvS5 z=L|Ov2~KA?#Z=Juf@o2vF1=VZJJ`Ud?Ih|E2 zdYE^BLRiIw8o%0H;A$rdN9)PgXnvmvak4iZJW~OcH5@zcm30kU{SYTOG_%Jb(cUGg2m3;Cd|z_rI<-cexpI^?Ku6nFcT-v12+x zx@bjA8iA@KdA1_x4AT8_pMercD1{&5!y*o?TT{oS+ET4^m69hhTS5T=?DdU*7XF-5 z@FT~AUX8ll`n1D<2Z|h`EOCRhjgYDyTzEbJQ$~XNn)OJagD=SB?REsX_pscEq$CSl z+~*X5gDewr8|1oxBjY#iNcT7Y7`DyYVpfCe@$dz)LiZhogJS3CH^61>&gIbz?wmlW zNl(Z_Xcl{V*}PC<)w$Roa2otiU_)YPi8c1jz%G_4m*WRg$sDq|2TR4+H*TT5q5rb; zzs<+dXSxCy*Bw)*UJt~CK}X^I9InNZXmh55MEY7RM#bI8Fv0jx$E-C2N3%y*n1JR; zuKbN)O6n&R(%#ftU7560I&12>lC=7g0-$q6+K&+U`!Q$r2`22Jz8k#qb=Qg@L+T`Y z^?YH|B6~TF1R`FB`HITJX`aZRQl*n`A4c=EB+B_XZD})>zFDY{Vm}5g#xt8ZH4n10 z<=6y=$-pZ{pcUtx-YO3aXrh#EV28@|#*pF0fpDh6gnew{?3S&WIPM&Fc4>KRRi(N= z(>}F*74jYT_+i*_?N#tj3Uv(8=;-g-5hRSR0$<(ILNRJH;mGxj3O#;?yYvlmDvi!DS+}UhF7U?X5`;Y(%GMx#5&PF z-r}@2W;4tjC6eBYS|km&I7P0-w&)2~b!Eldfs}D@x9yTRP^$v4EP1-PX@Mm%^$S%y z;=7!1?NYUO)FtEe^O>_hS@lMhugNQtCp>*7m8lD_J2lQg4V<|-u*4B7<#rp%dI-_3 z*tY*8Rn@Ve{K@~spm1-sq}d&O@Xh}~jL-^Pp}yZKitPc%3V@__lpxd{z$0vnE=p>G zb$#3**4oscd?~@gOq@puur&Mk@T6I|jLVw|P)!*oY1cp^C+U5QYK7&P&eD@qN_>t0C@5uq`_>;5)_J@llP>jp<~b`%H*_X75o@ zW;1)x!~ojmsMRDA{BK|txiUbzceFFX=&!Li-7aRb0K;_=FuXJ537^c>E;=TxPTN*i z74npApC2|b8mqh;S>Q?n-dv^tN+L0>&1s;xBO1FWQ0C%k%`TIf+TZ3kfos=(1PTF`m;aKNCamz`Ti9 z1yX*4qbuxJw*!*w?9_GXYxgbCsSi2of~D;H2g;1kC7%)B$Y=UU8q#GX4ES*XoZpXg zpGCrIT&2Y~SGrDbK_D>8ArL+$H=+Qf&!0DcHM%^IY*Z0AQfN zWz#!!8FvI+Kp+KX+~G$nOfK@(yN4~5L;nDXq<<4VHMGP19h5W5#Fu=n?f48YNG_4E01ACM>-F6+EZD~A85E~ zwhU0sDqXQIF^s?+ zO%4v9;N=*V%Eq{&+3g(MM8>z2p(!NQ6$h;+ZLI;S%Hef@*qLJY#LP%yZc~D>-;3z+=uby@P|o5viRZ>8 zV)lO#>)SBp0)+yZ?j!bTpX_hI|OFl^GUmuSycCYY>X@eS=^D?mSRMWe9Wb=fRb zj5%4y^6;oiBzhnfUIj7RrT&h&Fxrm9Yi{o;#AksS6k@9!a(CrmN&kTW7eJftU$c(+ z+%YgT#5{T$e_x5Dxg6ATOwmT}{okwlT_^ZVONYW3{`lJdw-vOrqbXVgo10mdbOWLg zGWtL~WOlfd2(wJp-UajX5j@TjVSBhN>l^duyk&Z@IBu(z&aOK8cuR3SyGtFy8uyl! zK!U_F8GZ&ybcHo>)U4uXBHU78Gz}?&Q5ef@f~iId|7tkqD@=i;Sn}mKLs#kY{tl7Ny-F^$!=trZcuv>qh1FGchdTk}x94 zG}Y$5Rvdv$eN-lcr{6^qjY(E!5Rck#-bvQM-FPC)ZD9>c{~S{bE2qZVGXvkdvG`3P z+5Ecfw;7j?54VYj%lQ-Ktd2X4fBO>lj+^|VE-E(pi02hPubfqNkBL?#3paa%(2`~= zdmbTJ0`se7)TD&z%}SWiA)lygN|J4AlZ(b7l{vI?C&5<`nXjYA)Hu;EdN6T=INx2_ z^o6k+UF)BVxmb`CLvZlPpIiyOA=v2JD(3Lhe@8rISsob-nb6?+#1;!S!jt8_o|nrZ zY&o*sk|d}?CP`@xKo7@%_k?^C7r#f)exOG)&+R@RVSxYhC+7ogx;d+Eqc>b4Bp|+I z9>uBbxD%zmXb++w2oz?md5ac9Ocn}hQR8WOHGD%8{Aelnl}#P*N)|~z(L&U^y@xR* z-Z9XHZ;|WU-BdI+VI zR%sPWZH<~h$cdOr?mUfUU8e%&Wu~-B(aCZ32F*mSx{X}NOrsnUU82&2F&ljFBifq9 zRrqj1Y?d54zDO}d9V~O4h1W32a+XB_u9i-e$NCnk{jq;#f~<1f0|KIk7 zFuMSk-v}b(&G}wL2Px8NO3sepg&YDlXgaCs32}b}CK~skq5)gcDL*(1*3s>lh<-5n z{uY;TijTFyjucc}e5Q99B0J(#*>Pnvg>><=HE!wMN;u3+IeK z#YvQe-Y0)UoIvj1X2)Sfw7zm<5r`|PrUUS-Ka9^3XKRv)+p2Wx9=<_PIXLCRb`|)g zWb!YE+cUxO$AC-dG`i@A9s1cZA^xsE2S?Dv)P}EpP{4PN5Au78E8g+REGEoCR;Z?NIV)Xa3JU(OkoRje~~#0C@Z${D=jK zV??zZa(->bJ7%b%a;wvS2XDb~%(Ppjm}OjSqFOE`_D`9;GH~|lXtYGDOt1YKBSCVv zo;EF2e!jNH#p0=|_v?H-X`1+wk-BsUn56=3nSW4aXS(vr`Li7EZShyjwy-bROuL;? zR|M#02FITt`AOWQEPCFVZxH*~HF#}qH&%sdi2Rxgp(@R_LA6YzXV zoz#+%g`iEMdM)pMeido|qa>s)$3G~&RadPxY_tdov%2#jEyh|ZLb_(Y{9K}Y2ZRdZ zaw}d2uNo=pcPYlAgtbLEp@I9jjQRJ)b|zU@}6tiPrd)(|YTRb;Qy8?TJ@8FJ583)uZ_hBr z(+l4IAB%st&qrQW$As6iQ>oM9t4KazHYmU6h9pF(d*)8vr-@m=1XdA1=%;Xlde;NT zYI+9K!)&N{|o zO>{1^ts%5)>h=2fqgoR3RLJA%L zH5)a&k$?kIeNNTcd1+l!WIZ7|fXBu1%A7)|D>-u?G5>075EZcfvg_~@Hz^ZN7q>vJ zaXt*G!7y1tQY%Nuo8#sCE_;Lodw!9v$+l70Cp@c*lE*U{IB9jKy2>AvMntv{WZ&+& zS-{S^K&Y)YdK-sB2yNy2AZn9rCp{NMtoexnx z)3Ah>Bp_9^$5ncncSS8np*XT(IQlvm{-}^=bk%>wb7kC^Dh5mqVp3fG)65&08EZ@( zw)Is$&s+4knTR!o$h>egh4xSCT044g?mg?@LGON+sZR>v1Z~85fcZAez^B$a zhog&YCzeRlt^w1$J$2}ZtCxF1T+esx>wmt2+yIwv15wFlHnT=}lv7?PTvCd%CJxc3 z@21?&oKhyjPcuQ3nb`ta4u`u^@e49h`x{zYeG(p{iy$*hLZ~OlQ?(?N!+RJ9Xgt1s3x64U$y&%z@RMBnc@Q%$29Av z2kFmAYs{w20OW?mjGvdmY`Yn;T!zZKhj2rtQP$woW8X2Na z0&7UP{do|aA&?%d+DjmO&^NI5>HZuWaUuXyh1VIAj;7BcigO160z0y~Pb>8`0>3|M zx~cLoab_2s0sf&*;)+6F0>sAc^9oOX-2J_QjWJ$tB9(EC8)C6|Yu9DT!N~WLZf8a` zMzhB6Ls%sqpzQw(OSqM~60XH=j@3~J4A;csyb~d-BD?C?k>y`VQ1JiMF^ubh^D_^a zMGpu6{lDzXH8C#7W6ssYxr=dzuvmI~T}aF;ZT7S_7uNY+G*~}5L+RGA{9OI!pAO0Q zE(dWnvg<}eAH^&dNpr}}qaXCvQ~m0^;71R4vUb3P@iW!cNiqZnzfzq(@gn154Sh@J zJwWD7r>y-FOjAlM3ZLAa?WjF5Sqa8~%Aq^KLk@~+R5W#R#__k~;<6=~OG*n6L2B!6 z0fMt!Ab_S>qq!kiSDL7uxgALGILBB$MX$gGUSm~Ul&_>R#%-@hb94V zI^&Xg74SbtTDlEa$d+@f;)Mfn{l<<1dWwxXjL40((rqGKU&{xHi(Bm82#}PE18F2e zA>|)*sb?tL^eZtXWeR1ij%j(1f$Un1q6`!`D)Mbu8>NvIpHfQh;E(sO3SDvCO8+kl z5Wg$8-Qxm%tK`QdG2?k6!Xqs&WPobQ%YQd1E|q@2(euX9_FccvyaqA(H}k~oH(?e# zem9;1q3hrJ_y2t3slLf)p3lB;vefTPL>j~>s9=zHV3~hL0M1BxnTfSdd#>>ySOl*k z%A}$LK`TeAstiknXxn4%t*=%>U=jjYs1 zz10ukW}nRu(`Mx=mtcb8u#EJeb31_VcbNIvZAfn$*_#Or4(2CU<>eYYjOFI+y{W#E zHzGRi?tM1>Nf2i|D!!b7chBXbi>>B(^e{tR_QwKpBm}w_1I@9k`#UTzH)a31X@(?) z*0t9=_nGj1(+H9^G6XFk{Ie$6A3YSr)`SdYF;ScrcnW?9fnBXFA6N@x);kLx;Pv{K z|DHNFsU`L=jU44h`D-OG5sMf`xZQYD9oGK(mlm<pmY$3~{G9{*HRkdX*YHIW(gO~cnZrGY&C>Kw~ z1%FXQ`Xng5$+{z~$Hrpeeh6{H9~_ljW__%9I7{<+Hc?I*Z`yntoXi&wWkT%G(}1MM zt^d>OMP>?YyIlyUd#MjJ``eMA``xK);nSEK>U-`TwlCD79#(_KL06_srf-Bo+=|I~ zLM-cJ`iGq@`anj{?nb&46mTgaFJ=8sJA+SnC82?x#C8K_b{fCPOOJ(_+j^roA363K z)dHVz=vb{oDxRibd*FLnl{waNd<)p7&%8An7^?Ll4t+1uO<=R+y<|(6E5D7ra<7k1DxuBw0YqIOtfo(Kf1k=VyqnLXgCCow#qW|iV z4-e>NewvG#x6T|}JRHw67yb1i z;d6zcAiT%m_$^SRpa3I>2D2z0UtU85g}ZY6R9^1V_Hw_u7}4w8JNLYl4XKV|;=bY_ z2kxiMLPx3+R(Zw)vZw=&4_kpzB7Rd2%p*|5@fX`y!jiy+RRtIv%un&kIu7rshg7U5 zSmiK47XH>LsE7&<2o*GO)W6t;#4`8cJD?}M&Ure>z_wUcz4O_9sQ~bui-rah& zb&X=lOjBY#z1)Mhqq@2tqfP>0L>I!6cU7`>b5tQ!W4ke)JDp+U(c_vd+m%Gt5Y>aB z5ptqyHePGCWzv~2d3Nb?+T%S}QE#3Yer!;=|NJg0kbLsI$%8q{YsE@dXqz}~M-m)L zVQya2DpKWtaMIU;SS9lx8;q+vqaLw;BYvP@m(t5stXyv-}li>!d_6 z`5skGgEw^mVB?I9Gf9}NJW7hZlYwLEjQ<6LkB&(z#Gf@!D{q>sc~;;3VQVPqAQUq2Lt7| zoaPD`q(tB@$(7>ZU{rGc_3jfq|EUFifnd90CL%=Mt7xsLE_T{@Oc|40K{@$XcWX|X zd0$DhZFzFE+Am38J`z@l;bP<}Y?>dtAd7jIHigj!mTL3H&bAJTym1)iht`m<#^qft zXX68X=3QeV6lB5(SoEpGh42=Bwfw0A`BzQx2+N_Rx|$%%G60fwL!BGx<}&lV{FcIt zSZbh5y11(fI!8Na8o!dUbc8TxNe5Es*}$|so549a?z7n{-OKR^rNQR|N z9dX%yO2a$0uj)>L!Cm=RX5NJjH z-h{@ZC1D%$;u_H1(kV{O4IEX&x7wNL+=lLQfa03`pNiuVqrOjm|(XB8;GiRQ=PT+2hhQ<@K`NI`m=IM*X|{;B&#r< z@ch$GbsKjA0CNEi6;YRi&Cj0qa90mUQetB?@P~7zULDaWCNL(=J1NpqHCI-~ugG+Q zEPT8TEFp0ok738m2lSi&^Gy-IxW$qu@3~zyDh0v-qOI%FEQk@Hp){>lT;RjRf+pm= zJdFzsIPLz%l9EV%l}7rL1a{bHFWst^V))6yp2F%c2(ws5fJ3U+je<@-K6?)Ev6Vth za|F#gi&Vdw)b82@Kv7kODHRCRV8{Ih)D*Zb3=i8PWr~>( zFtzckgK+6nBB*EdSik4cbfefwKSf z-AWL_!AfY}FTN>yQbW+U82!)93NWw4tNtQ!BUh-WDNPUheRTliw<{*sH*M*F^Rm@_ zmsMAIs)S6to`K{Em3tj#(I5&VR5||(GCaw{E7e$n|MMI@#HY%5`=1u^$d&c!bcMS` zlTgZ?(V%*^U5&=d`LIjC9$YD2k0_Z!cLUv7dSfZeS3Fxl%2l?qp<$iuV1~Df>fjB! zgcaeqPd3dhGxfAnDZS3@n?R50MPkwa9^qS4_wHYpoD{KSA}2WoDr>DtQh2FKRv~k+ zPgwU0L^9_H=I$_2*}IJ%Q;>CJQv;eY@8Z1sfp_g)=5n7w@mC=wZG5oIHKjL8Fn_}s z;6Rjm2-hE*S~uObf5=HtA5_I34M6pVY2!<^2T^k_zy2vUUy z2F7@L*Yvz1XbzRy{a43r@1P9k;!s5~ad#1asrmqWJ(AjU^cYt!ef$%q@xD_}l$M<7 zfA<;E@tn$l&Ru-M>+MBi9h23P7FqnX>!G*?sVhgovMGB#elj;aS7f zpgN|CO;#ITP)f!!;T%o={sMDzad zh7k`?&;mX(S&lM`iaFRmX;F-Mgwk1s#Xse=ziKk5(fl_eF<+Nb|E;JC()A4Nu+-&s zNE+I~Q^6M$z!2k7IuHpMY_}@3xNUV0x3utEm(#}NuR+2R?5{k;+`b9EdVavK2*}~R zjrAw6p>%%PmyRvSVe5vwq51D_`0n}l0c~4`V{`MDTpqUDi8zq%jy{6U3{mUQ(e<84jMC1&K^ij(`CHCJ*j|ckzG?>i)LP z<1Q~Zy9zRJO}jbfH^RC0-7Y;6eB=PwoN#o#bIA{7PHtG};We7$g=Q^#GJ_lb9kT5O zZ^dgly>YaPG@OvT9aK8sZd_YCaUdWbcX7eGB~{*9dwW2kJnluHtkbt4&grsMeLw`!clLJE%d1pD$^!X-zKCxf{eo{xB1rBlwF4m9L zPP1c3LnKa7k%9d3`_q+Ah*)pmc8<^|fxyE)ysBd{PA6J7VQ^h`)52jv9>^!lJKOvs zeb56wldfYTZC%q$bHs1TqwM>UwP8oWWlD-19p1MXn)qlErsk@A!9K)sQJD5 z=Z+3R%Hep%HyO9fi(ZKrwJV~7wf__{2I>3`g>CFESyj*IbU>ceTs-Sp7lrrS*r_K8 zVkb0E)^KQwyzk}04Z`4qD06J3S`J$h)xO%UG^|QP1=|6wY&nUKxxI6=5dlHAupGmb zxP$6M{%|@+(m64>GQd1AD_C*-Nm?#fYZsTLi6-uQy-rlVO=`Mi+bqE^H8DJB6#J6} zx))d6krrg{^Dly*N(=&=RrEN$dKTm9hCt^#c6mC#(HSmtz<5zRD8P&0=Oiv@#!B>X zM)dAshvQ276e@W=9o_DPeT)nnbDo;LQBC!2$_aU~4?H1JxU=PKXto8%@;wi)xu|Ba zim-@kQlt(IQ?l30v~~Aqi6`Nw%#(48KDMTQq3*1&d74DI=q_wTAK5jxhJjQbeYY;U ze2HMl52jfFjYY4#BQ_Tm^zv?3Jo;FBW0RJTRqWC%M}=1t-goY) z&{$6I-*+@5`+F&r35Bi86k#QeptNkW!f%RxaAVpf!WU#b2d(fgImub^lC2+|`YUr6 zv*o|*!*fYZ-+teFv^68sPQ0z(yDhdn)nt0Ub;+Fg1qKbnQiNS39n%RD-khA49cY$K zu+q*0Qirc3c2y#bv>8RGW^G$#;0(hP3}({Uwr&MtT=J7 zAUIas#J4O!ml8V6Xpg%C!@L-5)Aadei_!0!UW$))bvt5)rv42BDg%Kt^kY_NyBSNU zU3C2|SU=)WNagh-nUNA7{+ZT}_gM@~!%}PX4CbPN*RG@28C8j!y7Hx~XWu7WO>r20 zxCw#i$Nr~2dy36~*^>{7EN}~FTCUVBZ#xb;KVcf%bk#b)FeoPDm!GL>`DVmpX3PXz)WH@wW6s-3i%AtCFMtVKtlnL5dW zz(n(`XFVGF_|ZiEg!V9YXIjXLL)Ofp;#iz@LsN%?n!Zh77Gyv=Y(#r?@oy3%&UAO} z&b4@49;P_!HZFGxkJAspD%hW=HDvei{Et0B=isIz1-^3>o(gD^!|PwAp+An%tmiWX0oGOo*5mb6FJnWWXv^Qq>gcKY{z&%@EWpV-t)rN6tjdB)w z_ZiB{3Ru|HB77E&$q7ZE^w!2KW^(%@lAP%{UboDNAbtoqf*+d{`v6Kja5>+M<;rU^ zaRLm!vVcUMo?-b$qph^vdw2|!n6)GK6bV+G&S%?Z<)^MGRKuhF6uDe0G>uym%PtiA zH{Nt=TlPgtCRqTWZm4h>|=yCCw@^dYXF?9LNsgm`OhWiRt9} zQ?s6wN6pOR$pg!~W%p~(1Uc&!JfV!DA|4z8-yi@vDi@T z;eu$Kb7=GpMkDAkEZG=qns+MNsyJ=_!kuq5io_!R9h(xWR0ZXWG7DXX%JmlEE&DO5 zgx;t#y5;y+$Oe6c1%if(^@AEDLny>tji6T8(A4)F|5S;X05rvY^i4AL&4c=|Q1_iZOHS(3~ zhmYBqv!7hzBEYt`8ZVTCZju`>7Y8?Wf~ilW#+lI!c6T!ckj^rkiAaK$*WBkvfI$ZW zE|XeMZ9Xg8t~0NmvfeZR|ET-$#Gb`mhY2)QNuDkp!^pFaMn*p@*^zL}r9APII0wN- z4<%VIm=J`v+EUeHGpbZlI(Gjj7D)BX#!y3^5|*?m(HKPA8Q#g1Nm`-7`1su^4P_l` zZ@GREwA0Wmfa_Y6G?WRpI$16{bfUyt?^CTqr-yz7&g)mu2)}&x1}0N}aq}tTqw`9p z!Du=~GO4klF_q43JEd*=Ea0OjOT^m@?|?Y%`VK}pWqcGTyJt!)I1tvrEEdZ4*w9MW zcAYIa?fH#j;uv~YZCreq-9C#Kd{Uje9wh?RC#Y&NP)}Ym z6aoga2cJfQRyBu1`L+gwr?dS8V^vKM22RX4S`e_AGE7v8Pf(`)tyWZ39H8cn?J-k= z(noI1CR}iN__ZKq6$d%6oR*tw^cL1Uk5#B$|>Xpi6OI}gga?zpkCos%V47cKqOmWiuH}mI>m8<6*TOM^U zXqC?Tl}+?;Ng3^sTMyD=Xl~=c-q(Ux-3V}c<>BOZa7e!BiBP~YHF5kD7uc&@RT9%} zA!k3E7Gme=eTdThs_>L$e!+Q6tneUHQjBWK5JnuPx{JjxBp(vnrDZi}axL3VC((zg zf0V*ru0l+^nZis>$+F|~y9h_EtCT_uy@cGNM46t)y$9t`3JN!`i(c>-8?tWOrQAjq zUcrp%Pte;Ka0FON_flE9=}3dhlfTqu3grgK_)_a~i$VYw;y*?{23|Q{ZNI#kZdplE z>-%@3b+f>+WWilu6^D&UwPJaSz%hB*rcrnBTq|Y?>b1ZguB+kp4pFwb;0F7-j0Z-P zyI}+BNGq+9GZWXr?>j)X-%Bd?I%m(VadJIxWVG%bpa6II~ z?NsAK5~}l}B!&?Yszcvv`_GSqx%@iHS}-1v`ZGYnGReVf1}NwIiB)48KO4SX&kjVh zal`AeH)b<_RmHkE zNHx*gP3kP3oU^N+L=`nu_eD{)+EKrKd`jM5S}ZdLlaQ|x9t8{m)VK;xq?Z4fr&m8z z6P(B_4T-%~)U4j}L)4)99LUW&aC}m#Km%vVVT|EPuQffOA42NTJlf`Cg8u1TsgjuCk z!!YWQrDC_jB_=C-P2Wr-7ibC(RWy}5q<3-GN_E0tk=)7Zl#1>7r5i_fdPO`*_>!eO z#u8^Psi(pF;~*N9U1?KIbK0_V<{XL=CpM)+<=!I^rX+NB37Kp>8#x8FWChW2=`;Lc z06fyiliTi$dZ`4$>q6kL+bkm3tX|~+D3nG*+noO6-q!T*-1R;3;(`V0X2-s*7P1~bq!*dqchU7mkbk@1B6>eB4g+23F)+2FMrMAaDStEGG+no zgV~3aT{FyRXLnX@-kGf8F<3h z#U>}{661fEv4%-a-osD8eSYOCOo!NKFThE$j%<-+FTV!<^{}6nVRKYE+S~f_LPFs# zh@D*F#l=m%7^W~`vxh1Mmc7DaDsaL(DI*PFWfcpegEVK!#In6BZq^99`!Ex`uHtYI zevP=2a&CW;XCT~@1KgVP)epkkxE!>Ggui^kee_8p9IAu+-xO4}GCI6ZVC+Uu?4GDt z*?0m+d7Mr69y(+2GHyAJ2}ma-4g6h1a>ly4?B51I0G|Vjoo~`C9s8dX?e^khls3#z zz7}uBk8Ji%I7G_rD&EQpseQqAm(pu;ApJ{_S&T!a#k=;>L$L+;cmGOnUCYnQ9;d(Y z%aS1iSsAaGZGU)I_E%|4j(m=&H5}p+-_{a;XdG2C`(f+BBcM~NxZ5QK%xyA0zYTs~cjXw}4AxSp5o%w`%Iuk@c$}J!j1rC2Emk32FKGTW zq`pHwBUGuLqsaP7Cyak8%;e@3BL%x{OhNSyvo0^=_&&V{f%^2UnuIv!-Z!S zYd|u>(gP(c3z#PcO#3OfTtK4}aIL)|O*f_=>HZG$Mr~{*apB-F>^hQ~c9-T9d?vJb zE|~b?(`-6}9)uNp0tsxmL->m2iDOYUS7b6f zbYKZ6arlC#LtoEOt*QP-@Nr{?WSoJeqQ6w67FDjy{4!`|g!(}1rn0Jqn#i8epb;XA)yxFXU4gMZZARKC^=d?Mj6&xj+vVi_G;*qaWjT0SVJyW#fM+h zh}uoKZMZqDjKbi>GNV2!>-%%#e}CfrlThG+^~Ki>55Z?DCmN=I^P>9`pW*wX2yg~E z)I9ruph;LwLaKL32SR*6mQmG4-2Y0HMs`p0htIjxJ-@2@0(les81!?+XG!r`iL{Ip zea(4j1U-T}OgY6#F&#nBj|&*55z>elP6WiiN`dBns;rt)rYW>09p9AwA~n^kA`TUynQ%SaBI$R8yzi`PK&D2Yv2sbM7Zx5|v)D*J1{iPADT;}Rx& z_TcjGW%#|ajGelfLuRp-yS*Hqltv9LO8s+{#YBxp!1u$}^axMNO;}*t2mt;O+GOWV z^RJ2%(sD--JO1l;iHh4BYv*qiwY!K>QKO_2yFH(2m|F!^|Cxh;db_eEPI8?)D3tfW z!^=?@>;R{8BO;cOtvNx!J$pizIn<^!mhU^I*On!&M5ur-je2!I1~aqw;f_GXvxeOG zk9rpV;-`IX9K$&OzT!eD6@MjP1iYe1Q;8z?d~<%Ju#2%>P9&)W*$B{9l0lLzWm>I9 z8#nm5+!5pNp)qVzR3*FuTK)5Ce$v#l{SnZkC_Kmah_~pe_n_wCs3V(ER5N13em>)7 zdFG5MKtJKz81umqY-d=`Rb38L7xFzMfgX0v*Sf*Ifitn0vJH>duzqTW5>E$vSbqa! zLH=>7D*HZNT^Ih5nQWC842fF=UnO>Sii5}uC4~I@H|KF=Tn89HTvfxN@qpmKeK4cetlHkyzS-Lcef=Dehm;~y zyhqNVFDp|8*69CrgGC7ff+j5^E~4J11*l}z>ZBt#=GZHQN%d*12yele~N{R(t1s80M%s z7~u%xu!5nIQbmhi3|)+ZStKnfRKN~^aIx75fiNi1m9z@`)@RKY&slvi>3_(3gO<#Q za$ody%H&gE#45g!cO0=OSRE#x)eL=Nf7$Euk7TtF57Axjke_kCDYp&;hgLeJ<0~5_ z39!RHa8O>%@Bfi{uD+h%w=jc>6(au;T$NHTFo6(+$wt!l;(4~}bVw+FKRO&?>Pflm zMe|!z;}4(mFR8OBhYB(8(I7YrNk)N==&GxJ0_V2)biU|L&w}t1Zr;(@7S?nH#X&f} ztzZ)&4NP7hfto=p>6PQr+eNb>oO9Yx73rk|)Zf*JhQXu_)Sm#G&SstNOl<^(YC*(G2 z%b|^!Iypp_hC&jR5aam0+0;Vii<(;5JJ$TMcz%IuUKAS!e!r_0mm_|(yRPdnOj8?m zO0dHPjEsz2mj7P>DiPK0{C~sNVgIe%o)65NZc6K0p=Y*ukNLGlK5t$^Xz>>zspB<0 zc}%=1rlqOehlmS;J1ox`TMKzxr-~0Z<06%P%8Ux8^)Y3uR#pv}iL9m#aB}NCMYfC_W9U%f(R0ii~Fg_Xxa~tl}@hgiQhT_^o3`kDHij+tTB` zh?%|o!+?Zj&`ha+MEn<2Zm8hr(a;5+^h7X7-H1{P>*q0_u9l}(A$U1dq+{i58NWp) zOT%NL6Et7**N5p!!`BPu-^gpeS1x2XlYzjkH!evAd@2vvhZXH*-^n2Hyj0?)x*s$hMAbi?T5lg(VRKP^_L4e zC+(l^@imPJdo)^oFHG2@$7@E{w({-WW7XSC>w&;TW5@LaAp;^I2ZCToomln%YSn?g z55iGxzUe~;ffG*&ZYDSRyka$FsaOy;c>st1ttdDQ0pd}uN|3!jUSoY80c#St@k-E) z!f!@AB0#v9=KQaUtByT*n8fb)J%nG=U=3tImhS{xaX#HmIi%zlMMw5D^@2i3NNJxCeUO8m)a8f$-x{^l{a%E9s4XZwe=3Y_>fw1FDqkEZxFZ5l!`J-rvJzHD zFOJH`Agq(qn9!n-nr7(HV=pG`(VR_>H&8;Hzrvw@ctgLG8~&ZK6IDoD_wc>kG7};a z$m7L<(UF%*lq#_yQSwW+*st zQFOd7VP*o5?u=sW3dhMqL(E@qqp%qi*XEe9ZB$O2lhvX0ufptWiqDj9$<`wxv{0K9 zCuc1^#ob6|MR5az#EPa(R7NUwIg6}a?hn9l+j!B_H^YRDczV3G2)%@kY+|NI8{T&! zWJ?C})>{W8zPq zm{nHxl_L#Ec#`6b9=j%X@{*|$GR6CHay}^yIF(?-T;M7RY1I@AS-MyydA^vr>=kod zI@w9b_?zDdnRmnF+-9~xv$_+wFOyNniVoTHaEz}1-xa1}p9g(EBq&N1mm~vc`^I{8 zuFK5b#(A|m@zI;(FjUB3A>cmS3C^Q)DEmH4`Q(FOv^kY)8)mn0)b)%aV{Yhcg3_3< zM~^qgggtt^cy#RJQwgn)Zgo5k@dA{4gvNWw+SjtvG}BM8Wr6`K!lr?%42p%#fnYhO zS55)K)KFl|FsYC6Jk*#QXp5;zn)9O-n!!B@y<{#(!T|RgUSG&})-j3+GME@_LXBjl zEGUY$U)$Y}NeNi^QoN$kA&^!AbeIwq$R9Mx44A^;R6fB`U*LSA$gV5M+@m^OXc>Hh zJ)PoAMgf2|zf$0ZTip7|f#iW$%;SVOEdu9@(sIVJak#%XrgY$i&Lm9oWa4Dq>>0DP zwv}3ejR|`+E^K0^M~~k-uwMz8Md9lnl@R#=%O`|G;aE;LEQ%n=IL7pfa_h?1zZ_$~ z;J6>dxLY=B5gJ>|8^}&3v*yT9-=V_gT>`kJ4kyT4p@gV@@% z;-W$pS0(e)Tv@xUTit?Eruz({p_ctAHCOo_!d}njj{RxDcV!*=vvv6BBuyt42pUmF^AWcS9|~>3;fNV~{wl7AH$Wq2_qj5-~iq zxu)+QuR332rbjan?+mK`Ix$m^$!5z_j~|$2FWe4^H=q;9DJ+UlvSs+f9lZu zS&0m^S`?0@vDPPfJ#GXSTkxW@4LO2ZH5G|`JNb~R1%xD*61l?i!V1$fDez(xj_0iv z>N$rEiEUFB+=qcXib4>TkKp0M-co`Y4n2&)V-J#ULNq5vXUa@rcV)$PeiArKz+!@# zo*ft_OO5YoP&;BxI}TcT-yKL=Xw*hq1s^QX$)AiFnwV++r)TwUvu`E*qom8f^hUp( z>U+HWW#IazuDikj&oM(#xZ@{QMKVgyU{#dGP>VQBh9Mim567K5q*Pur)YG=$RBr`B z^!rf?V1(aXur5~R+&EbRb|{74)>f{0{BWH0ocY0gKb5Jz)umoYQW;2L!ZV$4y*-g~ zY^*#ZI=d65q5LmoLy=V+Q;m!U+q2~$P4OpE!%`~^61^=8_BonWLah<0J4&HI2x8I4 zoOPNm1`~n*z0M8d%tI!UzR5Y1YT{#dmAPtczAl_%o=}^8Sh(()h`QUu)vcshI~O+gh<>cGLB+JEu-I)#lU{=f!#YmqpnZ%zq~N2dg~Ji<274@&LJ83q zJBVhJiq$ycuGkKr^FISt>{;)egx95lhpLkn-&$BH>lVpUdgRj2Is5ktq^gQ8Pn)hi zP0TLb3bH4U+9U&wX9@#$91OHKqjRVfcp%M0nv;+lm^CJB;PZNI?QPGW+Dh1?mHrKh znIkXRcJhNUqFBYm1ocv*xctbUi9cg8yIay;LF;Ig2kci2Fz2qCPSIil?-Y=)0Gt+L2M$ITz`=-|uqPAx{E#GQ z*k0PIW^U4?l}W>rxTBh`^Sh-rHBSs7YqV0N;G=}hjd$>)-O8~wrDcS@b}o^U)b`Qp z%tM(H-Mm+kW3iqzl=~hCLP)~hn6O8W_r`=hdUV|24=CZ~t9eu<19nvh*p7UbGJz0W zLGa;K&#_eVrq+;YgjozcL8Oi}W8aI1UzG-SWr9j%Hp~zmrC$n-E&`7@lXT5%< zB9S$tM4J=gq7q8L3zJ=-Y^k!NZWN}*PdH3Fv~gTX+!f~zND=Z48ZVY;9K2jb`1}oT zl{mbK&;V{yZzWc?^kRg0pQ?S2!MJ2*mF{93x81uwxs(a#{&QZ(HR;)gFYbqi5~@*} z!F5p8bE+A;dNr(L!8G_#ZP$icV5O_MXBttUh;eR17yUVZRg0t5o`Eg9=GT2G+(;|Y z6%+w#OxWYa_NVlSKM6!z348Q-8ztNw$00ZY3pXg&dYN$)o#s%OS{ke`8R~NvpA858 zm|r)2kf%Tzlm*FLeI7fPdZr41!%F&0j&c%eem}gf#BrDe0(zygV?qs9zxcrI7R(bH zSlFakBNp;GqzJ$33t0=SrNlwbQy5Gkb3LK4@`&U?3do>i+wZ|srtzOBVjS2XFfq|a zpCr>A9b;9B0bnu11?M5R-vrT#rIt)FfHr1Nx79aX5L2uXbG4oL6hwS(5)i&;wadMI z_`u!<)E0HqK+0-(TmBTMz&XOM`LR?~=4!p!nD8$%AH9Z6%>1R%VJ1D6l@Qr+uGAUf zE-7AW*T^)k00j;5c=V4L5lrYKO*eVA#6&r5XPVoZneVL4LV6_)_qr~GoSa|bo_?j{ zNA~mdeq{bJuol`UTu#CBaa(FkE- z5tvx7Sc+Gii?vzKa-hDbw#Wy71o&XNS(V~ z@dW@vm>|Sxo2#@xqSsksXy}n{tlt_lVworWvRwUjLPNZ-H~f&TIj!>n|K(64V~^p* zP|o|rB#Qt!BaN)Rgyp8pG+x5pJb89*6DH)U-t_3v~T#JU<+EDz^ z&5Fdbz29HyuwSW(v)rz3d(O8pBa`z2yYG zB1|^hF<~tsq^R8N^$4qd7+hBkKg(%o2kZnSq}Gw~4hPkGA`6AH>7$`Y)ZJ04rf-7} zWDq4$92n1g0gn^eQ;a0Jju0Oy=H=E~Oov2>sp5-{D>EC$N?zVl6G6jb4aSUN+{^z` zPSbOkSv*^7*qE@#&yS9rXeDeiqsPClgkT5@kk@pb_;|%n{{wZ!nX494yD&+;&w&eS z^NFw*3O^2_gorROq)?_16ANy;oDmyv?N*~3(|g!~UPKWkF?=}Ka{xQ?w!?00RgoXA z6mn)&KXlcM`jL-UB&ivny9JAj!Hhm~ObGIC$C|nF>7U$2Ohji`Po!)2a{@1+ged6I zaA6Wu$ao8BorFBh)5KFN>5_rYqcif1wKJ}Fzdty z0`z*Dr&3T0H;v>a)FbH1wB@Xaa1n_Az?=}(CHgf>H-S+i~8 z-&3Mb?ygpyh@Laa;OKY-LBN|y(`FBYSh;MY&u+1_E?D?OVB}tqb45tINrRn1c-k@~ t&KncH2SjW5*O;(Jj~=arJ$n4n@gKvn?byHPcWwXx002ovPDHLkV1h|;Ge7_U literal 0 HcmV?d00001 diff --git a/autotests/data/RequestFullScreen.pdf b/autotests/data/RequestFullScreen.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fdbcf0dcd62f1a5cc56bdeec545b4a447d9abf06 GIT binary patch literal 4903 zcmeHL&yU+g6y|^svJ{CwVHC9LR#h@H{t?HPCq@DYZ{(SV?7k_>B84(nXKaea7;e8$+rMD3U(E#C|AEZ2n&w!=e z;cnz{WZP1b#+*&1#ltJ3S4X=eq7TSd0euo1HUglUJREQpSlC?z>O>l~XUgANoj z^`p=cN$onOOo&Ew(vYcY5aS9Zmk7CZ8Nv{HQH*v+e35oNKLuGo@`Rc66f=O(o4dfE z-9B^CjUl>;D5)!T1HCh6ae9gX*sMy6^s=;$(8wb^MApO`b8aXNk1;B{#GrE1<2qBQ z%8ZF?DE1jtq+3OK7crkm1Y(fL>V+Dbrf6t_3K?wx3&abBD;bf2Lt8T1gko&TR06SY z$>ipfGDQQLZ0V^DsLYm3qfp*0Swk=ROJn8-JkIX!&_Csn8^VJqN|E3Nkp6l&iI6C{ zSUX5SJ6PUfC_sjX-e^iYJKY;SDW{TUW%mo}%W-cW1VcCGJcR3$G7qRFjsPc_PR_1u zz0Xdfd5VXAcoc9!Uo7a4b2i#`Wy$qQ&ObP%%)b9+QNg`6^>9I}Gq9>)>4tkvmYW5) z*KuWO!6k&ihVyYMV!zqnFFK+k8~QS#0tee(_N|I!U0uwWdk1>Om>>CJtNO<`-&T?D zwW{xGebS$G_-+5q)0huW-yXTAcU;4(UbQ7_VJ@b#DWHlL(;!UDMXSo7-*FSxLX4{@ zQ%Uc%s!E;KbV94Pgb=b~Z(R+-34bOpW!>D5g$14^e6!*SXtw0f!hKdM@CNR%0k|uhxP#Cv zZixNNzH8wP{pTIJ=dKtto5w*$OwYwU;8XF_4AIlg=snk*MDdiRHk-`?-_3rWM2r?* zZ$0lQfq?z~D$osx3u;fNn{j3)rW3hyk;rw&p3i;HY3dilSz#b zN@Z17$0}Dd?)Lj-+fCxZ-t{m^S?KZ&zr0D#;o*P`HX$A(iR`nQW6*0Qy!%jZL ziOI2|Be{}Ir-Tx1H8fZ9L7Gx+HM~|Nn67A{tgNTxij+^V6)|>Y11v4guch%7rq@HO z=j?U6@HoI}x2fF89tSvGy$z28+D5Mfj{~fRqqkL~O}bsGQtB9ca<5nX``S~xs(lN_ bNB$v#sTaoJ3jEDlj=>cezvW6c2Uq?DTrVuW literal 0 HcmV?d00001 diff --git a/autotests/data/additionalFormActions.pdf b/autotests/data/additionalFormActions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c26379dd715ae720ffbbad63e1cc13d17f4a865d GIT binary patch literal 45857 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 literal 0 HcmV?d00001 diff --git a/autotests/data/checkbox_ro.pdf b/autotests/data/checkbox_ro.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e5d62b02d2191551432faf7dceb08858345da7ea GIT binary patch literal 41601 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 G;{6}Qe2Rhq literal 0 HcmV?d00001 diff --git a/autotests/data/contents.epub b/autotests/data/contents.epub new file mode 100644 index 0000000000000000000000000000000000000000..133a184949495b98147e2798fa4e9b862232ab61 GIT binary patch literal 3158 zcmai$2{@Gd7sp>SmSOD4zVErlE-9g@k)5$6i6)6*n8Bn`Zjr65;i`X|ZK|O}AuS?H zLKkC;Ye}+2wk|@J>%K!}Lihj9b7r1-=6OGJe&6?;?>W|HP)0TYfB`__i!LNUcQFB? z0Lt1PscLV>3P6?4*P*X~af$>77#N440I>RI4c^WN-VOua-S0xmo^f!hX8?d2@MrGt zw-YdK-WU&e6+GeOD(M-f4&4OC2GXr$i-Z<6?nr8vE9Pr7ufoWc2*p|#eokX!V`Tx~ z+`SeLYa?Fl+LBt|)-HzT&licxE5)3efSC{v=u`FQ^`{?% zb*}5g6yIa{!zuG-_8kX-hZ6e*GMre4(nf)VWl3dT`Fv z96M0o%_Tf0S#&`cuP@QDZ6^Nr&;7d{Vn4()PPKpbN8&`cwAojR6#2RdIpj{{mz7PrEyxHhQGcZl+1LWatdvl_#Bxaw-UA zAnPz^cys|bu0uJJ?_qlV%ol3>8_qNu$&+RblPejjWV!QfQwj>X&AE<@72Ez3{3S`U zgd#52Jj#P!j7)t!xl1*y4v+b}?SO49TBdPbgw9+8X^O+OGEiGaklO5E=ZQ@7Rtqwh+%OElRfBfX(IQkQ~n{(>bl9 zngbf-i1N5=n#73~$D!@gEo|sWlO3839}U8~pR&&cF`2yJ%kOzFvaSR5VHYyM#jIHg zY>x#{2fFs~$Eee(!0Ac8+Sln8mqhRs!SY{3ojtT3-@&Rg7te3h0RBm`GYtU(aBpB427C)O?MB-lCS77BWE=BM4 zQV_DhCRHQ|iKz1Lydpa$=4@P3Hl(%E!xZ2_;d=<5RH4G(PGtWcyh1w5Y(e(P|CFC@ z_rg(=qqnI|y3tGB^8l~mXzXLjrOZsOeIc`?ET#sttJOD0qaTz8c=_b#TrbaZs(Xi! zfF!hU7w^^*V)RxE*+XV&hUFgA9XvcsQA}U5@*k;8y6ydigV;TIcMbW%_R)LoihnG;$$07U!GmKV!Pl<1{HV2tJ$y*3 znyI1w?h3Sw_xO!#;u3<8x7|}Sp(AkGN!G?6nOyhN_+tf6Vu7;ThcK};S{s4SVz)fS zx)_*(8AAv8%ZLY{5Q|{&(<5kphr#-~`>T+?`CU&OtMwLx&?3HstwN12Voo1bleEu^ znA}(>`LuW*P%n88E6JV@IGY~?G55;OKK1$#vnqR!L#(zYTKHzvysb#R z{P3;p7KM-@dB({c6L%%n38}X7zbHbOL$I419gBUpqlT`Ijw`QxNUbOvL?()u%e3$J z`NFiW-;gL;50AO83~mDeEnwi`eXu_6#2|wEY7tx%IBP~ewyDW51Og80h9P3{zN)mM z`RxprurBE=xK*U$0x%jNQ3nihFn&B0Hw+GY+~3{xI3DlqgYowcP$80tW|noe=1Qh< zRw@W3)B4{osT!MG#aX?fQX4Fk-?ZIB=RC@5(gUxH?X{q_W5lkVp>~?HaNx_>Q@WV8VWQbpfJ?nJL;$P2&B^1qyM08o~QIw2XL~i zCb(g`{{L(@&nJ4W3%Jm&atRo^X$4Yg)9OF6-R!{h)MiFH>JL8#sjGhcvlr7VyV-Q; zsoKonsOuI4B54-1Wum|8{x#&@Z4 literal 0 HcmV?d00001 diff --git a/autotests/data/file1-docdata.xml b/autotests/data/file1-docdata.xml new file mode 100644 index 0000000..0904d74 --- /dev/null +++ b/autotests/data/file1-docdata.xml @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autotests/data/file1.pdf b/autotests/data/file1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7623feda88cb654d0094769cb2f1aafb1a58ab5a GIT binary patch literal 15605 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 E5A@N)3;+NC literal 0 HcmV?d00001 diff --git a/autotests/data/file1.pdf.gz b/autotests/data/file1.pdf.gz new file mode 100644 index 0000000000000000000000000000000000000000..8ca6d6addae81b2def37d5ab7c8cde1fd9c46041 GIT binary patch literal 15351 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 VD-0>AsJs}={{T5VGz9fL002<3BzOP- literal 0 HcmV?d00001 diff --git a/autotests/data/file2.pdf b/autotests/data/file2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6cfdbf5a3b0d814da755aafc88fef31468376337 GIT binary patch literal 188546 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 literal 0 HcmV?d00001 diff --git a/autotests/data/imageSizes.md b/autotests/data/imageSizes.md new file mode 100644 index 0000000..abda7fa --- /dev/null +++ b/autotests/data/imageSizes.md @@ -0,0 +1,77 @@ +# Test for specifying image sizes in markdown + +(c) + +## small image + +* no explicit size: + +![potato](potato.jpg) + +* only width specified `=100x`: + +![potato](potato.jpg =100x) + +* only height specified `=x100`: + +![potato](potato.jpg =x100) + +* both specified `=100x100`: + +![potato](potato.jpg =100x100) + +* only width, using html `4200x`: + +potato + +* both specified, using html `4200x4200`: + +potato + +## wide image + +* no explicit size: + +![1500x300](1500x300.png) + +* only width specified `=100x`: + +![1500x300](1500x300.png =100x) + +* only height specified `=x100`: + +![1500x300](1500x300.png =x100) + +* both specified `=100x100`: + +![1500x300](1500x300.png =100x100) + +* only height specified, using html `x4200`: + +1500x300 + +* both specified, using html `4200x4200`: + +1500x300 + +## tall image + +* no explicit size: + +![300x1500](300x1500.png) + +* only width specified `=100x`: + +![300x1500](300x1500.png =100x) + +* only height specified `=x100`: + +![300x1500](300x1500.png =x100) + +* both specified `=100x100`: + +![300x1500](300x1500.png =100x100) + +* both specified, using html `4200x4200`: + +300x1500 diff --git a/autotests/data/kjsfunctionstest.pdf b/autotests/data/kjsfunctionstest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c580283a6eba847a7c5dd9331a4e2ef2f5fb821d GIT binary patch literal 83477 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�iBl9hkMtYZ}` zI`hg6Kf&DX4aYV2Uf=Wj$9weI!o{`nB&dTlwYE;US(9NR*u0aoqltmdH-`UrBOXGQ z7Bz7~MyS|1qGW4?jUK|Ps;MTcp~fU4C#C@f+)muuz|0B4f%*n2XXPBIB5{tL2e>vs z%npL#vLlohCnH485(oH+h=IMN2_i-X!7ULtL0mWoX9Gu4&IZ;NMnbk`)+UIHz>jL9 z280?Q!tefq0|t^_M9d8w5n?($D+q2eF>^GqHnwm=gpPm+Qv~7S7U1VlR2tLwE)8Id z`lbtgW#)+HQ3pUR<>uKt_<@&mg1Xf|&C9*GRV*kQhO&FRE{QyPkT-K<)i(mCywOJ1I8 zJ9AF$H1qSTU#dn{ovP+L^(LkbE?pk2>L6_p#pb|mJFM|wfZ(tobDm0ZX=yx~qbU7# zO()Tg!yQSo%A;h>7~=K*&1`p09Aniyp)vMc34N9Za-dwzvx^q{{-_9g^VB8(HXf&2@Dp5-6=10|=9!JPJWa(962Lu>P#LgUX z5D|NgHrgCZL*&a|k#SU~DX;EG)Z>%j zKNIl(WIh)k>3QVowL1`AQJlN~vTz+= z)8$dv`i%!$x9_H6su$9Hd_^%&qOa>d>=9MZowYz~DW)NJCBaobp6@?T%RsK8ThQ#P;&O0o* zeJWS=08^5MF}Eap#7I+#iHV^v<%wuo+39kM8D zzW&^EZuJ)bshz04O->7Xrg@fFPH*%tg(_Ww94^xn6W5x`6NjU3-V`5Kif>$4Z(W~a zTmL-ts_zwtQh-Iz1g*ozOSP5XH$)SQ;6`A{{*#N=l)chvpG^Y^u4ef*m$E=3<) zdyA~J7K z+LF=~6|y>MX8C?HjZj_Ru2KfI43E>Wl+Tv8<-?Yu9~swWmS4;3eJ?W4gdJN-wG<|x zZe;e%VP3vR=e^jSr;}rzcTF;{&D*3-CK+#=mL$_`J>Ywy`o_rT0&M6mQ&qp^ykt;Q zKVRfwJG+?Yjgl=YUejy6R!j#IRikG~R0*u^9;_>@7);zKz0+DCF`ih?ZE;09sm*b0 znj_b52r{OKeb%Od@IvY2S+z{b1H+>Ax%YAh-Cpw9)Jz!7dyD6v*z`#W^7dLP zmu8XB+`F$QHxoN&`mSPJ2+e~!CBrfCy?uD&v$R5O=&$hVtd13-9>I) zH%#Dmp{kbLlO~sAEGOkCTqW5^2H$?5$km$bu6yHk(z@qVeNF1^>bvKil50I)R!Vy^ zdf3QQzoS~{+U6%AN?6(^4UXfl(4i#ZHf(Y||9EgE_mMA#7I7AZpP&quj+O+4Qpc0P zo=eFCJYOi6UwWhp^;ONwTb@oV$)9x#t~{j~Kdb_)$fL8PIw3#sfL7W~ca_~#N$ypa zkY+A>iuQ@8B6OuLa5LN7*FMtcJqkQKVO?7mV;f?f!961I@^gw+YY}r&Z?ApaL6gxP zdGmJ`3L;XzV=X9e(?7FNX%!7c6>-2q<)i@b*@uI&0saY+w?NoBLfJ%QbndcGI1k{o z-}on-8}=Osg(5C~&q2>Y!3h)(q_v4)Gd(0B3 z!Eg?63ltyyo^`TALE7yvu+F$4>V}Ak^K(j}=ZZMau$!{k#*>*+*Ri$bisnO?#(RnjYy~6)&X{JKjgHX!g#z-Dz+q#jNtBXD{HKg(Djk zBaeAFwyP`bkqk5OR>saj=-V7@IOsh*UI-4eh{{V>s9{o(c@k{;iq9 zkl;v6${A<>l8Qk5C_#85E{269HwAtNgz?}f3=9bNYin|g<29*=G*UXa4qfh zO2!%CrnM)FTT{%Gfz6ph;b_&AMpz0O%(yfx9{e#l7?dIyM*^`I(W1_x!$sJWD4R$H z$D16gQ=0-<_30_D9B4If;aMBmK@T%oynf@RQHQ^=@Hs0RbZw@giJd!{j+)F-&ow=0 zk23kzZ%5T~ADO(YQkEMm^@j9BoT5WH8*bu|gGevgRs398hiBTW6>1FG^L*hf-m?^z zd>XTl>|svvv$-E~eb+KrzF5mmrl@U-I-56V&Dq^CkPwHR%6F;Eh8^0Bj>2Dp&UbHX zE*P%xV^4Q-_A4d%LW)jW6)(JT$%uaV_QZN3w$f(-1C!4I8cbHK-gG{8-a0dMco;Do zSsgDhTihMWJU#Qn%lPRS>Gjf^jW302*7WE!s+J|Jd>q}JHO9A$sKT=7*9coSef#CY z;&@Mwbkzl07RMuK=*FaMj6+3&p5;t*UOh7z_i(6QkF`sEgzFqQX>Dlb5|Q})=!<4I zg|&_QSDMDEE8h65=QefgOc!Lf=@ZjdMPMAiFf`p=mVLXQ+u4y;>0E>pzs1P&bHl~h zj6FhE2Z!-*1P~P9l+1pJuRMQU@e}?@-mYgf6X%UL&Ql*R9_!Gb#S`j37p6$v~kSqdL%Q&`FC>ODUz=s%&tUyS*K_q9CZ}3jK&(!1<88BDb>C5E1P&y4Z8zN}w^0bh;iW8+NeASEiptoEnV(FbZY z+chxmE1nlDeBU!iM|AY<%K~m^o7{JnmC%*1w$IELl~eeE>gh=QUBrDRa#Ehb)x*ik=>+ zl593hv)y7?J)se+A~yEq@F3y2HfIt&2WRcd{LyoFFXeS><+{{dC_QoEy7ob@>x&;4 z&XTx4r_0sU;u^=|cWjg%_l{06Z?`sk)$q#j<4dYe*6H*`wIL|elaTGZyton9c$c+u z#2%!Ov0u%Nf>y3bRo>5N9@HbVRqG!AqCN$0ydxwe(9+JBeYU~K=fi#UPSdN|ap5(w zGFvH4^AX&Z4_qnA`58%IX=#^Vy-)R?>x?_nExO!DN&cWwwK=yoj(C=5Rgo9z!{ z>obWS-itjmA`&2R0(+?Uwio#r?DDPaKK&P*+e6g`3U(T&l=32Ow7-%$>MEluxWW*9 zi3Pvs=5v7)e&$`X>`zlX#C4-N&&+M!7=B?B_;Osn!VjNWphHjj*d6MpYFMUu$F?nS zy;hrLBbJ58*b7TCtGrxrX`fR^Se_0ny#^id@zHzy=0&GY6{O>BE1m`^Gr5=M;T7B- zudd~mIaQxV!`aH26AD$qFwU$KzH+yQl&dc;TXIE)*mLq6I3cor^qoAzAA)F z5|0+6J7HR|V>04bDePYIX^$43pnno7(?V8OV6K!`#@)kdRo~6)VALq!=e3|<*1Lt~ zRoQrdOEH0KB)>Fyon4K;MUlpa&BCSqOU#nian8kBlk~DD53lE>zg@cjY3s&VUN~oG z`IF#=%D0XAu5Sy=Z@$Ys&9ZYstjxSCm|msgpb4MRh2fud$H8*}TI$YF%~1+HO0mC~qXX z>8bC_6DlfvGP6V8(p_!qcQI~hyszgh+Z5I+8;bINU8wO^P8#5n03A#(A_Gi}pNL!#AX?p6EmMV8|-Z6jc$Tr}w>uTnDknyB4#^qG}d(JNHCxSPg zZF)R+5U@07n_{k zn#{0Dff`lH;Gu zAu{qB%4!I6h|)h=LjcYRN}L1fKoA}{$oc<0aqg=@1P+W8{~*j6e=o?P#I_#=xm`~U zvTu7P5FY4vf*d=HeSbj?5mxlmf}96m+?V4GA_=dB@foN30@-?RJUH=&!nmcX$RPaS z9ZfQr>wx7^hN1X#in)!R4KZi5qYFanW6l*$NvD5!Z+LQ2drcSJGx}%NkIGUJ8J2*JFB&yMam~SbosKjDsG-=R|@!dR3iyj0DV=Cm7 zVK{~ZWFI|hhN5Z)T=S!q2P8Gz2-(qk;?`)Du)7x^hr)!8p^0z|VAR4qFLiKN-wJsi zFo~uqNEM9HTBWjvW|~GQxrn7}!b5~pO%iqzgC&hOq59C5ammP0am=`92I`@Gt8uK7 ziv~#t(hkQSMXSkRiuT7t(-Gp5Pa=wTAZ@f?++q9dKNycol|8nxiF^K`AtKnwG5CyC4@zC&VX(Bx>-F}TU?0*M$72;rc~*kf&>cchMy z(aAt!$j_h|(Vz4`5na1(k{(Xm|5%9alX^zbr6YE@M$nOK8GL9?H5&mJ{3$VxFl5pQ zlKT_g52C@vQbiNrlxVfbSVH#^dO?^`4GHJnrh;8R;}uoy*Ii9s8@YBT2Nw+wQ);C8 z+1bK$p=H7tgR;bEBbEI8`~%IQ`6qYo)F?=vjuPD7xJhpHh5D%hxeT_D-;o*~$+L#t zh3>VpwRI<0fTfI75u1^aDdV7zL8^bYoOyJ2_7Doy#dS{ep+So2N%ebFgvt`ds>8LRC%6+yOVJ;{*nfnEgNNK?WXtcmC+s#10Uy~Or)h7#uy=?kd+VW*ba9Wn7Qw$7#MJ zxv}njvb)P=GFj(Mx7ov3_?+}zyQnvxA6>rUdV@w`=uI|O(QD!2H0lH?LE%r&brQx_ z6?{tXtu11};1fJ@#le9Pejc+2VFanF18e0@w(8>4!+sn*F@cZCpZFJfbUli_+QPv{ zjjeBDVczZYp6<-Zgj3Fp_0qc9P`jUGM zlFlEf3!WYzER8MG^s{)c1WS&fvdfQ_$kgg>eI0wX;G)diw^nrx*eS-30{vW>HR$I! z!s{~n#}7~8sX-ofKpm|mi?0s_(rNjL=gCQFTpiE9XK(!KlgUha=B9}N$u#L?h^pPt zqs{2-3#Z<7ABm26ef<69Wy`zzlaZ||Ege_hF6A*Ms}oKQX)Gp5JdbPk<<$%D+satX zOv;fh>)B2cJ=>$)Hn%v*H3NQc?C8{q2PFAFsAr zm6y+O_e>I>FMo7?G_CoK`RPaKPcHFYD7@ zTfkLL-O0rE`uRORePTDCMTR$?u9<$R()2=yJG|mXB|YTB;?GMkC&e~-Z#58cG_Nkz z@w(*k@q}Q?#(u(@j>kW7OrXH)Q{?mGn$d#3MvXV{?kRF61y-u~J&H=7DHZNa*e+Wp z%N4s7ZWDK)p11#ml)`NCn@39Lk1@KFGew;lPQ!{+xTfeaUw-5a_JzV|D17wQvO+|} z_)8kn;vi0W#fu23~!YEWu)_tupMNU#wRpE6NJG**oXlAqXDedV76?y7_Fo zAGN4yedTav8bgvEbUH;=L&qSVEk;*eo zyqXW5B3SD!o?3||bnCGaj}Dgd7Zd4rz0os&)JSXNfm>7c8oNuSi1%c=c1AT*AjGvz zrOsmPY2Hht;^~XEoELB#Y;Yeu9eHHnIT)GlPA{k`zE@}e^HQ|D-V|9<{mbi8obESYs}whKUMu%9 z@U$iD?~%ogxIU%k@}Au+xuTstoh8_B&E8bYndET;-8Gz*z&m>M=2f$7as0&8RFlz%YAyYn__{PtzuEc_2#sqp|04wN?D`{@ZgIlEKFGc#LF+liqMlXDGKF zq#V*WBm7kIF>lQ=U1g-Kp}KilS6!Os!Y92_Ql*s_FCiTm9lmYjl6PNZLgdcIH(qae zJRv;$aRgfV@#vv$wAJ<*HY;bc^;Gn}6^#SNA0khTUkKxL47j*7?=kwM&(2c(6eYFz zkY=sk&A9PcH5TmkJ5PyJm(ve^UWmu?v^u}(e30c;{U|@Tn#~AV_ftikh1yS8sSA-J z@~6hHSvsxB-n^VzaFP9yLH&EFd=*`-ZZn6E@jgejqU%JBeVxd%r+4i#-=TNbxq?UD_ebbT^UXEH*)12BCi49YQOnP7JXv+fc5-~A{ zOq=MoaSo01spadc5Ad4h!oj{S;2W)edP0{isbUXWDyLr_-9R8S>S}KTC1<+WDv6 z3^(g_a!k5UuiUCSQc-z<<|fSJ)pS`@GG$?~MbfF(uqWg%a7FrWdp2dX+)j7VO-Zwk zbB9A=;Y-Y3=XR!Ezi7Iicl!eI*d>@Qkzw(%Da&k?rKt61OGL$<`>8OyaaTX3!u)@w zeFr?%-~T@$BYR|zM2Ncga<6+uMs{Y|o4B&~&W@x|2q`loO32JEB3pL0hLJ)t%le|k4jMJJYFj@i@xeWZJEG7LexdRjO@tZlu}5NiOL330M@LPMOv zUw5<@+6m%r>jUwyaYLga9^TFnKeU_kVZR6Cc2Fzy=}S~V4q(@9bG_he~&AsZJOys z6pjANL}?!GyLgREl)Zf==<7U`32ntEU8RMBp-4r%q4yzpw3J*>eR?wc&=4E^3RPYD zhb&C5@jV>Z>lrNY?9a94#wn8rOMf5?@rXT|EJtutRhZ$E95cZXoMrmwvy7cMMa$#VOr8qVbe%_w`EKC{q6b}E&j8-D~Zgc+}dSt`*l zIOzV#VEh4>pLYz1DI*nljYN*va^dZtl%r_6bn+D*f0TWwBi@tB9nos_%Lg-1Rrv=Ow>`rbjbb-Ey}*hVi1 z7JhnEh(saON-2ml-oaHE^?1p{ASK{ZkB&fq>%*51ZMzZA>bgo+ditAf^?YJ7f65M~ zHGVhd{Q=8|&A(?zD1M!LKj4l_=^NSpZmC`2u#tFq~ z=+(mWe&#(z@*Izu*PAy)d`iQtXGC zey#R4GVA^kvVAUBJ<(XKy1%cK(ep05muz`gPw+U`2BF5LB&&?~{rv1JB_}h##02S7 z&*hkHob#y4(%fFp?Qk_g&>j_F-+DVV`$VsZtU~R^_(eU*s+7fz9v80Ouo|M}>) zA@waO{L!BNiQyV0zv@&-dqurCL-nb;2_=Sz(*;Pp+>h{+1 zD%l@0X3Zppc9D5V#l@RT1%9PmZW_7ATqLxhRhgQ5xvrOW@ds^y=tfmf1~sXg)v>-B zgW&1r$;Alz zHi^$Nnrnw&Ng7RiIw%ggoHUnsnz2WszL3=TTvI@2;~HCQ@Wt%J*UswY!$!SdUOsW9 z;xE}!&VqQGaa$*)&++Xf+Rl{+q6|(_Z3LrCn-iu!ov&WLnOP!WDSo~Q#-(z8Sy@JN zE966ZE)7ATh;sjyB)sP`rClMP(TUn8ngPX^5KGY<=pZFat@sbU&vMoijRh9R;k>tL z36xB!MK0OK`|I>}CG7flg?@M=q0{lQB=+X$5%^GWip>dwfbO%lF!sxgO`B5kH4L$E z|7s~sf8o4qHD?7+DHICw4%}y5Zy$|xcI|b`G3^Pud7&S+Q9{BlmN80_oR(N*e7#D= zR~+1*lszMM;v;p>M4?@odyO`6XysON)}`s?%1sw(3Wpf+!lA^+4YpKgn3tk?t&bxiFB2yMHsj-d)?5m(bjOEKY*A;M;>`>3sKl z(leo}F7@`hMg)9|sgSTUxYcn}&zJpZwNalsCvtxhdyMSIK9RJ-DVaMD2CoBH8ZKTWVr5ne8YNd+34L`fGVd>0}@ZIqNsZHdU4!PqKJd;-K z0q(~398XlTh!G5zO|$EpO_}nIqK>ip2Q9jp=tM|pSr?!DgtvKLYJ$R(bNjQ&b4}d` zJ~i;1C7p!sS{XBk{S#V@LNJ@v?EntNq)UwywPDp)pU=7#Hp(~WW_Fu#l>cNIJcs(K zTv5;b3S~lJaVx1j$4MxjQtZtcJSILuafRo(g_Fq?O9FvE5{(K4{WhL5{&-To|Ec6m zY3t{JF2arv_4)ociZu9^OuYTd4Ij-$+{>ZXK6R0epkrBlDF?qLr#(?pOICaa-d=I{ zLdru}Ni)y2`at=nc*i+TDI+bU@U5#_7e<{u&T%U`J=5u?wV#?ee?pO*Q%ll(y2jqA zfqm`Nj8MiaLdPxbdTP$ zAMl_QQIMczi`xEtrV^sXBCbR9^Br?$cH>Oa;@H?N7DW7vrpA}+g=+-}nM@On=AqEnkU*|40Y#?$m)>2ilDv}>#^$~YY5&YK z-@?VRVal~n-D|mRnI%7w+|(EO)l6zm$+!cb+RS7qwb~}xvvogff|BiPrdjl5Qo>Pg zo5&t5)mZ&Jy-$l&UCohQb*8V}@6cV+sf!SOYs4_yMM-7f&^+X~)WTZ7u=Q;L|N8U^ zFJhBYU5>jBZ0fl({Vm$;e3y17M~}J?&54O<+1=7>epf|A*A)G#`P&awqQ?f$v=o*C zdY=fE6BgzUOulOCLn9d!%|-OThK4*K-91^#*P?Nbj4RHULe2exN!!RuvbfT^|FICS z)yb<4mGZUDJi?o|pG|L0vQ9`|js8~m$+fBS%1YoX<_Y2Pf}VtGT~1a@$vTUM$n78f zZTm;8pQ-cy&9V41w(Ea78@Z@|@#5u+zZ?s2!tj@iE@wcfD{w48BrXUlL?S?3#=kon z`A;1S5Sj7&XymYCAp=o{SU{{GXvkHFEyMxh2yueAK|BsS4hPY3hi<<7EdT^1_UC~K z(EqQF0}9mZKXn`~9~_vd548++T~;z}Pejj_M`EdI-+7sZsWU6k$Y;$UAZg=i{k8ihF&!(87@xZ9MI-~4bFnJ_l z2^&Av6M~<|y}X{_@!tuKy!|Df3(l;_lOh*?!V^zhivZu`7BV9kPddB$QQWyaJUZgF z$USY^ZdR3}*=sosv3G+DIprFCACU$VJ%|e5nLjVl>+>>ZKJt32wy!kf9b$(D9l|3O znp|>Zq0sM8YCd7nBnU!tPAyx#SrIDBkj3xk)I& z@KV|o`hquB^4KH6A3-;NmRFr1x>G5)9bmuTl^vAR8;FuvZyE)`B5i+7CsC^t=D z&N*qRG6QKQw&vyG0#fGaH@*wBwJX%YTlnvfP`I9;ZedZ}czwjw#-D4AJ%Z%Enf%*; z?X&n!-m_)bGh;jN1O)aNWVsT47kIKiWzrDa@MgN_{t_iAcKd&Ysu zXz6b}S6m2x%J4tMv!Nwb3-5(o=MW&sVm zSijeJ)2yq^e`|E9fkTtFh#tvSE46sK-$hR~OoPoRwR4(wg=XfZ0=|*cLdonv;De^?RN|Kku{ju}adytNcd7wI63#o2J?By>lN- zT7I6$%!^iOR#AyxdBXXatVAJ8R;bv~;m+McsWq6aBVdM_kX$?{_ zi{K|&`c1sf8GT-;Q6jmg`&0E`5?H zxD+Z_G1fRMQFbl!?6ukR#9oY2V#5$8{p8So?q%v%8$~eOd!O zn~?6ve7EXCTQ~zPq`De2j&~3rDWTkhpfwiYFN+Uz2aRtr8rr;T7oFJ?-rG^mfxL=i~My=RYTp z8HI_?^A4f2h*H{(U;DG&aDP0on;Rgv2mP^7s?ORs%&GXrl40g(m|K&)C0f=}Fnw}~ zPH!;K;ge5?Pai_M! z@2HV2B``jm>>fb{oONJiF{9n3v+9K|^wY!~eRXd~Yl8KmmYa~kk8b$vwpoxpiAUlv zx18so;*I0x6Sq5^biLzd7zcP4WM`@dD=0D_d0T%jcqEr7_E`JW2pxp8rtoO4;nb^j z2Fkni&xsX`housNll&jb|9p5_vZKa?Er>ha#K);I^Bq04*|N=a}*o_=4v0oV#MSmkUYcEU`Y=8RF_t?vyEN%c&$8*YX|299Ybr-?XQ z3;i<()-#9O_{s8y%BNT44gDLdziLKrE4-~3?3JNla}2q3UE8$Nag#>SDAvid_}VcE ziQq_|@wU4@kfe&^)%4Hpxy8^Q^;BOMyH9@jaTnsvZQzyQIGbgn^WpnT)|FMFROd~5 z6RxD(%Lqd^$ON15VDhIj>#EGESoyMtrD2X!w}ogT?WHxhw8#zAx&?<|ySb~diAS_P zk?2MJrynDZ`J_cvl_va{eAjrsMnCerM(wEA=kZUoAGFP?GosBq*ab`#B?sFy2k+<8 zR|ZoG%smPm?$KFSR_b=$i_mv})^0j9)EYg@EqEg=w*S@+{wQO(0~gZssl#cW8w zXr?0V^;wqH2Won1368#0j2>&89?KKF=c{%@6=KKvdr|{?Yi2$*gz`J~9yzvH<5{ur z#!rsD*o)TcYdR;~;2FNn>T74{FOPRw2odx$iCYo}6;&;pdIc>A^pj-yPyh zP4bN;J?}o`&0ul%Oo!OT_B-xEB3ElPCv%sC$@5F%cSqBSA&hU2e`PKGJ~3fpTG}>2 zXPz!g(=Ei{T*!!m$)}u_Oq)MJ;gToCSGFmBzQ$LV{umvTC0bqOiG{_b_lEwOx>EPG zxK7QR^g$OGUIZB;&H2(F(g{+Lctx%7F8{O|pB-^TbuPWo4scw!?6&^KQ<_n5s%uU% z3vR)+V|r?=0U~GAD=Ca$NlWwWEa#Ms>RU$m3o)vgzDHyi(f(^YBCYYs2_mO$v*PAr z5v$xs+H@sq<7&K{vqLf(NlNjU!_r^i>zrtDJryG9_Y!d~? zEx*n)4x-fm9@!=eP(uG>C&eB_sUP@hoMgo$EH!fb3Jel_! zNhFk1Wz2%Nwz#;YV+n`)ed~)JCl&Ffzb8Ku31^7p<<)wLxQmeea2=1C2NuahOmpQl zbNf6C?Q?n(QqrRW48(*=Ip$-X$Hd+pow=(T!5+{`v{f~kL&%_bgMDmBI=-`D%k~{IpY=)M_?MLKQHOtapw$0WT)!K_z3p#NV zeP4T>IQ(vo0KZZw$&qj#$)sw!`b&)XmsC$Yd`OY=`m!o*FrV@X^OIku2w}b?xnX&D zSv+lAmxL0UMo_PNtAuTqt>s;$Vxq{&Z+irZ4~`T_N4+2L(qSR2mHJ%D^npYS=HRBo8uT(ej3hj>Xt!q6LrD>mV@JsxiPk5!J!x^}LT&Z7=DYnN&x48VmYgRTZYCv+vbi zu@uqL^_q5Fp5n+EthqDc`G83YDU?SV6#7jA6~&QaHrT(r?W4Oe`Q>`u?FPBjz{?_X z3>5Eqp?*FY#k(^>qI7(blkK84OpC9tY1L77?Xu?wsHg-`>d5JPB?NBy(ex!5qf3qG z+o)MegWUJdT5()@M-MZX_LjV_&a^v8MYYL#o@IQ*@6y$7@e$wBwgK)f#q}>yl9m_h z+@S5suYO7=dwXSG^s#YF+0*w@NOcIARp`a<*y0WiAq^)*1Y^~31e z6;FqUtBo-&`Av3XrFShxAJ`m^Ab0G#2wg0CL`l9&QSN5 zY@SV}s{V`-GKk1wfpO8#*3wSd)pqN(CA#V4*s%CW(z&I8^ZWun4Yb}PWqqk&7L4cYUBMqIbDa?OJ29Xj@{jiilt+VkhHGZ2hL ztldT7l=yt&5lQ?NVQiy)9{i?rdfx`F$1^|4PAkl>au;m)VaCZU+dZi0n_pQzT3u^y z3@+Mqcm;t7AJaR>(!v#y2*$$NuibWo?^g7~Ba&08kR_Jag(OC^uGz;Y`G354Ry=c1 zcWz^IYO+|#@>>9{xYx|Z_wqs4dRGgNIw;>(dAc4GO*iIOF?(DxPHiXmHD}p^DbvR- zZi&6LCNG&@nYHvA=C2f2d>ca@qG3`!9`^Au19#J4Qj0j$MLln1sghVpKa)HJR7Go(?lC6CVko++cSJkmEg@QD5+Ae zrV)T@W!-NnU}>-Xel{|{)BHiFQR~-SnvWhX9f6TEZ?)W|)np3<*gB;J6kD#&h3A53B}8h*jd7P#VSlO%sX#{}`E?8{WLUQ#Mqvi9s= z9~-)N!p(WKef?s?{#+tsQil_Rzi-QatJ^%|%zL4Z=iZz{3`?yIuIJjWl~Y=Bo7I+7 zkEdN>KOLz{%CS?s7eDrglgU#vL?_SeI@=aY8po`Ihmrf-#Fnt{ z%0vp&BdPg@Vj_OlzfAN8>@NVu=Rdm4prNiVtD=4|(JTME+YBHw{J$<_1M0^A!*zx; zn0wRz6<-JD+JCd}=mR+vmo5x0fghf}|H9sZi5>h+LkDoEz$J9B$9TcQ9gX=7ZV>*V zXnhd+j#(OA2J0MKH+K)r)e0^#%vt~d9RL0TsO>y#01xQ_>C>N!3HYC(e*fCx{qMBF zif25m%&*YML&}I^_Dla!2J_{>8Sv4p_Z$U;Tfl4AzBwY-J80qW-iDpkVq#n}ct^ z)xntJPuqaC(!atW|1;ZQU#`K{2Xj&9ka6H(efoFfVDC-;f;ju%SqFPd9$TFQWVAoc zBZ~M#9T*I3um83VCgk-`>l|>#{O{DkT9#vLgVT%;83zFt*uRzeWygQvR|BZs|Lv>7 z89K1k`Ncx@r*UAyhuRJ%aN@T@zbyGLg?_R19ySjK>DnD!escB%of>3TvBhwo{(|WH z6NyjwA85FPArOPZ0g~~{Ia{6q2zYKD0s!sqpyyx#dc%GZ!g2AtfO5_Pgl`z?Kr7(d zsMh=#1Do3jhr&BGQv0t3sfA*%>} zf6$3B0OlAGW>h=?0)%KN0L(rO!0-CY7~lbzXJE=#bGAYQ3RwpSz`27)JCQ*&T+mK3 zzX)Yv*iA?HK=RLH}06N+M798-CEI?850KZeU&_?TXdE0u} za9shoDrh$@OAu4-&gF%6bH`BDiU9CU0SKsxm8T`zjo-z}8l*o1z#RduqX0w&?dy#p zz2yfdQ3p>1S>!OdhWv8pFbqO~DGUI}3B%!Hf>0PA6v_wEf%^PUNdRxOiwoKcpd4c8 zZNY2Mme)UvF~JoJCnumHzqXC7I~Vw)W~+ix=a*Jo0M8CUkOSrc{{PZX;E&TVA2+l$ z85A@C1R3<74}iM^gs2EEYp!211WFjgZH@VGIsKN2U?Rw|Wy07pOad^<9i;o`d6+Mt z)#AuNbHb5JfIcJxUof5ckPJZc zVF;)W%TTc2_5G)eUnze5`-crM+@Oc@LZQMK&`~TI95bI|$pBy>jtqqv8V;ueICj|j zL1BQb7AGD2FEUXK6e!m7FbJktGSKaD$^ZdpIC+IdFd(yspC=6eOWwcKO&AGUBX(X4 zT?m#8j`-aUe%oFIidl>uE*G%*S3faeEUa{JF$@s_c3#ktuw*b8fVIStApk4I;k*E3 z1GB6lW`WiS{DifuobhzO1iK(RRQ2yg~s)+1PDATao(hh#7j6aXd0k|8h{ zz1T7Y&Ugw#ATcEb#M*!aorygJ(f@3Q%S>f197`$`bGB8Lbhjj+&aLWM5 z$2jT0JIC&CU05x*0|R7(l@5sk-aRBkKoK}?Ll}v|%?tWDb~_LT{TxS^zw~p^i*W5MhQh4v4(TES zIv4iyL|_OENgY-?+%XZ11~@hqfuV5b8Gw$BGlzn%k26<@h#-;JZ3E0Q7{})1AhgKm!9uHYgV&V$4Cg^OVBc^#G^zyOGCKS0NZVM@b%ey@u`PsNadV97*r=4AL^ z-X#L~1UNb)FhTlH*fJ3)&KeU8O*pnk0J~u8f&g6x+g6~7 z1D*z~asi|xPM?7zaBK=kApo%tc3!aR!jXw#$O$o@-*!fT!30+(j5~IMwH}TQ!1@ZO zZV23UC+Mj-{Tu;?N$hry5Ix|=J**#aD{%A^1xCQGho~rK_Yf;D5@#)n5Ea8|rwFig z#3=(Hm*bRy1QQZ=8A#Bgab%)6>njA9_i^fr0=q_7dEo#d9ml3f45QBBx*@^%g7ZGW zG=rTEfr8@nRU`^DUaaTAfegEDfKvgGG#xG%fkNV}C&6kBXAKNwI64CvuARl8fL;Qt z4DgC@Y!6%}Y@IP(8e3;k;5K6G40<5W93={N4zS+`;D^KUQvmx7PTfQi0MQLgXVB_# z{5(;V7_RNX)+DyhNU-sZJ=THc2F@IX1l*?Op+NTk E05nXp2><{9 literal 0 HcmV?d00001 diff --git a/autotests/data/pdf_with_links.pdf b/autotests/data/pdf_with_links.pdf new file mode 100644 index 0000000000000000000000000000000000000000..77e6e5345e1c93f5488291598007e715a63241d1 GIT binary patch literal 13957 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 literal 0 HcmV?d00001 diff --git a/autotests/data/pdf_with_signature.pdf b/autotests/data/pdf_with_signature.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c8ecf2e1550d2a48f3f15388b3e4d88f3bd73232 GIT binary patch literal 74044 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 y$BbsVFr|3A>!2kn)83)0P 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 Row3mKQ_#vg^V0v{1ON?gNAdsw literal 0 HcmV?d00001 diff --git a/autotests/data/protected.pdf b/autotests/data/protected.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c331c56c31b1635e0e533c698a6d227e8759975e GIT binary patch literal 16476 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�TgOJ>V}^)h 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 aiWwIeg2T8m03Z-~27ri&j+rh4;Qs-9My56Z literal 0 HcmV?d00001 diff --git a/autotests/data/synctextest.tex b/autotests/data/synctextest.tex new file mode 100644 index 0000000..5aa10e6 --- /dev/null +++ b/autotests/data/synctextest.tex @@ -0,0 +1,104 @@ +\documentclass[a4paper,10pt]{article} +\usepackage[utf8]{inputenc} + +%opening +\title{SyncTeX Test document} + +\begin{document} + +\maketitle + +\begin{abstract} +This is a sample document to demonstrate the use of SyncTex between Kile and Okular. +The document contains junk text to generate a two page PDF so that SyncTeX behavior +can be clearly seen. +\end{abstract} + +\section{Junk Text} +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + +asdfoijwoefjamcv;nslvcmlakjsfdoijwa oejasdoiajs doj fdojasod ifjoiwjfeoaijsdf asdf +oiwejroacv asdf we werasdfo ij mklzmlkz xvc';laf3jfoaisdlj4uu asdf asdf +asdfoiwjef oi asdf. + + + +\end{document} diff --git a/autotests/data/tocreload.pdf b/autotests/data/tocreload.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9525ad86ce1f2facf3669b976fcc92d84973322f GIT binary patch literal 17245 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 DfxbAn literal 0 HcmV?d00001 diff --git a/autotests/data/visibilitytest.pdf b/autotests/data/visibilitytest.pdf new file mode 100644 index 0000000..d919c4e --- /dev/null +++ b/autotests/data/visibilitytest.pdf @@ -0,0 +1,718 @@ +%PDF-1.6 +%¿÷¢þ +1 0 obj +<< /AcroForm 5 0 R /Metadata 43 0 R /Outlines 45 0 R /Pages 49 0 R /Type /Catalog >> +endobj +2 0 obj +<< /Type /ObjStm /Length 174 /N 1 /First 4 >> +stream +3 0 +<< /CreationDate (D:20180322154616+01'00') /Creator (Adobe Acrobat Pro DC 18.11.20038) /ModDate (D:20180409153511+02'00') /Producer (Adobe Acrobat Pro DC 18.11.20038) >> +endstream +endobj +4 0 obj +<< /Type /ObjStm /Length 6347 /N 38 /First 292 >> +stream +5 0 6 216 7 303 8 541 9 629 10 1940 11 2158 12 2246 13 2394 14 2637 15 2707 16 2903 17 3151 18 3403 19 3636 20 3724 21 3957 22 4045 23 4286 24 4374 25 4615 26 4703 27 4907 28 4953 29 4998 30 5046 31 5094 32 5139 33 5170 34 5225 35 5279 36 5336 37 5390 38 5430 39 5677 40 5929 41 5975 42 6020 +<< /DA (/Helv 0 Tf 0 g ) /DR << /Encoding << /PDFDocEncoding 55 0 R >> /Font << /HeBo 52 0 R /Helv 53 0 R /ZaDb 54 0 R >> >> /Fields [ 7 0 R 10 0 R 12 0 R 13 0 R 15 0 R 18 0 R 22 0 R 20 0 R 24 0 R 51 0 R 26 0 R ] >> +[ 7 0 R 10 0 R 12 0 R 13 0 R 15 0 R 16 0 R 17 0 R 18 0 R 20 0 R 22 0 R 24 0 R 26 0 R ] +<< /AP << /N 56 0 R >> /DA (/HeBo 12 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Are widgets nicely redrawn?) /IF << >> >> /P 57 0 R /Rect [ 18.4581 675.365 251.638 777.152 ] /Subtype /Widget /T (Underlay) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /Differences [ 24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde 39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright /minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 160 /Euro 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot /.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] /Type /Encoding >> +<< /AP << /N 58 0 R >> /DA (/HeBo 12 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Button) /IF << >> >> /P 57 0 R /Rect [ 92.5797 742.96 164.58 762.96 ] /Subtype /Widget /T (TargetButton) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /DA (/Helv 12 Tf 0 g) /F 4 /FT /Tx /MK << >> /P 57 0 R /Rect [ 48.779 715.655 198.779 737.655 ] /Subtype /Widget /T (TargetText) /Type /Annot >> +<< /AP << /D << /Ja 59 0 R /Off 60 0 R >> /N << /Ja 61 0 R /Off 62 0 R >> >> /AS /Off /F 4 /FT /Btn /MK << /BC [ 0.0 ] /BG [ 1.0 ] /CA (4) >> /P 57 0 R /Rect [ 48.3801 692.924 67.577 710.924 ] /Subtype /Widget /T (TargetCheck) /Type /Annot >> +<< /BaseFont /ZapfDingbats /Name /ZaDb /Subtype /Type1 /Type /Font >> +<< /AP << /N 63 0 R >> /DA (/Helv 12 Tf 0 g) /F 4 /FT /Ch /Ff 131072 /MK << /BG [ 1.0 ] >> /P 57 0 R /Rect [ 82.6907 691.722 154.691 711.722 ] /Subtype /Widget /T (TargetDropDown) /Type /Annot >> +<< /AP << /D << /1 64 0 R /Off 65 0 R >> /N << /1 66 0 R /Off 67 0 R >> >> /AS /1 /BS << /S /I /W 1 >> /F 4 /MK << /BC [ 0.0 ] /BG [ 1.0 ] /CA (l) >> /P 57 0 R /Parent 51 0 R /Rect [ 177.244 682.95 194.845 700.95 ] /Subtype /Widget /Type /Annot >> +<< /AP << /D << /0 68 0 R /Off 69 0 R >> /N << /0 70 0 R /Off 71 0 R >> >> /AS /Off /BS << /S /I /W 1 >> /F 4 /MK << /BC [ 0.0 ] /BG [ 1.0 ] /CA (l) >> /P 57 0 R /Parent 51 0 R /Rect [ 205.547 683.373 223.547 701.373 ] /Subtype /Widget /Type /Annot >> +<< /A 27 0 R /AP << /N 72 0 R >> /DA (/HeBo 12 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Hide) /IF << >> >> /P 57 0 R /Rect [ 46.2829 649.314 118.283 669.314 ] /Subtype /Widget /T (HideActionButton) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /A 33 0 R /AP << /N 73 0 R >> /DA (/HeBo 12 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Show) /IF << >> >> /P 57 0 R /Rect [ 139.742 648.635 211.742 668.635 ] /Subtype /Widget /T (ShowActionButton) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /A 38 0 R /AP << /N 74 0 R >> /DA (/HeBo 10 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Hide with JS) /IF << >> >> /P 57 0 R /Rect [ 45.6931 620.135 117.693 640.135 ] /Subtype /Widget /T (HideScriptButton) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /A 39 0 R /AP << /N 75 0 R >> /DA (/HeBo 10 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] /CA (Show with JS) /IF << >> >> /P 57 0 R /Rect [ 139.343 621.106 211.343 641.106 ] /Subtype /Widget /T (ShowScriptButton) /Type /Annot >> +<< /BaseFont /Helvetica-Bold /Encoding 9 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /A 40 0 R /AP << /N 76 0 R >> /DA (/HeBo 12 Tf 0 g) /F 4 /FT /Btn /Ff 65536 /MK << /BG [ 0.75293 ] >> /P 57 0 R /Rect [ 91.7609 589.675 163.761 609.675 ] /Subtype /Widget /T (LoopNext) /Type /Annot >> +<< /Next 28 0 R /S /Hide /T (TargetButton) >> +<< /Next 29 0 R /S /Hide /T (TargetCheck) >> +<< /Next 30 0 R /S /Hide /T (TargetDropDown) >> +<< /Next 31 0 R /S /Hide /T (TargetDropDown) >> +<< /Next 32 0 R /S /Hide /T (TargetRadio) >> +<< /S /Hide /T (TargetText) >> +<< /H false /Next 34 0 R /S /Hide /T (TargetButton) >> +<< /H false /Next 35 0 R /S /Hide /T (TargetCheck) >> +<< /H false /Next 36 0 R /S /Hide /T (TargetDropDown) >> +<< /H false /Next 37 0 R /S /Hide /T (TargetRadio) >> +<< /H false /S /Hide /T (TargetText) >> +<< /JS (getField\("TargetButton"\).hidden = true;\r\ngetField\("TargetText"\).hidden = true;\r\ngetField\("TargetCheck"\).hidden = true;\r\ngetField\("TargetDropDown"\).hidden = true;\r\ngetField\("TargetRadio"\).hidden = true;) /S /JavaScript >> +<< /JS (getField\("TargetButton"\).hidden = false;\r\ngetField\("TargetText"\).hidden = false;\r\ngetField\("TargetCheck"\).hidden = false;\r\ngetField\("TargetDropDown"\).hidden = false;\r\ngetField\("TargetRadio"\).hidden = false;) /S /JavaScript >> +<< /Next 41 0 R /S /Hide /T (TargetButton) >> +<< /Next 41 0 R /S /Hide /T (TargetCheck) >> +<< /S /Hide /T (TargetDropDown) >> +endstream +endobj +43 0 obj +<< /Subtype /XML /Type /Metadata /Length 3189 >> +stream + + + + + 2018-04-09T15:35:11+02:00 + 2018-03-22T15:46:16+01:00 + 2018-04-09T15:35:11+02:00 + Adobe Acrobat Pro DC 18.11.20038 + application/pdf + uuid:d7a80371-6095-484e-b9d7-e859d2331a96 + uuid:486d99a8-964e-4807-b940-382f252a7e0f + Adobe Acrobat Pro DC 18.11.20038 + + + + + + + + + + + + + + + + + + + + + + + + +endstream +endobj +44 0 obj +<< /Type /ObjStm /Length 173 /N 3 /First 18 >> +stream +45 0 46 58 47 110 +<< /Count 1 /First 46 0 R /Last 46 0 R /Type /Outlines >> +<< /A 47 0 R /Parent 45 0 R /Title (Leere Seite) >> +<< /D [ 57 0 R /XYZ 0 792 null ] /S /GoTo >> +endstream +endobj +48 0 obj +<< /Type /ObjStm /Length 50 /N 1 /First 5 >> +stream +49 0 +<< /Count 1 /Kids [ 57 0 R ] /Type /Pages >> +endstream +endobj +50 0 obj +<< /Type /ObjStm /Length 1690 /N 5 /First 33 >> +stream +51 0 52 103 53 192 54 276 55 346 +<< /FT /Btn /Ff 49152 /Kids [ 17 0 R 16 0 R ] /Opt [ (Auswahl1) (Auswahl1) ] /T (TargetRadio) /V /1 >> +<< /BaseFont /Helvetica-Bold /Encoding 55 0 R /Name /HeBo /Subtype /Type1 /Type /Font >> +<< /BaseFont /Helvetica /Encoding 55 0 R /Name /Helv /Subtype /Type1 /Type /Font >> +<< /BaseFont /ZapfDingbats /Name /ZaDb /Subtype /Type1 /Type /Font >> +<< /Differences [ 24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde 39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright /minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron /Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 160 /Euro 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot /.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine 188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] /Type /Encoding >> +endstream +endobj +56 0 obj +<< /BBox [ 0.0 0.0 233.18 101.787 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 8 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 198 >> +stream +0.75293 g +0 0 233.1799 101.7869 re +f +q +1 1 231.1799 99.7869 re +W +n +0 g +BT +/HeBo 12 Tf +0 g +35.314 46.75 Td +(Are ) Tj +23.328 0 Td +(widgets ) Tj +47.952 0 Td +(nicely ) Tj +37.308 0 Td +(redrawn?) Tj +ET +Q +endstream +endobj +57 0 obj +<< /Annots 6 0 R /Contents 77 0 R /CropBox [ 0.0 0.0 612.0 792.0 ] /MediaBox [ 0.0 0.0 612.0 792.0 ] /Parent 49 0 R /Resources << >> /Rotate 0 /Type /Page >> +endobj +58 0 obj +<< /BBox [ 0.0 0.0 71.9999 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 11 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 110 >> +stream +0.75293 g +0 0 71.9999 20 re +f +q +1 1 69.9999 18 re +W +n +0 g +BT +/HeBo 12 Tf +0 g +16.692 5.857 Td +(Button) Tj +ET +Q +endstream +endobj +59 0 obj +<< /BBox [ 0.0 0.0 19.1969 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /ZaDb 14 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 147 >> +stream +0.75293 g +0 0 19.1969 18 re +f +0.5 0.5 18.1969 17 re +s +q +1 1 17.1969 16 re +W +n +0 g +BT +/ZaDb 14.532 Tf +3.4514 4.081 Td +13.9943 TL +0 0 Td +(4) Tj +ET +Q +endstream +endobj +60 0 obj +<< /BBox [ 0.0 0.0 19.1969 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 54 >> +stream +0.75293 g +0 0 19.1969 18 re +f +0.5 0.5 18.1969 17 re +s +endstream +endobj +61 0 obj +<< /BBox [ 0.0 0.0 19.1969 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /ZaDb 14 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 141 >> +stream +1 g +0 0 19.1969 18 re +f +0.5 0.5 18.1969 17 re +s +q +1 1 17.1969 16 re +W +n +0 g +BT +/ZaDb 14.532 Tf +3.4514 4.081 Td +13.9943 TL +0 0 Td +(4) Tj +ET +Q +endstream +endobj +62 0 obj +<< /BBox [ 0.0 0.0 19.1969 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 48 >> +stream +1 g +0 0 19.1969 18 re +f +0.5 0.5 18.1969 17 re +s +endstream +endobj +63 0 obj +<< /BBox [ 0.0 0.0 72.0 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 19 >> +stream +1 g +0 0 72 20 re +f +endstream +endobj +64 0 obj +<< /BBox [ 0.0 0.0 17.601 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 924 >> +stream +0.749023 -0.250977 -0.250977 rg +q +1 0 0 1 8.8005 9 cm +8.8005 0 m +8.8005 4.8606 4.8606 8.8005 0 8.8005 c +-4.8606 8.8005 -8.8005 4.8606 -8.8005 0 c +-8.8005 -4.8606 -4.8606 -8.8005 0 -8.8005 c +4.8606 -8.8005 8.8005 -4.8606 8.8005 0 c +f +Q +q +1 0 0 1 8.8005 9 cm +8.3005 0 m +8.3005 4.5844 4.5844 8.3005 0 8.3005 c +-4.5844 8.3005 -8.3005 4.5844 -8.3005 0 c +-8.3005 -4.5844 -4.5844 -8.3005 0 -8.3005 c +4.5844 -8.3005 8.3005 -4.5844 8.3005 0 c +s +Q +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +7.3005 0 m +7.3005 4.0321 4.0321 7.3005 0 7.3005 c +-4.0321 7.3005 -7.3005 4.0321 -7.3005 0 c +S +Q +1 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +-7.3005 0 m +-7.3005 -4.0321 -4.0321 -7.3005 0 -7.3005 c +4.0321 -7.3005 7.3005 -4.0321 7.3005 0 c +S +Q +0 g +q +1 0 0 1 8.8005 9 cm +3.4003 0 m +3.4003 1.878 1.878 3.4003 0 3.4003 c +-1.878 3.4003 -3.4003 1.878 -3.4003 0 c +-3.4003 -1.878 -1.878 -3.4003 0 -3.4003 c +1.878 -3.4003 3.4003 -1.878 3.4003 0 c +f +Q +endstream +endobj +65 0 obj +<< /BBox [ 0.0 0.0 17.601 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 725 >> +stream +0.749023 -0.250977 -0.250977 rg +q +1 0 0 1 8.8005 9 cm +8.8005 0 m +8.8005 4.8606 4.8606 8.8005 0 8.8005 c +-4.8606 8.8005 -8.8005 4.8606 -8.8005 0 c +-8.8005 -4.8606 -4.8606 -8.8005 0 -8.8005 c +4.8606 -8.8005 8.8005 -4.8606 8.8005 0 c +f +Q +q +1 0 0 1 8.8005 9 cm +8.3005 0 m +8.3005 4.5844 4.5844 8.3005 0 8.3005 c +-4.5844 8.3005 -8.3005 4.5844 -8.3005 0 c +-8.3005 -4.5844 -4.5844 -8.3005 0 -8.3005 c +4.5844 -8.3005 8.3005 -4.5844 8.3005 0 c +s +Q +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +7.3005 0 m +7.3005 4.0321 4.0321 7.3005 0 7.3005 c +-4.0321 7.3005 -7.3005 4.0321 -7.3005 0 c +S +Q +1 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +-7.3005 0 m +-7.3005 -4.0321 -4.0321 -7.3005 0 -7.3005 c +4.0321 -7.3005 7.3005 -4.0321 7.3005 0 c +S +Q +endstream +endobj +66 0 obj +<< /BBox [ 0.0 0.0 17.601 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 913 >> +stream +1 g +q +1 0 0 1 8.8005 9 cm +8.8005 0 m +8.8005 4.8606 4.8606 8.8005 0 8.8005 c +-4.8606 8.8005 -8.8005 4.8606 -8.8005 0 c +-8.8005 -4.8606 -4.8606 -8.8005 0 -8.8005 c +4.8606 -8.8005 8.8005 -4.8606 8.8005 0 c +f +Q +q +1 0 0 1 8.8005 9 cm +8.3005 0 m +8.3005 4.5844 4.5844 8.3005 0 8.3005 c +-4.5844 8.3005 -8.3005 4.5844 -8.3005 0 c +-8.3005 -4.5844 -4.5844 -8.3005 0 -8.3005 c +4.5844 -8.3005 8.3005 -4.5844 8.3005 0 c +s +Q +0.501953 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +7.3005 0 m +7.3005 4.0321 4.0321 7.3005 0 7.3005 c +-4.0321 7.3005 -7.3005 4.0321 -7.3005 0 c +S +Q +0.75293 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +-7.3005 0 m +-7.3005 -4.0321 -4.0321 -7.3005 0 -7.3005 c +4.0321 -7.3005 7.3005 -4.0321 7.3005 0 c +S +Q +0 g +q +1 0 0 1 8.8005 9 cm +3.4003 0 m +3.4003 1.878 1.878 3.4003 0 3.4003 c +-1.878 3.4003 -3.4003 1.878 -3.4003 0 c +-3.4003 -1.878 -1.878 -3.4003 0 -3.4003 c +1.878 -3.4003 3.4003 -1.878 3.4003 0 c +f +Q +endstream +endobj +67 0 obj +<< /BBox [ 0.0 0.0 17.601 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 714 >> +stream +1 g +q +1 0 0 1 8.8005 9 cm +8.8005 0 m +8.8005 4.8606 4.8606 8.8005 0 8.8005 c +-4.8606 8.8005 -8.8005 4.8606 -8.8005 0 c +-8.8005 -4.8606 -4.8606 -8.8005 0 -8.8005 c +4.8606 -8.8005 8.8005 -4.8606 8.8005 0 c +f +Q +q +1 0 0 1 8.8005 9 cm +8.3005 0 m +8.3005 4.5844 4.5844 8.3005 0 8.3005 c +-4.5844 8.3005 -8.3005 4.5844 -8.3005 0 c +-8.3005 -4.5844 -4.5844 -8.3005 0 -8.3005 c +4.5844 -8.3005 8.3005 -4.5844 8.3005 0 c +s +Q +0.501953 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +7.3005 0 m +7.3005 4.0321 4.0321 7.3005 0 7.3005 c +-4.0321 7.3005 -7.3005 4.0321 -7.3005 0 c +S +Q +0.75293 G +q +0.7071 0.7071 -0.7071 0.7071 8.8005 9 cm +-7.3005 0 m +-7.3005 -4.0321 -4.0321 -7.3005 0 -7.3005 c +4.0321 -7.3005 7.3005 -4.0321 7.3005 0 c +S +Q +endstream +endobj +68 0 obj +<< /BBox [ 0.0 0.0 18.0 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 722 >> +stream +0.749023 -0.250977 -0.250977 rg +q +1 0 0 1 9 9 cm +9 0 m +9 4.9708 4.9708 9 0 9 c +-4.9708 9 -9 4.9708 -9 0 c +-9 -4.9708 -4.9708 -9 0 -9 c +4.9708 -9 9 -4.9708 9 0 c +f +Q +q +1 0 0 1 9 9 cm +8.5 0 m +8.5 4.6946 4.6946 8.5 0 8.5 c +-4.6946 8.5 -8.5 4.6946 -8.5 0 c +-8.5 -4.6946 -4.6946 -8.5 0 -8.5 c +4.6946 -8.5 8.5 -4.6946 8.5 0 c +s +Q +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +7.5 0 m +7.5 4.1423 4.1423 7.5 0 7.5 c +-4.1423 7.5 -7.5 4.1423 -7.5 0 c +S +Q +1 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +-7.5 0 m +-7.5 -4.1423 -4.1423 -7.5 0 -7.5 c +4.1423 -7.5 7.5 -4.1423 7.5 0 c +S +Q +0 g +q +1 0 0 1 9 9 cm +3.5 0 m +3.5 1.9331 1.9331 3.5 0 3.5 c +-1.9331 3.5 -3.5 1.9331 -3.5 0 c +-3.5 -1.9331 -1.9331 -3.5 0 -3.5 c +1.9331 -3.5 3.5 -1.9331 3.5 0 c +f +Q +endstream +endobj +69 0 obj +<< /BBox [ 0.0 0.0 18.0 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 559 >> +stream +0.749023 -0.250977 -0.250977 rg +q +1 0 0 1 9 9 cm +9 0 m +9 4.9708 4.9708 9 0 9 c +-4.9708 9 -9 4.9708 -9 0 c +-9 -4.9708 -4.9708 -9 0 -9 c +4.9708 -9 9 -4.9708 9 0 c +f +Q +q +1 0 0 1 9 9 cm +8.5 0 m +8.5 4.6946 4.6946 8.5 0 8.5 c +-4.6946 8.5 -8.5 4.6946 -8.5 0 c +-8.5 -4.6946 -4.6946 -8.5 0 -8.5 c +4.6946 -8.5 8.5 -4.6946 8.5 0 c +s +Q +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +7.5 0 m +7.5 4.1423 4.1423 7.5 0 7.5 c +-4.1423 7.5 -7.5 4.1423 -7.5 0 c +S +Q +1 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +-7.5 0 m +-7.5 -4.1423 -4.1423 -7.5 0 -7.5 c +4.1423 -7.5 7.5 -4.1423 7.5 0 c +S +Q +endstream +endobj +70 0 obj +<< /BBox [ 0.0 0.0 18.0 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 711 >> +stream +1 g +q +1 0 0 1 9 9 cm +9 0 m +9 4.9708 4.9708 9 0 9 c +-4.9708 9 -9 4.9708 -9 0 c +-9 -4.9708 -4.9708 -9 0 -9 c +4.9708 -9 9 -4.9708 9 0 c +f +Q +q +1 0 0 1 9 9 cm +8.5 0 m +8.5 4.6946 4.6946 8.5 0 8.5 c +-4.6946 8.5 -8.5 4.6946 -8.5 0 c +-8.5 -4.6946 -4.6946 -8.5 0 -8.5 c +4.6946 -8.5 8.5 -4.6946 8.5 0 c +s +Q +0.501953 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +7.5 0 m +7.5 4.1423 4.1423 7.5 0 7.5 c +-4.1423 7.5 -7.5 4.1423 -7.5 0 c +S +Q +0.75293 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +-7.5 0 m +-7.5 -4.1423 -4.1423 -7.5 0 -7.5 c +4.1423 -7.5 7.5 -4.1423 7.5 0 c +S +Q +0 g +q +1 0 0 1 9 9 cm +3.5 0 m +3.5 1.9331 1.9331 3.5 0 3.5 c +-1.9331 3.5 -3.5 1.9331 -3.5 0 c +-3.5 -1.9331 -1.9331 -3.5 0 -3.5 c +1.9331 -3.5 3.5 -1.9331 3.5 0 c +f +Q +endstream +endobj +71 0 obj +<< /BBox [ 0.0 0.0 18.0 18.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 548 >> +stream +1 g +q +1 0 0 1 9 9 cm +9 0 m +9 4.9708 4.9708 9 0 9 c +-4.9708 9 -9 4.9708 -9 0 c +-9 -4.9708 -4.9708 -9 0 -9 c +4.9708 -9 9 -4.9708 9 0 c +f +Q +q +1 0 0 1 9 9 cm +8.5 0 m +8.5 4.6946 4.6946 8.5 0 8.5 c +-4.6946 8.5 -8.5 4.6946 -8.5 0 c +-8.5 -4.6946 -4.6946 -8.5 0 -8.5 c +4.6946 -8.5 8.5 -4.6946 8.5 0 c +s +Q +0.501953 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +7.5 0 m +7.5 4.1423 4.1423 7.5 0 7.5 c +-4.1423 7.5 -7.5 4.1423 -7.5 0 c +S +Q +0.75293 G +q +0.7071 0.7071 -0.7071 0.7071 9 9 cm +-7.5 0 m +-7.5 -4.1423 -4.1423 -7.5 0 -7.5 c +4.1423 -7.5 7.5 -4.1423 7.5 0 c +S +Q +endstream +endobj +72 0 obj +<< /BBox [ 0.0 0.0 72.0004 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 19 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 107 >> +stream +0.75293 g +0 0 72.0004 20 re +f +q +1 1 70.0004 18 re +W +n +0 g +BT +/HeBo 12 Tf +0 g +23.01 5.857 Td +(Hide) Tj +ET +Q +endstream +endobj +73 0 obj +<< /BBox [ 0.0 0.0 72.0 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 21 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 98 >> +stream +0.75293 g +0 0 72 20 re +f +q +1 1 70 18 re +W +n +0 g +BT +/HeBo 12 Tf +0 g +20.022 5.857 Td +(Show) Tj +ET +Q +endstream +endobj +74 0 obj +<< /BBox [ 0.0 0.0 72.0004 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 23 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 151 >> +stream +0.75293 g +0 0 72.0004 20 re +f +q +1 1 70.0004 18 re +W +n +0 g +BT +/HeBo 10 Tf +0 g +6.303 6.548 Td +(Hide ) Tj +24.426 0 Td +(with ) Tj +22.746 0 Td +(JS) Tj +ET +Q +endstream +endobj +75 0 obj +<< /BBox [ 0.0 0.0 72.0 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /Font << /HeBo 25 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 141 >> +stream +0.75293 g +0 0 72 20 re +f +q +1 1 70 18 re +W +n +0 g +BT +/HeBo 10 Tf +0 g +3.813 6.548 Td +(Show ) Tj +29.406 0 Td +(with ) Tj +22.746 0 Td +(JS) Tj +ET +Q +endstream +endobj +76 0 obj +<< /BBox [ 0.0 0.0 72.0 20.0 ] /FormType 1 /Matrix [ 1.0 0.0 0.0 1.0 0.0 0.0 ] /Resources << /ProcSet [ /PDF ] >> /Subtype /Form /Type /XObject /Length 25 >> +stream +0.75293 g +0 0 72 20 re +f +endstream +endobj +77 0 obj +<< /Length 0 >> +stream +endstream +endobj +78 0 obj +<< /Type /XRef /Length 316 /W [ 1 2 1 ] /Info 3 0 R /Root 1 0 R /Size 79 /ID [<3684e699f7ea7b4bba2c439dc398ed0e><94a3aadfcfc2687808f994840852e4da>] >> +stream +so  +    !"#$%Œ'S,,,(P0(Ð22222/»1d23b4×5Ï7>809=`@÷EJHÖLhOWRÞUÂWXOYÈ[4\ \= +endstream +endobj +startxref +23613 +%%EOF diff --git a/autotests/documenttest.cpp b/autotests/documenttest.cpp new file mode 100644 index 0000000..18bada7 --- /dev/null +++ b/autotests/documenttest.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2013 by Fabio D'Urso * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include + +#include + +#include "../core/annotations.h" +#include "../core/document.h" +#include "../core/document_p.h" +#include "../core/generator.h" +#include "../core/observer.h" +#include "../core/page.h" +#include "../core/rotationjob_p.h" +#include "../settings_core.h" + +class DocumentTest : public QObject +{ + Q_OBJECT + +private slots: + void testCloseDuringRotationJob(); + void testDocdataMigration(); +}; + +// Test that we don't crash if the document is closed while a RotationJob +// is enqueued/running +void DocumentTest::testCloseDuringRotationJob() +{ + Okular::SettingsCore::instance(QStringLiteral("documenttest")); + Okular::Document *m_document = new Okular::Document(nullptr); + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + + Okular::DocumentObserver *dummyDocumentObserver = new Okular::DocumentObserver(); + m_document->addObserver(dummyDocumentObserver); + + m_document->openDocument(testFile, QUrl(), mime); + m_document->setRotation(1); + + // Tell ThreadWeaver not to start any new job + ThreadWeaver::Queue::instance()->suspend(); + + // Request a pixmap. A RotationJob will be enqueued but not started + Okular::PixmapRequest *pixmapReq = new Okular::PixmapRequest(dummyDocumentObserver, 0, 100, 100, 1, Okular::PixmapRequest::NoFeature); + m_document->requestPixmaps(QLinkedList() << pixmapReq); + + // Delete the document + delete m_document; + + // Resume job processing and wait for the RotationJob to finish + ThreadWeaver::Queue::instance()->resume(); + ThreadWeaver::Queue::instance()->finish(); + qApp->processEvents(); + + delete dummyDocumentObserver; +} + +// Test that, if there's a XML file in docdata referring to a document, we +// detect that it must be migrated, that it doesn't get wiped out if you close +// the document without migrating and that it does get wiped out after migrating +void DocumentTest::testDocdataMigration() +{ + Okular::SettingsCore::instance(QStringLiteral("documenttest")); + + const QUrl testFileUrl = QUrl::fromLocalFile(KDESRCDIR "data/file1.pdf"); + const QString testFilePath = testFileUrl.toLocalFile(); + const qint64 testFileSize = QFileInfo(testFilePath).size(); + + // Copy XML file to the docdata/ directory + const QString docDataPath = Okular::DocumentPrivate::docDataFileName(testFileUrl, testFileSize); + QFile::remove(docDataPath); + QVERIFY(QFile::copy(KDESRCDIR "data/file1-docdata.xml", docDataPath)); + + // Open our document + Okular::Document *m_document = new Okular::Document(nullptr); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFilePath); + QCOMPARE(m_document->openDocument(testFilePath, testFileUrl, mime), Okular::Document::OpenSuccess); + + // Check that the annotation from file1-docdata.xml was loaded + QCOMPARE(m_document->page(0)->annotations().size(), 1); + QCOMPARE(m_document->page(0)->annotations().first()->uniqueName(), QStringLiteral("testannot")); + + // Check that we detect that it must be migrated + QVERIFY(m_document->isDocdataMigrationNeeded()); + m_document->closeDocument(); + + // Reopen the document and check that the annotation is still present + // (because we have not migrated) + QCOMPARE(m_document->openDocument(testFilePath, testFileUrl, mime), Okular::Document::OpenSuccess); + QCOMPARE(m_document->page(0)->annotations().size(), 1); + QCOMPARE(m_document->page(0)->annotations().first()->uniqueName(), QStringLiteral("testannot")); + QVERIFY(m_document->isDocdataMigrationNeeded()); + + // Do the migration + QTemporaryFile migratedSaveFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + QVERIFY(migratedSaveFile.open()); + migratedSaveFile.close(); + QVERIFY(m_document->saveChanges(migratedSaveFile.fileName())); + m_document->docdataMigrationDone(); + QVERIFY(!m_document->isDocdataMigrationNeeded()); + m_document->closeDocument(); + + // Now the docdata file should have no annotations, let's check + QCOMPARE(m_document->openDocument(testFilePath, testFileUrl, mime), Okular::Document::OpenSuccess); + QCOMPARE(m_document->page(0)->annotations().size(), 0); + QVERIFY(!m_document->isDocdataMigrationNeeded()); + m_document->closeDocument(); + + // And the new file should have 1 annotation, let's check + QCOMPARE(m_document->openDocument(migratedSaveFile.fileName(), QUrl::fromLocalFile(migratedSaveFile.fileName()), mime), Okular::Document::OpenSuccess); + QCOMPARE(m_document->page(0)->annotations().size(), 1); + QVERIFY(!m_document->isDocdataMigrationNeeded()); + m_document->closeDocument(); + + delete m_document; +} + +QTEST_MAIN(DocumentTest) +#include "documenttest.moc" diff --git a/autotests/editannotationcontentstest.cpp b/autotests/editannotationcontentstest.cpp new file mode 100644 index 0000000..59b0220 --- /dev/null +++ b/autotests/editannotationcontentstest.cpp @@ -0,0 +1,528 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/annotations.h" +#include "core/document.h" +#include +#include + +class MockEditor; + +class EditAnnotationContentsTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + void testConsecutiveCharBackspacesMerged(); + void testConsecutiveNewlineBackspacesNotMerged(); + void testConsecutiveCharInsertionsMerged(); + void testConsecutiveNewlineInsertionsNotMerged(); + void testConsecutiveCharDeletesMerged(); + void testConsecutiveNewlineDeletesNotMerged(); + void testConsecutiveEditsNotMergedAcrossDifferentAnnotations(); + void testInsertWithSelection(); + void testCombinations(); + +private: + Okular::Document *m_document; + Okular::TextAnnotation *m_annot1; + Okular::TextAnnotation *m_annot2; + MockEditor *m_editor1; + MockEditor *m_editor2; +}; + +/* + * Simple class that receives the Document::annotationContentsChangedByUndoRedo + * signal that would normally be directed to an annotation's + * contents editor (For example AnnotWindow) + */ +class MockEditor : public QObject +{ + Q_OBJECT + +public: + MockEditor(Okular::Annotation *annot, Okular::Document *doc); + QString contents() + { + return m_contents; + } + int cursorPos() + { + return m_cursorPos; + } + int anchorPos() + { + return m_anchorPos; + } + +private slots: + void slotAnnotationContentsChangedByUndoRedo(Okular::Annotation *annotation, const QString &contents, int cursorPos, int anchorPos); + +private: + Okular::Document *m_document; + Okular::Annotation *m_annot; + + QString m_contents; + int m_cursorPos; + int m_anchorPos; +}; + +MockEditor::MockEditor(Okular::Annotation *annot, Okular::Document *doc) +{ + m_annot = annot; + m_document = doc; + connect(m_document, &Okular::Document::annotationContentsChangedByUndoRedo, this, &MockEditor::slotAnnotationContentsChangedByUndoRedo); + m_cursorPos = 0; + m_anchorPos = 0; + m_contents = annot->contents(); +} + +void MockEditor::slotAnnotationContentsChangedByUndoRedo(Okular::Annotation *annotation, const QString &contents, int cursorPos, int anchorPos) +{ + if (annotation == m_annot) { + m_contents = contents; + m_cursorPos = cursorPos; + m_anchorPos = anchorPos; + } +} + +void EditAnnotationContentsTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("editannotationcontentstest")); + m_document = new Okular::Document(nullptr); +} + +void EditAnnotationContentsTest::cleanupTestCase() +{ + delete m_document; +} + +void EditAnnotationContentsTest::init() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Create two distinct text annotations + m_annot1 = new Okular::TextAnnotation(); + m_annot1->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + m_annot1->setContents(QStringLiteral("Hello, World")); + m_document->addPageAnnotation(0, m_annot1); + + m_annot2 = new Okular::TextAnnotation(); + m_annot2->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + m_annot2->setContents(QStringLiteral("Hello, World")); + m_document->addPageAnnotation(0, m_annot2); + + // setup editors + m_editor1 = new MockEditor(m_annot1, m_document); + m_editor2 = new MockEditor(m_annot2, m_document); +} + +void EditAnnotationContentsTest::cleanup() +{ + m_document->closeDocument(); + delete m_editor1; + delete m_editor2; + // m_annot1 and m_annot2 are deleted when document is closed +} + +void EditAnnotationContentsTest::testConsecutiveCharBackspacesMerged() +{ + // Hello, World| -> Hello, Worl| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Worl"), 11, 12, 12); + QCOMPARE(QStringLiteral("Hello, Worl"), m_annot1->contents()); + + // Hello, Worl| -> Hello, Wor| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Wor"), 10, 11, 11); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + + // undo and verify that consecutive backspace operations are merged together + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(12, m_editor1->cursorPos()); + QCOMPARE(12, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor1->contents()); + QCOMPARE(10, m_editor1->cursorPos()); + QCOMPARE(10, m_editor1->anchorPos()); + + // Hello, Wor| -> Hello, Wo| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Wo"), 9, 10, 10); + QCOMPARE(QStringLiteral("Hello, Wo"), m_annot1->contents()); + + // Hello, Wo| -> Hello, W| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, W"), 8, 9, 9); + QCOMPARE(QStringLiteral("Hello, W"), m_annot1->contents()); + + // Hello, W| -> Hello, | + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, "), 7, 8, 8); + QCOMPARE(QStringLiteral("Hello, "), m_annot1->contents()); + + // undo and verify that consecutive backspace operations are merged together + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(12, m_editor1->cursorPos()); + QCOMPARE(12, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, "), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, "), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveNewlineBackspacesNotMerged() +{ + // Set contents to Hello, \n\n|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, \n\nWorld"), 0, 0, 0); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + + // Hello, \n\n|World -> Hello, \n|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, \nWorld"), 8, 9, 9); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_annot1->contents()); + + // Hello, \n|World -> Hello, |World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, World"), 7, 8, 8); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + + // Hello, |World -> Hello,|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello,World"), 6, 7, 7); + QCOMPARE(QStringLiteral("Hello,World"), m_annot1->contents()); + + // Hello,|World -> Hello|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("HelloWorld"), 5, 6, 6); + QCOMPARE(QStringLiteral("HelloWorld"), m_annot1->contents()); + + // Backspace operations of non-newline characters should be merged + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); + + // Backspace operations on newline characters should not be merged + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_editor1->contents()); + QCOMPARE(8, m_editor1->cursorPos()); + QCOMPARE(8, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_editor1->contents()); + QCOMPARE(9, m_editor1->cursorPos()); + QCOMPARE(9, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveCharInsertionsMerged() +{ + // Hello, |World -> Hello, B|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, BWorld"), 8, 7, 7); + QCOMPARE(QStringLiteral("Hello, BWorld"), m_annot1->contents()); + + // Hello, l| -> Hello, li| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, BiWorld"), 9, 8, 8); + QCOMPARE(QStringLiteral("Hello, BiWorld"), m_annot1->contents()); + + // Hello, li| -> Hello, lin| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, BigWorld"), 10, 9, 9); + QCOMPARE(QStringLiteral("Hello, BigWorld"), m_annot1->contents()); + + // Hello, lin| -> Hello, line| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Big World"), 11, 10, 10); + QCOMPARE(QStringLiteral("Hello, Big World"), m_annot1->contents()); + + // Verify undo/redo operations merged + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, Big World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, Big World"), m_editor1->contents()); + QCOMPARE(11, m_editor1->cursorPos()); + QCOMPARE(11, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveNewlineInsertionsNotMerged() +{ + // Hello, |World -> Hello, \n|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, \nWorld"), 8, 7, 7); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_annot1->contents()); + + // Hello, |World -> Hello, \n|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, \n\nWorld"), 9, 8, 8); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_editor1->contents()); + QCOMPARE(8, m_editor1->cursorPos()); + QCOMPARE(8, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \nWorld"), m_editor1->contents()); + QCOMPARE(8, m_editor1->cursorPos()); + QCOMPARE(8, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_editor1->contents()); + QCOMPARE(9, m_editor1->cursorPos()); + QCOMPARE(9, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveCharDeletesMerged() +{ + // Hello, |World -> Hello, |orld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, orld"), 7, 7, 7); + QCOMPARE(QStringLiteral("Hello, orld"), m_annot1->contents()); + + // Hello, |orld -> Hello, |rld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, rld"), 7, 7, 7); + QCOMPARE(QStringLiteral("Hello, rld"), m_annot1->contents()); + + // Hello, |rld -> Hello, |ld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, ld"), 7, 7, 7); + QCOMPARE(QStringLiteral("Hello, ld"), m_annot1->contents()); + + // Hello, |ld -> Hello, |d + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, d"), 7, 7, 7); + QCOMPARE(QStringLiteral("Hello, d"), m_annot1->contents()); + + // Hello, | -> Hello, | + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, "), 7, 7, 7); + QCOMPARE(QStringLiteral("Hello, "), m_annot1->contents()); + + // Verify undo/redo operations merged + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); + + m_document->redo(); + QCOMPARE(QStringLiteral("Hello, "), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, "), m_editor1->contents()); + QCOMPARE(7, m_editor1->cursorPos()); + QCOMPARE(7, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveNewlineDeletesNotMerged() +{ + // Set contents to Hello, \n\n|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, \n\nWorld"), 0, 0, 0); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + + // He|llo, \n\nWorld -> He|lo, \n\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Helo, \n\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("Helo, \n\nWorld"), m_annot1->contents()); + + // He|lo, \n\nWorld -> He|o, \n\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Heo, \n\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("Heo, \n\nWorld"), m_annot1->contents()); + + // He|o, \n\nWorld -> He|, \n\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("He, \n\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("He, \n\nWorld"), m_annot1->contents()); + + // He|, \n\nWorld -> He| \n\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("He \n\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("He \n\nWorld"), m_annot1->contents()); + + // He| \n\nWorld -> He|\n\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("He\n\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("He\n\nWorld"), m_annot1->contents()); + + // He|\n\nWorld -> He|\nWorld + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("He\nWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("He\nWorld"), m_annot1->contents()); + + // He|\nWorld -> He|World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("HeWorld"), 2, 2, 2); + QCOMPARE(QStringLiteral("HeWorld"), m_annot1->contents()); + + // Verify that deletions of newlines are not merged, but deletions of other characters are + m_document->undo(); + QCOMPARE(QStringLiteral("He\nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("He\nWorld"), m_editor1->contents()); + QCOMPARE(2, m_editor1->cursorPos()); + QCOMPARE(2, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("He\n\nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("He\n\nWorld"), m_editor1->contents()); + QCOMPARE(2, m_editor1->cursorPos()); + QCOMPARE(2, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, \n\nWorld"), m_editor1->contents()); + QCOMPARE(2, m_editor1->cursorPos()); + QCOMPARE(2, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testConsecutiveEditsNotMergedAcrossDifferentAnnotations() +{ + // Annot1: Hello, World| -> Hello, Worl| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Worl"), 11, 12, 12); + QCOMPARE(QStringLiteral("Hello, Worl"), m_annot1->contents()); + // Annot1: Hello, Worl| -> Hello, Wor| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Wor"), 10, 11, 11); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + + // Annot2: Hello, World| -> Hello, Worl| + m_document->editPageAnnotationContents(0, m_annot2, QStringLiteral("Hello, Worl"), 11, 12, 12); + QCOMPARE(QStringLiteral("Hello, Worl"), m_annot2->contents()); + // Annot2: Hello, Worl| -> Hello, Wor| + m_document->editPageAnnotationContents(0, m_annot2, QStringLiteral("Hello, Wor"), 10, 11, 11); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot2->contents()); + + // Annot1: Hello, Wor| -> Hello, Wo| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Wo"), 9, 10, 10); + QCOMPARE(QStringLiteral("Hello, Wo"), m_annot1->contents()); + // Annot1: Hello, Wo| -> Hello, W| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, W"), 8, 9, 9); + QCOMPARE(QStringLiteral("Hello, W"), m_annot1->contents()); + // Annot1: Hello, W| -> Hello, | + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, "), 7, 8, 8); + QCOMPARE(QStringLiteral("Hello, "), m_annot1->contents()); + + // Annot2: Hello, Wor| -> Hello, Wo| + m_document->editPageAnnotationContents(0, m_annot2, QStringLiteral("Hello, Wo"), 9, 10, 10); + QCOMPARE(QStringLiteral("Hello, Wo"), m_annot2->contents()); + // Annot2: Hello, Wo| -> Hello, W| + m_document->editPageAnnotationContents(0, m_annot2, QStringLiteral("Hello, W"), 8, 9, 9); + QCOMPARE(QStringLiteral("Hello, W"), m_annot2->contents()); + // Annot2: Hello, W| -> Hello, | + m_document->editPageAnnotationContents(0, m_annot2, QStringLiteral("Hello, "), 7, 8, 8); + QCOMPARE(QStringLiteral("Hello, "), m_annot2->contents()); + + // undo and verify that consecutive backspace operations are merged together + // m_annot2 -> "Hello, Wor|" + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot2->contents()); + QCOMPARE(QStringLiteral("Hello, "), m_editor1->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor2->contents()); + QCOMPARE(10, m_editor2->cursorPos()); + QCOMPARE(10, m_editor2->anchorPos()); + + // m_annot1 -> "Hello, Wor|" + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor1->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor2->contents()); + QCOMPARE(10, m_editor1->cursorPos()); + QCOMPARE(10, m_editor1->anchorPos()); + + // m_annot2 -> "Hello, World|" + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot2->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor2->contents()); + QCOMPARE(12, m_editor2->cursorPos()); + QCOMPARE(12, m_editor2->anchorPos()); + + // m_annot1 -> "Hello, World|" + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor2->contents()); + QCOMPARE(12, m_editor1->cursorPos()); + QCOMPARE(12, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testInsertWithSelection() +{ + // Annot1: |Hello|, World -> H|, World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("H, World"), 1, 0, 5); + QCOMPARE(QStringLiteral("H, World"), m_annot1->contents()); + + // Annot1: H|, World -> Hi|, World + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hi, World"), 2, 1, 1); + QCOMPARE(QStringLiteral("Hi, World"), m_annot1->contents()); + + m_document->undo(); + QCOMPARE(QStringLiteral("H, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("H, World"), m_editor1->contents()); + QCOMPARE(1, m_editor1->cursorPos()); + QCOMPARE(1, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(0, m_editor1->cursorPos()); + QCOMPARE(5, m_editor1->anchorPos()); +} + +void EditAnnotationContentsTest::testCombinations() +{ + // Annot1: Hello, World| -> Hello, Worl| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Worl"), 11, 12, 12); + QCOMPARE(QStringLiteral("Hello, Worl"), m_annot1->contents()); + + // Annot1: Hello, Worl| -> Hello, Wor| + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("Hello, Wor"), 10, 11, 11); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + + // Annot1: |He|llo, Wor -> |llo, Wor + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("llo, Wor"), 0, 2, 0); + QCOMPARE(QStringLiteral("llo, Wor"), m_annot1->contents()); + + // Annot1: |llo, Wor -> |lo, Wor + m_document->editPageAnnotationContents(0, m_annot1, QStringLiteral("lo, Wor"), 0, 0, 0); + QCOMPARE(QStringLiteral("lo, Wor"), m_annot1->contents()); + + m_document->undo(); + QCOMPARE(QStringLiteral("llo, Wor"), m_annot1->contents()); + QCOMPARE(QStringLiteral("llo, Wor"), m_editor1->contents()); + QCOMPARE(0, m_editor1->cursorPos()); + QCOMPARE(0, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, Wor"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, Wor"), m_editor1->contents()); + QCOMPARE(2, m_editor1->cursorPos()); + QCOMPARE(0, m_editor1->anchorPos()); + + m_document->undo(); + QCOMPARE(QStringLiteral("Hello, World"), m_annot1->contents()); + QCOMPARE(QStringLiteral("Hello, World"), m_editor1->contents()); + QCOMPARE(12, m_editor1->cursorPos()); + QCOMPARE(12, m_editor1->anchorPos()); +} + +QTEST_MAIN(EditAnnotationContentsTest) +#include "editannotationcontentstest.moc" diff --git a/autotests/editdrawingtooldialogtest.cpp b/autotests/editdrawingtooldialogtest.cpp new file mode 100644 index 0000000..4ab1927 --- /dev/null +++ b/autotests/editdrawingtooldialogtest.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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. * + ***************************************************************************/ + +#include "editdrawingtooldialogtest.h" +#include "../part/editdrawingtooldialog.h" + +#include +#include + +#include +#include +#include + +EditDrawingToolDialogTest::EditDrawingToolDialogTest(QObject *parent) + : QObject(parent) +{ +} + +EditDrawingToolDialogTest::~EditDrawingToolDialogTest() +{ +} + +void EditDrawingToolDialogTest::shouldHaveDefaultValues() +{ + EditDrawingToolDialog dlg; + + const QDialogButtonBox *buttonBox = dlg.findChild(QStringLiteral("buttonbox")); + QVERIFY(buttonBox); + + const KLineEdit *name = dlg.findChild(QStringLiteral("name")); + QVERIFY(name); + + const KColorButton *colorButton = dlg.findChild(QStringLiteral("colorbutton")); + QVERIFY(colorButton); + + const QSpinBox *opacity = dlg.findChild(QStringLiteral("opacity")); + QVERIFY(opacity); + + QVERIFY(name->text().isEmpty()); +} + +QTEST_MAIN(EditDrawingToolDialogTest) diff --git a/autotests/editdrawingtooldialogtest.h b/autotests/editdrawingtooldialogtest.h new file mode 100644 index 0000000..d38be41 --- /dev/null +++ b/autotests/editdrawingtooldialogtest.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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 EDITDRAWINGTOOLDIALOGTEST_H +#define EDITDRAWINGTOOLDIALOGTEST_H + +#include + +class EditDrawingToolDialogTest : public QObject +{ + Q_OBJECT +public: + explicit EditDrawingToolDialogTest(QObject *parent = nullptr); + ~EditDrawingToolDialogTest() override; + +private Q_SLOTS: + void shouldHaveDefaultValues(); +}; + +#endif // EDITDRAWINGTOOLDIALOGTEST_H diff --git a/autotests/editformstest.cpp b/autotests/editformstest.cpp new file mode 100644 index 0000000..799363b --- /dev/null +++ b/autotests/editformstest.cpp @@ -0,0 +1,423 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/document.h" +#include +#include +#include +#include + +class EditFormsTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testRadioButtonForm(); + void testCheckBoxForm(); + void testTextLineForm(); + void testTextAreaForm(); + void testFileEditForm(); + void testComboEditForm(); + void testListSingleEdit(); + void testListMultiEdit(); + + // helper methods + void verifyRadioButtonStates(bool state1, bool state2, bool state3); + void setRadioButtonStates(bool state1, bool state2, bool state3); + void verifyTextForm(Okular::FormFieldText *form); + +private: + Okular::Document *m_document; + QList m_radioButtonForms; + QList m_checkBoxForms; + Okular::FormFieldText *m_textLineForm; + Okular::FormFieldText *m_textAreaForm; + Okular::FormFieldText *m_fileEditForm; + Okular::FormFieldChoice *m_comboEdit; + Okular::FormFieldChoice *m_listSingleEdit; + Okular::FormFieldChoice *m_listMultiEdit; +}; + +void EditFormsTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("editformstest")); + m_document = new Okular::Document(nullptr); +} + +void EditFormsTest::cleanupTestCase() +{ + delete m_document; +} + +void EditFormsTest::init() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/formSamples.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + const Okular::Page *page = m_document->page(0); + QLinkedList pageFields = page->formFields(); + + // Clear lists + m_checkBoxForms.clear(); + m_radioButtonForms.clear(); + + // Collect forms of the various types + QLinkedList::const_iterator ffIt = pageFields.constBegin(), ffEnd = pageFields.constEnd(); + for (; ffIt != ffEnd; ++ffIt) { + Okular::FormField *ff = *ffIt; + ff->type(); + + switch (ff->type()) { + case Okular::FormField::FormButton: { + Okular::FormFieldButton *ffb = static_cast(ff); + switch (ffb->buttonType()) { + case Okular::FormFieldButton::Push: + break; + case Okular::FormFieldButton::CheckBox: + m_checkBoxForms.append(ffb); + break; + case Okular::FormFieldButton::Radio: + m_radioButtonForms.append(ffb); + break; + default:; + } + break; + } + case Okular::FormField::FormText: { + Okular::FormFieldText *fft = static_cast(ff); + switch (fft->textType()) { + case Okular::FormFieldText::Multiline: + m_textAreaForm = fft; + break; + case Okular::FormFieldText::Normal: + m_textLineForm = fft; + break; + case Okular::FormFieldText::FileSelect: + m_fileEditForm = fft; + break; + } + break; + } + case Okular::FormField::FormChoice: { + Okular::FormFieldChoice *ffc = static_cast(ff); + switch (ffc->choiceType()) { + case Okular::FormFieldChoice::ListBox: + if (ffc->multiSelect()) { + m_listMultiEdit = ffc; + } else { + m_listSingleEdit = ffc; + } + break; + case Okular::FormFieldChoice::ComboBox: + m_comboEdit = ffc; + break; + } + break; + } + default:; + } + } +} + +void EditFormsTest::cleanup() +{ + m_document->closeDocument(); +} + +void EditFormsTest::testRadioButtonForm() +{ + // Initially the first radio button is checked + verifyRadioButtonStates(true, false, false); + + // Set the second radio to checked and make sure the first + // is now unchecked and that an undo action is available + setRadioButtonStates(false, true, false); + verifyRadioButtonStates(false, true, false); + QVERIFY(m_document->canUndo()); + + // Now undo the action + m_document->undo(); + verifyRadioButtonStates(true, false, false); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Now redo the action + m_document->redo(); + verifyRadioButtonStates(false, true, false); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); +} + +void EditFormsTest::testCheckBoxForm() +{ + // Examine the first and second checkboxes + // Initially both checkboxes are unchecked + QVERIFY(m_checkBoxForms[0]->state() == false); + QVERIFY(m_checkBoxForms[1]->state() == false); + + // Set checkbox 1 to true + m_document->editFormButtons(0, QList() << m_checkBoxForms[0], QList() << true); + QVERIFY(m_checkBoxForms[0]->state() == true); + QVERIFY(m_checkBoxForms[1]->state() == false); + QVERIFY(m_document->canUndo()); + + // Set checkbox 2 to true + m_document->editFormButtons(0, QList() << m_checkBoxForms[1], QList() << true); + QVERIFY(m_checkBoxForms[0]->state() == true); + QVERIFY(m_checkBoxForms[1]->state() == true); + QVERIFY(m_document->canUndo()); + + // Undo checking of second checkbox + m_document->undo(); + QVERIFY(m_checkBoxForms[0]->state() == true); + QVERIFY(m_checkBoxForms[1]->state() == false); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Undo checking of first checkbox + m_document->undo(); + QVERIFY(m_checkBoxForms[0]->state() == false); + QVERIFY(m_checkBoxForms[1]->state() == false); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Redo checking of first checkbox + m_document->redo(); + QVERIFY(m_checkBoxForms[0]->state() == true); + QVERIFY(m_checkBoxForms[1]->state() == false); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); +} + +void EditFormsTest::testTextLineForm() +{ + verifyTextForm(m_textLineForm); +} + +void EditFormsTest::testTextAreaForm() +{ + verifyTextForm(m_textAreaForm); +} + +void EditFormsTest::testFileEditForm() +{ + verifyTextForm(m_fileEditForm); +} + +void EditFormsTest::testComboEditForm() +{ + // Editable combo with predefined choices: + // - combo1 + // - combo2 + // - combo3 + + // Initially no choice is selected + QCOMPARE(m_comboEdit->currentChoices().length(), 0); + QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); + + // Select first choice + m_document->editFormCombo(0, m_comboEdit, QStringLiteral("combo1"), 0, 0, 0); + QCOMPARE(m_comboEdit->currentChoices().length(), 1); + QCOMPARE(m_comboEdit->currentChoices().constFirst(), 0); + QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Select third choice + m_document->editFormCombo(0, m_comboEdit, QStringLiteral("combo3"), 0, 0, 0); + QCOMPARE(m_comboEdit->currentChoices().length(), 1); + QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); + QCOMPARE(m_comboEdit->editChoice(), QLatin1String("")); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Undo and verify that first choice is selected + m_document->undo(); + QCOMPARE(m_comboEdit->currentChoices().length(), 1); + QCOMPARE(m_comboEdit->currentChoices().constFirst(), 0); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Redo and verify that third choice is selected + m_document->redo(); + QCOMPARE(m_comboEdit->currentChoices().length(), 1); + QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Select a custom choice and verify that no predefined choices are selected + m_document->editFormCombo(0, m_comboEdit, QStringLiteral("comboEdit"), 0, 0, 0); + QCOMPARE(m_comboEdit->currentChoices().length(), 0); + QCOMPARE(m_comboEdit->editChoice(), QStringLiteral("comboEdit")); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Undo and verify that third choice is selected + m_document->undo(); + QCOMPARE(m_comboEdit->currentChoices().length(), 1); + QCOMPARE(m_comboEdit->currentChoices().constFirst(), 2); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); +} + +void EditFormsTest::testListSingleEdit() +{ + // A list with three items that allows only single selections + // Initially no choice is selected + QCOMPARE(m_listSingleEdit->currentChoices().length(), 0); + + // Select first item + m_document->editFormList(0, m_listSingleEdit, QList() << 0); + QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); + QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 0); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Select second item + m_document->editFormList(0, m_listSingleEdit, QList() << 1); + QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); + QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 1); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Undo and verify that first item is selected + m_document->undo(); + QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); + QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 0); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Redo and verify that second item is selected + m_document->redo(); + QCOMPARE(m_listSingleEdit->currentChoices().length(), 1); + QCOMPARE(m_listSingleEdit->currentChoices().constFirst(), 1); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); +} + +void EditFormsTest::testListMultiEdit() +{ + // A list with three items that allows for multiple selections + // Initially no choice is selected + QCOMPARE(m_listMultiEdit->currentChoices().length(), 0); + + // Select first item + m_document->editFormList(0, m_listMultiEdit, QList() << 0); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Select first and third items + m_document->editFormList(0, m_listMultiEdit, QList() << 0 << 2); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0 << 2); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Select all three items + m_document->editFormList(0, m_listMultiEdit, QList() << 0 << 1 << 2); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0 << 1 << 2); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Undo and verify that first and third items are selected + m_document->undo(); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0 << 2); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Undo and verify that first item is selected + m_document->undo(); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Redo and verify that first and third items are selected + m_document->redo(); + QCOMPARE(m_listMultiEdit->currentChoices(), QList() << 0 << 2); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); +} + +// helper methods +void EditFormsTest::verifyRadioButtonStates(bool state1, bool state2, bool state3) +{ + QVERIFY(m_radioButtonForms[0]->state() == state1); + QVERIFY(m_radioButtonForms[1]->state() == state2); + QVERIFY(m_radioButtonForms[2]->state() == state3); +} + +void EditFormsTest::setRadioButtonStates(bool state1, bool state2, bool state3) +{ + QList newButtonStates; + newButtonStates.append(state1); + newButtonStates.append(state2); + newButtonStates.append(state3); + m_document->editFormButtons(0, m_radioButtonForms, newButtonStates); +} + +void EditFormsTest::verifyTextForm(Okular::FormFieldText *form) +{ + // Text in form is initially empty + QCOMPARE(form->text(), QLatin1String("")); + + // Insert the string "Hello" into the form + m_document->editFormText(0, form, QStringLiteral("Hello"), 5, 0, 0); + QCOMPARE(form->text(), QStringLiteral("Hello")); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Undo the insertion and verify that form is empty again + m_document->undo(); + QCOMPARE(form->text(), QLatin1String("")); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Redo the insertion of "Hello" + m_document->redo(); + QCOMPARE(form->text(), QStringLiteral("Hello")); + QVERIFY(m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Type "_World" after "Hello" + m_document->editFormText(0, form, QStringLiteral("Hello_"), 6, 5, 5); + m_document->editFormText(0, form, QStringLiteral("Hello_W"), 7, 6, 6); + m_document->editFormText(0, form, QStringLiteral("Hello_Wo"), 8, 7, 7); + m_document->editFormText(0, form, QStringLiteral("Hello_Wor"), 9, 8, 8); + m_document->editFormText(0, form, QStringLiteral("Hello_Worl"), 10, 9, 9); + m_document->editFormText(0, form, QStringLiteral("Hello_World"), 11, 10, 10); + + // Verify that character insertion operations were merged together into a single undo command + m_document->undo(); + QCOMPARE(form->text(), QStringLiteral("Hello")); + QVERIFY(m_document->canUndo()); + QVERIFY(m_document->canRedo()); + + // Verify that one more undo gets us back to the original state (empty form) + m_document->undo(); + QCOMPARE(form->text(), QLatin1String("")); + QVERIFY(!m_document->canUndo()); + QVERIFY(m_document->canRedo()); +} + +QTEST_MAIN(EditFormsTest) +#include "editformstest.moc" diff --git a/autotests/formattest.cpp b/autotests/formattest.cpp new file mode 100644 index 0000000..4fa47af --- /dev/null +++ b/autotests/formattest.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include +#include +#include +#include +#include +#include +#include + +#include "../generators/poppler/config-okular-poppler.h" + +class FormatTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void testTimeFormat(); + void testTimeFormat_data(); + void testSpecialFormat(); + void testSpecialFormat_data(); + void testFocusAction(); + void testFocusAction_data(); + void testValidateAction(); + void testValidateAction_data(); + +private: + Okular::Document *m_document; + QMap m_fields; + QString m_formattedText; +}; + +void FormatTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("formattest")); + m_document = new Okular::Document(nullptr); + + // Force consistent locale + QLocale locale(QStringLiteral("en_US")); + QLocale::setDefault(locale); + + const QString testFile = QStringLiteral(KDESRCDIR "data/formattest.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + connect(m_document, &Okular::Document::refreshFormWidget, this, [this](Okular::FormField *form) { + Okular::FormFieldText *fft = reinterpret_cast(form); + if (fft) + m_formattedText = fft->text(); + }); + + const Okular::Page *page = m_document->page(0); + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + m_fields.insert(ff->name(), ff); + } +} + +void FormatTest::testTimeFormat() +{ + QFETCH(QString, fieldName); + QFETCH(QString, text); + QFETCH(QString, result); + + Okular::FormFieldText *fft = reinterpret_cast(m_fields[fieldName]); + fft->setText(text); + m_document->processFormatAction(fft->additionalAction(Okular::FormField::FormatField), fft); + + QCOMPARE(m_formattedText, result); +} + +void FormatTest::testTimeFormat_data() +{ + QTest::addColumn("fieldName"); + QTest::addColumn("text"); + QTest::addColumn("result"); + + QTest::newRow("field hh:mm") << QStringLiteral("time1") << QStringLiteral("1:20") << QStringLiteral("01:20"); + QTest::newRow("field hh:mm with pm") << QStringLiteral("time1") << QStringLiteral("1:20 pm") << QStringLiteral("13:20"); + QTest::newRow("field hh:mm invalid one number") << QStringLiteral("time1") << QStringLiteral("1") << QString(QLatin1String("")); + QTest::newRow("field hh:mm invalid time") << QStringLiteral("time1") << QStringLiteral("25:12") << QString(QLatin1String("")); + QTest::newRow("field hh:mm invalid only letters") << QStringLiteral("time1") << QStringLiteral("abcd") << QString(QLatin1String("")); + QTest::newRow("field hh:mm ap") << QStringLiteral("time2") << QStringLiteral("1:20") << QStringLiteral("1:20 am"); + QTest::newRow("field hh:mm ap remove zero") << QStringLiteral("time2") << QStringLiteral("01:20 pm") << QStringLiteral("1:20 pm"); + QTest::newRow("field hh:mm ap change to AM/PM") << QStringLiteral("time2") << QStringLiteral("13:20") << QStringLiteral("1:20 pm"); + QTest::newRow("field hh:mm:ss without seconds") << QStringLiteral("time3") << QStringLiteral("1:20") << QStringLiteral("01:20:00"); + QTest::newRow("field hh:mm:ss with pm") << QStringLiteral("time3") << QStringLiteral("1:20:00 pm") << QStringLiteral("13:20:00"); + QTest::newRow("field hh:mm:ss ap without am") << QStringLiteral("time4") << QStringLiteral("1:20:00") << QStringLiteral("1:20:00 am"); + QTest::newRow("field hh:mm:ss ap remove 0") << QStringLiteral("time4") << QStringLiteral("01:20:00 pm") << QStringLiteral("1:20:00 pm"); + QTest::newRow("field hh:mm:ss ap change to AM/PM") << QStringLiteral("time4") << QStringLiteral("13:20:00") << QStringLiteral("1:20:00 pm"); +} + +void FormatTest::testSpecialFormat() +{ + m_formattedText = QLatin1String(""); + QFETCH(QString, fieldName); + QFETCH(QString, text); + QFETCH(bool, edited); + QFETCH(QString, result); + + Okular::FormFieldText *fft = reinterpret_cast(m_fields[fieldName]); + fft->setText(text); + bool ok = false; + m_document->processFormatAction(fft->additionalAction(Okular::FormField::FormatField), fft); + m_document->processKeystrokeAction(fft->additionalAction(Okular::FormField::FieldModified), fft, ok); + + QCOMPARE(m_formattedText, result); + QCOMPARE(ok, edited); +} + +void FormatTest::testSpecialFormat_data() +{ + QTest::addColumn("fieldName"); + QTest::addColumn("text"); + QTest::addColumn("edited"); + QTest::addColumn("result"); + + // The tests which have invalid edited, keep the same value as when it was formatted before. + QTest::newRow("field validated but not changed") << QStringLiteral("CEP") << QStringLiteral("12345") << true << QString(QLatin1String("")); + QTest::newRow("field invalid but not changed") << QStringLiteral("CEP") << QStringLiteral("123456") << false << QString(QLatin1String("")); + QTest::newRow("field formatted and changed") << QStringLiteral("8Digits") << QStringLiteral("123456789") << true << QStringLiteral("12345-6789"); + QTest::newRow("field invalid 10 digits") << QStringLiteral("8Digits") << QStringLiteral("1234567890") << false << QStringLiteral("12345-6789"); + QTest::newRow("field formatted telephone") << QStringLiteral("telefone") << QStringLiteral("1234567890") << true << QStringLiteral("(123) 456-7890"); + QTest::newRow("field invalid telephone") << QStringLiteral("telefone") << QStringLiteral("12345678900") << false << QStringLiteral("(123) 456-7890"); + QTest::newRow("field formatted SSN") << QStringLiteral("CPF") << QStringLiteral("123456789") << true << QStringLiteral("123-45-6789"); + QTest::newRow("field invalid SSN") << QStringLiteral("CPF") << QStringLiteral("1234567890") << false << QStringLiteral("123-45-6789"); +} + +void FormatTest::testFocusAction() +{ + QFETCH(QString, result); + Okular::FormFieldText *fft = reinterpret_cast(m_fields[QStringLiteral("Validate/Focus")]); + + m_document->processFocusAction(fft->additionalAction(Okular::Annotation::FocusIn), fft); + QCOMPARE(fft->text(), result); +} + +void FormatTest::testFocusAction_data() +{ + QTest::addColumn("result"); + + QTest::newRow("when focuses") << QStringLiteral("No"); +} + +void FormatTest::testValidateAction() +{ + QFETCH(QString, text); + QFETCH(QString, result); + Okular::FormFieldText *fft = reinterpret_cast(m_fields[QStringLiteral("Validate/Focus")]); + + fft->setText(text); + bool ok = false; + m_document->processValidateAction(fft->additionalAction(Okular::Annotation::FocusOut), fft, ok); + QCOMPARE(fft->text(), result); + QVERIFY(ok); +} + +void FormatTest::testValidateAction_data() +{ + QTest::addColumn("text"); + QTest::addColumn("result"); + + QTest::newRow("valid text was set") << QStringLiteral("123") << QStringLiteral("valid"); + QTest::newRow("invalid text was set") << QStringLiteral("abc") << QStringLiteral("invalid"); +} + +void FormatTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +QTEST_MAIN(FormatTest) +#include "formattest.moc" diff --git a/autotests/generatorstest.cpp b/autotests/generatorstest.cpp new file mode 100644 index 0000000..ef7ccc4 --- /dev/null +++ b/autotests/generatorstest.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2015 by Alex Richardson * + * * + * 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. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "../generator.h" + +class GeneratorsTest : public QObject +{ + Q_OBJECT +private slots: + void testLoadsCorrectly(); +}; + +void GeneratorsTest::testLoadsCorrectly() +{ + QCoreApplication::setLibraryPaths(QStringList()); + QVERIFY2(QDir(QStringLiteral(GENERATORS_BUILD_DIR)).exists(), GENERATORS_BUILD_DIR); + // find all possible generators in $CMAKE_BINARY_DIR/generators + // We can't simply hardcore the list of generators since some might not be built + // depending on which dependencies were found by CMake + QStringList generatorLibs; + QDirIterator it(QStringLiteral(GENERATORS_BUILD_DIR), QDir::Files | QDir::Executable, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + if (QLibrary::isLibrary(it.fileName())) { + if (it.fileName().startsWith(QLatin1String("kio_"))) { + continue; // don't check kio_msits.so + } + generatorLibs << it.fileInfo().absoluteFilePath(); + } + } + int failures = 0; + int successful = 0; + 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; + failures++; + continue; + } + Okular::Generator *generator = factory->create(); + if (!generator) { + qWarning() << "Failed to cast" << lib << "to Okular::Generator"; + // without the necessary Q_INTERFACES() qobject_cast fails! + auto obj = factory->create(); + qDebug() << "Object is of type " << obj->metaObject()->className(); + qDebug() << "dynamic_cast:" << dynamic_cast(obj); + qDebug() << "qobject_cast:" << qobject_cast(obj); + failures++; + continue; + } + successful++; + } + qDebug() << "Successfully loaded" << successful << "generators"; + QCOMPARE(failures, 0); +} + +QTEST_MAIN(GeneratorsTest) + +#include "generatorstest.moc" diff --git a/autotests/kjsfunctionstest.cpp b/autotests/kjsfunctionstest.cpp new file mode 100644 index 0000000..86d4c33 --- /dev/null +++ b/autotests/kjsfunctionstest.cpp @@ -0,0 +1,359 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/action.h" +#include "core/document.h" +#include "core/scripter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../generators/poppler/config-okular-poppler.h" + +class MessageBoxHelper : public QObject +{ + Q_OBJECT + +public: + MessageBoxHelper(QMessageBox::StandardButton b, QString message, QMessageBox::Icon icon, QString title, bool hasCheckBox) + : m_button(b) + , m_clicked(false) + , m_message(std::move(message)) + , m_icon(icon) + , m_title(std::move(title)) + , m_checkBox(hasCheckBox) + { + QTimer::singleShot(0, this, &MessageBoxHelper::closeMessageBox); + } + + ~MessageBoxHelper() override + { + QVERIFY(m_clicked); + } + +private slots: + void closeMessageBox() + { + const QWidgetList allToplevelWidgets = QApplication::topLevelWidgets(); + QMessageBox *mb = nullptr; + for (QWidget *w : allToplevelWidgets) { + if (w->inherits("QMessageBox")) { + mb = qobject_cast(w); + QCOMPARE(mb->text(), m_message); + QCOMPARE(mb->windowTitle(), m_title); + QCOMPARE(mb->icon(), m_icon); + QCheckBox *box = mb->checkBox(); + QCOMPARE(box != nullptr, m_checkBox); + mb->button(m_button)->click(); + } + } + if (!mb) { + QTimer::singleShot(0, this, &MessageBoxHelper::closeMessageBox); + return; + } + m_clicked = true; + } + +private: + QMessageBox::StandardButton m_button; + bool m_clicked; + QString m_message; + QMessageBox::Icon m_icon; + QString m_title; + bool m_checkBox; +}; + +class KJSFunctionsTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testNthFieldName(); + void testDisplay(); + void testSetClearInterval(); + void testSetClearTimeOut(); + void testGetOCGs(); + void cleanupTestCase(); + void testAlert(); + void testPrintD(); + void testPrintD_data(); + +private: + Okular::Document *m_document; + QMap m_fields; +}; + +void KJSFunctionsTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("kjsfunctionstest")); + m_document = new Okular::Document(nullptr); + + const QString testFile = QStringLiteral(KDESRCDIR "data/kjsfunctionstest.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + const Okular::Page *page = m_document->page(0); + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + m_fields.insert(ff->name(), ff); + } +} + +void KJSFunctionsTest::testNthFieldName() +{ + for (int i = 0; i < 21; ++i) { + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, + QStringLiteral("var field = Doc.getField( Doc.getNthFieldName(%1) );\ + field.display = display.visible;") + .arg(i)); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.%1").arg(i)]->isVisible()); + m_fields[QStringLiteral("0.%1").arg(i)]->setVisible(false); + delete action; + } +} + +void KJSFunctionsTest::testDisplay() +{ + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("field = Doc.getField(\"0.0\");field.display=display.hidden;\ + field = Doc.getField(\"0.10\");field.display=display.visible;")); + m_document->processAction(action); + QVERIFY(!m_fields[QStringLiteral("0.0")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.0")]->isPrintable()); + QVERIFY(m_fields[QStringLiteral("0.10")]->isVisible()); + QVERIFY(m_fields[QStringLiteral("0.10")]->isPrintable()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("field = Doc.getField(\"0.10\");field.display=display.noView;\ + field = Doc.getField(\"0.15\");field.display=display.noPrint;")); + m_document->processAction(action); + QVERIFY(!m_fields[QStringLiteral("0.10")]->isVisible()); + QVERIFY(m_fields[QStringLiteral("0.10")]->isPrintable()); + QVERIFY(m_fields[QStringLiteral("0.15")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.15")]->isPrintable()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("field = Doc.getField(\"0.15\");field.display=display.hidden;\ + field = Doc.getField(\"0.20\");field.display=display.visible;")); + m_document->processAction(action); + QVERIFY(!m_fields[QStringLiteral("0.15")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.15")]->isPrintable()); + QVERIFY(m_fields[QStringLiteral("0.20")]->isVisible()); + QVERIFY(m_fields[QStringLiteral("0.20")]->isPrintable()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("field = Doc.getField(\"0.20\");field.display=display.hidden;\ + field = Doc.getField(\"0.0\");field.display=display.visible;")); + m_document->processAction(action); + QVERIFY(!m_fields[QStringLiteral("0.20")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.20")]->isPrintable()); + QVERIFY(m_fields[QStringLiteral("0.0")]->isVisible()); + QVERIFY(m_fields[QStringLiteral("0.0")]->isPrintable()); + delete action; +} + +void delay() +{ + QTime dieTime = QTime::currentTime().addSecs(2); + while (QTime::currentTime() < dieTime) + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); +} + +void KJSFunctionsTest::testSetClearInterval() +{ + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("obj = new Object();obj.idx=0;\ + obj.inc=function(){field = Doc.getField(Doc.getNthFieldName(obj.idx));\ + field.display = display.visible;\ + obj.idx = obj.idx + 1;};\ + intv = app.setInterval('obj.inc()', 450);obj.idx;")); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.0")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.3")]->isVisible()); + delete action; + delay(); + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("app.clearInterval(intv);obj.idx;")); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.3")]->isVisible()); + delete action; +} + +void KJSFunctionsTest::testSetClearTimeOut() +{ + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("intv = app.setTimeOut('obj.inc()', 1);obj.idx;")); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.3")]->isVisible()); + QVERIFY(!m_fields[QStringLiteral("0.4")]->isVisible()); + delay(); + delete action; + + QVERIFY(m_fields[QStringLiteral("0.4")]->isVisible()); + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("intv = app.setTimeOut('obj.inc()', 2000);obj.idx;")); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.4")]->isVisible()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("app.clearTimeOut(intv);obj.idx;")); + m_document->processAction(action); + QVERIFY(m_fields[QStringLiteral("0.4")]->isVisible()); + delay(); + QVERIFY(m_fields[QStringLiteral("0.4")]->isVisible()); + delete action; +} + +void KJSFunctionsTest::testGetOCGs() +{ + QAbstractItemModel *model = m_document->layersModel(); + + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("var ocg = this.getOCGs(this.pageNum);\ + ocg[0].state = false;")); + m_document->processAction(action); + QVERIFY(!model->data(model->index(0, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[0].state = true;")); + m_document->processAction(action); + QVERIFY(model->data(model->index(0, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[1].state = false;")); + m_document->processAction(action); + QVERIFY(!model->data(model->index(1, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[1].state = true;")); + m_document->processAction(action); + QVERIFY(model->data(model->index(1, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[2].state = false;")); + m_document->processAction(action); + QVERIFY(!model->data(model->index(2, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[2].state = true;")); + m_document->processAction(action); + QVERIFY(model->data(model->index(2, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[3].state = false;")); + m_document->processAction(action); + QVERIFY(!model->data(model->index(3, 0), Qt::CheckStateRole).toBool()); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ocg[3].state = true;")); + m_document->processAction(action); + QVERIFY(model->data(model->index(3, 0), Qt::CheckStateRole).toBool()); + delete action; +} + +void KJSFunctionsTest::testAlert() +{ + Okular::ScriptAction *action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ret = app.alert( \"Random Message\" );")); + QScopedPointer messageBoxHelper; + messageBoxHelper.reset(new MessageBoxHelper(QMessageBox::Ok, QStringLiteral("Random Message"), QMessageBox::Critical, QStringLiteral("Okular"), false)); + m_document->processAction(action); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ret = app.alert( \"Empty Message\", 1 );")); + messageBoxHelper.reset(new MessageBoxHelper(QMessageBox::Ok, QStringLiteral("Empty Message"), QMessageBox::Warning, QStringLiteral("Okular"), false)); + m_document->processAction(action); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ret = app.alert( \"No Message\", 2, 2 );")); + messageBoxHelper.reset(new MessageBoxHelper(QMessageBox::Yes, QStringLiteral("No Message"), QMessageBox::Question, QStringLiteral("Okular"), false)); + m_document->processAction(action); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("ret = app.alert( \"No\", 3, 2, \"Test Dialog\" );")); + messageBoxHelper.reset(new MessageBoxHelper(QMessageBox::No, QStringLiteral("No"), QMessageBox::Information, QStringLiteral("Test Dialog"), false)); + m_document->processAction(action); + delete action; + + action = new Okular::ScriptAction(Okular::JavaScript, QStringLiteral("var oCheckBox = new Object();\ + ret = app.alert( \"Cancel\", 3, 3, \"Test Dialog\", 0, oCheckBox );")); + messageBoxHelper.reset(new MessageBoxHelper(QMessageBox::Cancel, QStringLiteral("Cancel"), QMessageBox::Information, QStringLiteral("Test Dialog"), true)); + m_document->processAction(action); + delete action; +} + +/** @brief Checks a single JS action against an expected result + * + * Runs an action with the given @p script and checks that it + * does pop-up a messagebox with the given @p result text. + */ +class PrintDHelper +{ +public: + PrintDHelper(Okular::Document *document, const QString &script, const QString &result) + : action(new Okular::ScriptAction(Okular::JavaScript, script)) + , box(new MessageBoxHelper(QMessageBox::Ok, result, QMessageBox::Critical, QStringLiteral("Okular"), false)) + { + document->processAction(action.data()); + } + +private: + QScopedPointer action; + QScopedPointer box; +}; + +void KJSFunctionsTest::testPrintD_data() +{ + // Force consistent locale + QLocale locale(QStringLiteral("en_US")); + QLocale::setDefault(locale); + + QTest::addColumn("script"); + QTest::addColumn("result"); + + QTest::newRow("mmyyy") << QStringLiteral( + "var date = new Date( 2010, 0, 5, 11, 10, 32, 1 );\ + ret = app.alert( util.printd( \"mm\\\\yyyy\", date ) );") + << QStringLiteral("01\\2010"); + QTest::newRow("myy") << QStringLiteral("ret = app.alert( util.printd( \"m\\\\yy\", date ) );") << QStringLiteral("1\\10"); + QTest::newRow("ddmmHHMM") << QStringLiteral("ret = app.alert( util.printd( \"dd\\\\mm HH:MM\", date ) );") << QStringLiteral("05\\01 11:10"); + QTest::newRow("ddmmHHMMss") << QStringLiteral("ret = app.alert( util.printd( \"dd\\\\mm HH:MM:ss\", date ) );") << QStringLiteral("05\\01 11:10:32"); + QTest::newRow("yyyymmHHMMss") << QStringLiteral("ret = app.alert( util.printd( \"yyyy\\\\mm HH:MM:ss\", date ) );") << QStringLiteral("2010\\01 11:10:32"); + QTest::newRow("0") << QStringLiteral("ret = app.alert( util.printd( 0, date ) );") << QStringLiteral("D:20100105111032"); + QTest::newRow("1") << QStringLiteral("ret = app.alert( util.printd( 1, date ) );") << QStringLiteral("2010.01.05 11:10:32"); + + QDate date(2010, 1, 5); + QTest::newRow("2") << QStringLiteral("ret = app.alert( util.printd( 2, date ) );") << QString(date.toString(locale.dateFormat(QLocale::ShortFormat)) + QStringLiteral(" 11:10:32 AM")); +} + +void KJSFunctionsTest::testPrintD() +{ + QFETCH(QString, script); + QFETCH(QString, result); + + QVERIFY(script.contains(QLatin1String("printd"))); + PrintDHelper test(m_document, script, result); +} + +void KJSFunctionsTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +QTEST_MAIN(KJSFunctionsTest) +#include "kjsfunctionstest.moc" diff --git a/autotests/mainshelltest.cpp b/autotests/mainshelltest.cpp new file mode 100644 index 0000000..0994f5b --- /dev/null +++ b/autotests/mainshelltest.cpp @@ -0,0 +1,702 @@ +/*************************************************************************** + * Copyright (C) 2014 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +// clazy:excludeall=qstring-allocations + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../core/document_p.h" +#include "../part/findbar.h" +#include "../part/part.h" +#include "../part/presentationwidget.h" +#include "../settings.h" +#include "../shell/okular_main.h" +#include "../shell/shell.h" +#include "../shell/shellutils.h" +#include "closedialoghelper.h" + +#include +#ifndef Q_OS_WIN +#include +#else +#include +#endif + +namespace Okular +{ +class PartTest +{ +public: + Okular::Document *partDocument(Okular::Part *part) const + { + return part->m_document; + } + QWidget *presentationWidget(Okular::Part *part) const + { + return part->m_presentationWidget; + } + FindBar *findWidget(Okular::Part *part) const + { + return part->m_findBar; + } +}; +} + +class ClosePrintDialogHelper : public QObject +{ + Q_OBJECT + +public: + ClosePrintDialogHelper(int expectedTab) + : foundDialog(false) + , m_expectedTab(expectedTab) + { + } + bool foundDialog; + +public slots: + void closePrintDialog(); + +private: + int m_expectedTab; +}; + +class MainShellTest : public QObject, public Okular::PartTest +{ + Q_OBJECT + +public: + static QTabWidget *tabWidget(Shell *s) + { + return s->m_tabWidget; + } + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + + void testShell_data(); + void testShell(); + void testFileRemembersPagePosition_data(); + void testFileRemembersPagePosition(); + void test2FilesError_data(); + void test2FilesError(); + void testMiddleButtonCloseUndo(); + void testSessionRestore_data(); + void testSessionRestore(); + void testOpenInvalidFiles_data(); + void testOpenInvalidFiles(); + void testOpenTheSameFileSeveralTimes(); + +private: +}; + +QList getShells() +{ + QList shells; + const QList mainWindows = KMainWindow::memberList(); + for (KMainWindow *kmw : mainWindows) { + Shell *shell = qobject_cast(kmw); + if (shell) { + shells.append(shell); + } + } + return shells; +} + +Shell *findShell(Shell *ignore = nullptr) +{ + const QWidgetList wList = QApplication::topLevelWidgets(); + for (QWidget *widget : wList) { + Shell *s = qobject_cast(widget); + if (s && s != ignore) + return s; + } + return nullptr; +} + +void MainShellTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); + // Don't pollute people's okular settings + Okular::Settings::instance(QStringLiteral("mainshelltest")); + + // Register in bus as okular + QDBusConnectionInterface *bus = QDBusConnection::sessionBus().interface(); + const QString myPid = QString::number(getpid()); + const QString serviceName = QStringLiteral("org.kde.okular-") + myPid; + QVERIFY(bus->registerService(serviceName) == QDBusConnectionInterface::ServiceRegistered); + + // Tell the presentationWidget and queryClose to not be annoying + KSharedConfigPtr c = KSharedConfig::openConfig(); + KConfigGroup cg = c->group("Notification Messages"); + cg.writeEntry("presentationInfo", false); + cg.writeEntry("ShowTabWarning", false); +} + +void MainShellTest::cleanupTestCase() +{ +} + +void MainShellTest::init() +{ + // Default settings for every test + Okular::Settings::self()->setDefaults(); + + // Clean docdatas + const QList urls = {QUrl::fromUserInput(QStringLiteral("file://" KDESRCDIR "data/file1.pdf")), + QUrl::fromUserInput(QStringLiteral("file://" KDESRCDIR "data/tocreload.pdf")), + QUrl::fromUserInput(QStringLiteral("file://" KDESRCDIR "data/contents.epub"))}; + + for (const QUrl &url : urls) { + QFileInfo fileReadTest(url.toLocalFile()); + const QString docDataPath = Okular::DocumentPrivate::docDataFileName(url, fileReadTest.size()); + QFile::remove(docDataPath); + } +} + +void MainShellTest::cleanup() +{ + Shell *s; + while ((s = findShell())) { + delete s; + } +} + +void MainShellTest::testShell_data() +{ + QTest::addColumn("paths"); + QTest::addColumn("serializedOptions"); + QTest::addColumn("useTabs"); + QTest::addColumn("externalProcessPath"); + QTest::addColumn("expectedPage"); + QTest::addColumn("expectPresentation"); + QTest::addColumn("expectPrintDialog"); + QTest::addColumn("unique"); + 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"), 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 << QStringLiteral("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() +{ + QFETCH(QStringList, paths); + QFETCH(QString, serializedOptions); + QFETCH(bool, useTabs); + QFETCH(QString, externalProcessPath); + QFETCH(uint, expectedPage); + QFETCH(bool, expectPresentation); + QFETCH(bool, expectPrintDialog); + QFETCH(bool, unique); + QFETCH(uint, externalProcessExpectedPage); + QFETCH(bool, externalProcessExpectPresentation); + QFETCH(bool, externalProcessExpectPrintDialog); + QFETCH(QString, externalProcessExpectFind); + + QScopedPointer helper; + + Okular::Settings::self()->setShellOpenFileInTabs(useTabs); + + if (expectPrintDialog || externalProcessExpectPrintDialog) { + const int expectedTab = externalProcessExpectPrintDialog && !unique ? 1 : 0; + helper.reset(new ClosePrintDialogHelper(expectedTab)); + QTimer::singleShot(0, helper.data(), &ClosePrintDialogHelper::closePrintDialog); + } + + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + + if (paths.count() == 1) { + QCOMPARE(s->m_tabs.count(), 1); + Okular::Part *part = s->findChild(); + 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()); + QCOMPARE(findWidget(part)->findChild()->text(), externalProcessExpectFind); + // Checking if the encryption/decryption worked + QCOMPARE(externalProcessExpectFind, ShellUtils::find(serializedOptions)); + + } else if (paths.count() == 2) { + if (useTabs) { + Shell *s = findShell(); + QVERIFY(s); + Okular::Part *part = dynamic_cast(s->m_tabs[0].part); + Okular::Part *part2 = dynamic_cast(s->m_tabs[1].part); + QCOMPARE(s->m_tabs.count(), 2); + QCOMPARE(part->url().url(), QStringLiteral("file://%1").arg(paths[0])); + QCOMPARE(part2->url().url(), QStringLiteral("file://%1").arg(paths[1])); + QCOMPARE(partDocument(part)->currentPage(), expectedPage); + QCOMPARE(partDocument(part2)->currentPage(), expectedPage); + } else { + QSet openUrls; + Shell *s = findShell(); + QVERIFY(s); + QCOMPARE(s->m_tabs.count(), 1); + Okular::Part *part = s->findChild(); + QVERIFY(part); + QCOMPARE(partDocument(part)->currentPage(), expectedPage); + openUrls << part->url().url(); + + Shell *s2 = findShell(s); + QVERIFY(s2); + QCOMPARE(s2->m_tabs.count(), 1); + Okular::Part *part2 = s2->findChild(); + QVERIFY(part2); + QCOMPARE(partDocument(part2)->currentPage(), expectedPage); + openUrls << part2->url().url(); + + for (const QString &path : qAsConst(paths)) { + QVERIFY(openUrls.contains(QStringLiteral("file://%1").arg(path))); + } + } + } + + if (!externalProcessPath.isEmpty()) { + Okular::Part *part = s->findChild(); + + QProcess p; + QStringList args; + args << externalProcessPath; + if (unique) + args << QStringLiteral("-unique"); + if (externalProcessExpectedPage != 0) + args << QStringLiteral("-page") << QString::number(externalProcessExpectedPage + 1); + if (externalProcessExpectPresentation) + args << QStringLiteral("-presentation"); + if (externalProcessExpectPrintDialog) + args << QStringLiteral("-print"); + p.start(QStringLiteral(OKULAR_BINARY), args); + p.waitForStarted(); + QCOMPARE(p.state(), QProcess::Running); + + if (useTabs || unique) { + // It is attaching to us, so will eventually stop + QTRY_COMPARE_WITH_TIMEOUT(p.state(), QProcess::NotRunning, 20000); + QCOMPARE(p.exitStatus(), QProcess::NormalExit); + QCOMPARE(p.exitCode(), 0); + + if (unique) { + // It is unique so part got "overwritten" + QCOMPARE(s->m_tabs.count(), 1); + QCOMPARE(part->url().url(), QStringLiteral("file://%1").arg(externalProcessPath)); + QCOMPARE(partDocument(part)->currentPage(), externalProcessExpectedPage); + } else { + // It is attaching to us so a second tab is there + QCOMPARE(s->m_tabs.count(), 2); + Okular::Part *part2 = dynamic_cast(s->m_tabs[1].part); + QCOMPARE(part2->url().url(), QStringLiteral("file://%1").arg(externalProcessPath)); + QCOMPARE(partDocument(part2)->currentPage(), externalProcessExpectedPage); + } + } else { + QTest::qWait(750); + + // It opened on a new process, so it is still running, we need to kill it + QCOMPARE(p.state(), QProcess::Running); + p.terminate(); + p.waitForFinished(); + 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(), QStringLiteral("file://%1").arg(paths[0])); + QCOMPARE(partDocument(part)->currentPage(), externalProcessExpectedPage); + } + } + + if (expectPresentation) { + QCOMPARE(paths.count(), 1); + Okular::Part *part = s->findChild(); + QTRY_VERIFY(presentationWidget(part) != nullptr); + } + + if (externalProcessExpectPresentation) { + Okular::Part *part; + if (unique) { + QCOMPARE(s->m_tabs.count(), 1); + part = dynamic_cast(s->m_tabs[0].part); + } else { + QCOMPARE(s->m_tabs.count(), 2); + part = dynamic_cast(s->m_tabs[1].part); + } + + QTRY_VERIFY(presentationWidget(part) != nullptr); + } + + if (helper) { + QVERIFY(helper->foundDialog); + } +} + +void ClosePrintDialogHelper::closePrintDialog() +{ + Shell *s = findShell(); + QPrintDialog *dialog = s->findChild(); + if (!dialog) { + QTimer::singleShot(0, this, &ClosePrintDialogHelper::closePrintDialog); + return; + } + QVERIFY(dialog); + QCOMPARE(MainShellTest::tabWidget(s)->currentIndex(), m_expectedTab); + dialog->close(); + foundDialog = true; +} + +void MainShellTest::testFileRemembersPagePosition_data() +{ + QTest::addColumn("mode"); + + QTest::newRow("normal") << 1; + QTest::newRow("unique") << 2; + QTest::newRow("tabs") << 3; +} + +void MainShellTest::testFileRemembersPagePosition() +{ + QFETCH(int, mode); + + 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(), QString()); + else + serializedOptions = ShellUtils::serializeOptions(false, false, false, true, false, QString(), QString()); + + Okular::Settings::self()->setShellOpenFileInTabs(mode == 3); + + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + Okular::Part *part = s->findChild(); + QVERIFY(part); + QCOMPARE(part->url().url(), QStringLiteral("file://%1").arg(paths[0])); + QCOMPARE(partDocument(part)->currentPage(), 0u); + partDocument(part)->setViewportPage(3); + QCOMPARE(partDocument(part)->currentPage(), 3u); + s->closeUrl(); + QCOMPARE(part->url().url(), QString()); + + if (mode == 1) { + delete s; + status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + } else { + QProcess p; + QStringList args; + args << paths[0]; + if (mode == 2) + args << QStringLiteral("-unique"); + p.start(QStringLiteral(OKULAR_BINARY), args); + p.waitForStarted(); + QCOMPARE(p.state(), QProcess::Running); + + // It is attaching to us, so will eventually stop + QTRY_COMPARE_WITH_TIMEOUT((int)p.state(), (int)QProcess::NotRunning, 20000); + QCOMPARE((int)p.exitStatus(), (int)QProcess::NormalExit); + QCOMPARE(p.exitCode(), 0); + } + s = findShell(); + QVERIFY(s); + part = s->findChild(); + QVERIFY(part); + QCOMPARE(part->url().url(), QStringLiteral("file://%1").arg(paths[0])); + QCOMPARE(partDocument(part)->currentPage(), 3u); +} + +void MainShellTest::test2FilesError_data() +{ + QTest::addColumn("serializedOptions"); + + 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() +{ + QFETCH(QString, serializedOptions); + + QStringList paths; + paths << QStringLiteral(KDESRCDIR "data/file1.pdf") << QStringLiteral(KDESRCDIR "data/tocreload.pdf"); + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Error); + + Shell *s = findShell(); + QVERIFY(!s); +} + +void MainShellTest::testSessionRestore_data() +{ + QTest::addColumn("paths"); + QTest::addColumn("options"); + QTest::addColumn("useTabsOpen"); + QTest::addColumn("useTabsRestore"); + + QStringList oneDocPaths(QStringLiteral(KDESRCDIR "data/file1.pdf")); + QStringList twoDocPaths(oneDocPaths); + twoDocPaths << QStringLiteral(KDESRCDIR "data/formSamples.pdf"); + + 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; + QTest::newRow("2 docs, 2 windows, tabs") << twoDocPaths << options << false << true; + QTest::newRow("2 docs, 2 windows, no tabs") << twoDocPaths << options << false << false; + QTest::newRow("2 docs, 1 window, no tabs") << twoDocPaths << options << true << false; +} + +void MainShellTest::testSessionRestore() +{ + QFETCH(QStringList, paths); + QFETCH(QString, options); + QFETCH(bool, useTabsOpen); + QFETCH(bool, useTabsRestore); + + Okular::Settings::self()->setShellOpenFileInTabs(useTabsOpen); + + Okular::Status status = Okular::main(paths, options); + QCOMPARE(status, Okular::Success); + + // Gather some information about the state + // Verify that the correct number of windows/tabs were opened + QList shells = getShells(); + QVERIFY(!shells.isEmpty()); + int numDocs = 0; + for (Shell *shell : qAsConst(shells)) { + QVERIFY(QTest::qWaitForWindowExposed(shell)); + numDocs += shell->m_tabs.size(); + } + + QCOMPARE(numDocs, paths.size()); + QCOMPARE(shells.size(), useTabsOpen ? 1 : paths.size()); + QTest::qWait(100); + + // Simulate session shutdown. The actual shutdown path comes through + // QSessionManager XSMP handlers, then KApplication::commitData/saveState, + // then KMWSessionManager::commitData/saveState. Without simulating an X + // session manager, the best we can do here is to make a temporary Config + // and call KMainWindows save functions directly. + QTemporaryFile configFile; + QVERIFY(configFile.open()); + + int numWindows = 0; + { // Scope for config so that we can reconstruct from file + KConfig config(configFile.fileName(), KConfig::SimpleConfig); + for (Shell *shell : qAsConst(shells)) { + shell->savePropertiesInternal(&config, ++numWindows); + // Windows aren't necessarily closed on shutdown, but we'll use + // this as a way to trigger the destructor code, which is normally + // connected to the aboutToQuit signal + shell->close(); + } + } + + // Wait for shells to delete themselves. QTest::qWait doesn't do deferred + // deletions so we'll set up a full event loop to do that. + QEventLoop eventLoop; + QTimer::singleShot(100, &eventLoop, &QEventLoop::quit); + eventLoop.exec(QEventLoop::AllEvents); + shells = getShells(); + QVERIFY(shells.isEmpty()); + + Okular::Settings::self()->setShellOpenFileInTabs(useTabsRestore); + + // Simulate session restore. We can't call KMainWindow::restore() directly + // because it asks for info from the session manager, which doesn't know + // about our temporary config. But the logic here mostly mirrors restore(). + KConfig config(configFile.fileName(), KConfig::SimpleConfig); + for (int i = 1; i <= numWindows; ++i) { + Shell *shell = new Shell; + shell->readPropertiesInternal(&config, i); + shell->show(); + } + + // Verify that the restore state is reasonable + shells = getShells(); + QVERIFY(!shells.isEmpty()); + numDocs = 0; + for (Shell *shell : qAsConst(shells)) { + QVERIFY(QTest::qWaitForWindowExposed(shell)); + numDocs += shell->m_tabs.size(); + } + + QCOMPARE(numDocs, paths.size()); + QCOMPARE(shells.size(), useTabsRestore ? numWindows : paths.size()); +} + +void MainShellTest::testOpenInvalidFiles_data() +{ + QTest::addColumn>("files"); + QTest::addColumn("options"); + + QString options = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + QUrl validFile1 = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/file1.pdf"), ShellUtils::qfileExistFunc(), QString()); + QUrl validFile2 = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/file2.pdf"), ShellUtils::qfileExistFunc(), QString()); + QUrl invalidFile = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/non-existing-doc.pdf"), ShellUtils::qfileExistFunc(), QString()); + + QList firstCase {invalidFile, validFile1, validFile2}; + QList secondCase {validFile1, validFile2, invalidFile}; + + QTest::newRow("opening the invalid file first") << firstCase << options; + QTest::newRow("opening the valids file first") << secondCase << options; +} + +void MainShellTest::testOpenInvalidFiles() +{ + QFETCH(QList, files); + QFETCH(QString, options); + + /* + * The purpose of this test is to verify that when we open an invalid file, no tab is created in the + * shell. + * + */ + + Okular::Settings::self()->setShellOpenFileInTabs(true); + Okular::Status status = Okular::main(QStringList(), options); + QCOMPARE(status, Okular::Success); + + Shell *shell = findShell(); + QVERIFY(shell); + + /* + * We need to make sure that the KrecentFilesAction is empty before starting, because we will also test that + * the file gets removed from the recent documents + * + */ + shell->m_recent->clear(); + + QScopedPointer closeDialogHelper {new TestingUtils::CloseDialogHelper(QDialogButtonBox::StandardButton::Ok)}; + + for (const QUrl &file : files) { + shell->openUrl(file); + } + + QList recentFiles = shell->m_recent->urls(); + + QVERIFY(shell->m_tabs.size() == 2); + QVERIFY(shell->m_tabWidget->tabBar()->isVisible()); + + QVERIFY(!shell->m_tabWidget->tabIcon(0).isNull()); + QVERIFY(!shell->m_tabWidget->tabIcon(1).isNull()); + + QVERIFY(recentFiles.size() == 2); +} + +void MainShellTest::testOpenTheSameFileSeveralTimes() +{ + QString options = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Settings::self()->setShellOpenFileInTabs(true); + Okular::Status status = Okular::main(QStringList(), options); + QCOMPARE(status, Okular::Success); + + Shell *shell = findShell(); + QVERIFY(shell); + + QUrl file1 = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/file1.pdf"), ShellUtils::qfileExistFunc(), QString()); + QUrl file2 = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/file2.pdf"), ShellUtils::qfileExistFunc(), QString()); + QUrl file3 = ShellUtils::urlFromArg(QStringLiteral(KDESRCDIR "data/formattest.pdf"), ShellUtils::qfileExistFunc(), QString()); + + shell->openUrl(file1); + shell->openUrl(file2); + shell->openUrl(file2); + + QVERIFY(shell->m_tabs.size() == 3); + + Okular::Settings::self()->setSwitchToTabIfOpen(true); + + shell->openUrl(file3); + + shell->openUrl(file1); + QVERIFY(shell->m_tabWidget->currentIndex() == 0); + + shell->openUrl(file3); + QVERIFY(shell->m_tabWidget->currentIndex() == 3); + + QVERIFY(shell->m_tabs.size() == 4); +} + +void MainShellTest::testMiddleButtonCloseUndo() +{ + const QStringList paths = {QStringLiteral(KDESRCDIR "data/file1.pdf"), QStringLiteral(KDESRCDIR "data/file2.pdf")}; + QString serializedOptions; + serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Settings::self()->setShellOpenFileInTabs(true); + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + + QCOMPARE(s->m_tabWidget->count(), paths.size()); + // Close a tab using middle key + QWidget *firstTab = s->m_tabWidget->tabBar()->tabButton(0, QTabBar::RightSide); + QVERIFY(firstTab); + QTest::mouseClick(firstTab, Qt::MiddleButton); + QCOMPARE(s->m_tabWidget->count(), paths.size() - 1); + // Undo tab close + s->undoCloseTab(); + QCOMPARE(s->m_tabWidget->count(), paths.size()); +} + +QTEST_MAIN(MainShellTest) +#include "mainshelltest.moc" diff --git a/autotests/markdowntest.cpp b/autotests/markdowntest.cpp new file mode 100644 index 0000000..57128a9 --- /dev/null +++ b/autotests/markdowntest.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright (C) 2020 by Markus Brenneis * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/document.h" +#include "generators/markdown/converter.h" +#include +#include +#include + +class MarkdownTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void testFancyPantsEnabled(); + void testFancyPantsDisabled(); + void testImageSizes(); + +private: + void findImages(QTextFrame *parent, QVector &images); + void findImages(const QTextBlock &parent, QVector &images); +}; + +void MarkdownTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("markdowntest")); +} + +void MarkdownTest::testFancyPantsEnabled() +{ + Markdown::Converter converter; + converter.setFancyPantsEnabled(true); + QTextDocument *document = converter.convert(QStringLiteral(KDESRCDIR "data/imageSizes.md")); + + QTextFrame::iterator secondFrame = ++(document->rootFrame()->begin()); + QVERIFY(secondFrame.currentBlock().text().startsWith(QStringLiteral("©"))); +} + +void MarkdownTest::testFancyPantsDisabled() +{ + Markdown::Converter converter; + converter.setFancyPantsEnabled(false); + QTextDocument *document = converter.convert(QStringLiteral(KDESRCDIR "data/imageSizes.md")); + + QTextFrame::iterator secondFrame = ++(document->rootFrame()->begin()); + QVERIFY(secondFrame.currentBlock().text().startsWith(QStringLiteral("(c)"))); +} + +void MarkdownTest::testImageSizes() +{ + Markdown::Converter converter; + QTextDocument *document = converter.convert(QStringLiteral(KDESRCDIR "data/imageSizes.md")); + + QTextFrame *parent = document->rootFrame(); + + QVector images; + findImages(parent, images); + + QCOMPARE(images.size(), 17); + + qreal expectedSizes[][2] = {// width, height + // small image + {412, 349}, + {100, 84.70873786407767}, + {118.0515759312321, 100}, + {100, 100}, + {890, 753.9077669902913}, + {890, 890}, + // wide image + {890, 178}, + {100, 20}, + {500, 100}, + {100, 100}, + {890, 178}, + {890, 890}, + // tall image + {300, 1500}, + {100, 500}, + {20, 100}, + {100, 100}, + {890, 890}}; + + for (int i = 0; i < images.size(); i++) { + QCOMPARE(images[i].width(), expectedSizes[i][0]); + QCOMPARE(images[i].height(), expectedSizes[i][1]); + } +} + +void MarkdownTest::findImages(QTextFrame *parent, QVector &images) +{ + for (QTextFrame::iterator it = parent->begin(); !it.atEnd(); ++it) { + QTextFrame *textFrame = it.currentFrame(); + const QTextBlock textBlock = it.currentBlock(); + + if (textFrame) { + findImages(textFrame, images); + } else if (textBlock.isValid()) { + findImages(textBlock, images); + } + } +} + +void MarkdownTest::findImages(const QTextBlock &parent, QVector &images) +{ + for (QTextBlock::iterator it = parent.begin(); !it.atEnd(); ++it) { + const QTextFragment textFragment = it.fragment(); + if (textFragment.isValid()) { + const QTextCharFormat textCharFormat = textFragment.charFormat(); + if (textCharFormat.isImageFormat()) { + images.append(textCharFormat.toImageFormat()); + } + } + } +} + +QTEST_MAIN(MarkdownTest) +#include "markdowntest.moc" diff --git a/autotests/modifyannotationpropertiestest.cpp b/autotests/modifyannotationpropertiestest.cpp new file mode 100644 index 0000000..2b18fe9 --- /dev/null +++ b/autotests/modifyannotationpropertiestest.cpp @@ -0,0 +1,168 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/document.h" +#include "testingutils.h" +#include +#include +#include +#include + +class ModifyAnnotationPropertiesTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + void testModifyAnnotationProperties(); + void testModifyDefaultAnnotationProperties(); + void testModifyAnnotationPropertiesWithRotation_Bug318828(); + +private: + Okular::Document *m_document; + Okular::TextAnnotation *m_annot1; +}; + +void ModifyAnnotationPropertiesTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("editannotationcontentstest")); + m_document = new Okular::Document(nullptr); +} + +void ModifyAnnotationPropertiesTest::cleanupTestCase() +{ + delete m_document; +} + +void ModifyAnnotationPropertiesTest::init() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Create two distinct text annotations + m_annot1 = new Okular::TextAnnotation(); + m_annot1->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + m_annot1->setContents(QStringLiteral("Hello, World")); + m_annot1->setAuthor(QStringLiteral("Jon Mease")); + m_annot1->style().setColor(Qt::red); + m_annot1->style().setWidth(4.0); + m_document->addPageAnnotation(0, m_annot1); +} + +void ModifyAnnotationPropertiesTest::cleanup() +{ + m_document->closeDocument(); + // m_annot1 and m_annot2 are deleted when document is closed +} + +void ModifyAnnotationPropertiesTest::testModifyAnnotationProperties() +{ + // Add m_annot1 to document and record its properties XML string + QString origLine1Xml = TestingUtils::getAnnotationXml(m_annot1); + + // Tell document we're going to modify m_annot1's properties + m_document->prepareToModifyAnnotationProperties(m_annot1); + + // Now modify m_annot1's properties and record properties XML string + m_annot1->style().setWidth(8.0); + m_annot1->style().setColor(Qt::green); + m_document->modifyPageAnnotationProperties(0, m_annot1); + QString m_annot1XmlA = TestingUtils::getAnnotationXml(m_annot1); + QCOMPARE(8.0, m_annot1->style().width()); + QCOMPARE(QColor(Qt::green), m_annot1->style().color()); + + // undo modification and check that original properties have been restored + m_document->undo(); + QCOMPARE(4.0, m_annot1->style().width()); + QCOMPARE(QColor(Qt::red), m_annot1->style().color()); + QCOMPARE(origLine1Xml, TestingUtils::getAnnotationXml(m_annot1)); + + // redo modification and verify that new properties have been restored + m_document->redo(); + QCOMPARE(8.0, m_annot1->style().width()); + QCOMPARE(QColor(Qt::green), m_annot1->style().color()); + QCOMPARE(m_annot1XmlA, TestingUtils::getAnnotationXml(m_annot1)); + + // Verify that default values are properly restored. (We haven't explicitly set opacity yet) + QCOMPARE(1.0, m_annot1->style().opacity()); + m_document->prepareToModifyAnnotationProperties(m_annot1); + m_annot1->style().setOpacity(0.5); + m_document->modifyPageAnnotationProperties(0, m_annot1); + QCOMPARE(0.5, m_annot1->style().opacity()); + + m_document->undo(); + QCOMPARE(1.0, m_annot1->style().opacity()); + QCOMPARE(m_annot1XmlA, TestingUtils::getAnnotationXml(m_annot1)); + + // And finally undo back to original properties + m_document->undo(); + QCOMPARE(4.0, m_annot1->style().width()); + QCOMPARE(QColor(Qt::red), m_annot1->style().color()); + QCOMPARE(origLine1Xml, TestingUtils::getAnnotationXml(m_annot1)); +} + +void ModifyAnnotationPropertiesTest::testModifyDefaultAnnotationProperties() +{ + QString origLine1Xml = TestingUtils::getAnnotationXml(m_annot1); + + // Verify that default values are properly restored. (We haven't explicitly set opacity yet) + QCOMPARE(1.0, m_annot1->style().opacity()); + m_document->prepareToModifyAnnotationProperties(m_annot1); + m_annot1->style().setOpacity(0.5); + m_document->modifyPageAnnotationProperties(0, m_annot1); + QCOMPARE(0.5, m_annot1->style().opacity()); + + m_document->undo(); + QCOMPARE(1.0, m_annot1->style().opacity()); + QCOMPARE(origLine1Xml, TestingUtils::getAnnotationXml(m_annot1)); +} + +void ModifyAnnotationPropertiesTest::testModifyAnnotationPropertiesWithRotation_Bug318828() +{ + Okular::NormalizedRect boundingRect = Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15); + Okular::NormalizedRect transformedBoundingRect; + m_annot1->setBoundingRectangle(boundingRect); + m_document->addPageAnnotation(0, m_annot1); + + transformedBoundingRect = m_annot1->transformedBoundingRectangle(); + + // Before page rotation boundingRect and transformedBoundingRect should be equal + QCOMPARE(boundingRect, transformedBoundingRect); + m_document->setRotation(1); + + // After rotation boundingRect should remain unchanged but + // transformedBoundingRect should no longer equal boundingRect + QCOMPARE(boundingRect, m_annot1->boundingRectangle()); + transformedBoundingRect = m_annot1->transformedBoundingRectangle(); + QVERIFY(!(boundingRect == transformedBoundingRect)); + + // Modifying the properties of m_annot1 while page is rotated shouldn't + // alter either boundingRect or transformedBoundingRect + m_document->prepareToModifyAnnotationProperties(m_annot1); + m_annot1->style().setOpacity(0.5); + m_document->modifyPageAnnotationProperties(0, m_annot1); + + QCOMPARE(boundingRect, m_annot1->boundingRectangle()); + QCOMPARE(transformedBoundingRect, m_annot1->transformedBoundingRectangle()); +} + +QTEST_MAIN(ModifyAnnotationPropertiesTest) +#include "modifyannotationpropertiestest.moc" diff --git a/autotests/parttest.cpp b/autotests/parttest.cpp new file mode 100644 index 0000000..15c5cf5 --- /dev/null +++ b/autotests/parttest.cpp @@ -0,0 +1,2075 @@ +/*************************************************************************** + * Copyright (C) 2013 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +// clazy:excludeall=qstring-allocations + +#include + +#include "../core/annotations.h" +#include "../core/form.h" +#include "../core/page.h" +#include "../part/pageview.h" +#include "../part/part.h" +#include "../part/presentationwidget.h" +#include "../part/sidebar.h" +#include "../part/toc.h" +#include "../part/toggleactionmenu.h" +#include "../settings.h" +#include "closedialoghelper.h" + +#include "../generators/poppler/config-okular-poppler.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Okular +{ +class PartTest : public QObject +{ + Q_OBJECT + + static bool openDocument(Okular::Part *part, const QString &filePath); + +signals: + void urlHandler(const QUrl &url); // NOLINT(readability-inconsistent-declaration-parameter-name) + +private slots: + void testReload(); + void testCanceledReload(); + void testTOCReload(); + void testForwardPDF(); + void testForwardPDF_data(); + void testGeneratorPreferences(); + void testSelectText(); + void testClickInternalLink(); + void testScrollBarAndMouseWheel(); + void testOpenUrlArguments(); + void test388288(); + void testSaveAs(); + void testSaveAs_data(); + void testSaveAsToNonExistingPath(); + void testSaveAsToSymlink(); + void testSaveIsSymlink(); + void testSidebarItemAfterSaving(); + void testViewModeSavingPerFile(); + void testSaveAsUndoStackAnnotations(); + void testSaveAsUndoStackAnnotations_data(); + void testSaveAsUndoStackForms(); + void testSaveAsUndoStackForms_data(); + void testMouseMoveOverLinkWhileInSelectionMode(); + void testClickUrlLinkWhileInSelectionMode(); + void testeTextSelectionOverAndAcrossLinks_data(); + void testeTextSelectionOverAndAcrossLinks(); + void testClickUrlLinkWhileLinkTextIsSelected(); + void testRClickWhileLinkTextIsSelected(); + void testRClickOverLinkWhileLinkTextIsSelected(); + void testRClickOnSelectionModeShoulShowFollowTheLinkMenu(); + void testClickAnywhereAfterSelectionShouldUnselect(); + void testeRectSelectionStartingOnLinks(); + void testCheckBoxReadOnly(); + void testCrashTextEditDestroy(); + void testAnnotWindow(); + void testAdditionalActionTriggers(); + void testTypewriterAnnotTool(); + void testJumpToPage(); + void testOpenAtPage(); + void testForwardBackwardNavigation(); + void testTabletProximityBehavior(); + void testOpenPrintPreview(); + void testMouseModeMenu(); + void testFullScreenRequest(); + void testZoomInFacingPages(); + +private: + void simulateMouseSelection(double startX, double startY, double endX, double endY, QWidget *target); +}; + +class PartThatHijacksQueryClose : public Okular::Part +{ + Q_OBJECT +public: + PartThatHijacksQueryClose(QWidget *parentWidget, QObject *parent, const QVariantList &args) + : Okular::Part(parentWidget, parent, args) + , behavior(PassThru) + { + } + + enum Behavior { PassThru, ReturnTrue, ReturnFalse }; + + void setQueryCloseBehavior(Behavior new_behavior) + { + behavior = new_behavior; + } + + bool queryClose() override + { + if (behavior == PassThru) + return Okular::Part::queryClose(); + else // ReturnTrue or ReturnFalse + return (behavior == ReturnTrue); + } + +private: + Behavior behavior; +}; + +bool PartTest::openDocument(Okular::Part *part, const QString &filePath) +{ + part->openDocument(filePath); + return part->m_document->isOpened(); +} + +// Test that Okular doesn't crash after a successful reload +void PartTest::testReload() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + part.reload(); + qApp->processEvents(); +} + +// Test that Okular doesn't crash after a canceled reload +void PartTest::testCanceledReload() +{ + QVariantList dummyArgs; + PartThatHijacksQueryClose part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + // When queryClose() returns false, the reload operation is canceled (as if + // the user had chosen Cancel in the "Save changes?" message box) + part.setQueryCloseBehavior(PartThatHijacksQueryClose::ReturnFalse); + + part.reload(); + + qApp->processEvents(); +} + +void PartTest::testTOCReload() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/tocreload.pdf"))); + QCOMPARE(part.m_toc->expandedNodes().count(), 0); + part.m_toc->m_treeView->expandAll(); + QCOMPARE(part.m_toc->expandedNodes().count(), 3); + part.reload(); + qApp->processEvents(); + QCOMPARE(part.m_toc->expandedNodes().count(), 3); +} + +void PartTest::testForwardPDF() +{ + QFETCH(QString, dir); + + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + + // Create temp dir named like this: ${system temp dir}/${random string}/${dir} + const QTemporaryDir tempDir; + const QDir workDir(QDir(tempDir.path()).filePath(dir)); + workDir.mkpath(QStringLiteral(".")); + + QFile f(QStringLiteral(KDESRCDIR "data/synctextest.tex")); + const QString texDestination = workDir.path() + QStringLiteral("/synctextest.tex"); + QVERIFY(f.copy(texDestination)); + QProcess process; + process.setWorkingDirectory(workDir.path()); + + const QString pdflatexPath(QStandardPaths::findExecutable(QStringLiteral("pdflatex"))); + if (pdflatexPath.isEmpty()) { + QFAIL("pdflatex executable not found, but needed for the test. Try installing the respective TeXLive packages."); + } + process.start(pdflatexPath, 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"); + + QVERIFY(QFile::exists(pdfResult)); + + QVERIFY(openDocument(&part, pdfResult)); + part.m_document->setViewportPage(0); + QCOMPARE(part.m_document->currentPage(), 0u); + part.closeUrl(); + + QUrl u(QUrl::fromLocalFile(pdfResult)); + u.setFragment(QStringLiteral("src:100") + texDestination); + part.openUrl(u); + QCOMPARE(part.m_document->currentPage(), 1u); +} + +void PartTest::testForwardPDF_data() +{ + QTest::addColumn("dir"); + + QTest::newRow("non-utf8") << QStringLiteral("synctextest"); + // QStringliteral is broken on windows with non ascii chars so using QString::fromUtf8 + QTest::newRow("utf8") << QString::fromUtf8("ßðđđŋßðđŋ"); +} + +void PartTest::testGeneratorPreferences() +{ + KConfigDialog *dialog; + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + + // Test that we don't crash while opening the dialog + dialog = part.slotGeneratorPreferences(); + qApp->processEvents(); + delete dialog; // closes the dialog and recursively destroys all widgets + + // Test that we don't crash while opening a new instance of the dialog + // This catches attempts to reuse widgets that have been destroyed + dialog = part.slotGeneratorPreferences(); + qApp->processEvents(); + delete dialog; +} + +void PartTest::testSelectText() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file2.pdf"))); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const int mouseY = height * 0.052; + const int mouseStartX = width * 0.12; + const int mouseEndX = width * 0.7; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + QApplication::clipboard()->clear(); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "copyTextSelection")); + + QCOMPARE(QApplication::clipboard()->text(), QStringLiteral("Hola que tal\n")); +} + +void PartTest::testClickInternalLink() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file2.pdf"))); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + QMetaObject::invokeMethod(part.m_pageView, "slotMouseNormalToggled", Q_ARG(bool, true)); + + QCOMPARE(part.m_document->currentPage(), 0u); + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.17, height * 0.05)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.17, height * 0.05)); + QTRY_COMPARE(part.m_document->currentPage(), 1u); + + // make sure cursor goes back to being an open hand again. Bug 421437 + QTRY_COMPARE_WITH_TIMEOUT(part.m_pageView->cursor().shape(), Qt::OpenHandCursor, 1000); +} + +// Test for bug 421159, which is: When scrolling down with the scroll bar +// followed by scrolling down with the mouse wheel, the mouse wheel scrolling +// will make the viewport jump back to the first page. +void PartTest::testScrollBarAndMouseWheel() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"))); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + // Make sure we are on the first page + QCOMPARE(part.m_document->currentPage(), 0u); + + // Two clicks on the vertical scrollbar + auto scrollBar = part.m_pageView->verticalScrollBar(); + + QTest::mouseClick(scrollBar, Qt::LeftButton); + QTest::qWait(QApplication::doubleClickInterval() * 2); // Wait a tiny bit + QTest::mouseClick(scrollBar, Qt::LeftButton); + + // We have scrolled enough to be on the second page now + QCOMPARE(part.m_document->currentPage(), 1u); + + // Scroll further down using the mouse wheel + auto wheelDown = new QWheelEvent({}, {}, {}, {0, -150}, Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + QCoreApplication::postEvent(part.m_pageView->viewport(), wheelDown); + + // Wait a little for the scrolling to actually happen. + // We should still be on the second page after that. + QTest::qWait(1000); + + QCOMPARE(part.m_document->currentPage(), 1u); +} + +// cursor switches to Hand when hovering over link in TextSelect mode. +void PartTest::testMouseMoveOverLinkWhileInSelectionMode() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + // move mouse over link + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.250, height * 0.127)); + + // check if mouse icon changed to proper icon + QTRY_COMPARE(part.m_pageView->cursor().shape(), Qt::PointingHandCursor); +} + +// clicking on hyperlink jumps to destination in TextSelect mode. +void PartTest::testClickUrlLinkWhileInSelectionMode() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + // overwrite urlHandler for 'mailto' urls + QDesktopServices::setUrlHandler(QStringLiteral("mailto"), this, "urlHandler"); + QSignalSpy openUrlSignalSpy(this, &PartTest::urlHandler); + + // click on url + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.250, height * 0.127)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.250, height * 0.127)); + + // expect that the urlHandler signal was called + QTRY_COMPARE(openUrlSignalSpy.count(), 1); + QList arguments = openUrlSignalSpy.takeFirst(); + QCOMPARE(arguments.at(0).value(), QUrl("mailto:foo@foo.bar")); +} + +void PartTest::testeTextSelectionOverAndAcrossLinks_data() +{ + QTest::addColumn("mouseStartX"); + QTest::addColumn("mouseEndX"); + QTest::addColumn("expectedResult"); + + // can text-select "over and across" hyperlink. + QTest::newRow("start selection before link") << 0.1564 << 0.2943 << QStringLiteral(" a link: foo@foo.b"); + // can text-select starting at text and ending selection in middle of hyperlink. + QTest::newRow("start selection in the middle of the link") << 0.28 << 0.382 << QStringLiteral("o.bar\n"); + // text selection works when selecting left to right or right to left + QTest::newRow("start selection after link") << 0.40 << 0.05 << QStringLiteral("This is a link: foo@foo.bar\n"); +} + +// can text-select "over and across" hyperlink. +void PartTest::testeTextSelectionOverAndAcrossLinks() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const double mouseY = height * 0.127; + QFETCH(double, mouseStartX); + QFETCH(double, mouseEndX); + + mouseStartX = width * mouseStartX; + mouseEndX = width * mouseEndX; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + QApplication::clipboard()->clear(); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "copyTextSelection")); + + QFETCH(QString, expectedResult); + QCOMPARE(QApplication::clipboard()->text(), expectedResult); +} + +// can jump to link while there's an active selection of text. +void PartTest::testClickUrlLinkWhileLinkTextIsSelected() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const double mouseY = height * 0.127; + const double mouseStartX = width * 0.13; + const double mouseEndX = width * 0.40; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + // overwrite urlHandler for 'mailto' urls + QDesktopServices::setUrlHandler(QStringLiteral("mailto"), this, "urlHandler"); + QSignalSpy openUrlSignalSpy(this, &PartTest::urlHandler); + + // click on url + const double mouseClickX = width * 0.2997; + const double mouseClickY = height * 0.1293; + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseClickX, mouseClickY)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(mouseClickX, mouseClickY), 1000); + + // expect that the urlHandler signal was called + QTRY_COMPARE(openUrlSignalSpy.count(), 1); + QList arguments = openUrlSignalSpy.takeFirst(); + QCOMPARE(arguments.at(0).value(), QUrl("mailto:foo@foo.bar")); +} + +// r-click on the selected text gives the "Go To:" content menu option +void PartTest::testRClickWhileLinkTextIsSelected() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const double mouseY = height * 0.162; + const double mouseStartX = width * 0.42; + const double mouseEndX = width * 0.60; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + // Need to do this because the pop-menu will have his own mainloop and will block tests until + // the menu disappear + PageView *view = part.m_pageView; + bool menuClosed = false; + QTimer::singleShot(2000, view, [view, &menuClosed]() { + // check if popup menu is active and visible + QMenu *menu = qobject_cast(view->findChild(QStringLiteral("PopupMenu"))); + QVERIFY(menu); + QVERIFY(menu->isVisible()); + + // check if the menu contains go-to link action + QAction *goToAction = qobject_cast(menu->findChild(QStringLiteral("GoToAction"))); + QVERIFY(goToAction); + + // check if the "follow this link" action is not visible + QAction *processLinkAction = qobject_cast(menu->findChild(QStringLiteral("ProcessLinkAction"))); + QVERIFY(!processLinkAction); + + // check if the "copy link address" action is not visible + QAction *copyLinkLocation = qobject_cast(menu->findChild(QStringLiteral("CopyLinkLocationAction"))); + QVERIFY(!copyLinkLocation); + + // close menu to continue test + menu->close(); + menuClosed = true; + }); + + // click on url + const double mouseClickX = width * 0.425; + const double mouseClickY = height * 0.162; + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseClickX, mouseClickY)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::RightButton, Qt::NoModifier, QPoint(mouseClickX, mouseClickY), 1000); + + // will continue after pop-menu get closed + QTRY_VERIFY(menuClosed); +} + +// r-click on the link gives the "follow this link" content menu option +void PartTest::testRClickOverLinkWhileLinkTextIsSelected() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const double mouseY = height * 0.162; + const double mouseStartX = width * 0.42; + const double mouseEndX = width * 0.60; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + // Need to do this because the pop-menu will have his own mainloop and will block tests until + // the menu disappear + PageView *view = part.m_pageView; + bool menuClosed = false; + QTimer::singleShot(2000, view, [view, &menuClosed]() { + // check if popup menu is active and visible + QMenu *menu = qobject_cast(view->findChild(QStringLiteral("PopupMenu"))); + QVERIFY(menu); + QVERIFY(menu->isVisible()); + + // check if the menu contains "follow this link" action + QAction *processLinkAction = qobject_cast(menu->findChild(QStringLiteral("ProcessLinkAction"))); + QVERIFY(processLinkAction); + + // check if the menu contains "copy link address" action + QAction *copyLinkLocation = qobject_cast(menu->findChild(QStringLiteral("CopyLinkLocationAction"))); + QVERIFY(copyLinkLocation); + + // close menu to continue test + menu->close(); + menuClosed = true; + }); + + // click on url + const double mouseClickX = width * 0.593; + const double mouseClickY = height * 0.162; + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseClickX, mouseClickY)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::RightButton, Qt::NoModifier, QPoint(mouseClickX, mouseClickY), 1000); + + // will continue after pop-menu get closed + QTRY_VERIFY(menuClosed); +} + +void PartTest::testRClickOnSelectionModeShoulShowFollowTheLinkMenu() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + // Need to do this because the pop-menu will have his own mainloop and will block tests until + // the menu disappear + PageView *view = part.m_pageView; + bool menuClosed = false; + QTimer::singleShot(2000, view, [view, &menuClosed]() { + // check if popup menu is active and visible + QMenu *menu = qobject_cast(view->findChild(QStringLiteral("PopupMenu"))); + QVERIFY(menu); + QVERIFY(menu->isVisible()); + + // check if the menu contains "Follow this link" action + QAction *processLink = qobject_cast(menu->findChild(QStringLiteral("ProcessLinkAction"))); + QVERIFY(processLink); + + // chek if the menu contains "Copy Link Address" action + QAction *actCopyLinkLocation = qobject_cast(menu->findChild(QStringLiteral("CopyLinkLocationAction"))); + QVERIFY(actCopyLinkLocation); + + // close menu to continue test + menu->close(); + menuClosed = true; + }); + + // r-click on url + const double mouseClickX = width * 0.604; + const double mouseClickY = height * 0.162; + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseClickX, mouseClickY)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::RightButton, Qt::NoModifier, QPoint(mouseClickX, mouseClickY), 1000); + + // will continue after pop-menu get closed + QTRY_VERIFY(menuClosed); +} + +void PartTest::testClickAnywhereAfterSelectionShouldUnselect() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // resize window to avoid problem with selection areas + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseTextSelect")); + + const double mouseY = height * 0.162; + const double mouseStartX = width * 0.42; + const double mouseEndX = width * 0.60; + + simulateMouseSelection(mouseStartX, mouseY, mouseEndX, mouseY, part.m_pageView->viewport()); + + // click on url + const double mouseClickX = width * 0.10; + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(mouseClickX, mouseY)); + QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(mouseClickX, mouseY), 1000); + + QApplication::clipboard()->clear(); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "copyTextSelection")); + + // check if copied text is empty what means no text selected + QVERIFY(QApplication::clipboard()->text().isEmpty()); +} + +void PartTest::testeRectSelectionStartingOnLinks() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/pdf_with_links.pdf"))); + // hide info messages as they interfere with selection area + Okular::Settings::self()->setShowOSD(false); + ; + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // enter text-selection mode + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseSelect")); + + const double mouseStartY = height * 0.127; + const double mouseEndY = height * 0.127; + const double mouseStartX = width * 0.28; + const double mouseEndX = width * 0.382; + + // Need to do this because the pop-menu will have his own mainloop and will block tests until + // the menu disappear + PageView *view = part.m_pageView; + bool menuClosed = false; + QTimer::singleShot(2000, view, [view, &menuClosed]() { + QApplication::clipboard()->clear(); + + // check if popup menu is active and visible + QMenu *menu = qobject_cast(view->findChild(QStringLiteral("PopupMenu"))); + QVERIFY(menu); + QVERIFY(menu->isVisible()); + + // check if the copy selected text to clipboard is present + QAction *copyAct = qobject_cast(menu->findChild(QStringLiteral("CopyTextToClipboard"))); + QVERIFY(copyAct); + + menu->close(); + menuClosed = true; + }); + + simulateMouseSelection(mouseStartX, mouseStartY, mouseEndX, mouseEndY, part.m_pageView->viewport()); + + // wait menu get closed + QTRY_VERIFY(menuClosed); +} + +void PartTest::simulateMouseSelection(double startX, double startY, double endX, double endY, QWidget *target) +{ + const int steps = 5; + const double diffX = endX - startX; + const double diffY = endY - startY; + const double diffXStep = diffX / steps; + const double diffYStep = diffY / steps; + + QTestEventList events; + events.addMouseMove(QPoint(startX, startY)); + events.addMousePress(Qt::LeftButton, Qt::NoModifier, QPoint(startX, startY)); + for (int i = 0; i < steps - 1; ++i) { + events.addMouseMove(QPoint(startX + i * diffXStep, startY + i * diffYStep)); + events.addDelay(100); + } + events.addMouseMove(QPoint(endX, endY)); + events.addDelay(100); + events.addMouseRelease(Qt::LeftButton, Qt::NoModifier, QPoint(endX, endY)); + + events.simulate(target); +} + +void PartTest::testSaveAsToNonExistingPath() +{ + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(KDESRCDIR "data/file1.pdf"); + + QString saveFilePath; + { + QTemporaryFile saveFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + saveFile.open(); + saveFilePath = saveFile.fileName(); + // QTemporaryFile is destroyed and the file it created is gone, this is a TOCTOU but who cares + } + + QVERIFY(!QFileInfo::exists(saveFilePath)); + + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFilePath), Part::NoSaveAsFlags)); + + QFile::remove(saveFilePath); +} + +void PartTest::testSaveAsToSymlink() +{ +#ifdef Q_OS_UNIX + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(KDESRCDIR "data/file1.pdf"); + + QTemporaryFile newFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + newFile.open(); + + QString linkFilePath; + { + QTemporaryFile linkFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + linkFile.open(); + linkFilePath = linkFile.fileName(); + // QTemporaryFile is destroyed and the file it created is gone, this is a TOCTOU but who cares + } + + QFile::link(newFile.fileName(), linkFilePath); + + QVERIFY(QFileInfo(linkFilePath).isSymLink()); + + QVERIFY(part.saveAs(QUrl::fromLocalFile(linkFilePath), Part::NoSaveAsFlags)); + + QVERIFY(QFileInfo(linkFilePath).isSymLink()); + + QFile::remove(linkFilePath); +#endif +} + +void PartTest::testSaveIsSymlink() +{ +#ifdef Q_OS_UNIX + Okular::Part part(nullptr, nullptr, QVariantList()); + + QString newFilePath; + { + QTemporaryFile newFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + newFile.open(); + newFilePath = newFile.fileName(); + // QTemporaryFile is destroyed and the file it created is gone, this is a TOCTOU but who cares + } + + QFile::copy(KDESRCDIR "data/file1.pdf", newFilePath); + + QString linkFilePath; + { + QTemporaryFile linkFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + linkFile.open(); + linkFilePath = linkFile.fileName(); + // QTemporaryFile is destroyed and the file it created is gone, this is a TOCTOU but who cares + } + + QFile::link(newFilePath, linkFilePath); + + QVERIFY(QFileInfo(linkFilePath).isSymLink()); + + part.openDocument(linkFilePath); + QVERIFY(part.saveAs(QUrl::fromLocalFile(linkFilePath), Part::NoSaveAsFlags)); + + QVERIFY(QFileInfo(linkFilePath).isSymLink()); + + QFile::remove(newFilePath); + QFile::remove(linkFilePath); +#endif +} + +void PartTest::testSaveAs() +{ + QFETCH(QString, file); + QFETCH(QString, extension); + QFETCH(bool, nativelySupportsAnnotations); + QFETCH(bool, canSwapBackingFile); + + QScopedPointer closeDialogHelper; + + QString annotName; + QTemporaryFile archiveSave(QStringLiteral("%1/okrXXXXXX.okular").arg(QDir::tempPath())); + QTemporaryFile nativeDirectSave(QStringLiteral("%1/okrXXXXXX.%2").arg(QDir::tempPath(), extension)); + QTemporaryFile nativeFromArchiveFile(QStringLiteral("%1/okrXXXXXX.%2").arg(QDir::tempPath(), extension)); + QVERIFY(archiveSave.open()); + archiveSave.close(); + QVERIFY(nativeDirectSave.open()); + nativeDirectSave.close(); + QVERIFY(nativeFromArchiveFile.open()); + nativeFromArchiveFile.close(); + + qDebug() << "Open file, add annotation and save both natively and to .okular"; + { + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(file); + part.m_document->documentInfo(); + + QCOMPARE(part.m_document->canSwapBackingFile(), canSwapBackingFile); + + Okular::Annotation *annot = new Okular::TextAnnotation(); + annot->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + annot->setContents(QStringLiteral("annot contents")); + part.m_document->addPageAnnotation(0, annot); + annotName = annot->uniqueName(); + + if (canSwapBackingFile) { + if (!nativelySupportsAnnotations) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(nativeDirectSave.fileName()), Part::NoSaveAsFlags)); + // For backends that don't support annotations natively we mark the part as still modified + // after a save because we keep the annotation around but it will get lost if the user closes the app + // so we want to give her a last chance to save on close with the "you have changes dialog" + QCOMPARE(part.isModified(), !nativelySupportsAnnotations); + QVERIFY(part.saveAs(QUrl::fromLocalFile(archiveSave.fileName()), Part::SaveAsOkularArchive)); + } else { + // We need to save to archive first otherwise we lose the annotation + + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::Yes)); // this is the "you're going to lose the undo/redo stack" dialog + QVERIFY(part.saveAs(QUrl::fromLocalFile(archiveSave.fileName()), Part::SaveAsOkularArchive)); + + if (!nativelySupportsAnnotations) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(nativeDirectSave.fileName()), Part::NoSaveAsFlags)); + } + + QCOMPARE(part.m_document->documentInfo().get(Okular::DocumentInfo::FilePath), part.m_document->currentDocument().toDisplayString()); + part.closeUrl(); + } + + qDebug() << "Open the .okular, check that the annotation is present and save to native"; + { + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(archiveSave.fileName()); + part.m_document->documentInfo(); + + QCOMPARE(part.m_document->page(0)->annotations().size(), 1); + QCOMPARE(part.m_document->page(0)->annotations().first()->uniqueName(), annotName); + + if (!nativelySupportsAnnotations) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(nativeFromArchiveFile.fileName()), Part::NoSaveAsFlags)); + + if (canSwapBackingFile && !nativelySupportsAnnotations) { + // For backends that don't support annotations natively we mark the part as still modified + // after a save because we keep the annotation around but it will get lost if the user closes the app + // so we want to give her a last chance to save on close with the "you have changes dialog" + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "do you want to save or discard" dialog + } + + QCOMPARE(part.m_document->documentInfo().get(Okular::DocumentInfo::FilePath), part.m_document->currentDocument().toDisplayString()); + part.closeUrl(); + } + + qDebug() << "Open the native file saved directly, and check that the annot" + << "is there iff we expect it"; + { + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(nativeDirectSave.fileName()); + + QCOMPARE(part.m_document->page(0)->annotations().size(), nativelySupportsAnnotations ? 1 : 0); + if (nativelySupportsAnnotations) + QCOMPARE(part.m_document->page(0)->annotations().first()->uniqueName(), annotName); + + part.closeUrl(); + } + + qDebug() << "Open the native file saved from the .okular, and check that the annot" + << "is there iff we expect it"; + { + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(nativeFromArchiveFile.fileName()); + + QCOMPARE(part.m_document->page(0)->annotations().size(), nativelySupportsAnnotations ? 1 : 0); + if (nativelySupportsAnnotations) + QCOMPARE(part.m_document->page(0)->annotations().first()->uniqueName(), annotName); + + part.closeUrl(); + } +} + +void PartTest::testSaveAs_data() +{ + QTest::addColumn("file"); + QTest::addColumn("extension"); + QTest::addColumn("nativelySupportsAnnotations"); + QTest::addColumn("canSwapBackingFile"); + + QTest::newRow("pdf") << KDESRCDIR "data/file1.pdf" + << "pdf" << true << true; + QTest::newRow("pdf.gz") << KDESRCDIR "data/file1.pdf.gz" + << "pdf" << true << true; + QTest::newRow("epub") << KDESRCDIR "data/contents.epub" + << "epub" << false << false; + QTest::newRow("jpg") << KDESRCDIR "data/potato.jpg" + << "jpg" << false << true; +} + +void PartTest::testSidebarItemAfterSaving() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QWidget *currentSidebarItem = part.m_sidebar->currentItem(); // thumbnails + openDocument(&part, QStringLiteral(KDESRCDIR "data/tocreload.pdf")); + // since it has TOC it changes to TOC + QVERIFY(currentSidebarItem != part.m_sidebar->currentItem()); + // now change back to thumbnails + part.m_sidebar->setCurrentItem(currentSidebarItem); + + part.saveAs(QUrl::fromLocalFile(QStringLiteral(KDESRCDIR "data/tocreload.pdf"))); + + // Check it is still thumbnails after saving + QCOMPARE(currentSidebarItem, part.m_sidebar->currentItem()); +} + +void PartTest::testViewModeSavingPerFile() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + + // Open some file + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + // Switch to 'continuous' view mode + part.m_pageView->setCapability(Okular::View::ViewCapability::Continuous, QVariant(true)); + + // Close document + part.closeUrl(); + + // Open another file + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file2.pdf"))); + + // Switch to 'non-continuous' mode + part.m_pageView->setCapability(Okular::View::ViewCapability::Continuous, QVariant(false)); + + // Close that document, too + part.closeUrl(); + + // Open first document again + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + // If per-file view mode saving works, the view mode should be 'continuous' again. + QVERIFY(part.m_pageView->capability(Okular::View::ViewCapability::Continuous).toBool()); +} + +void PartTest::testSaveAsUndoStackAnnotations() +{ + QFETCH(QString, file); + QFETCH(QString, extension); + QFETCH(bool, nativelySupportsAnnotations); + QFETCH(bool, canSwapBackingFile); + QFETCH(bool, saveToArchive); + + const Part::SaveAsFlag saveFlags = saveToArchive ? Part::SaveAsOkularArchive : Part::NoSaveAsFlags; + + QScopedPointer closeDialogHelper; + + // closeDialogHelper relies on the availability of the "Continue" button to drop changes + // when saving to a file format not supporting those. However, this button is only sensible + // and available for "Save As", but not for "Save". By alternately saving to saveFile1 and + // saveFile2 we always force "Save As", so closeDialogHelper keeps working. + QTemporaryFile saveFile1(QStringLiteral("%1/okrXXXXXX_1.%2").arg(QDir::tempPath(), extension)); + QVERIFY(saveFile1.open()); + saveFile1.close(); + QTemporaryFile saveFile2(QStringLiteral("%1/okrXXXXXX_2.%2").arg(QDir::tempPath(), extension)); + QVERIFY(saveFile2.open()); + saveFile2.close(); + + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(file); + + QCOMPARE(part.m_document->canSwapBackingFile(), canSwapBackingFile); + + Okular::Annotation *annot = new Okular::TextAnnotation(); + annot->setBoundingRectangle(Okular::NormalizedRect(0.1, 0.1, 0.15, 0.15)); + annot->setContents(QStringLiteral("annot contents")); + part.m_document->addPageAnnotation(0, annot); + QString annotName = annot->uniqueName(); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + + if (!canSwapBackingFile) { + // The undo/redo stack gets lost if you can not swap the backing file + QVERIFY(!part.m_document->canUndo()); + QVERIFY(!part.m_document->canRedo()); + return; + } + + // Check we can still undo the annot add after save + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(!part.m_document->canUndo()); + + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->page(0)->annotations().isEmpty()); + + // Check we can redo the annot add after save + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(!part.m_document->canRedo()); + + if (nativelySupportsAnnotations) { + // If the annots are provided by the backend we need to refetch the pointer after save + annot = part.m_document->page(0)->annotation(annotName); + QVERIFY(annot); + } + + // Remove the annotation, creates another undo command + QVERIFY(part.m_document->canRemovePageAnnotation(annot)); + part.m_document->removePageAnnotation(0, annot); + QVERIFY(part.m_document->page(0)->annotations().isEmpty()); + + // Check we can still undo the annot remove after save + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.m_document->canUndo()); + QCOMPARE(part.m_document->page(0)->annotations().count(), 1); + + // Check we can still undo the annot add after save + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile2.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(!part.m_document->canUndo()); + QVERIFY(part.m_document->page(0)->annotations().isEmpty()); + + // Redo the add annotation + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.m_document->canUndo()); + QVERIFY(part.m_document->canRedo()); + + if (nativelySupportsAnnotations) { + // If the annots are provided by the backend we need to refetch the pointer after save + annot = part.m_document->page(0)->annotation(annotName); + QVERIFY(annot); + } + + // Add translate, adjust and modify commands + part.m_document->translatePageAnnotation(0, annot, Okular::NormalizedPoint(0.1, 0.1)); + part.m_document->adjustPageAnnotation(0, annot, Okular::NormalizedPoint(0.1, 0.1), Okular::NormalizedPoint(0.1, 0.1)); + part.m_document->prepareToModifyAnnotationProperties(annot); + part.m_document->modifyPageAnnotationProperties(0, annot); + + // Now check we can still undo/redo/save at all the intermediate states and things still work + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile2.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.m_document->canUndo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.m_document->canUndo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile2.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.m_document->canUndo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(!part.m_document->canUndo()); + QVERIFY(part.m_document->canRedo()); + QVERIFY(part.m_document->page(0)->annotations().isEmpty()); + + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.m_document->canRedo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile2.fileName()), saveFlags)); + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.m_document->canRedo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile1.fileName()), saveFlags)); + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.m_document->canRedo()); + + if (!nativelySupportsAnnotations && !saveToArchive) { + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "you're going to lose the annotations" dialog + } + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile2.fileName()), saveFlags)); + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(!part.m_document->canRedo()); + + closeDialogHelper.reset(new TestingUtils::CloseDialogHelper(&part, QDialogButtonBox::No)); // this is the "do you want to save or discard" dialog + part.closeUrl(); +} + +void PartTest::testSaveAsUndoStackAnnotations_data() +{ + QTest::addColumn("file"); + QTest::addColumn("extension"); + QTest::addColumn("nativelySupportsAnnotations"); + QTest::addColumn("canSwapBackingFile"); + QTest::addColumn("saveToArchive"); + + QTest::newRow("pdf") << KDESRCDIR "data/file1.pdf" + << "pdf" << true << true << false; + QTest::newRow("epub") << KDESRCDIR "data/contents.epub" + << "epub" << false << false << false; + QTest::newRow("jpg") << KDESRCDIR "data/potato.jpg" + << "jpg" << false << true << false; + QTest::newRow("pdfarchive") << KDESRCDIR "data/file1.pdf" + << "okular" << true << true << true; + QTest::newRow("jpgarchive") << KDESRCDIR "data/potato.jpg" + << "okular" << false << true << true; +} + +void PartTest::testSaveAsUndoStackForms() +{ + QFETCH(QString, file); + QFETCH(QString, extension); + QFETCH(bool, saveToArchive); + + const Part::SaveAsFlag saveFlags = saveToArchive ? Part::SaveAsOkularArchive : Part::NoSaveAsFlags; + + QTemporaryFile saveFile(QStringLiteral("%1/okrXXXXXX.%2").arg(QDir::tempPath(), extension)); + QVERIFY(saveFile.open()); + saveFile.close(); + + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(file); + + const QLinkedList pageFormFields = part.m_document->page(0)->formFields(); + for (FormField *ff : pageFormFields) { + if (ff->id() == 65537) { + QCOMPARE(ff->type(), FormField::FormText); + FormFieldText *fft = static_cast(ff); + part.m_document->editFormText(0, fft, QStringLiteral("BlaBla"), 6, 0, 0); + } else if (ff->id() == 65538) { + QCOMPARE(ff->type(), FormField::FormButton); + FormFieldButton *ffb = static_cast(ff); + QCOMPARE(ffb->buttonType(), FormFieldButton::Radio); + part.m_document->editFormButtons(0, QList() << ffb, QList() << true); + } else if (ff->id() == 65542) { + QCOMPARE(ff->type(), FormField::FormChoice); + FormFieldChoice *ffc = static_cast(ff); + QCOMPARE(ffc->choiceType(), FormFieldChoice::ListBox); + part.m_document->editFormList(0, ffc, QList() << 1); + } else if (ff->id() == 65543) { + QCOMPARE(ff->type(), FormField::FormChoice); + FormFieldChoice *ffc = static_cast(ff); + QCOMPARE(ffc->choiceType(), FormFieldChoice::ComboBox); + part.m_document->editFormCombo(0, ffc, QStringLiteral("combo2"), 3, 0, 0); + } + } + + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + QVERIFY(!part.m_document->canUndo()); + + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); + + QVERIFY(part.m_document->canRedo()); + part.m_document->redo(); + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), saveFlags)); +} + +void PartTest::testSaveAsUndoStackForms_data() +{ + QTest::addColumn("file"); + QTest::addColumn("extension"); + QTest::addColumn("saveToArchive"); + + QTest::newRow("pdf") << KDESRCDIR "data/formSamples.pdf" + << "pdf" << false; + QTest::newRow("pdfarchive") << KDESRCDIR "data/formSamples.pdf" + << "okular" << true; +} + +void PartTest::testOpenUrlArguments() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + + KParts::OpenUrlArguments args; + args.setMimeType(QStringLiteral("text/rtf")); + + part.setArguments(args); + + part.openUrl(QUrl::fromLocalFile(QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + QCOMPARE(part.arguments().mimeType(), QStringLiteral("text/rtf")); +} + +void PartTest::test388288() +{ + Okular::Part part(nullptr, nullptr, QVariantList()); + + part.openUrl(QUrl::fromLocalFile(QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + QMetaObject::invokeMethod(part.m_pageView, "slotMouseNormalToggled", Q_ARG(bool, true)); + + auto annot = new Okular::HighlightAnnotation(); + annot->setHighlightType(Okular::HighlightAnnotation::Highlight); + const Okular::NormalizedRect r(0.36, 0.16, 0.51, 0.17); + annot->setBoundingRectangle(r); + Okular::HighlightAnnotation::Quad q; + q.setCapStart(false); + q.setCapEnd(false); + q.setFeather(1.0); + q.setPoint(Okular::NormalizedPoint(r.left, r.bottom), 0); + q.setPoint(Okular::NormalizedPoint(r.right, r.bottom), 1); + q.setPoint(Okular::NormalizedPoint(r.right, r.top), 2); + q.setPoint(Okular::NormalizedPoint(r.left, r.top), 3); + annot->highlightQuads().append(q); + + part.m_document->addPageAnnotation(0, annot); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.5, height * 0.5)); + QTRY_COMPARE(part.m_pageView->cursor().shape(), Qt::OpenHandCursor); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.4, height * 0.165)); + QTRY_COMPARE(part.m_pageView->cursor().shape(), Qt::ArrowCursor); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.1, height * 0.165)); + + part.m_document->undo(); + + annot = new Okular::HighlightAnnotation(); + annot->setHighlightType(Okular::HighlightAnnotation::Highlight); + annot->setBoundingRectangle(r); + annot->highlightQuads().append(q); + + part.m_document->addPageAnnotation(0, annot); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * 0.5, height * 0.5)); + QTRY_COMPARE(part.m_pageView->cursor().shape(), Qt::OpenHandCursor); +} + +void PartTest::testCheckBoxReadOnly() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/checkbox_ro.pdf"); + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(testFile); + + // The test document uses the activation action of checkboxes + // to update the read only state. For this we need the part so that + // undo / redo activates the activation action. + + QVERIFY(part.m_document->isOpened()); + + const Okular::Page *page = part.m_document->page(0); + + QMap fields; + + // Field names in test document are: + // CBMakeRW, CBMakeRO, TargetDefaultRO, TargetDefaultRW + + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + fields.insert(ff->name(), static_cast(ff)); + } + + // First grab all fields and check that the setup is as expected. + auto cbMakeRW = dynamic_cast(fields[QStringLiteral("CBMakeRW")]); + auto cbMakeRO = dynamic_cast(fields[QStringLiteral("CBMakeRO")]); + + auto targetDefaultRW = dynamic_cast(fields[QStringLiteral("TargetDefaultRw")]); + auto targetDefaultRO = dynamic_cast(fields[QStringLiteral("TargetDefaultRo")]); + + QVERIFY(cbMakeRW); + QVERIFY(cbMakeRO); + QVERIFY(targetDefaultRW); + QVERIFY(targetDefaultRO); + + QVERIFY(!cbMakeRW->state()); + QVERIFY(!cbMakeRO->state()); + + QVERIFY(!targetDefaultRW->isReadOnly()); + QVERIFY(targetDefaultRO->isReadOnly()); + + QList btns; + btns << cbMakeRW << cbMakeRO; + + // Now check both boxes + QList btnStates; + btnStates << true << true; + + part.m_document->editFormButtons(0, btns, btnStates); + + // Read only should be inverted + QVERIFY(targetDefaultRW->isReadOnly()); + QVERIFY(!targetDefaultRO->isReadOnly()); + + // Test that undo / redo works + QVERIFY(part.m_document->canUndo()); + part.m_document->undo(); + QVERIFY(!targetDefaultRW->isReadOnly()); + QVERIFY(targetDefaultRO->isReadOnly()); + + part.m_document->redo(); + QVERIFY(targetDefaultRW->isReadOnly()); + QVERIFY(!targetDefaultRO->isReadOnly()); + + btnStates.clear(); + btnStates << false << true; + + part.m_document->editFormButtons(0, btns, btnStates); + QVERIFY(targetDefaultRW->isReadOnly()); + QVERIFY(targetDefaultRO->isReadOnly()); + + // Now set both to checked again and confirm that + // save / load works. + btnStates.clear(); + btnStates << true << true; + part.m_document->editFormButtons(0, btns, btnStates); + + QTemporaryFile saveFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + QVERIFY(saveFile.open()); + saveFile.close(); + + // Save + QVERIFY(part.saveAs(QUrl::fromLocalFile(saveFile.fileName()), Part::NoSaveAsFlags)); + part.closeUrl(); + + // Load + part.openDocument(saveFile.fileName()); + QVERIFY(part.m_document->isOpened()); + + page = part.m_document->page(0); + + fields.clear(); + + { + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + fields.insert(ff->name(), static_cast(ff)); + } + } + + cbMakeRW = dynamic_cast(fields[QStringLiteral("CBMakeRW")]); + cbMakeRO = dynamic_cast(fields[QStringLiteral("CBMakeRO")]); + + targetDefaultRW = dynamic_cast(fields[QStringLiteral("TargetDefaultRw")]); + targetDefaultRO = dynamic_cast(fields[QStringLiteral("TargetDefaultRo")]); + + QVERIFY(cbMakeRW->state()); + QVERIFY(cbMakeRO->state()); + QVERIFY(targetDefaultRW->isReadOnly()); + QVERIFY(!targetDefaultRO->isReadOnly()); +} + +void PartTest::testCrashTextEditDestroy() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/formSamples.pdf"); + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(testFile); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.widget()->findChild()->setText(QStringLiteral("HOLA")); + part.actionCollection()->action(QStringLiteral("view_toggle_forms"))->trigger(); +} + +void PartTest::testAnnotWindow() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + part.widget()->show(); + part.widget()->resize(800, 600); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->setViewportPage(0); + + QMetaObject::invokeMethod(part.m_pageView, "slotMouseNormalToggled", Q_ARG(bool, true)); + + QCOMPARE(part.m_document->currentPage(), 0u); + + // Create two distinct text annotations + Okular::Annotation *annot1 = new Okular::TextAnnotation(); + annot1->setBoundingRectangle(Okular::NormalizedRect(0.8, 0.1, 0.85, 0.15)); + annot1->setContents(QStringLiteral("Annot contents 111111")); + + Okular::Annotation *annot2 = new Okular::TextAnnotation(); + annot2->setBoundingRectangle(Okular::NormalizedRect(0.8, 0.3, 0.85, 0.35)); + annot2->setContents(QStringLiteral("Annot contents 222222")); + + // Add annot1 and annot2 to document + part.m_document->addPageAnnotation(0, annot1); + part.m_document->addPageAnnotation(0, annot2); + QVERIFY(part.m_document->page(0)->annotations().size() == 2); + + QTimer *delayResizeEventTimer = part.m_pageView->findChildren("delayResizeEventTimer").at(0); + QVERIFY(delayResizeEventTimer->isActive()); + QTest::qWait(delayResizeEventTimer->interval() * 2); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + // Double click the first annotation to open its window (move mouse for visual feedback) + const NormalizedPoint annot1pt = annot1->boundingRectangle().center(); + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * annot1pt.x, height * annot1pt.y)); + QTest::mouseDClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * annot1pt.x, height * annot1pt.y)); + QTRY_COMPARE(part.m_pageView->findChildren("AnnotWindow").size(), 1); + // Verify that the window is visible + QFrame *win1 = part.m_pageView->findChild(QStringLiteral("AnnotWindow")); + QVERIFY(!win1->visibleRegion().isEmpty()); + + // Double click the second annotation to open its window (move mouse for visual feedback) + const NormalizedPoint annot2pt = annot2->boundingRectangle().center(); + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * annot2pt.x, height * annot2pt.y)); + QTest::mouseDClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * annot2pt.x, height * annot2pt.y)); + QTRY_COMPARE(part.m_pageView->findChildren("AnnotWindow").size(), 2); + // Verify that the first window is hidden covered by the second, which is visible + QList lstWin = part.m_pageView->findChildren(QStringLiteral("AnnotWindow")); + QFrame *win2; + if (lstWin[0] == win1) { + win2 = lstWin[1]; + } else { + win2 = lstWin[0]; + } + QVERIFY(win1->visibleRegion().isEmpty()); + QVERIFY(!win2->visibleRegion().isEmpty()); + + // Double click the first annotation to raise its window (move mouse for visual feedback) + QTest::mouseMove(part.m_pageView->viewport(), QPoint(width * annot1pt.x, height * annot1pt.y)); + QTest::mouseDClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * annot1pt.x, height * annot1pt.y)); + // Verify that the second window is hidden covered by the first, which is visible + QVERIFY(!win1->visibleRegion().isEmpty()); + QVERIFY(win2->visibleRegion().isEmpty()); + + // Move annotation window 1 to partially show annotation window 2 + win1->move(QPoint(win2->pos().x(), win2->pos().y() + 50)); + // Verify that both windows are partially visible + QVERIFY(!win1->visibleRegion().isEmpty()); + QVERIFY(!win2->visibleRegion().isEmpty()); + + // Click the second annotation window to raise it (move mouse for visual feedback) + auto widget = win2->window()->childAt(win2->mapTo(win2->window(), QPoint(10, 10))); + QTest::mouseMove(win2->window(), win2->mapTo(win2->window(), QPoint(10, 10))); + QTest::mouseClick(widget, Qt::LeftButton, Qt::NoModifier, widget->mapFrom(win2, QPoint(10, 10))); + QVERIFY(win1->visibleRegion().rectCount() == 3); + QVERIFY(win2->visibleRegion().rectCount() == 4); +} + +// Helper for testAdditionalActionTriggers +static void verifyTargetStates(const QString &triggerName, const QMap &fields, bool focusVisible, bool cursorVisible, bool mouseVisible, int line) +{ + Okular::FormField *focusTarget = fields.value(triggerName + QStringLiteral("_focus_target")); + Okular::FormField *cursorTarget = fields.value(triggerName + QStringLiteral("_cursor_target")); + Okular::FormField *mouseTarget = fields.value(triggerName + QStringLiteral("_mouse_target")); + + QVERIFY(focusTarget); + QVERIFY(cursorTarget); + QVERIFY(mouseTarget); + + QTRY_VERIFY2(focusTarget->isVisible() == focusVisible, QStringLiteral("line: %1 focus for %2 not matched. Expected %3 Actual %4").arg(line).arg(triggerName).arg(focusTarget->isVisible()).arg(focusVisible).toUtf8().constData()); + QTRY_VERIFY2(cursorTarget->isVisible() == cursorVisible, QStringLiteral("line: %1 cursor for %2 not matched. Actual %3 Expected %4").arg(line).arg(triggerName).arg(cursorTarget->isVisible()).arg(cursorVisible).toUtf8().constData()); + QTRY_VERIFY2(mouseTarget->isVisible() == mouseVisible, QStringLiteral("line: %1 mouse for %2 not matched. Expected %3 Actual %4").arg(line).arg(triggerName).arg(mouseTarget->isVisible()).arg(mouseVisible).toUtf8().constData()); +} + +void PartTest::testAdditionalActionTriggers() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/additionalFormActions.pdf"); + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(testFile); + part.widget()->resize(800, 600); + + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + QTimer *delayResizeEventTimer = part.m_pageView->findChildren("delayResizeEventTimer").at(0); + QVERIFY(delayResizeEventTimer->isActive()); + QTest::qWait(delayResizeEventTimer->interval() * 2); + + part.m_document->setViewportPage(0); + + // wait for pixmap + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + + QMap fields; + // Field names in test document are: + // For trigger fields: tf, cb, rb, dd, pb + // For target fields: _focus_target, _cursor_target, + // _mouse_target + const Okular::Page *page = part.m_document->page(0); + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + fields.insert(ff->name(), static_cast(ff)); + } + + // Verify that everything is set up. + verifyTargetStates(QStringLiteral("tf"), fields, true, true, true, __LINE__); + verifyTargetStates(QStringLiteral("cb"), fields, true, true, true, __LINE__); + verifyTargetStates(QStringLiteral("rb"), fields, true, true, true, __LINE__); + verifyTargetStates(QStringLiteral("dd"), fields, true, true, true, __LINE__); + verifyTargetStates(QStringLiteral("pb"), fields, true, true, true, __LINE__); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + part.actionCollection()->action(QStringLiteral("view_toggle_forms"))->trigger(); + + QPoint tfPos(width * 0.045, height * 0.05); + QPoint cbPos(width * 0.045, height * 0.08); + QPoint rbPos(width * 0.045, height * 0.12); + QPoint ddPos(width * 0.045, height * 0.16); + QPoint pbPos(width * 0.045, height * 0.26); + + // Test text field + auto widget = part.m_pageView->viewport()->childAt(tfPos); + QVERIFY(widget); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(tfPos)); + verifyTargetStates(QStringLiteral("tf"), fields, true, false, true, __LINE__); + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("tf"), fields, false, false, false, __LINE__); + QTest::mouseRelease(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("tf"), fields, false, false, true, __LINE__); + + // Checkbox + widget = part.m_pageView->viewport()->childAt(cbPos); + QVERIFY(widget); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(cbPos)); + verifyTargetStates(QStringLiteral("cb"), fields, true, false, true, __LINE__); + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("cb"), fields, false, false, false, __LINE__); + // Confirm that the textfield no longer has any invisible + verifyTargetStates(QStringLiteral("tf"), fields, true, true, true, __LINE__); + QTest::mouseRelease(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("cb"), fields, false, false, true, __LINE__); + + // Radio + widget = part.m_pageView->viewport()->childAt(rbPos); + QVERIFY(widget); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(rbPos)); + verifyTargetStates(QStringLiteral("rb"), fields, true, false, true, __LINE__); + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("rb"), fields, false, false, false, __LINE__); + QTest::mouseRelease(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("rb"), fields, false, false, true, __LINE__); + + // Dropdown + widget = part.m_pageView->viewport()->childAt(ddPos); + QVERIFY(widget); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(ddPos)); + verifyTargetStates(QStringLiteral("dd"), fields, true, false, true, __LINE__); + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("dd"), fields, false, false, false, __LINE__); + QTest::mouseRelease(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("dd"), fields, false, false, true, __LINE__); + + // Pushbutton + widget = part.m_pageView->viewport()->childAt(pbPos); + QVERIFY(widget); + + QTest::mouseMove(part.m_pageView->viewport(), QPoint(pbPos)); + verifyTargetStates(QStringLiteral("pb"), fields, true, false, true, __LINE__); + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("pb"), fields, false, false, false, __LINE__); + QTest::mouseRelease(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("pb"), fields, false, false, true, __LINE__); + + // Confirm that a mouse release outside does not trigger the show action. + QTest::mousePress(widget, Qt::LeftButton, Qt::NoModifier, QPoint(5, 5)); + verifyTargetStates(QStringLiteral("pb"), fields, false, false, false, __LINE__); + QTest::mouseRelease(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, tfPos); + verifyTargetStates(QStringLiteral("pb"), fields, false, false, false, __LINE__); +} + +void PartTest::testTypewriterAnnotTool() +{ + Okular::Part part(nullptr, nullptr, QVariantList()); + + part.openUrl(QUrl::fromLocalFile(QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + const int width = part.m_pageView->horizontalScrollBar()->maximum() + part.m_pageView->viewport()->width(); + const int height = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + + part.m_document->setViewportPage(0); + + // Find the TypeWriter annotation + QAction *typeWriterAction = part.actionCollection()->action(QStringLiteral("annotation_typewriter")); + QVERIFY(typeWriterAction); + + typeWriterAction->trigger(); + + QTest::qWait(1000); // Wait for the "add new note" dialog to appear + TestingUtils::CloseDialogHelper closeDialogHelper(QDialogButtonBox::Ok); + + QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.5, height * 0.2)); + + Annotation *annot = part.m_document->page(0)->annotations().first(); + TextAnnotation *ta = static_cast(annot); + QVERIFY(annot); + QVERIFY(ta); + QCOMPARE(annot->subType(), Okular::Annotation::AText); + QCOMPARE(annot->style().color(), QColor(255, 255, 255, 0)); + QCOMPARE(ta->textType(), Okular::TextAnnotation::InPlace); + QCOMPARE(ta->inplaceIntent(), Okular::TextAnnotation::TypeWriter); +} + +void PartTest::testJumpToPage() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"); + const int targetPage = 25; + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(testFile); + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + part.m_document->pages(); + part.m_document->setViewportPage(targetPage); + + /* Document::setViewportPage triggers pixmap rendering in another thread. + * We want to test how things look AFTER finished signal arrives back, + * because PageView::slotRelayoutPages may displace the viewport again. + */ + QTRY_VERIFY(part.m_document->page(targetPage)->hasPixmap(part.m_pageView)); + + const int contentAreaHeight = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + const int pageWithSpaceTop = contentAreaHeight / part.m_document->pages() * targetPage; + + /* + * This is a test for a "known by trial" displacement. + * We'd need access to part.m_pageView->d->items[targetPage]->croppedGeometry().top(), + * to determine the expected viewport position, but we don't have access. + */ + QCOMPARE(part.m_pageView->verticalScrollBar()->value(), pageWithSpaceTop - 4); +} + +void PartTest::testOpenAtPage() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"); + QUrl url = QUrl::fromLocalFile(testFile); + Okular::Part part(nullptr, nullptr, QVariantList()); + + const uint targetPageNumA = 25; + const uint expectedPageA = targetPageNumA - 1; + url.setFragment(QString::number(targetPageNumA)); + part.openUrl(url); + QCOMPARE(part.m_document->currentPage(), expectedPageA); + + // 'page=' param as specified in RFC 3778 + const uint targetPageNumB = 15; + const uint expectedPageB = targetPageNumB - 1; + url.setFragment("page=" + QString::number(targetPageNumB)); + part.openUrl(url); + QCOMPARE(part.m_document->currentPage(), expectedPageB); +} + +void PartTest::testForwardBackwardNavigation() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/simple-multipage.pdf"); + Okular::Part part(nullptr, nullptr, QVariantList()); + part.openDocument(testFile); + part.widget()->resize(800, 600); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + + // Go to some page + const int targetPageA = 15; + part.m_document->setViewportPage(targetPageA); + + QVERIFY(part.m_document->viewport() == targetPageA); + + // Go to some other page + const int targetPageB = 25; + part.m_document->setViewportPage(targetPageB); + QVERIFY(part.m_document->viewport() == targetPageB); + + // Go back to page A + QVERIFY(QMetaObject::invokeMethod(&part, "slotHistoryBack")); + QVERIFY(part.m_document->viewport().pageNumber == targetPageA); + + // Go back to page B + QVERIFY(QMetaObject::invokeMethod(&part, "slotHistoryNext")); + QVERIFY(part.m_document->viewport().pageNumber == targetPageB); +} + +void PartTest::testTabletProximityBehavior() +{ + QVariantList dummyArgs; + Okular::Part part {nullptr, nullptr, dummyArgs}; + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + part.slotShowPresentation(); + PresentationWidget *w = part.m_presentationWidget; + QVERIFY(w); + part.widget()->show(); + + // close the KMessageBox "There are two ways of exiting[...]" + TestingUtils::CloseDialogHelper closeDialogHelper(w, QDialogButtonBox::Ok); // confirm the "To leave, press ESC" + + QTabletEvent enterProximityEvent {QEvent::TabletEnterProximity, QPoint(10, 10), QPoint(10, 10), QTabletEvent::Stylus, QTabletEvent::Pen, 1., 0, 0, 1., 1., 0, Qt::NoModifier, 0, Qt::NoButton, Qt::NoButton}; + QTabletEvent leaveProximityEvent {QEvent::TabletLeaveProximity, QPoint(10, 10), QPoint(10, 10), QTabletEvent::Stylus, QTabletEvent::Pen, 1., 0, 0, 1., 1., 0, Qt::NoModifier, 0, Qt::NoButton, Qt::NoButton}; + + // Test with the Okular::Settings::EnumSlidesCursor::Visible setting + Okular::Settings::self()->setSlidesCursor(Okular::Settings::EnumSlidesCursor::Visible); + + // Send an enterProximity event + qApp->notify(qApp, &enterProximityEvent); + + // The cursor should be a cross-hair + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::CrossCursor)); + + // Send a leaveProximity event + qApp->notify(qApp, &leaveProximityEvent); + + // After the leaveProximityEvent, the cursor should be an arrow again, because + // we have set the slidesCursor mode to 'Visible' + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::ArrowCursor)); + + // Test with the Okular::Settings::EnumSlidesCursor::Hidden setting + Okular::Settings::self()->setSlidesCursor(Okular::Settings::EnumSlidesCursor::Hidden); + + qApp->notify(qApp, &enterProximityEvent); + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::CrossCursor)); + qApp->notify(qApp, &leaveProximityEvent); + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::BlankCursor)); + + // Moving the mouse should not bring the cursor back + QTest::mouseMove(w, QPoint(100, 100)); + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::BlankCursor)); + + // First test with the Okular::Settings::EnumSlidesCursor::HiddenDelay setting + Okular::Settings::self()->setSlidesCursor(Okular::Settings::EnumSlidesCursor::HiddenDelay); + + qApp->notify(qApp, &enterProximityEvent); + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::CrossCursor)); + qApp->notify(qApp, &leaveProximityEvent); + + // After the leaveProximityEvent, the cursor should be blank, because + // we have set the slidesCursor mode to 'HiddenDelay' + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::BlankCursor)); + + // Moving the mouse should bring the cursor back + QTest::mouseMove(w, QPoint(150, 150)); + QVERIFY(w->cursor().shape() == Qt::CursorShape(Qt::ArrowCursor)); +} + +void PartTest::testOpenPrintPreview() +{ + QVariantList dummyArgs; + Okular::Part part {nullptr, nullptr, dummyArgs}; + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + TestingUtils::CloseDialogHelper closeDialogHelper(QDialogButtonBox::Close); + part.slotPrintPreview(); +} + +void PartTest::testMouseModeMenu() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file1.pdf"))); + + QMetaObject::invokeMethod(part.m_pageView, "slotSetMouseNormal"); + + // Get mouse mode menu action + QAction *mouseModeAction = part.actionCollection()->action(QStringLiteral("mouse_selecttools")); + QVERIFY(mouseModeAction); + QMenu *mouseModeActionMenu = mouseModeAction->menu(); + + // Test that actions are usable (not disabled) + QVERIFY(mouseModeActionMenu->actions().at(0)->isEnabled()); + QVERIFY(mouseModeActionMenu->actions().at(1)->isEnabled()); + QVERIFY(mouseModeActionMenu->actions().at(2)->isEnabled()); + + // Test activating area selection mode + mouseModeActionMenu->actions().at(0)->trigger(); + QCOMPARE(Okular::Settings::mouseMode(), (int)Okular::Settings::EnumMouseMode::RectSelect); + + // Test activating text selection mode + mouseModeActionMenu->actions().at(1)->trigger(); + QCOMPARE(Okular::Settings::mouseMode(), (int)Okular::Settings::EnumMouseMode::TextSelect); + + // Test activating table selection mode + mouseModeActionMenu->actions().at(2)->trigger(); + QCOMPARE(Okular::Settings::mouseMode(), (int)Okular::Settings::EnumMouseMode::TableSelect); +} + +void PartTest::testFullScreenRequest() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + + // Open file. For this particular file, a dialog has to appear asking whether + // one wants to comply with the wish to go to presentation mode directly. + // Answer 'no' + auto dialogHelper = std::make_unique(&part, QDialogButtonBox::No); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/RequestFullScreen.pdf"))); + + // Check that we are not in presentation mode + QEXPECT_FAIL("", "The presentation widget should not be shown because we clicked No in the dialog", Continue); + QTRY_VERIFY_WITH_TIMEOUT(part.m_presentationWidget, 1000); + + // Reload the file. The initial dialog should no appear again. + // (This is https://bugs.kde.org/show_bug.cgi?id=361740) + part.reload(); + + // Open the file again. Now we answer "yes, go to presentation mode" + dialogHelper = std::make_unique(&part, QDialogButtonBox::Yes); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/RequestFullScreen.pdf"))); + + // Test whether we really are in presentation mode + QTRY_VERIFY(part.m_presentationWidget); +} + +void PartTest::testZoomInFacingPages() +{ + QVariantList dummyArgs; + Okular::Part part(nullptr, nullptr, dummyArgs); + QVERIFY(openDocument(&part, QStringLiteral(KDESRCDIR "data/file2.pdf"))); + QAction *facingAction = part.m_pageView->findChild(QStringLiteral("view_render_mode_facing")); + KSelectAction *zoomSelectAction = part.m_pageView->findChild(QStringLiteral("zoom_to")); + part.widget()->resize(600, 400); + part.widget()->show(); + QVERIFY(QTest::qWaitForWindowExposed(part.widget())); + facingAction->trigger(); + while (zoomSelectAction->currentText() != "12%") { + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomOut")); + } + QTRY_VERIFY(part.m_document->page(0)->hasPixmap(part.m_pageView)); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomIn")); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomIn")); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomIn")); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomIn")); + QVERIFY(QMetaObject::invokeMethod(part.m_pageView, "slotZoomIn")); + QTRY_COMPARE(zoomSelectAction->currentText(), QStringLiteral("66%")); +} + +} // namespace Okular + +int main(int argc, char *argv[]) +{ + // Force consistent locale + QLocale locale(QStringLiteral("en_US.UTF-8")); + if (locale == QLocale::c()) { // This is the way to check if the above worked + locale = QLocale(QLocale::English, QLocale::UnitedStates); + } + + QLocale::setDefault(locale); + qputenv("LC_ALL", "en_US.UTF-8"); // For UNIX, third-party libraries + + // Ensure consistent configs/caches + QTemporaryDir homeDir; // QTemporaryDir automatically cleans up when it goes out of scope + Q_ASSERT(homeDir.isValid()); + QByteArray homePath = QFile::encodeName(homeDir.path()); + qDebug() << homePath; + qputenv("USERPROFILE", homePath); + qputenv("HOME", homePath); + qputenv("XDG_DATA_HOME", homePath + "/.local"); + qputenv("XDG_CONFIG_HOME", homePath + "/.kde-unit-test/xdg/config"); + + // Disable fancy debug output + qunsetenv("QT_MESSAGE_PATTERN"); + + QApplication app(argc, argv); + app.setApplicationName(QStringLiteral("okularparttest")); + app.setOrganizationDomain(QStringLiteral("kde.org")); + app.setQuitOnLastWindowClosed(false); + + qRegisterMetaType(); /*as done by kapplication*/ + qRegisterMetaType>(); + + Okular::PartTest test; + + return QTest::qExec(&test, argc, argv); +} + +#include "parttest.moc" diff --git a/autotests/searchtest.cpp b/autotests/searchtest.cpp new file mode 100644 index 0000000..333f42d --- /dev/null +++ b/autotests/searchtest.cpp @@ -0,0 +1,432 @@ +/*************************************************************************** + * Copyright (C) 2013 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +// clazy:excludeall=qstring-allocations + +#include + +#include "../core/document.h" +#include "../core/page.h" +#include "../core/textpage.h" +#include "../settings_core.h" + +Q_DECLARE_METATYPE(Okular::Document::SearchStatus) + +class SearchFinishedReceiver : public QObject +{ + Q_OBJECT + +public slots: + void searchFinished(int id, Okular::Document::SearchStatus status) + { + m_id = id; + m_status = status; + } + +public: + int m_id; + Okular::Document::SearchStatus m_status; +}; + +class SearchTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testNextAndPrevious(); + void test311232(); + void test323262(); + void test323263(); + void test430243(); + void testDottedI(); + void testHyphenAtEndOfLineWithoutYOverlap(); + void testHyphenWithYOverlap(); + void testHyphenAtEndOfPage(); + void testOneColumn(); + void testTwoColumns(); +}; + +void SearchTest::initTestCase() +{ + qRegisterMetaType(); + Okular::SettingsCore::instance(QStringLiteral("searchtest")); +} + +static void createTextPage(const QVector &text, const QVector &rect, Okular::TextPage *&tp, Okular::Page *&page) +{ + tp = new Okular::TextPage(); + for (int i = 0; i < text.size(); i++) { + tp->append(text[i], new Okular::NormalizedRect(rect[i])); + } + + // The Page::setTextPage method invokes the layout analysis algorithms tested by some tests here + // and also sets the tp->d->m_page field (the latter was used in older versions of Okular by + // TextPage::stringLengthAdaptedWithHyphen). + // Note that calling "delete page;" will delete the TextPage as well. + page = new Okular::Page(1, 100, 100, Okular::Rotation0); + page->setTextPage(tp); +} + +#define CREATE_PAGE \ + QCOMPARE(text.size(), rect.size()); \ + Okular::Page *page; \ + Okular::TextPage *tp; \ + createTextPage(text, rect, tp, page); + +#define TEST_NEXT_PREV(searchType, expectedStatus) \ + { \ + Okular::RegularAreaRect *result = tp->findText(0, searchString, searchType, Qt::CaseSensitive, NULL); \ + QCOMPARE(!!result, expectedStatus); \ + delete result; \ + } + +// The test testNextAndPrevious checks that +// a) if one starts a new search, then the first or last match is found, depending on the search direction +// (2 cases: FromTop/FromBottom) +// b) if the last search has found a match, +// then clicking the "Next" button moves to the next occurrence an "Previous" to the previous one +// (if there is any). Altogether there are four combinations of the last search and new search +// direction: Next-Next, Previous-Previous, Next-Previous, Previous-Next; the first two combination +// have two subcases (the new search may give a match or not, so altogether 6 cases to test). +// This gives 8 cases altogether. By taking into account the cases where the last search has given no match, +// we would have 4 more cases (Next (no match)-Next, Next (no match)-Previous, Previous (no match)-Previous, +// Previous (no match)-Next), but those are more the business of Okular::Document::searchText rather than +// Okular::TextPage (at least in the multi-page case). + +// We have four test situations: four documents and four corresponding search strings. +// The first situation (document="ababa", search string="b") is a generic one where the +// two matches are not side-by-side and neither the first character nor the last character of +// the document match. The only special thing is that the search string has only length 1. +// The second situation (document="abab", search string="ab") is notable for that the two occurrences +// of the search string are side-by-side with no characters in between, so some off-by-one errors +// would be detected by this test. As the first match starts at the beginning at the document the +// last match ends at the end of the document, it also detects off-by-one errors for finding the first/last match. +// The third situation (document="abababa", search string="aba") is notable for it shows whether +// the next match is allowed to contain letters from the previous one: currently it is not +//(as in the majority of browsers, viewers and editors), and therefore "abababa" is considered to +// contain not three but two occurrences of "aba" (if one starts search from the beginning of the document). +// The fourth situation (document="a ba b", search string="a b") demonstrates the case when one TinyTextEntity +// contains multiple characters that are contained in different matches (namely, the middle "ba" is one TinyTextEntity); +// in particular, since these matches are side-by-side, this test would detect some off-by-one +// offset errors. + +void SearchTest::testNextAndPrevious() +{ +#define TEST_NEXT_PREV_SITUATION_COUNT 4 + + QVector texts[TEST_NEXT_PREV_SITUATION_COUNT] = {QVector() << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("a"), + QVector() << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("a") << QStringLiteral("b"), + QVector() << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("a") << QStringLiteral("b") + << QStringLiteral("a"), + QVector() << QStringLiteral("a") << QStringLiteral(" ") << QStringLiteral("ba") << QStringLiteral(" ") << QStringLiteral("b")}; + + QString searchStrings[TEST_NEXT_PREV_SITUATION_COUNT] = {QStringLiteral("b"), QStringLiteral("ab"), QStringLiteral("aba"), QStringLiteral("a b")}; + + for (int i = 0; i < TEST_NEXT_PREV_SITUATION_COUNT; i++) { + const QVector &text = texts[i]; + const QString &searchString = searchStrings[i]; + + QVector rect; + + for (int i = 0; i < text.size(); i++) { + rect << Okular::NormalizedRect(0.1 * i, 0.0, 0.1 * (i + 1), 0.1); + } + + CREATE_PAGE; + + // Test 3 of the 8 cases listed above: + // FromTop, Next-Next (match) and Next-Next (no match) + TEST_NEXT_PREV(Okular::FromTop, true); + TEST_NEXT_PREV(Okular::NextResult, true); + TEST_NEXT_PREV(Okular::NextResult, false); + + // Test 5 cases: FromBottom, Previous-Previous (match), Previous-Next, + // Next-Previous, Previous-Previous (no match) + TEST_NEXT_PREV(Okular::FromBottom, true); + TEST_NEXT_PREV(Okular::PreviousResult, true); + TEST_NEXT_PREV(Okular::NextResult, true); + TEST_NEXT_PREV(Okular::PreviousResult, true); + TEST_NEXT_PREV(Okular::PreviousResult, false); + + delete page; + } +} + +void SearchTest::test311232() +{ + Okular::Document d(nullptr); + SearchFinishedReceiver receiver; + QSignalSpy spy(&d, &Okular::Document::searchFinished); + + QObject::connect(&d, &Okular::Document::searchFinished, &receiver, &SearchFinishedReceiver::searchFinished); + + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + d.openDocument(testFile, QUrl(), mime); + + const int searchId = 0; + d.searchText(searchId, QStringLiteral(" i "), true, Qt::CaseSensitive, Okular::Document::NextMatch, false, QColor()); + QTRY_COMPARE(spy.count(), 1); + QCOMPARE(receiver.m_id, searchId); + QCOMPARE(receiver.m_status, Okular::Document::MatchFound); + + d.continueSearch(searchId, Okular::Document::PreviousMatch); + QTRY_COMPARE(spy.count(), 2); + QCOMPARE(receiver.m_id, searchId); + QCOMPARE(receiver.m_status, Okular::Document::NoMatchFound); +} + +void SearchTest::test323262() +{ + QVector text; + text << QStringLiteral("a\n"); + + QVector rect; + rect << Okular::NormalizedRect(1, 2, 3, 4); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("a"), Okular::FromBottom, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + + delete page; +} + +void SearchTest::test323263() +{ + QVector text; + text << QStringLiteral("a") << QStringLiteral("a") << QStringLiteral("b"); + + QVector rect; + rect << Okular::NormalizedRect(0, 0, 1, 1) << Okular::NormalizedRect(1, 0, 2, 1) << Okular::NormalizedRect(2, 0, 3, 1); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("ab"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + Okular::RegularAreaRect expected; + expected.append(rect[1]); + expected.append(rect[2]); + expected.simplify(); + QCOMPARE(*result, expected); + delete result; + + delete page; +} + +void SearchTest::test430243() +{ + // 778 is COMBINING RING ABOVE + // 197 is LATIN CAPITAL LETTER A WITH RING ABOVE + QVector text; + text << QStringLiteral("A") << QString(QChar(778)); + + QVector rect; + rect << Okular::NormalizedRect(0, 0, 1, 1) << Okular::NormalizedRect(1, 0, 2, 1); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QString(QChar(197)), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + Okular::RegularAreaRect expected; + expected.append(rect[0] | rect[1]); + QCOMPARE(*result, expected); + delete result; + + delete page; +} + +void SearchTest::testDottedI() +{ + // Earlier versions of okular had the bug that the letter "İ" (capital dotter i) did not match itself + // in case-insensitive mode (this was caused by an unnecessary call of toLower() and the fact that + // QString::fromUtf8("İ").compare(QString::fromUtf8("İ").toLower(), Qt::CaseInsensitive) == FALSE, + // at least in Qt 4.8). + + // In the future it would be nice to add support for matching "İ"<->"i" and "I"<->"ı" in case-insensitive + // mode as well (QString::compare does not match them, at least in non-Turkish locales, since it follows + // the Unicode case-folding rules https://www.unicode.org/Public/6.2.0/ucd/CaseFolding.txt). + + QVector text; + text << QStringLiteral("İ"); + + QVector rect; + rect << Okular::NormalizedRect(1, 2, 3, 4); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("İ"), Okular::FromTop, Qt::CaseInsensitive, nullptr); + QVERIFY(result); + delete result; + + delete page; +} + +void SearchTest::testHyphenAtEndOfLineWithoutYOverlap() +{ + QVector text; + text << QStringLiteral("super-") << QStringLiteral("cali-\n") << QStringLiteral("fragilistic") << QStringLiteral("-") << QStringLiteral("expiali") << QStringLiteral("-\n") << QStringLiteral("docious"); + + QVector rect; + rect << Okular::NormalizedRect(0.4, 0.0, 0.9, 0.1) << Okular::NormalizedRect(0.0, 0.1, 0.6, 0.2) << Okular::NormalizedRect(0.0, 0.2, 0.8, 0.3) << Okular::NormalizedRect(0.8, 0.2, 0.9, 0.3) << Okular::NormalizedRect(0.0, 0.3, 0.8, 0.4) + << Okular::NormalizedRect(0.8, 0.3, 0.9, 0.4) << Okular::NormalizedRect(0.0, 0.4, 0.7, 0.5); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("supercalifragilisticexpialidocious"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + Okular::RegularAreaRect expected; + for (int i = 0; i < text.size(); i++) { + expected.append(rect[i]); + } + expected.simplify(); + QCOMPARE(*result, expected); + delete result; + + result = tp->findText(0, QStringLiteral("supercalifragilisticexpialidocious"), Okular::FromBottom, Qt::CaseSensitive, nullptr); + QVERIFY(result); + QCOMPARE(*result, expected); + delete result; + + // If the user is looking for the text explicitly with the hyphen also find it + result = tp->findText(0, QStringLiteral("super-cali-fragilistic"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + + // If the user is looking for the text explicitly with the hyphen also find it + result = tp->findText(0, QStringLiteral("super-cali-fragilistic"), Okular::FromBottom, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + + delete page; +} + +#define CREATE_PAGE_AND_TEST_SEARCH(searchString, matchExpected) \ + { \ + CREATE_PAGE; \ + \ + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral(searchString), Okular::FromTop, Qt::CaseSensitive, NULL); \ + \ + QCOMPARE(!!result, matchExpected); \ + \ + delete result; \ + delete page; \ + } + +void SearchTest::testHyphenWithYOverlap() +{ + QVector text; + text << QStringLiteral("a-") << QStringLiteral("b"); + + QVector rect(2); + + // different lines (50% y-coordinate overlap), first rectangle has larger height + rect[0] = Okular::NormalizedRect(0.0, 0.0, 0.9, 0.35); + rect[1] = Okular::NormalizedRect(0.0, 0.3, 0.2, 0.4); + CREATE_PAGE_AND_TEST_SEARCH("ab", true); + + // different lines (50% y-coordinate overlap), second rectangle has larger height + rect[0] = Okular::NormalizedRect(0.0, 0.0, 0.9, 0.1); + rect[1] = Okular::NormalizedRect(0.0, 0.05, 0.2, 0.4); + CREATE_PAGE_AND_TEST_SEARCH("ab", true); + + // same line (90% y-coordinate overlap), first rectangle has larger height + rect[0] = Okular::NormalizedRect(0.0, 0.0, 0.4, 0.2); + rect[1] = Okular::NormalizedRect(0.4, 0.11, 0.6, 0.21); + CREATE_PAGE_AND_TEST_SEARCH("ab", false); + CREATE_PAGE_AND_TEST_SEARCH("a-b", true); + + // same line (90% y-coordinate overlap), second rectangle has larger height + rect[0] = Okular::NormalizedRect(0.0, 0.0, 0.4, 0.1); + rect[1] = Okular::NormalizedRect(0.4, 0.01, 0.6, 0.2); + CREATE_PAGE_AND_TEST_SEARCH("ab", false); + CREATE_PAGE_AND_TEST_SEARCH("a-b", true); +} + +void SearchTest::testHyphenAtEndOfPage() +{ + // Tests for segmentation fault that would occur if + // we tried look ahead (for determining whether the + // next character is at the same line) at the end of the page. + + QVector text; + text << QStringLiteral("a-"); + + QVector rect; + rect << Okular::NormalizedRect(0, 0, 1, 1); + + CREATE_PAGE; + + { + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("a"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + } + + { + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("a"), Okular::FromBottom, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + } + + delete page; +} + +void SearchTest::testOneColumn() +{ + // Tests that the layout analysis algorithm does not create too many columns. + // Bug 326207 was caused by the fact that if all the horizontal breaks in a line + // had the same length and were smaller than vertical breaks between lines then + // the horizontal breaks were treated as column separators. + //(Note that "same length" means "same length after rounding rectangles to integer pixels". + // The resolution used by the XY Cut algorithm with a square page is 1000 x 1000, + // and the horizontal spaces in the example are 0.1, so they are indeed both exactly 100 pixels.) + + QVector text; + text << QStringLiteral("Only") << QStringLiteral("one") << QStringLiteral("column") << QStringLiteral("here"); + + // characters and line breaks have length 0.05, word breaks 0.1 + QVector rect; + rect << Okular::NormalizedRect(0.0, 0.0, 0.2, 0.1) << Okular::NormalizedRect(0.3, 0.0, 0.5, 0.1) << Okular::NormalizedRect(0.6, 0.0, 0.9, 0.1) << Okular::NormalizedRect(0.0, 0.15, 0.2, 0.25); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("Only one column"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(result); + delete result; + + delete page; +} + +void SearchTest::testTwoColumns() +{ + // Tests that the layout analysis algorithm can detect two columns. + + QVector text; + text << QStringLiteral("This") << QStringLiteral("text") << QStringLiteral("in") << QStringLiteral("two") << QStringLiteral("is") << QStringLiteral("set") << QStringLiteral("columns."); + + // characters, word breaks and line breaks have length 0.05 + QVector rect; + rect << Okular::NormalizedRect(0.0, 0.0, 0.20, 0.1) << Okular::NormalizedRect(0.25, 0.0, 0.45, 0.1) << Okular::NormalizedRect(0.6, 0.0, 0.7, 0.1) << Okular::NormalizedRect(0.75, 0.0, 0.9, 0.1) + << Okular::NormalizedRect(0.0, 0.15, 0.1, 0.25) << Okular::NormalizedRect(0.15, 0.15, 0.3, 0.25) << Okular::NormalizedRect(0.6, 0.15, 1.0, 0.25); + + CREATE_PAGE; + + Okular::RegularAreaRect *result = tp->findText(0, QStringLiteral("This text in"), Okular::FromTop, Qt::CaseSensitive, nullptr); + QVERIFY(!result); + delete result; + + delete page; +} + +QTEST_MAIN(SearchTest) +#include "searchtest.moc" diff --git a/autotests/shelltest.cpp b/autotests/shelltest.cpp new file mode 100644 index 0000000..43aceb6 --- /dev/null +++ b/autotests/shelltest.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2009 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. * + ***************************************************************************/ + +#include + +#include +#include + +#include "../shell/shellutils.h" + +static const QUrl makeUrlFromCwd(const QString &u, const QString &ref = QString()) +{ + QUrl url = QUrl::fromLocalFile(QDir::currentPath() + QLatin1Char('/') + u); + if (!ref.isEmpty()) + url.setFragment(ref); + url.setPath(QDir::cleanPath(url.path())); + return url; +} + +static bool fileExist_always_Func(const QString &) +{ + return true; +} + +static bool fileExist_never_Func(const QString &) +{ + return false; +} + +class ShellTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testUrlArgs_data(); + void testUrlArgs(); +}; + +void ShellTest::initTestCase() +{ + qRegisterMetaType(); +} + +void ShellTest::testUrlArgs_data() +{ + QTest::addColumn("arg"); + QTest::addColumn("exists"); + QTest::addColumn("resUrl"); + + // local files + QTest::newRow("foo.pdf, exist") << "foo.pdf" << true << makeUrlFromCwd(QStringLiteral("foo.pdf")); + QTest::newRow("foo.pdf, !exist") << "foo.pdf" << false << makeUrlFromCwd(QStringLiteral("foo.pdf")); + QTest::newRow("foo#bar.pdf, exist") << "foo#bar.pdf" << true << makeUrlFromCwd(QStringLiteral("foo#bar.pdf")); + QTest::newRow("foo#bar.pdf, !exist") << "foo#bar.pdf" << false << makeUrlFromCwd(QStringLiteral("foo"), QStringLiteral("bar.pdf")); + QTest::newRow("foo.pdf#anchor, !exist") << "foo.pdf#anchor" << false << makeUrlFromCwd(QStringLiteral("foo.pdf"), QStringLiteral("anchor")); + QTest::newRow("#207461") << "file:///tmp/file%20with%20spaces.pdf" << true << QUrl(QStringLiteral("file:///tmp/file%20with%20spaces.pdf")); + + // non-local files + QTest::newRow("http://kde.org/foo.pdf") << "http://kde.org/foo.pdf" << true << QUrl(QStringLiteral("http://kde.org/foo.pdf")); + QUrl withAnchor(QStringLiteral("http://kde.org/foo.pdf")); + withAnchor.setFragment(QStringLiteral("anchor")); + QTest::newRow("http://kde.org/foo.pdf#anchor") << "http://kde.org/foo.pdf#anchor" << true << withAnchor; + QTest::newRow("#207461") << "http://homepages.inf.ed.ac.uk/mef/file%20with%20spaces.pdf" << true << QUrl(QStringLiteral("http://homepages.inf.ed.ac.uk/mef/file%20with%20spaces.pdf")); + QUrl openOnPage3 = QUrl(QStringLiteral("http://itzsimpl.info/lectures/CG/L2-transformations.pdf")); + openOnPage3.setFragment(QStringLiteral("3")); + QTest::newRow("RR124738") << "http://itzsimpl.info/lectures/CG/L2-transformations.pdf#3" << true << openOnPage3; +} + +void ShellTest::testUrlArgs() +{ + QFETCH(QString, arg); + QFETCH(bool, exists); + QFETCH(QUrl, resUrl); + qDebug() << "Expected url:" << resUrl << "path =" << resUrl.path() << "fragment =" << resUrl.fragment(); + QUrl url = ShellUtils::urlFromArg(arg, exists ? fileExist_always_Func : fileExist_never_Func); + QCOMPARE(url, resUrl); +} + +QTEST_GUILESS_MAIN(ShellTest) +#include "shelltest.moc" diff --git a/autotests/signatureformtest.cpp b/autotests/signatureformtest.cpp new file mode 100644 index 0000000..2e63ae5 --- /dev/null +++ b/autotests/signatureformtest.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include + +#include +#include + +#include "../settings_core.h" +#include +#include +#include + +class SignatureFormTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void testSignatureForm(); + +private: + Okular::Document *m_document; +}; + +void SignatureFormTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("signatureformtest")); + m_document = new Okular::Document(nullptr); +} + +void SignatureFormTest::cleanupTestCase() +{ + delete m_document; +} + +void SignatureFormTest::testSignatureForm() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/pdf_with_signature.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + const Okular::Page *page = m_document->page(0); + QLinkedList pageFields = page->formFields(); + QCOMPARE(pageFields.size(), 1); + QCOMPARE(pageFields.first()->type(), Okular::FormField::FormSignature); + + Okular::FormFieldSignature *sf = static_cast(pageFields.first()); + QCOMPARE(sf->signatureType(), Okular::FormFieldSignature::AdbePkcs7detached); +} + +QTEST_MAIN(SignatureFormTest) +#include "signatureformtest.moc" diff --git a/autotests/testingutils.cpp b/autotests/testingutils.cpp new file mode 100644 index 0000000..19e6379 --- /dev/null +++ b/autotests/testingutils.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include "testingutils.h" +#include "core/annotations.h" + +namespace TestingUtils +{ +QString getAnnotationXml(const Okular::Annotation *annotation) +{ + QString annotXmlString; + QTextStream stream(&annotXmlString, QIODevice::Append); + annotation->getAnnotationPropertiesDomNode().save(stream, 0); + return annotXmlString; +} + +bool pointListsAlmostEqual(const QLinkedList &points1, const QLinkedList &points2) +{ + QLinkedListIterator it1(points1); + QLinkedListIterator it2(points2); + while (it1.hasNext() && it2.hasNext()) { + const Okular::NormalizedPoint &p1 = it1.next(); + const Okular::NormalizedPoint &p2 = it2.next(); + if (!qFuzzyCompare(p1.x, p2.x) || !qFuzzyCompare(p1.y, p2.y)) { + return false; + } + } + return !it1.hasNext() && !it2.hasNext(); +} + +QString AnnotationDisposeWatcher::m_disposedAnnotationName = QString(); // krazy:exclude=nullstrassign + +QString AnnotationDisposeWatcher::disposedAnnotationName() +{ + return m_disposedAnnotationName; +} + +void AnnotationDisposeWatcher::resetDisposedAnnotationName() +{ + m_disposedAnnotationName = QString(); +} + +void AnnotationDisposeWatcher::disposeAnnotation(const Okular::Annotation *ann) +{ + m_disposedAnnotationName = ann->uniqueName(); +} + +} diff --git a/autotests/testingutils.h b/autotests/testingutils.h new file mode 100644 index 0000000..9766882 --- /dev/null +++ b/autotests/testingutils.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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_TESTINGUTILS_H +#define OKULAR_TESTINGUTILS_H + +template class QLinkedList; +class QString; + +namespace Okular +{ +class NormalizedPoint; +class Annotation; +} + +namespace TestingUtils +{ +/** + * Return the XML string associated with an annotation's properties + */ +QString getAnnotationXml(const Okular::Annotation *annotation); + +/** + * Returns true if the pairwise comparison coordinates of points in @p points1 and @p points2 are almost + * equal (according to qFuzzyCompare) + */ +bool pointListsAlmostEqual(const QLinkedList &points1, const QLinkedList &points2); + +/* + * The AnnotationDisposeWatcher class provides a static disposeAnnotation function + * that may be assigned to an annotation with Annotation::setDisposeDataFunction in order to + * determine when an annotation has been disposed of. + */ +class AnnotationDisposeWatcher +{ +private: + static QString m_disposedAnnotationName; + +public: + static QString disposedAnnotationName(); + static void resetDisposedAnnotationName(); + static void disposeAnnotation(const Okular::Annotation *ann); +}; + +} + +#endif diff --git a/autotests/translateannotationtest.cpp b/autotests/translateannotationtest.cpp new file mode 100644 index 0000000..d0421d7 --- /dev/null +++ b/autotests/translateannotationtest.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2013 by Jon Mease * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/annotations.h" +#include "core/document.h" +#include "testingutils.h" +#include +#include + +Okular::LineAnnotation *getNewLineAnnotation(double startX, double startY, double endX, double endY) +{ + Okular::LineAnnotation *line = new Okular::LineAnnotation; + line->setLinePoints(QLinkedList() << Okular::NormalizedPoint(startX, startY) << Okular::NormalizedPoint(endX, endY)); + + double left = qMin(startX, endX); + double top = qMin(startY, endY); + double right = qMax(startX, endX); + double bottom = qMax(startY, endY); + + line->setBoundingRectangle(Okular::NormalizedRect(left, top, right, bottom)); + return line; +} + +class TranslateAnnotationTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + void testTranslateAnnotation(); + void testSequentialTranslationsMergedIfBeingMovedIsSet(); + void testSequentialTranslationsNotMergedIfBeingMovedIsNotSet(); + void testAlternateTranslationsNotMerged(); + +private: + Okular::Document *m_document; + Okular::LineAnnotation *m_annot1; + Okular::LineAnnotation *m_annot2; + + Okular::NormalizedPoint m_deltaA; + Okular::NormalizedPoint m_deltaB; + + QLinkedList m_origPoints1; + QLinkedList m_origPoints2; + + QLinkedList m_points1DeltaA; + QLinkedList m_points1DeltaAB; + QLinkedList m_points2DeltaA; + QLinkedList m_points2DeltaAB; +}; + +void TranslateAnnotationTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("editannotationcontentstest")); + m_document = new Okular::Document(nullptr); + + // translate m_annot1 + m_deltaA = Okular::NormalizedPoint(0.05, 0.1); + m_deltaB = Okular::NormalizedPoint(0.1, 0.2); + + // Build lists of expected points for various states + m_origPoints1 = QLinkedList() << Okular::NormalizedPoint(0.1, 0.1) << Okular::NormalizedPoint(0.2, 0.3); + + m_points1DeltaA = QLinkedList() << Okular::NormalizedPoint(0.15, 0.2) << Okular::NormalizedPoint(0.25, 0.4); + + m_points1DeltaAB = QLinkedList() << Okular::NormalizedPoint(0.25, 0.4) << Okular::NormalizedPoint(0.35, 0.6); + + m_origPoints2 = QLinkedList() << Okular::NormalizedPoint(0.1, 0.1) << Okular::NormalizedPoint(0.3, 0.4); + + m_points2DeltaA = QLinkedList() << Okular::NormalizedPoint(0.15, 0.2) << Okular::NormalizedPoint(0.35, 0.5); + + m_points2DeltaAB = QLinkedList() << Okular::NormalizedPoint(0.25, 0.4) << Okular::NormalizedPoint(0.45, 0.7); +} + +void TranslateAnnotationTest::cleanupTestCase() +{ + delete m_document; +} + +void TranslateAnnotationTest::init() +{ + const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + // Undo and Redo should be unavailable when docuemnt is first opened. + QVERIFY(!m_document->canUndo()); + QVERIFY(!m_document->canRedo()); + + // Create two distinct line annotations and add them to the document + m_annot1 = getNewLineAnnotation(m_origPoints1.first().x, m_origPoints1.first().y, m_origPoints1.last().x, m_origPoints1.last().y); + m_document->addPageAnnotation(0, m_annot1); + + m_annot2 = getNewLineAnnotation(m_origPoints2.first().x, m_origPoints2.first().y, m_origPoints2.last().x, m_origPoints2.last().y); + m_document->addPageAnnotation(0, m_annot2); +} + +void TranslateAnnotationTest::cleanup() +{ + m_document->closeDocument(); + // m_annot1 and m_annot2 are deleted when document is closed +} + +void TranslateAnnotationTest::testTranslateAnnotation() +{ + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); + m_document->translatePageAnnotation(0, m_annot1, m_deltaA); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + + // undo and ensure m_annot1 is back to where it started + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); + + // redo then translate m_annot1 by m_deltaB + m_document->redo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); +} + +void TranslateAnnotationTest::testSequentialTranslationsMergedIfBeingMovedIsSet() +{ + // mark m_annot1 as BeingMoved but not m_annot2 + m_annot1->setFlags(m_annot1->flags() | Okular::Annotation::BeingMoved); + + // Verify initial positions + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2)); + + // Translate m_annot1 by m_deltaA then m_deltaB + m_document->translatePageAnnotation(0, m_annot1, m_deltaA); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + m_document->translatePageAnnotation(0, m_annot1, m_deltaB); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB)); + + // Now undo and verify that these two translations were merged into one undo command + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); +} + +void TranslateAnnotationTest::testSequentialTranslationsNotMergedIfBeingMovedIsNotSet() +{ + // mark m_annot1 as not BeingMoved + m_annot1->setFlags(m_annot1->flags() & ~Okular::Annotation::BeingMoved); + + // Verify initial positions + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2)); + + // Translate m_annot1 by m_deltaA then m_deltaB + m_document->translatePageAnnotation(0, m_annot1, m_deltaA); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + m_document->translatePageAnnotation(0, m_annot1, m_deltaB); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB)); + + // Now undo and verify that these two translations were NOT merged into one undo command + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); +} + +void TranslateAnnotationTest::testAlternateTranslationsNotMerged() +{ + // Set both m_annot1 and m_annot2 to BeingMoved + m_annot1->setFlags(m_annot1->flags() | Okular::Annotation::BeingMoved); + m_annot2->setFlags(m_annot2->flags() | Okular::Annotation::BeingMoved); + + m_document->translatePageAnnotation(0, m_annot1, m_deltaA); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2)); + m_document->translatePageAnnotation(0, m_annot2, m_deltaA); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA)); + m_document->translatePageAnnotation(0, m_annot1, m_deltaB); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA)); + m_document->translatePageAnnotation(0, m_annot2, m_deltaB); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaAB)); + + // First undo should move only m_annot2 back by m_deltaB + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaAB)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA)); + + // Next undo should move only m_annot1 back by m_deltaB + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_points2DeltaA)); + + // Next Undo should move only m_annot2 back to its original location + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_points1DeltaA)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2)); + + // Next undo should move m_annot1 back to its original location + m_document->undo(); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot1->linePoints(), m_origPoints1)); + QVERIFY(TestingUtils::pointListsAlmostEqual(m_annot2->linePoints(), m_origPoints2)); +} + +QTEST_MAIN(TranslateAnnotationTest) +#include "translateannotationtest.moc" diff --git a/autotests/urldetecttest.cpp b/autotests/urldetecttest.cpp new file mode 100644 index 0000000..59474e8 --- /dev/null +++ b/autotests/urldetecttest.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2013 Jaydeep Solanki * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../part/url_utils.h" + +namespace Okular +{ +class UrlDetectTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testURL(); + void testURL_data(); +}; + +void UrlDetectTest::testURL() +{ + QFETCH(QString, selectedText); + QFETCH(QString, url); + QCOMPARE(UrlUtils::getUrl(selectedText), url); +} + +void UrlDetectTest::testURL_data() +{ + QTest::addColumn("selectedText"); + QTest::addColumn("url"); + QTest::newRow("1") << QStringLiteral("asdfhttp://okular.org") << QString(); + QTest::newRow("2") << QStringLiteral("google.com/index.php/") << QString(); + QTest::newRow("3") << QStringLiteral("http://google.com)") << QString(); + + QTest::newRow("4") << QStringLiteral("https://okular.org") << QStringLiteral("https://okular.org"); + QTest::newRow("5") << QStringLiteral("www.google.com") << QStringLiteral("http://www.google.com"); + QTest::newRow("6") << QStringLiteral("asdf http://okular.kde.org/") << QStringLiteral("http://okular.kde.org/"); + QTest::newRow("7") << QStringLiteral("http://www.example.com/wpstyle/?p=364") << QStringLiteral("http://www.example.com/wpstyle/?p=364"); + QTest::newRow("8") << QStringLiteral("asdf http://okular.org fdsa") << QStringLiteral("http://okular.org"); + QTest::newRow("9") << QStringLiteral("http://google.com/ø") << QStringLiteral("http://google.com/ø"); + QTest::newRow("10") << QStringLiteral("http://www.wolframalpha.com/input/?i=Plot[%281%2Be^%28-%282%29v%29%29^%28-2%29+%2B+%282%29+%281%2Be^v%29^%28-2%29%2C+{t%2C-0.5%2C+0.5}]") + << QStringLiteral("http://www.wolframalpha.com/input/?i=Plot[%281%2Be^%28-%282%29v%29%29^%28-2%29+%2B+%282%29+%281%2Be^v%29^%28-2%29%2C+{t%2C-0.5%2C+0.5}]"); + QTest::newRow("11") << QStringLiteral("http://uid:pass@example.com:8080") << QStringLiteral("http://uid:pass@example.com:8080"); + QTest::newRow("12") << QStringLiteral("www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf") << QStringLiteral("http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf"); + QTest::newRow("13") << QStringLiteral("http://IISServer/nwind?template=SELECTTOP2*FROM[OrderDetails]WHEREUnitPrice%26lt;10FORXMLAUTO") + << QStringLiteral("http://IISServer/nwind?template=SELECTTOP2*FROM[OrderDetails]WHEREUnitPrice%26lt;10FORXMLAUTO"); + QTest::newRow("14") << QStringLiteral("https://www.example.com/foo/?bar=baz&inga=42&quux") << QStringLiteral("https://www.example.com/foo/?bar=baz&inga=42&quux"); + QTest::newRow("15") << QStringLiteral("http://foo.bar/#tag") << QStringLiteral("http://foo.bar/#tag"); +} + +} + +QTEST_MAIN(Okular::UrlDetectTest) +#include "urldetecttest.moc" diff --git a/autotests/visibilitytest.cpp b/autotests/visibilitytest.cpp new file mode 100644 index 0000000..3dd986f --- /dev/null +++ b/autotests/visibilitytest.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "../settings_core.h" +#include "core/document.h" +#include +#include +#include +#include +#include + +#include "../generators/poppler/config-okular-poppler.h" + +class VisibilityTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testJavaScriptVisibility(); + void testSaveLoad(); + void testActionVisibility(); + +private: + void verifyTargetStates(bool visible); + + Okular::Document *m_document; + QMap m_fields; +}; + +void VisibilityTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("visibilitytest")); + m_document = new Okular::Document(nullptr); + + const QString testFile = QStringLiteral(KDESRCDIR "data/visibilitytest.pdf"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); + + // The test document has four buttons: + // HideScriptButton -> Hides targets with JavaScript + // ShowScriptButton -> Shows targets with JavaScript + // HideActionButton -> Hides targets with HideAction + // ShowActionButton -> Shows targets with HideAction + // + // The target fields are: + // TargetButton TargetText TargetCheck TargetDropDown TargetRadio + // + // With two radio buttons named TargetRadio. + + const Okular::Page *page = m_document->page(0); + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + m_fields.insert(ff->name(), ff); + } +} + +void VisibilityTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +void VisibilityTest::verifyTargetStates(bool visible) +{ + QCOMPARE(m_fields[QStringLiteral("TargetButton")]->isVisible(), visible); + QCOMPARE(m_fields[QStringLiteral("TargetText")]->isVisible(), visible); + QCOMPARE(m_fields[QStringLiteral("TargetCheck")]->isVisible(), visible); + QCOMPARE(m_fields[QStringLiteral("TargetDropDown")]->isVisible(), visible); + + // Radios do not properly inherit a name from the parent group so + // this does not work yet (And would probably need some list handling). + // QCOMPARE( m_fields[QStringLiteral( "TargetRadio" )].isVisible(), visible ); +} + +void VisibilityTest::testJavaScriptVisibility() +{ + auto hideBtn = m_fields[QStringLiteral("HideScriptButton")]; + auto showBtn = m_fields[QStringLiteral("ShowScriptButton")]; + + // We start with all fields visible + verifyTargetStates(true); + + m_document->processAction(hideBtn->activationAction()); + + // Now all should be hidden + verifyTargetStates(false); + + // And show again + m_document->processAction(showBtn->activationAction()); + verifyTargetStates(true); +} + +void VisibilityTest::testSaveLoad() +{ + auto hideBtn = m_fields[QStringLiteral("HideScriptButton")]; + auto showBtn = m_fields[QStringLiteral("ShowScriptButton")]; + + // We start with all fields visible + verifyTargetStates(true); + + m_document->processAction(hideBtn->activationAction()); + + // Now all should be hidden + verifyTargetStates(false); + + // Save the changed states + QTemporaryFile saveFile(QStringLiteral("%1/okrXXXXXX.pdf").arg(QDir::tempPath())); + QVERIFY(saveFile.open()); + saveFile.close(); + + QVERIFY(m_document->saveChanges(saveFile.fileName())); + + auto newDoc = new Okular::Document(nullptr); + + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(saveFile.fileName()); + QCOMPARE(newDoc->openDocument(saveFile.fileName(), QUrl(), mime), Okular::Document::OpenSuccess); + + const Okular::Page *page = newDoc->page(0); + + bool anyChecked = false; // Saveguard against accidental test passing here ;-) + const QLinkedList pageFormFields = page->formFields(); + for (Okular::FormField *ff : pageFormFields) { + if (ff->name().startsWith(QStringLiteral("Target"))) { + QVERIFY(!ff->isVisible()); + anyChecked = true; + } + } + QVERIFY(anyChecked); + + newDoc->closeDocument(); + delete newDoc; + + // Restore the state of the member document + m_document->processAction(showBtn->activationAction()); +} + +void VisibilityTest::testActionVisibility() +{ + auto hideBtn = m_fields[QStringLiteral("HideActionButton")]; + auto showBtn = m_fields[QStringLiteral("ShowActionButton")]; + + verifyTargetStates(true); + + m_document->processAction(hideBtn->activationAction()); + + verifyTargetStates(false); + + m_document->processAction(showBtn->activationAction()); + + verifyTargetStates(true); +} + +QTEST_MAIN(VisibilityTest) +#include "visibilitytest.moc" diff --git a/cmake/modules/COPYING-CMAKE-SCRIPTS b/cmake/modules/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..4b41776 --- /dev/null +++ b/cmake/modules/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/modules/FindCHM.cmake b/cmake/modules/FindCHM.cmake new file mode 100644 index 0000000..4e7ae29 --- /dev/null +++ b/cmake/modules/FindCHM.cmake @@ -0,0 +1,33 @@ +# - Try to find the chm library +# Once done this will define +# +# CHM_FOUND - system has the chm library +# CHM_INCLUDE_DIR - the chm include directory +# CHM_LIBRARY - Link this to use the chm library +# +# Copyright (c) 2006, 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 (CHM_LIBRARY AND CHM_INCLUDE_DIR) + # in cache already + set(CHM_FOUND TRUE) +else (CHM_LIBRARY AND CHM_INCLUDE_DIR) + + find_path(CHM_INCLUDE_DIR chm_lib.h + ${GNUWIN32_DIR}/include + ) + + find_library(CHM_LIBRARY NAMES chm + PATHS + ${GNUWIN32_DIR}/lib + ) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(CHM DEFAULT_MSG CHM_INCLUDE_DIR CHM_LIBRARY ) + # ensure that they are cached + set(CHM_INCLUDE_DIR ${CHM_INCLUDE_DIR} CACHE INTERNAL "The chmlib include path") + set(CHM_LIBRARY ${CHM_LIBRARY} CACHE INTERNAL "The libraries needed to use chmlib") + +endif (CHM_LIBRARY AND CHM_INCLUDE_DIR) diff --git a/cmake/modules/FindDiscount.cmake b/cmake/modules/FindDiscount.cmake new file mode 100644 index 0000000..583fb05 --- /dev/null +++ b/cmake/modules/FindDiscount.cmake @@ -0,0 +1,41 @@ +# - Find Discount +# Find the discount markdown library. +# +# This module defines +# discount_FOUND - whether the discount library was found +# discount_LIBRARIES - the discount library +# discount_INCLUDE_DIR - the include path of the discount library + +# Copyright (c) 2017, Julian Wolff, +# Copyright (c) 2018, Sune Vuorela, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +if (discount_INCLUDE_DIR AND discount_LIBRARIES) + + # Already in cache + set (discount_FOUND TRUE) + +else (discount_INCLUDE_DIR AND discount_LIBRARIES) + + find_library (discount_LIBRARIES + NAMES markdown libmarkdown + ) + + find_path (discount_INCLUDE_DIR + NAMES mkdio.h + ) + + include (FindPackageHandleStandardArgs) + find_package_handle_standard_args (discount DEFAULT_MSG discount_LIBRARIES discount_INCLUDE_DIR) + +endif (discount_INCLUDE_DIR AND discount_LIBRARIES) + +mark_as_advanced(discount_INCLUDE_DIR discount_LIBRARIES) + +if (discount_FOUND) + add_library(discount::Lib UNKNOWN IMPORTED) + set_target_properties(discount::Lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${discount_INCLUDE_DIR} IMPORTED_LOCATION ${discount_LIBRARIES}) +endif() diff --git a/cmake/modules/FindDjVuLibre.cmake b/cmake/modules/FindDjVuLibre.cmake new file mode 100644 index 0000000..4403127 --- /dev/null +++ b/cmake/modules/FindDjVuLibre.cmake @@ -0,0 +1,39 @@ +# - Try to find the DjVuLibre library +# Once done this will define +# +# DJVULIBRE_FOUND - system has the DjVuLibre library +# DJVULIBRE_INCLUDE_DIR - the DjVuLibre include directory +# DJVULIBRE_LIBRARY - Link this to use the DjVuLibre library + +if (DJVULIBRE_INCLUDE_DIR AND DJVULIBRE_LIBRARY) + + # in cache already + set(DJVULIBRE_FOUND TRUE) + +else (DJVULIBRE_INCLUDE_DIR AND DJVULIBRE_LIBRARY) + IF (NOT WIN32) + find_package(PkgConfig) + + pkg_check_modules(PC_DJVULIBRE ddjvuapi) + endif(NOT WIN32) + + find_path(DJVULIBRE_INCLUDE_DIR libdjvu/ddjvuapi.h + PATHS + ${PC_DJVULIBRE_INCLUDEDIR} + ${PC_DJVULIBRE_INCLUDE_DIRS} + ${GNUWIN32_DIR}/include + ) + + find_library(DJVULIBRE_LIBRARY NAMES djvulibre + PATHS + ${PC_DJVULIBRE_LIBDIR} + ${PC_DJVULIBRE_LIBRARY_DIRS} + ${GNUWIN32_DIR}/lib + ) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(DjVuLibre DEFAULT_MSG DJVULIBRE_INCLUDE_DIR DJVULIBRE_LIBRARY ) + + mark_as_advanced(DJVULIBRE_INCLUDE_DIR DJVULIBRE_LIBRARY) + +endif (DJVULIBRE_INCLUDE_DIR AND DJVULIBRE_LIBRARY) diff --git a/cmake/modules/FindEPub.cmake b/cmake/modules/FindEPub.cmake new file mode 100644 index 0000000..929ad65 --- /dev/null +++ b/cmake/modules/FindEPub.cmake @@ -0,0 +1,35 @@ +# - Find EPub +# Find the EPub library. +# +# This module defines +# EPUB_FOUND - whether the EPub library was found +# EPUB_LIBRARIES - the EPub library +# EPUB_INCLUDE_DIR - the include path of the EPub library + +# Copyright (c) 2008, 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 (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES) + + # Already in cache + set (EPUB_FOUND TRUE) + +else (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES) + + find_library (EPUB_LIBRARIES + NAMES epub libepub + ) + + find_path (EPUB_INCLUDE_DIR + NAMES epub.h + ) + + include (FindPackageHandleStandardArgs) + find_package_handle_standard_args (EPub DEFAULT_MSG EPUB_LIBRARIES EPUB_INCLUDE_DIR) + +endif (EPUB_INCLUDE_DIR AND EPUB_LIBRARIES) + +mark_as_advanced(EPUB_INCLUDE_DIR EPUB_LIBRARIES) diff --git a/cmake/modules/FindLibSpectre.cmake b/cmake/modules/FindLibSpectre.cmake new file mode 100644 index 0000000..0387b49 --- /dev/null +++ b/cmake/modules/FindLibSpectre.cmake @@ -0,0 +1,50 @@ +# - Try to find the libspectre PS library +# Once done this will define +# +# LIBSPECTRE_FOUND - system has libspectre +# LIBSPECTRE_INCLUDE_DIR - the libspectre include directory +# LIBSPECTRE_LIBRARY - Link this to use libspectre +# + +# Copyright (c) 2006-2007, Pino Toscano, +# Copyright (c) 2008, Albert Astals Cid, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +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) + + if(LIBSPECTRE_MINIMUM_VERSION}) + pkg_check_modules(_pc_LIBSPECTRE libspectre>=${LIBSPECTRE_MINIMUM_VERSION}) + else(LIBSPECTRE_MINIMUM_VERSION}) + pkg_check_modules(_pc_LIBSPECTRE libspectre) + endif(LIBSPECTRE_MINIMUM_VERSION}) +else(NOT WIN32) + # do not use pkg-config on windows + set(_pc_LIBSPECTRE_FOUND TRUE) +endif(NOT WIN32) + + +if(_pc_LIBSPECTRE_FOUND) + find_library(LIBSPECTRE_LIBRARY + NAMES libspectre spectre + HINTS ${_pc_LIBSPECTRE_LIBRARY_DIRS} ${CMAKE_LIBRARY_PATH} + ) + + find_path(LIBSPECTRE_INCLUDE_DIR spectre.h + HINTS ${_pc_LIBSPECTRE_INCLUDE_DIRS} + PATH_SUFFIXES libspectre + ) + + set(LIBSPECTRE_INTERNAL_FOUND TRUE) +endif(_pc_LIBSPECTRE_FOUND) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibSpectre DEFAULT_MSG LIBSPECTRE_LIBRARY LIBSPECTRE_INTERNAL_FOUND) + +# ensure that they are cached +set(LIBSPECTRE_INCLUDE_DIR ${LIBSPECTRE_INCLUDE_DIR} CACHE INTERNAL "The libspectre include path") +set(LIBSPECTRE_LIBRARY ${LIBSPECTRE_LIBRARY} CACHE INTERNAL "The libspectre library") diff --git a/cmake/modules/FindLibZip.cmake b/cmake/modules/FindLibZip.cmake new file mode 100644 index 0000000..a39f0e4 --- /dev/null +++ b/cmake/modules/FindLibZip.cmake @@ -0,0 +1,34 @@ +# - Try to find libzip +# Once done this will define +# +# LIBZIP_FOUND - system has the zip library +# LIBZIP_INCLUDE_DIR - the zip include directory +# LIBZIP_LIBRARY - Link this to use the zip library +# +# Copyright (c) 2006, 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 (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) + # in cache already + set(LIBZIP_FOUND TRUE) +else (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) + + find_path(LIBZIP_INCLUDE_DIR zip.h + ${GNUWIN32_DIR}/include + ) + + find_library(LIBZIP_LIBRARY NAMES zip + PATHS + ${GNUWIN32_DIR}/lib + ) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibZip DEFAULT_MSG LIBZIP_LIBRARY LIBZIP_INCLUDE_DIR) + + # ensure that they are cached + set(LIBZIP_INCLUDE_DIR ${LIBZIP_INCLUDE_DIR} CACHE INTERNAL "The libzip include path") + set(LIBZIP_LIBRARY ${LIBZIP_LIBRARY} CACHE INTERNAL "The libraries needed to use libzip") + +endif (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) diff --git a/conf/okular.kcfg b/conf/okular.kcfg new file mode 100644 index 0000000..ddf56f0 --- /dev/null +++ b/conf/okular.kcfg @@ -0,0 +1,401 @@ + + + kuser.h + + + + + + true + + + + + false + + + false + + + + + false + + + false + + + + + false + + + false + + + + + false + + + false + + + + QStringList drawingTools; + // load the default tool list from the 'xml tools definition' file + QFile infoDrawingFile( QStandardPaths::locate(QStandardPaths::GenericDataLocation, "okular/drawingtools.xml") ); + if ( infoDrawingFile.exists() && infoDrawingFile.open( QIODevice::ReadOnly ) ) + { + QDomDocument doc; + if ( doc.setContent( &infoDrawingFile ) ) + { + const QDomElement toolsDefinition = doc.elementsByTagName("drawingTools").item( 0 ).toElement(); + // create the annotationTools list from the XML dom tree + QDomNode toolDescription = toolsDefinition.firstChild(); + while ( toolDescription.isElement() ) + { + const QDomElement toolElement = toolDescription.toElement(); + if ( toolElement.tagName() == "tool" ) + { + QDomDocument temp; + temp.appendChild( temp.importNode( toolElement, true) ); + // add each <tool>...</tool> as XML string + drawingTools << temp.toString(-1); + } + toolDescription = toolDescription.nextSibling(); + } + } + else + { + qWarning() << "DrawingTools XML file seems to be damaged"; + } + } + else + { + qWarning() << "Unable to open DrawingTools XML definition"; + } + + drawingTools + + + + QStringList builtinAnnotationTools; + // load the default tool list from the 'xml tools definition' file + QFile infoFile( QStandardPaths::locate(QStandardPaths::GenericDataLocation, "okular/tools.xml") ); + if ( infoFile.exists() && infoFile.open( QIODevice::ReadOnly ) ) + { + QDomDocument doc; + if ( doc.setContent( &infoFile ) ) + { + QDomElement toolsDefinition = doc.elementsByTagName("annotatingTools").item( 0 ).toElement(); + // create the builtinAnnotationTools list from the XML dom tree + QDomNode toolDescription = toolsDefinition.firstChild(); + while ( toolDescription.isElement() ) + { + QDomElement toolElement = toolDescription.toElement(); + if ( toolElement.tagName() == "tool" ) + { + QDomDocument temp; + temp.appendChild( temp.importNode( toolElement, true) ); + // add each <tool>...</tool> as XML string + builtinAnnotationTools << temp.toString(-1); + } + toolDescription = toolDescription.nextSibling(); + } + } + else + { + qWarning() << "AnnotatingTools XML file seems to be damaged"; + } + } + else + { + qWarning() << "Unable to open AnnotatingTools XML definition"; + } + + builtinAnnotationTools + + + + + QStringList quickAnnotationTools; + // load the default tool list from the 'xml tools definition' file + QFile quickAnnFile( QStandardPaths::locate(QStandardPaths::GenericDataLocation, "okular/toolsQuick.xml") ); + if ( quickAnnFile.exists() && quickAnnFile.open( QIODevice::ReadOnly ) ) + { + QDomDocument doc; + if ( doc.setContent( &quickAnnFile ) ) + { + QDomElement toolsDefinition = doc.elementsByTagName("quickAnnotatingTools").item( 0 ).toElement(); + // create the quickAnnotationTools list from the XML dom tree + QDomNode toolDescription = toolsDefinition.firstChild(); + while ( toolDescription.isElement() ) + { + QDomElement toolElement = toolDescription.toElement(); + if ( toolElement.tagName() == "tool" ) + { + QDomDocument temp; + temp.appendChild( temp.importNode( toolElement, true) ); + // add each <tool>...</tool> as XML string + quickAnnotationTools << temp.toString(-1); + } + toolDescription = toolDescription.nextSibling(); + } + } + else + { + qWarning() << "QuickAnnotatingTools XML file seems to be damaged"; + } + } + else + { + qWarning() << "Unable to open QuickAnnotatingTools XML definition"; + } + + quickAnnotationTools + + + + true + + + + + 1 + 3 + + + + + false + + + false + + + true + + + true + + + false + + + Name + + + + + + + + speechd + + + true + + + + + Qt::black + + + Replace + + + + + + + + + + + + + + + + + + + + + + + + HiddenDelay + + + + + + + + true + + + false + + + true + + + -2 + -2 + 20 + + + + + true + + + + false + + + + + false + + + true + + + true + + + false + + + true + + + true + + + true + + + 48 + + + + + 0 + + + true + + + true + + + 0 + 0 + 50 + + + 3 + 1 + 8 + + + false + + + true + + + Single + + + + + + + + + None + + + + + + + + Browse + + + + + + + + + + + + false + + + false + + + + + + + false + + + true + + + true + + + + + false + + + false + + + 0x600000 + + + 0xF0F0F0 + + + 127 + 2 + 253 + + + 2 + 2 + 6 + + + + + + KUser currentUser; + QString userString = currentUser.property( KUser::FullName ).toString(); + if ( userString.isEmpty() ) + { + userString = currentUser.loginName(); + } + + userString + + + diff --git a/conf/okular_core.kcfg b/conf/okular_core.kcfg new file mode 100644 index 0000000..41b03bd --- /dev/null +++ b/conf/okular_core.kcfg @@ -0,0 +1,110 @@ + + + kuser.h + + + + Normal + + + + + + + + + true + + + Enabled + + + + + + + Enabled + + + + + + + Disabled + + + + + + + + + Qt::white + + + false + + + Inverted + + + + + + + + + + + + + + + + true + + + false + + + Kate + + + + + + + + + + + + + kate --line %l --column %c + + + + + false + + + 5 + 1 + 3600 + + + false + + + Forward + + + + + + + + diff --git a/conf/settings.kcfgc b/conf/settings.kcfgc new file mode 100644 index 0000000..28be96f --- /dev/null +++ b/conf/settings.kcfgc @@ -0,0 +1,10 @@ +ClassName=Settings +NameSpace=Okular +File=okular.kcfg +Inherits=SettingsCore +Mutators=true +Singleton=true +Visibility=OKULARPART_EXPORT +IncludeFiles=settings_core.h,okularpart_export.h +SourceIncludeFiles=qdom.h,QStandardPaths +MemberVariables=dpointer diff --git a/conf/settings_core.kcfgc b/conf/settings_core.kcfgc new file mode 100644 index 0000000..59ca21c --- /dev/null +++ b/conf/settings_core.kcfgc @@ -0,0 +1,8 @@ +ClassName=SettingsCore +NameSpace=Okular +File=okular_core.kcfg +Mutators=true +Singleton=true +Visibility=OKULARCORE_EXPORT +IncludeFiles=okularcore_export.h +MemberVariables=dpointer diff --git a/conf/settings_mobile.kcfgc b/conf/settings_mobile.kcfgc new file mode 100644 index 0000000..737ff65 --- /dev/null +++ b/conf/settings_mobile.kcfgc @@ -0,0 +1,10 @@ +ClassName=Settings +NameSpace=Okular +File=okular.kcfg +Inherits=SettingsCore +Mutators=true +Singleton=true +Visibility= +IncludeFiles=settings_core.h +SourceIncludeFiles=qdom.h,QStandardPaths +MemberVariables=dpointer diff --git a/config-okular.h.cmake b/config-okular.h.cmake new file mode 100644 index 0000000..905aac9 --- /dev/null +++ b/config-okular.h.cmake @@ -0,0 +1,8 @@ +/* Defines if force the use DRM in okular */ +#define OKULAR_FORCE_DRM ${_OKULAR_FORCE_DRM} + +/* Defines if the purpose framework is available */ +#define PURPOSE_FOUND ${PURPOSE_FOUND} + +/* Defines whether the malloc_trim method from malloc.h is available */ +#cmakedefine01 HAVE_MALLOC_TRIM diff --git a/core/action.cpp b/core/action.cpp new file mode 100644 index 0000000..8d414e8 --- /dev/null +++ b/core/action.cpp @@ -0,0 +1,601 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "action.h" + +// kde includes +#include + +// local includes +#include "document.h" +#include "movie.h" +#include "sound.h" +#include "sourcereference_p.h" + +using namespace Okular; + +class Okular::ActionPrivate +{ +public: + ActionPrivate() + { + } + + virtual ~ActionPrivate() + { + qDeleteAll(m_nextActions); + } + + ActionPrivate(const ActionPrivate &) = delete; + ActionPrivate &operator=(const ActionPrivate &) = delete; + + QVariant m_nativeId; + QVector m_nextActions; +}; + +Action::Action(ActionPrivate &dd) + : d_ptr(&dd) +{ +} + +Action::~Action() +{ + delete d_ptr; +} + +QString Action::actionTip() const +{ + return QLatin1String(""); +} + +void Action::setNativeId(const QVariant &id) +{ + Q_D(Action); + d->m_nativeId = id; +} + +QVariant Action::nativeId() const +{ + Q_D(const Action); + return d->m_nativeId; +} + +QVector Action::nextActions() const +{ + Q_D(const Action); + return d->m_nextActions; +} + +void Action::setNextActions(const QVector &actions) +{ + Q_D(Action); + qDeleteAll(d->m_nextActions); + d->m_nextActions = actions; +} + +// GotoAction + +class Okular::GotoActionPrivate : public Okular::ActionPrivate +{ +public: + GotoActionPrivate(const QString &fileName, const DocumentViewport &viewport) + : ActionPrivate() + , m_extFileName(fileName) + , m_vp(viewport) + { + } + + GotoActionPrivate(const QString &fileName, const QString &namedDestination) + : ActionPrivate() + , m_extFileName(fileName) + , m_dest(namedDestination) + { + } + + QString m_extFileName; + DocumentViewport m_vp; + QString m_dest; +}; + +GotoAction::GotoAction(const QString &fileName, const DocumentViewport &viewport) + : Action(*new GotoActionPrivate(fileName, viewport)) +{ +} + +GotoAction::GotoAction(const QString &fileName, const QString &namedDestination) + : Action(*new GotoActionPrivate(fileName, namedDestination)) +{ +} + +GotoAction::~GotoAction() +{ +} + +Action::ActionType GotoAction::actionType() const +{ + return Goto; +} + +QString GotoAction::actionTip() const +{ + Q_D(const GotoAction); + return d->m_extFileName.isEmpty() ? (d->m_vp.isValid() ? i18n("Go to page %1", d->m_vp.pageNumber + 1) : QLatin1String("")) : i18n("Open external file"); +} + +bool GotoAction::isExternal() const +{ + Q_D(const GotoAction); + return !d->m_extFileName.isEmpty(); +} + +QString GotoAction::fileName() const +{ + Q_D(const GotoAction); + return d->m_extFileName; +} + +DocumentViewport GotoAction::destViewport() const +{ + Q_D(const GotoAction); + return d->m_vp; +} + +QString GotoAction::destinationName() const +{ + Q_D(const GotoAction); + return d->m_dest; +} + +// ExecuteAction + +class Okular::ExecuteActionPrivate : public Okular::ActionPrivate +{ +public: + ExecuteActionPrivate(const QString &file, const QString ¶meters) + : ActionPrivate() + , m_fileName(file) + , m_parameters(parameters) + { + } + + QString m_fileName; + QString m_parameters; +}; + +ExecuteAction::ExecuteAction(const QString &file, const QString ¶meters) + : Action(*new ExecuteActionPrivate(file, parameters)) +{ +} + +ExecuteAction::~ExecuteAction() +{ +} + +Action::ActionType ExecuteAction::actionType() const +{ + return Execute; +} + +QString ExecuteAction::actionTip() const +{ + Q_D(const Okular::ExecuteAction); + return i18n("Execute '%1'...", d->m_fileName); +} + +QString ExecuteAction::fileName() const +{ + Q_D(const Okular::ExecuteAction); + return d->m_fileName; +} + +QString ExecuteAction::parameters() const +{ + Q_D(const Okular::ExecuteAction); + return d->m_parameters; +} + +// BrowseAction + +class Okular::BrowseActionPrivate : public Okular::ActionPrivate +{ +public: + BrowseActionPrivate(const QUrl &url) + : ActionPrivate() + , m_url(url) + { + } + + QUrl m_url; +}; + +BrowseAction::BrowseAction(const QUrl &url) + : Action(*new BrowseActionPrivate(url)) +{ +} + +BrowseAction::~BrowseAction() +{ +} + +Action::ActionType BrowseAction::actionType() const +{ + return Browse; +} + +QString BrowseAction::actionTip() const +{ + Q_D(const Okular::BrowseAction); + QString source; + int row = 0, col = 0; + if (extractLilyPondSourceReference(d->m_url, &source, &row, &col)) { + return sourceReferenceToolTip(source, row, col); + } + return d->m_url.toDisplayString(); +} + +QUrl BrowseAction::url() const +{ + Q_D(const Okular::BrowseAction); + return d->m_url; +} + +// DocumentAction + +class Okular::DocumentActionPrivate : public Okular::ActionPrivate +{ +public: + DocumentActionPrivate(enum DocumentAction::DocumentActionType documentActionType) + : ActionPrivate() + , m_type(documentActionType) + { + } + + DocumentAction::DocumentActionType m_type; +}; + +DocumentAction::DocumentAction(enum DocumentActionType documentActionType) + : Action(*new DocumentActionPrivate(documentActionType)) +{ +} + +DocumentAction::~DocumentAction() +{ +} + +DocumentAction::DocumentActionType DocumentAction::documentActionType() const +{ + Q_D(const Okular::DocumentAction); + return d->m_type; +} + +Action::ActionType DocumentAction::actionType() const +{ + return DocAction; +} + +QString DocumentAction::actionTip() const +{ + Q_D(const Okular::DocumentAction); + switch (d->m_type) { + case PageFirst: + return i18n("First Page"); + case PagePrev: + return i18n("Previous Page"); + case PageNext: + return i18n("Next Page"); + case PageLast: + return i18n("Last Page"); + case HistoryBack: + return i18n("Back"); + case HistoryForward: + return i18n("Forward"); + case Quit: + return i18n("Quit"); + case Presentation: + return i18n("Start Presentation"); + case EndPresentation: + return i18n("End Presentation"); + case Find: + return i18n("Find..."); + case GoToPage: + return i18n("Go To Page..."); + case Close: + default:; + } + + return QString(); +} + +// SoundAction + +class Okular::SoundActionPrivate : public Okular::ActionPrivate +{ +public: + SoundActionPrivate(double volume, bool sync, bool repeat, bool mix, Okular::Sound *sound) + : ActionPrivate() + , m_volume(volume) + , m_sync(sync) + , m_repeat(repeat) + , m_mix(mix) + , m_sound(sound) + { + } + + ~SoundActionPrivate() override + { + delete m_sound; + } + + double m_volume; + bool m_sync : 1; + bool m_repeat : 1; + bool m_mix : 1; + Okular::Sound *m_sound; +}; + +SoundAction::SoundAction(double volume, bool sync, bool repeat, bool mix, Okular::Sound *sound) + : Action(*new SoundActionPrivate(volume, sync, repeat, mix, sound)) +{ +} + +SoundAction::~SoundAction() +{ +} + +Action::ActionType SoundAction::actionType() const +{ + return Sound; +} + +QString SoundAction::actionTip() const +{ + return i18n("Play sound..."); +} + +double SoundAction::volume() const +{ + Q_D(const Okular::SoundAction); + return d->m_volume; +} + +bool SoundAction::synchronous() const +{ + Q_D(const Okular::SoundAction); + return d->m_sync; +} + +bool SoundAction::repeat() const +{ + Q_D(const Okular::SoundAction); + return d->m_repeat; +} + +bool SoundAction::mix() const +{ + Q_D(const Okular::SoundAction); + return d->m_mix; +} + +Okular::Sound *SoundAction::sound() const +{ + Q_D(const Okular::SoundAction); + return d->m_sound; +} + +// ScriptAction + +class Okular::ScriptActionPrivate : public Okular::ActionPrivate +{ +public: + ScriptActionPrivate(enum ScriptType type, const QString &script) + : ActionPrivate() + , m_scriptType(type) + , m_script(script) + { + } + + ScriptType m_scriptType; + QString m_script; +}; + +ScriptAction::ScriptAction(enum ScriptType type, const QString &script) + : Action(*new ScriptActionPrivate(type, script)) +{ +} + +ScriptAction::~ScriptAction() +{ +} + +Action::ActionType ScriptAction::actionType() const +{ + return Script; +} + +QString ScriptAction::actionTip() const +{ + Q_D(const Okular::ScriptAction); + switch (d->m_scriptType) { + case JavaScript: + return i18n("JavaScript Script"); + } + + return QString(); +} + +ScriptType ScriptAction::scriptType() const +{ + Q_D(const Okular::ScriptAction); + return d->m_scriptType; +} + +QString ScriptAction::script() const +{ + Q_D(const Okular::ScriptAction); + return d->m_script; +} + +// MovieAction + +class Okular::MovieActionPrivate : public Okular::ActionPrivate +{ +public: + MovieActionPrivate(MovieAction::OperationType operation) + : ActionPrivate() + , m_operation(operation) + , m_annotation(nullptr) + { + } + + MovieAction::OperationType m_operation; + MovieAnnotation *m_annotation; +}; + +MovieAction::MovieAction(OperationType operation) + : Action(*new MovieActionPrivate(operation)) +{ +} + +MovieAction::~MovieAction() +{ +} + +Action::ActionType MovieAction::actionType() const +{ + return Movie; +} + +QString MovieAction::actionTip() const +{ + return i18n("Play movie..."); +} + +MovieAction::OperationType MovieAction::operation() const +{ + Q_D(const Okular::MovieAction); + return d->m_operation; +} + +void MovieAction::setAnnotation(MovieAnnotation *annotation) +{ + Q_D(Okular::MovieAction); + d->m_annotation = annotation; +} + +MovieAnnotation *MovieAction::annotation() const +{ + Q_D(const Okular::MovieAction); + return d->m_annotation; +} + +// RenditionAction + +class Okular::RenditionActionPrivate : public Okular::ActionPrivate +{ +public: + RenditionActionPrivate(RenditionAction::OperationType operation, Okular::Movie *movie, enum ScriptType scriptType, const QString &script) + : ActionPrivate() + , m_operation(operation) + , m_movie(movie) + , m_scriptType(scriptType) + , m_script(script) + , m_annotation(nullptr) + { + } + + RenditionAction::OperationType m_operation; + Okular::Movie *m_movie; + ScriptType m_scriptType; + QString m_script; + ScreenAnnotation *m_annotation; +}; + +RenditionAction::RenditionAction(OperationType operation, Okular::Movie *movie, enum ScriptType scriptType, const QString &script) + : Action(*new RenditionActionPrivate(operation, movie, scriptType, script)) +{ +} + +RenditionAction::~RenditionAction() +{ +} + +Action::ActionType RenditionAction::actionType() const +{ + return Rendition; +} + +QString RenditionAction::actionTip() const +{ + Q_D(const Okular::RenditionAction); + + switch (d->m_operation) { + default: + case None: + switch (d->m_scriptType) { + case JavaScript: + return i18n("JavaScript Script"); + default: + return QString(); + } + case Play: + return i18n("Play movie"); + case Stop: + return i18n("Stop movie"); + case Pause: + return i18n("Pause movie"); + case Resume: + return i18n("Resume movie"); + } +} + +RenditionAction::OperationType RenditionAction::operation() const +{ + Q_D(const Okular::RenditionAction); + return d->m_operation; +} + +Okular::Movie *RenditionAction::movie() const +{ + Q_D(const Okular::RenditionAction); + return d->m_movie; +} + +ScriptType RenditionAction::scriptType() const +{ + Q_D(const Okular::RenditionAction); + return d->m_scriptType; +} + +QString RenditionAction::script() const +{ + Q_D(const Okular::RenditionAction); + return d->m_script; +} + +void RenditionAction::setAnnotation(ScreenAnnotation *annotation) +{ + Q_D(Okular::RenditionAction); + d->m_annotation = annotation; +} + +ScreenAnnotation *RenditionAction::annotation() const +{ + Q_D(const Okular::RenditionAction); + return d->m_annotation; +} + +BackendOpaqueAction::BackendOpaqueAction() + : Action(*new ActionPrivate()) +{ +} + +Action::ActionType BackendOpaqueAction::actionType() const +{ + return BackendOpaque; +} diff --git a/core/action.h b/core/action.h new file mode 100644 index 0000000..c83d471 --- /dev/null +++ b/core/action.h @@ -0,0 +1,592 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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_ACTION_H_ +#define _OKULAR_ACTION_H_ + +#include "global.h" +#include "okularcore_export.h" + +#include +#include + +namespace Okular +{ +class ActionPrivate; +class GotoActionPrivate; +class ExecuteActionPrivate; +class BrowseActionPrivate; +class DocumentActionPrivate; +class SoundActionPrivate; +class ScriptActionPrivate; +class MovieActionPrivate; +class RenditionActionPrivate; +class MovieAnnotation; +class ScreenAnnotation; +class Movie; +class Sound; +class DocumentViewport; + +/** + * @short Encapsulates data that describes an action. + * + * This is the base class for actions. It makes mandatory for inherited + * widgets to reimplement the 'actionType' method and return the type of + * the action described by the reimplemented class. + */ +class OKULARCORE_EXPORT Action +{ +public: + /** + * Describes the type of action. + */ + enum ActionType { + Goto, ///< Goto a given page or external document + Execute, ///< Execute a command or external application + Browse, ///< Browse a given website + DocAction, ///< Start a custom action + Sound, ///< Play a sound + Movie, ///< Play a movie + Script, ///< Executes a Script code + Rendition, ///< Play a movie and/or execute a Script code @since 0.16 (KDE 4.10) + BackendOpaque ///< Calls back to the backend with the action @since 1.1 + }; + + /** + * Destroys the action. + */ + virtual ~Action(); + + /** + * Returns the type of the action. Every inherited class must return + * an unique identifier. + * + * @see ActionType + */ + virtual ActionType actionType() const = 0; + + /** + * Returns a i18n'ed tip of the action that is presented to + * the user. + */ + virtual QString actionTip() const; + + /** + * Sets the "native" @p id of the action. + * + * This is for use of the Generator, that can optionally store an + * handle (a pointer, an identifier, etc) of the "native" action + * object, if any. + * + * @note Okular makes no use of this + * + * @since 0.15 (KDE 4.9) + */ + void setNativeId(const QVariant &id); + + /** + * Returns the "native" id of the action. + * + * @since 0.15 (KDE 4.9) + */ + QVariant nativeId() const; + + /** + * Returns the next actions to be executed after. + * + * @since 1.5 + */ + QVector nextActions() const; + + /** + * Sets the next actions. + * + * Takes ownership of the objects in the actions vector. + * @since 1.5 + */ + void setNextActions(const QVector &actions); + +protected: + /// @cond PRIVATE + Action(ActionPrivate &dd); + Q_DECLARE_PRIVATE(Action) + ActionPrivate *d_ptr; + /// @endcond + +private: + Q_DISABLE_COPY(Action) +}; + +/** + * The Goto action changes the viewport to another page + * or loads an external document. + */ +class OKULARCORE_EXPORT GotoAction : public Action +{ +public: + /** + * Creates a new goto action. + * + * @p fileName The name of an external file that shall be loaded. + * @p viewport The target viewport information of the current document. + */ + GotoAction(const QString &fileName, const DocumentViewport &viewport); + + /** + * Creates a new goto action. + * + * @p fileName The name of an external file that shall be loaded. + * @p namedDestination The target named destination for the target document. + * + * @since 0.9 (KDE 4.3) + */ + GotoAction(const QString &fileName, const QString &namedDestination); + + /** + * Destroys the goto action. + */ + ~GotoAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns whether the goto action points to an external document. + */ + bool isExternal() const; + + /** + * Returns the filename of the external document. + */ + QString fileName() const; + + /** + * Returns the document viewport the goto action points to. + */ + DocumentViewport destViewport() const; + + /** + * Returns the document named destination the goto action points to. + * + * @since 0.9 (KDE 4.3) + */ + QString destinationName() const; + +private: + Q_DECLARE_PRIVATE(GotoAction) + Q_DISABLE_COPY(GotoAction) +}; + +/** + * The Execute action executes an external application. + */ +class OKULARCORE_EXPORT ExecuteAction : public Action +{ +public: + /** + * Creates a new execute action. + * + * @param fileName The file name of the application to execute. + * @param parameters The parameters of the application to execute. + */ + ExecuteAction(const QString &fileName, const QString ¶meters); + + /** + * Destroys the execute action. + */ + ~ExecuteAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the file name of the application to execute. + */ + QString fileName() const; + + /** + * Returns the parameters of the application to execute. + */ + QString parameters() const; + +private: + Q_DECLARE_PRIVATE(ExecuteAction) + Q_DISABLE_COPY(ExecuteAction) +}; + +/** + * The Browse action browses an url by opening a web browser or + * email client, depending on the url protocol (e.g. http, mailto, etc.). + */ +class OKULARCORE_EXPORT BrowseAction : public Action +{ +public: + /** + * Creates a new browse action. + * + * @param url The url to browse. + */ + explicit BrowseAction(const QUrl &url); + + /** + * Destroys the browse action. + */ + ~BrowseAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the url to browse. + */ + QUrl url() const; + +private: + Q_DECLARE_PRIVATE(BrowseAction) + Q_DISABLE_COPY(BrowseAction) +}; + +/** + * The DocumentAction action contains an action that is performed on + * the current document. + */ +class OKULARCORE_EXPORT DocumentAction : public Action +{ +public: + /** + * Describes the possible action types. + * + * WARNING KEEP IN SYNC WITH POPPLER! + */ + enum DocumentActionType { + PageFirst = 1, ///< Jump to first page + PagePrev = 2, ///< Jump to previous page + PageNext = 3, ///< Jump to next page + PageLast = 4, ///< Jump to last page + HistoryBack = 5, ///< Go back in page history + HistoryForward = 6, ///< Go forward in page history + Quit = 7, ///< Quit application + Presentation = 8, ///< Start presentation + EndPresentation = 9, ///< End presentation + Find = 10, ///< Open find dialog + GoToPage = 11, ///< Goto page + Close = 12 ///< Close document + }; + + /** + * Creates a new document action. + * + * @param documentActionType The type of document action. + */ + explicit DocumentAction(enum DocumentActionType documentActionType); + + /** + * Destroys the document action. + */ + ~DocumentAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the type of action. + */ + DocumentActionType documentActionType() const; + +private: + Q_DECLARE_PRIVATE(DocumentAction) + Q_DISABLE_COPY(DocumentAction) +}; + +/** + * The Sound action plays a sound on activation. + */ +class OKULARCORE_EXPORT SoundAction : public Action +{ +public: + /** + * Creates a new sound action. + * + * @param volume The volume of the sound. + * @param synchronous Whether the sound shall be played synchronous. + * @param repeat Whether the sound shall be repeated. + * @param mix Whether the sound shall be mixed. + * @param sound The sound object which contains the sound data. + */ + SoundAction(double volume, bool synchronous, bool repeat, bool mix, Okular::Sound *sound); + + /** + * Destroys the sound action. + */ + ~SoundAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the volume of the sound. + */ + double volume() const; + + /** + * Returns whether the sound shall be played synchronous. + */ + bool synchronous() const; + + /** + * Returns whether the sound shall be repeated. + */ + bool repeat() const; + + /** + * Returns whether the sound shall be mixed. + */ + bool mix() const; + + /** + * Returns the sound object which contains the sound data. + */ + Okular::Sound *sound() const; + +private: + Q_DECLARE_PRIVATE(SoundAction) + Q_DISABLE_COPY(SoundAction) +}; + +/** + * The Script action executes a Script code. + * + * @since 0.7 (KDE 4.1) + */ +class OKULARCORE_EXPORT ScriptAction : public Action +{ +public: + /** + * Creates a new Script action. + * + * @param type The type of the script (for now, only JavaScript = 0 is implemented). + * @param script The code to execute. + */ + ScriptAction(enum ScriptType type, const QString &script); + + /** + * Destroys the browse action. + */ + ~ScriptAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the type of action. + */ + ScriptType scriptType() const; + + /** + * Returns the code. + */ + QString script() const; + +private: + Q_DECLARE_PRIVATE(ScriptAction) + Q_DISABLE_COPY(ScriptAction) +}; + +/** + * The Movie action executes an operation on a video on activation. + * + * @since 0.15 (KDE 4.9) + */ +class OKULARCORE_EXPORT MovieAction : public Action +{ +public: + /** + * Describes the possible operation types. + */ + enum OperationType { Play, Stop, Pause, Resume }; + + /** + * Creates a new movie action. + */ + explicit MovieAction(OperationType operation); + + /** + * Destroys the movie action. + */ + ~MovieAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the operation type. + */ + OperationType operation() const; + + /** + * Sets the @p annotation that is associated with the movie action. + */ + void setAnnotation(MovieAnnotation *annotation); + + /** + * Returns the annotation or @c 0 if no annotation has been set. + */ + MovieAnnotation *annotation() const; + +private: + Q_DECLARE_PRIVATE(MovieAction) + Q_DISABLE_COPY(MovieAction) +}; + +/** + * The Rendition action executes an operation on a video or + * executes some JavaScript code on activation. + * + * @since 0.16 (KDE 4.10) + */ +class OKULARCORE_EXPORT RenditionAction : public Action +{ +public: + /** + * Describes the possible operation types. + */ + enum OperationType { + None, ///< Execute only the JavaScript + Play, ///< Start playing the video + Stop, ///< Stop playing the video + Pause, ///< Pause the video + Resume ///< Resume playing the video + }; + + /** + * Creates a new rendition action. + * + * @param operation The type of operation the action executes. + * @param movie The movie object the action references. + * @param scriptType The type of script the action executes. + * @param script The actual script the action executes. + */ + RenditionAction(OperationType operation, Okular::Movie *movie, enum ScriptType scriptType, const QString &script); + + /** + * Destroys the rendition action. + */ + ~RenditionAction() override; + + /** + * Returns the action type. + */ + ActionType actionType() const override; + + /** + * Returns the action tip. + */ + QString actionTip() const override; + + /** + * Returns the operation type. + */ + OperationType operation() const; + + /** + * Returns the movie object or @c 0 if no movie object was set on construction time. + */ + Okular::Movie *movie() const; + + /** + * Returns the type of script. + */ + ScriptType scriptType() const; + + /** + * Returns the script code. + */ + QString script() const; + + /** + * Sets the @p annotation that is associated with the rendition action. + */ + void setAnnotation(ScreenAnnotation *annotation); + + /** + * Returns the annotation or @c 0 if no annotation has been set. + */ + ScreenAnnotation *annotation() const; + +private: + Q_DECLARE_PRIVATE(RenditionAction) + Q_DISABLE_COPY(RenditionAction) +}; + +class OKULARCORE_EXPORT BackendOpaqueAction : public Action +{ +public: + BackendOpaqueAction(); + + /** + * Returns the action type. + */ + ActionType actionType() const override; + +private: + Q_DISABLE_COPY(BackendOpaqueAction) +}; + +} + +#endif diff --git a/core/annotations.cpp b/core/annotations.cpp new file mode 100644 index 0000000..91c0a1d --- /dev/null +++ b/core/annotations.cpp @@ -0,0 +1,3079 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "annotations.h" +#include "annotations_p.h" + +// qt/kde includes +#include +#include + +// DBL_MAX +#include + +// local includes +#include "action.h" +#include "document.h" +#include "document_p.h" +#include "movie.h" +#include "page_p.h" +#include "sound.h" + +using namespace Okular; + +/** + * True, if point @p c lies to the left of the vector from @p a to @p b + * @internal + */ +static bool isLeftOfVector(const NormalizedPoint &a, const NormalizedPoint &b, const NormalizedPoint &c) +{ + // cross product + return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) > 0; +} + +/** + * @brief Calculates distance of the given point @p x @p y @p xScale @p yScale to the @p path + * + * Does piecewise comparison and selects the distance to the closest segment + */ +static double distanceSqr(double x, double y, double xScale, double yScale, const QLinkedList &path) +{ + double distance = DBL_MAX; + double thisDistance; + QLinkedList::const_iterator i = path.constBegin(); + NormalizedPoint lastPoint = *i; + + for (++i; i != path.constEnd(); ++i) { + thisDistance = NormalizedPoint::distanceSqr(x, y, xScale, yScale, lastPoint, (*i)); + + if (thisDistance < distance) + distance = thisDistance; + + lastPoint = *i; + } + return distance; +} + +/** + * Given the squared @p distance from the idealized 0-width line and a pen width @p penWidth, + * (not squared!), returns the final distance + * + * @warning The returned distance is not exact: + * We calculate an (exact) squared distance to the ideal (centered) line, and then subtract + * the squared width of the pen: + * a^2 - b^2 where a = "distance from idealized 0-width line" b = "pen width" + * For an exact result, we would want to calculate "(a - b)^2" but that would require + * a square root operation because we only know the squared distance a^2. + * + * However, the approximation is feasible, because: + * error = (a-b)^2 - (a^2 - b^2) = -2ab + 2b^2 = 2b(b - a) + * Therefore: + * lim_{a->b} a^2 - b^2 - a^2 + 2ab - b^2 --> 0 + * + * In other words, this approximation will estimate the distance to be slightly more than it actually is + * for as long as we are far "outside" the line, becoming more accurate the closer we get to the line + * boundary. Trivially, it also fulfils (a1 < a2) => ((a1^2 - b^2) < (a2^2 - b^2)) making it monotonic. + * "Inside" of the drawn line, the distance is 0 anyway. + */ +static double strokeDistance(double distance, double penWidth) +{ + return fmax(distance - pow(penWidth, 2), 0); +} + +// BEGIN AnnotationUtils implementation +Annotation *AnnotationUtils::createAnnotation(const QDomElement &annElement) +{ + // safety check on annotation element + if (!annElement.hasAttribute(QStringLiteral("type"))) + return nullptr; + + // build annotation of given type + Annotation *annotation = nullptr; + int typeNumber = annElement.attribute(QStringLiteral("type")).toInt(); + switch (typeNumber) { + case Annotation::AText: + annotation = new TextAnnotation(annElement); + break; + case Annotation::ALine: + annotation = new LineAnnotation(annElement); + break; + case Annotation::AGeom: + annotation = new GeomAnnotation(annElement); + break; + case Annotation::AHighlight: + annotation = new HighlightAnnotation(annElement); + break; + case Annotation::AStamp: + annotation = new StampAnnotation(annElement); + break; + case Annotation::AInk: + annotation = new InkAnnotation(annElement); + break; + case Annotation::ACaret: + annotation = new CaretAnnotation(annElement); + break; + } + + // return created annotation + return annotation; +} + +void AnnotationUtils::storeAnnotation(const Annotation *ann, QDomElement &annElement, QDomDocument &document) +{ + // save annotation's type as element's attribute + annElement.setAttribute(QStringLiteral("type"), (uint)ann->subType()); + + // append all annotation data as children of this node + ann->store(annElement, document); +} + +QDomElement AnnotationUtils::findChildElement(const QDomNode &parentNode, const QString &name) +{ + // loop through the whole children and return a 'name' named element + QDomNode subNode = parentNode.firstChild(); + while (subNode.isElement()) { + QDomElement element = subNode.toElement(); + if (element.tagName() == name) + return element; + subNode = subNode.nextSibling(); + } + // if the name can't be found, return a dummy null element + return QDomElement(); +} + +QRect AnnotationUtils::annotationGeometry(const Annotation *annotation, double scaleX, double scaleY) +{ + const QRect rect = annotation->transformedBoundingRectangle().geometry((int)scaleX, (int)scaleY); + if (annotation->subType() == Annotation::AText && (((TextAnnotation *)annotation)->textType() == TextAnnotation::Linked)) { + // To be honest i have no clue of why the 24,24 is here, maybe to make sure it's not too small? + // But why only for linked text? + const QRect rect24 = QRect((int)(annotation->transformedBoundingRectangle().left * scaleX), (int)(annotation->transformedBoundingRectangle().top * scaleY), 24, 24); + return rect24.united(rect); + } + + return rect; +} +// END AnnotationUtils implementation + +AnnotationProxy::AnnotationProxy() +{ +} + +AnnotationProxy::~AnnotationProxy() +{ +} + +// BEGIN Annotation implementation + +class Annotation::Style::Private +{ +public: + Private() + : m_opacity(1.0) + , m_width(1.0) + , m_style(Solid) + , m_xCorners(0.0) + , m_yCorners(0.0) + , m_marks(3) + , m_spaces(0) + , m_effect(NoEffect) + , m_effectIntensity(1.0) + { + } + + QColor m_color; + double m_opacity; + double m_width; + LineStyle m_style; + double m_xCorners; + double m_yCorners; + int m_marks; + int m_spaces; + LineEffect m_effect; + double m_effectIntensity; +}; + +Annotation::Style::Style() + : d(new Private) +{ +} + +Annotation::Style::~Style() +{ + delete d; +} + +Annotation::Style::Style(const Style &other) + : d(new Private) +{ + *d = *other.d; +} + +Annotation::Style &Annotation::Style::operator=(const Style &other) +{ + if (this != &other) + *d = *other.d; + + return *this; +} + +void Annotation::Style::setColor(const QColor &color) +{ + d->m_color = color; +} + +QColor Annotation::Style::color() const +{ + return d->m_color; +} + +void Annotation::Style::setOpacity(double opacity) +{ + d->m_opacity = opacity; +} + +double Annotation::Style::opacity() const +{ + return d->m_opacity; +} + +void Annotation::Style::setWidth(double width) +{ + d->m_width = width; +} + +double Annotation::Style::width() const +{ + return d->m_width; +} + +void Annotation::Style::setLineStyle(LineStyle style) +{ + d->m_style = style; +} + +Annotation::LineStyle Annotation::Style::lineStyle() const +{ + return d->m_style; +} + +void Annotation::Style::setXCorners(double xCorners) +{ + d->m_xCorners = xCorners; +} + +double Annotation::Style::xCorners() const +{ + return d->m_xCorners; +} + +void Annotation::Style::setYCorners(double yCorners) +{ + d->m_yCorners = yCorners; +} + +double Annotation::Style::yCorners() const +{ + return d->m_yCorners; +} + +void Annotation::Style::setMarks(int marks) +{ + d->m_marks = marks; +} + +int Annotation::Style::marks() const +{ + return d->m_marks; +} + +void Annotation::Style::setSpaces(int spaces) +{ + d->m_spaces = spaces; +} + +int Annotation::Style::spaces() const +{ + return d->m_spaces; +} + +void Annotation::Style::setLineEffect(LineEffect effect) +{ + d->m_effect = effect; +} + +Annotation::LineEffect Annotation::Style::lineEffect() const +{ + return d->m_effect; +} + +void Annotation::Style::setEffectIntensity(double intensity) +{ + d->m_effectIntensity = intensity; +} + +double Annotation::Style::effectIntensity() const +{ + return d->m_effectIntensity; +} + +class Annotation::Window::Private +{ +public: + Private() + : m_flags(-1) + , m_width(0) + , m_height(0) + { + } + + int m_flags; + NormalizedPoint m_topLeft; + int m_width; + int m_height; + QString m_title; + QString m_summary; +}; + +Annotation::Window::Window() + : d(new Private) +{ +} + +Annotation::Window::~Window() +{ + delete d; +} + +Annotation::Window::Window(const Window &other) + : d(new Private) +{ + *d = *other.d; +} + +Annotation::Window &Annotation::Window::operator=(const Window &other) +{ + if (this != &other) + *d = *other.d; + + return *this; +} + +void Annotation::Window::setFlags(int flags) +{ + d->m_flags = flags; +} + +int Annotation::Window::flags() const +{ + return d->m_flags; +} + +void Annotation::Window::setTopLeft(const NormalizedPoint &point) +{ + d->m_topLeft = point; +} + +NormalizedPoint Annotation::Window::topLeft() const +{ + return d->m_topLeft; +} + +void Annotation::Window::setWidth(int width) +{ + d->m_width = width; +} + +int Annotation::Window::width() const +{ + return d->m_width; +} + +void Annotation::Window::setHeight(int height) +{ + d->m_height = height; +} + +int Annotation::Window::height() const +{ + return d->m_height; +} + +void Annotation::Window::setTitle(const QString &title) +{ + d->m_title = title; +} + +QString Annotation::Window::title() const +{ + return d->m_title; +} + +void Annotation::Window::setSummary(const QString &summary) +{ + d->m_summary = summary; +} + +QString Annotation::Window::summary() const +{ + return d->m_summary; +} + +class Annotation::Revision::Private +{ +public: + Private() + : m_annotation(nullptr) + , m_scope(Reply) + , m_type(None) + { + } + + Annotation *m_annotation; + RevisionScope m_scope; + RevisionType m_type; +}; + +Annotation::Revision::Revision() + : d(new Private) +{ +} + +Annotation::Revision::~Revision() +{ + delete d; +} + +Annotation::Revision::Revision(const Revision &other) + : d(new Private) +{ + *d = *other.d; +} + +Annotation::Revision &Annotation::Revision::operator=(const Revision &other) +{ + if (this != &other) + *d = *other.d; + + return *this; +} + +void Annotation::Revision::setAnnotation(Annotation *annotation) +{ + d->m_annotation = annotation; +} + +Annotation *Annotation::Revision::annotation() const +{ + return d->m_annotation; +} + +void Annotation::Revision::setScope(RevisionScope scope) +{ + d->m_scope = scope; +} + +Annotation::RevisionScope Annotation::Revision::scope() const +{ + return d->m_scope; +} + +void Annotation::Revision::setType(RevisionType type) +{ + d->m_type = type; +} + +Annotation::RevisionType Annotation::Revision::type() const +{ + return d->m_type; +} + +AnnotationPrivate::AnnotationPrivate() + : m_page(nullptr) + , m_flags(0) + , m_disposeFunc(nullptr) +{ +} + +AnnotationPrivate::~AnnotationPrivate() +{ + // delete all children revisions + if (m_revisions.isEmpty()) + return; + + QLinkedList::iterator it = m_revisions.begin(), end = m_revisions.end(); + for (; it != end; ++it) + delete (*it).annotation(); +} + +Annotation::Annotation(AnnotationPrivate &dd) + : d_ptr(&dd) +{ +} + +Annotation::Annotation(AnnotationPrivate &dd, const QDomNode &description) + : d_ptr(&dd) +{ + d_ptr->setAnnotationProperties(description); +} + +Annotation::~Annotation() +{ + if (d_ptr->m_disposeFunc) + d_ptr->m_disposeFunc(this); + + delete d_ptr; +} + +void Annotation::setAuthor(const QString &author) +{ + Q_D(Annotation); + d->m_author = author; +} + +QString Annotation::author() const +{ + Q_D(const Annotation); + return d->m_author; +} + +void Annotation::setContents(const QString &contents) +{ + Q_D(Annotation); + d->m_contents = contents; +} + +QString Annotation::contents() const +{ + Q_D(const Annotation); + return d->m_contents; +} + +void Annotation::setUniqueName(const QString &name) +{ + Q_D(Annotation); + d->m_uniqueName = name; +} + +QString Annotation::uniqueName() const +{ + Q_D(const Annotation); + return d->m_uniqueName; +} + +void Annotation::setModificationDate(const QDateTime &date) +{ + Q_D(Annotation); + d->m_modifyDate = date; +} + +QDateTime Annotation::modificationDate() const +{ + Q_D(const Annotation); + return d->m_modifyDate; +} + +void Annotation::setCreationDate(const QDateTime &date) +{ + Q_D(Annotation); + d->m_creationDate = date; +} + +QDateTime Annotation::creationDate() const +{ + Q_D(const Annotation); + return d->m_creationDate; +} + +void Annotation::setFlags(int flags) +{ + Q_D(Annotation); + d->m_flags = flags; +} + +int Annotation::flags() const +{ + Q_D(const Annotation); + return d->m_flags; +} + +void Annotation::setBoundingRectangle(const NormalizedRect &rectangle) +{ + Q_D(Annotation); + d->m_boundary = rectangle; + d->resetTransformation(); + if (d->m_page) { + d->transform(d->m_page->rotationMatrix()); + } +} + +NormalizedRect Annotation::boundingRectangle() const +{ + Q_D(const Annotation); + return d->m_boundary; +} + +NormalizedRect Annotation::transformedBoundingRectangle() const +{ + Q_D(const Annotation); + return d->m_transformedBoundary; +} + +void Annotation::translate(const NormalizedPoint &coord) +{ + Q_D(Annotation); + d->translate(coord); + d->resetTransformation(); + if (d->m_page) { + d->transform(d->m_page->rotationMatrix()); + } +} + +void Annotation::adjust(const NormalizedPoint &deltaCoord1, const NormalizedPoint &deltaCoord2) +{ + Q_D(Annotation); + d->adjust(deltaCoord1, deltaCoord2); + d->resetTransformation(); + if (d->m_page) { + d->transform(d->m_page->rotationMatrix()); + } +} + +bool Annotation::openDialogAfterCreation() const +{ + Q_D(const Annotation); + return d->openDialogAfterCreation(); +} + +Annotation::Style &Annotation::style() +{ + Q_D(Annotation); + return d->m_style; +} + +const Annotation::Style &Annotation::style() const +{ + Q_D(const Annotation); + return d->m_style; +} + +Annotation::Window &Annotation::window() +{ + Q_D(Annotation); + return d->m_window; +} + +const Annotation::Window &Annotation::window() const +{ + Q_D(const Annotation); + return d->m_window; +} + +QLinkedList &Annotation::revisions() +{ + Q_D(Annotation); + return d->m_revisions; +} + +const QLinkedList &Annotation::revisions() const +{ + Q_D(const Annotation); + return d->m_revisions; +} + +void Annotation::setNativeId(const QVariant &id) +{ + Q_D(Annotation); + d->m_nativeId = id; +} + +QVariant Annotation::nativeId() const +{ + Q_D(const Annotation); + return d->m_nativeId; +} + +void Annotation::setDisposeDataFunction(DisposeDataFunction func) +{ + Q_D(Annotation); + d->m_disposeFunc = func; +} + +bool Annotation::canBeMoved() const +{ + Q_D(const Annotation); + + // Don't move annotations if they cannot be modified + if (!d->m_page || !d->m_page->m_doc->m_parent->canModifyPageAnnotation(this)) + return false; + + // highlight "requires" to be "bounded" to text, and that's tricky for now + if (subType() == AHighlight) + return false; + + return true; +} + +bool Annotation::canBeResized() const +{ + Q_D(const Annotation); + + // Don't resize annotations if they cannot be modified + if (!d->m_page || !d->m_page->m_doc->m_parent->canModifyPageAnnotation(this)) + return false; + + return d->canBeResized(); +} + +void Annotation::store(QDomNode &annNode, QDomDocument &document) const +{ + Q_D(const Annotation); + // create [base] element of the annotation node + QDomElement e = document.createElement(QStringLiteral("base")); + annNode.appendChild(e); + + // store -contents- attributes + if (!d->m_author.isEmpty()) + e.setAttribute(QStringLiteral("author"), d->m_author); + if (!d->m_contents.isEmpty()) + e.setAttribute(QStringLiteral("contents"), d->m_contents); + if (!d->m_uniqueName.isEmpty()) + e.setAttribute(QStringLiteral("uniqueName"), d->m_uniqueName); + if (d->m_modifyDate.isValid()) + e.setAttribute(QStringLiteral("modifyDate"), d->m_modifyDate.toString(Qt::ISODate)); + if (d->m_creationDate.isValid()) + e.setAttribute(QStringLiteral("creationDate"), d->m_creationDate.toString(Qt::ISODate)); + + // store -other- attributes + if (d->m_flags) // Strip internal flags + e.setAttribute(QStringLiteral("flags"), d->m_flags & ~(External | ExternallyDrawn | BeingMoved | BeingResized)); + if (d->m_style.color().isValid()) + e.setAttribute(QStringLiteral("color"), d->m_style.color().name(QColor::HexArgb)); + if (d->m_style.opacity() != 1.0) + e.setAttribute(QStringLiteral("opacity"), QString::number(d->m_style.opacity())); + + // Sub-Node-1 - boundary + QDomElement bE = document.createElement(QStringLiteral("boundary")); + e.appendChild(bE); + bE.setAttribute(QStringLiteral("l"), QString::number(d->m_boundary.left)); + bE.setAttribute(QStringLiteral("t"), QString::number(d->m_boundary.top)); + bE.setAttribute(QStringLiteral("r"), QString::number(d->m_boundary.right)); + bE.setAttribute(QStringLiteral("b"), QString::number(d->m_boundary.bottom)); + + // Sub-Node-2 - penStyle + if (d->m_style.width() != 1 || d->m_style.lineStyle() != Solid || d->m_style.xCorners() != 0 || d->m_style.yCorners() != 0.0 || d->m_style.marks() != 3 || d->m_style.spaces() != 0) { + QDomElement psE = document.createElement(QStringLiteral("penStyle")); + e.appendChild(psE); + psE.setAttribute(QStringLiteral("width"), QString::number(d->m_style.width())); + psE.setAttribute(QStringLiteral("style"), (int)d->m_style.lineStyle()); + psE.setAttribute(QStringLiteral("xcr"), QString::number(d->m_style.xCorners())); + psE.setAttribute(QStringLiteral("ycr"), QString::number(d->m_style.yCorners())); + psE.setAttribute(QStringLiteral("marks"), d->m_style.marks()); + psE.setAttribute(QStringLiteral("spaces"), d->m_style.spaces()); + } + + // Sub-Node-3 - penEffect + if (d->m_style.lineEffect() != NoEffect || d->m_style.effectIntensity() != 1.0) { + QDomElement peE = document.createElement(QStringLiteral("penEffect")); + e.appendChild(peE); + peE.setAttribute(QStringLiteral("effect"), (int)d->m_style.lineEffect()); + peE.setAttribute(QStringLiteral("intensity"), QString::number(d->m_style.effectIntensity())); + } + + // Sub-Node-4 - window + if (d->m_window.flags() != -1 || !d->m_window.title().isEmpty() || !d->m_window.summary().isEmpty()) { + QDomElement wE = document.createElement(QStringLiteral("window")); + e.appendChild(wE); + wE.setAttribute(QStringLiteral("flags"), d->m_window.flags()); + wE.setAttribute(QStringLiteral("top"), QString::number(d->m_window.topLeft().x)); + wE.setAttribute(QStringLiteral("left"), QString::number(d->m_window.topLeft().y)); + wE.setAttribute(QStringLiteral("width"), d->m_window.width()); + wE.setAttribute(QStringLiteral("height"), d->m_window.height()); + wE.setAttribute(QStringLiteral("title"), d->m_window.title()); + wE.setAttribute(QStringLiteral("summary"), d->m_window.summary()); + } + + // create [revision] element of the annotation node (if any) + if (d->m_revisions.isEmpty()) + return; + + // add all revisions as children of revisions element + QLinkedList::const_iterator it = d->m_revisions.begin(), end = d->m_revisions.end(); + for (; it != end; ++it) { + // create revision element + const Revision &revision = *it; + QDomElement r = document.createElement(QStringLiteral("revision")); + annNode.appendChild(r); + // set element attributes + r.setAttribute(QStringLiteral("revScope"), (int)revision.scope()); + r.setAttribute(QStringLiteral("revType"), (int)revision.type()); + // use revision as the annotation element, so fill it up + AnnotationUtils::storeAnnotation(revision.annotation(), r, document); + } +} + +QDomNode Annotation::getAnnotationPropertiesDomNode() const +{ + QDomDocument doc(QStringLiteral("documentInfo")); + QDomElement node = doc.createElement(QStringLiteral("annotation")); + + store(node, doc); + return node; +} + +void Annotation::setAnnotationProperties(const QDomNode &node) +{ + // Save off internal properties that aren't contained in node + Okular::PagePrivate *p = d_ptr->m_page; + QVariant nativeID = d_ptr->m_nativeId; + const int internalFlags = d_ptr->m_flags & (External | ExternallyDrawn | BeingMoved | BeingResized); + Annotation::DisposeDataFunction disposeFunc = d_ptr->m_disposeFunc; + + // Replace AnnotationPrivate object with a fresh copy + AnnotationPrivate *new_d_ptr = d_ptr->getNewAnnotationPrivate(); + delete (d_ptr); + d_ptr = new_d_ptr; + + // Set the annotations properties from node + d_ptr->setAnnotationProperties(node); + + // Restore internal properties + d_ptr->m_page = p; + d_ptr->m_nativeId = nativeID; + d_ptr->m_flags = d_ptr->m_flags | internalFlags; + d_ptr->m_disposeFunc = disposeFunc; + + // Transform annotation to current page rotation + d_ptr->transform(d_ptr->m_page->rotationMatrix()); +} + +double AnnotationPrivate::distanceSqr(double x, double y, double xScale, double yScale) const +{ + return m_transformedBoundary.distanceSqr(x, y, xScale, yScale); +} + +void AnnotationPrivate::annotationTransform(const QTransform &matrix) +{ + resetTransformation(); + transform(matrix); +} + +void AnnotationPrivate::transform(const QTransform &matrix) +{ + m_transformedBoundary.transform(matrix); +} + +void AnnotationPrivate::baseTransform(const QTransform &matrix) +{ + m_boundary.transform(matrix); +} + +void AnnotationPrivate::resetTransformation() +{ + m_transformedBoundary = m_boundary; +} + +void AnnotationPrivate::translate(const NormalizedPoint &coord) +{ + m_boundary.left = m_boundary.left + coord.x; + m_boundary.right = m_boundary.right + coord.x; + m_boundary.top = m_boundary.top + coord.y; + m_boundary.bottom = m_boundary.bottom + coord.y; +} + +void AnnotationPrivate::adjust(const NormalizedPoint &deltaCoord1, const NormalizedPoint &deltaCoord2) +{ + m_boundary.left = m_boundary.left + qBound(-m_boundary.left, deltaCoord1.x, m_boundary.right - m_boundary.left); + m_boundary.top = m_boundary.top + qBound(-m_boundary.top, deltaCoord1.y, m_boundary.bottom - m_boundary.top); + ; + m_boundary.right = m_boundary.right + qBound(m_boundary.left - m_boundary.right, deltaCoord2.x, 1. - m_boundary.right); + m_boundary.bottom = m_boundary.bottom + qBound(m_boundary.top - m_boundary.bottom, deltaCoord2.y, 1. - m_boundary.bottom); +} + +bool AnnotationPrivate::openDialogAfterCreation() const +{ + return false; +} + +void AnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + // get the [base] element of the annotation node + QDomElement e = AnnotationUtils::findChildElement(node, QStringLiteral("base")); + if (e.isNull()) + return; + + // parse -contents- attributes + if (e.hasAttribute(QStringLiteral("author"))) + m_author = e.attribute(QStringLiteral("author")); + if (e.hasAttribute(QStringLiteral("contents"))) + m_contents = e.attribute(QStringLiteral("contents")); + if (e.hasAttribute(QStringLiteral("uniqueName"))) + m_uniqueName = e.attribute(QStringLiteral("uniqueName")); + if (e.hasAttribute(QStringLiteral("modifyDate"))) + m_modifyDate = QDateTime::fromString(e.attribute(QStringLiteral("modifyDate")), Qt::ISODate); + if (e.hasAttribute(QStringLiteral("creationDate"))) + m_creationDate = QDateTime::fromString(e.attribute(QStringLiteral("creationDate")), Qt::ISODate); + + // parse -other- attributes + if (e.hasAttribute(QStringLiteral("flags"))) + m_flags = e.attribute(QStringLiteral("flags")).toInt(); + if (e.hasAttribute(QStringLiteral("color"))) + m_style.setColor(QColor(e.attribute(QStringLiteral("color")))); + if (e.hasAttribute(QStringLiteral("opacity"))) + m_style.setOpacity(e.attribute(QStringLiteral("opacity")).toDouble()); + + // parse -the-subnodes- (describing Style, Window, Revision(s) structures) + // Note: all subnodes if present must be 'attributes complete' + QDomNode eSubNode = e.firstChild(); + while (eSubNode.isElement()) { + QDomElement ee = eSubNode.toElement(); + eSubNode = eSubNode.nextSibling(); + + // parse boundary + if (ee.tagName() == QLatin1String("boundary")) { + m_boundary = NormalizedRect(ee.attribute(QStringLiteral("l")).toDouble(), ee.attribute(QStringLiteral("t")).toDouble(), ee.attribute(QStringLiteral("r")).toDouble(), ee.attribute(QStringLiteral("b")).toDouble()); + } + // parse penStyle if not default + else if (ee.tagName() == QLatin1String("penStyle")) { + m_style.setWidth(ee.attribute(QStringLiteral("width")).toDouble()); + m_style.setLineStyle((Annotation::LineStyle)ee.attribute(QStringLiteral("style")).toInt()); + m_style.setXCorners(ee.attribute(QStringLiteral("xcr")).toDouble()); + m_style.setYCorners(ee.attribute(QStringLiteral("ycr")).toDouble()); + m_style.setMarks(ee.attribute(QStringLiteral("marks")).toInt()); + m_style.setSpaces(ee.attribute(QStringLiteral("spaces")).toInt()); + } + // parse effectStyle if not default + else if (ee.tagName() == QLatin1String("penEffect")) { + m_style.setLineEffect((Annotation::LineEffect)ee.attribute(QStringLiteral("effect")).toInt()); + m_style.setEffectIntensity(ee.attribute(QStringLiteral("intensity")).toDouble()); + } + // parse window if present + else if (ee.tagName() == QLatin1String("window")) { + m_window.setFlags(ee.attribute(QStringLiteral("flags")).toInt()); + m_window.setTopLeft(NormalizedPoint(ee.attribute(QStringLiteral("top")).toDouble(), ee.attribute(QStringLiteral("left")).toDouble())); + m_window.setWidth(ee.attribute(QStringLiteral("width")).toInt()); + m_window.setHeight(ee.attribute(QStringLiteral("height")).toInt()); + m_window.setTitle(ee.attribute(QStringLiteral("title"))); + m_window.setSummary(ee.attribute(QStringLiteral("summary"))); + } + } + + // get the [revisions] element of the annotation node + QDomNode revNode = node.firstChild(); + for (; revNode.isElement(); revNode = revNode.nextSibling()) { + QDomElement revElement = revNode.toElement(); + if (revElement.tagName() != QLatin1String("revision")) + continue; + + // compile the Revision structure crating annotation + Annotation::Revision revision; + revision.setScope((Annotation::RevisionScope)revElement.attribute(QStringLiteral("revScope")).toInt()); + revision.setType((Annotation::RevisionType)revElement.attribute(QStringLiteral("revType")).toInt()); + revision.setAnnotation(AnnotationUtils::createAnnotation(revElement)); + + // if annotation is valid, add revision to internal list + if (revision.annotation()) + m_revisions.append(revision); + } + + m_transformedBoundary = m_boundary; +} + +bool AnnotationPrivate::canBeResized() const +{ + return false; +} + +// END Annotation implementation + +/** TextAnnotation [Annotation] */ + +class Okular::TextAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + TextAnnotationPrivate() + : AnnotationPrivate() + , m_textType(TextAnnotation::Linked) + , m_textIcon(QStringLiteral("Comment")) + , m_inplaceAlign(0) + , m_inplaceIntent(TextAnnotation::Unknown) + { + } + + void transform(const QTransform &matrix) override; + void baseTransform(const QTransform &matrix) override; + void resetTransformation() override; + void translate(const NormalizedPoint &coord) override; + bool openDialogAfterCreation() const override; + void setAnnotationProperties(const QDomNode &node) override; + bool canBeResized() const override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + TextAnnotation::TextType m_textType; + QString m_textIcon; + QFont m_textFont; + QColor m_textColor; + int m_inplaceAlign; + NormalizedPoint m_inplaceCallout[3]; + NormalizedPoint m_transformedInplaceCallout[3]; + TextAnnotation::InplaceIntent m_inplaceIntent; +}; + +/* + The default textIcon for text annotation is Note as the PDF Reference says +*/ +TextAnnotation::TextAnnotation() + : Annotation(*new TextAnnotationPrivate()) +{ +} + +TextAnnotation::TextAnnotation(const QDomNode &description) + : Annotation(*new TextAnnotationPrivate(), description) +{ +} + +TextAnnotation::~TextAnnotation() +{ +} + +void TextAnnotation::setTextType(TextType textType) +{ + Q_D(TextAnnotation); + d->m_textType = textType; +} + +TextAnnotation::TextType TextAnnotation::textType() const +{ + Q_D(const TextAnnotation); + return d->m_textType; +} + +void TextAnnotation::setTextIcon(const QString &icon) +{ + Q_D(TextAnnotation); + d->m_textIcon = icon; +} + +QString TextAnnotation::textIcon() const +{ + Q_D(const TextAnnotation); + return d->m_textIcon; +} + +void TextAnnotation::setTextFont(const QFont &font) +{ + Q_D(TextAnnotation); + d->m_textFont = font; +} + +QFont TextAnnotation::textFont() const +{ + Q_D(const TextAnnotation); + return d->m_textFont; +} + +void TextAnnotation::setTextColor(const QColor &color) +{ + Q_D(TextAnnotation); + d->m_textColor = color; +} + +QColor TextAnnotation::textColor() const +{ + Q_D(const TextAnnotation); + return d->m_textColor; +} + +void TextAnnotation::setInplaceAlignment(int alignment) +{ + Q_D(TextAnnotation); + d->m_inplaceAlign = alignment; +} + +int TextAnnotation::inplaceAlignment() const +{ + Q_D(const TextAnnotation); + return d->m_inplaceAlign; +} + +void TextAnnotation::setInplaceCallout(const NormalizedPoint &point, int index) +{ + if (index < 0 || index > 2) + return; + + Q_D(TextAnnotation); + d->m_inplaceCallout[index] = point; +} + +NormalizedPoint TextAnnotation::inplaceCallout(int index) const +{ + if (index < 0 || index > 2) + return NormalizedPoint(); + + Q_D(const TextAnnotation); + return d->m_inplaceCallout[index]; +} + +NormalizedPoint TextAnnotation::transformedInplaceCallout(int index) const +{ + if (index < 0 || index > 2) + return NormalizedPoint(); + + Q_D(const TextAnnotation); + return d->m_transformedInplaceCallout[index]; +} + +void TextAnnotation::setInplaceIntent(InplaceIntent intent) +{ + Q_D(TextAnnotation); + d->m_inplaceIntent = intent; +} + +TextAnnotation::InplaceIntent TextAnnotation::inplaceIntent() const +{ + Q_D(const TextAnnotation); + return d->m_inplaceIntent; +} + +Annotation::SubType TextAnnotation::subType() const +{ + return AText; +} + +void TextAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const TextAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [text] element + QDomElement textElement = document.createElement(QStringLiteral("text")); + node.appendChild(textElement); + + // store the optional attributes + if (d->m_textType != Linked) + textElement.setAttribute(QStringLiteral("type"), (int)d->m_textType); + if (!d->m_textIcon.isEmpty()) + textElement.setAttribute(QStringLiteral("icon"), d->m_textIcon); + if (d->m_textFont != QApplication::font()) + textElement.setAttribute(QStringLiteral("font"), d->m_textFont.toString()); + if (d->m_textColor.isValid()) + textElement.setAttribute(QStringLiteral("fontColor"), d->m_textColor.name()); + if (d->m_inplaceAlign) + textElement.setAttribute(QStringLiteral("align"), d->m_inplaceAlign); + if (d->m_inplaceIntent != Unknown) + textElement.setAttribute(QStringLiteral("intent"), (int)d->m_inplaceIntent); + + // Sub-Node - callout + if (d->m_inplaceCallout[0].x != 0.0) { + QDomElement calloutElement = document.createElement(QStringLiteral("callout")); + textElement.appendChild(calloutElement); + calloutElement.setAttribute(QStringLiteral("ax"), QString::number(d->m_inplaceCallout[0].x)); + calloutElement.setAttribute(QStringLiteral("ay"), QString::number(d->m_inplaceCallout[0].y)); + calloutElement.setAttribute(QStringLiteral("bx"), QString::number(d->m_inplaceCallout[1].x)); + calloutElement.setAttribute(QStringLiteral("by"), QString::number(d->m_inplaceCallout[1].y)); + calloutElement.setAttribute(QStringLiteral("cx"), QString::number(d->m_inplaceCallout[2].x)); + calloutElement.setAttribute(QStringLiteral("cy"), QString::number(d->m_inplaceCallout[2].y)); + } +} + +void TextAnnotationPrivate::transform(const QTransform &matrix) +{ + AnnotationPrivate::transform(matrix); + + for (NormalizedPoint &np : m_transformedInplaceCallout) { + np.transform(matrix); + } +} + +void TextAnnotationPrivate::baseTransform(const QTransform &matrix) +{ + AnnotationPrivate::baseTransform(matrix); + + for (NormalizedPoint &np : m_inplaceCallout) { + np.transform(matrix); + } +} + +void TextAnnotationPrivate::resetTransformation() +{ + AnnotationPrivate::resetTransformation(); + + for (int i = 0; i < 3; ++i) { + m_transformedInplaceCallout[i] = m_inplaceCallout[i]; + } +} + +void TextAnnotationPrivate::translate(const NormalizedPoint &coord) +{ + AnnotationPrivate::translate(coord); + +#define ADD_COORD(c1, c2) \ + { \ + c1.x = c1.x + c2.x; \ + c1.y = c1.y + c2.y; \ + } + ADD_COORD(m_inplaceCallout[0], coord) + ADD_COORD(m_inplaceCallout[1], coord) + ADD_COORD(m_inplaceCallout[2], coord) +#undef ADD_COORD +} + +bool TextAnnotationPrivate::openDialogAfterCreation() const +{ + return (m_textType == Okular::TextAnnotation::Linked); +} + +void TextAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'text' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("text")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("type"))) + m_textType = (TextAnnotation::TextType)e.attribute(QStringLiteral("type")).toInt(); + if (e.hasAttribute(QStringLiteral("icon"))) + m_textIcon = e.attribute(QStringLiteral("icon")); + if (e.hasAttribute(QStringLiteral("font"))) + m_textFont.fromString(e.attribute(QStringLiteral("font"))); + if (e.hasAttribute(QStringLiteral("fontColor"))) + m_textColor = QColor(e.attribute(QStringLiteral("fontColor"))); + if (e.hasAttribute(QStringLiteral("align"))) + m_inplaceAlign = e.attribute(QStringLiteral("align")).toInt(); + if (e.hasAttribute(QStringLiteral("intent"))) + m_inplaceIntent = (TextAnnotation::InplaceIntent)e.attribute(QStringLiteral("intent")).toInt(); + + // parse the subnodes + QDomNode eSubNode = e.firstChild(); + while (eSubNode.isElement()) { + QDomElement ee = eSubNode.toElement(); + eSubNode = eSubNode.nextSibling(); + + if (ee.tagName() == QLatin1String("escapedText")) { + m_contents = ee.firstChild().toCDATASection().data(); + } else if (ee.tagName() == QLatin1String("callout")) { + m_inplaceCallout[0].x = ee.attribute(QStringLiteral("ax")).toDouble(); + m_inplaceCallout[0].y = ee.attribute(QStringLiteral("ay")).toDouble(); + m_inplaceCallout[1].x = ee.attribute(QStringLiteral("bx")).toDouble(); + m_inplaceCallout[1].y = ee.attribute(QStringLiteral("by")).toDouble(); + m_inplaceCallout[2].x = ee.attribute(QStringLiteral("cx")).toDouble(); + m_inplaceCallout[2].y = ee.attribute(QStringLiteral("cy")).toDouble(); + } + } + + // loading complete + break; + } + + for (int i = 0; i < 3; ++i) + m_transformedInplaceCallout[i] = m_inplaceCallout[i]; +} + +bool TextAnnotationPrivate::canBeResized() const +{ + if (m_textType != TextAnnotation::Linked) { + return true; + } + return false; +} + +AnnotationPrivate *TextAnnotationPrivate::getNewAnnotationPrivate() +{ + return new TextAnnotationPrivate(); +} + +/** LineAnnotation [Annotation] */ + +class Okular::LineAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + LineAnnotationPrivate() + : AnnotationPrivate() + , m_lineStartStyle(LineAnnotation::None) + , m_lineEndStyle(LineAnnotation::None) + , m_lineClosed(false) + , m_lineShowCaption(false) + , m_lineLeadingFwdPt(0) + , m_lineLeadingBackPt(0) + , m_lineIntent(LineAnnotation::Unknown) + { + } + + void transform(const QTransform &matrix) override; + void baseTransform(const QTransform &matrix) override; + void resetTransformation() override; + void translate(const NormalizedPoint &coord) override; + double distanceSqr(double x, double y, double xScale, double yScale) const override; + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + QLinkedList m_linePoints; + QLinkedList m_transformedLinePoints; + LineAnnotation::TermStyle m_lineStartStyle; + LineAnnotation::TermStyle m_lineEndStyle; + bool m_lineClosed : 1; + bool m_lineShowCaption : 1; + QColor m_lineInnerColor; + double m_lineLeadingFwdPt; + double m_lineLeadingBackPt; + LineAnnotation::LineIntent m_lineIntent; +}; + +LineAnnotation::LineAnnotation() + : Annotation(*new LineAnnotationPrivate()) +{ +} + +LineAnnotation::LineAnnotation(const QDomNode &description) + : Annotation(*new LineAnnotationPrivate(), description) +{ +} + +LineAnnotation::~LineAnnotation() +{ +} + +void LineAnnotation::setLinePoints(const QLinkedList &points) +{ + Q_D(LineAnnotation); + d->m_linePoints = points; +} + +QLinkedList LineAnnotation::linePoints() const +{ + Q_D(const LineAnnotation); + return d->m_linePoints; +} + +QLinkedList LineAnnotation::transformedLinePoints() const +{ + Q_D(const LineAnnotation); + return d->m_transformedLinePoints; +} + +void LineAnnotation::setLineStartStyle(TermStyle style) +{ + Q_D(LineAnnotation); + d->m_lineStartStyle = style; +} + +LineAnnotation::TermStyle LineAnnotation::lineStartStyle() const +{ + Q_D(const LineAnnotation); + return d->m_lineStartStyle; +} + +void LineAnnotation::setLineEndStyle(TermStyle style) +{ + Q_D(LineAnnotation); + d->m_lineEndStyle = style; +} + +LineAnnotation::TermStyle LineAnnotation::lineEndStyle() const +{ + Q_D(const LineAnnotation); + return d->m_lineEndStyle; +} + +void LineAnnotation::setLineClosed(bool closed) +{ + Q_D(LineAnnotation); + d->m_lineClosed = closed; +} + +bool LineAnnotation::lineClosed() const +{ + Q_D(const LineAnnotation); + return d->m_lineClosed; +} + +void LineAnnotation::setLineInnerColor(const QColor &color) +{ + Q_D(LineAnnotation); + d->m_lineInnerColor = color; +} + +QColor LineAnnotation::lineInnerColor() const +{ + Q_D(const LineAnnotation); + return d->m_lineInnerColor; +} + +void LineAnnotation::setLineLeadingForwardPoint(double point) +{ + Q_D(LineAnnotation); + d->m_lineLeadingFwdPt = point; +} + +double LineAnnotation::lineLeadingForwardPoint() const +{ + Q_D(const LineAnnotation); + return d->m_lineLeadingFwdPt; +} + +void LineAnnotation::setLineLeadingBackwardPoint(double point) +{ + Q_D(LineAnnotation); + d->m_lineLeadingBackPt = point; +} + +double LineAnnotation::lineLeadingBackwardPoint() const +{ + Q_D(const LineAnnotation); + return d->m_lineLeadingBackPt; +} + +void LineAnnotation::setShowCaption(bool show) +{ + Q_D(LineAnnotation); + d->m_lineShowCaption = show; +} + +bool LineAnnotation::showCaption() const +{ + Q_D(const LineAnnotation); + return d->m_lineShowCaption; +} + +void LineAnnotation::setLineIntent(LineIntent intent) +{ + Q_D(LineAnnotation); + d->m_lineIntent = intent; +} + +LineAnnotation::LineIntent LineAnnotation::lineIntent() const +{ + Q_D(const LineAnnotation); + return d->m_lineIntent; +} + +Annotation::SubType LineAnnotation::subType() const +{ + return ALine; +} + +void LineAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const LineAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [line] element + QDomElement lineElement = document.createElement(QStringLiteral("line")); + node.appendChild(lineElement); + + // store the attributes + if (d->m_lineStartStyle != None) + lineElement.setAttribute(QStringLiteral("startStyle"), (int)d->m_lineStartStyle); + if (d->m_lineEndStyle != None) + lineElement.setAttribute(QStringLiteral("endStyle"), (int)d->m_lineEndStyle); + if (d->m_lineClosed) + lineElement.setAttribute(QStringLiteral("closed"), d->m_lineClosed); + if (d->m_lineInnerColor.isValid()) + lineElement.setAttribute(QStringLiteral("innerColor"), d->m_lineInnerColor.name()); + if (d->m_lineLeadingFwdPt != 0.0) + lineElement.setAttribute(QStringLiteral("leadFwd"), QString::number(d->m_lineLeadingFwdPt)); + if (d->m_lineLeadingBackPt != 0.0) + lineElement.setAttribute(QStringLiteral("leadBack"), QString::number(d->m_lineLeadingBackPt)); + if (d->m_lineShowCaption) + lineElement.setAttribute(QStringLiteral("showCaption"), d->m_lineShowCaption); + if (d->m_lineIntent != Unknown) + lineElement.setAttribute(QStringLiteral("intent"), d->m_lineIntent); + + // append the list of points + int points = d->m_linePoints.count(); + if (points > 1) { + QLinkedList::const_iterator it = d->m_linePoints.begin(), end = d->m_linePoints.end(); + while (it != end) { + const NormalizedPoint &p = *it; + QDomElement pElement = document.createElement(QStringLiteral("point")); + lineElement.appendChild(pElement); + pElement.setAttribute(QStringLiteral("x"), QString::number(p.x)); + pElement.setAttribute(QStringLiteral("y"), QString::number(p.y)); + it++; // to avoid loop + } + } +} + +void LineAnnotationPrivate::transform(const QTransform &matrix) +{ + AnnotationPrivate::transform(matrix); + + QMutableLinkedListIterator it(m_transformedLinePoints); + while (it.hasNext()) + it.next().transform(matrix); +} + +void LineAnnotationPrivate::baseTransform(const QTransform &matrix) +{ + AnnotationPrivate::baseTransform(matrix); + + QMutableLinkedListIterator it(m_linePoints); + while (it.hasNext()) + it.next().transform(matrix); +} + +void LineAnnotationPrivate::resetTransformation() +{ + AnnotationPrivate::resetTransformation(); + + m_transformedLinePoints = m_linePoints; +} + +void LineAnnotationPrivate::translate(const NormalizedPoint &coord) +{ + AnnotationPrivate::translate(coord); + + QMutableLinkedListIterator it(m_linePoints); + while (it.hasNext()) { + NormalizedPoint &p = it.next(); + p.x = p.x + coord.x; + p.y = p.y + coord.y; + } +} + +void LineAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'line' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("line")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("startStyle"))) + m_lineStartStyle = (LineAnnotation::TermStyle)e.attribute(QStringLiteral("startStyle")).toInt(); + if (e.hasAttribute(QStringLiteral("endStyle"))) + m_lineEndStyle = (LineAnnotation::TermStyle)e.attribute(QStringLiteral("endStyle")).toInt(); + if (e.hasAttribute(QStringLiteral("closed"))) + m_lineClosed = e.attribute(QStringLiteral("closed")).toInt(); + if (e.hasAttribute(QStringLiteral("innerColor"))) + m_lineInnerColor = QColor(e.attribute(QStringLiteral("innerColor"))); + if (e.hasAttribute(QStringLiteral("leadFwd"))) + m_lineLeadingFwdPt = e.attribute(QStringLiteral("leadFwd")).toDouble(); + if (e.hasAttribute(QStringLiteral("leadBack"))) + m_lineLeadingBackPt = e.attribute(QStringLiteral("leadBack")).toDouble(); + if (e.hasAttribute(QStringLiteral("showCaption"))) + m_lineShowCaption = e.attribute(QStringLiteral("showCaption")).toInt(); + if (e.hasAttribute(QStringLiteral("intent"))) + m_lineIntent = (LineAnnotation::LineIntent)e.attribute(QStringLiteral("intent")).toInt(); + + // parse all 'point' subnodes + QDomNode pointNode = e.firstChild(); + while (pointNode.isElement()) { + QDomElement pe = pointNode.toElement(); + pointNode = pointNode.nextSibling(); + + if (pe.tagName() != QLatin1String("point")) + continue; + + NormalizedPoint p; + p.x = pe.attribute(QStringLiteral("x"), QStringLiteral("0.0")).toDouble(); + p.y = pe.attribute(QStringLiteral("y"), QStringLiteral("0.0")).toDouble(); + m_linePoints.append(p); + } + + // loading complete + break; + } + + m_transformedLinePoints = m_linePoints; +} + +AnnotationPrivate *LineAnnotationPrivate::getNewAnnotationPrivate() +{ + return new LineAnnotationPrivate(); +} + +double LineAnnotationPrivate::distanceSqr(double x, double y, double xScale, double yScale) const +{ + QLinkedList transformedLinePoints = m_transformedLinePoints; + + if (m_lineClosed) // Close the path + transformedLinePoints.append(transformedLinePoints.first()); + + if (m_lineInnerColor.isValid()) { + QPolygonF polygon; + for (const NormalizedPoint &p : qAsConst(transformedLinePoints)) + polygon.append(QPointF(p.x, p.y)); + + if (polygon.containsPoint(QPointF(x, y), Qt::WindingFill)) + return 0; + } + + return strokeDistance(::distanceSqr(x, y, xScale, yScale, transformedLinePoints), m_style.width() * xScale / (m_page->m_width * 2)); +} + +/** GeomAnnotation [Annotation] */ + +class Okular::GeomAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + GeomAnnotationPrivate() + : AnnotationPrivate() + , m_geomType(GeomAnnotation::InscribedSquare) + { + } + void setAnnotationProperties(const QDomNode &node) override; + bool canBeResized() const override; + AnnotationPrivate *getNewAnnotationPrivate() override; + double distanceSqr(double x, double y, double xScale, double yScale) const override; + + GeomAnnotation::GeomType m_geomType; + QColor m_geomInnerColor; +}; + +GeomAnnotation::GeomAnnotation() + : Annotation(*new GeomAnnotationPrivate()) +{ +} + +GeomAnnotation::GeomAnnotation(const QDomNode &description) + : Annotation(*new GeomAnnotationPrivate(), description) +{ +} + +GeomAnnotation::~GeomAnnotation() +{ +} + +void GeomAnnotation::setGeometricalType(GeomType type) +{ + Q_D(GeomAnnotation); + d->m_geomType = type; +} + +GeomAnnotation::GeomType GeomAnnotation::geometricalType() const +{ + Q_D(const GeomAnnotation); + return d->m_geomType; +} + +void GeomAnnotation::setGeometricalInnerColor(const QColor &color) +{ + Q_D(GeomAnnotation); + d->m_geomInnerColor = color; +} + +QColor GeomAnnotation::geometricalInnerColor() const +{ + Q_D(const GeomAnnotation); + return d->m_geomInnerColor; +} + +Annotation::SubType GeomAnnotation::subType() const +{ + return AGeom; +} + +void GeomAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const GeomAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [geom] element + QDomElement geomElement = document.createElement(QStringLiteral("geom")); + node.appendChild(geomElement); + + // append the optional attributes + if (d->m_geomType != InscribedSquare) + geomElement.setAttribute(QStringLiteral("type"), (int)d->m_geomType); + if (d->m_geomInnerColor.isValid()) + geomElement.setAttribute(QStringLiteral("color"), d->m_geomInnerColor.name()); +} + +void GeomAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + // loop through the whole children looking for a 'geom' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("geom")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("type"))) + m_geomType = (GeomAnnotation::GeomType)e.attribute(QStringLiteral("type")).toInt(); + if (e.hasAttribute(QStringLiteral("color"))) + m_geomInnerColor = QColor(e.attribute(QStringLiteral("color"))); + // compatibility + if (e.hasAttribute(QStringLiteral("width"))) + m_style.setWidth(e.attribute(QStringLiteral("width")).toInt()); + + // loading complete + break; + } +} + +bool GeomAnnotationPrivate::canBeResized() const +{ + return true; +} + +AnnotationPrivate *GeomAnnotationPrivate::getNewAnnotationPrivate() +{ + return new GeomAnnotationPrivate(); +} + +double GeomAnnotationPrivate::distanceSqr(double x, double y, double xScale, double yScale) const +{ + double distance = 0; + // the line thickness is applied unevenly (only on the "inside") - account for this + bool withinShape = false; + switch (m_geomType) { + case GeomAnnotation::InscribedCircle: { + // calculate the center point and focus lengths of the ellipse + const double centerX = (m_transformedBoundary.left + m_transformedBoundary.right) / 2.0; + const double centerY = (m_transformedBoundary.top + m_transformedBoundary.bottom) / 2.0; + const double focusX = (m_transformedBoundary.right - centerX); + const double focusY = (m_transformedBoundary.bottom - centerY); + + const double focusXSqr = pow(focusX, 2); + const double focusYSqr = pow(focusY, 2); + + // to calculate the distance from the ellipse, we will first find the point "projection" + // that lies on the ellipse and is closest to the point (x,y) + // This point can obviously be written as "center + lambda(inputPoint - center)". + // Because the point lies on the ellipse, we know that: + // 1 = ((center.x - projection.x)/focusX)^2 + ((center.y - projection.y)/focusY)^2 + // After filling in projection.x = center.x + lambda * (inputPoint.x - center.x) + // and its y-equivalent, we can solve for lambda: + const double lambda = sqrt(focusXSqr * focusYSqr / (focusYSqr * pow(x - centerX, 2) + focusXSqr * pow(y - centerY, 2))); + + // if the ellipse is filled, we treat all points within as "on" it + if (lambda > 1) { + if (m_geomInnerColor.isValid()) + return 0; + else + withinShape = true; + } + + // otherwise we calculate the squared distance from the projected point on the ellipse + NormalizedPoint projection(centerX, centerY); + projection.x += lambda * (x - centerX); + projection.y += lambda * (y - centerY); + + distance = projection.distanceSqr(x, y, xScale, yScale); + break; + } + + case GeomAnnotation::InscribedSquare: + // if the square is filled, only check the bounding box + if (m_geomInnerColor.isValid()) + return AnnotationPrivate::distanceSqr(x, y, xScale, yScale); + + QLinkedList edges; + edges << NormalizedPoint(m_transformedBoundary.left, m_transformedBoundary.top); + edges << NormalizedPoint(m_transformedBoundary.right, m_transformedBoundary.top); + edges << NormalizedPoint(m_transformedBoundary.right, m_transformedBoundary.bottom); + edges << NormalizedPoint(m_transformedBoundary.left, m_transformedBoundary.bottom); + edges << NormalizedPoint(m_transformedBoundary.left, m_transformedBoundary.top); + distance = ::distanceSqr(x, y, xScale, yScale, edges); + + if (m_transformedBoundary.contains(x, y)) + withinShape = true; + + break; + } + if (withinShape) + distance = strokeDistance(distance, m_style.width() * xScale / m_page->m_width); + + return distance; +} + +/** HighlightAnnotation [Annotation] */ + +class HighlightAnnotation::Quad::Private +{ +public: + Private() + { + } + + NormalizedPoint m_points[4]; + NormalizedPoint m_transformedPoints[4]; + bool m_capStart : 1; + bool m_capEnd : 1; + double m_feather; +}; + +HighlightAnnotation::Quad::Quad() + : d(new Private) +{ +} + +HighlightAnnotation::Quad::~Quad() +{ + delete d; +} + +HighlightAnnotation::Quad::Quad(const Quad &other) + : d(new Private) +{ + *d = *other.d; +} + +HighlightAnnotation::Quad &HighlightAnnotation::Quad::operator=(const Quad &other) +{ + if (this != &other) + *d = *other.d; + + return *this; +} + +void HighlightAnnotation::Quad::setPoint(const NormalizedPoint &point, int index) +{ + if (index < 0 || index > 3) + return; + + d->m_points[index] = point; +} + +NormalizedPoint HighlightAnnotation::Quad::point(int index) const +{ + if (index < 0 || index > 3) + return NormalizedPoint(); + + return d->m_points[index]; +} + +NormalizedPoint HighlightAnnotation::Quad::transformedPoint(int index) const +{ + if (index < 0 || index > 3) + return NormalizedPoint(); + + return d->m_transformedPoints[index]; +} + +void HighlightAnnotation::Quad::setCapStart(bool value) +{ + d->m_capStart = value; +} + +bool HighlightAnnotation::Quad::capStart() const +{ + return d->m_capStart; +} + +void HighlightAnnotation::Quad::setCapEnd(bool value) +{ + d->m_capEnd = value; +} + +bool HighlightAnnotation::Quad::capEnd() const +{ + return d->m_capEnd; +} + +void HighlightAnnotation::Quad::setFeather(double width) +{ + d->m_feather = width; +} + +double HighlightAnnotation::Quad::feather() const +{ + return d->m_feather; +} + +void HighlightAnnotation::Quad::transform(const QTransform &matrix) +{ + for (int i = 0; i < 4; ++i) { + d->m_transformedPoints[i] = d->m_points[i]; + d->m_transformedPoints[i].transform(matrix); + } +} + +class Okular::HighlightAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + HighlightAnnotationPrivate() + : AnnotationPrivate() + , m_highlightType(HighlightAnnotation::Highlight) + { + } + + void transform(const QTransform &matrix) override; + void baseTransform(const QTransform &matrix) override; + double distanceSqr(double x, double y, double xScale, double yScale) const override; + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + HighlightAnnotation::HighlightType m_highlightType; + QList m_highlightQuads; +}; + +HighlightAnnotation::HighlightAnnotation() + : Annotation(*new HighlightAnnotationPrivate()) +{ +} + +HighlightAnnotation::HighlightAnnotation(const QDomNode &description) + : Annotation(*new HighlightAnnotationPrivate(), description) +{ +} + +HighlightAnnotation::~HighlightAnnotation() +{ +} + +void HighlightAnnotation::setHighlightType(HighlightType type) +{ + Q_D(HighlightAnnotation); + d->m_highlightType = type; +} + +HighlightAnnotation::HighlightType HighlightAnnotation::highlightType() const +{ + Q_D(const HighlightAnnotation); + return d->m_highlightType; +} + +QList &HighlightAnnotation::highlightQuads() +{ + Q_D(HighlightAnnotation); + return d->m_highlightQuads; +} + +void HighlightAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const HighlightAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [hl] element + QDomElement hlElement = document.createElement(QStringLiteral("hl")); + node.appendChild(hlElement); + + // append the optional attributes + if (d->m_highlightType != Highlight) + hlElement.setAttribute(QStringLiteral("type"), (int)d->m_highlightType); + if (d->m_highlightQuads.count() < 1) + return; + // append highlight quads, all children describe quads + QList::const_iterator it = d->m_highlightQuads.begin(), end = d->m_highlightQuads.end(); + for (; it != end; ++it) { + QDomElement quadElement = document.createElement(QStringLiteral("quad")); + hlElement.appendChild(quadElement); + const Quad &q = *it; + quadElement.setAttribute(QStringLiteral("ax"), QString::number(q.point(0).x)); + quadElement.setAttribute(QStringLiteral("ay"), QString::number(q.point(0).y)); + quadElement.setAttribute(QStringLiteral("bx"), QString::number(q.point(1).x)); + quadElement.setAttribute(QStringLiteral("by"), QString::number(q.point(1).y)); + quadElement.setAttribute(QStringLiteral("cx"), QString::number(q.point(2).x)); + quadElement.setAttribute(QStringLiteral("cy"), QString::number(q.point(2).y)); + quadElement.setAttribute(QStringLiteral("dx"), QString::number(q.point(3).x)); + quadElement.setAttribute(QStringLiteral("dy"), QString::number(q.point(3).y)); + if (q.capStart()) + quadElement.setAttribute(QStringLiteral("start"), 1); + if (q.capEnd()) + quadElement.setAttribute(QStringLiteral("end"), 1); + quadElement.setAttribute(QStringLiteral("feather"), QString::number(q.feather())); + } +} + +Annotation::SubType HighlightAnnotation::subType() const +{ + return AHighlight; +} + +void HighlightAnnotationPrivate::transform(const QTransform &matrix) +{ + AnnotationPrivate::transform(matrix); + + QMutableListIterator it(m_highlightQuads); + while (it.hasNext()) + it.next().transform(matrix); +} + +void HighlightAnnotationPrivate::baseTransform(const QTransform &matrix) +{ + AnnotationPrivate::baseTransform(matrix); + + QMutableListIterator it(m_highlightQuads); + while (it.hasNext()) + it.next().transform(matrix); +} + +void HighlightAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + m_highlightQuads.clear(); + + // loop through the whole children looking for a 'hl' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("hl")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("type"))) + m_highlightType = (HighlightAnnotation::HighlightType)e.attribute(QStringLiteral("type")).toInt(); + + // parse all 'quad' subnodes + QDomNode quadNode = e.firstChild(); + for (; quadNode.isElement(); quadNode = quadNode.nextSibling()) { + QDomElement qe = quadNode.toElement(); + if (qe.tagName() != QLatin1String("quad")) + continue; + + HighlightAnnotation::Quad q; + q.setPoint(NormalizedPoint(qe.attribute(QStringLiteral("ax"), QStringLiteral("0.0")).toDouble(), qe.attribute(QStringLiteral("ay"), QStringLiteral("0.0")).toDouble()), 0); + q.setPoint(NormalizedPoint(qe.attribute(QStringLiteral("bx"), QStringLiteral("0.0")).toDouble(), qe.attribute(QStringLiteral("by"), QStringLiteral("0.0")).toDouble()), 1); + q.setPoint(NormalizedPoint(qe.attribute(QStringLiteral("cx"), QStringLiteral("0.0")).toDouble(), qe.attribute(QStringLiteral("cy"), QStringLiteral("0.0")).toDouble()), 2); + q.setPoint(NormalizedPoint(qe.attribute(QStringLiteral("dx"), QStringLiteral("0.0")).toDouble(), qe.attribute(QStringLiteral("dy"), QStringLiteral("0.0")).toDouble()), 3); + q.setCapStart(qe.hasAttribute(QStringLiteral("start"))); + q.setCapEnd(qe.hasAttribute(QStringLiteral("end"))); + q.setFeather(qe.attribute(QStringLiteral("feather"), QStringLiteral("0.1")).toDouble()); + + q.transform(QTransform()); + + m_highlightQuads.append(q); + } + + // loading complete + break; + } +} + +AnnotationPrivate *HighlightAnnotationPrivate::getNewAnnotationPrivate() +{ + return new HighlightAnnotationPrivate(); +} + +double HighlightAnnotationPrivate::distanceSqr(double x, double y, double xScale, double yScale) const +{ + NormalizedPoint point(x, y); + double outsideDistance = DBL_MAX; + for (const HighlightAnnotation::Quad &quad : m_highlightQuads) { + QLinkedList pathPoints; + + // first, we check if the point is within the area described by the 4 quads + // this is the case, if the point is always on one side of each segments delimiting the polygon: + pathPoints << quad.transformedPoint(0); + int directionVote = 0; + for (int i = 1; i < 5; ++i) { + NormalizedPoint thisPoint = quad.transformedPoint(i % 4); + directionVote += (isLeftOfVector(pathPoints.back(), thisPoint, point)) ? 1 : -1; + pathPoints << thisPoint; + } + if (abs(directionVote) == 4) + return 0; + + // if that's not the case, we treat the outline as path and simply determine + // the distance from the path to the point + const double thisOutsideDistance = ::distanceSqr(x, y, xScale, yScale, pathPoints); + if (thisOutsideDistance < outsideDistance) + outsideDistance = thisOutsideDistance; + } + + return outsideDistance; +} + +/** StampAnnotation [Annotation] */ + +class Okular::StampAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + StampAnnotationPrivate() + : AnnotationPrivate() + , m_stampIconName(QStringLiteral("Draft")) + { + } + void setAnnotationProperties(const QDomNode &node) override; + bool canBeResized() const override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + QString m_stampIconName; +}; + +StampAnnotation::StampAnnotation() + : Annotation(*new StampAnnotationPrivate()) +{ +} + +StampAnnotation::StampAnnotation(const QDomNode &description) + : Annotation(*new StampAnnotationPrivate(), description) +{ +} + +StampAnnotation::~StampAnnotation() +{ +} + +void StampAnnotation::setStampIconName(const QString &name) +{ + Q_D(StampAnnotation); + d->m_stampIconName = name; +} + +QString StampAnnotation::stampIconName() const +{ + Q_D(const StampAnnotation); + return d->m_stampIconName; +} + +Annotation::SubType StampAnnotation::subType() const +{ + return AStamp; +} + +void StampAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const StampAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [stamp] element + QDomElement stampElement = document.createElement(QStringLiteral("stamp")); + node.appendChild(stampElement); + + // append the optional attributes + if (d->m_stampIconName != QLatin1String("Draft")) + stampElement.setAttribute(QStringLiteral("icon"), d->m_stampIconName); +} + +void StampAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'stamp' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("stamp")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("icon"))) + m_stampIconName = e.attribute(QStringLiteral("icon")); + + // loading complete + break; + } +} + +bool StampAnnotationPrivate::canBeResized() const +{ + return true; +} + +AnnotationPrivate *StampAnnotationPrivate::getNewAnnotationPrivate() +{ + return new StampAnnotationPrivate(); +} + +/** InkAnnotation [Annotation] */ + +class Okular::InkAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + InkAnnotationPrivate() + : AnnotationPrivate() + { + } + + void transform(const QTransform &matrix) override; + void baseTransform(const QTransform &matrix) override; + void resetTransformation() override; + double distanceSqr(double x, double y, double xScale, double yScale) const override; + void translate(const NormalizedPoint &coord) override; + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + QList> m_inkPaths; + QList> m_transformedInkPaths; +}; + +InkAnnotation::InkAnnotation() + : Annotation(*new InkAnnotationPrivate()) +{ +} + +InkAnnotation::InkAnnotation(const QDomNode &description) + : Annotation(*new InkAnnotationPrivate(), description) +{ +} + +InkAnnotation::~InkAnnotation() +{ +} + +void InkAnnotation::setInkPaths(const QList> &paths) +{ + Q_D(InkAnnotation); + d->m_inkPaths = paths; +} + +QList> InkAnnotation::inkPaths() const +{ + Q_D(const InkAnnotation); + return d->m_inkPaths; +} + +QList> InkAnnotation::transformedInkPaths() const +{ + Q_D(const InkAnnotation); + return d->m_transformedInkPaths; +} + +Annotation::SubType InkAnnotation::subType() const +{ + return AInk; +} + +void InkAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const InkAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [ink] element + QDomElement inkElement = document.createElement(QStringLiteral("ink")); + node.appendChild(inkElement); + + // append the optional attributes + if (d->m_inkPaths.count() < 1) + return; + + QList>::const_iterator pIt = d->m_inkPaths.begin(), pEnd = d->m_inkPaths.end(); + for (; pIt != pEnd; ++pIt) { + QDomElement pathElement = document.createElement(QStringLiteral("path")); + inkElement.appendChild(pathElement); + const QLinkedList &path = *pIt; + QLinkedList::const_iterator iIt = path.begin(), iEnd = path.end(); + for (; iIt != iEnd; ++iIt) { + const NormalizedPoint &point = *iIt; + QDomElement pointElement = document.createElement(QStringLiteral("point")); + pathElement.appendChild(pointElement); + pointElement.setAttribute(QStringLiteral("x"), QString::number(point.x)); + pointElement.setAttribute(QStringLiteral("y"), QString::number(point.y)); + } + } +} + +double InkAnnotationPrivate::distanceSqr(double x, double y, double xScale, double yScale) const +{ + double distance = DBL_MAX; + for (const QLinkedList &path : m_transformedInkPaths) { + const double thisDistance = ::distanceSqr(x, y, xScale, yScale, path); + if (thisDistance < distance) + distance = thisDistance; + } + return strokeDistance(distance, m_style.width() * xScale / (m_page->m_width * 2)); +} + +void InkAnnotationPrivate::transform(const QTransform &matrix) +{ + AnnotationPrivate::transform(matrix); + + for (int i = 0; i < m_transformedInkPaths.count(); ++i) { + QMutableLinkedListIterator it(m_transformedInkPaths[i]); + while (it.hasNext()) + it.next().transform(matrix); + } +} + +void InkAnnotationPrivate::baseTransform(const QTransform &matrix) +{ + AnnotationPrivate::baseTransform(matrix); + + for (int i = 0; i < m_inkPaths.count(); ++i) { + QMutableLinkedListIterator it(m_inkPaths[i]); + while (it.hasNext()) + it.next().transform(matrix); + } +} + +void InkAnnotationPrivate::resetTransformation() +{ + AnnotationPrivate::resetTransformation(); + + m_transformedInkPaths = m_inkPaths; +} + +void InkAnnotationPrivate::translate(const NormalizedPoint &coord) +{ + AnnotationPrivate::translate(coord); + + for (int i = 0; i < m_inkPaths.count(); ++i) { + QMutableLinkedListIterator it(m_inkPaths[i]); + while (it.hasNext()) { + NormalizedPoint &p = it.next(); + p.x = p.x + coord.x; + p.y = p.y + coord.y; + } + } +} + +void InkAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + m_inkPaths.clear(); + + // loop through the whole children looking for a 'ink' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("ink")) + continue; + + // parse the 'path' subnodes + QDomNode pathNode = e.firstChild(); + while (pathNode.isElement()) { + QDomElement pathElement = pathNode.toElement(); + pathNode = pathNode.nextSibling(); + + if (pathElement.tagName() != QLatin1String("path")) + continue; + + // build each path parsing 'point' subnodes + QLinkedList path; + QDomNode pointNode = pathElement.firstChild(); + while (pointNode.isElement()) { + QDomElement pointElement = pointNode.toElement(); + pointNode = pointNode.nextSibling(); + + if (pointElement.tagName() != QLatin1String("point")) + continue; + + NormalizedPoint p; + p.x = pointElement.attribute(QStringLiteral("x"), QStringLiteral("0.0")).toDouble(); + p.y = pointElement.attribute(QStringLiteral("y"), QStringLiteral("0.0")).toDouble(); + path.append(p); + } + + // add the path to the path list if it contains at least 2 nodes + if (path.count() >= 2) + m_inkPaths.append(path); + } + + // loading complete + break; + } + + m_transformedInkPaths = m_inkPaths; +} + +AnnotationPrivate *InkAnnotationPrivate::getNewAnnotationPrivate() +{ + return new InkAnnotationPrivate(); +} + +/** CaretAnnotation [Annotation] */ + +class Okular::CaretAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + CaretAnnotationPrivate() + : AnnotationPrivate() + , m_symbol(CaretAnnotation::None) + { + } + + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + CaretAnnotation::CaretSymbol m_symbol; +}; + +static QString caretSymbolToString(CaretAnnotation::CaretSymbol symbol) +{ + switch (symbol) { + case CaretAnnotation::None: + return QStringLiteral("None"); + case CaretAnnotation::P: + return QStringLiteral("P"); + } + return QString(); +} + +static CaretAnnotation::CaretSymbol caretSymbolFromString(const QString &symbol) +{ + if (symbol == QLatin1String("None")) + return CaretAnnotation::None; + else if (symbol == QLatin1String("P")) + return CaretAnnotation::P; + return CaretAnnotation::None; +} + +void CaretAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'caret' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("caret")) + continue; + + // parse the attributes + if (e.hasAttribute(QStringLiteral("symbol"))) + m_symbol = caretSymbolFromString(e.attribute(QStringLiteral("symbol"))); + + // loading complete + break; + } +} + +AnnotationPrivate *CaretAnnotationPrivate::getNewAnnotationPrivate() +{ + return new CaretAnnotationPrivate(); +} + +CaretAnnotation::CaretAnnotation() + : Annotation(*new CaretAnnotationPrivate()) +{ +} + +CaretAnnotation::CaretAnnotation(const QDomNode &description) + : Annotation(*new CaretAnnotationPrivate(), description) +{ +} + +CaretAnnotation::~CaretAnnotation() +{ +} + +void CaretAnnotation::setCaretSymbol(CaretAnnotation::CaretSymbol symbol) +{ + Q_D(CaretAnnotation); + d->m_symbol = symbol; +} + +CaretAnnotation::CaretSymbol CaretAnnotation::caretSymbol() const +{ + Q_D(const CaretAnnotation); + return d->m_symbol; +} + +Annotation::SubType CaretAnnotation::subType() const +{ + return ACaret; +} + +void CaretAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + Q_D(const CaretAnnotation); + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [caret] element + QDomElement caretElement = document.createElement(QStringLiteral("caret")); + node.appendChild(caretElement); + + // append the optional attributes + if (d->m_symbol != None) + caretElement.setAttribute(QStringLiteral("symbol"), caretSymbolToString(d->m_symbol)); +} + +/** FileAttachmentAnnotation [Annotation] */ + +class Okular::FileAttachmentAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + FileAttachmentAnnotationPrivate() + : AnnotationPrivate() + , icon(QStringLiteral("PushPin")) + , embfile(nullptr) + { + } + ~FileAttachmentAnnotationPrivate() override + { + delete embfile; + } + + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + // data fields + QString icon; + EmbeddedFile *embfile; +}; + +void FileAttachmentAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'fileattachment' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("fileattachment")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *FileAttachmentAnnotationPrivate::getNewAnnotationPrivate() +{ + return new FileAttachmentAnnotationPrivate(); +} + +FileAttachmentAnnotation::FileAttachmentAnnotation() + : Annotation(*new FileAttachmentAnnotationPrivate()) +{ +} + +FileAttachmentAnnotation::FileAttachmentAnnotation(const QDomNode &description) + : Annotation(*new FileAttachmentAnnotationPrivate(), description) +{ +} + +FileAttachmentAnnotation::~FileAttachmentAnnotation() +{ +} + +void FileAttachmentAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [fileattachment] element + QDomElement fileAttachmentElement = document.createElement(QStringLiteral("fileattachment")); + node.appendChild(fileAttachmentElement); +} + +Annotation::SubType FileAttachmentAnnotation::subType() const +{ + return AFileAttachment; +} + +QString FileAttachmentAnnotation::fileIconName() const +{ + Q_D(const FileAttachmentAnnotation); + return d->icon; +} + +void FileAttachmentAnnotation::setFileIconName(const QString &iconName) +{ + Q_D(FileAttachmentAnnotation); + d->icon = iconName; +} + +EmbeddedFile *FileAttachmentAnnotation::embeddedFile() const +{ + Q_D(const FileAttachmentAnnotation); + return d->embfile; +} + +void FileAttachmentAnnotation::setEmbeddedFile(EmbeddedFile *ef) +{ + Q_D(FileAttachmentAnnotation); + d->embfile = ef; +} + +/** SoundAnnotation [Annotation] */ + +class Okular::SoundAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + SoundAnnotationPrivate() + : AnnotationPrivate() + , icon(QStringLiteral("Speaker")) + , sound(nullptr) + { + } + ~SoundAnnotationPrivate() override + { + delete sound; + } + + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + // data fields + QString icon; + Sound *sound; +}; + +void SoundAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'sound' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("sound")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *SoundAnnotationPrivate::getNewAnnotationPrivate() +{ + return new SoundAnnotationPrivate(); +} + +SoundAnnotation::SoundAnnotation() + : Annotation(*new SoundAnnotationPrivate()) +{ +} + +SoundAnnotation::SoundAnnotation(const QDomNode &description) + : Annotation(*new SoundAnnotationPrivate(), description) +{ +} + +SoundAnnotation::~SoundAnnotation() +{ +} + +void SoundAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [sound] element + QDomElement soundElement = document.createElement(QStringLiteral("sound")); + node.appendChild(soundElement); +} + +Annotation::SubType SoundAnnotation::subType() const +{ + return ASound; +} + +QString SoundAnnotation::soundIconName() const +{ + Q_D(const SoundAnnotation); + return d->icon; +} + +void SoundAnnotation::setSoundIconName(const QString &iconName) +{ + Q_D(SoundAnnotation); + d->icon = iconName; +} + +Sound *SoundAnnotation::sound() const +{ + Q_D(const SoundAnnotation); + return d->sound; +} + +void SoundAnnotation::setSound(Sound *s) +{ + Q_D(SoundAnnotation); + d->sound = s; +} + +/** MovieAnnotation [Annotation] */ + +class Okular::MovieAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + MovieAnnotationPrivate() + : AnnotationPrivate() + , movie(nullptr) + { + } + ~MovieAnnotationPrivate() override + { + delete movie; + } + + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + // data fields + Movie *movie; +}; + +void MovieAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'movie' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("movie")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *MovieAnnotationPrivate::getNewAnnotationPrivate() +{ + return new MovieAnnotationPrivate(); +} + +MovieAnnotation::MovieAnnotation() + : Annotation(*new MovieAnnotationPrivate()) +{ +} + +MovieAnnotation::MovieAnnotation(const QDomNode &description) + : Annotation(*new MovieAnnotationPrivate(), description) +{ +} + +MovieAnnotation::~MovieAnnotation() +{ +} + +void MovieAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [movie] element + QDomElement movieElement = document.createElement(QStringLiteral("movie")); + node.appendChild(movieElement); +} + +Annotation::SubType MovieAnnotation::subType() const +{ + return AMovie; +} + +Movie *MovieAnnotation::movie() const +{ + Q_D(const MovieAnnotation); + return d->movie; +} + +void MovieAnnotation::setMovie(Movie *movie) +{ + Q_D(MovieAnnotation); + d->movie = movie; +} + +/** ScreenAnnotation [Annotation] */ + +class Okular::ScreenAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + ScreenAnnotationPrivate(); + ~ScreenAnnotationPrivate() override; + + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + Okular::Action *m_action; + QMap m_additionalActions; +}; + +ScreenAnnotationPrivate::ScreenAnnotationPrivate() + : m_action(nullptr) +{ +} + +ScreenAnnotationPrivate::~ScreenAnnotationPrivate() +{ + delete m_action; + qDeleteAll(m_additionalActions); +} + +void ScreenAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'screen' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("screen")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *ScreenAnnotationPrivate::getNewAnnotationPrivate() +{ + return new ScreenAnnotationPrivate(); +} + +ScreenAnnotation::ScreenAnnotation() + : Annotation(*new ScreenAnnotationPrivate()) +{ +} + +ScreenAnnotation::ScreenAnnotation(const QDomNode &description) + : Annotation(*new ScreenAnnotationPrivate(), description) +{ +} + +ScreenAnnotation::~ScreenAnnotation() +{ +} + +void ScreenAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [screen] element + QDomElement movieElement = document.createElement(QStringLiteral("screen")); + node.appendChild(movieElement); +} + +Annotation::SubType ScreenAnnotation::subType() const +{ + return AScreen; +} + +void ScreenAnnotation::setAdditionalAction(AdditionalActionType type, Action *action) +{ + Q_D(ScreenAnnotation); + if (d->m_additionalActions.contains(type)) + delete d->m_additionalActions.value(type); + + d->m_additionalActions.insert(type, action); +} + +Action *ScreenAnnotation::additionalAction(AdditionalActionType type) const +{ + Q_D(const ScreenAnnotation); + if (!d->m_additionalActions.contains(type)) + return nullptr; + else + return d->m_additionalActions.value(type); +} + +void ScreenAnnotation::setAction(Action *action) +{ + Q_D(ScreenAnnotation); + + delete d->m_action; + d->m_action = action; +} + +Action *ScreenAnnotation::action() const +{ + Q_D(const ScreenAnnotation); + return d->m_action; +} + +/** WidgetAnnotation [Annotation] */ + +class Okular::WidgetAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + ~WidgetAnnotationPrivate() override; + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + QMap m_additionalActions; +}; + +WidgetAnnotationPrivate::~WidgetAnnotationPrivate() +{ + qDeleteAll(m_additionalActions); +} + +void WidgetAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'widget' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("widget")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *WidgetAnnotationPrivate::getNewAnnotationPrivate() +{ + return new WidgetAnnotationPrivate(); +} + +WidgetAnnotation::WidgetAnnotation() + : Annotation(*new WidgetAnnotationPrivate()) +{ +} + +WidgetAnnotation::WidgetAnnotation(const QDomNode &description) + : Annotation(*new WidgetAnnotationPrivate, description) +{ +} + +WidgetAnnotation::~WidgetAnnotation() +{ +} + +void WidgetAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [widget] element + QDomElement movieElement = document.createElement(QStringLiteral("widget")); + node.appendChild(movieElement); +} + +Annotation::SubType WidgetAnnotation::subType() const +{ + return AWidget; +} + +void WidgetAnnotation::setAdditionalAction(AdditionalActionType type, Action *action) +{ + Q_D(WidgetAnnotation); + if (d->m_additionalActions.contains(type)) + delete d->m_additionalActions.value(type); + + d->m_additionalActions.insert(type, action); +} + +Action *WidgetAnnotation::additionalAction(AdditionalActionType type) const +{ + Q_D(const WidgetAnnotation); + if (!d->m_additionalActions.contains(type)) + return nullptr; + else + return d->m_additionalActions.value(type); +} + +/** RichMediaAnnotation [Annotation] */ + +class Okular::RichMediaAnnotationPrivate : public Okular::AnnotationPrivate +{ +public: + RichMediaAnnotationPrivate(); + ~RichMediaAnnotationPrivate() override; + void setAnnotationProperties(const QDomNode &node) override; + AnnotationPrivate *getNewAnnotationPrivate() override; + + // data fields + Movie *movie; + EmbeddedFile *embeddedFile; +}; + +RichMediaAnnotationPrivate::RichMediaAnnotationPrivate() + : movie(nullptr) + , embeddedFile(nullptr) +{ +} + +RichMediaAnnotationPrivate::~RichMediaAnnotationPrivate() +{ + delete movie; + delete embeddedFile; +} + +void RichMediaAnnotationPrivate::setAnnotationProperties(const QDomNode &node) +{ + Okular::AnnotationPrivate::setAnnotationProperties(node); + + // loop through the whole children looking for a 'richMedia' element + QDomNode subNode = node.firstChild(); + while (subNode.isElement()) { + QDomElement e = subNode.toElement(); + subNode = subNode.nextSibling(); + if (e.tagName() != QLatin1String("richMedia")) + continue; + + // loading complete + break; + } +} + +AnnotationPrivate *RichMediaAnnotationPrivate::getNewAnnotationPrivate() +{ + return new RichMediaAnnotationPrivate(); +} + +RichMediaAnnotation::RichMediaAnnotation() + : Annotation(*new RichMediaAnnotationPrivate()) +{ +} + +RichMediaAnnotation::RichMediaAnnotation(const QDomNode &description) + : Annotation(*new RichMediaAnnotationPrivate, description) +{ +} + +RichMediaAnnotation::~RichMediaAnnotation() +{ +} + +void RichMediaAnnotation::store(QDomNode &node, QDomDocument &document) const +{ + // recurse to parent objects storing properties + Annotation::store(node, document); + + // create [richMedia] element + QDomElement movieElement = document.createElement(QStringLiteral("richMedia")); + node.appendChild(movieElement); +} + +Annotation::SubType RichMediaAnnotation::subType() const +{ + return ARichMedia; +} + +void RichMediaAnnotation::setMovie(Movie *movie) +{ + Q_D(RichMediaAnnotation); + + delete d->movie; + d->movie = movie; +} + +Movie *RichMediaAnnotation::movie() const +{ + Q_D(const RichMediaAnnotation); + + return d->movie; +} + +EmbeddedFile *RichMediaAnnotation::embeddedFile() const +{ + Q_D(const RichMediaAnnotation); + + return d->embeddedFile; +} + +void RichMediaAnnotation::setEmbeddedFile(EmbeddedFile *embeddedFile) +{ + Q_D(RichMediaAnnotation); + + delete d->embeddedFile; + d->embeddedFile = embeddedFile; +} diff --git a/core/annotations.h b/core/annotations.h new file mode 100644 index 0000000..ffc9431 --- /dev/null +++ b/core/annotations.h @@ -0,0 +1,1753 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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_ANNOTATIONS_H_ +#define _OKULAR_ANNOTATIONS_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "area.h" +#include "okularcore_export.h" + +namespace Okular +{ +class Action; +class Annotation; +class AnnotationObjectRect; +class AnnotationPrivate; +class Document; +class EmbeddedFile; +class Page; +class PagePrivate; +class Sound; +class Movie; +class TextAnnotationPrivate; +class LineAnnotationPrivate; +class GeomAnnotationPrivate; +class HighlightAnnotationPrivate; +class StampAnnotationPrivate; +class InkAnnotationPrivate; +class CaretAnnotationPrivate; +class FileAttachmentAnnotationPrivate; +class SoundAnnotationPrivate; +class MovieAnnotationPrivate; +class ScreenAnnotationPrivate; +class WidgetAnnotationPrivate; +class RichMediaAnnotationPrivate; + +/** + * @short Helper class for (recursive) annotation retrieval/storage. + */ +class OKULARCORE_EXPORT AnnotationUtils +{ +public: + /** + * Restore an annotation (with revisions if needed) from the dom @p element. + * + * Returns a pointer to the complete annotation or 0 if element is invalid. + */ + static Annotation *createAnnotation(const QDomElement &element); + + /** + * Saves the @p annotation as a child of @p element taking + * care of saving all revisions if it has any. + */ + static void storeAnnotation(const Annotation *annotation, QDomElement &element, QDomDocument &document); + + /** + * Returns the child element with the given @p name from the direct + * children of @p parentNode or a null element if not found. + */ + static QDomElement findChildElement(const QDomNode &parentNode, const QString &name); + + /** + * Returns the geometry of the given @p annotation scaled by + * @p scaleX and @p scaleY. + */ + static QRect annotationGeometry(const Annotation *annotation, double scaleX, double scaleY); +}; + +/** + * @short Annotation struct holds properties shared by all annotations. + * + * An Annotation is an object (text note, highlight, sound, popup window, ..) + * contained by a Page in the document. + */ +class OKULARCORE_EXPORT Annotation +{ + /// @cond PRIVATE + friend class AnnotationObjectRect; + friend class Document; + friend class DocumentPrivate; + friend class ObjectRect; + friend class Page; + friend class PagePrivate; + /// @endcond + +public: + /** + * Describes the type of annotation as defined in PDF standard. + */ + enum SubType { + AText = 1, ///< A textual annotation + ALine = 2, ///< A line annotation + AGeom = 3, ///< A geometrical annotation + AHighlight = 4, ///< A highlight annotation + AStamp = 5, ///< A stamp annotation + AInk = 6, ///< An ink annotation + ACaret = 8, ///< A caret annotation + AFileAttachment = 9, ///< A file attachment annotation + ASound = 10, ///< A sound annotation + AMovie = 11, ///< A movie annotation + AScreen = 12, ///< A screen annotation + AWidget = 13, ///< A widget annotation + ARichMedia = 14, ///< A rich media annotation + A_BASE = 0 ///< The annotation base class + }; + + /** + * Describes additional properties of an annotation. + */ + enum Flag { + Hidden = 1, ///< Is not shown in the document + FixedSize = 2, ///< Has a fixed size + FixedRotation = 4, ///< Has a fixed rotation + DenyPrint = 8, ///< Cannot be printed + DenyWrite = 16, ///< Cannot be changed + DenyDelete = 32, ///< Cannot be deleted + ToggleHidingOnMouse = 64, ///< Can be hidden/shown by mouse click + External = 128, ///< Is stored external + ExternallyDrawn = 256, ///< Is drawn externally (by the generator which provided it) @since 0.10 (KDE 4.4) + BeingMoved = 512, ///< Is being moved (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 0.15 (KDE 4.9) + BeingResized = 1024 ///< Is being resized (mouse drag and drop). If ExternallyDrawn, the generator must not draw it @since 1.1.0 + }; + + /** + * Describes possible line styles for @see ALine annotation. + */ + enum LineStyle { + Solid = 1, ///< A solid line + Dashed = 2, ///< A dashed line + Beveled = 4, ///< A beveled line + Inset = 8, ///< An inset line + Underline = 16 ///< An underline + }; + + /** + * Describes possible line effects for @see ALine annotation. + */ + enum LineEffect { + NoEffect = 1, ///< No effect + Cloudy = 2 ///< The cloudy effect + }; + + /** + * Describes the scope of revision information. + */ + enum RevisionScope { + Reply = 1, ///< Belongs to a reply + Group = 2, ///< Belongs to a group + Delete = 4 ///< Belongs to a deleted paragraph + }; + + /** + * Describes the type of revision information. + */ + enum RevisionType { + None = 1, ///< Not specified + Marked = 2, ///< Is marked + Unmarked = 4, ///< Is unmarked + Accepted = 8, ///< Has been accepted + Rejected = 16, ///< Was rejected + Cancelled = 32, ///< Has been cancelled + Completed = 64 ///< Has been completed + }; + + /** + * Describes the type of additional actions. + * + * @since 0.16 (KDE 4.10) + */ + enum AdditionalActionType { + PageOpening, ///< Performed when the page containing the annotation is opened. + PageClosing, ///< Performed when the page containing the annotation is closed. + CursorEntering, ///< Performed when the cursor enters the annotation's active area @since 1.5 + CursorLeaving, ///< Performed when the cursor exists the annotation's active area @since 1.5 + MousePressed, ///< Performed when the mouse button is pressed inside the annotation's active area @since 1.5 + MouseReleased, ///< Performed when the mouse button is released inside the annotation's active area @since 1.5 + FocusIn, ///< Performed when the annotation receives the input focus @since 1.5 + FocusOut, ///< Performed when the annotation loses the input focus @since 1.5 + }; + + /** + * A function to be called when the annotation is destroyed. + * + * @warning the function must *not* call any virtual function, + * nor subcast. + * + * @since 0.7 (KDE 4.1) + */ + typedef void (*DisposeDataFunction)(const Okular::Annotation *); + + /** + * Destroys the annotation. + */ + virtual ~Annotation(); + + /** + * Sets the @p author of the annotation. + */ + void setAuthor(const QString &author); + + /** + * Returns the author of the annotation. + */ + QString author() const; + + /** + * Sets the @p contents of the annotation. + */ + void setContents(const QString &contents); + + /** + * Returns the contents of the annotation. + */ + QString contents() const; + + /** + * Sets the unique @p name of the annotation. + */ + void setUniqueName(const QString &name); + + /** + * Returns the unique name of the annotation. + */ + QString uniqueName() const; + + /** + * Sets the last modification @p date of the annotation. + * + * The date must be before or equal to QDateTime::currentDateTime() + */ + void setModificationDate(const QDateTime &date); + + /** + * Returns the last modification date of the annotation. + */ + QDateTime modificationDate() const; + + /** + * Sets the creation @p date of the annotation. + * + * The date must be before or equal to @see modificationDate() + */ + void setCreationDate(const QDateTime &date); + + /** + * Returns the creation date of the annotation. + */ + QDateTime creationDate() const; + + /** + * Sets the @p flags of the annotation. + * @see @ref Flag + */ + void setFlags(int flags); + + /** + * Returns the flags of the annotation. + * @see @ref Flag + */ + int flags() const; + + /** + * Sets the bounding @p rectangle of the annotation. + */ + void setBoundingRectangle(const NormalizedRect &rectangle); + + /** + * Returns the bounding rectangle of the annotation. + */ + NormalizedRect boundingRectangle() const; + + /** + * Returns the transformed bounding rectangle of the annotation. + * + * This rectangle must be used when showing annotations on screen + * to have them rotated correctly. + */ + NormalizedRect transformedBoundingRectangle() const; + + /** + * Move the annotation by the specified coordinates. + * + * @see canBeMoved() + */ + void translate(const NormalizedPoint &coord); + + /** + * Adjust the annotation by the specified coordinates. + * Adds coordinates of @p deltaCoord1 to annotations top left corner, + * and @p deltaCoord2 to the bottom right. + * + * @see canBeResized() + */ + void adjust(const NormalizedPoint &deltaCoord1, const NormalizedPoint &deltaCoord2); + + /** + * The Style class contains all information about style of the + * annotation. + */ + class OKULARCORE_EXPORT Style + { + public: + /** + * Creates a new style. + */ + Style(); + + /** + * Destroys the style. + */ + ~Style(); + + Style(const Style &other); + Style &operator=(const Style &other); + + /** + * Sets the @p color of the style. + */ + void setColor(const QColor &color); + + /** + * Returns the color of the style. + */ + QColor color() const; + + /** + * Sets the @p opacity of the style. + */ + void setOpacity(double opacity); + + /** + * Returns the opacity of the style. + */ + double opacity() const; + + /** + * Sets the @p width of the style. + */ + void setWidth(double width); + + /** + * Returns the width of the style. + */ + double width() const; + + /** + * Sets the line @p style of the style. + */ + void setLineStyle(LineStyle style); + + /** + * Returns the line style of the style. + */ + LineStyle lineStyle() const; + + /** + * Sets the x-corners of the style. + */ + void setXCorners(double xCorners); + + /** + * Returns the x-corners of the style. + */ + double xCorners() const; + + /** + * Sets the y-corners of the style. + */ + void setYCorners(double yCorners); + + /** + * Returns the y-corners of the style. + */ + double yCorners() const; + + /** + * Sets the @p marks of the style. + */ + void setMarks(int marks); + + /** + * Returns the marks of the style. + */ + int marks() const; + + /** + * Sets the @p spaces of the style. + */ + void setSpaces(int spaces); + + /** + * Returns the spaces of the style. + */ + int spaces() const; + + /** + * Sets the line @p effect of the style. + */ + void setLineEffect(LineEffect effect); + + /** + * Returns the line effect of the style. + */ + LineEffect lineEffect() const; + + /** + * Sets the effect @p intensity of the style. + */ + void setEffectIntensity(double intensity); + + /** + * Returns the effect intensity of the style. + */ + double effectIntensity() const; + + private: + class Private; + Private *const d; + }; + + /** + * Returns a reference to the style object of the annotation. + */ + Style &style(); + + /** + * Returns a const reference to the style object of the annotation. + */ + const Style &style() const; + + /** + * The Window class contains all information about the popup window + * of the annotation that is used to edit the content and properties. + */ + class OKULARCORE_EXPORT Window + { + public: + /** + * Creates a new window. + */ + Window(); + + /** + * Destroys the window. + */ + ~Window(); + + Window(const Window &other); + Window &operator=(const Window &other); + + /** + * Sets the @p flags of the window. + */ + void setFlags(int flags); + + /** + * Returns the flags of the window. + */ + int flags() const; + + /** + * Sets the top-left @p point of the window. + */ + void setTopLeft(const NormalizedPoint &point); + + /** + * Returns the top-left point of the window. + */ + NormalizedPoint topLeft() const; + + /** + * Sets the @p width of the window. + */ + void setWidth(int width); + + /** + * Returns the width of the window. + */ + int width() const; + + /** + * Sets the @p height of the window. + */ + void setHeight(int height); + + /** + * Returns the height of the window. + */ + int height() const; + + /** + * Sets the @p title of the window. + */ + void setTitle(const QString &title); + + /** + * Returns the title of the window. + */ + QString title() const; + + /** + * Sets the @p summary of the window. + */ + void setSummary(const QString &summary); + + /** + * Returns the summary of the window. + */ + QString summary() const; + + private: + class Private; + Private *const d; + }; + + /** + * Returns a reference to the window object of the annotation. + */ + Window &window(); + + /** + * Returns a const reference to the window object of the annotation. + */ + const Window &window() const; + + /** + * The Revision class contains all information about the revision + * of the annotation. + */ + class OKULARCORE_EXPORT Revision + { + public: + /** + * Creates a new revision. + */ + Revision(); + + /** + * Destroys the revision. + */ + ~Revision(); + + Revision(const Revision &other); + Revision &operator=(const Revision &other); + + /** + * Sets the @p annotation the revision belongs to. + */ + void setAnnotation(Annotation *annotation); + + /** + * Returns the annotation the revision belongs to. + */ + Annotation *annotation() const; + + /** + * Sets the @p scope of the revision. + * @see RevisionScope + */ + void setScope(RevisionScope scope); + + /** + * Returns the scope of the revision. + */ + RevisionScope scope() const; + + /** + * Sets the @p type of the revision. + * @see RevisionType + */ + void setType(RevisionType type); + + /** + * Returns the type of the revision. + */ + RevisionType type() const; + + private: + class Private; + Private *const d; + }; + + /** + * Returns a reference to the revision list of the annotation. + */ + QLinkedList &revisions(); + + /** + * Returns a reference to the revision list of the annotation. + */ + const QLinkedList &revisions() const; + + /** + * Sets the "native" @p id of the annotation. + * + * This is for use of the Generator, that can optionally store an + * handle (a pointer, an identifier, etc) of the "native" annotation + * object, if any. + * + * @note Okular makes no use of this + * + * @since 0.7 (KDE 4.1) + */ + void setNativeId(const QVariant &id); + + /** + * Returns the "native" id of the annotation. + * + * @since 0.7 (KDE 4.1) + */ + QVariant nativeId() const; + + /** + * Sets a function to be called when the annotation is destroyed. + * + * @warning the function must *not* call any virtual function, + * nor subcast. + * + * @since 0.7 (KDE 4.1) + */ + void setDisposeDataFunction(DisposeDataFunction func); + + /** + * Returns whether the annotation can be moved. + * + * @since 0.7 (KDE 4.1) + */ + bool canBeMoved() const; + + /** + * Returns whether the annotation can be resized. + */ + bool canBeResized() const; + + /** + * Returns whether the annotation dialog should be open after creation of the annotation or not + * + * @since 0.13 (KDE 4.7) + */ + bool openDialogAfterCreation() const; + + /** + * Returns the sub type of the annotation. + */ + virtual SubType subType() const = 0; + + /** + * Stores the annotation as xml in @p document under the given parent @p node. + */ + virtual void store(QDomNode &node, QDomDocument &document) const; + + /** + * Retrieve the QDomNode representing this annotation's properties + + * @since 0.17 (KDE 4.11) + */ + QDomNode getAnnotationPropertiesDomNode() const; + + /** + * Sets annotations internal properties according to the contents of @p node + * + * @since 0.17 (KDE 4.11) + */ + void setAnnotationProperties(const QDomNode &node); + +protected: + /// @cond PRIVATE + Annotation(AnnotationPrivate &dd); + Annotation(AnnotationPrivate &dd, const QDomNode &description); + Q_DECLARE_PRIVATE(Annotation) + AnnotationPrivate *d_ptr; + /// @endcond + +private: + Q_DISABLE_COPY(Annotation) +}; + +/** + * @short Native annotation interface + * + * Generators can subclass it to provide native annotation support. + * Generators can use Annotation::setNativeId to store per-annotation data. + * + * @since 0.15 (KDE 4.9) + */ +class OKULARCORE_EXPORT AnnotationProxy +{ +public: + enum Capability { + Addition, ///< Generator can create native annotations + Modification, ///< Generator can edit native annotations + Removal ///< Generator can remove native annotations + }; + + AnnotationProxy(); + + /** + * Destroys the annotation proxy. + */ + virtual ~AnnotationProxy(); + + AnnotationProxy(const AnnotationProxy &) = delete; + AnnotationProxy &operator=(const AnnotationProxy &) = delete; + + /** + * Query for the supported capabilities. + */ + virtual bool supports(Capability capability) const = 0; + + /** + * Called when a new @p annotation is added to a @p page. + * + * @note Only called if supports(Addition) == true + */ + virtual void notifyAddition(Annotation *annotation, int page) = 0; + + /** + * Called after an existing @p annotation at a given @p page is modified. + * + * Generator can call @p annotation getters to get the new values. + * @p appearanceChanged tells if a non-visible property was modified + * + * @note Only called if supports(Modification) == true + */ + virtual void notifyModification(const Annotation *annotation, int page, bool appearanceChanged) = 0; + + /** + * Called when an existing @p annotation at a given @p page is removed. + * + * @note Only called if supports(Removal) == true + */ + virtual void notifyRemoval(Annotation *annotation, int page) = 0; +}; + +class OKULARCORE_EXPORT TextAnnotation : public Annotation +{ +public: + /** + * Describes the type of the text. + */ + enum TextType { + Linked, ///< The annotation is linked to a text + InPlace ///< The annotation is located next to the text + }; + + /** + * Describes the style of the text. + */ + enum InplaceIntent { + Unknown, ///< Unknown style + Callout, ///< Callout style + TypeWriter ///< Type writer style + }; + + /** + * Creates a new text annotation. + */ + TextAnnotation(); + + /** + * Creates a new text annotation from the xml @p description + */ + explicit TextAnnotation(const QDomNode &description); + + /** + * Destroys the text annotation. + */ + ~TextAnnotation() override; + + /** + * Sets the text @p type of the text annotation. + * @see TextType + */ + void setTextType(TextType type); + + /** + * Returns the text type of the text annotation. + */ + TextType textType() const; + + /** + * Sets the @p icon of the text annotation. + */ + void setTextIcon(const QString &icon); + + /** + * Returns the icon of the text annotation. + */ + QString textIcon() const; + + /** + * Sets the @p font of the text annotation. + */ + void setTextFont(const QFont &font); + + /** + * Returns the font of the text annotation. + */ + QFont textFont() const; + + /** + * Sets the @p color of inplace text. + * + * @since 1.6 + */ + void setTextColor(const QColor &color); + + /** + * Returns the color of inplace text. + * + * @since 1.6 + */ + QColor textColor() const; + + /** + * Sets the inplace @p alignment of the text annotation. + * 0:left, 1:center, 2:right + */ + void setInplaceAlignment(int alignment); + + /** + * Returns the inplace alignment of the text annotation. + * 0:left, 1:center, 2:right + */ + int inplaceAlignment() const; + + /** + * Sets the inplace callout @p point at @p index. + * + * @p index must be between 0 and 2. + */ + void setInplaceCallout(const NormalizedPoint &point, int index); + + /** + * Returns the inplace callout point for @p index. + * + * @p index must be between 0 and 2. + */ + NormalizedPoint inplaceCallout(int index) const; + + /** + * Returns the transformed (e.g. rotated) inplace callout point for @p index. + * + * @p index must be between 0 and 2. + */ + NormalizedPoint transformedInplaceCallout(int index) const; + + /** + * Returns the inplace @p intent of the text annotation. + * @see InplaceIntent + */ + void setInplaceIntent(InplaceIntent intent); + + /** + * Returns the inplace intent of the text annotation. + */ + InplaceIntent inplaceIntent() const; + + /** + * Returns the sub type of the text annotation. + */ + SubType subType() const override; + + /** + * Stores the text annotation as xml in @p document under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(TextAnnotation) + Q_DISABLE_COPY(TextAnnotation) +}; + +class OKULARCORE_EXPORT LineAnnotation : public Annotation +{ +public: + /** + * Describes the line ending style. + */ + enum TermStyle { + Square, ///< Using a square + Circle, ///< Using a circle + Diamond, ///< Using a diamond + OpenArrow, ///< Using an open arrow + ClosedArrow, ///< Using a closed arrow + None, ///< No special ending style + Butt, ///< Using a butt ending + ROpenArrow, ///< Using an arrow opened at the right side + RClosedArrow, ///< Using an arrow closed at the right side + Slash ///< Using a slash + }; + + /** + * Describes the line intent. + */ + enum LineIntent { + Unknown, ///< Unknown intent + Arrow, ///< Arrow intent + Dimension, ///< Dimension intent + PolygonCloud ///< Polygon cloud intent + }; + + /** + * Creates a new line annotation. + */ + LineAnnotation(); + + /** + * Creates a new line annotation from the xml @p description + */ + explicit LineAnnotation(const QDomNode &description); + + /** + * Destroys the line annotation. + */ + ~LineAnnotation() override; + + /** + * Sets the normalized line @p points of the line annotation. + */ + void setLinePoints(const QLinkedList &points); + + /** + * Returns the normalized line points of the line annotation. + */ + QLinkedList linePoints() const; + + /** + * Returns the transformed (e.g. rotated) normalized line points + * of the line annotation. + */ + QLinkedList transformedLinePoints() const; + + /** + * Sets the line starting @p style of the line annotation. + * @see TermStyle + */ + void setLineStartStyle(TermStyle style); + + /** + * Returns the line starting style of the line annotation. + */ + TermStyle lineStartStyle() const; + + /** + * Sets the line ending @p style of the line annotation. + * @see TermStyle + */ + void setLineEndStyle(TermStyle style); + + /** + * Returns the line ending style of the line annotation. + */ + TermStyle lineEndStyle() const; + + /** + * Sets whether the line shall be @p closed. + */ + void setLineClosed(bool closed); + + /** + * Returns whether the line shall be closed. + */ + bool lineClosed() const; + + /** + * Sets the inner line @p color of the line annotation. + */ + void setLineInnerColor(const QColor &color); + + /** + * Returns the inner line color of the line annotation. + */ + QColor lineInnerColor() const; + + /** + * Sets the leading forward @p point of the line annotation. + */ + void setLineLeadingForwardPoint(double point); + + /** + * Returns the leading forward point of the line annotation. + */ + double lineLeadingForwardPoint() const; + + /** + * Sets the leading backward @p point of the line annotation. + */ + void setLineLeadingBackwardPoint(double point); + + /** + * Returns the leading backward point of the line annotation. + */ + double lineLeadingBackwardPoint() const; + + /** + * Sets whether the caption shall be @p shown. + */ + void setShowCaption(bool shown); + + /** + * Returns whether the caption shall be shown. + */ + bool showCaption() const; + + /** + * Sets the line @p intent of the line annotation. + * @see LineIntent + */ + void setLineIntent(LineIntent intent); + + /** + * Returns the line intent of the line annotation. + */ + LineIntent lineIntent() const; + + /** + * Returns the sub type of the line annotation. + */ + SubType subType() const override; + + /** + * Stores the line annotation as xml in @p document under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(LineAnnotation) + Q_DISABLE_COPY(LineAnnotation) +}; + +class OKULARCORE_EXPORT GeomAnnotation : public Annotation +{ +public: + // common enums + enum GeomType { + InscribedSquare, ///< Draw a square + InscribedCircle ///< Draw a circle + }; + + /** + * Creates a new geometrical annotation. + */ + GeomAnnotation(); + + /** + * Creates a new geometrical annotation from the xml @p description + */ + explicit GeomAnnotation(const QDomNode &description); + + /** + * Destroys the geometrical annotation. + */ + ~GeomAnnotation() override; + + /** + * Sets the geometrical @p type of the geometrical annotation. + * @see GeomType + */ + void setGeometricalType(GeomType type); + + /** + * Returns the geometrical type of the geometrical annotation. + */ + GeomType geometricalType() const; + + /** + * Sets the inner @p color of the geometrical annotation. + */ + void setGeometricalInnerColor(const QColor &color); + + /** + * Returns the inner color of the geometrical annotation. + */ + QColor geometricalInnerColor() const; + + /** + * Returns the sub type of the geometrical annotation. + */ + SubType subType() const override; + + /** + * Stores the geometrical annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(GeomAnnotation) + Q_DISABLE_COPY(GeomAnnotation) +}; + +class OKULARCORE_EXPORT HighlightAnnotation : public Annotation +{ +public: + /** + * Describes the highlighting style of the annotation. + */ + enum HighlightType { + Highlight, ///< Highlights the text + Squiggly, ///< Squiggles the text + Underline, ///< Underlines the text + StrikeOut ///< Strikes out the text + }; + + /** + * Creates a new highlight annotation. + */ + HighlightAnnotation(); + + /** + * Creates a new highlight annotation from the xml @p description + */ + explicit HighlightAnnotation(const QDomNode &description); + + /** + * Destroys the highlight annotation. + */ + ~HighlightAnnotation() override; + + /** + * Sets the @p type of the highlight annotation. + * @see HighlightType + */ + void setHighlightType(HighlightType type); + + /** + * Returns the type of the highlight annotation. + */ + HighlightType highlightType() const; + + /** + * @short Describes a highlight quad of a text markup annotation. + * + * The Quad is a closed path of 4 NormalizedPoints. + * Another set of 4 NormalizedPoints can be generated with transform(), + * e. g. to get highlighting coordinates on a rotated PageViewItem. + * Additionally, Quad stores some geometry related style attributes. + * + * To enable correct rendering of the annotation, + * the points 0 and 1 must describe the bottom edge of the quad + * (relative to the text orientation). + * + * @see NormalizedPoint + */ + class OKULARCORE_EXPORT Quad + { + public: + /** + * Creates a new quad. + */ + Quad(); + + /** + * Destroys the quad. + */ + ~Quad(); + + Quad(const Quad &other); + Quad &operator=(const Quad &other); + + /** + * Sets the normalized @p point at @p index. + * + * @p index must be between 0 and 3. + */ + void setPoint(const NormalizedPoint &point, int index); + + /** + * Returns the normalized point at @p index. + * + * @p index must be between 0 and 3. + */ + NormalizedPoint point(int index) const; + + /** + * Returns the transformed (e.g. rotated) normalized point at @p index. + * + * @p index must be between 0 and 3. + */ + NormalizedPoint transformedPoint(int index) const; + + /** + * Sets whether a cap should be used at the start. + */ + void setCapStart(bool value); + + /** + * Returns whether a cap should be used at the start. + */ + bool capStart() const; + + /** + * Sets whether a cap should be used at the end. + */ + void setCapEnd(bool value); + + /** + * Returns whether a cap should be used at the end. + */ + bool capEnd() const; + + /** + * Sets the @p width of the drawing feather. + */ + void setFeather(double width); + + /** + * Returns the width of the drawing feather. + */ + double feather() const; + + /** + * Transforms the quad coordinates with the transformation defined + * by @p matrix. + * + * The transformed coordinates will be accessible with transformedPoint(). + * The coordinates returned by point() are not affected. + */ + void transform(const QTransform &matrix); + + private: + class Private; + Private *const d; + }; + + /** + * Returns a reference to the quad list of the highlight annotation. + */ + QList &highlightQuads(); + + /** + * Returns the sub type of the highlight annotation. + */ + SubType subType() const override; + + /** + * Stores the highlight annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(HighlightAnnotation) + Q_DISABLE_COPY(HighlightAnnotation) +}; + +class OKULARCORE_EXPORT StampAnnotation : public Annotation +{ +public: + /** + * Creates a new stamp annotation. + */ + StampAnnotation(); + + /** + * Creates a new stamp annotation from the xml @p description + */ + explicit StampAnnotation(const QDomNode &description); + + /** + * Destroys the stamp annotation. + */ + ~StampAnnotation() override; + + /** + * Sets the @p name of the icon for the stamp annotation. + */ + void setStampIconName(const QString &name); + + /** + * Returns the name of the icon. + */ + QString stampIconName() const; + + /** + * Returns the sub type of the stamp annotation. + */ + SubType subType() const override; + + /** + * Stores the stamp annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(StampAnnotation) + Q_DISABLE_COPY(StampAnnotation) +}; + +class OKULARCORE_EXPORT InkAnnotation : public Annotation +{ +public: + /** + * Creates a new ink annotation. + */ + InkAnnotation(); + + /** + * Creates a new ink annotation from the xml @p description + */ + explicit InkAnnotation(const QDomNode &description); + + /** + * Destroys the ink annotation. + */ + ~InkAnnotation() override; + + /** + * Sets the @p paths of points for the ink annotation. + */ + void setInkPaths(const QList> &paths); + + /** + * Returns the paths of points of the ink annotation. + */ + QList> inkPaths() const; + + /** + * Returns the paths of transformed (e.g. rotated) points of + * the ink annotation. + */ + QList> transformedInkPaths() const; + + /** + * Returns the sub type of the ink annotation. + */ + SubType subType() const override; + + /** + * Stores the ink annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(InkAnnotation) + Q_DISABLE_COPY(InkAnnotation) +}; + +class OKULARCORE_EXPORT CaretAnnotation : public Annotation +{ +public: + /** + * Describes the highlighting style of the annotation. + */ + enum CaretSymbol { + None, ///< No symbol to be associated with the text + P ///< A 'paragraph' symbol + }; + + /** + * Creates a new caret annotation. + */ + CaretAnnotation(); + + /** + * Creates a new caret annotation from the xml @p description + */ + explicit CaretAnnotation(const QDomNode &description); + + /** + * Destroys the caret annotation. + */ + ~CaretAnnotation() override; + + /** + * Sets the @p symbol for the caret annotation. + */ + void setCaretSymbol(CaretAnnotation::CaretSymbol symbol); + + /** + * Returns the symbol of the annotation. + */ + CaretAnnotation::CaretSymbol caretSymbol() const; + + /** + * Returns the sub type of the caret annotation. + */ + SubType subType() const override; + + /** + * Stores the caret annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(CaretAnnotation) + Q_DISABLE_COPY(CaretAnnotation) +}; + +class OKULARCORE_EXPORT FileAttachmentAnnotation : public Annotation +{ +public: + /** + * Creates a new file attachment annotation. + */ + FileAttachmentAnnotation(); + /** + * Creates a new file attachment annotation from the xml @p description + */ + explicit FileAttachmentAnnotation(const QDomNode &description); + /** + * Destroys the file attachment annotation. + */ + ~FileAttachmentAnnotation() override; + + /** + * Gets the name of the icon. + */ + QString fileIconName() const; + + /** + * Sets the @p iconName of the icon for the file attachment annotation. + */ + void setFileIconName(const QString &iconName); + + /** + * Gets the embedded file object. + */ + EmbeddedFile *embeddedFile() const; + + /** + * Sets the @p ef representing the embedded file of the file + * attachment annotation. + */ + void setEmbeddedFile(EmbeddedFile *ef); + + /** + * Returns the sub type of the file attachment annotation. + */ + SubType subType() const override; + + /** + * Stores the file attachment annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(FileAttachmentAnnotation) + Q_DISABLE_COPY(FileAttachmentAnnotation) +}; + +/** + * \short Sound annotation. + * + * The sound annotation represents a sound to be played when activated. + * + * @since 0.7 (KDE 4.1) + */ +class OKULARCORE_EXPORT SoundAnnotation : public Annotation +{ +public: + /** + * Creates a new sound annotation. + */ + SoundAnnotation(); + /** + * Creates a new sound annotation from the xml @p description + */ + explicit SoundAnnotation(const QDomNode &description); + /** + * Destroys the sound annotation. + */ + ~SoundAnnotation() override; + + /** + * Gets the name of the icon. + */ + QString soundIconName() const; + + /** + * Sets the @p iconName of the icon for the sound annotation. + */ + void setSoundIconName(const QString &iconName); + + /** + * Gets the sound object. + */ + Sound *sound() const; + + /** + * Sets the @p s representing the sound of the file + * attachment annotation. + */ + void setSound(Sound *s); + + /** + * Returns the sub type of the sound annotation. + */ + SubType subType() const override; + + /** + * Stores the sound annotation as xml in @p document + * under the given parent @p node. + */ + void store(QDomNode &node, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(SoundAnnotation) + Q_DISABLE_COPY(SoundAnnotation) +}; + +/** + * \short Movie annotation. + * + * The movie annotation represents a movie to be played when activated. + * + * @since 0.8 (KDE 4.2) + */ +class OKULARCORE_EXPORT MovieAnnotation : public Annotation +{ +public: + /** + * Creates a new movie annotation. + */ + MovieAnnotation(); + /** + * Creates a new movie annotation from the xml @p description + */ + explicit MovieAnnotation(const QDomNode &description); + /** + * Destroys the movie annotation. + */ + ~MovieAnnotation() override; + /** + * Gets the movie object. + */ + Movie *movie() const; + /** + * Sets the new @p movie object. + */ + void setMovie(Movie *movie); + /** + * Returns the sub type of the movie annotation. + */ + SubType subType() const override; + /** + * Stores the movie annotation as xml in @p document + * under the given @p parentNode. + */ + void store(QDomNode &parentNode, QDomDocument &document) const override; + +private: + Q_DECLARE_PRIVATE(MovieAnnotation) + Q_DISABLE_COPY(MovieAnnotation) +}; + +/** + * \short Screen annotation. + * + * The screen annotation specifies a region of a page upon which media clips + * may be played. It also serves as an object from which actions can be triggered. + * + * @since 0.16 (KDE 4.10) + */ +class OKULARCORE_EXPORT ScreenAnnotation : public Annotation +{ +public: + /** + * Creates a new screen annotation. + */ + ScreenAnnotation(); + + /** + * Creates a new screen annotation from the xml @p description + */ + explicit ScreenAnnotation(const QDomNode &description); + + /** + * Destroys the screen annotation. + */ + ~ScreenAnnotation() override; + + /** + * Returns the sub type of the screen annotation. + */ + SubType subType() const override; + + /** + * Stores the screen annotation as xml in @p document + * under the given @p parentNode. + */ + void store(QDomNode &parentNode, QDomDocument &document) const override; + + /** + * Sets the @p action that is executed when the annotation is triggered. + * + * @since 0.16 (KDE 4.10) + */ + void setAction(Action *action); + + /** + * Returns the action that is executed when the annotation is triggered or @c 0 if not action has been defined. + * + * @since 0.16 (KDE 4.10) + */ + Action *action() const; + + /** + * Sets the additional @p action of the given @p type. + * + * @since 0.16 (KDE 4.10) + */ + void setAdditionalAction(AdditionalActionType type, Action *action); + + /** + * Returns the additional action of the given @p type or @c 0 if no action has been defined. + * + * @since 0.16 (KDE 4.10) + */ + Action *additionalAction(AdditionalActionType type) const; + +private: + Q_DECLARE_PRIVATE(ScreenAnnotation) + Q_DISABLE_COPY(ScreenAnnotation) +}; + +/** + * \short Widget annotation. + * + * The widget annotation represents a widget on a page. + * + * @since 0.16 (KDE 4.10) + */ +class OKULARCORE_EXPORT WidgetAnnotation : public Annotation +{ +public: + /** + * Creates a new widget annotation. + */ + WidgetAnnotation(); + + /** + * Creates a new widget annotation from the xml @p description + */ + explicit WidgetAnnotation(const QDomNode &description); + + /** + * Destroys the widget annotation. + */ + ~WidgetAnnotation() override; + + /** + * Returns the sub type of the widget annotation. + */ + SubType subType() const override; + + /** + * Stores the widget annotation as xml in @p document + * under the given @p parentNode. + */ + void store(QDomNode &parentNode, QDomDocument &document) const override; + + /** + * Sets the additional @p action of the given @p type. + * + * @since 0.16 (KDE 4.10) + */ + void setAdditionalAction(AdditionalActionType type, Action *action); + + /** + * Returns the additional action of the given @p type or @c 0 if no action has been defined. + * + * @since 0.16 (KDE 4.10) + */ + Action *additionalAction(AdditionalActionType type) const; + +private: + Q_DECLARE_PRIVATE(WidgetAnnotation) + Q_DISABLE_COPY(WidgetAnnotation) +}; + +/** + * \short RichMedia annotation. + * + * The rich media annotation represents an video or sound on a page. + * + * @since 1.0 + */ +class OKULARCORE_EXPORT RichMediaAnnotation : public Annotation +{ +public: + /** + * Creates a new rich media annotation. + */ + RichMediaAnnotation(); + + /** + * Creates a new rich media annotation from the xml @p description + */ + explicit RichMediaAnnotation(const QDomNode &description); + + /** + * Destroys the rich media annotation. + */ + ~RichMediaAnnotation() override; + + /** + * Returns the sub type of the rich media annotation. + */ + SubType subType() const override; + + /** + * Stores the rich media annotation as xml in @p document + * under the given @p parentNode. + */ + void store(QDomNode &parentNode, QDomDocument &document) const override; + + /** + * Gets the movie object. + */ + Movie *movie() const; + + /** + * Sets the new @p movie object. + */ + void setMovie(Movie *movie); + + /** + * Sets the @p embeddedFile representing the embedded file. + */ + void setEmbeddedFile(EmbeddedFile *embeddedFile); + + /** + * Gets the embedded file object. + */ + EmbeddedFile *embeddedFile() const; + +private: + Q_DECLARE_PRIVATE(RichMediaAnnotation) + Q_DISABLE_COPY(RichMediaAnnotation) +}; + +} + +#endif diff --git a/core/annotations_p.h b/core/annotations_p.h new file mode 100644 index 0000000..b48e4f6 --- /dev/null +++ b/core/annotations_p.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2007 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_ANNOTATIONS_P_H +#define OKULAR_ANNOTATIONS_P_H + +#include "annotations.h" +#include "area.h" + +// qt/kde includes +#include +#include +#include +#include + +class QTransform; + +namespace Okular +{ +class PagePrivate; + +class AnnotationPrivate +{ +public: + AnnotationPrivate(); + + virtual ~AnnotationPrivate(); + + AnnotationPrivate(const AnnotationPrivate &) = delete; + AnnotationPrivate &operator=(const AnnotationPrivate &) = delete; + + /** + * Transforms the annotation coordinates with the transformation + * defined by @p matrix. + */ + void annotationTransform(const QTransform &matrix); + + virtual void transform(const QTransform &matrix); + virtual void baseTransform(const QTransform &matrix); + virtual void resetTransformation(); + virtual void translate(const NormalizedPoint &coord); + virtual void adjust(const NormalizedPoint &deltaCoord1, const NormalizedPoint &deltaCoord2); + virtual bool openDialogAfterCreation() const; + virtual void setAnnotationProperties(const QDomNode &node); + virtual bool canBeResized() const; + virtual AnnotationPrivate *getNewAnnotationPrivate() = 0; + + /** + * Determines the distance of the closest point of the annotation to the + * given point @p x @p y @p xScale @p yScale + * @since 0.17 + */ + virtual double distanceSqr(double x, double y, double xScale, double yScale) const; + + PagePrivate *m_page; + + QString m_author; + QString m_contents; + QString m_uniqueName; + QDateTime m_modifyDate; + QDateTime m_creationDate; + + int m_flags; + NormalizedRect m_boundary; + NormalizedRect m_transformedBoundary; + + Okular::Annotation::Style m_style; + Okular::Annotation::Window m_window; + QLinkedList m_revisions; + + Annotation::DisposeDataFunction m_disposeFunc; + QVariant m_nativeId; +}; + +} + +#endif diff --git a/core/area.cpp b/core/area.cpp new file mode 100644 index 0000000..549c59f --- /dev/null +++ b/core/area.cpp @@ -0,0 +1,501 @@ +/*************************************************************************** + * Copyright (C) 2004-05 by Enrico Ros * + * Copyright (C) 2005 by Piotr Szymanski * + * 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. * + ***************************************************************************/ + +#include "area.h" + +#include +#include + +#include "action.h" +#include "annotations.h" +#include "annotations_p.h" +#include "debug_p.h" +#include "sourcereference.h" + +using namespace Okular; + +/** class NormalizedPoint **/ +NormalizedPoint::NormalizedPoint() + : x(0.0) + , y(0.0) +{ +} + +NormalizedPoint::NormalizedPoint(double dX, double dY) + : x(dX) + , y(dY) +{ +} + +NormalizedPoint::NormalizedPoint(int iX, int iY, int xScale, int yScale) + : x((double)iX / (double)xScale) + , y((double)iY / (double)yScale) +{ +} + +NormalizedPoint &NormalizedPoint::operator=(const NormalizedPoint &p) = default; +NormalizedPoint::NormalizedPoint(const NormalizedPoint &) = default; +NormalizedPoint::~NormalizedPoint() = default; + +void NormalizedPoint::transform(const QTransform &matrix) +{ + qreal tmp_x = (qreal)x; + qreal tmp_y = (qreal)y; + matrix.map(tmp_x, tmp_y, &tmp_x, &tmp_y); + x = tmp_x; + y = tmp_y; +} + +double NormalizedPoint::distanceSqr(double x, double y, double xScale, double yScale) const +{ + return pow((this->x - x) * xScale, 2) + pow((this->y - y) * yScale, 2); +} + +/** + * Returns a vector from the given points @p a and @p b + * @internal + */ +NormalizedPoint operator-(const NormalizedPoint &a, const NormalizedPoint &b) +{ + return NormalizedPoint(a.x - b.x, a.y - b.y); +} + +/** + * @brief Calculates distance of the point @p x @p y @p xScale @p yScale to the line segment from @p start to @p end + */ +double NormalizedPoint::distanceSqr(double x, double y, double xScale, double yScale, const NormalizedPoint &start, const NormalizedPoint &end) +{ + NormalizedPoint point(x, y); + double thisDistance; + NormalizedPoint lineSegment(end - start); + const double lengthSqr = pow(lineSegment.x, 2) + pow(lineSegment.y, 2); + + // if the length of the current segment is null, we can just + // measure the distance to either end point + if (lengthSqr == 0.0) { + thisDistance = end.distanceSqr(x, y, xScale, yScale); + } else { + // vector from the start point of the current line segment to the measurement point + NormalizedPoint a = point - start; + // vector from the same start point to the end point of the current line segment + NormalizedPoint b = end - start; + + // we're using a * b (dot product) := |a| * |b| * cos(phi) and the knowledge + // that cos(phi) is adjacent side / hypotenuse (hypotenuse = |b|) + // therefore, t becomes the length of the vector that represents the projection of + // the point p onto the current line segment + //(hint: if this is still unclear, draw it!) + float t = (a.x * b.x + a.y * b.y) / lengthSqr; + + if (t < 0) { + // projection falls outside the line segment on the side of "start" + thisDistance = point.distanceSqr(start.x, start.y, xScale, yScale); + } else if (t > 1) { + // projection falls outside the line segment on the side of the current point + thisDistance = point.distanceSqr(end.x, end.y, xScale, yScale); + } else { + // projection is within [start, *i]; + // determine the length of the perpendicular distance from the projection to the actual point + NormalizedPoint direction = end - start; + NormalizedPoint projection = start - NormalizedPoint(-t * direction.x, -t * direction.y); + thisDistance = projection.distanceSqr(x, y, xScale, yScale); + } + } + return thisDistance; +} + +QDebug operator<<(QDebug str, const Okular::NormalizedPoint &p) +{ + str.nospace() << "NormPt(" << p.x << "," << p.y << ")"; + return str.space(); +} + +/** class NormalizedRect **/ + +NormalizedRect::NormalizedRect() + : left(0.0) + , top(0.0) + , right(0.0) + , bottom(0.0) +{ +} + +NormalizedRect::NormalizedRect(double l, double t, double r, double b) + // note: check for swapping coords? + : left(l) + , top(t) + , right(r) + , bottom(b) +{ +} + +NormalizedRect::NormalizedRect(const QRect &r, double xScale, double yScale) // clazy:exclude=function-args-by-value TODO when BIC changes are allowed + : left((double)r.left() / xScale) + , top((double)r.top() / yScale) + , right((double)r.right() / xScale) + , bottom((double)r.bottom() / yScale) +{ +} + +NormalizedRect::NormalizedRect(const NormalizedRect &rect) = default; + +NormalizedRect NormalizedRect::fromQRectF(const QRectF &rect) +{ + QRectF nrect = rect.normalized(); + NormalizedRect ret; + ret.left = nrect.left(); + ret.top = nrect.top(); + ret.right = nrect.right(); + ret.bottom = nrect.bottom(); + return ret; +} + +bool NormalizedRect::isNull() const +{ + return left == 0 && top == 0 && right == 0 && bottom == 0; +} + +bool NormalizedRect::contains(double x, double y) const +{ + return x >= left && x <= right && y >= top && y <= bottom; +} + +bool NormalizedRect::intersects(const NormalizedRect &r) const +{ + return (r.left <= right) && (r.right >= left) && (r.top <= bottom) && (r.bottom >= top); +} + +bool NormalizedRect::intersects(const NormalizedRect *r) const +{ + return (r->left <= right) && (r->right >= left) && (r->top <= bottom) && (r->bottom >= top); +} + +bool NormalizedRect::intersects(double l, double t, double r, double b) const +{ + return (l <= right) && (r >= left) && (t <= bottom) && (b >= top); +} + +NormalizedRect NormalizedRect::operator|(const NormalizedRect &r) const +{ + NormalizedRect ret; + // todo ! + ret.left = qMin(left, r.left); + ret.top = qMin(top, r.top); + ret.bottom = qMax(bottom, r.bottom); + ret.right = qMax(right, r.right); + return ret; +} + +NormalizedRect &NormalizedRect::operator|=(const NormalizedRect &r) +{ + left = qMin(left, r.left); + top = qMin(top, r.top); + bottom = qMax(bottom, r.bottom); + right = qMax(right, r.right); + return *this; +} + +NormalizedRect NormalizedRect::operator&(const NormalizedRect &r) const +{ + if (isNull() || r.isNull()) + return NormalizedRect(); + + NormalizedRect ret; + ret.left = qMax(left, r.left); + ret.top = qMax(top, r.top); + ret.bottom = qMin(bottom, r.bottom); + ret.right = qMin(right, r.right); + return ret; +} + +NormalizedRect &NormalizedRect::operator=(const NormalizedRect &r) = default; + +NormalizedRect::~NormalizedRect() = default; + +bool NormalizedRect::operator==(const NormalizedRect &r) const +{ + return (isNull() && r.isNull()) || (fabs(left - r.left) < 1e-4 && fabs(right - r.right) < 1e-4 && fabs(top - r.top) < 1e-4 && fabs(bottom - r.bottom) < 1e-4); +} + +NormalizedPoint NormalizedRect::center() const +{ + return NormalizedPoint((left + right) / 2.0, (top + bottom) / 2.0); +} + +/* +QDebug operator << (QDebug str , const NormalizedRect &r) +{ + str << "[" <() + , d(nullptr) +{ +} + +RegularAreaRect::RegularAreaRect(const RegularAreaRect &rar) + : RegularArea(rar) + , d(nullptr) +{ +} + +RegularAreaRect::~RegularAreaRect() +{ +} + +RegularAreaRect &RegularAreaRect::operator=(const RegularAreaRect &rar) +{ + if (this != &rar) { + RegularArea::operator=(rar); + } + return *this; +} + +HighlightAreaRect::HighlightAreaRect(const RegularAreaRect *area) + : RegularAreaRect() + , s_id(-1) +{ + if (area) { + RegularAreaRect::ConstIterator it = area->begin(); + RegularAreaRect::ConstIterator itEnd = area->end(); + for (; it != itEnd; ++it) { + append(NormalizedRect(*it)); + } + } +} + +/** class ObjectRect **/ + +ObjectRect::ObjectRect(double l, double t, double r, double b, bool ellipse, ObjectType type, void *object) + : m_objectType(type) + , m_object(object) +{ + // assign coordinates swapping them if negative width or height + QRectF rect(r > l ? l : r, b > t ? t : b, fabs(r - l), fabs(b - t)); + if (ellipse) + m_path.addEllipse(rect); + else + m_path.addRect(rect); + + m_transformedPath = m_path; +} + +ObjectRect::ObjectRect(const NormalizedRect &r, bool ellipse, ObjectType type, void *object) + : m_objectType(type) + , m_object(object) +{ + QRectF rect(r.left, r.top, fabs(r.right - r.left), fabs(r.bottom - r.top)); + if (ellipse) + m_path.addEllipse(rect); + else + m_path.addRect(rect); + + m_transformedPath = m_path; +} + +ObjectRect::ObjectRect(const QPolygonF &poly, ObjectType type, void *object) + : m_objectType(type) + , m_object(object) +{ + m_path.addPolygon(poly); + + m_transformedPath = m_path; +} + +ObjectRect::ObjectType ObjectRect::objectType() const +{ + return m_objectType; +} + +const void *ObjectRect::object() const +{ + return m_object; +} + +const QPainterPath &ObjectRect::region() const +{ + return m_transformedPath; +} + +QRect ObjectRect::boundingRect(double xScale, double yScale) const +{ + const QRectF &br = m_transformedPath.boundingRect(); + + return QRect((int)(br.left() * xScale), (int)(br.top() * yScale), (int)(br.width() * xScale), (int)(br.height() * yScale)); +} + +bool ObjectRect::contains(double x, double y, double, double) const +{ + return m_transformedPath.contains(QPointF(x, y)); +} + +void ObjectRect::transform(const QTransform &matrix) +{ + m_transformedPath = matrix.map(m_path); +} + +double ObjectRect::distanceSqr(double x, double y, double xScale, double yScale) const +{ + switch (m_objectType) { + case Action: + case Image: { + const QRectF &rect(m_transformedPath.boundingRect()); + return NormalizedRect(rect.x(), rect.y(), rect.right(), rect.bottom()).distanceSqr(x, y, xScale, yScale); + } + case OAnnotation: { + return static_cast(m_object)->d_func()->distanceSqr(x, y, xScale, yScale); + } + case SourceRef: { + const SourceRefObjectRect *sr = static_cast(this); + const NormalizedPoint &point = sr->m_point; + if (point.x == -1.0) { + return pow((y - point.y) * yScale, 2); + } else if (point.y == -1.0) { + return pow((x - point.x) * xScale, 2); + } else { + return pow((x - point.x) * xScale, 2) + pow((y - point.y) * yScale, 2); + } + } + } + return 0.0; +} + +ObjectRect::~ObjectRect() +{ + if (!m_object) + return; + + if (m_objectType == Action) + delete static_cast(m_object); + else if (m_objectType == SourceRef) + delete static_cast(m_object); + else + qCDebug(OkularCoreDebug).nospace() << "Object deletion not implemented for type '" << m_objectType << "'."; +} + +/** class AnnotationObjectRect **/ + +AnnotationObjectRect::AnnotationObjectRect(Annotation *annotation) + : ObjectRect(QPolygonF(), OAnnotation, annotation) + , m_annotation(annotation) +{ +} + +Annotation *AnnotationObjectRect::annotation() const +{ + return m_annotation; +} + +QRect AnnotationObjectRect::boundingRect(double xScale, double yScale) const +{ + const QRect annotRect = AnnotationUtils::annotationGeometry(m_annotation, xScale, yScale); + const QPoint center = annotRect.center(); + + // Make sure that the rectangle has a minimum size, so that it's possible + // to click on it + const int minSize = 14; + const QRect minRect(center.x() - minSize / 2, center.y() - minSize / 2, minSize, minSize); + + return annotRect | minRect; +} + +bool AnnotationObjectRect::contains(double x, double y, double xScale, double yScale) const +{ + return boundingRect(xScale, yScale).contains((int)(x * xScale), (int)(y * yScale), false); +} + +AnnotationObjectRect::~AnnotationObjectRect() +{ + // the annotation pointer is kept elsewehere (in Page, most probably), + // so just release its pointer + m_object = nullptr; +} + +void AnnotationObjectRect::transform(const QTransform &matrix) +{ + m_annotation->d_func()->annotationTransform(matrix); +} + +/** class SourceRefObjectRect **/ + +SourceRefObjectRect::SourceRefObjectRect(const NormalizedPoint &point, void *srcRef) + : ObjectRect(point.x, point.y, .0, .0, false, SourceRef, srcRef) + , m_point(point) +{ + const double x = m_point.x < 0.0 ? 0.5 : m_point.x; + const double y = m_point.y < 0.0 ? 0.5 : m_point.y; + const QRectF rect(x - 2, y - 2, 5, 5); + m_path.addRect(rect); + + m_transformedPath = m_path; +} + +QRect SourceRefObjectRect::boundingRect(double xScale, double yScale) const +{ + const double x = m_point.x < 0.0 ? 0.5 : m_point.x; + const double y = m_point.y < 0.0 ? 0.5 : m_point.y; + + return QRect(x * xScale, y * yScale, 1, 1); +} + +bool SourceRefObjectRect::contains(double x, double y, double xScale, double yScale) const +{ + return distanceSqr(x, y, xScale, yScale) < (pow(7.0 / xScale, 2) + pow(7.0 / yScale, 2)); +} + +/** class NonOwningObjectRect **/ + +NonOwningObjectRect::NonOwningObjectRect(double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object) + : ObjectRect(left, top, right, bottom, ellipse, type, object) +{ +} + +NonOwningObjectRect::~NonOwningObjectRect() +{ + // Set m_object so that ~ObjectRect() doesn't delete it + m_object = nullptr; +} diff --git a/core/area.h b/core/area.h new file mode 100644 index 0000000..7046635 --- /dev/null +++ b/core/area.h @@ -0,0 +1,966 @@ +/*************************************************************************** + * Copyright (C) 2004-05 by Enrico Ros * + * Copyright (C) 2005 by Piotr Szymanski * + * 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_AREA_H_ +#define _OKULAR_AREA_H_ + +#include + +#include +#include +#include +#include +#include + +#include "global.h" +#include "okularcore_export.h" + +class QPolygonF; +class QRect; + +namespace Okular +{ +class Annotation; +class Action; +class NormalizedShape; + +/** + * NormalizedPoint is a helper class which stores the coordinates + * of a normalized point. + * + * @par Normalized Coordinate System + * @parblock + * Normalized means that the coordinates are always between 0 and 1, + * unless the point shall be outside of the reference area. + * + * The reference area is a rectangle, and all normalized points + * with coordinates of 0 or 1 describe its edges. + * + * This allows to locate things on a reference area without knowing its + * (current or future) actual size. When the reference area is resized, + * all things which are described in normalized coordinates keep their + * proportional position on the area. + * @endparblock + * + * @par Transformation to and from Normalized Coordinates + * @parblock + * To transform normalized coordinates to coordinates on the reference area, + * just multiply them with the size of the reference area. + * + * To get normalized coordinates from a point on the reference area, + * just divide its coordinates with the size of the reference area. + * + * Many methods have parameters @c xScale and @c yScale, + * these are equal to the size of the reference area. + * @endparblock + * + * @par Normalized Coordinate System Applied to Pages + * @parblock + * Okular uses a normalized coordinate system mainly to describe + * positions on pages. + * This is useful because pages can be shown in different sizes (zoom), + * but all objects shall keep their proportional position on the page. + * + * Okular maps from page to normalized coordinates as follows: + * * Left edge of the page: x = 0 + * * Right edge of the page: x = 1 + * * Top edge of the page: y = 0 + * * Bottom edge of the page: y = 1 + * @endparblock + * + * @par Example: Draw a Point on a Page + * @parblock + * The point is given in normalized coordinates (0.5, 0.3). + * + * If you want to draw it on a 800x600 page, + * just multiply the x coordinate (0.5) with the page width (800), + * and the y coordinate (0.3) with the page height (600). + * So, the point will be drawn on the page at (400, 180). + * + * That allows you to zoom the page by just multiplying the normalized points with the + * zoomed page size. + * @endparblock + * + * @par Example: Select Text on a Page using Mouse Events + * @parblock + * The position of all glyphs and words is stored in normalized coordinates. + * (This is what TextPage actually does.) + * Mouse press and release events are given in page coordinates (400, 180) and (600, 450), + * while the page has a size of 800x600. + * + * If you want to search all text between the mouse click and release event, + * you need their normalized coordinates. + * Just divide the x coordinates (400 and 600) by the page width (800), + * and the y coordinates (180 and 450) by the page height (600). + * So, you have to search for all glyphs between (0.5, 0.3) and (0.75, 0.75). + * + * That allows you to process all glyphs and words without + * having to keep any of their positions in sync with the page. + * @endparblock + * + * @par Geometric operations + * @parblock + * NormalizedPoint supports basic geometric operations. + * * You can transform it with a QTransform matrix. + * * With the size of the reference area, you can calculate the squared + * absolute distance to another NormalizedPoint or a line of two NormalizedPoints. + * + * NormalizedRect provides additional geometric operations for rectangles. + * @endparblock + * + * @see NormalizedRect + */ +class OKULARCORE_EXPORT NormalizedPoint +{ +public: + /** + * Creates a normalized point at (0, 0). + */ + NormalizedPoint(); + + /** + * Creates a new normalized point with the normalized coordinates (@p x, @p y ). + */ + NormalizedPoint(double x, double y); + + /** + * Creates a new normalized point from an absolute point (@p x, @p y) + * on a reference area of size @p xScale x @p yScale. + */ + NormalizedPoint(int x, int y, int xScale, int yScale); + + /** + * @internal + */ + NormalizedPoint &operator=(const NormalizedPoint &); + + NormalizedPoint(const NormalizedPoint &); + // TODO next ABI break, move the = default to here + ~NormalizedPoint(); // NOLINT(performance-trivially-destructible) + + /** + * Transforms the normalized point with the operations defined by @p matrix. + */ + void transform(const QTransform &matrix); + + /** + * Returns squared distance to normalized point (@p x, @p y) + * on a reference area of size @p xScale x @p yScale. + * @since 0.17 (KDE 4.11) + */ + double distanceSqr(double x, double y, double xScale, double yScale) const; + + /** + * Returns squared distance of the normalized point (@p x, @p y) + * to the line segment from @p start to @p end + * on a reference area of size @p xScale x @p yScale. + * @since 0.17 (KDE 4.11) + */ + static double distanceSqr(double x, double y, double xScale, double yScale, const NormalizedPoint &start, const NormalizedPoint &end); + + /** + * The normalized x coordinate. + */ + double x; + + /** + * The normalized y coordinate. + */ + double y; +}; + +/** + * A NormalizedRect is a rectangle which can be defined by two NormalizedPoints. + * + * It describes a rectangular area on a reference area of undefined size. + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * In Okular, NormalizedRect can be used e. g. to describe bounding boxes of TextEntity objects, + * and the highlight area of text selections. + * + * If you need to describe an area which consists of multiple rectangles, + * you can use RegularAreaRect instead. + * + * @see NormalizedPoint, RegularAreaRect, TextEntity + */ +class OKULARCORE_EXPORT NormalizedRect +{ +public: + /** + * Creates a null normalized rectangle. + * @see isNull() + */ + NormalizedRect(); + + /** + * Creates a normalized rectangle with the normalized coordinates + * @p left, @p top, @p right, @p bottom. + * + * If you need the x, y, width and height coordinates use the + * following formulas: + * + * @li x = left + * @li y = top + * @li width = right - left + * @li height = bottom - top + * + * @note + * The coordinates for @p left and @p top should be lower than + * @p right and @p bottom, respectively. + * At negative width or height the behaviour of some operations is undefined. + */ + NormalizedRect(double left, double top, double right, double bottom); + + /** + * Creates a normalized rectangle from the given @p rectangle + * on a reference area of size @p xScale x @p yScale. + * + * @note + * The rectangle should have positive width and height. + * You can use e. g. QRect::normalize() to ensure this. + * At negative width or height the behaviour of some operations is undefined. + */ + NormalizedRect(const QRect &rectangle, double xScale, double yScale); + + /** + * @internal + */ + NormalizedRect(const NormalizedRect &); + + /** + * @internal + */ + NormalizedRect &operator=(const NormalizedRect &other); + + // TODO next ABI break, move the = default to here + ~NormalizedRect(); // NOLINT(performance-trivially-destructible) + + /** + * Build a normalized rect from a QRectF, which already has normalized coordinates. + */ + static NormalizedRect fromQRectF(const QRectF &rect); + + /** + * Returns whether this normalized rectangle is a null normalized rect. + */ + bool isNull() const; + + /** + * Returns whether the normalized rectangle contains the normalized point + * (@p x, @p y). + */ + bool contains(double x, double y) const; + + /** + * Returns whether the normalized rectangle intersects the @p other normalized + * rectangle. + */ + bool intersects(const NormalizedRect &other) const; + + /** + * This is an overloaded member function, provided for convenience. It behaves essentially + * like the above function. + */ + bool intersects(const NormalizedRect *other) const; + + /** + * Returns whether the normalized rectangle intersects an other normalized + * rectangle, which is defined by @p left, @p top, @p right and @p bottom. + */ + bool intersects(double left, double top, double right, double bottom) const; + + /** + * Returns the rectangle mapped to a reference area of @p xScale x @p yScale. + */ + QRect geometry(int xScale, int yScale) const; + + /** + * Same functionality as geometry, but the output is now rounded before typecasting to int + * + * @since 0.14 (KDE 4.8) + */ + QRect roundedGeometry(int xScale, int yScale) const; + + /** + * Returns the normalized bounding rectangle of the normalized rectangle + * combined with the @p other normalized rectangle. + */ + NormalizedRect operator|(const NormalizedRect &other) const; + + /** + * Sets the normalized rectangle to the normalized bounding rectangle + * of itself combined with the @p other normalized rectangle. + */ + NormalizedRect &operator|=(const NormalizedRect &other); + + /** + * Returns the intersection of this normalized rectangle with the specified + * @p other. If the rects do not intersect then the result is a null rectangle. + * + * @since 0.7 (KDE 4.1) + */ + NormalizedRect operator&(const NormalizedRect &other) const; + + /** + * Returns whether the normalized rectangle is equal to the @p other + * normalized rectangle. + */ + bool operator==(const NormalizedRect &other) const; + + /** + * Returns the center of the rectangle + * @since 0.10 (KDE 4.4) + */ + NormalizedPoint center() const; + + /** + * Transforms the normalized rectangle with the operations defined by @p matrix. + */ + void transform(const QTransform &matrix); + + /** + * Returns true if the point @p pt is located below the bottom of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isBottom(const NormalizedPoint &pt) const + { + return bottom < pt.y; + } + + /** + * Returns true if the point @p pt is located above the top of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isTop(const NormalizedPoint &pt) const + { + return top > pt.y; + } + + /** + * Returns true if the point @p pt is located below the top of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isBottomOrLevel(const NormalizedPoint &pt) const + { + return top < pt.y; + } + + /** + * Returns true if the point @p pt is located above the bottom of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isTopOrLevel(const NormalizedPoint &pt) const + { + return bottom > pt.y; + } + + /** + * Returns true if the point @p pt is located to the right of the left edge of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isLeft(const NormalizedPoint &pt) const + { + return left < pt.x; + } + + /** + * Returns true if the point @p pt is located to the left of the right edge of the rectangle + * @since 0.14 (KDE 4.8) + */ + bool isRight(const NormalizedPoint &pt) const + { + return right > pt.x; + } + + /** + * Returns the squared distance of the normalized point (@p x, @p y) + * to the closest edge, or 0 if the point is within the rectangle; + * using a reference area of size @p xScale x @p yScale + * @since 0.17 (KDE 4.11) + */ + double distanceSqr(double x, double y, double xScale, double yScale) const + { + double distX = 0; + if (x < left) + distX = left - x; + else if (x > right) + distX = x - right; + + double distY = 0; + if (top > y) + distY = top - y; + else if (bottom < y) + distY = y - bottom; + return pow(distX * xScale, 2) + pow(distY * yScale, 2); + } + + /// @since 1.4 + double width() const + { + return right - left; + } + + /// @since 1.4 + double height() const + { + return bottom - top; + } + + /** + * The normalized left coordinate. + */ + double left; + + /** + * The normalized top coordinate. + */ + double top; + + /** + * The normalized right coordinate. + */ + double right; + + /** + * The normalized bottom coordinate. + */ + double bottom; +}; +// KDE_DUMMY_QHASH_FUNCTION(NormalizedRect) + +/** + * @short An area with normalized coordinates that contains a reference to an object. + * + * These areas ("rects") contain a pointer to a document object + * (such as a hyperlink, an action, or something like that). + * The pointer is read and stored as 'void pointer' so cast is + * performed by accessors based on the value returned by objectType(). Objects + * are reparented to this class. + * + * Type / Class correspondence tab: + * - Action : class Action: description of an action + * - Image : class Image : description of an image (n/a) + * - Annotation: class Annotation: description of an annotation + * + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * @see NormalizedPoint + */ +class OKULARCORE_EXPORT ObjectRect +{ +public: + /** + * Describes the type of storable object. + */ + enum ObjectType { + Action, ///< An action + Image, ///< An image + OAnnotation, ///< An annotation + SourceRef ///< A source reference + }; + + /** + * Creates a new object rectangle. + * + * @param left The left coordinate of the rectangle. + * @param top The top coordinate of the rectangle. + * @param right The right coordinate of the rectangle. + * @param bottom The bottom coordinate of the rectangle. + * @param ellipse If true the rectangle describes an ellipse. + * @param type The type of the storable object @see ObjectType. + * @param object The pointer to the storable object. + */ + ObjectRect(double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object); + + /** + * This is an overloaded member function, provided for convenience. + */ + ObjectRect(const NormalizedRect &r, bool ellipse, ObjectType type, void *object); + + /** + * This is an overloaded member function, provided for convenience. + */ + ObjectRect(const QPolygonF &poly, ObjectType type, void *object); + + /** + * Destroys the object rectangle. + */ + virtual ~ObjectRect(); + + ObjectRect(const ObjectRect &o) = delete; + ObjectRect &operator=(const ObjectRect &o) = delete; + + /** + * Returns the object type of the object rectangle. + * @see ObjectType + */ + ObjectType objectType() const; + + /** + * Returns the storable object of the object rectangle. + */ + const void *object() const; + + /** + * Returns the region that is covered by the object rectangle. + */ + const QPainterPath ®ion() const; + + /** + * Returns the bounding rect of the object rectangle for the + * scaling factor @p xScale and @p yScale. + */ + virtual QRect boundingRect(double xScale, double yScale) const; + + /** + * Returns whether the object rectangle contains the point with absolute coordinates + * (@p x, @p y) at a page size of @p xScale x @p yScale. + */ + virtual bool contains(double x, double y, double xScale, double yScale) const; + + /** + * Transforms the object rectangle with the operations defined by @p matrix. + */ + virtual void transform(const QTransform &matrix); + + /** + * Returns the squared distance between the object + * and the point with + * normalized coordinates (@p x, @p y) + * at a page size of @p xScale x @p yScale. + * + * @since 0.8.2 (KDE 4.2.2) + */ + // FIXME this should most probably be a virtual method + double distanceSqr(double x, double y, double xScale, double yScale) const; + +protected: + ObjectType m_objectType; + void *m_object; + QPainterPath m_path; + QPainterPath m_transformedPath; +}; + +/** + * This class describes the object rectangle for an annotation. + */ +class OKULARCORE_EXPORT AnnotationObjectRect : public ObjectRect +{ +public: + /** + * Creates a new annotation object rectangle with the + * given @p annotation. + */ + explicit AnnotationObjectRect(Annotation *annotation); + + /** + * Destroys the annotation object rectangle. + */ + ~AnnotationObjectRect() override; + + /** + * Returns the annotation object of the annotation object rectangle. + */ + Annotation *annotation() const; + + /** + * Returns the bounding rect of the annotation object rectangle for the + * scaling factor @p xScale and @p yScale. + */ + QRect boundingRect(double xScale, double yScale) const override; + + /** + * Returns whether the annotation object rectangle contains the point @p x, @p y for the + * scaling factor @p xScale and @p yScale. + */ + bool contains(double x, double y, double xScale, double yScale) const override; + + /** + * Transforms the annotation object rectangle with the operations defined by @p matrix. + */ + void transform(const QTransform &matrix) override; + +private: + Annotation *m_annotation; +}; + +/** + * This class describes the object rectangle for a source reference. + */ +class OKULARCORE_EXPORT SourceRefObjectRect : public ObjectRect +{ + friend class ObjectRect; + +public: + /** + * Creates a new source reference object rectangle. + * + * @param point The point of the source reference. + * @param srcRef The storable source reference object. + */ + SourceRefObjectRect(const NormalizedPoint &point, void *srcRef); + + /** + * Returns the bounding rect of the source reference object rectangle for the + * scaling factor @p xScale and @p yScale. + */ + QRect boundingRect(double xScale, double yScale) const override; + + /** + * Returns whether the source reference object rectangle contains the point @p x, @p y for the + * scaling factor @p xScale and @p yScale. + */ + bool contains(double x, double y, double xScale, double yScale) const override; + +private: + NormalizedPoint m_point; +}; + +/** + * This class is an object rect that doesn't own the given pointer, i.e. won't delete it on destruction + * @since 1.7 + */ +class OKULARCORE_EXPORT NonOwningObjectRect : public ObjectRect +{ +public: + NonOwningObjectRect(double left, double top, double right, double bottom, bool ellipse, ObjectType type, void *object); + ~NonOwningObjectRect() override; +}; + +/// @cond PRIVATE +/** @internal */ +/** @internal */ +template T *givePtr(T &t) +{ + return &t; +} + +/** @internal */ +template T &deref(T &t) +{ + return t; +} +/// @endcond + +/** + * @short An area with normalized coordinates, consisting of NormalizedShape objects. + * + * This is a template class to describe an area which consists of + * multiple shapes of the same type, intersecting or non-intersecting. + * The coordinates are normalized, and can be mapped to a reference area of defined size. + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * Class NormalizedShape \b must have the following functions/operators defined: + * - bool contains( double, double ), whether it contains the given NormalizedPoint + * - bool intersects( NormalizedShape ) + * - bool isNull() + * - Shape geometry( int, int ), which maps to the reference area + * - operator|=( NormalizedShape ), which unites two NormalizedShape's + * + * @see RegularAreaRect, NormalizedPoint + */ +template class RegularArea : public QList +{ +public: + /** + * Returns whether this area contains the normalized point (@p x, @p y). + */ + bool contains(double x, double y) const; + + /** + * Returns whether this area contains a NormalizedShape object that equals @p shape. + * + * @note + * The original NormalizedShape objects can be lost if simplify() was called. + */ + bool contains(const NormalizedShape &shape) const; + + /** + * Returns whether this area intersects with the given @p area. + */ + bool intersects(const RegularArea *area) const; + + /** + * Returns whether the regular area intersects with the given @p shape. + */ + bool intersects(const NormalizedShape &shape) const; + + /** + * Appends the given @p area to this area. + */ + void appendArea(const RegularArea *area); + + /** + * Appends the given @p shape to this area. + */ + void appendShape(const NormalizedShape &shape, MergeSide side = MergeAll); + + /** + * Simplifies this regular area by merging its intersecting subareas. + * This might change the effective geometry of this area. + */ + void simplify(); + + /** + * Returns whether the regular area is a null area. + */ + bool isNull() const; + + /** + * Returns the subareas of this regular area + * mapped to a reference area of size @p xScale x @p yScale, + * then translated by @p dx and @p dy. + */ + QList geometry(int xScale, int yScale, int dx = 0, int dy = 0) const; + + /** + * Transforms the regular area with the operations defined by @p matrix. + */ + void transform(const QTransform &matrix); +}; + +template void RegularArea::simplify() +{ +#ifdef DEBUG_REGULARAREA + int prev_end = this->count(); +#endif + int end = this->count() - 1, x = 0; + for (int i = 0; i < end; ++i) { + if (givePtr((*this)[x])->intersects(deref((*this)[i + 1]))) { + deref((*this)[x]) |= deref((*this)[i + 1]); + this->removeAt(i + 1); + --end; + --i; + } else { + x = i + 1; + } + } +#ifdef DEBUG_REGULARAREA + qCDebug(OkularCoreDebug) << "from" << prev_end << "to" << this->count(); +#endif +} + +template bool RegularArea::isNull() const +{ + if (this->isEmpty()) + return true; + + typename QList::const_iterator it = this->begin(), itEnd = this->end(); + for (; it != itEnd; ++it) + if (!givePtr(*it)->isNull()) + return false; + + return true; +} + +template bool RegularArea::intersects(const NormalizedShape &shape) const +{ + if (this->isEmpty()) + return false; + + typename QList::const_iterator it = this->begin(), itEnd = this->end(); + for (; it != itEnd; ++it) + if (!givePtr(*it)->isNull() && givePtr(*it)->intersects(shape)) + return true; + + return false; +} + +template bool RegularArea::intersects(const RegularArea *area) const +{ + if (this->isEmpty()) + return false; + + typename QList::const_iterator it = this->begin(), itEnd = this->end(); + for (; it != itEnd; ++it) { + typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); + for (; areaIt != areaItEnd; ++areaIt) { + if (!(*it).isNull() && (*it).intersects(*areaIt)) + return true; + } + } + + return false; +} + +template void RegularArea::appendArea(const RegularArea *area) +{ + typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); + for (; areaIt != areaItEnd; ++areaIt) + this->append(*areaIt); +} + +template void RegularArea::appendShape(const NormalizedShape &shape, MergeSide side) +{ + int size = this->count(); + // if the list is empty, adds the shape normally + if (size == 0) { + this->append(shape); + } else { + bool intersection = false; + NormalizedShape &last = (*this)[size - 1]; +#define O_LAST givePtr(last) +#define O_LAST_R O_LAST->right +#define O_LAST_L O_LAST->left +#define O_LAST_T O_LAST->top +#define O_LAST_B O_LAST->bottom +#define O_NEW givePtr(shape) +#define O_NEW_R O_NEW->right +#define O_NEW_L O_NEW->left +#define O_NEW_T O_NEW->top +#define O_NEW_B O_NEW->bottom + switch (side) { + case MergeRight: + intersection = (O_LAST_R >= O_NEW_L) && (O_LAST_L <= O_NEW_R) && ((O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B) || (O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B)); + break; + case MergeBottom: + intersection = (O_LAST_B >= O_NEW_T) && (O_LAST_T <= O_NEW_B) && ((O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L) || (O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L)); + break; + case MergeLeft: + intersection = (O_LAST_L <= O_NEW_R) && (O_LAST_R >= O_NEW_L) && ((O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B) || (O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B)); + break; + case MergeTop: + intersection = (O_LAST_T <= O_NEW_B) && (O_LAST_B >= O_NEW_T) && ((O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L) || (O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L)); + break; + case MergeAll: + intersection = O_LAST->intersects(shape); + break; + } +#undef O_LAST +#undef O_LAST_R +#undef O_LAST_L +#undef O_LAST_T +#undef O_LAST_B +#undef O_NEW +#undef O_NEW_R +#undef O_NEW_L +#undef O_NEW_T +#undef O_NEW_B + // if the new shape intersects with the last shape in the list, then + // merge it with that and delete the shape + if (intersection) { + deref((*this)[size - 1]) |= deref(shape); + } else + this->append(shape); + } +} + +template bool RegularArea::contains(double x, double y) const +{ + if (this->isEmpty()) + return false; + + typename QList::const_iterator it = this->begin(), itEnd = this->end(); + for (; it != itEnd; ++it) + if ((*it).contains(x, y)) + return true; + + return false; +} + +template bool RegularArea::contains(const NormalizedShape &shape) const +{ + if (this->isEmpty()) + return false; + + return QList::contains(shape); +} + +template QList RegularArea::geometry(int xScale, int yScale, int dx, int dy) const +{ + if (this->isEmpty()) + return QList(); + + QList ret; + Shape t; + typename QList::const_iterator it = this->begin(), itEnd = this->end(); + for (; it != itEnd; ++it) { + t = givePtr(*it)->geometry(xScale, yScale); + t.translate(dx, dy); + ret.append(t); + } + + return ret; +} + +template void RegularArea::transform(const QTransform &matrix) +{ + if (this->isEmpty()) + return; + + for (int i = 0; i < this->count(); ++i) + givePtr((*this)[i])->transform(matrix); +} + +/** + * This is a list of NormalizedRect, to describe an area consisting of + * multiple rectangles using normalized coordinates. + * + * This area can be mapped to a reference area, resulting in a list of QRects. + * For more information about the normalized coordinate system, see NormalizedPoint. + * + * Okular uses this area e. g. to describe a text highlight area, + * which consists of multiple, intersecting or non-intersecting rectangles. + * + * @see NormalizedRect, NormalizedPoint + */ +class OKULARCORE_EXPORT RegularAreaRect : public RegularArea +{ +public: + RegularAreaRect(); + RegularAreaRect(const RegularAreaRect &rar); + ~RegularAreaRect(); + + RegularAreaRect &operator=(const RegularAreaRect &rar); + +private: + class Private; + Private *const d; +}; + +/** + * This class stores the geometry of a highlighting area in normalized coordinates, + * together with highlighting specific information. + */ +class HighlightAreaRect : public RegularAreaRect +{ +public: + /** + * Creates a new highlight area rect with the coordinates of + * the given @p area. + */ + explicit HighlightAreaRect(const RegularAreaRect *area = nullptr); + + /** + * The search ID of the highlight owner. + */ + int s_id; + + /** + * The color of the highlight. + */ + QColor color; +}; + +uint qHash(const Okular::NormalizedRect &r, uint seed = 0); +} + +#ifndef QT_NO_DEBUG_STREAM +/** + * Debug operator for normalized @p point. + */ +OKULARCORE_EXPORT QDebug operator<<(QDebug str, const Okular::NormalizedPoint &point); + +/** + * Debug operator for normalized @p rect. + */ +OKULARCORE_EXPORT QDebug operator<<(QDebug str, const Okular::NormalizedRect &rect); +#endif + +#endif diff --git a/core/audioplayer.cpp b/core/audioplayer.cpp new file mode 100644 index 0000000..c949b4b --- /dev/null +++ b/core/audioplayer.cpp @@ -0,0 +1,247 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "audioplayer.h" +#include "audioplayer_p.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "action.h" +#include "debug_p.h" +#include "sound.h" + +using namespace Okular; + +// helper class used to store info about a sound to be played +class SoundInfo +{ +public: + explicit SoundInfo(const Sound *s = nullptr, const SoundAction *ls = nullptr) + : sound(s) + , volume(0.5) + , synchronous(false) + , repeat(false) + , mix(false) + { + if (ls) { + volume = ls->volume(); + synchronous = ls->synchronous(); + repeat = ls->repeat(); + mix = ls->mix(); + } + } + + const Sound *sound; + double volume; + bool synchronous; + bool repeat; + bool mix; +}; + +class PlayData +{ +public: + PlayData() + : m_mediaobject(nullptr) + , m_output(nullptr) + , m_buffer(nullptr) + { + } + + void play() + { + if (m_buffer) { + m_buffer->open(QIODevice::ReadOnly); + } + m_mediaobject->play(); + } + + ~PlayData() + { + m_mediaobject->stop(); + delete m_mediaobject; + delete m_output; + delete m_buffer; + } + + PlayData(const PlayData &) = delete; + PlayData &operator=(const PlayData &) = delete; + + Phonon::MediaObject *m_mediaobject; + Phonon::AudioOutput *m_output; + QBuffer *m_buffer; + SoundInfo m_info; +}; + +AudioPlayerPrivate::AudioPlayerPrivate(AudioPlayer *qq) + : q(qq) + , m_state(AudioPlayer::StoppedState) +{ +} + +AudioPlayerPrivate::~AudioPlayerPrivate() +{ + stopPlayings(); +} + +int AudioPlayerPrivate::newId() const +{ + int newid = 0; + QHash::const_iterator it; + QHash::const_iterator itEnd = m_playing.constEnd(); + do { + newid = KRandom::random(); + it = m_playing.constFind(newid); + } while (it != itEnd); + return newid; +} + +bool AudioPlayerPrivate::play(const SoundInfo &si) +{ + qCDebug(OkularCoreDebug); + PlayData *data = new PlayData(); + data->m_output = new Phonon::AudioOutput(Phonon::NotificationCategory); + data->m_output->setVolume(si.volume); + data->m_mediaobject = new Phonon::MediaObject(); + Phonon::createPath(data->m_mediaobject, data->m_output); + data->m_info = si; + bool valid = false; + + switch (si.sound->soundType()) { + case Sound::External: { + QString url = si.sound->url(); + qCDebug(OkularCoreDebug) << "External," << url; + if (!url.isEmpty()) { + int newid = newId(); + QObject::connect(data->m_mediaobject, &Phonon::MediaObject::finished, q, [this, newid]() { finished(newid); }); + QUrl newurl; + if (QUrl::fromUserInput(url).isRelative()) { + newurl = m_currentDocument.adjusted(QUrl::RemoveFilename); + newurl.setPath(newurl.path() + url); + } else { + newurl = QUrl::fromLocalFile(url); + } + data->m_mediaobject->setCurrentSource(newurl); + m_playing.insert(newid, data); + valid = true; + } + break; + } + case Sound::Embedded: { + QByteArray filedata = si.sound->data(); + qCDebug(OkularCoreDebug) << "Embedded," << filedata.length(); + if (!filedata.isEmpty()) { + qCDebug(OkularCoreDebug) << "Mediaobject:" << data->m_mediaobject; + int newid = newId(); + QObject::connect(data->m_mediaobject, &Phonon::MediaObject::finished, q, [this, newid]() { finished(newid); }); + data->m_buffer = new QBuffer(); + data->m_buffer->setData(filedata); + data->m_mediaobject->setCurrentSource(Phonon::MediaSource(data->m_buffer)); + m_playing.insert(newid, data); + valid = true; + } + break; + } + } + if (!valid) { + delete data; + data = nullptr; + } + if (data) { + qCDebug(OkularCoreDebug) << "PLAY"; + data->play(); + m_state = AudioPlayer::PlayingState; + } + return valid; +} + +void AudioPlayerPrivate::stopPlayings() +{ + qDeleteAll(m_playing); + m_playing.clear(); + m_state = AudioPlayer::StoppedState; +} + +void AudioPlayerPrivate::finished(int id) +{ + QHash::iterator it = m_playing.find(id); + if (it == m_playing.end()) + return; + + SoundInfo si = it.value()->m_info; + // if the sound must be repeated indefinitely, then start the playback + // again, otherwise destroy the PlayData as it's no more useful + if (si.repeat) { + it.value()->play(); + } else { + delete it.value(); + m_playing.erase(it); + m_state = AudioPlayer::StoppedState; + } + qCDebug(OkularCoreDebug) << "finished," << m_playing.count(); +} + +AudioPlayer::AudioPlayer() + : QObject() + , d(new AudioPlayerPrivate(this)) +{ +} + +AudioPlayer::~AudioPlayer() +{ + delete d; +} + +AudioPlayer *AudioPlayer::instance() +{ + static AudioPlayer ap; + return ≈ +} + +void AudioPlayer::playSound(const Sound *sound, const SoundAction *linksound) +{ + // we can't play null pointers ;) + if (!sound) + return; + + // we don't play external sounds for remote documents + if (sound->soundType() == Sound::External && !d->m_currentDocument.isLocalFile()) + return; + + qCDebug(OkularCoreDebug); + SoundInfo si(sound, linksound); + + // if the mix flag of the new sound is false, then the currently playing + // sounds must be stopped. + if (!si.mix) + d->stopPlayings(); + + d->play(si); +} + +void AudioPlayer::stopPlaybacks() +{ + d->stopPlayings(); +} + +AudioPlayer::State AudioPlayer::state() const +{ + return d->m_state; +} + +#include "moc_audioplayer.cpp" diff --git a/core/audioplayer.h b/core/audioplayer.h new file mode 100644 index 0000000..465019d --- /dev/null +++ b/core/audioplayer.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2007 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_AUDIOPLAYER_H_ +#define _OKULAR_AUDIOPLAYER_H_ + +#include "okularcore_export.h" + +#include + +namespace Okular +{ +class AudioPlayerPrivate; +class Document; +class Sound; +class SoundAction; + +/** + * @short An audio player. + * + * Singleton utility class to play sounds in documents using the KDE sound + * system. + */ +class OKULARCORE_EXPORT AudioPlayer : public QObject +{ + Q_OBJECT + +public: + /** + * The state of AudioPlayer + * @since 0.19 (KDE 4.13) + */ + enum State { + /** + * The AudioPlayer is playing a audio file. + */ + PlayingState, + /** + * The AudioPlayer isn't playing a audio file. + */ + StoppedState + }; + + ~AudioPlayer() override; + + /** + * Gets the instance of the audio player. + */ + static AudioPlayer *instance(); + + /** + * Enqueue the specified @p sound for playing, optionally taking more + * information about the playing from the @p soundlink . + */ + void playSound(const Sound *sound, const SoundAction *linksound = nullptr); + + /** + * Tell the AudioPlayer to stop all the playbacks. + */ + void stopPlaybacks(); + + /** + * Return state of sound (playing/stopped) + * @since 0.19 (KDE 4.13) + */ + State state() const; + +private: + AudioPlayer(); + + friend class AudioPlayerPrivate; + AudioPlayerPrivate *const d; + friend class Document; + + Q_DISABLE_COPY(AudioPlayer) +}; + +} + +#endif diff --git a/core/audioplayer_p.h b/core/audioplayer_p.h new file mode 100644 index 0000000..2fb1d18 --- /dev/null +++ b/core/audioplayer_p.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 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_AUDIOPLAYER_P_H_ +#define _OKULAR_AUDIOPLAYER_P_H_ + +// qt/kde includes +#include +#include + +class PlayData; +class SoundInfo; + +namespace Okular +{ +class AudioPlayer; + +class AudioPlayerPrivate +{ +public: + explicit AudioPlayerPrivate(AudioPlayer *qq); + + ~AudioPlayerPrivate(); + + int newId() const; + bool play(const SoundInfo &si); + void stopPlayings(); + + void finished(int); + + AudioPlayer *q; + + QHash m_playing; + QUrl m_currentDocument; + AudioPlayer::State m_state; +}; + +} + +#endif diff --git a/core/bookmarkmanager.cpp b/core/bookmarkmanager.cpp new file mode 100644 index 0000000..afeea1a --- /dev/null +++ b/core/bookmarkmanager.cpp @@ -0,0 +1,728 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "bookmarkmanager.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "document_p.h" +#include "observer.h" + +using namespace Okular; + +#define foreachObserver(cmd) \ + { \ + QSet::const_iterator it = d->document->m_observers.constBegin(), end = d->document->m_observers.constEnd(); \ + for (; it != end; ++it) { \ + (*it)->cmd; \ + } \ + } + +#define foreachObserverD(cmd) \ + { \ + QSet::const_iterator it = document->m_observers.constBegin(), end = document->m_observers.constEnd(); \ + for (; it != end; ++it) { \ + (*it)->cmd; \ + } \ + } + +class OkularBookmarkAction : public KBookmarkAction +{ + Q_OBJECT +public: + OkularBookmarkAction(const Okular::DocumentViewport &vp, const KBookmark &bk, KBookmarkOwner *owner, QObject *parent) + : KBookmarkAction(bk, owner, parent) + { + if (vp.isValid()) + setText(QString::number(vp.pageNumber + 1) + QStringLiteral(" - ") + text()); + setProperty("pageNumber", vp.pageNumber + 1); + setProperty("htmlRef", bk.url().fragment(QUrl::FullyDecoded)); + } + + inline int pageNumber() const + { + return property("pageNumber").toInt(); + } + + inline QString htmlRef() const + { + return property("htmlRef").toString(); + } +}; + +static inline bool documentViewportFuzzyCompare(const DocumentViewport &vp1, const DocumentViewport &vp2) +{ + bool equal = vp1.isValid() && vp2.isValid() && (vp1.pageNumber == vp2.pageNumber) && (vp1.rePos.pos == vp2.rePos.pos); + + if (!equal) + return false; + + if (qAbs(vp1.rePos.normalizedX - vp2.rePos.normalizedX) >= 0.000001) + return false; + + if (qAbs(vp1.rePos.normalizedY - vp2.rePos.normalizedY) >= 0.000001) + return false; + + return true; +} + +static inline bool bookmarkLessThan(const KBookmark &b1, const KBookmark &b2) +{ + DocumentViewport vp1(b1.url().fragment(QUrl::FullyDecoded)); + DocumentViewport vp2(b2.url().fragment(QUrl::FullyDecoded)); + + return vp1 < vp2; +} + +static inline bool okularBookmarkActionLessThan(QAction *a1, QAction *a2) +{ + DocumentViewport vp1(static_cast(a1)->htmlRef()); + DocumentViewport vp2(static_cast(a2)->htmlRef()); + + return vp1 < vp2; +} + +static QUrl mostCanonicalUrl(const QUrl &url) +{ + if (!url.isLocalFile()) + return url; + + const QFileInfo fi(url.toLocalFile()); + return QUrl::fromLocalFile(fi.canonicalFilePath()); +} + +class BookmarkManager::Private : public KBookmarkOwner +{ +public: + Private(BookmarkManager *qq) + : KBookmarkOwner() + , q(qq) + , document(nullptr) + , manager(nullptr) + { + } + + ~Private() override + { + knownFiles.clear(); + // no need to delete the manager, it's automatically done by KBookmarkManager + // delete manager; + } + + Private(const Private &) = delete; + Private &operator=(const Private &) = delete; + + QUrl currentUrl() const override; + QString currentTitle() const override; + bool enableOption(BookmarkOption option) const override; + void openBookmark(const KBookmark &bm, Qt::MouseButtons, Qt::KeyboardModifiers) override; + + QHash::iterator bookmarkFind(const QUrl &url, bool doCreate, KBookmarkGroup *result = nullptr); + + // slots + void _o_changed(const QString &groupAddress, const QString &caller); + + BookmarkManager *q; + QUrl url; + QHash urlBookmarks; + DocumentPrivate *document; + QString file; + KBookmarkManager *manager; + QHash knownFiles; +}; + +static inline QUrl urlForGroup(const KBookmark &group) +{ + if (group.url().isValid()) + return group.url(); + else + return QUrl::fromUserInput(group.fullText()); +} + +BookmarkManager::BookmarkManager(DocumentPrivate *document) + : QObject(document->m_parent) + , d(new Private(this)) +{ + setObjectName(QStringLiteral("Okular::BookmarkManager")); + + d->document = document; + + d->file = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/okular/bookmarks.xml"); + + d->manager = KBookmarkManager::managerForFile(d->file, QStringLiteral("okular")); + d->manager->setEditorOptions(QGuiApplication::applicationDisplayName(), false); + d->manager->setUpdate(true); + connect(d->manager, &KBookmarkManager::changed, this, [this](const QString &groupAddress, const QString &caller) { d->_o_changed(groupAddress, caller); }); +} + +BookmarkManager::~BookmarkManager() +{ + delete d; +} + +// BEGIN Reimplementations from KBookmarkOwner +QUrl BookmarkManager::Private::currentUrl() const +{ + return url; +} + +QString BookmarkManager::Private::currentTitle() const +{ + return url.toDisplayString(); +} + +bool BookmarkManager::Private::enableOption(BookmarkOption option) const +{ + Q_UNUSED(option) + return false; +} + +void BookmarkManager::Private::openBookmark(const KBookmark &bm, Qt::MouseButtons, Qt::KeyboardModifiers) +{ + emit q->openUrl(bm.url()); +} +// END Reimplementations from KBookmarkOwner + +void BookmarkManager::Private::_o_changed(const QString &groupAddress, const QString &caller) +{ + Q_UNUSED(caller); + if (groupAddress.isEmpty()) + return; + + QUrl referurl; + // first, try to find the bookmark group whom change notification was just received + QHash::iterator it = knownFiles.begin(), itEnd = knownFiles.end(); + for (; it != itEnd; ++it) { + if (it.value() == groupAddress) { + referurl = it.key(); + knownFiles.erase(it); + break; + } + } + if (!referurl.isValid()) { + const KBookmark bm = manager->findByAddress(groupAddress); + // better be safe than sorry + if (bm.isNull()) + return; + Q_ASSERT(bm.isGroup()); + referurl = urlForGroup(bm); + } + Q_ASSERT(referurl.isValid()); + emit q->bookmarksChanged(referurl); + // case for the url representing the current document + // (this might happen if the same document is open in another place; + // in such case, make really sure to be in sync) + if (referurl == url) { + // save the old bookmarks for the current url + const QHash oldUrlBookmarks = urlBookmarks; + // set the same url again, so we reload the information we have about it + q->setUrl(referurl); + // then notify the observers about the changes in the bookmarks + for (int i = 0; i < qMax(oldUrlBookmarks.size(), urlBookmarks.size()); i++) { + bool oldContains = oldUrlBookmarks.contains(i) && oldUrlBookmarks[i] > 0; + bool curContains = urlBookmarks.contains(i) && urlBookmarks[i] > 0; + + if (oldContains != curContains) { + foreachObserverD(notifyPageChanged(i, DocumentObserver::Bookmark)); + } else if (oldContains && oldUrlBookmarks[i] != urlBookmarks[i]) { + foreachObserverD(notifyPageChanged(i, DocumentObserver::Bookmark)); + } + } + } + emit q->saved(); +} + +QList BookmarkManager::files() const +{ + QList ret; + KBookmarkGroup group = d->manager->root(); + for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) { + if (bm.isSeparator() || !bm.isGroup()) + continue; + + ret.append(urlForGroup(bm)); + } + return ret; +} + +KBookmark::List BookmarkManager::bookmarks(const QUrl &documentUrl) const +{ + const QUrl url = mostCanonicalUrl(documentUrl); + KBookmark::List ret; + KBookmarkGroup group = d->manager->root(); + for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) { + if (!bm.isGroup() || urlForGroup(bm) != url) + continue; + + KBookmarkGroup group = bm.toGroup(); + for (KBookmark b = group.first(); !b.isNull(); b = group.next(b)) { + if (b.isSeparator() || b.isGroup()) + continue; + + ret.append(b); + } + break; + } + + return ret; +} + +KBookmark::List BookmarkManager::bookmarks() const +{ + return bookmarks(d->url); +} + +KBookmark::List BookmarkManager::bookmarks(int page) const +{ + const KBookmark::List bmarks = bookmarks(); + KBookmark::List ret; + for (const KBookmark &bm : bmarks) { + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (vp.isValid() && vp.pageNumber == page) { + ret.append(bm); + } + } + + return ret; +} + +KBookmark BookmarkManager::bookmark(int page) const +{ + const KBookmark::List bmarks = bookmarks(); + for (const KBookmark &bm : bmarks) { + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (vp.isValid() && vp.pageNumber == page) { + return bm; + } + } + return KBookmark(); +} + +KBookmark BookmarkManager::bookmark(const DocumentViewport &viewport) const +{ + if (!viewport.isValid() || !isBookmarked(viewport.pageNumber)) + return KBookmark(); + + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(d->url, false, &thebg); + if (it == d->knownFiles.end()) + return KBookmark(); + + for (KBookmark bm = thebg.first(); !bm.isNull(); bm = thebg.next(bm)) { + if (bm.isSeparator() || bm.isGroup()) + continue; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (documentViewportFuzzyCompare(vp, viewport)) { + return bm; + } + } + + return KBookmark(); +} + +void BookmarkManager::save() const +{ + d->manager->emitChanged(); + emit const_cast(this)->saved(); +} + +QHash::iterator BookmarkManager::Private::bookmarkFind(const QUrl &url, bool doCreate, KBookmarkGroup *result) +{ + QHash::iterator it = knownFiles.find(url); + if (it == knownFiles.end()) { + // if the url we want to add a new entry for is not in the hash of the + // known files, then first try to find the file among the top-level + // "folder" names + bool found = false; + KBookmarkGroup root = manager->root(); + for (KBookmark bm = root.first(); !found && !bm.isNull(); bm = root.next(bm)) { + if (bm.isSeparator() || !bm.isGroup()) + continue; + + QUrl tmpurl(urlForGroup(bm)); + if (tmpurl == url) { + // got it! place it the hash of known files + KBookmarkGroup bg = bm.toGroup(); + it = knownFiles.insert(url, bg.address()); + found = true; + if (result) + *result = bg; + break; + } + } + if (!found && doCreate) { + // folder not found :( + // then, in a single step create a new folder and add it in our cache :) + QString purl = url.isLocalFile() ? url.toLocalFile() : url.toDisplayString(); + KBookmarkGroup newbg = root.createNewFolder(purl); + newbg.setUrl(url); + it = knownFiles.insert(url, newbg.address()); + if (result) + *result = newbg; + } + } else if (result) { + const KBookmark bm = manager->findByAddress(it.value()); + Q_ASSERT(bm.isGroup()); + *result = bm.toGroup(); + } + return it; +} + +void BookmarkManager::addBookmark(int page) +{ + if (page >= 0 && page < (int)d->document->m_pagesVector.count()) { + if (setPageBookmark(page)) + foreachObserver(notifyPageChanged(page, DocumentObserver::Bookmark)); + } +} + +void BookmarkManager::addBookmark(const DocumentViewport &vp) +{ + addBookmark(d->url, vp); +} + +bool BookmarkManager::addBookmark(const QUrl &documentUrl, const Okular::DocumentViewport &vp, const QString &title) +{ + if (!documentUrl.isValid() || !vp.isValid()) + return false; + + if (vp.pageNumber < 0 || vp.pageNumber >= d->document->m_pagesVector.count()) + return false; + + const QUrl referurl = mostCanonicalUrl(documentUrl); + + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(referurl, true, &thebg); + Q_ASSERT(it != d->knownFiles.end()); + + int count = 0; // Number of bookmarks in the current page + bool found = false; + // Check if the bookmark already exists + for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) { + if (bm.isSeparator() || bm.isGroup()) + continue; + + DocumentViewport bmViewport(bm.url().fragment(QUrl::FullyDecoded)); + if (bmViewport.isValid() && bmViewport.pageNumber == vp.pageNumber) { + ++count; + + if (documentViewportFuzzyCompare(bmViewport, vp)) + found = true; + } + } + + if (found) + return false; + + QString newtitle; + if (title.isEmpty()) { + // if we have no title specified for the new bookmark, then give it the + // name '#p' where p is the page number where the bookmark is located. + // if there's more than one bookmark per page, give the name '#p-n' + // where n is the index of this bookmark among the ones of its page. + if (count > 0) + newtitle = QStringLiteral("#%1-%2").arg(vp.pageNumber + 1).arg(count); + else + newtitle = QStringLiteral("#%1").arg(vp.pageNumber + 1); + } else + newtitle = title; + + QUrl newurl = referurl; + newurl.setFragment(vp.toString(), QUrl::DecodedMode); + thebg.addBookmark(newtitle, newurl, QString()); + if (referurl == d->document->m_url) { + d->urlBookmarks[vp.pageNumber]++; + foreachObserver(notifyPageChanged(vp.pageNumber, DocumentObserver::Bookmark)); + } + d->manager->emitChanged(thebg); + return true; +} + +void BookmarkManager::removeBookmark(int page) +{ + if (page >= 0 && page < (int)d->document->m_pagesVector.count()) { + if (removePageBookmark(page)) + foreachObserver(notifyPageChanged(page, DocumentObserver::Bookmark)); + } +} + +void BookmarkManager::removeBookmark(const DocumentViewport &vp) +{ + int page = vp.pageNumber; + if (page >= 0 && page < d->document->m_pagesVector.count()) { + removeBookmark(d->url, bookmark(vp)); + } +} + +void BookmarkManager::renameBookmark(KBookmark *bm, const QString &newName) +{ + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(d->url, false, &thebg); + Q_ASSERT(it != d->knownFiles.end()); + if (it == d->knownFiles.end()) + return; + + bm->setFullText(newName); + d->manager->emitChanged(thebg); +} + +void BookmarkManager::renameBookmark(const QUrl &documentUrl, const QString &newName) +{ + if (!documentUrl.isValid()) + return; + + const QUrl referurl = mostCanonicalUrl(documentUrl); + + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(referurl, false, &thebg); + Q_ASSERT(it != d->knownFiles.end()); + if (it == d->knownFiles.end()) + return; + + thebg.setFullText(newName); + d->manager->emitChanged(thebg); +} + +QString BookmarkManager::titleForUrl(const QUrl &documentUrl) const +{ + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(mostCanonicalUrl(documentUrl), false, &thebg); + Q_ASSERT(it != d->knownFiles.end()); + + return thebg.fullText(); +} + +int BookmarkManager::removeBookmark(const QUrl &documentUrl, const KBookmark &bm) +{ + if (!documentUrl.isValid() || bm.isNull() || bm.isGroup() || bm.isSeparator()) + return -1; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (!vp.isValid()) + return -1; + + const QUrl referurl = mostCanonicalUrl(documentUrl); + + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(referurl, false, &thebg); + if (it == d->knownFiles.end()) + return -1; + + thebg.deleteBookmark(bm); + + if (referurl == d->document->m_url) { + d->urlBookmarks[vp.pageNumber]--; + foreachObserver(notifyPageChanged(vp.pageNumber, DocumentObserver::Bookmark)); + } + d->manager->emitChanged(thebg); + + return vp.pageNumber; +} + +void BookmarkManager::removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list) +{ + if (!documentUrl.isValid() || list.isEmpty()) + return; + + const QUrl referurl = mostCanonicalUrl(documentUrl); + + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(referurl, false, &thebg); + if (it == d->knownFiles.end()) + return; + + const QHash oldUrlBookmarks = d->urlBookmarks; + bool deletedAny = false; + for (const KBookmark &bm : list) { + if (bm.parentGroup() == thebg) { + thebg.deleteBookmark(bm); + deletedAny = true; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (referurl == d->document->m_url) { + d->urlBookmarks[vp.pageNumber]--; + } + } + } + + if (referurl == d->document->m_url) { + for (int i = 0; i < qMax(oldUrlBookmarks.size(), d->urlBookmarks.size()); i++) { + bool oldContains = oldUrlBookmarks.contains(i) && oldUrlBookmarks[i] > 0; + bool curContains = d->urlBookmarks.contains(i) && d->urlBookmarks[i] > 0; + + if (oldContains != curContains) { + foreachObserver(notifyPageChanged(i, DocumentObserver::Bookmark)); + } else if (oldContains && oldUrlBookmarks[i] != d->urlBookmarks[i]) { + foreachObserver(notifyPageChanged(i, DocumentObserver::Bookmark)); + } + } + } + if (deletedAny) + d->manager->emitChanged(thebg); +} + +QList BookmarkManager::actionsForUrl(const QUrl &documentUrl) const +{ + const QUrl url = mostCanonicalUrl(documentUrl); + QList ret; + KBookmarkGroup group = d->manager->root(); + for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) { + if (!bm.isGroup() || urlForGroup(bm) != url) + continue; + + KBookmarkGroup group = bm.toGroup(); + for (KBookmark b = group.first(); !b.isNull(); b = group.next(b)) { + if (b.isSeparator() || b.isGroup()) + continue; + + ret.append(new OkularBookmarkAction(DocumentViewport(b.url().fragment(QUrl::FullyDecoded)), b, d, nullptr)); + } + break; + } + std::sort(ret.begin(), ret.end(), okularBookmarkActionLessThan); + return ret; +} + +void BookmarkManager::setUrl(const QUrl &url) +{ + d->url = mostCanonicalUrl(url); + d->urlBookmarks.clear(); + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(d->url, false, &thebg); + if (it != d->knownFiles.end()) { + for (KBookmark bm = thebg.first(); !bm.isNull(); bm = thebg.next(bm)) { + if (bm.isSeparator() || bm.isGroup()) + continue; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (!vp.isValid()) + continue; + + d->urlBookmarks[vp.pageNumber]++; + } + } +} + +bool BookmarkManager::setPageBookmark(int page) +{ + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(d->url, true, &thebg); + Q_ASSERT(it != d->knownFiles.end()); + + bool found = false; + bool added = false; + for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) { + if (bm.isSeparator() || bm.isGroup()) + continue; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (vp.isValid() && vp.pageNumber == page) + found = true; + } + if (!found) { + d->urlBookmarks[page]++; + DocumentViewport vp; + vp.pageNumber = page; + QUrl newurl = d->url; + newurl.setFragment(vp.toString(), QUrl::DecodedMode); + thebg.addBookmark(QLatin1String("#") + QString::number(vp.pageNumber + 1), newurl, QString()); + added = true; + d->manager->emitChanged(thebg); + } + return added; +} + +bool BookmarkManager::removePageBookmark(int page) +{ + KBookmarkGroup thebg; + QHash::iterator it = d->bookmarkFind(d->url, false, &thebg); + if (it == d->knownFiles.end()) + return false; + + bool found = false; + for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) { + if (bm.isSeparator() || bm.isGroup()) + continue; + + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (vp.isValid() && vp.pageNumber == page) { + found = true; + thebg.deleteBookmark(bm); + d->urlBookmarks[page]--; + d->manager->emitChanged(thebg); + } + } + return found; +} + +bool BookmarkManager::isBookmarked(int page) const +{ + return d->urlBookmarks.contains(page) && d->urlBookmarks[page] > 0; +} + +bool BookmarkManager::isBookmarked(const DocumentViewport &viewport) const +{ + KBookmark bm = bookmark(viewport); + + return !bm.isNull(); +} + +KBookmark BookmarkManager::nextBookmark(const DocumentViewport &viewport) const +{ + KBookmark::List bmarks = bookmarks(); + std::sort(bmarks.begin(), bmarks.end(), bookmarkLessThan); + + KBookmark bookmark; + for (const KBookmark &bm : qAsConst(bmarks)) { + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (viewport < vp) { + bookmark = bm; + break; + } + } + + return bookmark; +} + +KBookmark BookmarkManager::previousBookmark(const DocumentViewport &viewport) const +{ + KBookmark::List bmarks = bookmarks(); + std::sort(bmarks.begin(), bmarks.end(), bookmarkLessThan); + + KBookmark bookmark; + for (KBookmark::List::const_iterator it = bmarks.constEnd(); it != bmarks.constBegin(); --it) { + KBookmark bm = *(it - 1); + DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded)); + if (vp < viewport) { + bookmark = bm; + break; + } + } + + return bookmark; +} + +#undef foreachObserver +#undef foreachObserverD + +#include "bookmarkmanager.moc" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/bookmarkmanager.h b/core/bookmarkmanager.h new file mode 100644 index 0000000..970bfd4 --- /dev/null +++ b/core/bookmarkmanager.h @@ -0,0 +1,211 @@ +/*************************************************************************** + * Copyright (C) 2006 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_BOOKMARK_MANAGER_H_ +#define _OKULAR_BOOKMARK_MANAGER_H_ + +#include + +#include "okularcore_export.h" +#include +#include + +class QAction; + +namespace Okular +{ +class Document; +class DocumentPrivate; +class DocumentViewport; + +/** + * @brief Bookmarks manager utility. + * + * This class is responsible for loading and saving the bookmarks using the + * proper format, and for working with them (eg querying, adding, removing). + */ +class OKULARCORE_EXPORT BookmarkManager : public QObject +{ + Q_OBJECT + +public: + ~BookmarkManager() override; + + /** + * Returns the list of documents with bookmarks. + */ + QList files() const; + + /** + * Returns the list of bookmarks for the specified @p documentUrl. + */ + KBookmark::List bookmarks(const QUrl &documentUrl) const; + + /** + * Returns the list of bookmarks for document + * @since 0.14 (KDE 4.8) + */ + KBookmark::List bookmarks() const; + + /** + * Returns the list of bookmarks for the given page of the document + * @since 0.15 (KDE 4.9) + */ + KBookmark::List bookmarks(int page) const; + + /** + * Returns the bookmark for the given page of the document + * @since 0.14 (KDE 4.8) + */ + KBookmark bookmark(int page) const; + + /** + * Returns the bookmark for the given @p viewport of the document + * @since 0.15 (KDE 4.9) + */ + KBookmark bookmark(const DocumentViewport &viewport) const; + + /** + * Forces to save the list of bookmarks. + */ + void save() const; + + /** + * Adds a bookmark for the given @p page. + */ + void addBookmark(int page); + + /** + * Adds a bookmark for the given viewport @p vp + * @since 0.15 (KDE 4.9) + */ + void addBookmark(const DocumentViewport &vp); + + /** + * Adds a new bookmark for the @p documentUrl at the specified viewport @p vp, + * with an optional @p title. + * + * If no @p title is specified, then \em \#n will be used. + */ + bool addBookmark(const QUrl &documentUrl, const Okular::DocumentViewport &vp, const QString &title = QString()); + + /** + * Remove a bookmark for the given @p page. + */ + void removeBookmark(int page); + + /** + * Remove a bookmark for the given viewport @p vp + * @since 0.15 (KDE 4.9) + */ + void removeBookmark(const DocumentViewport &vp); + + /** + * Removes the bookmark @p bm for the @p documentUrl specified. + */ + int removeBookmark(const QUrl &documentUrl, const KBookmark &bm); + + /** + * Removes the bookmarks in @p list for the @p documentUrl specified. + * + * @note it will remove only the bookmarks which belong to @p documentUrl + * + * @since 0.11 (KDE 4.5) + */ + void removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list); + + /** + * Returns the bookmark given bookmark of the document + * @since 0.14 (KDE 4.8) + */ + void renameBookmark(KBookmark *bm, const QString &newName); + + /** + * Renames the top-level bookmark for the @p documentUrl specified with + * the @p newName specified. + * @since 0.15 (KDE 4.9) + */ + void renameBookmark(const QUrl &documentUrl, const QString &newName); + + /** + * Returns title for the @p documentUrl + * @since 0.15 (KDE 4.9) + */ + QString titleForUrl(const QUrl &documentUrl) const; + + /** + * Returns whether the given @p page is bookmarked. + */ + bool isBookmarked(int page) const; + + /** + * Return whether the given @p viewport is bookmarked. + * @since 0.15 (KDE 4.9) + */ + bool isBookmarked(const DocumentViewport &viewport) const; + + /** + * Given a @p viewport, returns the next bookmark + * @since 0.15 (KDE 4.9) + */ + KBookmark nextBookmark(const DocumentViewport &viewport) const; + + /** + * Given a @p viewport, returns the previous bookmark + * @since 0.15 (KDE 4.9) + */ + KBookmark previousBookmark(const DocumentViewport &viewport) const; + + /** + * Returns a list of actions for the bookmarks of the specified @p url. + * + * @note the actions will have no parents, so you have to delete them + * yourself + */ + QList actionsForUrl(const QUrl &documentUrl) const; + +Q_SIGNALS: + /** + * The bookmark manager is requesting to open the specified @p url. + */ + void openUrl(const QUrl &url); + + /** + * This signal is emitted whenever bookmarks have been saved. + */ + void saved(); + + /** + * The bookmarks for specified @p url were changed. + * + * @since 0.7 (KDE 4.1) + */ + void bookmarksChanged(const QUrl &url); + +private: + class Private; + Private *const d; + friend class Private; + + // private interface used by the Document + friend class Document; + friend class DocumentPrivate; + + BookmarkManager(DocumentPrivate *document); + + void setUrl(const QUrl &url); + bool setPageBookmark(int page); + bool removePageBookmark(int page); + + Q_DISABLE_COPY(BookmarkManager) +}; + +} + +#endif diff --git a/core/chooseenginedialog.cpp b/core/chooseenginedialog.cpp new file mode 100644 index 0000000..4afad67 --- /dev/null +++ b/core/chooseenginedialog.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "chooseenginedialog_p.h" + +#include +#include + +#include +#include +#include +#include + +#include "ui_chooseenginewidget.h" + +ChooseEngineDialog::ChooseEngineDialog(const QStringList &generators, const QMimeType &mime, QWidget *parent) + : QDialog(parent) +{ + setWindowTitle(i18n("Backend Selection")); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); // NOLINT(bugprone-suspicious-enum-usage) + connect(buttonBox, &QDialogButtonBox::accepted, this, &ChooseEngineDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ChooseEngineDialog::reject); + okButton->setDefault(true); + QWidget *main = new QWidget(this); + m_widget = new Ui_ChooseEngineWidget(); + m_widget->setupUi(main); + mainLayout->addWidget(main); + mainLayout->addWidget(buttonBox); + m_widget->engineList->addItems(generators); + + m_widget->description->setText( + i18n("More than one backend found for the MIME type:
" + "%1 (%2).

" + "Please select which one to use:
", + mime.comment(), + mime.name())); +} + +ChooseEngineDialog::~ChooseEngineDialog() +{ + delete m_widget; +} + +int ChooseEngineDialog::selectedGenerator() const +{ + return m_widget->engineList->currentIndex(); +} diff --git a/core/chooseenginedialog_p.h b/core/chooseenginedialog_p.h new file mode 100644 index 0000000..1d9208f --- /dev/null +++ b/core/chooseenginedialog_p.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _CHOOSEENGINEDIALOG_H +#define _CHOOSEENGINEDIALOG_H + +#include + +#include +#include + +class Ui_ChooseEngineWidget; + +class ChooseEngineDialog : public QDialog +{ + Q_OBJECT + +public: + ChooseEngineDialog(const QStringList &generators, const QMimeType &mime, QWidget *parent = nullptr); + ~ChooseEngineDialog() override; + + int selectedGenerator() const; + +protected: + Ui_ChooseEngineWidget *m_widget; +}; + +#endif diff --git a/core/chooseenginewidget.ui b/core/chooseenginewidget.ui new file mode 100644 index 0000000..541d284 --- /dev/null +++ b/core/chooseenginewidget.ui @@ -0,0 +1,42 @@ + + ChooseEngineWidget + + + + 0 + 0 + 286 + 96 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::RichText + + + + + + + + + + + diff --git a/core/debug.cpp b/core/debug.cpp new file mode 100644 index 0000000..8e37693 --- /dev/null +++ b/core/debug.cpp @@ -0,0 +1,12 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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. * + ***************************************************************************/ + +#include "debug_p.h" + +Q_LOGGING_CATEGORY(OkularCoreDebug, "org.kde.okular.core", QtWarningMsg) diff --git a/core/debug_p.h b/core/debug_p.h new file mode 100644 index 0000000..1e34bd0 --- /dev/null +++ b/core/debug_p.h @@ -0,0 +1,18 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_P_H +#define OKULAR_DEBUG_P_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularCoreDebug) + +#endif diff --git a/core/document.cpp b/core/document.cpp new file mode 100644 index 0000000..16e939c --- /dev/null +++ b/core/document.cpp @@ -0,0 +1,5475 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2008 by Albert Astals Cid * + * Copyright (C) 2017, 2018 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "document.h" +#include "document_p.h" +#include "documentcommands_p.h" + +#include +#include +#ifdef Q_OS_WIN +#define _WIN32_WINNT 0x0500 +#include +#elif defined(Q_OS_FREEBSD) +// clang-format off +// FreeBSD really wants this include order +#include +#include +// clang-format on +#include +#endif + +// qt/kde/system includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "action.h" +#include "annotations.h" +#include "annotations_p.h" +#include "audioplayer.h" +#include "audioplayer_p.h" +#include "bookmarkmanager.h" +#include "chooseenginedialog_p.h" +#include "debug_p.h" +#include "form.h" +#include "generator_p.h" +#include "interfaces/configinterface.h" +#include "interfaces/guiinterface.h" +#include "interfaces/printinterface.h" +#include "interfaces/saveinterface.h" +#include "misc.h" +#include "observer.h" +#include "page.h" +#include "page_p.h" +#include "pagecontroller_p.h" +#include "script/event_p.h" +#include "scripter.h" +#include "settings_core.h" +#include "sourcereference.h" +#include "sourcereference_p.h" +#include "texteditors_p.h" +#include "tile.h" +#include "tilesmanager_p.h" +#include "utils.h" +#include "utils_p.h" +#include "view.h" +#include "view_p.h" + +#include + +#if HAVE_MALLOC_TRIM +#include "malloc.h" +#endif + +using namespace Okular; + +struct AllocatedPixmap { + // owner of the page + DocumentObserver *observer; + int page; + qulonglong memory; + // public constructor: initialize data + AllocatedPixmap(DocumentObserver *o, int p, qulonglong m) + : observer(o) + , page(p) + , memory(m) + { + } +}; + +struct ArchiveData { + ArchiveData() + { + } + + QString originalFileName; + QTemporaryFile document; + QTemporaryFile metadataFile; +}; + +struct RunningSearch { + // store search properties + int continueOnPage; + RegularAreaRect continueOnMatch; + QSet highlightedPages; + + // fields related to previous searches (used for 'continueSearch') + QString cachedString; + Document::SearchType cachedType; + Qt::CaseSensitivity cachedCaseSensitivity; + bool cachedViewportMove : 1; + bool isCurrentlySearching : 1; + QColor cachedColor; + int pagesDone; +}; + +#define foreachObserver(cmd) \ + { \ + QSet::const_iterator it = d->m_observers.constBegin(), end = d->m_observers.constEnd(); \ + for (; it != end; ++it) { \ + (*it)->cmd; \ + } \ + } + +#define foreachObserverD(cmd) \ + { \ + QSet::const_iterator it = m_observers.constBegin(), end = m_observers.constEnd(); \ + for (; it != end; ++it) { \ + (*it)->cmd; \ + } \ + } + +#define OKULAR_HISTORY_MAXSTEPS 100 +#define OKULAR_HISTORY_SAVEDSTEPS 10 + +// how often to run slotTimedMemoryCheck +const int kMemCheckTime = 2000; // in msec + +/***** Document ******/ + +QString DocumentPrivate::pagesSizeString() const +{ + if (m_generator) { + if (m_generator->pagesSizeMetric() != Generator::None) { + QSizeF size = m_parent->allPagesSize(); + // Single page size + if (size.isValid()) + return localizedSize(size); + + // Multiple page sizes + QString sizeString; + QHash pageSizeFrequencies; + + // Compute frequencies of each page size + for (int i = 0; i < m_pagesVector.count(); ++i) { + const Page *p = m_pagesVector.at(i); + sizeString = localizedSize(QSizeF(p->width(), p->height())); + pageSizeFrequencies[sizeString] = pageSizeFrequencies.value(sizeString, 0) + 1; + } + + // Figure out which page size is most frequent + int largestFrequencySeen = 0; + QString mostCommonPageSize = QString(); + QHash::const_iterator i = pageSizeFrequencies.constBegin(); + while (i != pageSizeFrequencies.constEnd()) { + if (i.value() > largestFrequencySeen) { + largestFrequencySeen = i.value(); + mostCommonPageSize = i.key(); + } + ++i; + } + QString finalText = i18nc("@info %1 is a page size", "Most pages are %1.", mostCommonPageSize); + + return finalText; + } else + return QString(); + } else + return QString(); +} + +QString DocumentPrivate::namePaperSize(double inchesWidth, double inchesHeight) const +{ + const QPrinter::Orientation orientation = inchesWidth > inchesHeight ? QPrinter::Landscape : QPrinter::Portrait; + + const QSize pointsSize(inchesWidth * 72.0, inchesHeight * 72.0); + const QPageSize::PageSizeId paperSize = QPageSize::id(pointsSize, QPageSize::FuzzyOrientationMatch); + + const QString paperName = QPageSize::name(paperSize); + + if (orientation == QPrinter::Portrait) { + return i18nc("paper type and orientation (eg: Portrait A4)", "Portrait %1", paperName); + } else { + return i18nc("paper type and orientation (eg: Portrait A4)", "Landscape %1", paperName); + } +} + +QString DocumentPrivate::localizedSize(const QSizeF size) const +{ + double inchesWidth = 0, inchesHeight = 0; + switch (m_generator->pagesSizeMetric()) { + case Generator::Points: + inchesWidth = size.width() / 72.0; + inchesHeight = size.height() / 72.0; + break; + + case Generator::Pixels: { + const QSizeF dpi = m_generator->dpi(); + inchesWidth = size.width() / dpi.width(); + inchesHeight = size.height() / dpi.height(); + } break; + + case Generator::None: + break; + } + if (QLocale::system().measurementSystem() == QLocale::ImperialSystem) { + return i18nc("%1 is width, %2 is height, %3 is paper size name", "%1 x %2 in (%3)", inchesWidth, inchesHeight, namePaperSize(inchesWidth, inchesHeight)); + } else { + return i18nc("%1 is width, %2 is height, %3 is paper size name", "%1 x %2 mm (%3)", QString::number(inchesWidth * 25.4, 'd', 0), QString::number(inchesHeight * 25.4, 'd', 0), namePaperSize(inchesWidth, inchesHeight)); + } +} + +qulonglong DocumentPrivate::calculateMemoryToFree() +{ + // [MEM] choose memory parameters based on configuration profile + qulonglong clipValue = 0; + qulonglong memoryToFree = 0; + + switch (SettingsCore::memoryLevel()) { + case SettingsCore::EnumMemoryLevel::Low: + memoryToFree = m_allocatedPixmapsTotalMemory; + break; + + case SettingsCore::EnumMemoryLevel::Normal: { + qulonglong thirdTotalMemory = getTotalMemory() / 3; + qulonglong freeMemory = getFreeMemory(); + if (m_allocatedPixmapsTotalMemory > thirdTotalMemory) + memoryToFree = m_allocatedPixmapsTotalMemory - thirdTotalMemory; + if (m_allocatedPixmapsTotalMemory > freeMemory) + clipValue = (m_allocatedPixmapsTotalMemory - freeMemory) / 2; + } break; + + case SettingsCore::EnumMemoryLevel::Aggressive: { + qulonglong freeMemory = getFreeMemory(); + if (m_allocatedPixmapsTotalMemory > freeMemory) + clipValue = (m_allocatedPixmapsTotalMemory - freeMemory) / 2; + } break; + case SettingsCore::EnumMemoryLevel::Greedy: { + qulonglong freeSwap; + qulonglong freeMemory = getFreeMemory(&freeSwap); + const qulonglong memoryLimit = qMin(qMax(freeMemory, getTotalMemory() / 2), freeMemory + freeSwap); + if (m_allocatedPixmapsTotalMemory > memoryLimit) + clipValue = (m_allocatedPixmapsTotalMemory - memoryLimit) / 2; + } break; + } + + if (clipValue > memoryToFree) + memoryToFree = clipValue; + + return memoryToFree; +} + +void DocumentPrivate::cleanupPixmapMemory() +{ + cleanupPixmapMemory(calculateMemoryToFree()); +} + +void DocumentPrivate::cleanupPixmapMemory(qulonglong memoryToFree) +{ + if (memoryToFree < 1) + return; + + const int currentViewportPage = (*m_viewportIterator).pageNumber; + + // Create a QMap of visible rects, indexed by page number + QMap visibleRects; + QVector::const_iterator vIt = m_pageRects.constBegin(), vEnd = m_pageRects.constEnd(); + for (; vIt != vEnd; ++vIt) + visibleRects.insert((*vIt)->pageNumber, (*vIt)); + + // Free memory starting from pages that are farthest from the current one + int pagesFreed = 0; + while (memoryToFree > 0) { + AllocatedPixmap *p = searchLowestPriorityPixmap(true, true); + if (!p) // No pixmap to remove + break; + + qCDebug(OkularCoreDebug).nospace() << "Evicting cache pixmap observer=" << p->observer << " page=" << p->page; + + // m_allocatedPixmapsTotalMemory can't underflow because we always add or remove + // the memory used by the AllocatedPixmap so at most it can reach zero + m_allocatedPixmapsTotalMemory -= p->memory; + // Make sure memoryToFree does not underflow + if (p->memory > memoryToFree) + memoryToFree = 0; + else + memoryToFree -= p->memory; + pagesFreed++; + // delete pixmap + m_pagesVector.at(p->page)->deletePixmap(p->observer); + // delete allocation descriptor + delete p; + } + + // If we're still on low memory, try to free individual tiles + + // Store pages that weren't completely removed + + QLinkedList pixmapsToKeep; + while (memoryToFree > 0) { + int clean_hits = 0; + for (DocumentObserver *observer : qAsConst(m_observers)) { + AllocatedPixmap *p = searchLowestPriorityPixmap(false, true, observer); + if (!p) // No pixmap to remove + continue; + + clean_hits++; + + TilesManager *tilesManager = m_pagesVector.at(p->page)->d->tilesManager(observer); + if (tilesManager && tilesManager->totalMemory() > 0) { + qulonglong memoryDiff = p->memory; + NormalizedRect visibleRect; + if (visibleRects.contains(p->page)) + visibleRect = visibleRects[p->page]->rect; + + // Free non visible tiles + tilesManager->cleanupPixmapMemory(memoryToFree, visibleRect, currentViewportPage); + + p->memory = tilesManager->totalMemory(); + memoryDiff -= p->memory; + memoryToFree = (memoryDiff < memoryToFree) ? (memoryToFree - memoryDiff) : 0; + m_allocatedPixmapsTotalMemory -= memoryDiff; + + if (p->memory > 0) + pixmapsToKeep.append(p); + else + delete p; + } else + pixmapsToKeep.append(p); + } + + if (clean_hits == 0) + break; + } + + m_allocatedPixmaps += pixmapsToKeep; + // p--rintf("freeMemory A:[%d -%d = %d] \n", m_allocatedPixmaps.count() + pagesFreed, pagesFreed, m_allocatedPixmaps.count() ); +} + +/* Returns the next pixmap to evict from cache, or NULL if no suitable pixmap + * if found. If unloadableOnly is set, only unloadable pixmaps are returned. If + * thenRemoveIt is set, the pixmap is removed from m_allocatedPixmaps before + * returning it + */ +AllocatedPixmap *DocumentPrivate::searchLowestPriorityPixmap(bool unloadableOnly, bool thenRemoveIt, DocumentObserver *observer) +{ + QLinkedList::iterator pIt = m_allocatedPixmaps.begin(); + QLinkedList::iterator pEnd = m_allocatedPixmaps.end(); + QLinkedList::iterator farthestPixmap = pEnd; + const int currentViewportPage = (*m_viewportIterator).pageNumber; + + /* Find the pixmap that is farthest from the current viewport */ + int maxDistance = -1; + while (pIt != pEnd) { + const AllocatedPixmap *p = *pIt; + // Filter by observer + if (observer == nullptr || p->observer == observer) { + const int distance = qAbs(p->page - currentViewportPage); + if (maxDistance < distance && (!unloadableOnly || p->observer->canUnloadPixmap(p->page))) { + maxDistance = distance; + farthestPixmap = pIt; + } + } + ++pIt; + } + + /* No pixmap to remove */ + if (farthestPixmap == pEnd) + return nullptr; + + AllocatedPixmap *selectedPixmap = *farthestPixmap; + if (thenRemoveIt) + m_allocatedPixmaps.erase(farthestPixmap); + return selectedPixmap; +} + +qulonglong DocumentPrivate::getTotalMemory() +{ + static qulonglong cachedValue = 0; + if (cachedValue) + return cachedValue; + +#if defined(Q_OS_LINUX) + // if /proc/meminfo doesn't exist, return 128MB + QFile memFile(QStringLiteral("/proc/meminfo")); + if (!memFile.open(QIODevice::ReadOnly)) + return (cachedValue = 134217728); + + QTextStream readStream(&memFile); + while (true) { + QString entry = readStream.readLine(); + if (entry.isNull()) + break; + if (entry.startsWith(QLatin1String("MemTotal:"))) + return (cachedValue = (Q_UINT64_C(1024) * entry.section(QLatin1Char(' '), -2, -2).toULongLong())); + } +#elif defined(Q_OS_FREEBSD) + qulonglong physmem; + int mib[] = {CTL_HW, HW_PHYSMEM}; + size_t len = sizeof(physmem); + if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0) + return (cachedValue = physmem); +#elif defined(Q_OS_WIN) + MEMORYSTATUSEX stat; + stat.dwLength = sizeof(stat); + GlobalMemoryStatusEx(&stat); + + return (cachedValue = stat.ullTotalPhys); +#endif + return (cachedValue = 134217728); +} + +qulonglong DocumentPrivate::getFreeMemory(qulonglong *freeSwap) +{ + static QTime lastUpdate = QTime::currentTime().addSecs(-3); + static qulonglong cachedValue = 0; + static qulonglong cachedFreeSwap = 0; + + if (qAbs(lastUpdate.msecsTo(QTime::currentTime())) <= kMemCheckTime - 100) { + if (freeSwap) + *freeSwap = cachedFreeSwap; + return cachedValue; + } + + /* Initialize the returned free swap value to 0. It is overwritten if the + * actual value is available */ + if (freeSwap) + *freeSwap = 0; + +#if defined(Q_OS_LINUX) + // if /proc/meminfo doesn't exist, return MEMORY FULL + QFile memFile(QStringLiteral("/proc/meminfo")); + if (!memFile.open(QIODevice::ReadOnly)) + return 0; + + // read /proc/meminfo and sum up the contents of 'MemFree', 'Buffers' + // and 'Cached' fields. consider swapped memory as used memory. + qulonglong memoryFree = 0; + QString entry; + QTextStream readStream(&memFile); + static const int nElems = 5; + QString names[nElems] = {QStringLiteral("MemFree:"), QStringLiteral("Buffers:"), QStringLiteral("Cached:"), QStringLiteral("SwapFree:"), QStringLiteral("SwapTotal:")}; + qulonglong values[nElems] = {0, 0, 0, 0, 0}; + bool foundValues[nElems] = {false, false, false, false, false}; + while (true) { + entry = readStream.readLine(); + if (entry.isNull()) + break; + for (int i = 0; i < nElems; ++i) { + if (entry.startsWith(names[i])) { + values[i] = entry.section(QLatin1Char(' '), -2, -2).toULongLong(&foundValues[i]); + } + } + } + memFile.close(); + bool found = true; + for (int i = 0; found && i < nElems; ++i) + found = found && foundValues[i]; + if (found) { + /* MemFree + Buffers + Cached - SwapUsed = + * = MemFree + Buffers + Cached - (SwapTotal - SwapFree) = + * = MemFree + Buffers + Cached + SwapFree - SwapTotal */ + memoryFree = values[0] + values[1] + values[2] + values[3]; + if (values[4] > memoryFree) + memoryFree = 0; + else + memoryFree -= values[4]; + } else { + return 0; + } + + lastUpdate = QTime::currentTime(); + + if (freeSwap) + *freeSwap = (cachedFreeSwap = (Q_UINT64_C(1024) * values[3])); + return (cachedValue = (Q_UINT64_C(1024) * memoryFree)); +#elif defined(Q_OS_FREEBSD) + qulonglong cache, inact, free, psize; + size_t cachelen, inactlen, freelen, psizelen; + cachelen = sizeof(cache); + inactlen = sizeof(inact); + freelen = sizeof(free); + psizelen = sizeof(psize); + // sum up inactive, cached and free memory + if (sysctlbyname("vm.stats.vm.v_cache_count", &cache, &cachelen, NULL, 0) == 0 && sysctlbyname("vm.stats.vm.v_inactive_count", &inact, &inactlen, NULL, 0) == 0 && + sysctlbyname("vm.stats.vm.v_free_count", &free, &freelen, NULL, 0) == 0 && sysctlbyname("vm.stats.vm.v_page_size", &psize, &psizelen, NULL, 0) == 0) { + lastUpdate = QTime::currentTime(); + return (cachedValue = (cache + inact + free) * psize); + } else { + return 0; + } +#elif defined(Q_OS_WIN) + MEMORYSTATUSEX stat; + stat.dwLength = sizeof(stat); + GlobalMemoryStatusEx(&stat); + + lastUpdate = QTime::currentTime(); + + if (freeSwap) + *freeSwap = (cachedFreeSwap = stat.ullAvailPageFile); + return (cachedValue = stat.ullAvailPhys); +#else + // tell the memory is full.. will act as in LOW profile + return 0; +#endif +} + +bool DocumentPrivate::loadDocumentInfo(LoadDocumentInfoFlags loadWhat) +// note: load data and stores it internally (document or pages). observers +// are still uninitialized at this point so don't access them +{ + // qCDebug(OkularCoreDebug).nospace() << "Using '" << d->m_xmlFileName << "' as document info file."; + if (m_xmlFileName.isEmpty()) + return false; + + QFile infoFile(m_xmlFileName); + return loadDocumentInfo(infoFile, loadWhat); +} + +bool DocumentPrivate::loadDocumentInfo(QFile &infoFile, LoadDocumentInfoFlags loadWhat) +{ + if (!infoFile.exists() || !infoFile.open(QIODevice::ReadOnly)) + return false; + + // Load DOM from XML file + QDomDocument doc(QStringLiteral("documentInfo")); + if (!doc.setContent(&infoFile)) { + qCDebug(OkularCoreDebug) << "Can't load XML pair! Check for broken xml."; + infoFile.close(); + return false; + } + infoFile.close(); + + QDomElement root = doc.documentElement(); + + if (root.tagName() != QLatin1String("documentInfo")) + return false; + + bool loadedAnything = false; // set if something gets actually loaded + + // Parse the DOM tree + QDomNode topLevelNode = root.firstChild(); + while (topLevelNode.isElement()) { + QString catName = topLevelNode.toElement().tagName(); + + // Restore page attributes (bookmark, annotations, ...) from the DOM + if (catName == QLatin1String("pageList") && (loadWhat & LoadPageInfo)) { + QDomNode pageNode = topLevelNode.firstChild(); + while (pageNode.isElement()) { + QDomElement pageElement = pageNode.toElement(); + if (pageElement.hasAttribute(QStringLiteral("number"))) { + // get page number (node's attribute) + bool ok; + int pageNumber = pageElement.attribute(QStringLiteral("number")).toInt(&ok); + + // pass the domElement to the right page, to read config data from + if (ok && pageNumber >= 0 && pageNumber < (int)m_pagesVector.count()) { + if (m_pagesVector[pageNumber]->d->restoreLocalContents(pageElement)) + loadedAnything = true; + } + } + pageNode = pageNode.nextSibling(); + } + } + + // Restore 'general info' from the DOM + else if (catName == QLatin1String("generalInfo") && (loadWhat & LoadGeneralInfo)) { + QDomNode infoNode = topLevelNode.firstChild(); + while (infoNode.isElement()) { + QDomElement infoElement = infoNode.toElement(); + + // restore viewports history + if (infoElement.tagName() == QLatin1String("history")) { + // clear history + m_viewportHistory.clear(); + // append old viewports + QDomNode historyNode = infoNode.firstChild(); + while (historyNode.isElement()) { + QDomElement historyElement = historyNode.toElement(); + if (historyElement.hasAttribute(QStringLiteral("viewport"))) { + QString vpString = historyElement.attribute(QStringLiteral("viewport")); + m_viewportIterator = m_viewportHistory.insert(m_viewportHistory.end(), DocumentViewport(vpString)); + loadedAnything = true; + } + historyNode = historyNode.nextSibling(); + } + // consistency check + if (m_viewportHistory.isEmpty()) + m_viewportIterator = m_viewportHistory.insert(m_viewportHistory.end(), DocumentViewport()); + } else if (infoElement.tagName() == QLatin1String("rotation")) { + QString str = infoElement.text(); + bool ok = true; + int newrotation = !str.isEmpty() ? (str.toInt(&ok) % 4) : 0; + if (ok && newrotation != 0) { + setRotationInternal(newrotation, false); + loadedAnything = true; + } + } else if (infoElement.tagName() == QLatin1String("views")) { + QDomNode viewNode = infoNode.firstChild(); + while (viewNode.isElement()) { + QDomElement viewElement = viewNode.toElement(); + if (viewElement.tagName() == QLatin1String("view")) { + const QString viewName = viewElement.attribute(QStringLiteral("name")); + for (View *view : qAsConst(m_views)) { + if (view->name() == viewName) { + loadViewsInfo(view, viewElement); + loadedAnything = true; + break; + } + } + } + viewNode = viewNode.nextSibling(); + } + } + infoNode = infoNode.nextSibling(); + } + } + + topLevelNode = topLevelNode.nextSibling(); + } // + + return loadedAnything; +} + +void DocumentPrivate::loadViewsInfo(View *view, const QDomElement &e) +{ + QDomNode viewNode = e.firstChild(); + while (viewNode.isElement()) { + QDomElement viewElement = viewNode.toElement(); + + if (viewElement.tagName() == QLatin1String("zoom")) { + const QString valueString = viewElement.attribute(QStringLiteral("value")); + bool newzoom_ok = true; + const double newzoom = !valueString.isEmpty() ? valueString.toDouble(&newzoom_ok) : 1.0; + if (newzoom_ok && newzoom != 0 && view->supportsCapability(View::Zoom) && (view->capabilityFlags(View::Zoom) & (View::CapabilityRead | View::CapabilitySerializable))) { + view->setCapability(View::Zoom, newzoom); + } + const QString modeString = viewElement.attribute(QStringLiteral("mode")); + bool newmode_ok = true; + const int newmode = !modeString.isEmpty() ? modeString.toInt(&newmode_ok) : 2; + if (newmode_ok && view->supportsCapability(View::ZoomModality) && (view->capabilityFlags(View::ZoomModality) & (View::CapabilityRead | View::CapabilitySerializable))) { + view->setCapability(View::ZoomModality, newmode); + } + } else if (viewElement.tagName() == QLatin1String("viewMode")) { + const QString modeString = viewElement.attribute(QStringLiteral("mode")); + bool newmode_ok = true; + const int newmode = !modeString.isEmpty() ? modeString.toInt(&newmode_ok) : 2; + if (newmode_ok && view->supportsCapability(View::ViewModeModality) && (view->capabilityFlags(View::ViewModeModality) & (View::CapabilityRead | View::CapabilitySerializable))) { + view->setCapability(View::ViewModeModality, newmode); + } + } else if (viewElement.tagName() == QLatin1String("continuous")) { + const QString modeString = viewElement.attribute(QStringLiteral("mode")); + bool newmode_ok = true; + const int newmode = !modeString.isEmpty() ? modeString.toInt(&newmode_ok) : 2; + if (newmode_ok && view->supportsCapability(View::Continuous) && (view->capabilityFlags(View::Continuous) & (View::CapabilityRead | View::CapabilitySerializable))) { + view->setCapability(View::Continuous, newmode); + } + } else if (viewElement.tagName() == QLatin1String("trimMargins")) { + const QString valueString = viewElement.attribute(QStringLiteral("value")); + bool newmode_ok = true; + const int newmode = !valueString.isEmpty() ? valueString.toInt(&newmode_ok) : 2; + if (newmode_ok && view->supportsCapability(View::TrimMargins) && (view->capabilityFlags(View::TrimMargins) & (View::CapabilityRead | View::CapabilitySerializable))) { + view->setCapability(View::TrimMargins, newmode); + } + } + + viewNode = viewNode.nextSibling(); + } +} + +void DocumentPrivate::saveViewsInfo(View *view, QDomElement &e) const +{ + if (view->supportsCapability(View::Zoom) && (view->capabilityFlags(View::Zoom) & (View::CapabilityRead | View::CapabilitySerializable)) && view->supportsCapability(View::ZoomModality) && + (view->capabilityFlags(View::ZoomModality) & (View::CapabilityRead | View::CapabilitySerializable))) { + QDomElement zoomEl = e.ownerDocument().createElement(QStringLiteral("zoom")); + e.appendChild(zoomEl); + bool ok = true; + const double zoom = view->capability(View::Zoom).toDouble(&ok); + if (ok && zoom != 0) { + zoomEl.setAttribute(QStringLiteral("value"), QString::number(zoom)); + } + const int mode = view->capability(View::ZoomModality).toInt(&ok); + if (ok) { + zoomEl.setAttribute(QStringLiteral("mode"), mode); + } + } + if (view->supportsCapability(View::Continuous) && (view->capabilityFlags(View::Continuous) & (View::CapabilityRead | View::CapabilitySerializable))) { + QDomElement contEl = e.ownerDocument().createElement(QStringLiteral("continuous")); + e.appendChild(contEl); + const bool mode = view->capability(View::Continuous).toBool(); + contEl.setAttribute(QStringLiteral("mode"), mode); + } + if (view->supportsCapability(View::ViewModeModality) && (view->capabilityFlags(View::ViewModeModality) & (View::CapabilityRead | View::CapabilitySerializable))) { + QDomElement viewEl = e.ownerDocument().createElement(QStringLiteral("viewMode")); + e.appendChild(viewEl); + bool ok = true; + const int mode = view->capability(View::ViewModeModality).toInt(&ok); + if (ok) { + viewEl.setAttribute(QStringLiteral("mode"), mode); + } + } + if (view->supportsCapability(View::TrimMargins) && (view->capabilityFlags(View::TrimMargins) & (View::CapabilityRead | View::CapabilitySerializable))) { + QDomElement contEl = e.ownerDocument().createElement(QStringLiteral("trimMargins")); + e.appendChild(contEl); + const bool value = view->capability(View::TrimMargins).toBool(); + contEl.setAttribute(QStringLiteral("value"), value); + } +} + +QUrl DocumentPrivate::giveAbsoluteUrl(const QString &fileName) const +{ + if (!QDir::isRelativePath(fileName)) + return QUrl::fromLocalFile(fileName); + + if (!m_url.isValid()) + return QUrl(); + + return QUrl(KIO::upUrl(m_url).toString() + fileName); +} + +bool DocumentPrivate::openRelativeFile(const QString &fileName) +{ + const QUrl newUrl = giveAbsoluteUrl(fileName); + if (newUrl.isEmpty()) + return false; + + qCDebug(OkularCoreDebug).nospace() << "openRelativeFile: '" << newUrl << "'"; + + emit m_parent->openUrl(newUrl); + return m_url == newUrl; +} + +Generator *DocumentPrivate::loadGeneratorLibrary(const KPluginMetaData &service) +{ + KPluginLoader loader(service.fileName()); + qCDebug(OkularCoreDebug) << service.fileName(); + KPluginFactory *factory = loader.factory(); + if (!factory) { + qCWarning(OkularCoreDebug).nospace() << "Invalid plugin factory for " << service.fileName() << ":" << loader.errorString(); + return nullptr; + } + + Generator *plugin = factory->create(); + + GeneratorInfo info(plugin, service); + m_loadedGenerators.insert(service.pluginId(), info); + return plugin; +} + +void DocumentPrivate::loadAllGeneratorLibraries() +{ + if (m_generatorsLoaded) + return; + + loadServiceList(availableGenerators()); + + m_generatorsLoaded = true; +} + +void DocumentPrivate::loadServiceList(const QVector &offers) +{ + int count = offers.count(); + if (count <= 0) + return; + + for (int i = 0; i < count; ++i) { + QString id = offers.at(i).pluginId(); + // don't load already loaded generators + QHash::const_iterator genIt = m_loadedGenerators.constFind(id); + if (!m_loadedGenerators.isEmpty() && genIt != m_loadedGenerators.constEnd()) + continue; + + Generator *g = loadGeneratorLibrary(offers.at(i)); + (void)g; + } +} + +void DocumentPrivate::unloadGenerator(const GeneratorInfo &info) +{ + delete info.generator; +} + +void DocumentPrivate::cacheExportFormats() +{ + if (m_exportCached) + return; + + const ExportFormat::List formats = m_generator->exportFormats(); + for (int i = 0; i < formats.count(); ++i) { + if (formats.at(i).mimeType().name() == QLatin1String("text/plain")) + m_exportToText = formats.at(i); + else + m_exportFormats.append(formats.at(i)); + } + + m_exportCached = true; +} + +ConfigInterface *DocumentPrivate::generatorConfig(GeneratorInfo &info) +{ + if (info.configChecked) + return info.config; + + info.config = qobject_cast(info.generator); + info.configChecked = true; + return info.config; +} + +SaveInterface *DocumentPrivate::generatorSave(GeneratorInfo &info) +{ + if (info.saveChecked) + return info.save; + + info.save = qobject_cast(info.generator); + info.saveChecked = true; + return info.save; +} + +Document::OpenResult DocumentPrivate::openDocumentInternal(const KPluginMetaData &offer, bool isstdin, const QString &docFile, const QByteArray &filedata, const QString &password) +{ + QString propName = offer.pluginId(); + QHash::const_iterator genIt = m_loadedGenerators.constFind(propName); + m_walletGenerator = nullptr; + if (genIt != m_loadedGenerators.constEnd()) { + m_generator = genIt.value().generator; + } else { + m_generator = loadGeneratorLibrary(offer); + if (!m_generator) + return Document::OpenError; + genIt = m_loadedGenerators.constFind(propName); + Q_ASSERT(genIt != m_loadedGenerators.constEnd()); + } + Q_ASSERT_X(m_generator, "Document::load()", "null generator?!"); + + m_generator->d_func()->m_document = this; + + // connect error reporting signals + m_openError.clear(); + QMetaObject::Connection errorToOpenErrorConnection = QObject::connect(m_generator, &Generator::error, m_parent, [this](const QString &message) { m_openError = message; }); + QObject::connect(m_generator, &Generator::warning, m_parent, &Document::warning); + QObject::connect(m_generator, &Generator::notice, m_parent, &Document::notice); + + QApplication::setOverrideCursor(Qt::WaitCursor); + + const QSizeF dpi = Utils::realDpi(m_widget); + qCDebug(OkularCoreDebug) << "Output DPI:" << dpi; + m_generator->setDPI(dpi); + + Document::OpenResult openResult = Document::OpenError; + if (!isstdin) { + openResult = m_generator->loadDocumentWithPassword(docFile, m_pagesVector, password); + } else if (!filedata.isEmpty()) { + if (m_generator->hasFeature(Generator::ReadRawData)) { + openResult = m_generator->loadDocumentFromDataWithPassword(filedata, m_pagesVector, password); + } else { + m_tempFile = new QTemporaryFile(); + if (!m_tempFile->open()) { + delete m_tempFile; + m_tempFile = nullptr; + } else { + m_tempFile->write(filedata); + QString tmpFileName = m_tempFile->fileName(); + m_tempFile->close(); + openResult = m_generator->loadDocumentWithPassword(tmpFileName, m_pagesVector, password); + } + } + } + + QApplication::restoreOverrideCursor(); + if (openResult != Document::OpenSuccess || m_pagesVector.size() <= 0) { + m_generator->d_func()->m_document = nullptr; + QObject::disconnect(m_generator, nullptr, m_parent, nullptr); + + // TODO this is a bit of a hack, since basically means that + // you can only call walletDataForFile after calling openDocument + // but since in reality it's what happens I've decided not to refactor/break API + // One solution is just kill walletDataForFile and make OpenResult be an object + // where the wallet data is also returned when OpenNeedsPassword + m_walletGenerator = m_generator; + m_generator = nullptr; + + qDeleteAll(m_pagesVector); + m_pagesVector.clear(); + delete m_tempFile; + m_tempFile = nullptr; + + // TODO: emit a message telling the document is empty + if (openResult == Document::OpenSuccess) + openResult = Document::OpenError; + } else { + /* + * Now that the documen is opened, the tab (if using tabs) is visible, which mean that + * we can now connect the error reporting signal directly to the parent + */ + + QObject::disconnect(errorToOpenErrorConnection); + QObject::connect(m_generator, &Generator::error, m_parent, &Document::error); + } + + return openResult; +} + +bool DocumentPrivate::savePageDocumentInfo(QTemporaryFile *infoFile, int what) const +{ + if (infoFile->open()) { + // 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")); + doc.appendChild(root); + + // 2.1. Save page attributes (bookmark state, annotations, ... ) to DOM + QDomElement pageList = doc.createElement(QStringLiteral("pageList")); + root.appendChild(pageList); + // .... save pages that hold data + QVector::const_iterator pIt = m_pagesVector.constBegin(), pEnd = m_pagesVector.constEnd(); + for (; pIt != pEnd; ++pIt) + (*pIt)->d->saveLocalContents(pageList, doc, PageItems(what)); + + // 3. Save DOM to XML file + QString xml = doc.toString(); + QTextStream os(infoFile); + os.setCodec("UTF-8"); + os << xml; + return true; + } + return false; +} + +DocumentViewport DocumentPrivate::nextDocumentViewport() const +{ + DocumentViewport ret = m_nextDocumentViewport; + if (!m_nextDocumentDestination.isEmpty() && m_generator) { + DocumentViewport vp(m_parent->metaData(QStringLiteral("NamedViewport"), m_nextDocumentDestination).toString()); + if (vp.isValid()) { + ret = vp; + } + } + return ret; +} + +void DocumentPrivate::performAddPageAnnotation(int page, Annotation *annotation) +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + AnnotationProxy *proxy = iface ? iface->annotationProxy() : nullptr; + + // find out the page to attach annotation + Page *kp = m_pagesVector[page]; + if (!m_generator || !kp) + return; + + // the annotation belongs already to a page + if (annotation->d_ptr->m_page) + return; + + // add annotation to the page + kp->addAnnotation(annotation); + + // tell the annotation proxy + if (proxy && proxy->supports(AnnotationProxy::Addition)) + proxy->notifyAddition(annotation, page); + + // notify observers about the change + notifyAnnotationChanges(page); + + if (annotation->flags() & Annotation::ExternallyDrawn) { + // Redraw everything, including ExternallyDrawn annotations + refreshPixmaps(page); + } +} + +void DocumentPrivate::performRemovePageAnnotation(int page, Annotation *annotation) +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + AnnotationProxy *proxy = iface ? iface->annotationProxy() : nullptr; + bool isExternallyDrawn; + + // find out the page + Page *kp = m_pagesVector[page]; + if (!m_generator || !kp) + return; + + if (annotation->flags() & Annotation::ExternallyDrawn) + isExternallyDrawn = true; + else + isExternallyDrawn = false; + + // try to remove the annotation + if (m_parent->canRemovePageAnnotation(annotation)) { + // tell the annotation proxy + if (proxy && proxy->supports(AnnotationProxy::Removal)) + proxy->notifyRemoval(annotation, page); + + kp->removeAnnotation(annotation); // Also destroys the object + + // in case of success, notify observers about the change + notifyAnnotationChanges(page); + + if (isExternallyDrawn) { + // Redraw everything, including ExternallyDrawn annotations + refreshPixmaps(page); + } + } +} + +void DocumentPrivate::performModifyPageAnnotation(int page, Annotation *annotation, bool appearanceChanged) +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + AnnotationProxy *proxy = iface ? iface->annotationProxy() : nullptr; + + // find out the page + Page *kp = m_pagesVector[page]; + if (!m_generator || !kp) + return; + + // tell the annotation proxy + if (proxy && proxy->supports(AnnotationProxy::Modification)) { + proxy->notifyModification(annotation, page, appearanceChanged); + } + + // notify observers about the change + notifyAnnotationChanges(page); + if (appearanceChanged && (annotation->flags() & Annotation::ExternallyDrawn)) { + /* When an annotation is being moved, the generator will not render it. + * Therefore there's no need to refresh pixmaps after the first time */ + if (annotation->flags() & (Annotation::BeingMoved | Annotation::BeingResized)) { + if (m_annotationBeingModified) + return; + else // First time: take note + m_annotationBeingModified = true; + } else { + m_annotationBeingModified = false; + } + + // Redraw everything, including ExternallyDrawn annotations + qCDebug(OkularCoreDebug) << "Refreshing Pixmaps"; + refreshPixmaps(page); + } +} + +void DocumentPrivate::performSetAnnotationContents(const QString &newContents, Annotation *annot, int pageNumber) +{ + bool appearanceChanged = false; + + // Check if appearanceChanged should be true + switch (annot->subType()) { + // If it's an in-place TextAnnotation, set the inplace text + case Okular::Annotation::AText: { + Okular::TextAnnotation *txtann = static_cast(annot); + if (txtann->textType() == Okular::TextAnnotation::InPlace) { + appearanceChanged = true; + } + break; + } + // If it's a LineAnnotation, check if caption text is visible + case Okular::Annotation::ALine: { + Okular::LineAnnotation *lineann = static_cast(annot); + if (lineann->showCaption()) + appearanceChanged = true; + break; + } + default: + break; + } + + // Set contents + annot->setContents(newContents); + + // Tell the document the annotation has been modified + performModifyPageAnnotation(pageNumber, annot, appearanceChanged); +} + +void DocumentPrivate::recalculateForms() +{ + const QVariant fco = m_parent->metaData(QStringLiteral("FormCalculateOrder")); + const QVector formCalculateOrder = fco.value>(); + foreach (int formId, formCalculateOrder) { + for (uint pageIdx = 0; pageIdx < m_parent->pages(); pageIdx++) { + const Page *p = m_parent->page(pageIdx); + if (p) { + bool pageNeedsRefresh = false; + foreach (FormField *form, p->formFields()) { + if (form->id() == formId) { + Action *action = form->additionalAction(FormField::CalculateField); + if (action) { + FormFieldText *fft = dynamic_cast(form); + std::shared_ptr event; + QString oldVal; + if (fft) { + // Prepare text calculate event + event = Event::createFormCalculateEvent(fft, m_pagesVector[pageIdx]); + if (!m_scripter) + m_scripter = new Scripter(this); + m_scripter->setEvent(event.get()); + // The value maybe changed in javascript so save it first. + oldVal = fft->text(); + } + + m_parent->processAction(action); + if (event && fft) { + // Update text field from calculate + m_scripter->setEvent(nullptr); + const QString newVal = event->value().toString(); + if (newVal != oldVal) { + fft->setText(newVal); + fft->setAppearanceText(newVal); + if (const Okular::Action *action = fft->additionalAction(Okular::FormField::FormatField)) { + // The format action handles the refresh. + m_parent->processFormatAction(action, fft); + } else { + emit m_parent->refreshFormWidget(fft); + pageNeedsRefresh = true; + } + } + } + } else { + qWarning() << "Form that is part of calculate order doesn't have a calculate action"; + } + } + } + if (pageNeedsRefresh) { + refreshPixmaps(p->number()); + } + } + } + } +} + +void DocumentPrivate::saveDocumentInfo() const +{ + if (m_xmlFileName.isEmpty()) + return; + + QFile infoFile(m_xmlFileName); + qCDebug(OkularCoreDebug) << "About to save document info to" << m_xmlFileName; + if (!infoFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + qCWarning(OkularCoreDebug) << "Failed to open docdata file" << m_xmlFileName; + return; + } + // 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 + // -> do this if there are not-yet-migrated annots or forms in docdata/ + if (m_docdataMigrationNeeded) { + QDomElement pageList = doc.createElement(QStringLiteral("pageList")); + root.appendChild(pageList); + // OriginalAnnotationPageItems and OriginalFormFieldPageItems tell to + // store the same unmodified annotation list and form contents that we + // read when we opened the file and ignore any change made by the user. + // Since we don't store annotations and forms in docdata/ any more, this is + // necessary to preserve annotations/forms that previous Okular version + // had stored there. + const PageItems saveWhat = AllPageItems | OriginalAnnotationPageItems | OriginalFormFieldPageItems; + // .... save pages that hold data + QVector::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 + const auto currentViewportIterator = QLinkedList::const_iterator(m_viewportIterator); + QLinkedList::const_iterator backIterator = currentViewportIterator; + 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::const_iterator endIt = currentViewportIterator; + ++endIt; + while (backIterator != endIt) { + QString name = (backIterator == currentViewportIterator) ? QStringLiteral("current") : QStringLiteral("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); + for (View *view : qAsConst(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(); +} + +void DocumentPrivate::slotTimedMemoryCheck() +{ + // [MEM] clean memory (for 'free mem dependent' profiles only) + if (SettingsCore::memoryLevel() != SettingsCore::EnumMemoryLevel::Low && m_allocatedPixmapsTotalMemory > 1024 * 1024) + cleanupPixmapMemory(); +} + +void DocumentPrivate::sendGeneratorPixmapRequest() +{ + /* If the pixmap cache will have to be cleaned in order to make room for the + * next request, get the distance from the current viewport of the page + * whose pixmap will be removed. We will ignore preload requests for pages + * that are at the same distance or farther */ + const qulonglong memoryToFree = calculateMemoryToFree(); + const int currentViewportPage = (*m_viewportIterator).pageNumber; + int maxDistance = INT_MAX; // Default: No maximum + if (memoryToFree) { + AllocatedPixmap *pixmapToReplace = searchLowestPriorityPixmap(true); + if (pixmapToReplace) + maxDistance = qAbs(pixmapToReplace->page - currentViewportPage); + } + + // find a request + PixmapRequest *request = nullptr; + m_pixmapRequestsMutex.lock(); + while (!m_pixmapRequestsStack.isEmpty() && !request) { + PixmapRequest *r = m_pixmapRequestsStack.last(); + if (!r) { + m_pixmapRequestsStack.pop_back(); + continue; + } + + QRect requestRect = r->isTile() ? r->normalizedRect().geometry(r->width(), r->height()) : QRect(0, 0, r->width(), r->height()); + TilesManager *tilesManager = r->d->tilesManager(); + const double normalizedArea = r->normalizedRect().width() * r->normalizedRect().height(); + const QScreen *screen = nullptr; + if (m_widget) { + const QWindow *window = m_widget->window()->windowHandle(); + if (window) + screen = window->screen(); + } + if (!screen) + screen = QGuiApplication::primaryScreen(); + const long screenSize = screen->devicePixelRatio() * screen->size().width() * screen->devicePixelRatio() * screen->size().height(); + + // If it's a preload but the generator is not threaded no point in trying to preload + if (r->preload() && !m_generator->hasFeature(Generator::Threaded)) { + m_pixmapRequestsStack.pop_back(); + delete r; + } + // request only if page isn't already present and request has valid id + else if ((!r->d->mForce && r->page()->hasPixmap(r->observer(), r->width(), r->height(), r->normalizedRect())) || !m_observers.contains(r->observer())) { + m_pixmapRequestsStack.pop_back(); + delete r; + } else if (!r->d->mForce && r->preload() && qAbs(r->pageNumber() - currentViewportPage) >= maxDistance) { + m_pixmapRequestsStack.pop_back(); + // qCDebug(OkularCoreDebug) << "Ignoring request that doesn't fit in cache"; + delete r; + } + // Ignore requests for pixmaps that are already being generated + else if (tilesManager && tilesManager->isRequesting(r->normalizedRect(), r->width(), r->height())) { + m_pixmapRequestsStack.pop_back(); + delete r; + } + // If the requested area is above 4*screenSize pixels, and we're not rendering most of the page, switch on the tile manager + else if (!tilesManager && m_generator->hasFeature(Generator::TiledRendering) && (long)r->width() * (long)r->height() > 4L * screenSize && normalizedArea < 0.75 && normalizedArea != 0) { + // if the image is too big. start using tiles + qCDebug(OkularCoreDebug).nospace() << "Start using tiles on page " << r->pageNumber() << " (" << r->width() << "x" << r->height() << " px);"; + + // fill the tiles manager with the last rendered pixmap + const QPixmap *pixmap = r->page()->_o_nearestPixmap(r->observer(), r->width(), r->height()); + if (pixmap) { + tilesManager = new TilesManager(r->pageNumber(), pixmap->width(), pixmap->height(), r->page()->rotation()); + tilesManager->setPixmap(pixmap, NormalizedRect(0, 0, 1, 1), true /*isPartialPixmap*/); + tilesManager->setSize(r->width(), r->height()); + } else { + // create new tiles manager + tilesManager = new TilesManager(r->pageNumber(), r->width(), r->height(), r->page()->rotation()); + } + tilesManager->setRequest(r->normalizedRect(), r->width(), r->height()); + r->page()->deletePixmap(r->observer()); + r->page()->d->setTilesManager(r->observer(), tilesManager); + r->setTile(true); + + // Change normalizedRect to the smallest rect that contains all + // visible tiles. + if (!r->normalizedRect().isNull()) { + NormalizedRect tilesRect; + const QList tiles = tilesManager->tilesAt(r->normalizedRect(), TilesManager::TerminalTile); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + while (tIt != tEnd) { + Tile tile = *tIt; + if (tilesRect.isNull()) + tilesRect = tile.rect(); + else + tilesRect |= tile.rect(); + + ++tIt; + } + + r->setNormalizedRect(tilesRect); + request = r; + } else { + // Discard request if normalizedRect is null. This happens in + // preload requests issued by PageView if the requested page is + // not visible and the user has just switched from a non-tiled + // zoom level to a tiled one + m_pixmapRequestsStack.pop_back(); + delete r; + } + } + // If the requested area is below 3*screenSize pixels, switch off the tile manager + else if (tilesManager && (long)r->width() * (long)r->height() < 3L * screenSize) { + qCDebug(OkularCoreDebug).nospace() << "Stop using tiles on page " << r->pageNumber() << " (" << r->width() << "x" << r->height() << " px);"; + + // page is too small. stop using tiles. + r->page()->deletePixmap(r->observer()); + r->setTile(false); + + request = r; + } else if ((long)requestRect.width() * (long)requestRect.height() > 100L * screenSize && (SettingsCore::memoryLevel() != SettingsCore::EnumMemoryLevel::Greedy)) { + m_pixmapRequestsStack.pop_back(); + if (!m_warnedOutOfMemory) { + qCWarning(OkularCoreDebug).nospace() << "Running out of memory on page " << r->pageNumber() << " (" << r->width() << "x" << r->height() << " px);"; + qCWarning(OkularCoreDebug) << "this message will be reported only once."; + m_warnedOutOfMemory = true; + } + delete r; + } else { + request = r; + } + } + + // if no request found (or already generated), return + if (!request) { + m_pixmapRequestsMutex.unlock(); + return; + } + + // [MEM] preventive memory freeing + qulonglong pixmapBytes = 0; + TilesManager *tm = request->d->tilesManager(); + if (tm) + pixmapBytes = tm->totalMemory(); + else + pixmapBytes = 4 * request->width() * request->height(); + + if (pixmapBytes > (1024 * 1024)) + cleanupPixmapMemory(memoryToFree /* previously calculated value */); + + // submit the request to the generator + if (m_generator->canGeneratePixmap()) { + QRect requestRect = !request->isTile() ? QRect(0, 0, request->width(), request->height()) : request->normalizedRect().geometry(request->width(), request->height()); + qCDebug(OkularCoreDebug).nospace() << "sending request observer=" << request->observer() << " " << requestRect.width() << "x" << requestRect.height() << "@" << request->pageNumber() << " async == " << request->asynchronous() + << " isTile == " << request->isTile(); + m_pixmapRequestsStack.removeAll(request); + + if (tm) + tm->setRequest(request->normalizedRect(), request->width(), request->height()); + + if ((int)m_rotation % 2) + request->d->swap(); + + if (m_rotation != Rotation0 && !request->normalizedRect().isNull()) + request->setNormalizedRect(TilesManager::fromRotatedRect(request->normalizedRect(), m_rotation)); + + // If set elsewhere we already know we want it to be partial + if (!request->partialUpdatesWanted()) { + request->setPartialUpdatesWanted(request->asynchronous() && !request->page()->hasPixmap(request->observer())); + } + + // we always have to unlock _before_ the generatePixmap() because + // a sync generation would end with requestDone() -> deadlock, and + // we can not really know if the generator can do async requests + m_executingPixmapRequests.push_back(request); + m_pixmapRequestsMutex.unlock(); + m_generator->generatePixmap(request); + } else { + m_pixmapRequestsMutex.unlock(); + // pino (7/4/2006): set the polling interval from 10 to 30 + QTimer::singleShot(30, m_parent, [this] { sendGeneratorPixmapRequest(); }); + } +} + +void DocumentPrivate::rotationFinished(int page, Okular::Page *okularPage) +{ + Okular::Page *wantedPage = m_pagesVector.value(page, nullptr); + if (!wantedPage || wantedPage != okularPage) + return; + + foreach (DocumentObserver *o, m_observers) + o->notifyPageChanged(page, DocumentObserver::Pixmap | DocumentObserver::Annotations); +} + +void DocumentPrivate::slotFontReadingProgress(int page) +{ + emit m_parent->fontReadingProgress(page); + + if (page >= (int)m_parent->pages() - 1) { + emit m_parent->fontReadingEnded(); + m_fontThread = nullptr; + m_fontsCached = true; + } +} + +void DocumentPrivate::fontReadingGotFont(const Okular::FontInfo &font) +{ + // Try to avoid duplicate fonts + if (m_fontsCache.indexOf(font) == -1) { + m_fontsCache.append(font); + + emit m_parent->gotFont(font); + } +} + +void DocumentPrivate::slotGeneratorConfigChanged() +{ + if (!m_generator) + return; + + // reparse generator config and if something changed clear Pages + bool configchanged = false; + QHash::iterator it = m_loadedGenerators.begin(), itEnd = m_loadedGenerators.end(); + for (; it != itEnd; ++it) { + Okular::ConfigInterface *iface = generatorConfig(it.value()); + if (iface) { + bool it_changed = iface->reparseConfig(); + if (it_changed && (m_generator == it.value().generator)) + configchanged = true; + } + } + if (configchanged) { + // invalidate pixmaps + QVector::const_iterator it = m_pagesVector.constBegin(), end = m_pagesVector.constEnd(); + for (; it != end; ++it) { + (*it)->deletePixmaps(); + } + + // [MEM] remove allocation descriptors + qDeleteAll(m_allocatedPixmaps); + m_allocatedPixmaps.clear(); + m_allocatedPixmapsTotalMemory = 0; + + // send reload signals to observers + foreachObserverD(notifyContentsCleared(DocumentObserver::Pixmap)); + } + + // free memory if in 'low' profile + if (SettingsCore::memoryLevel() == SettingsCore::EnumMemoryLevel::Low && !m_allocatedPixmaps.isEmpty() && !m_pagesVector.isEmpty()) + cleanupPixmapMemory(); +} + +void DocumentPrivate::refreshPixmaps(int pageNumber) +{ + Page *page = m_pagesVector.value(pageNumber, nullptr); + if (!page) + return; + + QMap::ConstIterator it = page->d->m_pixmaps.constBegin(), itEnd = page->d->m_pixmaps.constEnd(); + QVector pixmapsToRequest; + for (; it != itEnd; ++it) { + const QSize size = (*it).m_pixmap->size(); + PixmapRequest *p = new PixmapRequest(it.key(), pageNumber, size.width() / qApp->devicePixelRatio(), size.height() / qApp->devicePixelRatio(), 1, PixmapRequest::Asynchronous); + p->d->mForce = true; + pixmapsToRequest << p; + } + + // Need to do this ↑↓ in two steps since requestPixmaps can end up calling cancelRenderingBecauseOf + // which changes m_pixmaps and thus breaks the loop above + for (PixmapRequest *pr : qAsConst(pixmapsToRequest)) { + QLinkedList requestedPixmaps; + requestedPixmaps.push_back(pr); + m_parent->requestPixmaps(requestedPixmaps, Okular::Document::NoOption); + } + + for (DocumentObserver *observer : qAsConst(m_observers)) { + QLinkedList requestedPixmaps; + + TilesManager *tilesManager = page->d->tilesManager(observer); + if (tilesManager) { + tilesManager->markDirty(); + + PixmapRequest *p = new PixmapRequest(observer, pageNumber, tilesManager->width() / qApp->devicePixelRatio(), tilesManager->height() / qApp->devicePixelRatio(), 1, PixmapRequest::Asynchronous); + + // Get the visible page rect + NormalizedRect visibleRect; + QVector::const_iterator vIt = m_pageRects.constBegin(), vEnd = m_pageRects.constEnd(); + for (; vIt != vEnd; ++vIt) { + if ((*vIt)->pageNumber == pageNumber) { + visibleRect = (*vIt)->rect; + break; + } + } + + if (!visibleRect.isNull()) { + p->setNormalizedRect(visibleRect); + p->setTile(true); + p->d->mForce = true; + requestedPixmaps.push_back(p); + } else { + delete p; + } + } + + m_parent->requestPixmaps(requestedPixmaps, Okular::Document::NoOption); + } +} + +void DocumentPrivate::_o_configChanged() +{ + // free text pages if needed + calculateMaxTextPages(); + while (m_allocatedTextPagesFifo.count() > m_maxAllocatedTextPages) { + int pageToKick = m_allocatedTextPagesFifo.takeFirst(); + m_pagesVector.at(pageToKick)->setTextPage(nullptr); // deletes the textpage + } +} + +void DocumentPrivate::doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct) +{ + DoContinueDirectionMatchSearchStruct *searchStruct = static_cast(doContinueDirectionMatchSearchStruct); + RunningSearch *search = m_searches.value(searchStruct->searchID); + + if ((m_searchCancelled && !searchStruct->match) || !search) { + // if the user cancelled but he just got a match, give him the match! + QApplication::restoreOverrideCursor(); + + if (search) + search->isCurrentlySearching = false; + + emit m_parent->searchFinished(searchStruct->searchID, Document::SearchCancelled); + delete searchStruct->pagesToNotify; + delete searchStruct; + return; + } + + const bool forward = search->cachedType == Document::NextMatch; + bool doContinue = false; + // if no match found, loop through the whole doc, starting from currentPage + if (!searchStruct->match) { + const int pageCount = m_pagesVector.count(); + if (search->pagesDone < pageCount) { + doContinue = true; + if (searchStruct->currentPage >= pageCount) { + searchStruct->currentPage = 0; + emit m_parent->notice(i18n("Continuing search from beginning"), 3000); + } else if (searchStruct->currentPage < 0) { + searchStruct->currentPage = pageCount - 1; + emit m_parent->notice(i18n("Continuing search from bottom"), 3000); + } + } + } + + if (doContinue) { + // get page + Page *page = m_pagesVector[searchStruct->currentPage]; + // request search page if needed + if (!page->hasTextPage()) + m_parent->requestTextPage(page->number()); + + // if found a match on the current page, end the loop + searchStruct->match = page->findText(searchStruct->searchID, search->cachedString, forward ? FromTop : FromBottom, search->cachedCaseSensitivity); + if (!searchStruct->match) { + if (forward) + searchStruct->currentPage++; + else + searchStruct->currentPage--; + search->pagesDone++; + } else { + search->pagesDone = 1; + } + + // Both of the previous if branches need to call doContinueDirectionMatchSearch + QTimer::singleShot(0, m_parent, [this, searchStruct] { doContinueDirectionMatchSearch(searchStruct); }); + } else { + doProcessSearchMatch(searchStruct->match, search, searchStruct->pagesToNotify, searchStruct->currentPage, searchStruct->searchID, search->cachedViewportMove, search->cachedColor); + delete searchStruct; + } +} + +void DocumentPrivate::doProcessSearchMatch(RegularAreaRect *match, RunningSearch *search, QSet *pagesToNotify, int currentPage, int searchID, bool moveViewport, const QColor &color) +{ + // reset cursor to previous shape + QApplication::restoreOverrideCursor(); + + bool foundAMatch = false; + + search->isCurrentlySearching = false; + + // if a match has been found.. + if (match) { + // update the RunningSearch structure adding this match.. + foundAMatch = true; + search->continueOnPage = currentPage; + search->continueOnMatch = *match; + search->highlightedPages.insert(currentPage); + // ..add highlight to the page.. + m_pagesVector[currentPage]->d->setHighlight(searchID, match, color); + + // ..queue page for notifying changes.. + pagesToNotify->insert(currentPage); + + // Create a normalized rectangle around the search match that includes a 5% buffer on all sides. + const Okular::NormalizedRect matchRectWithBuffer = Okular::NormalizedRect(match->first().left - 0.05, match->first().top - 0.05, match->first().right + 0.05, match->first().bottom + 0.05); + + const bool matchRectFullyVisible = isNormalizedRectangleFullyVisible(matchRectWithBuffer, currentPage); + + // ..move the viewport to show the first of the searched word sequence centered + if (moveViewport && !matchRectFullyVisible) { + DocumentViewport searchViewport(currentPage); + searchViewport.rePos.enabled = true; + searchViewport.rePos.normalizedX = (match->first().left + match->first().right) / 2.0; + searchViewport.rePos.normalizedY = (match->first().top + match->first().bottom) / 2.0; + m_parent->setViewport(searchViewport, nullptr, true); + } + delete match; + } + + // notify observers about highlights changes + foreach (int pageNumber, *pagesToNotify) + foreach (DocumentObserver *observer, m_observers) + observer->notifyPageChanged(pageNumber, DocumentObserver::Highlights); + + if (foundAMatch) + emit m_parent->searchFinished(searchID, Document::MatchFound); + else + emit m_parent->searchFinished(searchID, Document::NoMatchFound); + + delete pagesToNotify; +} + +void DocumentPrivate::doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID) +{ + QMap> *pageMatches = static_cast> *>(pageMatchesMap); + QSet *pagesToNotify = static_cast *>(pagesToNotifySet); + RunningSearch *search = m_searches.value(searchID); + + if (m_searchCancelled || !search) { + typedef QVector MatchesVector; + + QApplication::restoreOverrideCursor(); + + if (search) + search->isCurrentlySearching = false; + + emit m_parent->searchFinished(searchID, Document::SearchCancelled); + foreach (const MatchesVector &mv, *pageMatches) + qDeleteAll(mv); + delete pageMatches; + delete pagesToNotify; + return; + } + + if (currentPage < m_pagesVector.count()) { + // get page (from the first to the last) + Page *page = m_pagesVector.at(currentPage); + int pageNumber = page->number(); // redundant? is it == currentPage ? + + // request search page if needed + if (!page->hasTextPage()) + m_parent->requestTextPage(pageNumber); + + // loop on a page adding highlights for all found items + RegularAreaRect *lastMatch = nullptr; + while (true) { + if (lastMatch) + lastMatch = page->findText(searchID, search->cachedString, NextResult, search->cachedCaseSensitivity, lastMatch); + else + lastMatch = page->findText(searchID, search->cachedString, FromTop, search->cachedCaseSensitivity); + + if (!lastMatch) + break; + + // add highlight rect to the matches map + (*pageMatches)[page].append(lastMatch); + } + delete lastMatch; + + QTimer::singleShot(0, m_parent, [this, pagesToNotifySet, pageMatches, currentPage, searchID] { doContinueAllDocumentSearch(pagesToNotifySet, pageMatches, currentPage + 1, searchID); }); + } else { + // reset cursor to previous shape + QApplication::restoreOverrideCursor(); + + search->isCurrentlySearching = false; + bool foundAMatch = pageMatches->count() != 0; + QMap>::const_iterator it, itEnd; + it = pageMatches->constBegin(); + itEnd = pageMatches->constEnd(); + for (; it != itEnd; ++it) { + foreach (RegularAreaRect *match, it.value()) { + it.key()->d->setHighlight(searchID, match, search->cachedColor); + delete match; + } + search->highlightedPages.insert(it.key()->number()); + pagesToNotify->insert(it.key()->number()); + } + + foreach (DocumentObserver *observer, m_observers) + observer->notifySetup(m_pagesVector, 0); + + // notify observers about highlights changes + foreach (int pageNumber, *pagesToNotify) + foreach (DocumentObserver *observer, m_observers) + observer->notifyPageChanged(pageNumber, DocumentObserver::Highlights); + + if (foundAMatch) + emit m_parent->searchFinished(searchID, Document::MatchFound); + else + emit m_parent->searchFinished(searchID, Document::NoMatchFound); + + delete pageMatches; + delete pagesToNotify; + } +} + +void DocumentPrivate::doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QStringList &words) +{ + typedef QPair MatchColor; + QMap> *pageMatches = static_cast> *>(pageMatchesMap); + QSet *pagesToNotify = static_cast *>(pagesToNotifySet); + RunningSearch *search = m_searches.value(searchID); + + if (m_searchCancelled || !search) { + typedef QVector MatchesVector; + + QApplication::restoreOverrideCursor(); + + if (search) + search->isCurrentlySearching = false; + + emit m_parent->searchFinished(searchID, Document::SearchCancelled); + + foreach (const MatchesVector &mv, *pageMatches) { + foreach (const MatchColor &mc, mv) + delete mc.first; + } + delete pageMatches; + delete pagesToNotify; + return; + } + + const int wordCount = words.count(); + const int hueStep = (wordCount > 1) ? (60 / (wordCount - 1)) : 60; + int baseHue, baseSat, baseVal; + search->cachedColor.getHsv(&baseHue, &baseSat, &baseVal); + + if (currentPage < m_pagesVector.count()) { + // get page (from the first to the last) + Page *page = m_pagesVector.at(currentPage); + int pageNumber = page->number(); // redundant? is it == currentPage ? + + // request search page if needed + if (!page->hasTextPage()) + m_parent->requestTextPage(pageNumber); + + // loop on a page adding highlights for all found items + bool allMatched = wordCount > 0, anyMatched = false; + for (int w = 0; w < wordCount; w++) { + const QString &word = words[w]; + int newHue = baseHue - w * hueStep; + if (newHue < 0) + newHue += 360; + QColor wordColor = QColor::fromHsv(newHue, baseSat, baseVal); + RegularAreaRect *lastMatch = nullptr; + // add all highlights for current word + bool wordMatched = false; + while (true) { + if (lastMatch) + lastMatch = page->findText(searchID, word, NextResult, search->cachedCaseSensitivity, lastMatch); + else + lastMatch = page->findText(searchID, word, FromTop, search->cachedCaseSensitivity); + + if (!lastMatch) + break; + + // add highligh rect to the matches map + (*pageMatches)[page].append(MatchColor(lastMatch, wordColor)); + wordMatched = true; + } + allMatched = allMatched && wordMatched; + anyMatched = anyMatched || wordMatched; + } + + // if not all words are present in page, remove partial highlights + const bool matchAll = search->cachedType == Document::GoogleAll; + if (!allMatched && matchAll) { + QVector &matches = (*pageMatches)[page]; + foreach (const MatchColor &mc, matches) + delete mc.first; + pageMatches->remove(page); + } + + QTimer::singleShot(0, m_parent, [this, pagesToNotifySet, pageMatches, currentPage, searchID, words] { doContinueGooglesDocumentSearch(pagesToNotifySet, pageMatches, currentPage + 1, searchID, words); }); + } else { + // reset cursor to previous shape + QApplication::restoreOverrideCursor(); + + search->isCurrentlySearching = false; + bool foundAMatch = pageMatches->count() != 0; + QMap>::const_iterator it, itEnd; + it = pageMatches->constBegin(); + itEnd = pageMatches->constEnd(); + for (; it != itEnd; ++it) { + foreach (const MatchColor &mc, it.value()) { + it.key()->d->setHighlight(searchID, mc.first, mc.second); + delete mc.first; + } + search->highlightedPages.insert(it.key()->number()); + pagesToNotify->insert(it.key()->number()); + } + + // send page lists to update observers (since some filter on bookmarks) + foreach (DocumentObserver *observer, m_observers) + observer->notifySetup(m_pagesVector, 0); + + // notify observers about highlights changes + foreach (int pageNumber, *pagesToNotify) + foreach (DocumentObserver *observer, m_observers) + observer->notifyPageChanged(pageNumber, DocumentObserver::Highlights); + + if (foundAMatch) + emit m_parent->searchFinished(searchID, Document::MatchFound); + else + emit m_parent->searchFinished(searchID, Document::NoMatchFound); + + delete pageMatches; + delete pagesToNotify; + } +} + +QVariant DocumentPrivate::documentMetaData(const Generator::DocumentMetaDataKey key, const QVariant &option) const +{ + switch (key) { + case Generator::PaperColorMetaData: { + bool giveDefault = option.toBool(); + QColor color; + if ((SettingsCore::renderMode() == SettingsCore::EnumRenderMode::Paper) && SettingsCore::changeColors()) { + color = SettingsCore::paperColor(); + } else if (giveDefault) { + color = Qt::white; + } + return color; + } break; + + case Generator::TextAntialiasMetaData: + switch (SettingsCore::textAntialias()) { + case SettingsCore::EnumTextAntialias::Enabled: + return true; + break; +#if 0 + case Settings::EnumTextAntialias::UseKDESettings: + // TODO: read the KDE configuration + return true; + break; +#endif + case SettingsCore::EnumTextAntialias::Disabled: + return false; + break; + } + break; + + case Generator::GraphicsAntialiasMetaData: + switch (SettingsCore::graphicsAntialias()) { + case SettingsCore::EnumGraphicsAntialias::Enabled: + return true; + break; + case SettingsCore::EnumGraphicsAntialias::Disabled: + return false; + break; + } + break; + + case Generator::TextHintingMetaData: + switch (SettingsCore::textHinting()) { + case SettingsCore::EnumTextHinting::Enabled: + return true; + break; + case SettingsCore::EnumTextHinting::Disabled: + return false; + break; + } + break; + } + return QVariant(); +} + +bool DocumentPrivate::isNormalizedRectangleFullyVisible(const Okular::NormalizedRect &rectOfInterest, int rectPage) +{ + bool rectFullyVisible = false; + const QVector &visibleRects = m_parent->visiblePageRects(); + QVector::const_iterator vEnd = visibleRects.end(); + QVector::const_iterator vIt = visibleRects.begin(); + + for (; (vIt != vEnd) && !rectFullyVisible; ++vIt) { + if ((*vIt)->pageNumber == rectPage && (*vIt)->rect.contains(rectOfInterest.left, rectOfInterest.top) && (*vIt)->rect.contains(rectOfInterest.right, rectOfInterest.bottom)) { + rectFullyVisible = true; + } + } + return rectFullyVisible; +} + +struct pdfsyncpoint { + QString file; + qlonglong x; + qlonglong y; + int row; + int column; + int page; +}; + +void DocumentPrivate::loadSyncFile(const QString &filePath) +{ + QFile f(filePath + QLatin1String("sync")); + if (!f.open(QIODevice::ReadOnly)) + return; + + QTextStream ts(&f); + // first row: core name of the pdf output + const QString coreName = ts.readLine(); + // second row: version string, in the form 'Version %u' + const QString versionstr = ts.readLine(); + // anchor the pattern with \A and \z to match the entire subject string + // TODO: with Qt 5.12 QRegularExpression::anchoredPattern() can be used instead + QRegularExpression versionre(QStringLiteral("\\AVersion \\d+\\z"), QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch match = versionre.match(versionstr); + if (!match.hasMatch()) { + return; + } + + QHash points; + QStack fileStack; + int currentpage = -1; + const QLatin1String texStr(".tex"); + const QChar spaceChar = QChar::fromLatin1(' '); + + fileStack.push(coreName + texStr); + + const QSizeF dpi = m_generator->dpi(); + + QString line; + while (!ts.atEnd()) { + line = ts.readLine(); + const QStringList tokens = line.split(spaceChar, QString::SkipEmptyParts); + const int tokenSize = tokens.count(); + if (tokenSize < 1) + continue; + if (tokens.first() == QLatin1String("l") && tokenSize >= 3) { + int id = tokens.at(1).toInt(); + QHash::const_iterator it = points.constFind(id); + if (it == points.constEnd()) { + pdfsyncpoint pt; + pt.x = 0; + pt.y = 0; + pt.row = tokens.at(2).toInt(); + pt.column = 0; // TODO + pt.page = -1; + pt.file = fileStack.top(); + points[id] = pt; + } + } else if (tokens.first() == QLatin1String("s") && tokenSize >= 2) { + currentpage = tokens.at(1).toInt() - 1; + } else if (tokens.first() == QLatin1String("p*") && tokenSize >= 4) { + // TODO + qCDebug(OkularCoreDebug) << "PdfSync: 'p*' line ignored"; + } else if (tokens.first() == QLatin1String("p") && tokenSize >= 4) { + int id = tokens.at(1).toInt(); + QHash::iterator it = points.find(id); + if (it != points.end()) { + it->x = tokens.at(2).toInt(); + it->y = tokens.at(3).toInt(); + it->page = currentpage; + } + } else if (line.startsWith(QLatin1Char('(')) && tokenSize == 1) { + QString newfile = line; + // chop the leading '(' + newfile.remove(0, 1); + if (!newfile.endsWith(texStr)) { + newfile += texStr; + } + fileStack.push(newfile); + } else if (line == QLatin1String(")")) { + if (!fileStack.isEmpty()) { + fileStack.pop(); + } else + qCDebug(OkularCoreDebug) << "PdfSync: going one level down too much"; + } else + qCDebug(OkularCoreDebug).nospace() << "PdfSync: unknown line format: '" << line << "'"; + } + + QVector> refRects(m_pagesVector.size()); + for (const pdfsyncpoint &pt : qAsConst(points)) { + // drop pdfsync points not completely valid + if (pt.page < 0 || pt.page >= m_pagesVector.size()) + continue; + + // magic numbers for TeX's RSU's (Ridiculously Small Units) conversion to pixels + Okular::NormalizedPoint p((pt.x * dpi.width()) / (72.27 * 65536.0 * m_pagesVector[pt.page]->width()), (pt.y * dpi.height()) / (72.27 * 65536.0 * m_pagesVector[pt.page]->height())); + QString file = pt.file; + Okular::SourceReference *sourceRef = new Okular::SourceReference(file, pt.row, pt.column); + refRects[pt.page].append(new Okular::SourceRefObjectRect(p, sourceRef)); + } + for (int i = 0; i < refRects.size(); ++i) + if (!refRects.at(i).isEmpty()) + m_pagesVector[i]->setSourceReferences(refRects.at(i)); +} + +void DocumentPrivate::clearAndWaitForRequests() +{ + m_pixmapRequestsMutex.lock(); + QLinkedList::const_iterator sIt = m_pixmapRequestsStack.constBegin(); + QLinkedList::const_iterator sEnd = m_pixmapRequestsStack.constEnd(); + for (; sIt != sEnd; ++sIt) + delete *sIt; + m_pixmapRequestsStack.clear(); + m_pixmapRequestsMutex.unlock(); + + QEventLoop loop; + bool startEventLoop = false; + do { + m_pixmapRequestsMutex.lock(); + startEventLoop = !m_executingPixmapRequests.isEmpty(); + + if (m_generator->hasFeature(Generator::SupportsCancelling)) { + for (PixmapRequest *executingRequest : qAsConst(m_executingPixmapRequests)) + executingRequest->d->mShouldAbortRender = 1; + + if (m_generator->d_ptr->mTextPageGenerationThread) + m_generator->d_ptr->mTextPageGenerationThread->abortExtraction(); + } + + m_pixmapRequestsMutex.unlock(); + if (startEventLoop) { + m_closingLoop = &loop; + loop.exec(); + m_closingLoop = nullptr; + } + } while (startEventLoop); +} + +int DocumentPrivate::findFieldPageNumber(Okular::FormField *field) +{ + // Lookup the page of the FormField + int foundPage = -1; + for (uint pageIdx = 0, nPages = m_parent->pages(); pageIdx < nPages; pageIdx++) { + const Page *p = m_parent->page(pageIdx); + if (p && p->formFields().contains(field)) { + foundPage = static_cast(pageIdx); + break; + } + } + return foundPage; +} + +void DocumentPrivate::executeScriptEvent(const std::shared_ptr &event, const Okular::ScriptAction *linkscript) +{ + if (!m_scripter) { + m_scripter = new Scripter(this); + } + m_scripter->setEvent(event.get()); + m_scripter->execute(linkscript->scriptType(), linkscript->script()); + + // Clear out the event after execution + m_scripter->setEvent(nullptr); +} + +Document::Document(QWidget *widget) + : QObject(nullptr) + , d(new DocumentPrivate(this)) +{ + d->m_widget = widget; + d->m_bookmarkManager = new BookmarkManager(d); + d->m_viewportIterator = d->m_viewportHistory.insert(d->m_viewportHistory.end(), DocumentViewport()); + d->m_undoStack = new QUndoStack(this); + + connect(SettingsCore::self(), &SettingsCore::configChanged, this, [this] { d->_o_configChanged(); }); + connect(d->m_undoStack, &QUndoStack::canUndoChanged, this, &Document::canUndoChanged); + connect(d->m_undoStack, &QUndoStack::canRedoChanged, this, &Document::canRedoChanged); + connect(d->m_undoStack, &QUndoStack::cleanChanged, this, &Document::undoHistoryCleanChanged); + + qRegisterMetaType(); +} + +Document::~Document() +{ + // delete generator, pages, and related stuff + closeDocument(); + + QSet::const_iterator viewIt = d->m_views.constBegin(), viewEnd = d->m_views.constEnd(); + for (; viewIt != viewEnd; ++viewIt) { + View *v = *viewIt; + v->d_func()->document = nullptr; + } + + // delete the bookmark manager + delete d->m_bookmarkManager; + + // delete the loaded generators + QHash::const_iterator it = d->m_loadedGenerators.constBegin(), itEnd = d->m_loadedGenerators.constEnd(); + for (; it != itEnd; ++it) + d->unloadGenerator(it.value()); + d->m_loadedGenerators.clear(); + + // delete the private structure + delete d; +} + +QString DocumentPrivate::docDataFileName(const QUrl &url, qint64 document_size) +{ + QString fn = url.fileName(); + fn = QString::number(document_size) + QLatin1Char('.') + fn + QStringLiteral(".xml"); + 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(oldfile, newokularfile)) + return QString(); + } + } + return newokularfile; +} + +QVector DocumentPrivate::availableGenerators() +{ + static QVector result; + if (result.isEmpty()) { + result = KPluginLoader::findPlugins(QStringLiteral("okular/generators")); + } + return result; +} + +KPluginMetaData DocumentPrivate::generatorForMimeType(const QMimeType &type, QWidget *widget, const QVector &triedOffers) +{ + // First try to find an exact match, and then look for more general ones (e. g. the plain text one) + // Ideally we would rank these by "closeness", but that might be overdoing it + + const QVector available = availableGenerators(); + QVector offers; + QVector exactMatches; + + QMimeDatabase mimeDatabase; + + for (const KPluginMetaData &md : available) { + if (triedOffers.contains(md)) + continue; + + const QStringList mimetypes = md.mimeTypes(); + for (const QString &supported : mimetypes) { + QMimeType mimeType = mimeDatabase.mimeTypeForName(supported); + if (mimeType == type && !exactMatches.contains(md)) { + exactMatches << md; + } + + if (type.inherits(supported) && !offers.contains(md)) { + offers << md; + } + } + } + + if (!exactMatches.isEmpty()) { + offers = exactMatches; + } + + if (offers.isEmpty()) { + return KPluginMetaData(); + } + int hRank = 0; + // best ranked offer search + int offercount = offers.size(); + if (offercount > 1) { + // sort the offers: the offers with an higher priority come before + auto cmp = [](const KPluginMetaData &s1, const KPluginMetaData &s2) { + const QString property = QStringLiteral("X-KDE-Priority"); + return s1.rawData()[property].toInt() > s2.rawData()[property].toInt(); + }; + std::stable_sort(offers.begin(), offers.end(), cmp); + + if (SettingsCore::chooseGenerators()) { + QStringList list; + for (int i = 0; i < offercount; ++i) { + list << offers.at(i).pluginId(); + } + ChooseEngineDialog choose(list, type, widget); + + if (choose.exec() == QDialog::Rejected) + return KPluginMetaData(); + + hRank = choose.selectedGenerator(); + } + } + Q_ASSERT(hRank < offers.size()); + return offers.at(hRank); +} + +Document::OpenResult Document::openDocument(const QString &docFile, const QUrl &url, const QMimeType &_mime, const QString &password) +{ + QMimeDatabase db; + QMimeType mime = _mime; + QByteArray filedata; + int fd = -1; + if (url.scheme() == QLatin1String("fd")) { + bool ok; + fd = url.path().midRef(1).toInt(&ok); + if (!ok) { + return OpenError; + } + } else if (url.fileName() == QLatin1String("-")) { + fd = 0; + } + bool triedMimeFromFileContent = false; + if (fd < 0) { + if (!mime.isValid()) + return OpenError; + + d->m_url = url; + d->m_docFileName = docFile; + + if (!d->updateMetadataXmlNameAndDocSize()) + return OpenError; + } else { + QFile qstdin; + const bool ret = qstdin.open(fd, QIODevice::ReadOnly, QFileDevice::AutoCloseHandle); + if (!ret) { + qWarning() << "failed to read" << url << filedata; + return OpenError; + } + + filedata = qstdin.readAll(); + mime = db.mimeTypeForData(filedata); + if (!mime.isValid() || mime.isDefault()) + return OpenError; + d->m_docSize = filedata.size(); + triedMimeFromFileContent = true; + } + + const bool fromFileDescriptor = fd >= 0; + + // 0. load Generator + // request only valid non-disabled plugins suitable for the mimetype + KPluginMetaData offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget); + if (!offer.isValid() && !triedMimeFromFileContent) { + QMimeType newmime = db.mimeTypeForFile(docFile, QMimeDatabase::MatchContent); + triedMimeFromFileContent = true; + if (newmime != mime) { + mime = newmime; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget); + } + if (!offer.isValid()) { + // There's still no offers, do a final mime search based on the filename + // We need this because sometimes (e.g. when downloading from a webserver) the mimetype we + // use is the one fed by the server, that may be wrong + newmime = db.mimeTypeForUrl(url); + + if (!newmime.isDefault() && newmime != mime) { + mime = newmime; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget); + } + } + } + if (!offer.isValid()) { + d->m_openError = i18n("Can not find a plugin which is able to handle the document being passed."); + emit error(d->m_openError, -1); + qCWarning(OkularCoreDebug).nospace() << "No plugin for mimetype '" << mime.name() << "'."; + return OpenError; + } + + // 1. load Document + OpenResult openResult = d->openDocumentInternal(offer, fromFileDescriptor, docFile, filedata, password); + if (openResult == OpenError) { + QVector triedOffers; + triedOffers << offer; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget, triedOffers); + + while (offer.isValid()) { + openResult = d->openDocumentInternal(offer, fromFileDescriptor, docFile, filedata, password); + + if (openResult == OpenError) { + triedOffers << offer; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget, triedOffers); + } else + break; + } + + if (openResult == OpenError && !triedMimeFromFileContent) { + QMimeType newmime = db.mimeTypeForFile(docFile, QMimeDatabase::MatchContent); + triedMimeFromFileContent = true; + if (newmime != mime) { + mime = newmime; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget, triedOffers); + while (offer.isValid()) { + openResult = d->openDocumentInternal(offer, fromFileDescriptor, docFile, filedata, password); + + if (openResult == OpenError) { + triedOffers << offer; + offer = DocumentPrivate::generatorForMimeType(mime, d->m_widget, triedOffers); + } else + break; + } + } + } + + if (openResult == OpenSuccess) { + // Clear errors, since we're trying various generators, maybe one of them errored out + // but we finally succeeded + // TODO one can still see the error message animating out but since this is a very rare + // condition we can leave this for future work + emit error(QString(), -1); + } + } + if (openResult != OpenSuccess) { + return openResult; + } + + // no need to check for the existence of a synctex file, no parser will be + // created if none exists + d->m_synctex_scanner = synctex_scanner_new_with_output_file(QFile::encodeName(docFile).constData(), nullptr, 1); + if (!d->m_synctex_scanner && QFile::exists(docFile + QLatin1String("sync"))) { + d->loadSyncFile(docFile); + } + + d->m_generatorName = offer.pluginId(); + d->m_pageController = new PageController(); + connect(d->m_pageController, &PageController::rotationFinished, this, [this](int p, Okular::Page *op) { d->rotationFinished(p, op); }); + + for (Page *p : qAsConst(d->m_pagesVector)) + p->d->m_doc = d; + + d->m_metadataLoadingCompleted = false; + d->m_docdataMigrationNeeded = false; + + // 2. load Additional Data (bookmarks, local annotations and metadata) about the document + if (d->m_archiveData) { + // QTemporaryFile is weird and will return false in exists if fileName wasn't called before + d->m_archiveData->metadataFile.fileName(); + d->loadDocumentInfo(d->m_archiveData->metadataFile, LoadPageInfo); + d->loadDocumentInfo(LoadGeneralInfo); + } else { + if (d->loadDocumentInfo(LoadPageInfo)) + d->m_docdataMigrationNeeded = true; + d->loadDocumentInfo(LoadGeneralInfo); + } + + d->m_metadataLoadingCompleted = true; + d->m_bookmarkManager->setUrl(d->m_url); + + // 3. setup observers internal lists and data + foreachObserver(notifySetup(d->m_pagesVector, DocumentObserver::DocumentChanged | DocumentObserver::UrlChanged)); + + // 4. set initial page (restoring the page saved in xml if loaded) + DocumentViewport loadedViewport = (*d->m_viewportIterator); + if (loadedViewport.isValid()) { + (*d->m_viewportIterator) = DocumentViewport(); + if (loadedViewport.pageNumber >= (int)d->m_pagesVector.size()) + loadedViewport.pageNumber = d->m_pagesVector.size() - 1; + } else + loadedViewport.pageNumber = 0; + setViewport(loadedViewport); + + // start bookmark saver timer + if (!d->m_saveBookmarksTimer) { + d->m_saveBookmarksTimer = new QTimer(this); + connect(d->m_saveBookmarksTimer, &QTimer::timeout, this, [this] { d->saveDocumentInfo(); }); + } + d->m_saveBookmarksTimer->start(5 * 60 * 1000); + + // start memory check timer + if (!d->m_memCheckTimer) { + d->m_memCheckTimer = new QTimer(this); + connect(d->m_memCheckTimer, &QTimer::timeout, this, [this] { d->slotTimedMemoryCheck(); }); + } + d->m_memCheckTimer->start(kMemCheckTime); + + const DocumentViewport nextViewport = d->nextDocumentViewport(); + if (nextViewport.isValid()) { + setViewport(nextViewport); + d->m_nextDocumentViewport = DocumentViewport(); + d->m_nextDocumentDestination = QString(); + } + + AudioPlayer::instance()->d->m_currentDocument = fromFileDescriptor ? QUrl() : d->m_url; + + const QStringList docScripts = d->m_generator->metaData(QStringLiteral("DocumentScripts"), QStringLiteral("JavaScript")).toStringList(); + if (!docScripts.isEmpty()) { + d->m_scripter = new Scripter(d); + for (const QString &docscript : docScripts) { + d->m_scripter->execute(JavaScript, docscript); + } + } + + return OpenSuccess; +} + +bool DocumentPrivate::updateMetadataXmlNameAndDocSize() +{ + // m_docFileName is always local so we can use QFileInfo on it + QFileInfo fileReadTest(m_docFileName); + if (!fileReadTest.isFile() && !fileReadTest.isReadable()) + return false; + + m_docSize = fileReadTest.size(); + + // determine the related "xml document-info" filename + if (m_url.isLocalFile()) { + const QString filePath = docDataFileName(m_url, m_docSize); + qCDebug(OkularCoreDebug) << "Metadata file is now:" << filePath; + m_xmlFileName = filePath; + } else { + qCDebug(OkularCoreDebug) << "Metadata file: disabled"; + m_xmlFileName = QString(); + } + + return true; +} + +KXMLGUIClient *Document::guiClient() +{ + if (d->m_generator) { + Okular::GuiInterface *iface = qobject_cast(d->m_generator); + if (iface) + return iface->guiClient(); + } + return nullptr; +} + +void Document::closeDocument() +{ + // check if there's anything to close... + if (!d->m_generator) + return; + + emit aboutToClose(); + + delete d->m_pageController; + d->m_pageController = nullptr; + + delete d->m_scripter; + d->m_scripter = nullptr; + + // remove requests left in queue + d->clearAndWaitForRequests(); + + if (d->m_fontThread) { + disconnect(d->m_fontThread, nullptr, this, nullptr); + d->m_fontThread->stopExtraction(); + d->m_fontThread->wait(); + d->m_fontThread = nullptr; + } + + // stop any audio playback + AudioPlayer::instance()->stopPlaybacks(); + + // close the current document and save document info if a document is still opened + if (d->m_generator && d->m_pagesVector.size() > 0) { + d->saveDocumentInfo(); + d->m_generator->closeDocument(); + } + + if (d->m_synctex_scanner) { + synctex_scanner_free(d->m_synctex_scanner); + d->m_synctex_scanner = nullptr; + } + + // stop timers + if (d->m_memCheckTimer) + d->m_memCheckTimer->stop(); + if (d->m_saveBookmarksTimer) + d->m_saveBookmarksTimer->stop(); + + if (d->m_generator) { + // disconnect the generator from this document ... + d->m_generator->d_func()->m_document = nullptr; + // .. and this document from the generator signals + disconnect(d->m_generator, nullptr, this, nullptr); + + QHash::const_iterator genIt = d->m_loadedGenerators.constFind(d->m_generatorName); + Q_ASSERT(genIt != d->m_loadedGenerators.constEnd()); + } + d->m_generator = nullptr; + d->m_generatorName = QString(); + d->m_url = QUrl(); + d->m_walletGenerator = nullptr; + d->m_docFileName = QString(); + d->m_xmlFileName = QString(); + delete d->m_tempFile; + d->m_tempFile = nullptr; + delete d->m_archiveData; + d->m_archiveData = nullptr; + d->m_docSize = -1; + d->m_exportCached = false; + d->m_exportFormats.clear(); + d->m_exportToText = ExportFormat(); + d->m_fontsCached = false; + d->m_fontsCache.clear(); + d->m_rotation = Rotation0; + + // send an empty list to observers (to free their data) + foreachObserver(notifySetup(QVector(), DocumentObserver::DocumentChanged | DocumentObserver::UrlChanged)); + + // delete pages and clear 'd->m_pagesVector' container + QVector::const_iterator pIt = d->m_pagesVector.constBegin(); + QVector::const_iterator pEnd = d->m_pagesVector.constEnd(); + for (; pIt != pEnd; ++pIt) + delete *pIt; + d->m_pagesVector.clear(); + + // clear 'memory allocation' descriptors + qDeleteAll(d->m_allocatedPixmaps); + d->m_allocatedPixmaps.clear(); + + // clear 'running searches' descriptors + QMap::const_iterator rIt = d->m_searches.constBegin(); + QMap::const_iterator rEnd = d->m_searches.constEnd(); + for (; rIt != rEnd; ++rIt) + delete *rIt; + d->m_searches.clear(); + + // clear the visible areas and notify the observers + QVector::const_iterator vIt = d->m_pageRects.constBegin(); + QVector::const_iterator vEnd = d->m_pageRects.constEnd(); + for (; vIt != vEnd; ++vIt) + delete *vIt; + d->m_pageRects.clear(); + foreachObserver(notifyVisibleRectsChanged()); + + // reset internal variables + + d->m_viewportHistory.clear(); + d->m_viewportHistory.append(DocumentViewport()); + d->m_viewportIterator = d->m_viewportHistory.begin(); + d->m_allocatedPixmapsTotalMemory = 0; + d->m_allocatedTextPagesFifo.clear(); + d->m_pageSize = PageSize(); + d->m_pageSizes.clear(); + + d->m_documentInfo = DocumentInfo(); + d->m_documentInfoAskedKeys.clear(); + + AudioPlayer::instance()->d->m_currentDocument = QUrl(); + + d->m_undoStack->clear(); + d->m_docdataMigrationNeeded = false; + +#if HAVE_MALLOC_TRIM + // trim unused memory, glibc should do this but it seems it does not + // this can greatly decrease the [perceived] memory consumption of okular + // see: https://sourceware.org/bugzilla/show_bug.cgi?id=14827 + malloc_trim(0); +#endif +} + +void Document::addObserver(DocumentObserver *pObserver) +{ + Q_ASSERT(!d->m_observers.contains(pObserver)); + d->m_observers << pObserver; + + // if the observer is added while a document is already opened, tell it + if (!d->m_pagesVector.isEmpty()) { + pObserver->notifySetup(d->m_pagesVector, DocumentObserver::DocumentChanged | DocumentObserver::UrlChanged); + pObserver->notifyViewportChanged(false /*disables smoothMove*/); + } +} + +void Document::removeObserver(DocumentObserver *pObserver) +{ + // remove observer from the set. it won't receive notifications anymore + if (d->m_observers.contains(pObserver)) { + // free observer's pixmap data + QVector::const_iterator it = d->m_pagesVector.constBegin(), end = d->m_pagesVector.constEnd(); + for (; it != end; ++it) + (*it)->deletePixmap(pObserver); + + // [MEM] free observer's allocation descriptors + QLinkedList::iterator aIt = d->m_allocatedPixmaps.begin(); + QLinkedList::iterator aEnd = d->m_allocatedPixmaps.end(); + while (aIt != aEnd) { + AllocatedPixmap *p = *aIt; + if (p->observer == pObserver) { + aIt = d->m_allocatedPixmaps.erase(aIt); + delete p; + } else + ++aIt; + } + + for (PixmapRequest *executingRequest : qAsConst(d->m_executingPixmapRequests)) { + if (executingRequest->observer() == pObserver) { + d->cancelRenderingBecauseOf(executingRequest, nullptr); + } + } + + // remove observer entry from the set + d->m_observers.remove(pObserver); + } +} + +void Document::reparseConfig() +{ + // reparse generator config and if something changed clear Pages + bool configchanged = false; + if (d->m_generator) { + Okular::ConfigInterface *iface = qobject_cast(d->m_generator); + if (iface) + configchanged = iface->reparseConfig(); + } + if (configchanged) { + // invalidate pixmaps + QVector::const_iterator it = d->m_pagesVector.constBegin(), end = d->m_pagesVector.constEnd(); + for (; it != end; ++it) { + (*it)->deletePixmaps(); + } + + // [MEM] remove allocation descriptors + qDeleteAll(d->m_allocatedPixmaps); + d->m_allocatedPixmaps.clear(); + d->m_allocatedPixmapsTotalMemory = 0; + + // send reload signals to observers + foreachObserver(notifyContentsCleared(DocumentObserver::Pixmap)); + } + + // free memory if in 'low' profile + if (SettingsCore::memoryLevel() == SettingsCore::EnumMemoryLevel::Low && !d->m_allocatedPixmaps.isEmpty() && !d->m_pagesVector.isEmpty()) + d->cleanupPixmapMemory(); +} + +bool Document::isOpened() const +{ + return d->m_generator; +} + +bool Document::canConfigurePrinter() const +{ + if (d->m_generator) { + Okular::PrintInterface *iface = qobject_cast(d->m_generator); + return iface ? true : false; + } else + return false; +} + +DocumentInfo Document::documentInfo() const +{ + QSet keys; + for (Okular::DocumentInfo::Key ks = Okular::DocumentInfo::Title; ks < Okular::DocumentInfo::Invalid; ks = Okular::DocumentInfo::Key(ks + 1)) { + keys << ks; + } + + return documentInfo(keys); +} + +DocumentInfo Document::documentInfo(const QSet &keys) const +{ + DocumentInfo result = d->m_documentInfo; + const QSet missingKeys = keys - d->m_documentInfoAskedKeys; + + if (d->m_generator && !missingKeys.isEmpty()) { + DocumentInfo info = d->m_generator->generateDocumentInfo(missingKeys); + + if (missingKeys.contains(DocumentInfo::FilePath)) { + info.set(DocumentInfo::FilePath, currentDocument().toDisplayString()); + } + + if (d->m_docSize != -1 && missingKeys.contains(DocumentInfo::DocumentSize)) { + const QString sizeString = KFormat().formatByteSize(d->m_docSize); + info.set(DocumentInfo::DocumentSize, sizeString); + } + if (missingKeys.contains(DocumentInfo::PagesSize)) { + const QString pagesSize = d->pagesSizeString(); + if (!pagesSize.isEmpty()) { + info.set(DocumentInfo::PagesSize, pagesSize); + } + } + + if (missingKeys.contains(DocumentInfo::Pages) && info.get(DocumentInfo::Pages).isEmpty()) { + info.set(DocumentInfo::Pages, QString::number(this->pages())); + } + + d->m_documentInfo.d->values.unite(info.d->values); + d->m_documentInfo.d->titles.unite(info.d->titles); + result.d->values.unite(info.d->values); + result.d->titles.unite(info.d->titles); + } + d->m_documentInfoAskedKeys += keys; + + return result; +} + +const DocumentSynopsis *Document::documentSynopsis() const +{ + return d->m_generator ? d->m_generator->generateDocumentSynopsis() : nullptr; +} + +void Document::startFontReading() +{ + if (!d->m_generator || !d->m_generator->hasFeature(Generator::FontInfo) || d->m_fontThread) + return; + + if (d->m_fontsCached) { + // in case we have cached fonts, simulate a reading + // this way the API is the same, and users no need to care about the + // internal caching + for (int i = 0; i < d->m_fontsCache.count(); ++i) { + emit gotFont(d->m_fontsCache.at(i)); + emit fontReadingProgress(i / pages()); + } + emit fontReadingEnded(); + return; + } + + d->m_fontThread = new FontExtractionThread(d->m_generator, pages()); + connect(d->m_fontThread, &FontExtractionThread::gotFont, this, [this](const Okular::FontInfo &f) { d->fontReadingGotFont(f); }); + connect(d->m_fontThread.data(), &FontExtractionThread::progress, this, [this](int p) { d->slotFontReadingProgress(p); }); + + d->m_fontThread->startExtraction(/*d->m_generator->hasFeature( Generator::Threaded )*/ true); +} + +void Document::stopFontReading() +{ + if (!d->m_fontThread) + return; + + disconnect(d->m_fontThread, nullptr, this, nullptr); + d->m_fontThread->stopExtraction(); + d->m_fontThread = nullptr; + d->m_fontsCache.clear(); +} + +bool Document::canProvideFontInformation() const +{ + return d->m_generator ? d->m_generator->hasFeature(Generator::FontInfo) : false; +} + +const QList *Document::embeddedFiles() const +{ + return d->m_generator ? d->m_generator->embeddedFiles() : nullptr; +} + +const Page *Document::page(int n) const +{ + return (n >= 0 && n < d->m_pagesVector.count()) ? d->m_pagesVector.at(n) : nullptr; +} + +const DocumentViewport &Document::viewport() const +{ + return (*d->m_viewportIterator); +} + +const QVector &Document::visiblePageRects() const +{ + return d->m_pageRects; +} + +void Document::setVisiblePageRects(const QVector &visiblePageRects, DocumentObserver *excludeObserver) +{ + QVector::const_iterator vIt = d->m_pageRects.constBegin(); + QVector::const_iterator vEnd = d->m_pageRects.constEnd(); + for (; vIt != vEnd; ++vIt) + delete *vIt; + d->m_pageRects = visiblePageRects; + // notify change to all other (different from id) observers + foreach (DocumentObserver *o, d->m_observers) + if (o != excludeObserver) + o->notifyVisibleRectsChanged(); +} + +uint Document::currentPage() const +{ + return (*d->m_viewportIterator).pageNumber; +} + +uint Document::pages() const +{ + return d->m_pagesVector.size(); +} + +QUrl Document::currentDocument() const +{ + return d->m_url; +} + +bool Document::isAllowed(Permission action) const +{ + if (action == Okular::AllowNotes && (d->m_docdataMigrationNeeded || !d->m_annotationEditingEnabled)) + return false; + if (action == Okular::AllowFillForms && d->m_docdataMigrationNeeded) + return false; + +#if !OKULAR_FORCE_DRM + if (KAuthorized::authorize(QStringLiteral("skip_drm")) && !SettingsCore::obeyDRM()) + return true; +#endif + + return d->m_generator ? d->m_generator->isAllowed(action) : false; +} + +bool Document::supportsSearching() const +{ + return d->m_generator ? d->m_generator->hasFeature(Generator::TextExtraction) : false; +} + +bool Document::supportsPageSizes() const +{ + return d->m_generator ? d->m_generator->hasFeature(Generator::PageSizes) : false; +} + +bool Document::supportsTiles() const +{ + return d->m_generator ? d->m_generator->hasFeature(Generator::TiledRendering) : false; +} + +PageSize::List Document::pageSizes() const +{ + if (d->m_generator) { + if (d->m_pageSizes.isEmpty()) + d->m_pageSizes = d->m_generator->pageSizes(); + return d->m_pageSizes; + } + return PageSize::List(); +} + +bool Document::canExportToText() const +{ + if (!d->m_generator) + return false; + + d->cacheExportFormats(); + return !d->m_exportToText.isNull(); +} + +bool Document::exportToText(const QString &fileName) const +{ + if (!d->m_generator) + return false; + + d->cacheExportFormats(); + if (d->m_exportToText.isNull()) + return false; + + return d->m_generator->exportTo(fileName, d->m_exportToText); +} + +ExportFormat::List Document::exportFormats() const +{ + if (!d->m_generator) + return ExportFormat::List(); + + d->cacheExportFormats(); + return d->m_exportFormats; +} + +bool Document::exportTo(const QString &fileName, const ExportFormat &format) const +{ + return d->m_generator ? d->m_generator->exportTo(fileName, format) : false; +} + +bool Document::historyAtBegin() const +{ + return d->m_viewportIterator == d->m_viewportHistory.begin(); +} + +bool Document::historyAtEnd() const +{ + return d->m_viewportIterator == --(d->m_viewportHistory.end()); +} + +QVariant Document::metaData(const QString &key, const QVariant &option) const +{ + // if option starts with "src:" assume that we are handling a + // source reference + if (key == QLatin1String("NamedViewport") && option.toString().startsWith(QLatin1String("src:"), Qt::CaseInsensitive) && d->m_synctex_scanner) { + const QString reference = option.toString(); + + // The reference is of form "src:1111Filename", where "1111" + // points to line number 1111 in the file "Filename". + // Extract the file name and the numeral part from the reference string. + // This will fail if Filename starts with a digit. + QString name, lineString; + // Remove "src:". Presence of substring has been checked before this + // function is called. + name = reference.mid(4); + // split + int nameLength = name.length(); + int i = 0; + for (i = 0; i < nameLength; ++i) { + if (!name[i].isDigit()) + break; + } + lineString = name.left(i); + name = name.mid(i); + // Remove spaces. + name = name.trimmed(); + lineString = lineString.trimmed(); + // Convert line to integer. + bool ok; + int line = lineString.toInt(&ok); + if (!ok) + line = -1; + + // Use column == -1 for now. + if (synctex_display_query(d->m_synctex_scanner, QFile::encodeName(name).constData(), line, -1, 0) > 0) { + synctex_node_p node; + // For now use the first hit. Could possibly be made smarter + // in case there are multiple hits. + while ((node = synctex_scanner_next_result(d->m_synctex_scanner))) { + Okular::DocumentViewport viewport; + + // TeX pages start at 1. + viewport.pageNumber = synctex_node_page(node) - 1; + + if (viewport.pageNumber >= 0) { + const QSizeF dpi = d->m_generator->dpi(); + + // TeX small points ... + double px = (synctex_node_visible_h(node) * dpi.width()) / 72.27; + double py = (synctex_node_visible_v(node) * dpi.height()) / 72.27; + viewport.rePos.normalizedX = px / page(viewport.pageNumber)->width(); + viewport.rePos.normalizedY = (py + 0.5) / page(viewport.pageNumber)->height(); + viewport.rePos.enabled = true; + viewport.rePos.pos = Okular::DocumentViewport::Center; + + return viewport.toString(); + } + } + } + } + return d->m_generator ? d->m_generator->metaData(key, option) : QVariant(); +} + +Rotation Document::rotation() const +{ + return d->m_rotation; +} + +QSizeF Document::allPagesSize() const +{ + bool allPagesSameSize = true; + QSizeF size; + for (int i = 0; allPagesSameSize && i < d->m_pagesVector.count(); ++i) { + const Page *p = d->m_pagesVector.at(i); + if (i == 0) + size = QSizeF(p->width(), p->height()); + else { + allPagesSameSize = (size == QSizeF(p->width(), p->height())); + } + } + if (allPagesSameSize) + return size; + else + return QSizeF(); +} + +QString Document::pageSizeString(int page) const +{ + if (d->m_generator) { + if (d->m_generator->pagesSizeMetric() != Generator::None) { + const Page *p = d->m_pagesVector.at(page); + return d->localizedSize(QSizeF(p->width(), p->height())); + } + } + return QString(); +} + +static bool shouldCancelRenderingBecauseOf(const PixmapRequest &executingRequest, const PixmapRequest &otherRequest) +{ + // New request has higher priority -> cancel + if (executingRequest.priority() > otherRequest.priority()) + return true; + + // New request has lower priority -> don't cancel + if (executingRequest.priority() < otherRequest.priority()) + return false; + + // New request has same priority and is from a different observer -> don't cancel + // AFAIK this never happens since all observers have different priorities + if (executingRequest.observer() != otherRequest.observer()) + return false; + + // Same priority and observer, different page number -> don't cancel + // may still end up cancelled later in the parent caller if none of the requests + // is of the executingRequest page and RemoveAllPrevious is specified + if (executingRequest.pageNumber() != otherRequest.pageNumber()) + return false; + + // Same priority, observer, page, different size -> cancel + if (executingRequest.width() != otherRequest.width()) + return true; + + // Same priority, observer, page, different size -> cancel + if (executingRequest.height() != otherRequest.height()) + return true; + + // Same priority, observer, page, different tiling -> cancel + if (executingRequest.isTile() != otherRequest.isTile()) + return true; + + // Same priority, observer, page, different tiling -> cancel + if (executingRequest.isTile()) { + const NormalizedRect bothRequestsRect = executingRequest.normalizedRect() | otherRequest.normalizedRect(); + if (!(bothRequestsRect == executingRequest.normalizedRect())) + return true; + } + + return false; +} + +bool DocumentPrivate::cancelRenderingBecauseOf(PixmapRequest *executingRequest, PixmapRequest *newRequest) +{ + // No point in aborting the rendering already finished, let it go through + if (!executingRequest->d->mResultImage.isNull()) + return false; + + if (newRequest && newRequest->asynchronous() && executingRequest->partialUpdatesWanted()) { + newRequest->setPartialUpdatesWanted(true); + } + + TilesManager *tm = executingRequest->d->tilesManager(); + if (tm) { + tm->setPixmap(nullptr, executingRequest->normalizedRect(), true /*isPartialPixmap*/); + tm->setRequest(NormalizedRect(), 0, 0); + } + PagePrivate::PixmapObject object = executingRequest->page()->d->m_pixmaps.take(executingRequest->observer()); + delete object.m_pixmap; + + if (executingRequest->d->mShouldAbortRender != 0) + return false; + + executingRequest->d->mShouldAbortRender = 1; + + if (m_generator->d_ptr->mTextPageGenerationThread && m_generator->d_ptr->mTextPageGenerationThread->page() == executingRequest->page()) { + m_generator->d_ptr->mTextPageGenerationThread->abortExtraction(); + } + + return true; +} + +void Document::requestPixmaps(const QLinkedList &requests) +{ + requestPixmaps(requests, RemoveAllPrevious); +} + +void Document::requestPixmaps(const QLinkedList &requests, PixmapRequestFlags reqOptions) +{ + if (requests.isEmpty()) + return; + + if (!d->m_pageController) { + // delete requests.. + QLinkedList::const_iterator rIt = requests.constBegin(), rEnd = requests.constEnd(); + for (; rIt != rEnd; ++rIt) + delete *rIt; + // ..and return + return; + } + + QSet observersPixmapCleared; + + // 1. [CLEAN STACK] remove previous requests of requesterID + DocumentObserver *requesterObserver = requests.first()->observer(); + QSet requestedPages; + { + QLinkedList::const_iterator rIt = requests.constBegin(), rEnd = requests.constEnd(); + for (; rIt != rEnd; ++rIt) { + Q_ASSERT((*rIt)->observer() == requesterObserver); + requestedPages.insert((*rIt)->pageNumber()); + } + } + const bool removeAllPrevious = reqOptions & RemoveAllPrevious; + d->m_pixmapRequestsMutex.lock(); + QLinkedList::iterator sIt = d->m_pixmapRequestsStack.begin(), sEnd = d->m_pixmapRequestsStack.end(); + while (sIt != sEnd) { + if ((*sIt)->observer() == requesterObserver && (removeAllPrevious || requestedPages.contains((*sIt)->pageNumber()))) { + // delete request and remove it from stack + delete *sIt; + sIt = d->m_pixmapRequestsStack.erase(sIt); + } else + ++sIt; + } + + // 1.B [PREPROCESS REQUESTS] tweak some values of the requests + for (PixmapRequest *request : requests) { + // set the 'page field' (see PixmapRequest) and check if it is valid + qCDebug(OkularCoreDebug).nospace() << "request observer=" << request->observer() << " " << request->width() << "x" << request->height() << "@" << request->pageNumber(); + if (d->m_pagesVector.value(request->pageNumber()) == nullptr) { + // skip requests referencing an invalid page (must not happen) + delete request; + continue; + } + + request->d->mPage = d->m_pagesVector.value(request->pageNumber()); + + if (request->isTile()) { + // Change the current request rect so that only invalid tiles are + // requested. Also make sure the rect is tile-aligned. + NormalizedRect tilesRect; + const QList tiles = request->d->tilesManager()->tilesAt(request->normalizedRect(), TilesManager::TerminalTile); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + while (tIt != tEnd) { + const Tile &tile = *tIt; + if (!tile.isValid()) { + if (tilesRect.isNull()) + tilesRect = tile.rect(); + else + tilesRect |= tile.rect(); + } + + tIt++; + } + + request->setNormalizedRect(tilesRect); + } + + if (!request->asynchronous()) + request->d->mPriority = 0; + } + + // 1.C [CANCEL REQUESTS] cancel those requests that are running and should be cancelled because of the new requests coming in + if (d->m_generator->hasFeature(Generator::SupportsCancelling)) { + for (PixmapRequest *executingRequest : qAsConst(d->m_executingPixmapRequests)) { + bool newRequestsContainExecutingRequestPage = false; + bool requestCancelled = false; + for (PixmapRequest *newRequest : requests) { + if (newRequest->pageNumber() == executingRequest->pageNumber() && requesterObserver == executingRequest->observer()) { + newRequestsContainExecutingRequestPage = true; + } + + if (shouldCancelRenderingBecauseOf(*executingRequest, *newRequest)) { + requestCancelled = d->cancelRenderingBecauseOf(executingRequest, newRequest); + } + } + + // If we were told to remove all the previous requests and the executing request page is not part of the new requests, cancel it + if (!requestCancelled && removeAllPrevious && requesterObserver == executingRequest->observer() && !newRequestsContainExecutingRequestPage) { + requestCancelled = d->cancelRenderingBecauseOf(executingRequest, nullptr); + } + + if (requestCancelled) { + observersPixmapCleared << executingRequest->observer(); + } + } + } + + // 2. [ADD TO STACK] add requests to stack + for (PixmapRequest *request : requests) { + // add request to the 'stack' at the right place + if (!request->priority()) + // add priority zero requests to the top of the stack + d->m_pixmapRequestsStack.append(request); + else { + // insert in stack sorted by priority + sIt = d->m_pixmapRequestsStack.begin(); + sEnd = d->m_pixmapRequestsStack.end(); + while (sIt != sEnd && (*sIt)->priority() > request->priority()) + ++sIt; + d->m_pixmapRequestsStack.insert(sIt, request); + } + } + d->m_pixmapRequestsMutex.unlock(); + + // 3. [START FIRST GENERATION] if generator is ready, start a new generation, + // or else (if gen is running) it will be started when the new contents will + // come from generator (in requestDone()) + // all handling of requests put into sendGeneratorPixmapRequest + // if ( generator->canRequestPixmap() ) + d->sendGeneratorPixmapRequest(); + + for (DocumentObserver *o : qAsConst(observersPixmapCleared)) + o->notifyContentsCleared(Okular::DocumentObserver::Pixmap); +} + +void Document::requestTextPage(uint pageNumber) +{ + Page *kp = d->m_pagesVector[pageNumber]; + if (!d->m_generator || !kp) + return; + + // Memory management for TextPages + + d->m_generator->generateTextPage(kp); +} + +void DocumentPrivate::notifyAnnotationChanges(int page) +{ + foreachObserverD(notifyPageChanged(page, DocumentObserver::Annotations)); +} + +void DocumentPrivate::notifyFormChanges(int /*page*/) +{ + recalculateForms(); +} + +void Document::addPageAnnotation(int page, Annotation *annotation) +{ + // Transform annotation's base boundary rectangle into unrotated coordinates + Page *p = d->m_pagesVector[page]; + QTransform t = p->d->rotationMatrix(); + annotation->d_ptr->baseTransform(t.inverted()); + QUndoCommand *uc = new AddAnnotationCommand(this->d, annotation, page); + d->m_undoStack->push(uc); +} + +bool Document::canModifyPageAnnotation(const Annotation *annotation) const +{ + if (!annotation || (annotation->flags() & Annotation::DenyWrite)) + return false; + + if (!isAllowed(Okular::AllowNotes)) + return false; + + if ((annotation->flags() & Annotation::External) && !d->canModifyExternalAnnotations()) + return false; + + switch (annotation->subType()) { + case Annotation::AText: + case Annotation::ALine: + case Annotation::AGeom: + case Annotation::AHighlight: + case Annotation::AStamp: + case Annotation::AInk: + return true; + default: + return false; + } +} + +void Document::prepareToModifyAnnotationProperties(Annotation *annotation) +{ + Q_ASSERT(d->m_prevPropsOfAnnotBeingModified.isNull()); + if (!d->m_prevPropsOfAnnotBeingModified.isNull()) { + qCCritical(OkularCoreDebug) << "Error: Document::prepareToModifyAnnotationProperties has already been called since last call to Document::modifyPageAnnotationProperties"; + return; + } + d->m_prevPropsOfAnnotBeingModified = annotation->getAnnotationPropertiesDomNode(); +} + +void Document::modifyPageAnnotationProperties(int page, Annotation *annotation) +{ + Q_ASSERT(!d->m_prevPropsOfAnnotBeingModified.isNull()); + if (d->m_prevPropsOfAnnotBeingModified.isNull()) { + qCCritical(OkularCoreDebug) << "Error: Document::prepareToModifyAnnotationProperties must be called before Annotation is modified"; + return; + } + QDomNode prevProps = d->m_prevPropsOfAnnotBeingModified; + QUndoCommand *uc = new Okular::ModifyAnnotationPropertiesCommand(d, annotation, page, prevProps, annotation->getAnnotationPropertiesDomNode()); + d->m_undoStack->push(uc); + d->m_prevPropsOfAnnotBeingModified.clear(); +} + +void Document::translatePageAnnotation(int page, Annotation *annotation, const NormalizedPoint &delta) +{ + int complete = (annotation->flags() & Okular::Annotation::BeingMoved) == 0; + QUndoCommand *uc = new Okular::TranslateAnnotationCommand(d, annotation, page, delta, complete); + d->m_undoStack->push(uc); +} + +void Document::adjustPageAnnotation(int page, Annotation *annotation, const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2) +{ + const bool complete = (annotation->flags() & Okular::Annotation::BeingResized) == 0; + QUndoCommand *uc = new Okular::AdjustAnnotationCommand(d, annotation, page, delta1, delta2, complete); + d->m_undoStack->push(uc); +} + +void Document::editPageAnnotationContents(int page, Annotation *annotation, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos) +{ + QString prevContents = annotation->contents(); + QUndoCommand *uc = new EditAnnotationContentsCommand(d, annotation, page, newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos); + d->m_undoStack->push(uc); +} + +bool Document::canRemovePageAnnotation(const Annotation *annotation) const +{ + if (!annotation || (annotation->flags() & Annotation::DenyDelete)) + return false; + + if ((annotation->flags() & Annotation::External) && !d->canRemoveExternalAnnotations()) + return false; + + switch (annotation->subType()) { + case Annotation::AText: + case Annotation::ALine: + case Annotation::AGeom: + case Annotation::AHighlight: + case Annotation::AStamp: + case Annotation::AInk: + case Annotation::ACaret: + return true; + default: + return false; + } +} + +void Document::removePageAnnotation(int page, Annotation *annotation) +{ + QUndoCommand *uc = new RemoveAnnotationCommand(this->d, annotation, page); + d->m_undoStack->push(uc); +} + +void Document::removePageAnnotations(int page, const QList &annotations) +{ + d->m_undoStack->beginMacro(i18nc("remove a collection of annotations from the page", "remove annotations")); + foreach (Annotation *annotation, annotations) { + QUndoCommand *uc = new RemoveAnnotationCommand(this->d, annotation, page); + d->m_undoStack->push(uc); + } + d->m_undoStack->endMacro(); +} + +bool DocumentPrivate::canAddAnnotationsNatively() const +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + + if (iface && iface->supportsOption(Okular::SaveInterface::SaveChanges) && iface->annotationProxy() && iface->annotationProxy()->supports(AnnotationProxy::Addition)) + return true; + + return false; +} + +bool DocumentPrivate::canModifyExternalAnnotations() const +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + + if (iface && iface->supportsOption(Okular::SaveInterface::SaveChanges) && iface->annotationProxy() && iface->annotationProxy()->supports(AnnotationProxy::Modification)) + return true; + + return false; +} + +bool DocumentPrivate::canRemoveExternalAnnotations() const +{ + Okular::SaveInterface *iface = qobject_cast(m_generator); + + if (iface && iface->supportsOption(Okular::SaveInterface::SaveChanges) && iface->annotationProxy() && iface->annotationProxy()->supports(AnnotationProxy::Removal)) + return true; + + return false; +} + +void Document::setPageTextSelection(int page, RegularAreaRect *rect, const QColor &color) +{ + Page *kp = d->m_pagesVector[page]; + if (!d->m_generator || !kp) + return; + + // add or remove the selection basing whether rect is null or not + if (rect) + kp->d->setTextSelections(rect, color); + else + kp->d->deleteTextSelections(); + + // notify observers about the change + foreachObserver(notifyPageChanged(page, DocumentObserver::TextSelection)); +} + +bool Document::canUndo() const +{ + return d->m_undoStack->canUndo(); +} + +bool Document::canRedo() const +{ + return d->m_undoStack->canRedo(); +} + +/* REFERENCE IMPLEMENTATION: better calling setViewport from other code +void Document::setNextPage() +{ + // advance page and set viewport on observers + if ( (*d->m_viewportIterator).pageNumber < (int)d->m_pagesVector.count() - 1 ) + setViewport( DocumentViewport( (*d->m_viewportIterator).pageNumber + 1 ) ); +} + +void Document::setPrevPage() +{ + // go to previous page and set viewport on observers + if ( (*d->m_viewportIterator).pageNumber > 0 ) + setViewport( DocumentViewport( (*d->m_viewportIterator).pageNumber - 1 ) ); +} +*/ + +void Document::setViewportWithHistory(const DocumentViewport &viewport, DocumentObserver *excludeObserver, bool smoothMove, bool updateHistory) +{ + if (!viewport.isValid()) { + qCDebug(OkularCoreDebug) << "invalid viewport:" << viewport.toString(); + return; + } + if (viewport.pageNumber >= int(d->m_pagesVector.count())) { + // qCDebug(OkularCoreDebug) << "viewport out of document:" << viewport.toString(); + return; + } + + // if already broadcasted, don't redo it + DocumentViewport &oldViewport = *d->m_viewportIterator; + // disabled by enrico on 2005-03-18 (less debug output) + // if ( viewport == oldViewport ) + // qCDebug(OkularCoreDebug) << "setViewport with the same viewport."; + + const int oldPageNumber = oldViewport.pageNumber; + + // set internal viewport taking care of history + if (oldViewport.pageNumber == viewport.pageNumber || !oldViewport.isValid() || !updateHistory) { + // if page is unchanged save the viewport at current position in queue + oldViewport = viewport; + } else { + // remove elements after viewportIterator in queue + d->m_viewportHistory.erase(++d->m_viewportIterator, d->m_viewportHistory.end()); + + // keep the list to a reasonable size by removing head when needed + if (d->m_viewportHistory.count() >= OKULAR_HISTORY_MAXSTEPS) + d->m_viewportHistory.pop_front(); + + // add the item at the end of the queue + d->m_viewportIterator = d->m_viewportHistory.insert(d->m_viewportHistory.end(), viewport); + } + + const int currentViewportPage = (*d->m_viewportIterator).pageNumber; + + const bool currentPageChanged = (oldPageNumber != currentViewportPage); + + // notify change to all other (different from id) observers + for (DocumentObserver *o : qAsConst(d->m_observers)) { + if (o != excludeObserver) + o->notifyViewportChanged(smoothMove); + + if (currentPageChanged) + o->notifyCurrentPageChanged(oldPageNumber, currentViewportPage); + } +} + +void Document::setViewportPage(int page, DocumentObserver *excludeObserver, bool smoothMove) +{ + // clamp page in range [0 ... numPages-1] + if (page < 0) + page = 0; + else if (page > (int)d->m_pagesVector.count()) + page = d->m_pagesVector.count() - 1; + + // make a viewport from the page and broadcast it + setViewport(DocumentViewport(page), excludeObserver, smoothMove); +} + +void Document::setViewport(const DocumentViewport &viewport, DocumentObserver *excludeObserver, bool smoothMove) +{ + // set viewport, updating history + setViewportWithHistory(viewport, excludeObserver, smoothMove, true); +} + +void Document::setZoom(int factor, DocumentObserver *excludeObserver) +{ + // notify change to all other (different from id) observers + for (DocumentObserver *o : qAsConst(d->m_observers)) + if (o != excludeObserver) + o->notifyZoom(factor); +} + +void Document::setPrevViewport() +// restore viewport from the history +{ + if (d->m_viewportIterator != d->m_viewportHistory.begin()) { + const int oldViewportPage = (*d->m_viewportIterator).pageNumber; + + // restore previous viewport and notify it to observers + --d->m_viewportIterator; + foreachObserver(notifyViewportChanged(true)); + + const int currentViewportPage = (*d->m_viewportIterator).pageNumber; + if (oldViewportPage != currentViewportPage) + foreachObserver(notifyCurrentPageChanged(oldViewportPage, currentViewportPage)); + } +} + +void Document::setNextViewport() +// restore next viewport from the history +{ + auto nextIterator = QLinkedList::const_iterator(d->m_viewportIterator); + ++nextIterator; + if (nextIterator != d->m_viewportHistory.constEnd()) { + const int oldViewportPage = (*d->m_viewportIterator).pageNumber; + + // restore next viewport and notify it to observers + ++d->m_viewportIterator; + foreachObserver(notifyViewportChanged(true)); + + const int currentViewportPage = (*d->m_viewportIterator).pageNumber; + if (oldViewportPage != currentViewportPage) + foreachObserver(notifyCurrentPageChanged(oldViewportPage, currentViewportPage)); + } +} + +void Document::setNextDocumentViewport(const DocumentViewport &viewport) +{ + d->m_nextDocumentViewport = viewport; +} + +void Document::setNextDocumentDestination(const QString &namedDestination) +{ + d->m_nextDocumentDestination = namedDestination; +} + +void Document::searchText(int searchID, const QString &text, bool fromStart, Qt::CaseSensitivity caseSensitivity, 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()) { + emit searchFinished(searchID, NoMatchFound); + return; + } + + // if searchID search not recorded, create new descriptor and init params + QMap::iterator searchIt = d->m_searches.find(searchID); + if (searchIt == d->m_searches.end()) { + RunningSearch *search = new RunningSearch(); + search->continueOnPage = -1; + searchIt = d->m_searches.insert(searchID, search); + } + RunningSearch *s = *searchIt; + + // update search structure + bool newText = text != s->cachedString; + s->cachedString = text; + s->cachedType = type; + s->cachedCaseSensitivity = caseSensitivity; + s->cachedViewportMove = moveViewport; + s->cachedColor = color; + s->isCurrentlySearching = true; + + // global data for search + QSet *pagesToNotify = new QSet; + + // remove highlights from pages and queue them for notifying changes + *pagesToNotify += s->highlightedPages; + for (const int pageNumber : qAsConst(s->highlightedPages)) { + d->m_pagesVector.at(pageNumber)->d->deleteHighlights(searchID); + } + s->highlightedPages.clear(); + + // set hourglass cursor + QApplication::setOverrideCursor(Qt::WaitCursor); + + // 1. ALLDOC - process all document marking pages + if (type == AllDocument) { + QMap> *pageMatches = new QMap>; + + // search and highlight 'text' (as a solid phrase) on all pages + QTimer::singleShot(0, this, [this, pagesToNotify, pageMatches, searchID] { d->doContinueAllDocumentSearch(pagesToNotify, pageMatches, 0, searchID); }); + } + // 2. NEXTMATCH - find next matching item (or start from top) + // 3. PREVMATCH - find previous matching item (or start from bottom) + else if (type == NextMatch || type == PreviousMatch) { + // find out from where to start/resume search from + const bool forward = type == NextMatch; + const int viewportPage = (*d->m_viewportIterator).pageNumber; + const int fromStartSearchPage = forward ? 0 : d->m_pagesVector.count() - 1; + int currentPage = fromStart ? fromStartSearchPage : ((s->continueOnPage != -1) ? s->continueOnPage : viewportPage); + Page *lastPage = fromStart ? nullptr : d->m_pagesVector[currentPage]; + int pagesDone = 0; + + // continue checking last TextPage first (if it is the current page) + RegularAreaRect *match = nullptr; + if (lastPage && lastPage->number() == s->continueOnPage) { + if (newText) + match = lastPage->findText(searchID, text, forward ? FromTop : FromBottom, caseSensitivity); + else + match = lastPage->findText(searchID, text, forward ? NextResult : PreviousResult, caseSensitivity, &s->continueOnMatch); + if (!match) { + if (forward) + currentPage++; + else + currentPage--; + pagesDone++; + } + } + + s->pagesDone = pagesDone; + + DoContinueDirectionMatchSearchStruct *searchStruct = new DoContinueDirectionMatchSearchStruct(); + searchStruct->pagesToNotify = pagesToNotify; + searchStruct->match = match; + searchStruct->currentPage = currentPage; + searchStruct->searchID = searchID; + + QTimer::singleShot(0, this, [this, searchStruct] { d->doContinueDirectionMatchSearch(searchStruct); }); + } + // 4. GOOGLE* - process all document marking pages + else if (type == GoogleAll || type == GoogleAny) { + QMap>> *pageMatches = new QMap>>; + const QStringList words = text.split(QLatin1Char(' '), QString::SkipEmptyParts); + + // search and highlight every word in 'text' on all pages + QTimer::singleShot(0, this, [this, pagesToNotify, pageMatches, searchID, words] { d->doContinueGooglesDocumentSearch(pagesToNotify, pageMatches, 0, searchID, words); }); + } +} + +void Document::continueSearch(int searchID) +{ + // check if searchID is present in runningSearches + QMap::const_iterator it = d->m_searches.constFind(searchID); + if (it == d->m_searches.constEnd()) { + emit searchFinished(searchID, NoMatchFound); + return; + } + + // start search with cached parameters from last search by searchID + RunningSearch *p = *it; + if (!p->isCurrentlySearching) + searchText(searchID, p->cachedString, false, p->cachedCaseSensitivity, p->cachedType, p->cachedViewportMove, p->cachedColor); +} + +void Document::continueSearch(int searchID, SearchType type) +{ + // check if searchID is present in runningSearches + QMap::const_iterator it = d->m_searches.constFind(searchID); + if (it == d->m_searches.constEnd()) { + emit searchFinished(searchID, NoMatchFound); + return; + } + + // start search with cached parameters from last search by searchID + RunningSearch *p = *it; + if (!p->isCurrentlySearching) + searchText(searchID, p->cachedString, false, p->cachedCaseSensitivity, type, p->cachedViewportMove, p->cachedColor); +} + +void Document::resetSearch(int searchID) +{ + // if we are closing down, don't bother doing anything + if (!d->m_generator) + return; + + // check if searchID is present in runningSearches + QMap::iterator searchIt = d->m_searches.find(searchID); + if (searchIt == d->m_searches.end()) + return; + + // get previous parameters for search + RunningSearch *s = *searchIt; + + // unhighlight pages and inform observers about that + for (const int pageNumber : qAsConst(s->highlightedPages)) { + d->m_pagesVector.at(pageNumber)->d->deleteHighlights(searchID); + foreachObserver(notifyPageChanged(pageNumber, DocumentObserver::Highlights)); + } + + // send the setup signal too (to update views that filter on matches) + foreachObserver(notifySetup(d->m_pagesVector, 0)); + + // remove search from the runningSearches list and delete it + d->m_searches.erase(searchIt); + delete s; +} + +void Document::cancelSearch() +{ + d->m_searchCancelled = true; +} + +void Document::undo() +{ + d->m_undoStack->undo(); +} + +void Document::redo() +{ + d->m_undoStack->redo(); +} + +void Document::editFormText(int pageNumber, Okular::FormFieldText *form, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos) +{ + QUndoCommand *uc = new EditFormTextCommand(this->d, form, pageNumber, newContents, newCursorPos, form->text(), prevCursorPos, prevAnchorPos); + d->m_undoStack->push(uc); +} + +void Document::editFormList(int pageNumber, FormFieldChoice *form, const QList &newChoices) +{ + const QList prevChoices = form->currentChoices(); + QUndoCommand *uc = new EditFormListCommand(this->d, form, pageNumber, newChoices, prevChoices); + d->m_undoStack->push(uc); +} + +void Document::editFormCombo(int pageNumber, FormFieldChoice *form, const QString &newText, int newCursorPos, int prevCursorPos, int prevAnchorPos) +{ + QString prevText; + if (form->currentChoices().isEmpty()) { + prevText = form->editChoice(); + } else { + prevText = form->choices().at(form->currentChoices().constFirst()); + } + + QUndoCommand *uc = new EditFormComboCommand(this->d, form, pageNumber, newText, newCursorPos, prevText, prevCursorPos, prevAnchorPos); + d->m_undoStack->push(uc); +} + +void Document::editFormButtons(int pageNumber, const QList &formButtons, const QList &newButtonStates) +{ + QUndoCommand *uc = new EditFormButtonsCommand(this->d, pageNumber, formButtons, newButtonStates); + d->m_undoStack->push(uc); +} + +void Document::reloadDocument() const +{ + const int numOfPages = pages(); + for (int i = currentPage(); i >= 0; i--) + d->refreshPixmaps(i); + for (int i = currentPage() + 1; i < numOfPages; i++) + d->refreshPixmaps(i); +} + +BookmarkManager *Document::bookmarkManager() const +{ + return d->m_bookmarkManager; +} + +QList Document::bookmarkedPageList() const +{ + QList list; + uint docPages = pages(); + + // pages are 0-indexed internally, but 1-indexed externally + for (uint i = 0; i < docPages; i++) { + if (bookmarkManager()->isBookmarked(i)) { + list << i + 1; + } + } + return list; +} + +QString Document::bookmarkedPageRange() const +{ + // Code formerly in Part::slotPrint() + // range detecting + QString range; + uint docPages = pages(); + int startId = -1; + int endId = -1; + + for (uint i = 0; i < docPages; ++i) { + if (bookmarkManager()->isBookmarked(i)) { + if (startId < 0) + startId = i; + if (endId < 0) + endId = startId; + else + ++endId; + } else if (startId >= 0 && endId >= 0) { + if (!range.isEmpty()) + range += QLatin1Char(','); + + if (endId - startId > 0) + range += QStringLiteral("%1-%2").arg(startId + 1).arg(endId + 1); + else + range += QString::number(startId + 1); + startId = -1; + endId = -1; + } + } + if (startId >= 0 && endId >= 0) { + if (!range.isEmpty()) + range += QLatin1Char(','); + + if (endId - startId > 0) + range += QStringLiteral("%1-%2").arg(startId + 1).arg(endId + 1); + else + range += QString::number(startId + 1); + } + return range; +} + +void Document::processAction(const Action *action) +{ + if (!action) + return; + + // Don't execute next actions if the action itself caused the closing of the document + bool executeNextActions = true; + QObject disconnectHelper; // guarantees the connect below will be disconnected on finishing the function + connect(this, &Document::aboutToClose, &disconnectHelper, [&executeNextActions] { executeNextActions = false; }); + + switch (action->actionType()) { + case Action::Goto: { + const GotoAction *go = static_cast(action); + d->m_nextDocumentViewport = go->destViewport(); + d->m_nextDocumentDestination = go->destinationName(); + + // Explanation of why d->m_nextDocumentViewport is needed: + // all openRelativeFile does is launch a signal telling we + // want to open another URL, the problem is that when the file is + // non local, the loading is done asynchronously so you can't + // do a setViewport after the if as it was because you are doing the setViewport + // on the old file and when the new arrives there is no setViewport for it and + // it does not show anything + + // first open filename if link is pointing outside this document + if (go->isExternal() && !d->openRelativeFile(go->fileName())) { + qCWarning(OkularCoreDebug).nospace() << "Action: Error opening '" << go->fileName() << "'."; + break; + } else { + const DocumentViewport nextViewport = d->nextDocumentViewport(); + // skip local links that point to nowhere (broken ones) + if (!nextViewport.isValid()) + break; + + setViewport(nextViewport, nullptr, true); + d->m_nextDocumentViewport = DocumentViewport(); + d->m_nextDocumentDestination = QString(); + } + + } break; + + case Action::Execute: { + const ExecuteAction *exe = static_cast(action); + const QString fileName = exe->fileName(); + if (fileName.endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive)) { + d->openRelativeFile(fileName); + break; + } + + // Albert: the only pdf i have that has that kind of link don't define + // an application and use the fileName as the file to open + QUrl url = d->giveAbsoluteUrl(fileName); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForUrl(url); + // Check executables + if (KRun::isExecutableFile(url, mime.name())) { + // Don't have any pdf that uses this code path, just a guess on how it should work + if (!exe->parameters().isEmpty()) { + url = d->giveAbsoluteUrl(exe->parameters()); + mime = db.mimeTypeForUrl(url); + + if (KRun::isExecutableFile(url, mime.name())) { + // this case is a link pointing to an executable with a parameter + // that also is an executable, possibly a hand-crafted pdf + KMessageBox::information(d->m_widget, i18n("The document is trying to execute an external application and, for your safety, Okular does not allow that.")); + break; + } + } else { + // this case is a link pointing to an executable with no parameters + // core developers find unacceptable executing it even after asking the user + KMessageBox::information(d->m_widget, i18n("The document is trying to execute an external application and, for your safety, Okular does not allow that.")); + break; + } + } + + KService::Ptr ptr = KMimeTypeTrader::self()->preferredService(mime.name(), QStringLiteral("Application")); + if (ptr) { + QList lst; + lst.append(url); + KRun::runService(*ptr, lst, nullptr); + } else + KMessageBox::information(d->m_widget, i18n("No application found for opening file of mimetype %1.", mime.name())); + } break; + + case Action::DocAction: { + const DocumentAction *docaction = static_cast(action); + switch (docaction->documentActionType()) { + case DocumentAction::PageFirst: + setViewportPage(0); + break; + case DocumentAction::PagePrev: + if ((*d->m_viewportIterator).pageNumber > 0) + setViewportPage((*d->m_viewportIterator).pageNumber - 1); + break; + case DocumentAction::PageNext: + if ((*d->m_viewportIterator).pageNumber < (int)d->m_pagesVector.count() - 1) + setViewportPage((*d->m_viewportIterator).pageNumber + 1); + break; + case DocumentAction::PageLast: + setViewportPage(d->m_pagesVector.count() - 1); + break; + case DocumentAction::HistoryBack: + setPrevViewport(); + break; + case DocumentAction::HistoryForward: + setNextViewport(); + break; + case DocumentAction::Quit: + emit quit(); + break; + case DocumentAction::Presentation: + emit linkPresentation(); + break; + case DocumentAction::EndPresentation: + emit linkEndPresentation(); + break; + case DocumentAction::Find: + emit linkFind(); + break; + case DocumentAction::GoToPage: + emit linkGoToPage(); + break; + case DocumentAction::Close: + emit close(); + break; + } + } break; + + case Action::Browse: { + const BrowseAction *browse = static_cast(action); + QString lilySource; + int lilyRow = 0, lilyCol = 0; + // if the url is a mailto one, invoke mailer + if (browse->url().scheme() == QLatin1String("mailto")) { + QDesktopServices::openUrl(browse->url()); + } else if (extractLilyPondSourceReference(browse->url(), &lilySource, &lilyRow, &lilyCol)) { + const SourceReference ref(lilySource, lilyRow, lilyCol); + processSourceReference(&ref); + } else { + const QUrl url = browse->url(); + + // fix for #100366, documents with relative links that are the form of http:foo.pdf + if ((url.scheme() == QLatin1String("http")) && url.host().isEmpty() && url.fileName().endsWith(QLatin1String("pdf"))) { + d->openRelativeFile(url.fileName()); + break; + } + + // handle documents with relative path + if (d->m_url.isValid()) { + const QUrl realUrl = KIO::upUrl(d->m_url).resolved(url); + // KRun autodeletes + KRun *r = new KRun(realUrl, d->m_widget); + r->setRunExecutables(false); + } + } + } break; + + case Action::Sound: { + const SoundAction *linksound = static_cast(action); + AudioPlayer::instance()->playSound(linksound->sound(), linksound); + } break; + + case Action::Script: { + const ScriptAction *linkscript = static_cast(action); + if (!d->m_scripter) + d->m_scripter = new Scripter(d); + d->m_scripter->execute(linkscript->scriptType(), linkscript->script()); + } break; + + case Action::Movie: + emit processMovieAction(static_cast(action)); + break; + case Action::Rendition: { + const RenditionAction *linkrendition = static_cast(action); + if (!linkrendition->script().isEmpty()) { + if (!d->m_scripter) + d->m_scripter = new Scripter(d); + d->m_scripter->execute(linkrendition->scriptType(), linkrendition->script()); + } + + emit processRenditionAction(static_cast(action)); + } break; + case Action::BackendOpaque: { + d->m_generator->opaqueAction(static_cast(action)); + } break; + } + + if (executeNextActions) { + const QVector nextActions = action->nextActions(); + for (const Action *a : nextActions) { + processAction(a); + } + } +} + +void Document::processFormatAction(const Action *action, Okular::FormFieldText *fft) +{ + if (action->actionType() != Action::Script) { + qCDebug(OkularCoreDebug) << "Unsupported action type" << action->actionType() << "for formatting."; + return; + } + + // Lookup the page of the FormFieldText + int foundPage = d->findFieldPageNumber(fft); + + if (foundPage == -1) { + qCDebug(OkularCoreDebug) << "Could not find page for formfield!"; + return; + } + + const QString unformattedText = fft->text(); + + std::shared_ptr event = Event::createFormatEvent(fft, d->m_pagesVector[foundPage]); + + const ScriptAction *linkscript = static_cast(action); + + d->executeScriptEvent(event, linkscript); + + const QString formattedText = event->value().toString(); + if (formattedText != unformattedText) { + // We set the formattedText, because when we call refreshFormWidget + // It will set the QLineEdit to this formattedText + fft->setText(formattedText); + fft->setAppearanceText(formattedText); + emit refreshFormWidget(fft); + d->refreshPixmaps(foundPage); + // Then we make the form have the unformatted text, to use + // in calculations and other things. + fft->setText(unformattedText); + } else if (fft->additionalAction(FormField::CalculateField)) { + // When the field was calculated we need to refresh even + // if the format script changed nothing. e.g. on error. + // This is because the recalculateForms function delegated + // the responsiblity for the refresh to us. + emit refreshFormWidget(fft); + d->refreshPixmaps(foundPage); + } +} + +void Document::processKeystrokeAction(const Action *action, Okular::FormFieldText *fft, bool &returnCode) +{ + if (action->actionType() != Action::Script) { + qCDebug(OkularCoreDebug) << "Unsupported action type" << action->actionType() << "for keystroke."; + return; + } + // Lookup the page of the FormFieldText + int foundPage = d->findFieldPageNumber(fft); + + if (foundPage == -1) { + qCDebug(OkularCoreDebug) << "Could not find page for formfield!"; + return; + } + + std::shared_ptr event = Event::createKeystrokeEvent(fft, d->m_pagesVector[foundPage]); + + const ScriptAction *linkscript = static_cast(action); + + d->executeScriptEvent(event, linkscript); + + returnCode = event->returnCode(); +} + +void Document::processFocusAction(const Action *action, Okular::FormField *field) +{ + if (!action || action->actionType() != Action::Script) + return; + + // Lookup the page of the FormFieldText + int foundPage = d->findFieldPageNumber(field); + + if (foundPage == -1) { + qCDebug(OkularCoreDebug) << "Could not find page for formfield!"; + return; + } + + std::shared_ptr event = Event::createFormFocusEvent(field, d->m_pagesVector[foundPage]); + + const ScriptAction *linkscript = static_cast(action); + + d->executeScriptEvent(event, linkscript); +} + +void Document::processValidateAction(const Action *action, Okular::FormFieldText *fft, bool &returnCode) +{ + if (!action || action->actionType() != Action::Script) + return; + + // Lookup the page of the FormFieldText + int foundPage = d->findFieldPageNumber(fft); + + if (foundPage == -1) { + qCDebug(OkularCoreDebug) << "Could not find page for formfield!"; + return; + } + + std::shared_ptr event = Event::createFormValidateEvent(fft, d->m_pagesVector[foundPage]); + + const ScriptAction *linkscript = static_cast(action); + + d->executeScriptEvent(event, linkscript); + returnCode = event->returnCode(); +} + +void Document::processSourceReference(const SourceReference *ref) +{ + if (!ref) + return; + + const QUrl url = d->giveAbsoluteUrl(ref->fileName()); + if (!url.isLocalFile()) { + qCDebug(OkularCoreDebug) << url.url() << "is not a local file."; + return; + } + + const QString absFileName = url.toLocalFile(); + if (!QFile::exists(absFileName)) { + qCDebug(OkularCoreDebug) << "No such file:" << absFileName; + return; + } + + bool handled = false; + emit sourceReferenceActivated(absFileName, ref->row(), ref->column(), &handled); + if (handled) { + return; + } + + static QHash editors; + // init the editors table if empty (on first run, usually) + if (editors.isEmpty()) { + editors = buildEditorsMap(); + } + + QHash::const_iterator it = editors.constFind(SettingsCore::externalEditor()); + QString p; + if (it != editors.constEnd()) + p = *it; + else + p = SettingsCore::externalEditorCommand(); + // custom editor not yet configured + if (p.isEmpty()) + return; + + // manually append the %f placeholder if not specified + if (p.indexOf(QLatin1String("%f")) == -1) + p.append(QLatin1String(" %f")); + + // replacing the placeholders + QHash map; + map.insert(QLatin1Char('f'), absFileName); + map.insert(QLatin1Char('c'), QString::number(ref->column())); + map.insert(QLatin1Char('l'), QString::number(ref->row())); + const QString cmd = KMacroExpander::expandMacrosShellQuote(p, map); + if (cmd.isEmpty()) + return; + const QStringList args = KShell::splitArgs(cmd); + if (args.isEmpty()) + return; + + KProcess::startDetached(args); +} + +const SourceReference *Document::dynamicSourceReference(int pageNr, double absX, double absY) +{ + if (!d->m_synctex_scanner) + return nullptr; + + const QSizeF dpi = d->m_generator->dpi(); + + if (synctex_edit_query(d->m_synctex_scanner, pageNr + 1, absX * 72. / dpi.width(), absY * 72. / dpi.height()) > 0) { + synctex_node_p node; + // TODO what should we do if there is really more than one node? + while ((node = synctex_scanner_next_result(d->m_synctex_scanner))) { + int line = synctex_node_line(node); + int col = synctex_node_column(node); + // column extraction does not seem to be implemented in synctex so far. set the SourceReference default value. + if (col == -1) { + col = 0; + } + const char *name = synctex_scanner_get_name(d->m_synctex_scanner, synctex_node_tag(node)); + + return new Okular::SourceReference(QFile::decodeName(name), line, col); + } + } + return nullptr; +} + +Document::PrintingType Document::printingSupport() const +{ + if (d->m_generator) { + if (d->m_generator->hasFeature(Generator::PrintNative)) { + return NativePrinting; + } + +#ifndef Q_OS_WIN + if (d->m_generator->hasFeature(Generator::PrintPostscript)) { + return PostscriptPrinting; + } +#endif + } + + return NoPrinting; +} + +bool Document::supportsPrintToFile() const +{ + return d->m_generator ? d->m_generator->hasFeature(Generator::PrintToFile) : false; +} + +bool Document::print(QPrinter &printer) +{ + return d->m_generator ? d->m_generator->print(printer) : false; +} + +QString Document::printError() const +{ + Okular::Generator::PrintError err = Generator::UnknownPrintError; + if (d->m_generator) { + QMetaObject::invokeMethod(d->m_generator, "printError", Qt::DirectConnection, Q_RETURN_ARG(Okular::Generator::PrintError, err)); + } + Q_ASSERT(err != Generator::NoPrintError); + switch (err) { + case Generator::TemporaryFileOpenPrintError: + return i18n("Could not open a temporary file"); + case Generator::FileConversionPrintError: + return i18n("Print conversion failed"); + case Generator::PrintingProcessCrashPrintError: + return i18n("Printing process crashed"); + case Generator::PrintingProcessStartPrintError: + return i18n("Printing process could not start"); + case Generator::PrintToFilePrintError: + return i18n("Printing to file failed"); + case Generator::InvalidPrinterStatePrintError: + return i18n("Printer was in invalid state"); + case Generator::UnableToFindFilePrintError: + return i18n("Unable to find file to print"); + case Generator::NoFileToPrintError: + return i18n("There was no file to print"); + case Generator::NoBinaryToPrintError: + return i18n("Could not find a suitable binary for printing. Make sure CUPS lpr binary is available"); + case Generator::InvalidPageSizePrintError: + return i18n("The page print size is invalid"); + case Generator::NoPrintError: + return QString(); + case Generator::UnknownPrintError: + return QString(); + } + + return QString(); +} + +QWidget *Document::printConfigurationWidget() const +{ + if (d->m_generator) { + PrintInterface *iface = qobject_cast(d->m_generator); + return iface ? iface->printConfigurationWidget() : nullptr; + } else + return nullptr; +} + +void Document::fillConfigDialog(KConfigDialog *dialog) +{ + if (!dialog) + return; + + // We know it's a BackendConfigDialog, but check anyway + BackendConfigDialog *bcd = dynamic_cast(dialog); + if (!bcd) + return; + + // ensure that we have all the generators with settings loaded + QVector offers = DocumentPrivate::configurableGenerators(); + d->loadServiceList(offers); + + // We want the generators to be sorted by name so let's fill in a QMap + // this sorts by internal id which is not awesome, but at least the sorting + // is stable between runs that before it wasn't + QMap sortedGenerators; + QHash::iterator it = d->m_loadedGenerators.begin(); + QHash::iterator itEnd = d->m_loadedGenerators.end(); + for (; it != itEnd; ++it) { + sortedGenerators.insert(it.key(), it.value()); + } + + bool pagesAdded = false; + QMap::iterator sit = sortedGenerators.begin(); + QMap::iterator sitEnd = sortedGenerators.end(); + for (; sit != sitEnd; ++sit) { + Okular::ConfigInterface *iface = d->generatorConfig(sit.value()); + if (iface) { + iface->addPages(dialog); + pagesAdded = true; + + if (sit.value().generator == d->m_generator) { + const int rowCount = bcd->thePageWidget()->model()->rowCount(); + KPageView *view = bcd->thePageWidget(); + view->setCurrentPage(view->model()->index(rowCount - 1, 0)); + } + } + } + if (pagesAdded) { + connect(dialog, &KConfigDialog::settingsChanged, this, [this] { d->slotGeneratorConfigChanged(); }); + } +} + +QVector DocumentPrivate::configurableGenerators() +{ + const QVector available = availableGenerators(); + QVector result; + for (const KPluginMetaData &md : available) { + if (md.rawData()[QStringLiteral("X-KDE-okularHasInternalSettings")].toBool()) { + result << md; + } + } + return result; +} + +KPluginMetaData Document::generatorInfo() const +{ + if (!d->m_generator) + return KPluginMetaData(); + + auto genIt = d->m_loadedGenerators.constFind(d->m_generatorName); + Q_ASSERT(genIt != d->m_loadedGenerators.constEnd()); + return genIt.value().metadata; +} + +int Document::configurableGenerators() const +{ + return DocumentPrivate::configurableGenerators().size(); +} + +QStringList Document::supportedMimeTypes() const +{ + // TODO: make it a static member of DocumentPrivate? + QStringList result = d->m_supportedMimeTypes; + if (result.isEmpty()) { + const QVector available = DocumentPrivate::availableGenerators(); + for (const KPluginMetaData &md : available) { + result << md.mimeTypes(); + } + + // Remove duplicate mimetypes represented by different names + QMimeDatabase mimeDatabase; + QSet uniqueMimetypes; + for (const QString &mimeName : qAsConst(result)) { + uniqueMimetypes.insert(mimeDatabase.mimeTypeForName(mimeName)); + } + result.clear(); + for (const QMimeType &mimeType : uniqueMimetypes) { + result.append(mimeType.name()); + } + + // Add the Okular archive mimetype + result << QStringLiteral("application/vnd.kde.okular-archive"); + + // Sorting by mimetype name doesn't make a ton of sense, + // but ensures that the list is ordered the same way every time + std::sort(result.begin(), result.end()); + + d->m_supportedMimeTypes = result; + } + return result; +} + +bool Document::canSwapBackingFile() const +{ + if (!d->m_generator) + return false; + + return d->m_generator->hasFeature(Generator::SwapBackingFile); +} + +bool Document::swapBackingFile(const QString &newFileName, const QUrl &url) +{ + if (!d->m_generator) + return false; + + if (!d->m_generator->hasFeature(Generator::SwapBackingFile)) + return false; + + // Save metadata about the file we're about to close + d->saveDocumentInfo(); + + d->clearAndWaitForRequests(); + + qCDebug(OkularCoreDebug) << "Swapping backing file to" << newFileName; + QVector newPagesVector; + Generator::SwapBackingFileResult result = d->m_generator->swapBackingFile(newFileName, newPagesVector); + if (result != Generator::SwapBackingFileError) { + QLinkedList rectsToDelete; + QLinkedList annotationsToDelete; + QSet pagePrivatesToDelete; + + if (result == Generator::SwapBackingFileReloadInternalData) { + // Here we need to replace everything that the old generator + // had created with what the new one has without making it look like + // we have actually closed and opened the file again + + // Simple sanity check + if (newPagesVector.count() != d->m_pagesVector.count()) + return false; + + // Update the undo stack contents + for (int i = 0; i < d->m_undoStack->count(); ++i) { + // Trust me on the const_cast ^_^ + QUndoCommand *uc = const_cast(d->m_undoStack->command(i)); + if (OkularUndoCommand *ouc = dynamic_cast(uc)) { + const bool success = ouc->refreshInternalPageReferences(newPagesVector); + if (!success) { + qWarning() << "Document::swapBackingFile: refreshInternalPageReferences failed" << ouc; + return false; + } + } else { + qWarning() << "Document::swapBackingFile: Unhandled undo command" << uc; + return false; + } + } + + for (int i = 0; i < d->m_pagesVector.count(); ++i) { + // switch the PagePrivate* from newPage to oldPage + // this way everyone still holding Page* doesn't get + // disturbed by it + Page *oldPage = d->m_pagesVector[i]; + Page *newPage = newPagesVector[i]; + newPage->d->adoptGeneratedContents(oldPage->d); + + pagePrivatesToDelete << oldPage->d; + oldPage->d = newPage->d; + oldPage->d->m_page = oldPage; + oldPage->d->m_doc = d; + newPage->d = nullptr; + + annotationsToDelete << oldPage->m_annotations; + rectsToDelete << oldPage->m_rects; + oldPage->m_annotations = newPage->m_annotations; + oldPage->m_rects = newPage->m_rects; + } + qDeleteAll(newPagesVector); + } + + d->m_url = url; + d->m_docFileName = newFileName; + d->updateMetadataXmlNameAndDocSize(); + d->m_bookmarkManager->setUrl(d->m_url); + d->m_documentInfo = DocumentInfo(); + d->m_documentInfoAskedKeys.clear(); + + if (d->m_synctex_scanner) { + synctex_scanner_free(d->m_synctex_scanner); + d->m_synctex_scanner = synctex_scanner_new_with_output_file(QFile::encodeName(newFileName).constData(), nullptr, 1); + if (!d->m_synctex_scanner && QFile::exists(newFileName + QLatin1String("sync"))) { + d->loadSyncFile(newFileName); + } + } + + foreachObserver(notifySetup(d->m_pagesVector, DocumentObserver::UrlChanged)); + + qDeleteAll(annotationsToDelete); + qDeleteAll(rectsToDelete); + qDeleteAll(pagePrivatesToDelete); + + return true; + } else { + return false; + } +} + +bool Document::swapBackingFileArchive(const QString &newFileName, const QUrl &url) +{ + qCDebug(OkularCoreDebug) << "Swapping backing archive to" << newFileName; + + ArchiveData *newArchive = DocumentPrivate::unpackDocumentArchive(newFileName); + if (!newArchive) + return false; + + const QString tempFileName = newArchive->document.fileName(); + + const bool success = swapBackingFile(tempFileName, url); + + if (success) { + delete d->m_archiveData; + d->m_archiveData = newArchive; + } + + return success; +} + +void Document::setHistoryClean(bool clean) +{ + if (clean) + d->m_undoStack->setClean(); + else + d->m_undoStack->resetClean(); +} + +bool Document::canSaveChanges() const +{ + if (!d->m_generator) + return false; + Q_ASSERT(!d->m_generatorName.isEmpty()); + + QHash::iterator genIt = d->m_loadedGenerators.find(d->m_generatorName); + Q_ASSERT(genIt != d->m_loadedGenerators.end()); + SaveInterface *saveIface = d->generatorSave(genIt.value()); + if (!saveIface) + return false; + + return saveIface->supportsOption(SaveInterface::SaveChanges); +} + +bool Document::canSaveChanges(SaveCapability cap) const +{ + switch (cap) { + case SaveFormsCapability: + /* Assume that if the generator supports saving, forms can be saved. + * We have no means to actually query the generator at the moment + * TODO: Add some method to query the generator in SaveInterface */ + return canSaveChanges(); + + case SaveAnnotationsCapability: + return d->canAddAnnotationsNatively(); + } + + return false; +} + +bool Document::saveChanges(const QString &fileName) +{ + QString errorText; + return saveChanges(fileName, &errorText); +} + +bool Document::saveChanges(const QString &fileName, QString *errorText) +{ + if (!d->m_generator || fileName.isEmpty()) + return false; + Q_ASSERT(!d->m_generatorName.isEmpty()); + + QHash::iterator genIt = d->m_loadedGenerators.find(d->m_generatorName); + Q_ASSERT(genIt != d->m_loadedGenerators.end()); + SaveInterface *saveIface = d->generatorSave(genIt.value()); + if (!saveIface || !saveIface->supportsOption(SaveInterface::SaveChanges)) + return false; + + return saveIface->save(fileName, SaveInterface::SaveChanges, errorText); +} + +void Document::registerView(View *view) +{ + if (!view) + return; + + Document *viewDoc = view->viewDocument(); + if (viewDoc) { + // check if already registered for this document + if (viewDoc == this) + return; + + viewDoc->unregisterView(view); + } + + d->m_views.insert(view); + view->d_func()->document = d; +} + +void Document::unregisterView(View *view) +{ + if (!view) + return; + + Document *viewDoc = view->viewDocument(); + if (!viewDoc || viewDoc != this) + return; + + view->d_func()->document = nullptr; + d->m_views.remove(view); +} + +QByteArray Document::fontData(const FontInfo &font) const +{ + QByteArray result; + + if (d->m_generator) { + // clang-format off + // Otherwise the Q_ARG(QByteArray* gets broken + QMetaObject::invokeMethod(d->m_generator, "requestFontData", Qt::DirectConnection, Q_ARG(Okular::FontInfo, font), Q_ARG(QByteArray*, &result)); + // clang-format on + } + + return result; +} + +ArchiveData *DocumentPrivate::unpackDocumentArchive(const QString &archivePath) +{ + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(archivePath, QMimeDatabase::MatchExtension); + if (!mime.inherits(QStringLiteral("application/vnd.kde.okular-archive"))) + return nullptr; + + KZip okularArchive(archivePath); + if (!okularArchive.open(QIODevice::ReadOnly)) + return nullptr; + + const KArchiveDirectory *mainDir = okularArchive.directory(); + + // Check the archive doesn't have folders, we don't create them when saving the archive + // and folders mean paths and paths mean path traversal issues + const QStringList mainDirEntries = mainDir->entries(); + for (const QString &entry : mainDirEntries) { + if (mainDir->entry(entry)->isDirectory()) { + qWarning() << "Warning: Found a directory inside" << archivePath << " - Okular does not create files like that so it is most probably forged."; + return nullptr; + } + } + + const KArchiveEntry *mainEntry = mainDir->entry(QStringLiteral("content.xml")); + if (!mainEntry || !mainEntry->isFile()) + return nullptr; + + std::unique_ptr mainEntryDevice(static_cast(mainEntry)->createDevice()); + QDomDocument doc; + if (!doc.setContent(mainEntryDevice.get())) + return nullptr; + mainEntryDevice.reset(); + + QDomElement root = doc.documentElement(); + if (root.tagName() != QLatin1String("OkularArchive")) + return nullptr; + + QString documentFileName; + QString metadataFileName; + QDomElement el = root.firstChild().toElement(); + for (; !el.isNull(); el = el.nextSibling().toElement()) { + if (el.tagName() == QLatin1String("Files")) { + QDomElement fileEl = el.firstChild().toElement(); + for (; !fileEl.isNull(); fileEl = fileEl.nextSibling().toElement()) { + if (fileEl.tagName() == QLatin1String("DocumentFileName")) + documentFileName = fileEl.text(); + else if (fileEl.tagName() == QLatin1String("MetadataFileName")) + metadataFileName = fileEl.text(); + } + } + } + if (documentFileName.isEmpty()) + return nullptr; + + const KArchiveEntry *docEntry = mainDir->entry(documentFileName); + if (!docEntry || !docEntry->isFile()) + return nullptr; + + std::unique_ptr archiveData(new ArchiveData()); + const int dotPos = documentFileName.indexOf(QLatin1Char('.')); + if (dotPos != -1) + archiveData->document.setFileTemplate(QDir::tempPath() + QLatin1String("/okular_XXXXXX") + documentFileName.mid(dotPos)); + if (!archiveData->document.open()) + return nullptr; + + archiveData->originalFileName = documentFileName; + + { + std::unique_ptr docEntryDevice(static_cast(docEntry)->createDevice()); + copyQIODevice(docEntryDevice.get(), &archiveData->document); + archiveData->document.close(); + } + + const KArchiveEntry *metadataEntry = mainDir->entry(metadataFileName); + if (metadataEntry && metadataEntry->isFile()) { + std::unique_ptr metadataEntryDevice(static_cast(metadataEntry)->createDevice()); + archiveData->metadataFile.setFileTemplate(QDir::tempPath() + QLatin1String("/okular_XXXXXX.xml")); + if (archiveData->metadataFile.open()) { + copyQIODevice(metadataEntryDevice.get(), &archiveData->metadataFile); + archiveData->metadataFile.close(); + } + } + + return archiveData.release(); +} + +Document::OpenResult Document::openDocumentArchive(const QString &docFile, const QUrl &url, const QString &password) +{ + d->m_archiveData = DocumentPrivate::unpackDocumentArchive(docFile); + if (!d->m_archiveData) + return OpenError; + + const QString tempFileName = d->m_archiveData->document.fileName(); + QMimeDatabase db; + const QMimeType docMime = db.mimeTypeForFile(tempFileName, QMimeDatabase::MatchExtension); + const OpenResult ret = openDocument(tempFileName, url, docMime, password); + + if (ret != OpenSuccess) { + delete d->m_archiveData; + d->m_archiveData = nullptr; + } + + return ret; +} + +bool Document::saveDocumentArchive(const QString &fileName) +{ + if (!d->m_generator) + return false; + + /* If we opened an archive, use the name of original file (eg foo.pdf) + * instead of the archive's one (eg foo.okular) */ + QString docFileName = d->m_archiveData ? d->m_archiveData->originalFileName : d->m_url.fileName(); + if (docFileName == QLatin1String("-")) + return false; + + QString docPath = d->m_docFileName; + const QFileInfo fi(docPath); + if (fi.isSymLink()) + docPath = fi.symLinkTarget(); + + KZip okularArchive(fileName); + if (!okularArchive.open(QIODevice::WriteOnly)) + return false; + + const KUser user; +#ifndef Q_OS_WIN + const KUserGroup userGroup(user.groupId()); +#else + const KUserGroup userGroup(QString("")); +#endif + + QDomDocument contentDoc(QStringLiteral("OkularArchive")); + QDomProcessingInstruction xmlPi = contentDoc.createProcessingInstruction(QStringLiteral("xml"), QStringLiteral("version=\"1.0\" encoding=\"utf-8\"")); + contentDoc.appendChild(xmlPi); + QDomElement root = contentDoc.createElement(QStringLiteral("OkularArchive")); + contentDoc.appendChild(root); + + QDomElement filesNode = contentDoc.createElement(QStringLiteral("Files")); + root.appendChild(filesNode); + + QDomElement fileNameNode = contentDoc.createElement(QStringLiteral("DocumentFileName")); + filesNode.appendChild(fileNameNode); + fileNameNode.appendChild(contentDoc.createTextNode(docFileName)); + + QDomElement metadataFileNameNode = contentDoc.createElement(QStringLiteral("MetadataFileName")); + filesNode.appendChild(metadataFileNameNode); + metadataFileNameNode.appendChild(contentDoc.createTextNode(QStringLiteral("metadata.xml"))); + + // If the generator can save annotations natively, do it + QTemporaryFile modifiedFile; + bool annotationsSavedNatively = false; + bool formsSavedNatively = false; + if (d->canAddAnnotationsNatively() || canSaveChanges(SaveFormsCapability)) { + if (!modifiedFile.open()) + return false; + + const QString modifiedFileName = modifiedFile.fileName(); + + modifiedFile.close(); // We're only interested in the file name + + QString errorText; + if (saveChanges(modifiedFileName, &errorText)) { + docPath = modifiedFileName; // Save this instead of the original file + annotationsSavedNatively = d->canAddAnnotationsNatively(); + formsSavedNatively = canSaveChanges(SaveFormsCapability); + } else { + qCWarning(OkularCoreDebug) << "saveChanges failed: " << errorText; + qCDebug(OkularCoreDebug) << "Falling back to saving a copy of the original file"; + } + } + + PageItems saveWhat = None; + if (!annotationsSavedNatively) + saveWhat |= AnnotationPageItems; + if (!formsSavedNatively) + saveWhat |= FormFieldPageItems; + + QTemporaryFile metadataFile; + if (!d->savePageDocumentInfo(&metadataFile, saveWhat)) + return false; + + const QByteArray contentDocXml = contentDoc.toByteArray(); + const mode_t perm = 0100644; + okularArchive.writeFile(QStringLiteral("content.xml"), contentDocXml, perm, user.loginName(), userGroup.name()); + + okularArchive.addLocalFile(docPath, docFileName); + okularArchive.addLocalFile(metadataFile.fileName(), QStringLiteral("metadata.xml")); + + if (!okularArchive.close()) + return false; + + return true; +} + +bool Document::extractArchivedFile(const QString &destFileName) +{ + if (!d->m_archiveData) + return false; + + // Remove existing file, if present (QFile::copy doesn't overwrite by itself) + QFile::remove(destFileName); + + return d->m_archiveData->document.copy(destFileName); +} + +QPrinter::Orientation Document::orientation() const +{ + double width, height; + int landscape, portrait; + const Okular::Page *currentPage; + + // if some pages are landscape and others are not, the most common wins, as + // QPrinter does not accept a per-page setting + landscape = 0; + portrait = 0; + for (uint i = 0; i < pages(); i++) { + currentPage = page(i); + width = currentPage->width(); + height = currentPage->height(); + if (currentPage->orientation() == Okular::Rotation90 || currentPage->orientation() == Okular::Rotation270) + qSwap(width, height); + if (width > height) + landscape++; + else + portrait++; + } + return (landscape > portrait) ? QPrinter::Landscape : QPrinter::Portrait; +} + +void Document::setAnnotationEditingEnabled(bool enable) +{ + d->m_annotationEditingEnabled = enable; + foreachObserver(notifySetup(d->m_pagesVector, 0)); +} + +void Document::walletDataForFile(const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey) const +{ + if (d->m_generator) { + d->m_generator->walletDataForFile(fileName, walletName, walletFolder, walletKey); + } else if (d->m_walletGenerator) { + d->m_walletGenerator->walletDataForFile(fileName, walletName, walletFolder, walletKey); + } +} + +bool Document::isDocdataMigrationNeeded() const +{ + return d->m_docdataMigrationNeeded; +} + +void Document::docdataMigrationDone() +{ + if (d->m_docdataMigrationNeeded) { + d->m_docdataMigrationNeeded = false; + foreachObserver(notifySetup(d->m_pagesVector, 0)); + } +} + +QAbstractItemModel *Document::layersModel() const +{ + return d->m_generator ? d->m_generator->layersModel() : nullptr; +} + +QString Document::openError() const +{ + return d->m_openError; +} + +QByteArray Document::requestSignedRevisionData(const Okular::SignatureInfo &info) +{ + QFile f(d->m_docFileName); + if (!f.open(QIODevice::ReadOnly)) { + KMessageBox::error(nullptr, i18n("Could not open '%1'. File does not exist", d->m_docFileName)); + return {}; + } + + const QList byteRange = info.signedRangeBounds(); + f.seek(byteRange.first()); + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream << f.read(byteRange.last() - byteRange.first()); + f.close(); + + return data; +} + +void Document::refreshPixmaps(int pageNumber) +{ + d->refreshPixmaps(pageNumber); +} + +void DocumentPrivate::executeScript(const QString &function) +{ + if (!m_scripter) + m_scripter = new Scripter(this); + m_scripter->execute(JavaScript, function); +} + +void DocumentPrivate::requestDone(PixmapRequest *req) +{ + if (!req) + return; + + if (!m_generator || m_closingLoop) { + m_pixmapRequestsMutex.lock(); + m_executingPixmapRequests.removeAll(req); + m_pixmapRequestsMutex.unlock(); + delete req; + if (m_closingLoop) + m_closingLoop->exit(); + return; + } + +#ifndef NDEBUG + if (!m_generator->canGeneratePixmap()) + qCDebug(OkularCoreDebug) << "requestDone with generator not in READY state."; +#endif + + if (!req->shouldAbortRender()) { + // [MEM] 1.1 find and remove a previous entry for the same page and id + QLinkedList::iterator aIt = m_allocatedPixmaps.begin(); + QLinkedList::iterator aEnd = m_allocatedPixmaps.end(); + for (; aIt != aEnd; ++aIt) + if ((*aIt)->page == req->pageNumber() && (*aIt)->observer == req->observer()) { + AllocatedPixmap *p = *aIt; + m_allocatedPixmaps.erase(aIt); + m_allocatedPixmapsTotalMemory -= p->memory; + delete p; + break; + } + + DocumentObserver *observer = req->observer(); + if (m_observers.contains(observer)) { + // [MEM] 1.2 append memory allocation descriptor to the FIFO + qulonglong memoryBytes = 0; + const TilesManager *tm = req->d->tilesManager(); + if (tm) + memoryBytes = tm->totalMemory(); + else + memoryBytes = 4 * req->width() * req->height(); + + AllocatedPixmap *memoryPage = new AllocatedPixmap(req->observer(), req->pageNumber(), memoryBytes); + m_allocatedPixmaps.append(memoryPage); + m_allocatedPixmapsTotalMemory += memoryBytes; + + // 2. notify an observer that its pixmap changed + observer->notifyPageChanged(req->pageNumber(), DocumentObserver::Pixmap); + } +#ifndef NDEBUG + else + qCWarning(OkularCoreDebug) << "Receiving a done request for the defunct observer" << observer; +#endif + } + + // 3. delete request + m_pixmapRequestsMutex.lock(); + m_executingPixmapRequests.removeAll(req); + m_pixmapRequestsMutex.unlock(); + delete req; + + // 4. start a new generation if some is pending + m_pixmapRequestsMutex.lock(); + bool hasPixmaps = !m_pixmapRequestsStack.isEmpty(); + m_pixmapRequestsMutex.unlock(); + if (hasPixmaps) + sendGeneratorPixmapRequest(); +} + +void DocumentPrivate::setPageBoundingBox(int page, const NormalizedRect &boundingBox) +{ + Page *kp = m_pagesVector[page]; + if (!m_generator || !kp) + return; + + if (kp->boundingBox() == boundingBox) + return; + kp->setBoundingBox(boundingBox); + + // notify observers about the change + foreachObserverD(notifyPageChanged(page, DocumentObserver::BoundingBox)); + + // TODO: For generators that generate the bbox by pixmap scanning, if the first generated pixmap is very small, the bounding box will forever be inaccurate. + // TODO: Crop computation should also consider annotations, actions, etc. to make sure they're not cropped away. + // TODO: Help compute bounding box for generators that create a QPixmap without a QImage, like text and plucker. + // TODO: Don't compute the bounding box if no one needs it (e.g., Trim Borders is off). +} + +void DocumentPrivate::calculateMaxTextPages() +{ + int multipliers = qMax(1, qRound(getTotalMemory() / 536870912.0)); // 512 MB + switch (SettingsCore::memoryLevel()) { + case SettingsCore::EnumMemoryLevel::Low: + m_maxAllocatedTextPages = multipliers * 2; + break; + + case SettingsCore::EnumMemoryLevel::Normal: + m_maxAllocatedTextPages = multipliers * 50; + break; + + case SettingsCore::EnumMemoryLevel::Aggressive: + m_maxAllocatedTextPages = multipliers * 250; + break; + + case SettingsCore::EnumMemoryLevel::Greedy: + m_maxAllocatedTextPages = multipliers * 1250; + break; + } +} + +void DocumentPrivate::textGenerationDone(Page *page) +{ + if (!m_pageController) + return; + + // 1. If we reached the cache limit, delete the first text page from the fifo + if (m_allocatedTextPagesFifo.size() == m_maxAllocatedTextPages) { + int pageToKick = m_allocatedTextPagesFifo.takeFirst(); + if (pageToKick != page->number()) // this should never happen but better be safe than sorry + { + m_pagesVector.at(pageToKick)->setTextPage(nullptr); // deletes the textpage + } + } + + // 2. Add the page to the fifo of generated text pages + m_allocatedTextPagesFifo.append(page->number()); +} + +void Document::setRotation(int r) +{ + d->setRotationInternal(r, true); +} + +void DocumentPrivate::setRotationInternal(int r, bool notify) +{ + Rotation rotation = (Rotation)r; + if (!m_generator || (m_rotation == rotation)) + return; + + // tell the pages to rotate + QVector::const_iterator pIt = m_pagesVector.constBegin(); + QVector::const_iterator pEnd = m_pagesVector.constEnd(); + for (; pIt != pEnd; ++pIt) + (*pIt)->d->rotateAt(rotation); + if (notify) { + // notify the generator that the current rotation has changed + m_generator->rotationChanged(rotation, m_rotation); + } + // set the new rotation + m_rotation = rotation; + + if (notify) { + foreachObserverD(notifySetup(m_pagesVector, DocumentObserver::NewLayoutForPages)); + foreachObserverD(notifyContentsCleared(DocumentObserver::Pixmap | DocumentObserver::Highlights | DocumentObserver::Annotations)); + } + qCDebug(OkularCoreDebug) << "Rotated:" << r; +} + +void Document::setPageSize(const PageSize &size) +{ + if (!d->m_generator || !d->m_generator->hasFeature(Generator::PageSizes)) + return; + + if (d->m_pageSizes.isEmpty()) + d->m_pageSizes = d->m_generator->pageSizes(); + int sizeid = d->m_pageSizes.indexOf(size); + if (sizeid == -1) + return; + + // tell the pages to change size + QVector::const_iterator pIt = d->m_pagesVector.constBegin(); + QVector::const_iterator pEnd = d->m_pagesVector.constEnd(); + for (; pIt != pEnd; ++pIt) + (*pIt)->d->changeSize(size); + // clear 'memory allocation' descriptors + qDeleteAll(d->m_allocatedPixmaps); + d->m_allocatedPixmaps.clear(); + d->m_allocatedPixmapsTotalMemory = 0; + // notify the generator that the current page size has changed + d->m_generator->pageSizeChanged(size, d->m_pageSize); + // set the new page size + d->m_pageSize = size; + + foreachObserver(notifySetup(d->m_pagesVector, DocumentObserver::NewLayoutForPages)); + foreachObserver(notifyContentsCleared(DocumentObserver::Pixmap | DocumentObserver::Highlights)); + qCDebug(OkularCoreDebug) << "New PageSize id:" << sizeid; +} + +/** DocumentViewport **/ + +DocumentViewport::DocumentViewport(int n) + : pageNumber(n) +{ + // default settings + rePos.enabled = false; + rePos.normalizedX = 0.5; + rePos.normalizedY = 0.0; + rePos.pos = Center; + autoFit.enabled = false; + autoFit.width = false; + autoFit.height = false; +} + +DocumentViewport::DocumentViewport(const QString &xmlDesc) + : pageNumber(-1) +{ + // default settings (maybe overridden below) + rePos.enabled = false; + rePos.normalizedX = 0.5; + rePos.normalizedY = 0.0; + rePos.pos = Center; + autoFit.enabled = false; + autoFit.width = false; + autoFit.height = false; + + // check for string presence + if (xmlDesc.isEmpty()) + return; + + // decode the string + bool ok; + int field = 0; + QString token = xmlDesc.section(QLatin1Char(';'), field, field); + while (!token.isEmpty()) { + // decode the current token + if (field == 0) { + pageNumber = token.toInt(&ok); + if (!ok) + return; + } else if (token.startsWith(QLatin1String("C1"))) { + rePos.enabled = true; + rePos.normalizedX = token.section(QLatin1Char(':'), 1, 1).toDouble(); + rePos.normalizedY = token.section(QLatin1Char(':'), 2, 2).toDouble(); + rePos.pos = Center; + } else if (token.startsWith(QLatin1String("C2"))) { + rePos.enabled = true; + rePos.normalizedX = token.section(QLatin1Char(':'), 1, 1).toDouble(); + rePos.normalizedY = token.section(QLatin1Char(':'), 2, 2).toDouble(); + if (token.section(QLatin1Char(':'), 3, 3).toInt() == 1) + rePos.pos = Center; + else + rePos.pos = TopLeft; + } else if (token.startsWith(QLatin1String("AF1"))) { + autoFit.enabled = true; + autoFit.width = token.section(QLatin1Char(':'), 1, 1) == QLatin1String("T"); + autoFit.height = token.section(QLatin1Char(':'), 2, 2) == QLatin1String("T"); + } + // proceed tokenizing string + field++; + token = xmlDesc.section(QLatin1Char(';'), field, field); + } +} + +QString DocumentViewport::toString() const +{ + // start string with page number + QString s = QString::number(pageNumber); + // if has center coordinates, save them on string + if (rePos.enabled) + s += QStringLiteral(";C2:") + QString::number(rePos.normalizedX) + QLatin1Char(':') + QString::number(rePos.normalizedY) + QLatin1Char(':') + QString::number(rePos.pos); + // if has autofit enabled, save its state on string + if (autoFit.enabled) + s += QStringLiteral(";AF1:") + (autoFit.width ? QLatin1Char('T') : QLatin1Char('F')) + QLatin1Char(':') + (autoFit.height ? QLatin1Char('T') : QLatin1Char('F')); + return s; +} + +bool DocumentViewport::isValid() const +{ + return pageNumber >= 0; +} + +bool DocumentViewport::operator==(const DocumentViewport &other) const +{ + bool equal = (pageNumber == other.pageNumber) && (rePos.enabled == other.rePos.enabled) && (autoFit.enabled == other.autoFit.enabled); + if (!equal) + return false; + if (rePos.enabled && ((rePos.normalizedX != other.rePos.normalizedX) || (rePos.normalizedY != other.rePos.normalizedY) || rePos.pos != other.rePos.pos)) + return false; + if (autoFit.enabled && ((autoFit.width != other.autoFit.width) || (autoFit.height != other.autoFit.height))) + return false; + return true; +} + +bool DocumentViewport::operator<(const DocumentViewport &other) const +{ + // TODO: Check autoFit and Position + + if (pageNumber != other.pageNumber) + return pageNumber < other.pageNumber; + + if (!rePos.enabled && other.rePos.enabled) + return true; + + if (!other.rePos.enabled) + return false; + + if (rePos.normalizedY != other.rePos.normalizedY) + return rePos.normalizedY < other.rePos.normalizedY; + + return rePos.normalizedX < other.rePos.normalizedX; +} + +/** DocumentInfo **/ + +DocumentInfo::DocumentInfo() + : d(new DocumentInfoPrivate()) +{ +} + +DocumentInfo::DocumentInfo(const DocumentInfo &info) + : d(new DocumentInfoPrivate()) +{ + *this = info; +} + +DocumentInfo &DocumentInfo::operator=(const DocumentInfo &info) +{ + if (this != &info) { + d->values = info.d->values; + d->titles = info.d->titles; + } + return *this; +} + +DocumentInfo::~DocumentInfo() +{ + delete d; +} + +void DocumentInfo::set(const QString &key, const QString &value, const QString &title) +{ + d->values[key] = value; + d->titles[key] = title; +} + +void DocumentInfo::set(Key key, const QString &value) +{ + d->values[getKeyString(key)] = value; +} + +QStringList DocumentInfo::keys() const +{ + return d->values.keys(); +} + +QString DocumentInfo::get(Key key) const +{ + return get(getKeyString(key)); +} + +QString DocumentInfo::get(const QString &key) const +{ + return d->values[key]; +} + +QString DocumentInfo::getKeyString(Key key) // const +{ + switch (key) { + case Title: + return QStringLiteral("title"); + break; + case Subject: + return QStringLiteral("subject"); + break; + case Description: + return QStringLiteral("description"); + break; + case Author: + return QStringLiteral("author"); + break; + case Creator: + return QStringLiteral("creator"); + break; + case Producer: + return QStringLiteral("producer"); + break; + case Copyright: + return QStringLiteral("copyright"); + break; + case Pages: + return QStringLiteral("pages"); + break; + case CreationDate: + return QStringLiteral("creationDate"); + break; + case ModificationDate: + return QStringLiteral("modificationDate"); + break; + case MimeType: + return QStringLiteral("mimeType"); + break; + case Category: + return QStringLiteral("category"); + break; + case Keywords: + return QStringLiteral("keywords"); + break; + case FilePath: + return QStringLiteral("filePath"); + break; + case DocumentSize: + return QStringLiteral("documentSize"); + break; + case PagesSize: + return QStringLiteral("pageSize"); + break; + default: + qCWarning(OkularCoreDebug) << "Unknown" << key; + return QString(); + break; + } +} + +DocumentInfo::Key DocumentInfo::getKeyFromString(const QString &key) // const +{ + if (key == QLatin1String("title")) + return Title; + else if (key == QLatin1String("subject")) + return Subject; + else if (key == QLatin1String("description")) + return Description; + else if (key == QLatin1String("author")) + return Author; + else if (key == QLatin1String("creator")) + return Creator; + else if (key == QLatin1String("producer")) + return Producer; + else if (key == QLatin1String("copyright")) + return Copyright; + else if (key == QLatin1String("pages")) + return Pages; + else if (key == QLatin1String("creationDate")) + return CreationDate; + else if (key == QLatin1String("modificationDate")) + return ModificationDate; + else if (key == QLatin1String("mimeType")) + return MimeType; + else if (key == QLatin1String("category")) + return Category; + else if (key == QLatin1String("keywords")) + return Keywords; + else if (key == QLatin1String("filePath")) + return FilePath; + else if (key == QLatin1String("documentSize")) + return DocumentSize; + else if (key == QLatin1String("pageSize")) + return PagesSize; + else + return Invalid; +} + +QString DocumentInfo::getKeyTitle(Key key) // const +{ + switch (key) { + case Title: + return i18n("Title"); + break; + case Subject: + return i18n("Subject"); + break; + case Description: + return i18n("Description"); + break; + case Author: + return i18n("Author"); + break; + case Creator: + return i18n("Creator"); + break; + case Producer: + return i18n("Producer"); + break; + case Copyright: + return i18n("Copyright"); + break; + case Pages: + return i18n("Pages"); + break; + case CreationDate: + return i18n("Created"); + break; + case ModificationDate: + return i18n("Modified"); + break; + case MimeType: + return i18n("Mime Type"); + break; + case Category: + return i18n("Category"); + break; + case Keywords: + return i18n("Keywords"); + break; + case FilePath: + return i18n("File Path"); + break; + case DocumentSize: + return i18n("File Size"); + break; + case PagesSize: + return i18n("Page Size"); + break; + default: + return QString(); + break; + } +} + +QString DocumentInfo::getKeyTitle(const QString &key) const +{ + QString title = getKeyTitle(getKeyFromString(key)); + if (title.isEmpty()) + title = d->titles[key]; + return title; +} + +/** DocumentSynopsis **/ + +DocumentSynopsis::DocumentSynopsis() + : QDomDocument(QStringLiteral("DocumentSynopsis")) +{ + // void implementation, only subclassed for naming +} + +DocumentSynopsis::DocumentSynopsis(const QDomDocument &document) + : QDomDocument(document) +{ +} + +/** EmbeddedFile **/ + +EmbeddedFile::EmbeddedFile() +{ +} + +EmbeddedFile::~EmbeddedFile() +{ +} + +VisiblePageRect::VisiblePageRect(int page, const NormalizedRect &rectangle) + : pageNumber(page) + , rect(rectangle) +{ +} + +#undef foreachObserver +#undef foreachObserverD + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/document.h b/core/document.h new file mode 100644 index 0000000..d2bfa2b --- /dev/null +++ b/core/document.h @@ -0,0 +1,1470 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2008 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_DOCUMENT_H_ +#define _OKULAR_DOCUMENT_H_ + +#include "area.h" +#include "global.h" +#include "okularcore_export.h" +#include "pagesize.h" + +#include +#include +#include +#include +#include + +#include +#include + +class KConfigDialog; +class KPluginMetaData; +class KXMLGUIClient; +class DocumentItem; +class QAbstractItemModel; + +namespace Okular +{ +class Annotation; +class BookmarkManager; +class DocumentInfoPrivate; +class DocumentObserver; +class DocumentPrivate; +class DocumentSynopsis; +class DocumentViewport; +class EmbeddedFile; +class ExportFormat; +class FontInfo; +class FormField; +class FormFieldText; +class FormFieldButton; +class FormFieldChoice; +class Generator; +class Action; +class MovieAction; +class Page; +class PixmapRequest; +class RenditionAction; +class SourceReference; +class View; +class VisiblePageRect; +class SignatureInfo; + +/** IDs for seaches. Globally defined here. **/ +#define PART_SEARCH_ID 1 +#define PAGEVIEW_SEARCH_ID 2 +#define SW_SEARCH_ID 3 +#define PRESENTATION_SEARCH_ID 4 + +/** + * The DocumentInfo structure can be filled in by generators to display + * metadata about the currently opened file. + */ +class OKULARCORE_EXPORT DocumentInfo +{ + friend class Document; + +public: + /** + * The list of predefined keys. + */ + enum Key { + Title, ///< The title of the document + Subject, ///< The subject of the document + Description, ///< The description of the document + Author, ///< The author of the document + Creator, ///< The creator of the document (this can be different from the author) + Producer, ///< The producer of the document (e.g. some software) + Copyright, ///< The copyright of the document + Pages, ///< The number of pages of the document + CreationDate, ///< The date of creation of the document + ModificationDate, ///< The date of last modification of the document + MimeType, ///< The mime type of the document + Category, ///< The category of the document + Keywords, ///< The keywords which describe the content of the document + FilePath, ///< The path of the file @since 0.10 (KDE 4.4) + DocumentSize, ///< The size of the document @since 0.10 (KDE 4.4) + PagesSize, ///< The size of the pages (if all pages have the same size) @since 0.10 (KDE 4.4) + CustomKeys, ///< All the custom keys the generator supports @since 0.21 + Invalid ///< An invalid key @since 0.21. It will always be the last element in the enum + }; + + /** + * Creates a new document info. + */ + DocumentInfo(); + DocumentInfo(const DocumentInfo &info); + DocumentInfo &operator=(const DocumentInfo &); + + ~DocumentInfo(); + + /** + * Returns all the keys present in this DocumentInfo + * + * @since 0.21 + */ + QStringList keys() const; + + /** + * Returns the value for a given key or an null string when the + * key doesn't exist. + */ + QString get(Key key) const; + + /** + * Returns the value for a given key or an null string when the + * key doesn't exist. + */ + QString get(const QString &key) const; + + /** + * Sets a value for a custom key. The title should be an i18n'ed + * string, since it's used in the document information dialog. + */ + void set(const QString &key, const QString &value, const QString &title = QString()); + + /** + * Sets a value for a special key. The title should be an i18n'ed + * string, since it's used in the document information dialog. + */ + void set(Key key, const QString &value); + + /** + * Returns the user visible string for the given key + * Takes into account keys added by the set() that takes a QString + * + * @since 0.21 + */ + QString getKeyTitle(const QString &key) const; + + /** + * Returns the internal string for the given key + * @since 0.10 (KDE 4.4) + */ + static QString getKeyString(Key key); + + /** + * Returns the user visible string for the given key + * @since 0.10 (KDE 4.4) + */ + static QString getKeyTitle(Key key); + + /** + * Returns the Key from a string key + * @since 0.21 + */ + static Key getKeyFromString(const QString &key); + +private: + DocumentInfoPrivate *d; +}; + +/** + * @short The Document. Heart of everything. Actions take place here. + * + * The Document is the main object in Okular. All views query the Document to + * get data/properties or even for accessing pages (in a 'const' way). + * + * It is designed to keep it detached from the document type (pdf, ps, you + * name it..) so whenever you want to get some data, it asks its internal + * generators to do the job and return results in a format-independent way. + * + * Apart from the generator (the currently running one) the document stores + * all the Pages ('Page' class) of the current document in a vector and + * notifies all the registered DocumentObservers when some content changes. + * + * For a better understanding of hierarchies @see README.internals.png + * @see DocumentObserver, Page + */ +class OKULARCORE_EXPORT Document : public QObject +{ + Q_OBJECT + +public: + /** + * Creates a new document with the given @p widget as widget to relay GUI things (messageboxes, ...). + */ + explicit Document(QWidget *widget); + + /** + * Destroys the document. + */ + ~Document() override; + + /** + * Describes the result of an open document operation. + * @since 0.20 (KDE 4.14) + */ + enum OpenResult { + OpenSuccess, //< The document was opened successfully + OpenError, //< The document failed to open + OpenNeedsPassword //< The document needs a password to be opened or the one provided is not the correct + }; + + /** + * Opens the document. + * @since 0.20 (KDE 4.14) + */ + OpenResult openDocument(const QString &docFile, const QUrl &url, const QMimeType &mime, const QString &password = QString()); + + /** + * Closes the document. + */ + void closeDocument(); + + /** + * Registers a new @p observer for the document. + */ + void addObserver(DocumentObserver *observer); + + /** + * Unregisters the given @p observer for the document. + */ + void removeObserver(DocumentObserver *observer); + + /** + * Reparses and applies the configuration. + */ + void reparseConfig(); + + /** + * Returns whether the document is currently opened. + */ + bool isOpened() const; + + /** + * Returns the meta data of the document. + */ + DocumentInfo documentInfo() const; + + /** + * Returns the asked set of meta data of the document. The result may contain more + * metadata than the one asked for. + */ + DocumentInfo documentInfo(const QSet &keys) const; + + /** + * Returns the table of content of the document or 0 if no + * table of content is available. + */ + const DocumentSynopsis *documentSynopsis() const; + + /** + * Starts the reading of the information about the fonts in the + * document, if available. + * + * The results as well the end of the reading is notified using the + * signals gotFont(), fontReadingProgress() and fontReadingEnded() + */ + void startFontReading(); + + /** + * Force the termination of the reading of the information about the + * fonts in the document, if running. + */ + void stopFontReading(); + + /** + * Whether the current document can provide information about the + * fonts used in it. + */ + bool canProvideFontInformation() const; + + /** + * Returns the list of embedded files or 0 if no embedded files + * are available. + */ + const QList *embeddedFiles() const; + + /** + * Returns the page object for the given page @p number or 0 + * if the number is out of range. + */ + const Page *page(int number) const; + + /** + * Returns the current viewport of the document. + */ + const DocumentViewport &viewport() const; + + /** + * Sets the list of visible page rectangles. + * @see VisiblePageRect + */ + void setVisiblePageRects(const QVector &visiblePageRects, DocumentObserver *excludeObserver = nullptr); + + /** + * Returns the list of visible page rectangles. + */ + const QVector &visiblePageRects() const; + + /** + * Returns the number of the current page. + */ + uint currentPage() const; + + /** + * Returns the number of pages of the document. + */ + uint pages() const; + + /** + * Returns the url of the currently opened document. + */ + QUrl currentDocument() const; + + /** + * Returns whether the given @p action is allowed in the document. + * @see @ref Permission + */ + bool isAllowed(Permission action) const; + + /** + * Returns whether the document supports searching. + */ + bool supportsSearching() const; + + /** + * Returns whether the document supports the listing of page sizes. + */ + bool supportsPageSizes() const; + + /** + * Returns whether the current document supports tiles + * + * @since 0.16 (KDE 4.10) + */ + bool supportsTiles() const; + + /** + * Returns the list of supported page sizes or an empty list if this + * feature is not available. + * @see supportsPageSizes() + */ + PageSize::List pageSizes() const; + + /** + * Returns whether the document supports the export to ASCII text. + */ + bool canExportToText() const; + + /** + * Exports the document as ASCII text and saves it under @p fileName. + */ + bool exportToText(const QString &fileName) const; + + /** + * Returns the list of supported export formats. + * @see ExportFormat + */ + QList exportFormats() const; + + /** + * Exports the document in the given @p format and saves it under @p fileName. + */ + bool exportTo(const QString &fileName, const ExportFormat &format) const; + + /** + * Returns whether the document history is at the begin. + */ + bool historyAtBegin() const; + + /** + * Returns whether the document history is at the end. + */ + bool historyAtEnd() const; + + /** + * Returns the meta data for the given @p key and @p option or an empty variant + * if the key doesn't exists. + */ + QVariant metaData(const QString &key, const QVariant &option = QVariant()) const; + + /** + * Returns the current rotation of the document. + */ + Rotation rotation() const; + + /** + * If all pages have the same size this method returns it, if the page sizes + * differ an empty size object is returned. + */ + QSizeF allPagesSize() const; + + /** + * Returns the size string for the given @p page or an empty string + * if the page is out of range. + */ + QString pageSizeString(int page) const; + + /** + * Returns the gui client of the generator, if it provides one. + */ + KXMLGUIClient *guiClient(); + + /** + * Sets the current document viewport to the given @p page. + * + * @param page The number of the page. + * @param excludeObserver The observer ids which shouldn't be effected by this change. + * @param smoothMove Whether the move shall be animated smoothly. + */ + void setViewportPage(int page, DocumentObserver *excludeObserver = nullptr, bool smoothMove = false); + + /** + * Sets the current document viewport to the given @p viewport. + * + * @param viewport The document viewport. + * @param excludeObserver The observer which shouldn't be effected by this change. + * @param smoothMove Whether the move shall be animated smoothly. + */ + void setViewport(const DocumentViewport &viewport, DocumentObserver *excludeObserver = nullptr, bool smoothMove = false); + + /** + * Sets the current document viewport to the given @p viewport. + * BCI TODO: merge with setViewport, adding a parameter "bool updateHistory = true" + * + * @param viewport The document viewport. + * @param excludeObserver The observer which shouldn't be effected by this change. + * @param smoothMove Whether the move shall be animated smoothly. + * @param updateHistory Whether to consider the change of viewport for the history navigation + */ + void setViewportWithHistory(const DocumentViewport &viewport, DocumentObserver *excludeObserver = nullptr, bool smoothMove = false, bool updateHistory = true); + + /** + * Sets the current document viewport to the next viewport in the + * viewport history. + */ + void setPrevViewport(); + + /** + * Sets the current document viewport to the previous viewport in the + * viewport history. + */ + void setNextViewport(); + + /** + * Sets the next @p viewport in the viewport history. + */ + void setNextDocumentViewport(const DocumentViewport &viewport); + + /** + * Sets the next @p namedDestination in the viewport history. + * + * @since 0.9 (KDE 4.3) + */ + void setNextDocumentDestination(const QString &namedDestination); + + /** + * Sets the zoom for the current document. + */ + void setZoom(int factor, DocumentObserver *excludeObserver = nullptr); + + /** + * Describes the possible options for the pixmap requests. + */ + enum PixmapRequestFlag { + NoOption = 0, ///< No options + RemoveAllPrevious = 1 ///< Remove all the previous requests, even for non requested page pixmaps + }; + Q_DECLARE_FLAGS(PixmapRequestFlags, PixmapRequestFlag) + + /** + * Sends @p requests for pixmap generation. + * + * The same as requestPixmaps( requests, RemoveAllPrevious ); + */ + void requestPixmaps(const QLinkedList &requests); + + /** + * Sends @p requests for pixmap generation. + * + * @param requests the linked list of requests + * @param reqOptions the options for the request + * + * @since 0.7 (KDE 4.1) + */ + void requestPixmaps(const QLinkedList &requests, PixmapRequestFlags reqOptions); + + /** + * Sends a request for text page generation for the given page @p pageNumber. + */ + void requestTextPage(uint pageNumber); + + /** + * Adds a new @p annotation to the given @p page. + */ + void addPageAnnotation(int page, Annotation *annotation); + + /** + * Tests if the @p annotation can be modified + * + * @since 0.15 (KDE 4.9) + */ + bool canModifyPageAnnotation(const Annotation *annotation) const; + + /** + * Prepares to modify the properties of the given @p annotation. + * Must be called before the annotation's properties are modified + * + * @since 0.17 (KDE 4.11) + */ + void prepareToModifyAnnotationProperties(Annotation *annotation); + + /** + * Modifies the given @p annotation on the given @p page. + * Must be preceded by a call to prepareToModifyAnnotationProperties before + * the annotation's properties are modified + * + * @since 0.17 (KDE 4.11) + */ + void modifyPageAnnotationProperties(int page, Annotation *annotation); + + /** + * Translates the position of the given @p annotation on the given @p page by a distance @p delta in normalized coordinates. + * + * Consecutive translations applied to the same @p annotation are merged together on the undo stack if the + * BeingMoved flag is set on the @p annotation. + * + * @since 0.17 (KDE 4.11) + */ + void translatePageAnnotation(int page, Annotation *annotation, const Okular::NormalizedPoint &delta); + + /** + * Adjusts the position of the top-left and bottom-right corners of given @p annotation on the given @p page. + * + * Can be used to implement resize functionality. + * @p delta1 in normalized coordinates is added to top-left. + * @p delta2 in normalized coordinates is added to bottom-right. + * + * Consecutive adjustments applied to the same @p annotation are merged together on the undo stack if the + * BeingResized flag is set on the @p annotation. + * + * @since 1.1.0 + */ + void adjustPageAnnotation(int page, Annotation *annotation, const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2); + + /** + * Edits the plain text contents of the given @p annotation on the given @p page. + * + * The contents are set to @p newContents with cursor position @p newCursorPos. + * The previous cursor position @p prevCursorPos and previous anchor position @p prevAnchorPos + * must also be supplied so that they can be restored if the edit action is undone. + * + * The Annotation's internal contents should not be modified prior to calling this method. + * + * @since 0.17 (KDE 4.11) + */ + void editPageAnnotationContents(int page, Annotation *annotation, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos); + + /** + * Tests if the @p annotation can be removed + * + * @since 0.15 (KDE 4.9) + */ + bool canRemovePageAnnotation(const Annotation *annotation) const; + + /** + * Removes the given @p annotation from the given @p page. + */ + void removePageAnnotation(int page, Annotation *annotation); + + /** + * Removes the given @p annotations from the given @p page. + */ + void removePageAnnotations(int page, const QList &annotations); + + /** + * Clears the text selection highlights for the given @p page, + * creates new ones if @p rect is not nullptr, + * and deletes @p rect. + * + * @param page The number of the page. + * @param rect The rectangle of the selection. + * @param color The color of the selection. + */ + void setPageTextSelection(int page, RegularAreaRect *rect, const QColor &color); + + /** + * Returns true if there is an undo command available; otherwise returns false. + * @since 0.17 (KDE 4.11) + */ + bool canUndo() const; + + /** + * Returns true if there is a redo command available; otherwise returns false. + * @since 0.17 (KDE 4.11) + */ + bool canRedo() const; + + /** + * Describes the possible search types. + */ + enum SearchType { + NextMatch, ///< Search next match + PreviousMatch, ///< Search previous match + AllDocument, ///< Search complete document + GoogleAll, ///< Search complete document (all words in google style) + GoogleAny ///< Search complete document (any words in google style) + }; + + /** + * Describes how search ended + */ + // TODO remove EndOfDocumentReached when we break API + enum SearchStatus { + MatchFound, ///< Any match was found + NoMatchFound, ///< No match was found + SearchCancelled, ///< The search was cancelled + EndOfDocumentReached ///< This is not ever emitted since 1.3. The end of document was reached without any match @since 0.20 (KDE 4.14) + }; + + /** + * Searches the given @p text in the document. + * + * @param searchID The unique id for this search request. + * @param text The text to be searched. + * @param fromStart Whether the search should be started at begin of the document. + * @param caseSensitivity Whether the search is case sensitive. + * @param type The type of the search. @ref SearchType + * @param moveViewport Whether the viewport shall be moved to the position of the matches. + * @param color The highlighting color of the matches. + */ + void searchText(int searchID, const QString &text, bool fromStart, Qt::CaseSensitivity caseSensitivity, SearchType type, bool moveViewport, const QColor &color); + + /** + * Continues the search for the given @p searchID. + */ + void continueSearch(int searchID); + + /** + * Continues the search for the given @p searchID, optionally specifying + * a new type for the search. + * + * @since 0.7 (KDE 4.1) + */ + void continueSearch(int searchID, SearchType type); + + /** + * Resets the search for the given @p searchID. + */ + void resetSearch(int searchID); + + /** + * Returns the bookmark manager of the document. + */ + BookmarkManager *bookmarkManager() const; + + /** + * Processes the given @p action. + */ + void processAction(const Action *action); + + /** + * Processes the given format @p action on @p fft. + * + * @since 1.9 + */ + void processFormatAction(const Action *action, Okular::FormFieldText *fft); + + /** + * Processes the given keystroke @p action on @p fft. + * + * @since 1.9 + */ + void processKeystrokeAction(const Action *action, Okular::FormFieldText *fft, bool &returnCode); + + /** + * Processes the given focus action on the field. + * + * @since 1.9 + */ + void processFocusAction(const Action *action, Okular::FormField *field); + + /** + * Processes the given keystroke @p action on @p fft. + * + * @since 1.9 + */ + void processValidateAction(const Action *action, Okular::FormFieldText *fft, bool &returnCode); + + /** + * Returns a list of the bookmarked.pages + */ + QList bookmarkedPageList() const; + + /** + * Returns the range of the bookmarked.pages + */ + QString bookmarkedPageRange() const; + + /** + * Processes/Executes the given source @p reference. + */ + void processSourceReference(const SourceReference *reference); + + /** + * Returns whether the document can configure the printer itself. + */ + bool canConfigurePrinter() const; + + /** + * What type of printing a document supports + */ + enum PrintingType { + NoPrinting, ///< Printing Not Supported + NativePrinting, ///< Native Cross-Platform Printing + PostscriptPrinting ///< Postscript file printing + }; + + /** + * Returns what sort of printing the document supports: + * Native, Postscript, None + */ + PrintingType printingSupport() const; + + /** + * Returns whether the document supports printing to both PDF and PS files. + */ + bool supportsPrintToFile() const; + + /** + * Prints the document to the given @p printer. + */ + bool print(QPrinter &printer); + + /** + * Returns the last print error in case print() failed + * @since 0.11 (KDE 4.5) + */ + QString printError() const; + + /** + * Returns a custom printer configuration page or 0 if no + * custom printer configuration page is available. + * + * The returned object should be of a PrintOptionsWidget subclass + * (which is not officially enforced by the signature for binary + * compatibility reasons). + */ + QWidget *printConfigurationWidget() const; + + /** + * Fill the KConfigDialog @p dialog with the setting pages of the + * generators. + */ + void fillConfigDialog(KConfigDialog *dialog); + + /** + * Returns the number of generators that have a configuration widget. + */ + int configurableGenerators() const; + + /** + * Returns the list with the supported MIME types. + */ + QStringList supportedMimeTypes() const; + + /** + * Returns the metadata associated with the generator. May be invalid. + */ + KPluginMetaData generatorInfo() const; + + /** + * Returns whether the generator supports hot-swapping the current file + * with another identical file + * + * @since 1.3 + */ + bool canSwapBackingFile() const; + + /** + * Reload the document from a new location, without any visible effect + * to the user. + * + * The new file must be identical to the current one or, if the document + * has been modified (eg the user edited forms and annotations), the new + * document must have these changes too. For example, you can call + * saveChanges first to write changes to a file and then swapBackingFile + * to switch to the new location. + * + * @since 1.3 + */ + bool swapBackingFile(const QString &newFileName, const QUrl &url); + + /** + * Same as swapBackingFile, but newFileName must be a .okular file. + * + * The new file must be identical to the current one or, if the document + * has been modified (eg the user edited forms and annotations), the new + * document must have these changes too. For example, you can call + * saveDocumentArchive first to write changes to a file and then + * swapBackingFileArchive to switch to the new location. + * + * @since 1.3 + */ + bool swapBackingFileArchive(const QString &newFileName, const QUrl &url); + + /** + * Sets the history to be clean + * + * @since 1.3 + */ + void setHistoryClean(bool clean); + + /** + * Saving capabilities. Their availability varies according to the + * underlying generator and/or the document type. + * + * @see canSaveChanges (SaveCapability) + * @since 0.15 (KDE 4.9) + */ + enum SaveCapability { + SaveFormsCapability = 1, ///< Can save form changes + SaveAnnotationsCapability = 2 ///< Can save annotation changes + }; + + /** + * Returns whether it's possible to save a given category of changes to + * another document. + * + * @since 0.15 (KDE 4.9) + */ + bool canSaveChanges(SaveCapability cap) const; + + /** + * Returns whether the changes to the document (modified annotations, + * values in form fields, etc) can be saved to another document. + * + * Equivalent to the logical OR of canSaveChanges(SaveCapability) for + * each capability. + * + * @since 0.7 (KDE 4.1) + */ + bool canSaveChanges() const; + + /** + * Save the document and the optional changes to it to the specified + * @p fileName. + * + * @since 0.7 (KDE 4.1) + */ + bool saveChanges(const QString &fileName); + + /** + * Save the document and the optional changes to it to the specified + * @p fileName and returns a @p errorText if fails. + * + * @since 0.10 (KDE 4.4) + */ + bool saveChanges(const QString &fileName, QString *errorText); + + /** + * Register the specified @p view for the current document. + * + * It is unregistered from the previous document, if any. + * + * @since 0.7 (KDE 4.1) + */ + void registerView(View *view); + + /** + * Unregister the specified @p view from the current document. + * + * @since 0.7 (KDE 4.1) + */ + void unregisterView(View *view); + + /** + * Gets the font data for the given font + * + * @since 0.8 (KDE 4.2) + */ + QByteArray fontData(const FontInfo &font) const; + + /** + * Opens a document archive. + * + * @since 0.20 (KDE 4.14) + */ + OpenResult openDocumentArchive(const QString &docFile, const QUrl &url, const QString &password = QString()); + + /** + * Saves a document archive. + * + * @since 0.8 (KDE 4.2) + */ + bool saveDocumentArchive(const QString &fileName); + + /** + * Extract the document file from the current archive. + * + * @warning This function only works if the current file is a document archive + * + * @since 1.3 + */ + bool extractArchivedFile(const QString &destFileName); + + /** + * Asks the generator to dynamically generate a SourceReference for a given + * page number and absolute X and Y position on this page. + * + * @attention Ownership of the returned SourceReference is transferred to the caller. + * @note This method does not call processSourceReference( const SourceReference * ) + * + * @since 0.10 (KDE 4.4) + */ + const SourceReference *dynamicSourceReference(int pageNr, double absX, double absY); + + /** + * Returns the orientation of the document (for printing purposes). This + * is used in the KPart to initialize the print dialog and in the + * generators to check whether the document needs to be rotated or not. + * + * @since 0.14 (KDE 4.8) + */ + QPrinter::Orientation orientation() const; + + /** + * Control annotation editing (creation, modification and removal), + * which is enabled by default. + * + * @since 0.15 (KDE 4.9) + */ + void setAnnotationEditingEnabled(bool enable); + + /** + * Returns which wallet data to use to read/write the password for the given fileName + * + * @since 0.20 (KDE 4.14) + */ + void walletDataForFile(const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey) const; + + /** + * Since version 0.21, okular does not allow editing annotations and + * form data if they are stored in the docdata directory (like older + * okular versions did by default). + * If this flag is set, then annotations and forms cannot be edited. + * + * @since 1.3 + */ + bool isDocdataMigrationNeeded() const; + + /** + * Delete annotations and form data from the docdata folder. Call it if + * isDocdataMigrationNeeded() was true and you've just saved them to an + * external file. + * + * @since 1.3 + */ + void docdataMigrationDone(); + + /** + * Returns the model for rendering layers (NULL if the document has no layers) + * + * @since 0.24 + */ + QAbstractItemModel *layersModel() const; + + /** + * Returns the reason why the file opening failed, if any. + * + * @since 1.10 + */ + QString openError() const; + +public Q_SLOTS: + /** + * This slot is called whenever the user changes the @p rotation of + * the document. + */ + void setRotation(int rotation); + + /** + * This slot is called whenever the user changes the page @p size + * of the document. + */ + void setPageSize(const Okular::PageSize &size); + + /** + * Cancels the current search + */ + void cancelSearch(); + + /** + * Undo last edit command + * @since 0.17 (KDE 4.11) + */ + void undo(); + + /** + * Redo last undone edit command + * @since 0.17 (KDE 4.11) + */ + void redo(); + + /** + * Edit the text contents of the specified @p form on page @p page to be @p newContents. + * The new text cursor position (@p newCursorPos), previous text cursor position (@p prevCursorPos), + * and previous cursor anchor position will be restored by the undo / redo commands. + * @since 0.17 (KDE 4.11) + */ + void editFormText(int pageNumber, Okular::FormFieldText *form, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos); + + /** + * Edit the selected list entries in @p form on page @p page to be @p newChoices. + * @since 0.17 (KDE 4.11) + */ + void editFormList(int pageNumber, Okular::FormFieldChoice *form, const QList &newChoices); + + /** + * Set the active choice in the combo box @p form on page @p page to @p newText + * The new cursor position (@p newCursorPos), previous cursor position + * (@p prevCursorPos), and previous anchor position (@p prevAnchorPos) + * will be restored by the undo / redo commands. + * + * @since 0.17 (KDE 4.11) + */ + void editFormCombo(int pageNumber, Okular::FormFieldChoice *form, const QString &newText, int newCursorPos, int prevCursorPos, int prevAnchorPos); + + /** + * Set the states of the group of form buttons @p formButtons on page @p page to @p newButtonStates. + * The lists @p formButtons and @p newButtonStates should be the same length and true values + * in @p newButtonStates indicate that the corresponding entry in @p formButtons should be enabled. + */ + void editFormButtons(int pageNumber, const QList &formButtons, const QList &newButtonStates); + + /** + * Reloads the pixmaps for whole document + * + * @since 0.24 + */ + void reloadDocument() const; + + /** + * Returns the part of document covered by the given signature @p info. + * + * @since 1.7 + */ + QByteArray requestSignedRevisionData(const Okular::SignatureInfo &info); + + /** + * Refresh the pixmaps for the given @p pageNumber. + * + * @since 1.10 + */ + void refreshPixmaps(int pageNumber); + +Q_SIGNALS: + /** + * This signal is emitted whenever the document is about to close. + * @since 1.5.3 + */ + void aboutToClose(); + + /** + * This signal is emitted whenever an action requests a + * document close operation. + */ + void close(); + + /** + * This signal is emitted whenever an action requests an + * application quit operation. + */ + void quit(); + + /** + * This signal is emitted whenever an action requests a + * find operation. + */ + void linkFind(); + + /** + * This signal is emitted whenever an action requests a + * goto operation. + */ + void linkGoToPage(); + + /** + * This signal is emitted whenever an action requests a + * start presentation operation. + */ + void linkPresentation(); + + /** + * This signal is emitted whenever an action requests an + * end presentation operation. + */ + void linkEndPresentation(); + + /** + * This signal is emitted whenever an action requests an + * open url operation for the given document @p url. + */ + void openUrl(const QUrl &url); + + /** + * This signal is emitted whenever an error occurred. + * + * @param text The description of the error. + * @param duration The time in milliseconds the message should be shown to the user. + */ + void error(const QString &text, int duration); + + /** + * This signal is emitted to signal a warning. + * + * @param text The description of the warning. + * @param duration The time in milliseconds the message should be shown to the user. + */ + void warning(const QString &text, int duration); + + /** + * This signal is emitted to signal a notice. + * + * @param text The description of the notice. + * @param duration The time in milliseconds the message should be shown to the user. + */ + void notice(const QString &text, int duration); + + /** + * Emitted when a new font is found during the reading of the fonts of + * the document. + */ + void gotFont(const Okular::FontInfo &font); + + /** + * Reports the progress when reading the fonts in the document. + * + * \param page is the page that was just finished to scan for fonts + */ + void fontReadingProgress(int page); + + /** + * Reports that the reading of the fonts in the document is finished. + */ + void fontReadingEnded(); + + /** + * Reports that the current search finished + */ + void searchFinished(int searchID, Okular::Document::SearchStatus endStatus); + + /** + * This signal is emitted whenever a source reference with the given parameters has been + * activated. + * + * \param absFileName absolute name of the file. + * \param line line number. + * \param col column number. + * \param handled should be set to 'true' if a slot handles this source reference; the + * default action to launch the configured editor will then not be performed + * by the document + * + * @since 0.14 (KDE 4.8) + */ + void sourceReferenceActivated(const QString &absFileName, int line, int col, bool *handled); + + /** + * This signal is emitted whenever an movie action is triggered and the UI should process it. + */ + void processMovieAction(const Okular::MovieAction *action); + + /** + * This signal is emitted whenever the availability of the undo function changes + * @since 0.17 (KDE 4.11) + */ + void canUndoChanged(bool undoAvailable); + + /** + * This signal is emitted whenever the availability of the redo function changes + * @since 0.17 (KDE 4.11) + */ + void canRedoChanged(bool redoAvailable); + + /** + * This signal is emitted whenever the undo history is clean (i.e. the same status the last time it was saved) + * @since 1.3 + */ + void undoHistoryCleanChanged(bool clean); + + /** + * This signal is emitted whenever an rendition action is triggered and the UI should process it. + * + * @since 0.16 (KDE 4.10) + */ + void processRenditionAction(const Okular::RenditionAction *action); + + /** + * This signal is emitted whenever the contents of the given @p annotation are changed by an undo + * or redo action. + * + * The new contents (@p contents), cursor position (@p cursorPos), and anchor position (@p anchorPos) are + * included + * @since 0.17 (KDE 4.11) + */ + void annotationContentsChangedByUndoRedo(Okular::Annotation *annotation, const QString &contents, int cursorPos, int anchorPos); + + /** + * This signal is emitted whenever the text contents of the given text @p form on the given @p page + * are changed by an undo or redo action. + * + * The new text contents (@p contents), cursor position (@p cursorPos), and anchor position (@p anchorPos) are + * included + * @since 0.17 (KDE 4.11) + */ + void formTextChangedByUndoRedo(int page, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos); + + /** + * This signal is emitted whenever the selected @p choices for the given list @p form on the + * given @p page are changed by an undo or redo action. + * @since 0.17 (KDE 4.11) + */ + void formListChangedByUndoRedo(int page, Okular::FormFieldChoice *form, const QList &choices); + + /** + * This signal is emitted whenever the active @p text for the given combo @p form on the + * given @p page is changed by an undo or redo action. + * @since 0.17 (KDE 4.11) + */ + void formComboChangedByUndoRedo(int page, Okular::FormFieldChoice *form, const QString &text, int cursorPos, int anchorPos); + + /** + * This signal is emitted whenever the state of the specified group of form buttons (@p formButtons) on the + * given @p page is changed by an undo or redo action. + * @since 0.17 (KDE 4.11) + */ + void formButtonsChangedByUndoRedo(int page, const QList &formButtons); + + /** + * This signal is emitted whenever a FormField was changed programmatically and the + * according widget should be updated. + * @since 1.4 + */ + void refreshFormWidget(Okular::FormField *field); + +private: + /// @cond PRIVATE + friend class DocumentPrivate; + friend class ::DocumentItem; + friend class EditAnnotationContentsCommand; + friend class EditFormTextCommand; + friend class EditFormListCommand; + friend class EditFormComboCommand; + friend class EditFormButtonsCommand; + /// @endcond + DocumentPrivate *const d; + + Q_DISABLE_COPY(Document) +}; + +/** + * @short A view on the document. + * + * The Viewport structure is the 'current view' over the document. Contained + * data is broadcasted between observers to synchronize their viewports to get + * the 'I scroll one view and others scroll too' views. + */ +class OKULARCORE_EXPORT DocumentViewport +{ +public: + /** + * Creates a new viewport for the given page @p number. + */ + DocumentViewport(int number = -1); + + /** + * Creates a new viewport from the given @p xmlDesc. + */ + DocumentViewport(const QString &xmlDesc); + + /** + * Returns the viewport as xml description. + */ + QString toString() const; + + /** + * Returns whether the viewport is valid. + */ + bool isValid() const; + + /** + * @internal + */ + bool operator==(const DocumentViewport &other) const; + bool operator<(const DocumentViewport &other) const; + + /** + * The number of the page nearest the center of the viewport. + */ + int pageNumber; + + /** + * Describes the relative position of the viewport. + */ + enum Position { + Center = 1, ///< Relative to the center of the page. + TopLeft = 2 ///< Relative to the top left corner of the page. + }; + + /** + * If 'rePos.enabled == true' then this structure contains the + * viewport center or top left depending on the value of pos. + */ + struct { + bool enabled; + double normalizedX; + double normalizedY; + Position pos; + } rePos; + + /** + * If 'autoFit.enabled == true' then the page must be autofit in the viewport. + */ + struct { + bool enabled; + bool width; + bool height; + } autoFit; +}; + +/** + * @short A DOM tree that describes the Table of Contents. + * + * The Synopsis (TOC or Table Of Contents for friends) is represented via + * a dom tree where each node has an internal name (displayed in the TOC) + * and one or more attributes. + * + * In the tree the tag name is the 'screen' name of the entry. A tag can have + * attributes. Here follows the list of tag attributes with meaning: + * - Destination: A string description of the referred viewport + * - DestinationName: A 'named reference' to the viewport that must be converted + * using metaData( "NamedViewport", viewport_name ) + * - ExternalFileName: A document to be opened, whose destination is specified + * with Destination or DestinationName + * - Open: a boolean saying whether its TOC branch is open or not (default: false) + * - URL: a URL to be open as destination; if set, no other Destination* or + * ExternalFileName entry is used + */ +class OKULARCORE_EXPORT DocumentSynopsis : public QDomDocument +{ +public: + /** + * Creates a new document synopsis object. + */ + DocumentSynopsis(); + + /** + * Creates a new document synopsis object with the given + * @p document as parent node. + */ + DocumentSynopsis(const QDomDocument &document); +}; + +/** + * @short An embedded file into the document. + * + * This class represents a sort of interface of an embedded file in a document. + * + * Generators \b must re-implement its members to give the all the information + * about an embedded file, like its name, its description, the date of creation + * and modification, and the real data of the file. + */ +class OKULARCORE_EXPORT EmbeddedFile +{ +public: + /** + * Creates a new embedded file. + */ + EmbeddedFile(); + + /** + * Destroys the embedded file. + */ + virtual ~EmbeddedFile(); + + EmbeddedFile(const EmbeddedFile &) = delete; + EmbeddedFile &operator=(const EmbeddedFile &) = delete; + + /** + * Returns the name of the file + */ + virtual QString name() const = 0; + + /** + * Returns the description of the file, or an empty string if not + * available + */ + virtual QString description() const = 0; + + /** + * Returns the real data representing the file contents + */ + virtual QByteArray data() const = 0; + + /** + * Returns the size (in bytes) of the file, if available, or -1 otherwise. + * + * @note this method should be a fast way to know the size of the file + * with no need to extract all the data from it + */ + virtual int size() const = 0; + + /** + * Returns the modification date of the file, or an invalid date + * if not available + */ + virtual QDateTime modificationDate() const = 0; + + /** + * Returns the creation date of the file, or an invalid date + * if not available + */ + virtual QDateTime creationDate() const = 0; +}; + +/** + * @short An area of a specified page + */ +class OKULARCORE_EXPORT VisiblePageRect +{ +public: + /** + * Creates a new visible page rectangle. + * + * @param pageNumber The page number where the rectangle is located. + * @param rectangle The rectangle in normalized coordinates. + */ + explicit VisiblePageRect(int pageNumber = -1, const NormalizedRect &rectangle = NormalizedRect()); + + /** + * The page number where the rectangle is located. + */ + int pageNumber; + + /** + * The rectangle in normalized coordinates. + */ + NormalizedRect rect; +}; + +} + +Q_DECLARE_METATYPE(Okular::DocumentInfo::Key) +Q_DECLARE_OPERATORS_FOR_FLAGS(Okular::Document::PixmapRequestFlags) + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/document_p.h b/core/document_p.h new file mode 100644 index 0000000..e718fa0 --- /dev/null +++ b/core/document_p.h @@ -0,0 +1,364 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2007 by Albert Astals Cid * + * * + * 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_DOCUMENT_P_H_ +#define _OKULAR_DOCUMENT_P_H_ + +#include "document.h" +#include "script/event_p.h" + +#include "synctex/synctex_parser.h" +#include + +// qt/kde/system includes +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "fontinfo.h" +#include "generator.h" + +class QUndoStack; +class QEventLoop; +class QFile; +class QTimer; +class QTemporaryFile; +class KPluginMetaData; + +struct AllocatedPixmap; +struct ArchiveData; +struct RunningSearch; + +namespace Okular +{ +class ScriptAction; +class ConfigInterface; +class PageController; +class SaveInterface; +class Scripter; +class View; +} + +struct GeneratorInfo { + explicit GeneratorInfo(Okular::Generator *g, const KPluginMetaData &data) + : generator(g) + , metadata(data) + , config(nullptr) + , save(nullptr) + , configChecked(false) + , saveChecked(false) + { + } + + Okular::Generator *generator; + KPluginMetaData metadata; + Okular::ConfigInterface *config; + Okular::SaveInterface *save; + bool configChecked : 1; + bool saveChecked : 1; +}; + +namespace Okular +{ +class OKULARCORE_EXPORT BackendConfigDialog : public KConfigDialog +{ + Q_OBJECT +public: + BackendConfigDialog(QWidget *parent, const QString &name, KCoreConfigSkeleton *config) + : KConfigDialog(parent, name, config) + { + } + + KPageWidget *thePageWidget() + { + return pageWidget(); + } +}; + +class FontExtractionThread; + +struct DoContinueDirectionMatchSearchStruct { + QSet *pagesToNotify; + RegularAreaRect *match; + int currentPage; + int searchID; +}; + +enum LoadDocumentInfoFlag { + LoadNone = 0, + LoadPageInfo = 1, // Load annotations and forms + LoadGeneralInfo = 2, // History, rotation, ... + LoadAllInfo = 0xff +}; +Q_DECLARE_FLAGS(LoadDocumentInfoFlags, LoadDocumentInfoFlag) + +class DocumentPrivate +{ +public: + explicit DocumentPrivate(Document *parent) + : m_parent(parent) + , m_tempFile(nullptr) + , m_docSize(-1) + , m_allocatedPixmapsTotalMemory(0) + , m_maxAllocatedTextPages(0) + , m_warnedOutOfMemory(false) + , m_rotation(Rotation0) + , m_exportCached(false) + , m_bookmarkManager(nullptr) + , m_memCheckTimer(nullptr) + , m_saveBookmarksTimer(nullptr) + , m_generator(nullptr) + , m_walletGenerator(nullptr) + , m_generatorsLoaded(false) + , m_pageController(nullptr) + , m_closingLoop(nullptr) + , m_scripter(nullptr) + , m_archiveData(nullptr) + , m_fontsCached(false) + , m_annotationEditingEnabled(true) + , m_annotationBeingModified(false) + , m_docdataMigrationNeeded(false) + , m_synctex_scanner(nullptr) + { + calculateMaxTextPages(); + } + + // private methods + bool updateMetadataXmlNameAndDocSize(); + QString pagesSizeString() const; + QString namePaperSize(double inchesWidth, double inchesHeight) const; + QString localizedSize(const QSizeF size) const; + qulonglong calculateMemoryToFree(); + void cleanupPixmapMemory(); + void cleanupPixmapMemory(qulonglong memoryToFree); + AllocatedPixmap *searchLowestPriorityPixmap(bool unloadableOnly = false, bool thenRemoveIt = false, DocumentObserver *observer = nullptr /* any */); + void calculateMaxTextPages(); + qulonglong getTotalMemory(); + qulonglong getFreeMemory(qulonglong *freeSwap = nullptr); + bool loadDocumentInfo(LoadDocumentInfoFlags loadWhat); + bool loadDocumentInfo(QFile &infoFile, LoadDocumentInfoFlags loadWhat); + void loadViewsInfo(View *view, const QDomElement &e); + void saveViewsInfo(View *view, QDomElement &e) const; + QUrl giveAbsoluteUrl(const QString &fileName) const; + bool openRelativeFile(const QString &fileName); + Generator *loadGeneratorLibrary(const KPluginMetaData &service); + void loadAllGeneratorLibraries(); + void loadServiceList(const QVector &offers); + void unloadGenerator(const GeneratorInfo &info); + void cacheExportFormats(); + void setRotationInternal(int r, bool notify); + ConfigInterface *generatorConfig(GeneratorInfo &info); + SaveInterface *generatorSave(GeneratorInfo &info); + Document::OpenResult openDocumentInternal(const KPluginMetaData &offer, bool isstdin, const QString &docFile, const QByteArray &filedata, const QString &password); + static ArchiveData *unpackDocumentArchive(const QString &archivePath); + bool savePageDocumentInfo(QTemporaryFile *infoFile, int what) const; + DocumentViewport nextDocumentViewport() const; + void notifyAnnotationChanges(int page); + void notifyFormChanges(int page); + bool canAddAnnotationsNatively() const; + bool canModifyExternalAnnotations() const; + bool canRemoveExternalAnnotations() const; + OKULARCORE_EXPORT static QString docDataFileName(const QUrl &url, qint64 document_size); + bool cancelRenderingBecauseOf(PixmapRequest *executingRequest, PixmapRequest *newRequest); + + // Methods that implement functionality needed by undo commands + void performAddPageAnnotation(int page, Annotation *annotation); + void performRemovePageAnnotation(int page, Annotation *annotation); + void performModifyPageAnnotation(int page, Annotation *annotation, bool appearanceChanged); + void performSetAnnotationContents(const QString &newContents, Annotation *annot, int pageNumber); + + void recalculateForms(); + + // private slots + void saveDocumentInfo() const; + void slotTimedMemoryCheck(); + void sendGeneratorPixmapRequest(); + void rotationFinished(int page, Okular::Page *okularPage); + void slotFontReadingProgress(int page); + void fontReadingGotFont(const Okular::FontInfo &font); + void slotGeneratorConfigChanged(); + void refreshPixmaps(int); + void _o_configChanged(); + void doContinueDirectionMatchSearch(void *doContinueDirectionMatchSearchStruct); + void doContinueAllDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID); + void doContinueGooglesDocumentSearch(void *pagesToNotifySet, void *pageMatchesMap, int currentPage, int searchID, const QStringList &words); + + void doProcessSearchMatch(RegularAreaRect *match, RunningSearch *search, QSet *pagesToNotify, int currentPage, int searchID, bool moveViewport, const QColor &color); + + /** + * Executes a JavaScript script from the setInterval function. + * + * @since 1.9 + */ + void executeScript(const QString &function); + + // generators stuff + /** + * This method is used by the generators to signal the finish of + * the pixmap generation @p request. + */ + void requestDone(PixmapRequest *request); + void textGenerationDone(Page *page); + /** + * Sets the bounding box of the given @p page (in terms of upright orientation, i.e., Rotation0). + */ + void setPageBoundingBox(int page, const NormalizedRect &boundingBox); + + /** + * Request a particular metadata of the Document itself (ie, not something + * depending on the document type/backend). + */ + QVariant documentMetaData(const Generator::DocumentMetaDataKey key, const QVariant &option) const; + + /** + * Return whether the normalized rectangle @p rectOfInterest on page number @p rectPage + * is fully visible. + */ + bool isNormalizedRectangleFullyVisible(const Okular::NormalizedRect &rectOfInterest, int rectPage); + + // For sync files + void loadSyncFile(const QString &filePath); + + void clearAndWaitForRequests(); + + /* + * Executes a ScriptAction with the event passed as parameter. + */ + void executeScriptEvent(const std::shared_ptr &event, const Okular::ScriptAction *linkscript); + + /* + * Find the corresponding page number for the form field passed as parameter. + */ + int findFieldPageNumber(Okular::FormField *field); + + // member variables + Document *m_parent; + QPointer m_widget; + + // find descriptors, mapped by ID (we handle multiple searches) + QMap m_searches; + bool m_searchCancelled; + + // needed because for remote documents docFileName is a local file and + // we want the remote url when the document refers to relativeNames + QUrl m_url; + + // cached stuff + QString m_docFileName; + QString m_xmlFileName; + QTemporaryFile *m_tempFile; + qint64 m_docSize; + + // viewport stuff + QLinkedList m_viewportHistory; + QLinkedList::iterator m_viewportIterator; + DocumentViewport m_nextDocumentViewport; // see Link::Goto for an explanation + QString m_nextDocumentDestination; + + // observers / requests / allocator stuff + QSet m_observers; + QLinkedList m_pixmapRequestsStack; + QLinkedList m_executingPixmapRequests; + QMutex m_pixmapRequestsMutex; + QLinkedList m_allocatedPixmaps; + qulonglong m_allocatedPixmapsTotalMemory; + QList m_allocatedTextPagesFifo; + int m_maxAllocatedTextPages; + bool m_warnedOutOfMemory; + + // the rotation applied to the document + Rotation m_rotation; + + // the current size of the pages (if available), and the cache of the + // available page sizes + PageSize m_pageSize; + PageSize::List m_pageSizes; + + // cache of the export formats + bool m_exportCached; + ExportFormat::List m_exportFormats; + ExportFormat m_exportToText; + + // our bookmark manager + BookmarkManager *m_bookmarkManager; + + // timers (memory checking / info saver) + QTimer *m_memCheckTimer; + QTimer *m_saveBookmarksTimer; + + QHash m_loadedGenerators; + Generator *m_generator; + QString m_generatorName; + Generator *m_walletGenerator; + bool m_generatorsLoaded; + QVector m_pagesVector; + QVector m_pageRects; + + // cache of the mimetype we support + QStringList m_supportedMimeTypes; + + PageController *m_pageController; + QEventLoop *m_closingLoop; + + Scripter *m_scripter; + + ArchiveData *m_archiveData; + QString m_archivedFileName; + + QPointer m_fontThread; + bool m_fontsCached; + QSet m_documentInfoAskedKeys; + DocumentInfo m_documentInfo; + FontInfo::List m_fontsCache; + + QSet m_views; + + bool m_annotationEditingEnabled; + bool m_annotationBeingModified; // is an annotation currently being moved or resized? + bool m_metadataLoadingCompleted; + + QUndoStack *m_undoStack; + QDomNode m_prevPropsOfAnnotBeingModified; + + // Since 0.21, we no longer support saving annotations and form data in + // the docdata/ directory and we ask the user to migrate them to an + // external file as soon as possible, otherwise the document will be + // shown in read-only mode. This flag is set if the docdata/ XML file + // for the current document contains any annotation or form. + bool m_docdataMigrationNeeded; + + synctex_scanner_p m_synctex_scanner; + + QString m_openError; + + // generator selection + static QVector availableGenerators(); + static QVector configurableGenerators(); + static KPluginMetaData generatorForMimeType(const QMimeType &type, QWidget *widget, const QVector &triedOffers = QVector()); +}; + +class DocumentInfoPrivate +{ +public: + QMap values; // key -> value + QMap titles; // key -> title For the custom keys +}; + +} + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/documentcommands.cpp b/core/documentcommands.cpp new file mode 100644 index 0000000..e1df1aa --- /dev/null +++ b/core/documentcommands.cpp @@ -0,0 +1,650 @@ +/*************************************************************************** + * Copyright (C) 2013 Jon Mease * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "documentcommands_p.h" + +#include "annotations.h" +#include "debug_p.h" +#include "document_p.h" +#include "form.h" +#include "page.h" +#include "page_p.h" +#include "utils_p.h" + +#include + +namespace Okular +{ +void moveViewportIfBoundingRectNotFullyVisible(Okular::NormalizedRect boundingRect, DocumentPrivate *docPriv, int pageNumber) +{ + const Rotation pageRotation = docPriv->m_parent->page(pageNumber)->rotation(); + const QTransform rotationMatrix = Okular::buildRotationMatrix(pageRotation); + boundingRect.transform(rotationMatrix); + if (!docPriv->isNormalizedRectangleFullyVisible(boundingRect, pageNumber)) { + DocumentViewport searchViewport(pageNumber); + searchViewport.rePos.enabled = true; + searchViewport.rePos.normalizedX = (boundingRect.left + boundingRect.right) / 2.0; + searchViewport.rePos.normalizedY = (boundingRect.top + boundingRect.bottom) / 2.0; + docPriv->m_parent->setViewport(searchViewport, nullptr, true); + } +} + +Okular::NormalizedRect buildBoundingRectangleForButtons(const QList &formButtons) +{ + // Initialize coordinates of the bounding rect + double left = 1.0; + double top = 1.0; + double right = 0.0; + double bottom = 0.0; + + for (const FormFieldButton *formButton : formButtons) { + left = qMin(left, formButton->rect().left); + top = qMin(top, formButton->rect().top); + right = qMax(right, formButton->rect().right); + bottom = qMax(bottom, formButton->rect().bottom); + } + Okular::NormalizedRect boundingRect(left, top, right, bottom); + return boundingRect; +} + +AddAnnotationCommand::AddAnnotationCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber) + : m_docPriv(docPriv) + , m_annotation(annotation) + , m_pageNumber(pageNumber) + , m_done(false) +{ + setText(i18nc("Add an annotation to the page", "add annotation")); +} + +AddAnnotationCommand::~AddAnnotationCommand() +{ + if (!m_done) { + delete m_annotation; + } +} + +void AddAnnotationCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performRemovePageAnnotation(m_pageNumber, m_annotation); + m_done = false; +} + +void AddAnnotationCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performAddPageAnnotation(m_pageNumber, m_annotation); + m_done = true; +} + +bool AddAnnotationCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + if (m_done) { + // We don't always update m_annotation because even if the annotation has been added to the document + // it can have been removed later so the annotation pointer is stored inside a following RemoveAnnotationCommand + // and thus doesn't need updating because it didn't change + // because of the document reload + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + } + + return true; +} + +RemoveAnnotationCommand::RemoveAnnotationCommand(Okular::DocumentPrivate *doc, Okular::Annotation *annotation, int pageNumber) + : m_docPriv(doc) + , m_annotation(annotation) + , m_pageNumber(pageNumber) + , m_done(false) +{ + setText(i18nc("Remove an annotation from the page", "remove annotation")); +} + +RemoveAnnotationCommand::~RemoveAnnotationCommand() +{ + if (m_done) { + delete m_annotation; + } +} + +void RemoveAnnotationCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performAddPageAnnotation(m_pageNumber, m_annotation); + m_done = false; +} + +void RemoveAnnotationCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performRemovePageAnnotation(m_pageNumber, m_annotation); + m_done = true; +} + +bool RemoveAnnotationCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + if (!m_done) { + // We don't always update m_annotation because it can happen that the annotation remove has been undo + // and that annotation addition has also been undone so the annotation pointer is stored inside + // a previous AddAnnotationCommand and thus doesn't need updating because it didn't change + // because of the document reload + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + } + + return true; +} + +ModifyAnnotationPropertiesCommand::ModifyAnnotationPropertiesCommand(DocumentPrivate *docPriv, Annotation *annotation, int pageNumber, const QDomNode &oldProperties, const QDomNode &newProperties) + : m_docPriv(docPriv) + , m_annotation(annotation) + , m_pageNumber(pageNumber) + , m_prevProperties(oldProperties) + , m_newProperties(newProperties) +{ + setText(i18nc("Modify an annotation's internal properties (Color, line-width, etc.)", "modify annotation properties")); +} + +void ModifyAnnotationPropertiesCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_annotation->setAnnotationProperties(m_prevProperties); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +void ModifyAnnotationPropertiesCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_annotation->setAnnotationProperties(m_newProperties); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +bool ModifyAnnotationPropertiesCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + // Same reason for not unconditionally updating m_annotation, the annotation pointer can be stored in an add/Remove command + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + + return true; +} + +TranslateAnnotationCommand::TranslateAnnotationCommand(DocumentPrivate *docPriv, Annotation *annotation, int pageNumber, const Okular::NormalizedPoint &delta, bool completeDrag) + : m_docPriv(docPriv) + , m_annotation(annotation) + , m_pageNumber(pageNumber) + , m_delta(delta) + , m_completeDrag(completeDrag) +{ + setText(i18nc("Translate an annotation's position on the page", "translate annotation")); +} + +void TranslateAnnotationCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(translateBoundingRectangle(minusDelta()), m_docPriv, m_pageNumber); + m_annotation->translate(minusDelta()); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +void TranslateAnnotationCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(translateBoundingRectangle(m_delta), m_docPriv, m_pageNumber); + m_annotation->translate(m_delta); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +int TranslateAnnotationCommand::id() const +{ + return 1; +} + +bool TranslateAnnotationCommand::mergeWith(const QUndoCommand *uc) +{ + TranslateAnnotationCommand *tuc = (TranslateAnnotationCommand *)uc; + + if (tuc->m_annotation != m_annotation) + return false; + + if (m_completeDrag) { + return false; + } + m_delta = Okular::NormalizedPoint(tuc->m_delta.x + m_delta.x, tuc->m_delta.y + m_delta.y); + m_completeDrag = tuc->m_completeDrag; + return true; +} + +Okular::NormalizedPoint TranslateAnnotationCommand::minusDelta() +{ + return Okular::NormalizedPoint(-m_delta.x, -m_delta.y); +} + +Okular::NormalizedRect TranslateAnnotationCommand::translateBoundingRectangle(const Okular::NormalizedPoint &delta) +{ + Okular::NormalizedRect annotBoundingRect = m_annotation->boundingRectangle(); + double left = qMin(annotBoundingRect.left, annotBoundingRect.left + delta.x); + double right = qMax(annotBoundingRect.right, annotBoundingRect.right + delta.x); + double top = qMin(annotBoundingRect.top, annotBoundingRect.top + delta.y); + double bottom = qMax(annotBoundingRect.bottom, annotBoundingRect.bottom + delta.y); + Okular::NormalizedRect boundingRect(left, top, right, bottom); + return boundingRect; +} + +bool TranslateAnnotationCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + // Same reason for not unconditionally updating m_annotation, the annotation pointer can be stored in an add/Remove command + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + + return true; +} + +AdjustAnnotationCommand::AdjustAnnotationCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber, const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2, bool completeDrag) + : m_docPriv(docPriv) + , m_annotation(annotation) + , m_pageNumber(pageNumber) + , m_delta1(delta1) + , m_delta2(delta2) + , m_completeDrag(completeDrag) +{ + setText(i18nc("Change an annotation's size", "adjust annotation")); +} + +void AdjustAnnotationCommand::undo() +{ + const NormalizedPoint minusDelta1 = Okular::NormalizedPoint(-m_delta1.x, -m_delta1.y); + const NormalizedPoint minusDelta2 = Okular::NormalizedPoint(-m_delta2.x, -m_delta2.y); + moveViewportIfBoundingRectNotFullyVisible(adjustBoundingRectangle(minusDelta1, minusDelta2), m_docPriv, m_pageNumber); + m_annotation->adjust(minusDelta1, minusDelta2); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +void AdjustAnnotationCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(adjustBoundingRectangle(m_delta1, m_delta2), m_docPriv, m_pageNumber); + m_annotation->adjust(m_delta1, m_delta2); + m_docPriv->performModifyPageAnnotation(m_pageNumber, m_annotation, true); +} + +int AdjustAnnotationCommand::id() const +{ + return 5; +} + +bool AdjustAnnotationCommand::mergeWith(const QUndoCommand *uc) +{ + AdjustAnnotationCommand *tuc = (AdjustAnnotationCommand *)uc; + + if (tuc->m_annotation != m_annotation) + return false; + + if (m_completeDrag) { + return false; + } + m_delta1 = Okular::NormalizedPoint(tuc->m_delta1.x + m_delta1.x, tuc->m_delta1.y + m_delta1.y); + m_delta2 = Okular::NormalizedPoint(tuc->m_delta2.x + m_delta2.x, tuc->m_delta2.y + m_delta2.y); + m_completeDrag = tuc->m_completeDrag; + return true; +} + +Okular::NormalizedRect AdjustAnnotationCommand::adjustBoundingRectangle(const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2) +{ + const Okular::NormalizedRect annotBoundingRect = m_annotation->boundingRectangle(); + const double left = qMin(annotBoundingRect.left, annotBoundingRect.left + delta1.x); + const double right = qMax(annotBoundingRect.right, annotBoundingRect.right + delta2.x); + const double top = qMin(annotBoundingRect.top, annotBoundingRect.top + delta1.y); + const double bottom = qMax(annotBoundingRect.bottom, annotBoundingRect.bottom + delta2.y); + return Okular::NormalizedRect(left, top, right, bottom); +} + +bool AdjustAnnotationCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + // Same reason for not unconditionally updating m_annotation, the annotation pointer can be stored in an add/Remove command + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + + return true; +} + +EditTextCommand::EditTextCommand(const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos) + : m_newContents(newContents) + , m_newCursorPos(newCursorPos) + , m_prevContents(prevContents) + , m_prevCursorPos(prevCursorPos) + , m_prevAnchorPos(prevAnchorPos) +{ + setText(i18nc("Generic text edit command", "edit text")); + + //// Determine edit type + // If There was a selection then edit was not a simple single character backspace, delete, or insert + if (m_prevCursorPos != m_prevAnchorPos) { + qCDebug(OkularCoreDebug) << "OtherEdit, selection"; + m_editType = OtherEdit; + } else if (newContentsRightOfCursor() == oldContentsRightOfCursor() && newContentsLeftOfCursor() == oldContentsLeftOfCursor().left(oldContentsLeftOfCursor().length() - 1) && oldContentsLeftOfCursor().rightRef(1) != "\n") { + qCDebug(OkularCoreDebug) << "CharBackspace"; + m_editType = CharBackspace; + } else if (newContentsLeftOfCursor() == oldContentsLeftOfCursor() && newContentsRightOfCursor() == oldContentsRightOfCursor().right(oldContentsRightOfCursor().length() - 1) && oldContentsRightOfCursor().leftRef(1) != "\n") { + qCDebug(OkularCoreDebug) << "CharDelete"; + m_editType = CharDelete; + } else if (newContentsRightOfCursor() == oldContentsRightOfCursor() && newContentsLeftOfCursor().left(newContentsLeftOfCursor().length() - 1) == oldContentsLeftOfCursor() && newContentsLeftOfCursor().rightRef(1) != "\n") { + qCDebug(OkularCoreDebug) << "CharInsert"; + m_editType = CharInsert; + } else { + qCDebug(OkularCoreDebug) << "OtherEdit"; + m_editType = OtherEdit; + } +} + +bool EditTextCommand::mergeWith(const QUndoCommand *uc) +{ + EditTextCommand *euc = (EditTextCommand *)uc; + + // Only attempt merge of euc into this if our new state matches euc's old state and + // the editTypes match and are not type OtherEdit + if (m_newContents == euc->m_prevContents && m_newCursorPos == euc->m_prevCursorPos && m_editType == euc->m_editType && m_editType != OtherEdit) { + m_newContents = euc->m_newContents; + m_newCursorPos = euc->m_newCursorPos; + return true; + } + return false; +} + +QString EditTextCommand::oldContentsLeftOfCursor() +{ + return m_prevContents.left(m_prevCursorPos); +} + +QString EditTextCommand::oldContentsRightOfCursor() +{ + return m_prevContents.right(m_prevContents.length() - m_prevCursorPos); +} + +QString EditTextCommand::newContentsLeftOfCursor() +{ + return m_newContents.left(m_newCursorPos); +} + +QString EditTextCommand::newContentsRightOfCursor() +{ + return m_newContents.right(m_newContents.length() - m_newCursorPos); +} + +EditAnnotationContentsCommand::EditAnnotationContentsCommand(DocumentPrivate *docPriv, Annotation *annotation, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos) + : EditTextCommand(newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos) + , m_docPriv(docPriv) + , m_annotation(annotation) + , m_pageNumber(pageNumber) +{ + setText(i18nc("Edit an annotation's text contents", "edit annotation contents")); +} + +void EditAnnotationContentsCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performSetAnnotationContents(m_prevContents, m_annotation, m_pageNumber); + emit m_docPriv->m_parent->annotationContentsChangedByUndoRedo(m_annotation, m_prevContents, m_prevCursorPos, m_prevAnchorPos); +} + +void EditAnnotationContentsCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_annotation->boundingRectangle(), m_docPriv, m_pageNumber); + m_docPriv->performSetAnnotationContents(m_newContents, m_annotation, m_pageNumber); + emit m_docPriv->m_parent->annotationContentsChangedByUndoRedo(m_annotation, m_newContents, m_newCursorPos, m_newCursorPos); +} + +int EditAnnotationContentsCommand::id() const +{ + return 2; +} + +bool EditAnnotationContentsCommand::mergeWith(const QUndoCommand *uc) +{ + EditAnnotationContentsCommand *euc = (EditAnnotationContentsCommand *)uc; + // Only attempt merge of euc into this if they modify the same annotation + if (m_annotation == euc->m_annotation) { + return EditTextCommand::mergeWith(uc); + } else { + return false; + } +} + +bool EditAnnotationContentsCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + auto a = newPagesVector[m_pageNumber]->annotation(m_annotation->uniqueName()); + if (a) + m_annotation = a; + + return true; +} + +EditFormTextCommand::EditFormTextCommand(Okular::DocumentPrivate *docPriv, Okular::FormFieldText *form, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos) + : EditTextCommand(newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos) + , m_docPriv(docPriv) + , m_form(form) + , m_pageNumber(pageNumber) +{ + setText(i18nc("Edit an form's text contents", "edit form contents")); +} + +void EditFormTextCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + m_form->setText(m_prevContents); + emit m_docPriv->m_parent->formTextChangedByUndoRedo(m_pageNumber, m_form, m_prevContents, m_prevCursorPos, m_prevAnchorPos); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +void EditFormTextCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + m_form->setText(m_newContents); + emit m_docPriv->m_parent->formTextChangedByUndoRedo(m_pageNumber, m_form, m_newContents, m_newCursorPos, m_newCursorPos); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +int EditFormTextCommand::id() const +{ + return 3; +} + +bool EditFormTextCommand::mergeWith(const QUndoCommand *uc) +{ + EditFormTextCommand *euc = (EditFormTextCommand *)uc; + // Only attempt merge of euc into this if they modify the same form + if (m_form == euc->m_form) { + return EditTextCommand::mergeWith(uc); + } else { + return false; + } +} + +bool EditFormTextCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + m_form = dynamic_cast(Okular::PagePrivate::findEquivalentForm(newPagesVector[m_pageNumber], m_form)); + + return m_form; +} + +EditFormListCommand::EditFormListCommand(Okular::DocumentPrivate *docPriv, FormFieldChoice *form, int pageNumber, const QList &newChoices, const QList &prevChoices) + : m_docPriv(docPriv) + , m_form(form) + , m_pageNumber(pageNumber) + , m_newChoices(newChoices) + , m_prevChoices(prevChoices) +{ + setText(i18nc("Edit a list form's choices", "edit list form choices")); +} + +void EditFormListCommand::undo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + m_form->setCurrentChoices(m_prevChoices); + emit m_docPriv->m_parent->formListChangedByUndoRedo(m_pageNumber, m_form, m_prevChoices); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +void EditFormListCommand::redo() +{ + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + m_form->setCurrentChoices(m_newChoices); + emit m_docPriv->m_parent->formListChangedByUndoRedo(m_pageNumber, m_form, m_newChoices); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +bool EditFormListCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + m_form = dynamic_cast(Okular::PagePrivate::findEquivalentForm(newPagesVector[m_pageNumber], m_form)); + + return m_form; +} + +EditFormComboCommand::EditFormComboCommand(Okular::DocumentPrivate *docPriv, FormFieldChoice *form, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos) + : EditTextCommand(newContents, newCursorPos, prevContents, prevCursorPos, prevAnchorPos) + , m_docPriv(docPriv) + , m_form(form) + , m_pageNumber(pageNumber) + , m_newIndex(-1) + , m_prevIndex(-1) +{ + setText(i18nc("Edit a combo form's selection", "edit combo form selection")); + + // Determine new and previous choice indices (if any) + for (int i = 0; i < m_form->choices().size(); i++) { + if (m_form->choices().at(i) == m_prevContents) { + m_prevIndex = i; + } + + if (m_form->choices().at(i) == m_newContents) { + m_newIndex = i; + } + } +} + +void EditFormComboCommand::undo() +{ + if (m_prevIndex != -1) { + m_form->setCurrentChoices(QList() << m_prevIndex); + } else { + m_form->setEditChoice(m_prevContents); + } + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + emit m_docPriv->m_parent->formComboChangedByUndoRedo(m_pageNumber, m_form, m_prevContents, m_prevCursorPos, m_prevAnchorPos); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +void EditFormComboCommand::redo() +{ + if (m_newIndex != -1) { + m_form->setCurrentChoices(QList() << m_newIndex); + } else { + m_form->setEditChoice(m_newContents); + } + moveViewportIfBoundingRectNotFullyVisible(m_form->rect(), m_docPriv, m_pageNumber); + emit m_docPriv->m_parent->formComboChangedByUndoRedo(m_pageNumber, m_form, m_newContents, m_newCursorPos, m_newCursorPos); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +int EditFormComboCommand::id() const +{ + return 4; +} + +bool EditFormComboCommand::mergeWith(const QUndoCommand *uc) +{ + EditFormComboCommand *euc = (EditFormComboCommand *)uc; + // Only attempt merge of euc into this if they modify the same form + if (m_form == euc->m_form) { + bool shouldMerge = EditTextCommand::mergeWith(uc); + if (shouldMerge) { + m_newIndex = euc->m_newIndex; + } + return shouldMerge; + } else { + return false; + } +} + +bool EditFormComboCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + m_form = dynamic_cast(Okular::PagePrivate::findEquivalentForm(newPagesVector[m_pageNumber], m_form)); + + return m_form; +} + +EditFormButtonsCommand::EditFormButtonsCommand(Okular::DocumentPrivate *docPriv, int pageNumber, const QList &formButtons, const QList &newButtonStates) + : m_docPriv(docPriv) + , m_pageNumber(pageNumber) + , m_formButtons(formButtons) + , m_newButtonStates(newButtonStates) + , m_prevButtonStates(QList()) +{ + setText(i18nc("Edit the state of a group of form buttons", "edit form button states")); + for (const FormFieldButton *formButton : qAsConst(m_formButtons)) { + m_prevButtonStates.append(formButton->state()); + } +} + +void EditFormButtonsCommand::undo() +{ + clearFormButtonStates(); + for (int i = 0; i < m_formButtons.size(); i++) { + bool checked = m_prevButtonStates.at(i); + if (checked) + m_formButtons.at(i)->setState(checked); + } + + Okular::NormalizedRect boundingRect = buildBoundingRectangleForButtons(m_formButtons); + moveViewportIfBoundingRectNotFullyVisible(boundingRect, m_docPriv, m_pageNumber); + emit m_docPriv->m_parent->formButtonsChangedByUndoRedo(m_pageNumber, m_formButtons); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +void EditFormButtonsCommand::redo() +{ + clearFormButtonStates(); + for (int i = 0; i < m_formButtons.size(); i++) { + bool checked = m_newButtonStates.at(i); + if (checked) + m_formButtons.at(i)->setState(checked); + } + + Okular::NormalizedRect boundingRect = buildBoundingRectangleForButtons(m_formButtons); + moveViewportIfBoundingRectNotFullyVisible(boundingRect, m_docPriv, m_pageNumber); + emit m_docPriv->m_parent->formButtonsChangedByUndoRedo(m_pageNumber, m_formButtons); + m_docPriv->notifyFormChanges(m_pageNumber); +} + +bool EditFormButtonsCommand::refreshInternalPageReferences(const QVector &newPagesVector) +{ + const QList oldFormButtons = m_formButtons; + m_formButtons.clear(); + for (FormFieldButton *oldFormButton : oldFormButtons) { + FormFieldButton *button = dynamic_cast(Okular::PagePrivate::findEquivalentForm(newPagesVector[m_pageNumber], oldFormButton)); + if (!button) + return false; + m_formButtons << button; + } + + return true; +} + +void EditFormButtonsCommand::clearFormButtonStates() +{ + for (FormFieldButton *formButton : qAsConst(m_formButtons)) { + formButton->setState(false); + } +} + +} diff --git a/core/documentcommands_p.h b/core/documentcommands_p.h new file mode 100644 index 0000000..e965629 --- /dev/null +++ b/core/documentcommands_p.h @@ -0,0 +1,263 @@ +/*************************************************************************** + * Copyright (C) 2013 Jon Mease * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_DOCUMENT_COMMANDS_P_H_ +#define _OKULAR_DOCUMENT_COMMANDS_P_H_ + +#include +#include + +#include "area.h" + +namespace Okular +{ +class Document; +class Annotation; +class DocumentPrivate; +class FormFieldText; +class FormFieldButton; +class FormFieldChoice; +class Page; + +class OkularUndoCommand : public QUndoCommand +{ +public: + virtual bool refreshInternalPageReferences(const QVector &newPagesVector) = 0; +}; + +class AddAnnotationCommand : public OkularUndoCommand +{ +public: + AddAnnotationCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber); + + ~AddAnnotationCommand() override; + + void undo() override; + + void redo() override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; + bool m_done; +}; + +class RemoveAnnotationCommand : public OkularUndoCommand +{ +public: + RemoveAnnotationCommand(Okular::DocumentPrivate *doc, Okular::Annotation *annotation, int pageNumber); + ~RemoveAnnotationCommand() override; + void undo() override; + void redo() override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; + bool m_done; +}; + +class ModifyAnnotationPropertiesCommand : public OkularUndoCommand +{ +public: + ModifyAnnotationPropertiesCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber, const QDomNode &oldProperties, const QDomNode &newProperties); + + void undo() override; + void redo() override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; + QDomNode m_prevProperties; + QDomNode m_newProperties; +}; + +class TranslateAnnotationCommand : public OkularUndoCommand +{ +public: + TranslateAnnotationCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber, const Okular::NormalizedPoint &delta, bool completeDrag); + void undo() override; + void redo() override; + int id() const override; + bool mergeWith(const QUndoCommand *uc) override; + Okular::NormalizedPoint minusDelta(); + Okular::NormalizedRect translateBoundingRectangle(const Okular::NormalizedPoint &delta); + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; + Okular::NormalizedPoint m_delta; + bool m_completeDrag; +}; + +class AdjustAnnotationCommand : public OkularUndoCommand +{ +public: + AdjustAnnotationCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber, const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2, bool completeDrag); + void undo() override; + void redo() override; + int id() const override; + bool mergeWith(const QUndoCommand *uc) override; + Okular::NormalizedRect adjustBoundingRectangle(const Okular::NormalizedPoint &delta1, const Okular::NormalizedPoint &delta2); + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; + Okular::NormalizedPoint m_delta1; + Okular::NormalizedPoint m_delta2; + bool m_completeDrag; +}; + +class EditTextCommand : public OkularUndoCommand +{ +public: + EditTextCommand(const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos); + + void undo() override = 0; + void redo() override = 0; + int id() const override = 0; + bool mergeWith(const QUndoCommand *uc) override; + +private: + enum EditType { + CharBackspace, ///< Edit made up of one or more single character backspace operations + CharDelete, ///< Edit made up of one or more single character delete operations + CharInsert, ///< Edit made up of one or more single character insertion operations + OtherEdit ///< All other edit operations (these will not be merged together) + }; + + QString oldContentsLeftOfCursor(); + QString newContentsLeftOfCursor(); + QString oldContentsRightOfCursor(); + QString newContentsRightOfCursor(); + +protected: + QString m_newContents; + int m_newCursorPos; + QString m_prevContents; + int m_prevCursorPos; + int m_prevAnchorPos; + EditType m_editType; +}; + +class EditAnnotationContentsCommand : public EditTextCommand +{ +public: + EditAnnotationContentsCommand(Okular::DocumentPrivate *docPriv, Okular::Annotation *annotation, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos); + + void undo() override; + void redo() override; + int id() const override; + bool mergeWith(const QUndoCommand *uc) override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::Annotation *m_annotation; + int m_pageNumber; +}; + +class EditFormTextCommand : public EditTextCommand +{ +public: + EditFormTextCommand(Okular::DocumentPrivate *docPriv, Okular::FormFieldText *form, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos); + void undo() override; + void redo() override; + int id() const override; + bool mergeWith(const QUndoCommand *uc) override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + Okular::FormFieldText *m_form; + int m_pageNumber; +}; + +class EditFormListCommand : public OkularUndoCommand +{ +public: + EditFormListCommand(Okular::DocumentPrivate *docPriv, FormFieldChoice *form, int pageNumber, const QList &newChoices, const QList &prevChoices); + + void undo() override; + void redo() override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + FormFieldChoice *m_form; + int m_pageNumber; + QList m_newChoices; + QList m_prevChoices; +}; + +class EditFormComboCommand : public EditTextCommand +{ +public: + EditFormComboCommand(Okular::DocumentPrivate *docPriv, FormFieldChoice *form, int pageNumber, const QString &newContents, int newCursorPos, const QString &prevContents, int prevCursorPos, int prevAnchorPos); + + void undo() override; + void redo() override; + int id() const override; + bool mergeWith(const QUndoCommand *uc) override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + Okular::DocumentPrivate *m_docPriv; + FormFieldChoice *m_form; + int m_pageNumber; + int m_newIndex; + int m_prevIndex; +}; + +class EditFormButtonsCommand : public OkularUndoCommand +{ +public: + EditFormButtonsCommand(Okular::DocumentPrivate *docPriv, int pageNumber, const QList &formButtons, const QList &newButtonStates); + + void undo() override; + void redo() override; + + bool refreshInternalPageReferences(const QVector &newPagesVector) override; + +private: + void clearFormButtonStates(); + +private: + Okular::DocumentPrivate *m_docPriv; + int m_pageNumber; + QList m_formButtons; + QList m_newButtonStates; + QList m_prevButtonStates; +}; + +} +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/fileprinter.cpp b/core/fileprinter.cpp new file mode 100644 index 0000000..dc2e9dc --- /dev/null +++ b/core/fileprinter.cpp @@ -0,0 +1,715 @@ +/*************************************************************************** + * Copyright (C) 2007,2010 by John Layt * + * * + * FilePrinterPreview based on KPrintPreview (originally LGPL) * + * Copyright (c) 2007 Alex Merry * + * * + * 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. * + ***************************************************************************/ + +#include "fileprinter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "debug_p.h" + +using namespace Okular; + +int FilePrinter::printFile(QPrinter &printer, + const QString file, // NOLINT(performance-unnecessary-value-param) clazy:exclude=function-args-by-ref TODO when BIC changes are allowed + QPrinter::Orientation documentOrientation, + FileDeletePolicy fileDeletePolicy, + PageSelectPolicy pageSelectPolicy, + const QString &pageRange) +{ + return printFile(printer, file, documentOrientation, fileDeletePolicy, pageSelectPolicy, pageRange, ScaleMode::FitToPrintArea); +} + +int FilePrinter::printFile(QPrinter &printer, + const QString file, // NOLINT(performance-unnecessary-value-param) clazy:exclude=function-args-by-ref TODO when BIC changes are allowed + QPrinter::Orientation documentOrientation, + FileDeletePolicy fileDeletePolicy, + PageSelectPolicy pageSelectPolicy, + const QString &pageRange, + ScaleMode scaleMode) +{ + FilePrinter fp; + return fp.doPrintFiles(printer, QStringList(file), fileDeletePolicy, pageSelectPolicy, pageRange, documentOrientation, scaleMode); +} + +int FilePrinter::doPrintFiles(QPrinter &printer, + const QStringList fileList, // NOLINT(performance-unnecessary-value-param) clazy:exclude=function-args-by-ref TODO when BIC changes are allowed + FileDeletePolicy fileDeletePolicy, + PageSelectPolicy pageSelectPolicy, + const QString &pageRange, + QPrinter::Orientation documentOrientation) +{ + return doPrintFiles(printer, fileList, fileDeletePolicy, pageSelectPolicy, pageRange, documentOrientation, ScaleMode::FitToPrintArea); +} + +int FilePrinter::doPrintFiles(QPrinter &printer, QStringList fileList, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, const QString &pageRange, QPrinter::Orientation documentOrientation, ScaleMode scaleMode) +{ + if (fileList.size() < 1) { + return -8; + } + + for (QStringList::ConstIterator it = fileList.constBegin(); it != fileList.constEnd(); ++it) { + if (!QFile::exists(*it)) { + return -7; + } + } + + if (printer.printerState() == QPrinter::Aborted || printer.printerState() == QPrinter::Error) { + return -6; + } + + QString exe; + QStringList argList; + int ret; + + // Print to File if a filename set, assumes there must be only 1 file + if (!printer.outputFileName().isEmpty()) { + if (QFile::exists(printer.outputFileName())) { + QFile::remove(printer.outputFileName()); + } + + QFileInfo inputFileInfo = QFileInfo(fileList[0]); + QFileInfo outputFileInfo = QFileInfo(printer.outputFileName()); + + bool doDeleteFile = (fileDeletePolicy == FilePrinter::SystemDeletesFiles); + if (inputFileInfo.suffix() == outputFileInfo.suffix()) { + if (doDeleteFile) { + bool res = QFile::rename(fileList[0], printer.outputFileName()); + if (res) { + doDeleteFile = false; + ret = 0; + } else { + ret = -5; + } + } else { + bool res = QFile::copy(fileList[0], printer.outputFileName()); + if (res) { + ret = 0; + } else { + ret = -5; + } + } + } else if (inputFileInfo.suffix() == QLatin1String("ps") && printer.outputFormat() == QPrinter::PdfFormat && ps2pdfAvailable()) { + exe = QStringLiteral("ps2pdf"); + argList << fileList[0] << printer.outputFileName(); + qCDebug(OkularCoreDebug) << "Executing" << exe << "with arguments" << argList; + ret = KProcess::execute(exe, argList); + } else if (inputFileInfo.suffix() == QLatin1String("pdf") && printer.outputFormat() == QPrinter::NativeFormat && pdf2psAvailable()) { + exe = QStringLiteral("pdf2ps"); + argList << fileList[0] << printer.outputFileName(); + qCDebug(OkularCoreDebug) << "Executing" << exe << "with arguments" << argList; + ret = KProcess::execute(exe, argList); + } else { + ret = -5; + } + + if (doDeleteFile) { + QFile::remove(fileList[0]); + } + + } else { // Print to a printer via lpr command + + // Decide what executable to use to print with, need the CUPS version of lpr if available + // Some distros name the CUPS version of lpr as lpr-cups or lpr.cups so try those first + // before default to lpr, or failing that to lp + + if (!QStandardPaths::findExecutable(QStringLiteral("lpr-cups")).isEmpty()) { + exe = QStringLiteral("lpr-cups"); + } else if (!QStandardPaths::findExecutable(QStringLiteral("lpr.cups")).isEmpty()) { + exe = QStringLiteral("lpr.cups"); + } else if (!QStandardPaths::findExecutable(QStringLiteral("lpr")).isEmpty()) { + exe = QStringLiteral("lpr"); + } else if (!QStandardPaths::findExecutable(QStringLiteral("lp")).isEmpty()) { + exe = QStringLiteral("lp"); + } else { + return -9; + } + + bool useCupsOptions = cupsAvailable(); + argList = printArguments(printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions, pageRange, exe, documentOrientation, scaleMode) << fileList; + qCDebug(OkularCoreDebug) << "Executing" << exe << "with arguments" << argList; + + ret = KProcess::execute(exe, argList); + } + + return ret; +} + +QList FilePrinter::pageList(QPrinter &printer, int lastPage, const QList &selectedPageList) +{ + return pageList(printer, lastPage, 0, selectedPageList); +} + +QList FilePrinter::pageList(QPrinter &printer, int lastPage, int currentPage, const QList &selectedPageList) +{ + if (printer.printRange() == QPrinter::Selection) { + return selectedPageList; + } + + int startPage, endPage; + QList list; + + if (printer.printRange() == QPrinter::PageRange) { + startPage = printer.fromPage(); + endPage = printer.toPage(); + } else if (printer.printRange() == QPrinter::CurrentPage) { + startPage = currentPage; + endPage = currentPage; + } else { // AllPages + startPage = 1; + endPage = lastPage; + } + + for (int i = startPage; i <= endPage; i++) { + list << i; + } + + return list; +} + +QString FilePrinter::pageRange(QPrinter &printer, int lastPage, const QList &selectedPageList) +{ + if (printer.printRange() == QPrinter::Selection) { + return pageListToPageRange(selectedPageList); + } + + if (printer.printRange() == QPrinter::PageRange) { + return QStringLiteral("%1-%2").arg(printer.fromPage()).arg(printer.toPage()); + } + + return QStringLiteral("1-%2").arg(lastPage); +} + +QString FilePrinter::pageListToPageRange(const QList &pageList) +{ + QString pageRange; + int count = pageList.count(); + int i = 0; + int seqStart = i; + int seqEnd; + + while (i != count) { + if (i + 1 == count || pageList[i] + 1 != pageList[i + 1]) { + seqEnd = i; + + if (!pageRange.isEmpty()) { + pageRange.append(QLatin1Char(',')); + } + + if (seqStart == seqEnd) { + pageRange.append(pageList[i]); + } else { + pageRange.append(QStringLiteral("%1-%2").arg(seqStart).arg(seqEnd)); + } + + seqStart = i + 1; + } + + i++; + } + + return pageRange; +} + +bool FilePrinter::ps2pdfAvailable() +{ + return (!QStandardPaths::findExecutable(QStringLiteral("ps2pdf")).isEmpty()); +} + +bool FilePrinter::pdf2psAvailable() +{ + return (!QStandardPaths::findExecutable(QStringLiteral("pdf2ps")).isEmpty()); +} + +bool FilePrinter::cupsAvailable() +{ +#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX) + // Ideally we would have access to the private Qt method + // QCUPSSupport::cupsAvailable() to do this as it is very complex routine. + // However, if CUPS is available then QPrinter::numCopies() will always return 1 + // whereas if CUPS is not available it will return the real number of copies. + // This behaviour is guaranteed never to change, so we can use it as a reliable substitute. + QPrinter testPrinter; + testPrinter.setNumCopies(2); + return (testPrinter.numCopies() == 1); +#else + return false; +#endif +} + +bool FilePrinter::detectCupsService() +{ + QTcpSocket qsock; + qsock.connectToHost(QStringLiteral("localhost"), 631); + bool rtn = qsock.waitForConnected() && qsock.isValid(); + qsock.abort(); + return rtn; +} + +bool FilePrinter::detectCupsConfig() +{ + if (QFile::exists(QStringLiteral("/etc/cups/cupsd.conf"))) + return true; + if (QFile::exists(QStringLiteral("/usr/etc/cups/cupsd.conf"))) + return true; + if (QFile::exists(QStringLiteral("/usr/local/etc/cups/cupsd.conf"))) + return true; + if (QFile::exists(QStringLiteral("/opt/etc/cups/cupsd.conf"))) + return true; + if (QFile::exists(QStringLiteral("/opt/local/etc/cups/cupsd.conf"))) + return true; + return false; +} + +QSize FilePrinter::psPaperSize(QPrinter &printer) +{ + QSize size = printer.pageLayout().pageSize().sizePoints(); + + if (printer.pageSize() == QPrinter::Custom) { + return QSize((int)printer.widthMM() * (25.4 / 72), (int)printer.heightMM() * (25.4 / 72)); + } + + if (printer.orientation() == QPrinter::Landscape) { + size.transpose(); + } + + return size; +} + +Generator::PrintError FilePrinter::printError(int c) +{ + Generator::PrintError pe; + if (c >= 0) { + pe = Generator::NoPrintError; + } else { + switch (c) { + case -1: + pe = Generator::PrintingProcessCrashPrintError; + break; + case -2: + pe = Generator::PrintingProcessStartPrintError; + break; + case -5: + pe = Generator::PrintToFilePrintError; + break; + case -6: + pe = Generator::InvalidPrinterStatePrintError; + break; + case -7: + pe = Generator::UnableToFindFilePrintError; + break; + case -8: + pe = Generator::NoFileToPrintError; + break; + case -9: + pe = Generator::NoBinaryToPrintError; + break; + default: + pe = Generator::UnknownPrintError; + } + } + return pe; +} + +QStringList +FilePrinter::printArguments(QPrinter &printer, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, bool useCupsOptions, const QString &pageRange, const QString &version, QPrinter::Orientation documentOrientation) +{ + return printArguments(printer, fileDeletePolicy, pageSelectPolicy, useCupsOptions, pageRange, version, documentOrientation, ScaleMode::FitToPrintArea); +} + +QStringList FilePrinter::printArguments(QPrinter &printer, + FileDeletePolicy fileDeletePolicy, + PageSelectPolicy pageSelectPolicy, + bool useCupsOptions, + const QString &pageRange, + const QString &version, + QPrinter::Orientation documentOrientation, + ScaleMode scaleMode) +{ + QStringList argList; + + if (!destination(printer, version).isEmpty()) { + argList << destination(printer, version); + } + + if (!copies(printer, version).isEmpty()) { + argList << copies(printer, version); + } + + if (!jobname(printer, version).isEmpty()) { + argList << jobname(printer, version); + } + + if (!pages(printer, pageSelectPolicy, pageRange, useCupsOptions, version).isEmpty()) { + argList << pages(printer, pageSelectPolicy, pageRange, useCupsOptions, version); + } + + if (useCupsOptions && !cupsOptions(printer, documentOrientation, scaleMode).isEmpty()) { + argList << cupsOptions(printer, documentOrientation, scaleMode); + } + + if (!deleteFile(printer, fileDeletePolicy, version).isEmpty()) { + argList << deleteFile(printer, fileDeletePolicy, version); + } + + if (version == QLatin1String("lp")) { + argList << QStringLiteral("--"); + } + + return argList; +} + +QStringList FilePrinter::destination(QPrinter &printer, const QString &version) +{ + if (version == QLatin1String("lp")) { + return QStringList(QStringLiteral("-d")) << printer.printerName(); + } + + if (version.startsWith(QLatin1String("lpr"))) { + return QStringList(QStringLiteral("-P")) << printer.printerName(); + } + + return QStringList(); +} + +QStringList FilePrinter::copies(QPrinter &printer, const QString &version) +{ + int cp = printer.actualNumCopies(); + + if (version == QLatin1String("lp")) { + return QStringList(QStringLiteral("-n")) << QStringLiteral("%1").arg(cp); + } + + if (version.startsWith(QLatin1String("lpr"))) { + return QStringList() << QStringLiteral("-#%1").arg(cp); + } + + return QStringList(); +} + +QStringList FilePrinter::jobname(QPrinter &printer, const QString &version) +{ + if (!printer.docName().isEmpty()) { + if (version == QLatin1String("lp")) { + return QStringList(QStringLiteral("-t")) << printer.docName(); + } + + if (version.startsWith(QLatin1String("lpr"))) { + const QString shortenedDocName = QString::fromUtf8(printer.docName().toUtf8().left(255)); + return QStringList(QStringLiteral("-J")) << shortenedDocName; + } + } + + return QStringList(); +} + +QStringList FilePrinter::deleteFile(QPrinter &, FileDeletePolicy fileDeletePolicy, const QString &version) +{ + if (fileDeletePolicy == FilePrinter::SystemDeletesFiles && version.startsWith(QLatin1String("lpr"))) { + return QStringList(QStringLiteral("-r")); + } + + return QStringList(); +} + +QStringList FilePrinter::pages(QPrinter &printer, PageSelectPolicy pageSelectPolicy, const QString &pageRange, bool useCupsOptions, const QString &version) +{ + if (pageSelectPolicy == FilePrinter::SystemSelectsPages) { + if (printer.printRange() == QPrinter::Selection && !pageRange.isEmpty()) { + if (version == QLatin1String("lp")) { + return QStringList(QStringLiteral("-P")) << pageRange; + } + + if (version.startsWith(QLatin1String("lpr")) && useCupsOptions) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("page-ranges=%1").arg(pageRange); + } + } + + if (printer.printRange() == QPrinter::PageRange) { + if (version == QLatin1String("lp")) { + return QStringList(QStringLiteral("-P")) << QStringLiteral("%1-%2").arg(printer.fromPage()).arg(printer.toPage()); + } + + if (version.startsWith(QLatin1String("lpr")) && useCupsOptions) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("page-ranges=%1-%2").arg(printer.fromPage()).arg(printer.toPage()); + } + } + } + + return QStringList(); // AllPages +} + +QStringList FilePrinter::cupsOptions(QPrinter &printer, QPrinter::Orientation documentOrientation) +{ + return cupsOptions(printer, documentOrientation, ScaleMode::FitToPrintArea); +} + +QStringList FilePrinter::cupsOptions(QPrinter &printer, QPrinter::Orientation documentOrientation, ScaleMode scaleMode) +{ + QStringList optionList; + + if (!optionMedia(printer).isEmpty()) { + optionList << optionMedia(printer); + } + + if (!optionOrientation(printer, documentOrientation).isEmpty()) { + optionList << optionOrientation(printer, documentOrientation); + } + + if (!optionDoubleSidedPrinting(printer).isEmpty()) { + optionList << optionDoubleSidedPrinting(printer); + } + + if (!optionPageOrder(printer).isEmpty()) { + optionList << optionPageOrder(printer); + } + + if (!optionCollateCopies(printer).isEmpty()) { + optionList << optionCollateCopies(printer); + } + + if (!optionPageMargins(printer, scaleMode).isEmpty()) { + optionList << optionPageMargins(printer, scaleMode); + } + + optionList << optionCupsProperties(printer); + + return optionList; +} + +QStringList FilePrinter::optionMedia(QPrinter &printer) +{ + if (!mediaPageSize(printer).isEmpty() && !mediaPaperSource(printer).isEmpty()) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("media=%1,%2").arg(mediaPageSize(printer), mediaPaperSource(printer)); + } + + if (!mediaPageSize(printer).isEmpty()) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("media=%1").arg(mediaPageSize(printer)); + } + + if (!mediaPaperSource(printer).isEmpty()) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("media=%1").arg(mediaPaperSource(printer)); + } + + return QStringList(); +} + +QString FilePrinter::mediaPageSize(QPrinter &printer) +{ + switch (printer.pageSize()) { + case QPrinter::A0: + return QStringLiteral("A0"); + case QPrinter::A1: + return QStringLiteral("A1"); + case QPrinter::A2: + return QStringLiteral("A2"); + case QPrinter::A3: + return QStringLiteral("A3"); + case QPrinter::A4: + return QStringLiteral("A4"); + case QPrinter::A5: + return QStringLiteral("A5"); + case QPrinter::A6: + return QStringLiteral("A6"); + case QPrinter::A7: + return QStringLiteral("A7"); + case QPrinter::A8: + return QStringLiteral("A8"); + case QPrinter::A9: + return QStringLiteral("A9"); + case QPrinter::B0: + return QStringLiteral("B0"); + case QPrinter::B1: + return QStringLiteral("B1"); + case QPrinter::B10: + return QStringLiteral("B10"); + case QPrinter::B2: + return QStringLiteral("B2"); + case QPrinter::B3: + return QStringLiteral("B3"); + case QPrinter::B4: + return QStringLiteral("B4"); + case QPrinter::B5: + return QStringLiteral("B5"); + case QPrinter::B6: + return QStringLiteral("B6"); + case QPrinter::B7: + return QStringLiteral("B7"); + case QPrinter::B8: + return QStringLiteral("B8"); + case QPrinter::B9: + return QStringLiteral("B9"); + case QPrinter::C5E: + return QStringLiteral("C5"); // Correct Translation? + case QPrinter::Comm10E: + return QStringLiteral("Comm10"); // Correct Translation? + case QPrinter::DLE: + return QStringLiteral("DL"); // Correct Translation? + case QPrinter::Executive: + return QStringLiteral("Executive"); + case QPrinter::Folio: + return QStringLiteral("Folio"); + case QPrinter::Ledger: + return QStringLiteral("Ledger"); + case QPrinter::Legal: + return QStringLiteral("Legal"); + case QPrinter::Letter: + return QStringLiteral("Letter"); + case QPrinter::Tabloid: + return QStringLiteral("Tabloid"); + case QPrinter::Custom: + return QStringLiteral("Custom.%1x%2mm").arg(printer.widthMM()).arg(printer.heightMM()); + default: + return QString(); + } +} + +// What about Upper and MultiPurpose? And others in PPD??? +QString FilePrinter::mediaPaperSource(QPrinter &printer) +{ + switch (printer.paperSource()) { + case QPrinter::Auto: + return QString(); + case QPrinter::Cassette: + return QStringLiteral("Cassette"); + case QPrinter::Envelope: + return QStringLiteral("Envelope"); + case QPrinter::EnvelopeManual: + return QStringLiteral("EnvelopeManual"); + case QPrinter::FormSource: + return QStringLiteral("FormSource"); + case QPrinter::LargeCapacity: + return QStringLiteral("LargeCapacity"); + case QPrinter::LargeFormat: + return QStringLiteral("LargeFormat"); + case QPrinter::Lower: + return QStringLiteral("Lower"); + case QPrinter::MaxPageSource: + return QStringLiteral("MaxPageSource"); + case QPrinter::Middle: + return QStringLiteral("Middle"); + case QPrinter::Manual: + return QStringLiteral("Manual"); + case QPrinter::OnlyOne: + return QStringLiteral("OnlyOne"); + case QPrinter::Tractor: + return QStringLiteral("Tractor"); + case QPrinter::SmallFormat: + return QStringLiteral("SmallFormat"); + default: + return QString(); + } +} + +QStringList FilePrinter::optionOrientation(QPrinter &printer, QPrinter::Orientation documentOrientation) +{ + // portrait and landscape options rotate the document according to the document orientation + // If we want to print a landscape document as one would expect it, we have to pass the + // portrait option so that the document is not rotated additionally + if (printer.orientation() == documentOrientation) { + // the user wants the document printed as is + return QStringList(QStringLiteral("-o")) << QStringLiteral("portrait"); + } else { + // the user expects the document being rotated by 90 degrees + return QStringList(QStringLiteral("-o")) << QStringLiteral("landscape"); + } +} + +QStringList FilePrinter::optionDoubleSidedPrinting(QPrinter &printer) +{ + switch (printer.duplex()) { + case QPrinter::DuplexNone: + return QStringList(QStringLiteral("-o")) << QStringLiteral("sides=one-sided"); + case QPrinter::DuplexAuto: + if (printer.orientation() == QPrinter::Landscape) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("sides=two-sided-short-edge"); + } else { + return QStringList(QStringLiteral("-o")) << QStringLiteral("sides=two-sided-long-edge"); + } + case QPrinter::DuplexLongSide: + return QStringList(QStringLiteral("-o")) << QStringLiteral("sides=two-sided-long-edge"); + case QPrinter::DuplexShortSide: + return QStringList(QStringLiteral("-o")) << QStringLiteral("sides=two-sided-short-edge"); + default: + return QStringList(); // Use printer default + } +} + +QStringList FilePrinter::optionPageOrder(QPrinter &printer) +{ + if (printer.pageOrder() == QPrinter::LastPageFirst) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("outputorder=reverse"); + } + return QStringList(QStringLiteral("-o")) << QStringLiteral("outputorder=normal"); +} + +QStringList FilePrinter::optionCollateCopies(QPrinter &printer) +{ + if (printer.collateCopies()) { + return QStringList(QStringLiteral("-o")) << QStringLiteral("Collate=True"); + } + return QStringList(QStringLiteral("-o")) << QStringLiteral("Collate=False"); +} + +QStringList FilePrinter::optionPageMargins(QPrinter &printer) +{ + return optionPageMargins(printer, ScaleMode::FitToPrintArea); +} + +QStringList FilePrinter::optionPageMargins(QPrinter &printer, ScaleMode scaleMode) +{ + if (printer.printEngine()->property(QPrintEngine::PPK_PageMargins).isNull()) { + return QStringList(); + } else { + qreal l(0), t(0), r(0), b(0); + if (!printer.fullPage()) { + printer.getPageMargins(&l, &t, &r, &b, QPrinter::Point); + } + QStringList marginOptions; + marginOptions << (QStringLiteral("-o")) << QStringLiteral("page-left=%1").arg(l) << QStringLiteral("-o") << QStringLiteral("page-top=%1").arg(t) << QStringLiteral("-o") << QStringLiteral("page-right=%1").arg(r) + << QStringLiteral("-o") << QStringLiteral("page-bottom=%1").arg(b); + if (scaleMode == ScaleMode::FitToPrintArea) { + marginOptions << QStringLiteral("-o") << QStringLiteral("fit-to-page"); + } + + return marginOptions; + } +} + +QStringList FilePrinter::optionCupsProperties(QPrinter &printer) +{ + QStringList dialogOptions = printer.printEngine()->property(QPrintEngine::PrintEnginePropertyKey(0xfe00)).toStringList(); + QStringList cupsOptions; + + for (int i = 0; i < dialogOptions.count(); i = i + 2) { + if (dialogOptions[i + 1].isEmpty()) { + cupsOptions << QStringLiteral("-o") << dialogOptions[i]; + } else { + cupsOptions << QStringLiteral("-o") << dialogOptions[i] + QLatin1Char('=') + dialogOptions[i + 1]; + } + } + + return cupsOptions; +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/fileprinter.h b/core/fileprinter.h new file mode 100644 index 0000000..8e25a28 --- /dev/null +++ b/core/fileprinter.h @@ -0,0 +1,219 @@ +/*************************************************************************** + * Copyright (C) 2007, 2010 by John Layt * + * * + * 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. * + ***************************************************************************/ + +// This Class is a temporary addition to Okular for the duration of KDE 4.0. +// In KDE 4.1 this class will either be moved to kdelibs if still required, +// or replaced with a Qt 4.4 based solution. + +#ifndef FILEPRINTER_H +#define FILEPRINTER_H + +#include +#include +#include + +#include "generator.h" +#include "okularcore_export.h" + +class QSize; + +namespace Okular +{ +class OKULARCORE_EXPORT FilePrinter +{ +public: + /** Whether file(s) get deleted by the application or by the print system. + * + * You may need to chose system deletion if your temp file clean-up + * deletes the file before the print system is finished with it. + */ + enum FileDeletePolicy { ApplicationDeletesFiles, SystemDeletesFiles }; + + /** Whether pages to be printed are selected by the application or the print system. + * + * If application side, then the generated file will only contain those pages + * selected by the user, so FilePrinter will print all the pages in the file. + * + * If system side, then the file will contain all the pages in the document, and + * the print system will print the users selected print range from out of the file. + * + * Note system side only works in CUPS, not LPR. + */ + enum PageSelectPolicy { ApplicationSelectsPages, SystemSelectsPages }; + + /** Whether to apply scaling when printing. + * + * 'NoScaling' indicates that no scaling should be applied. + * 'FitToPrintArea' indicates that the document should be scaled to the + * area that is available for printing. Whether or not this includes the printer's + * hardware margins depends on the value of 'QPrinter::fullPage()' for the given printer. + * + * @since 1.8 + */ + enum ScaleMode { NoScaling = 0, FitToPrintArea = 1 }; + + /** Print a file using the settings in QPrinter + * + * Only supports CUPS and LPR on *NIX. Page Range only supported in CUPS. + * Most settings unsupported by LPR, some settings unsupported by CUPS. + * + * The documentOrientation parameter was added in version 0.14. + * + * @param printer the print settings to use + * @param file the file to print + * @param documentOrientation the orientation stored in the document itself + * @param scaleMode scale mode to use + * @param fileDeletePolicy if the application or system deletes the file + * @param pageSelectPolicy if the application or system selects the pages to print + * @param pageRange page range to print if SystemSelectsPages and user chooses Selection in Print Dialog + * + * @returns Returns exit code: + * -9 if lpr not found + * -8 if empty file name + * -7 if unable to find file + * -6 if invalid printer state + * -5 if print to file copy failed + * -2 if the KProcess could not be started + * -1 if the KProcess crashed + * otherwise the KProcess exit code + * + * @since 1.8 + */ + // TODO make file const QString & when a BIC change happens somehwere else + static int printFile(QPrinter &printer, const QString file, QPrinter::Orientation documentOrientation, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, const QString &pageRange, ScaleMode scaleMode); + + /** Print a file using the settings in QPrinter + * + * Same as 'printFile()' with 7 parameters, but always using a 'scaleMode' of + * 'FitToPrintArea'. + * + * @since 0.14 (KDE 4.8) + */ + // TODO merge with function above when a BIC change happens somehwere else + static int printFile(QPrinter &printer, + const QString file, + QPrinter::Orientation documentOrientation, + FileDeletePolicy fileDeletePolicy = FilePrinter::ApplicationDeletesFiles, + PageSelectPolicy pageSelectPolicy = FilePrinter::ApplicationSelectsPages, + const QString &pageRange = QString()); + + /** Return the list of pages selected by the user in the Print Dialog + * + * @param printer the print settings to use + * @param lastPage the last page number, needed if AllPages option is selected + * @param currentPage the current page number, needed if CurrentPage option is selected + * @param selectedPageList list of pages to use if Selection option is selected + * @returns Returns list of pages to print + */ + static QList pageList(QPrinter &printer, int lastPage, int currentPage, const QList &selectedPageList); + + /** Return the list of pages selected by the user in the Print Dialog + * + * @param printer the print settings to use + * @param lastPage the last page number, needed if AllPages option is selected + * @param selectedPageList list of pages to use if Selection option is selected + * @returns Returns list of pages to print + */ + static QList pageList(QPrinter &printer, int lastPage, const QList &selectedPageList); + + /** Return the range of pages selected by the user in the Print Dialog + * + * @param printer the print settings to use + * @param lastPage the last page number, needed if AllPages option is selected + * @param selectedPageList list of pages to use if Selection option is selected + * @returns Returns range of pages to print + */ + static QString pageRange(QPrinter &printer, int lastPage, const QList &selectedPageList); + + /** convert a Page List into a Page Range + * + * @param pageList list of pages to convert + * @returns Returns equivalent page range + */ + static QString pageListToPageRange(const QList &pageList); + + /** Return if Ghostscript ps2pdf is available on this system + * + * @returns Returns true if Ghostscript ps2pdf available + */ + static bool ps2pdfAvailable(); + + /** Return if Ghostscript pdf2ps is available on this system + * + * @returns Returns true if Ghostscript pdf2ps available + */ + static bool pdf2psAvailable(); + + /** Return if CUPS Print System is available on this system + * + * @returns Returns true if CUPS available + */ + static bool cupsAvailable(); + + /** Returns the postscript standard page size + * + * @returns Returns paper size in ps points + */ + static QSize psPaperSize(QPrinter &printer); + + /** + * Convert the code returned by printFile* to PrintError + * @since 0.11 (KDE 4.5) + */ + static Generator::PrintError printError(int c); + +protected: + bool detectCupsService(); + bool detectCupsConfig(); + + // TODO make fileList const QStringList & when a BIC change happens somehwere else + int doPrintFiles(QPrinter &printer, const QStringList fileList, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, const QString &pageRange, QPrinter::Orientation documentOrientation); + // TODO merge with function above when a BIC change happens somehwere else + /// @since 1.8 + int doPrintFiles(QPrinter &printer, const QStringList fileList, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, const QString &pageRange, QPrinter::Orientation documentOrientation, ScaleMode scaleMode); + + QStringList printArguments(QPrinter &printer, FileDeletePolicy fileDeletePolicy, PageSelectPolicy pageSelectPolicy, bool useCupsOptions, const QString &pageRange, const QString &version, QPrinter::Orientation documentOrientation); + // TODO merge with function above when a BIC change happens somehwere else + /// @since 1.8 + QStringList printArguments(QPrinter &printer, + FileDeletePolicy fileDeletePolicy, + PageSelectPolicy pageSelectPolicy, + bool useCupsOptions, + const QString &pageRange, + const QString &version, + QPrinter::Orientation documentOrientation, + ScaleMode scaleMode); + + QStringList destination(QPrinter &printer, const QString &version); + QStringList copies(QPrinter &printer, const QString &version); + QStringList jobname(QPrinter &printer, const QString &version); + QStringList deleteFile(QPrinter &printer, FileDeletePolicy fileDeletePolicy, const QString &version); + QStringList pages(QPrinter &printer, PageSelectPolicy pageSelectPolicy, const QString &pageRange, bool useCupsOptions, const QString &version); + + QStringList cupsOptions(QPrinter &printer, QPrinter::Orientation documentOrientation); + // TODO merge with function above when a BIC change happens somehwere else + /// @since 1.8 + QStringList cupsOptions(QPrinter &printer, QPrinter::Orientation documentOrientation, ScaleMode scaleMode); + QStringList optionMedia(QPrinter &printer); + QString mediaPageSize(QPrinter &printer); + QString mediaPaperSource(QPrinter &printer); + QStringList optionOrientation(QPrinter &printer, QPrinter::Orientation documentOrientation); + QStringList optionDoubleSidedPrinting(QPrinter &printer); + QStringList optionPageOrder(QPrinter &printer); + QStringList optionCollateCopies(QPrinter &printer); + QStringList optionPageMargins(QPrinter &printer); + // TODO merge with function above when a BIC change happens somehwere else + /// @since 1.8 + QStringList optionPageMargins(QPrinter &printer, ScaleMode scaleMode); + QStringList optionCupsProperties(QPrinter &printer); +}; + +} + +#endif // FILEPRINTER_H diff --git a/core/fontinfo.cpp b/core/fontinfo.cpp new file mode 100644 index 0000000..e28451a --- /dev/null +++ b/core/fontinfo.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +// local includes +#include "fontinfo.h" + +#include + +using namespace Okular; + +class Okular::FontInfoPrivate : public QSharedData +{ +public: + FontInfoPrivate() + : type(FontInfo::Unknown) + , embedType(FontInfo::NotEmbedded) + , canBeExtracted(false) + { + } + + bool operator==(const FontInfoPrivate &rhs) const + { + return name == rhs.name && substituteName == rhs.substituteName && type == rhs.type && embedType == rhs.embedType && file == rhs.file && canBeExtracted == rhs.canBeExtracted; + } + + QString name; + QString substituteName; + FontInfo::FontType type; + FontInfo::EmbedType embedType; + bool canBeExtracted; + QString file; + QVariant nativeId; +}; + +FontInfo::FontInfo() + : d(new FontInfoPrivate) +{ +} + +FontInfo::FontInfo(const FontInfo &fi) + : d(fi.d) +{ +} + +FontInfo::~FontInfo() +{ +} + +QString FontInfo::name() const +{ + return d->name; +} + +void FontInfo::setName(const QString &name) +{ + d->name = name; +} + +QString FontInfo::substituteName() const +{ + return d->substituteName; +} + +void FontInfo::setSubstituteName(const QString &substituteName) +{ + d->substituteName = substituteName; +} + +FontInfo::FontType FontInfo::type() const +{ + return d->type; +} + +void FontInfo::setType(FontInfo::FontType type) +{ + d->type = type; +} + +FontInfo::EmbedType FontInfo::embedType() const +{ + return d->embedType; +} + +void FontInfo::setEmbedType(FontInfo::EmbedType type) +{ + d->embedType = type; +} + +QString FontInfo::file() const +{ + return d->file; +} + +void FontInfo::setFile(const QString &file) +{ + d->file = file; +} + +bool FontInfo::canBeExtracted() const +{ + return d->canBeExtracted; +} + +void FontInfo::setCanBeExtracted(bool extractable) +{ + d->canBeExtracted = extractable; +} + +void FontInfo::setNativeId(const QVariant &id) +{ + d->nativeId = id; +} + +QVariant FontInfo::nativeId() const +{ + return d->nativeId; +} + +bool FontInfo::operator==(const FontInfo &fi) const +{ + return *d == *fi.d; +} + +bool FontInfo::operator!=(const FontInfo &fi) const +{ + return !operator==(fi); +} + +FontInfo &FontInfo::operator=(const FontInfo &fi) +{ + if (this == &fi) + return *this; + + d = fi.d; + return *this; +} diff --git a/core/fontinfo.h b/core/fontinfo.h new file mode 100644 index 0000000..d4fcb73 --- /dev/null +++ b/core/fontinfo.h @@ -0,0 +1,166 @@ +/*************************************************************************** + * Copyright (C) 2007 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_FONTINFO_H_ +#define _OKULAR_FONTINFO_H_ + +#include +#include +#include +#include + +#include "okularcore_export.h" + +namespace Okular +{ +class FontInfoPrivate; + +/** + * @short A small class that represents the information of a font. + */ +class OKULARCORE_EXPORT FontInfo +{ +public: + typedef QVector List; + + /** + * The possible kinds of fonts. + */ + enum FontType { + Unknown, + Type1, + Type1C, + Type1COT, + Type3, + TrueType, + TrueTypeOT, + CIDType0, + CIDType0C, + CIDType0COT, + CIDTrueType, + CIDTrueTypeOT, + TeXPK, ///< @since 0.10 (KDE 4.4) + TeXVirtual, ///< @since 0.10 (KDE 4.4) + TeXFontMetric, ///< @since 0.10 (KDE 4.4) + TeXFreeTypeHandled ///< @since 0.10 (KDE 4.4) + }; + + /** + * The possible kinds of embed. + */ + enum EmbedType { NotEmbedded, EmbeddedSubset, FullyEmbedded }; + + /** + * Construct a new empty font info. + */ + FontInfo(); + /** + * Copy constructor. + */ + FontInfo(const FontInfo &fi); + /** + * Destructor. + */ + ~FontInfo(); + + /** + * Returns the name of the font. + */ + QString name() const; + /** + * Sets a new name for the font. + */ + void setName(const QString &name); + + /** + * Returns the substitute name for the font. + */ + QString substituteName() const; + + /** + * Sets a new substitute name for the font. + */ + void setSubstituteName(const QString &substituteName); + + /** + * Returns the type of the font. + */ + FontType type() const; + /** + * Change the type of the font. + */ + void setType(FontType type); + + /** + * Returns the type of font embedding. + */ + EmbedType embedType() const; + /** + * Sets the type of font embedding. + */ + void setEmbedType(EmbedType type); + + /** + * In case of not embedded font, returns the path of the font that + * represents this font. + */ + QString file() const; + void setFile(const QString &file); + + /** + * In case of embedded fonts, returns if the font can be extracted into a QByteArray + * + * @since 0.8 (KDE 4.2) + */ + bool canBeExtracted() const; + + /** + * Sets if a font can be extracted or not. False by default + */ + void setCanBeExtracted(bool extractable); + + /** + * Sets the "native" @p id of the font info. + * + * This is for use of the Generator, that can optionally store an + * handle (a pointer, an identifier, etc) of the "native" font + * object, if any. + * + * @since 0.8 (KDE 4.2) + */ + void setNativeId(const QVariant &id); + + /** + * Returns the "native" id of the font info. + * + * @since 0.8 (KDE 4.2) + */ + QVariant nativeId() const; + + FontInfo &operator=(const FontInfo &fi); + + /** + * Comparison operator. + */ + bool operator==(const FontInfo &fi) const; + + bool operator!=(const FontInfo &fi) const; + +private: + /// @cond PRIVATE + friend class FontInfoPrivate; + /// @endcond + QSharedDataPointer d; +}; + +} + +Q_DECLARE_METATYPE(Okular::FontInfo) + +#endif diff --git a/core/form.cpp b/core/form.cpp new file mode 100644 index 0000000..75fdc1b --- /dev/null +++ b/core/form.cpp @@ -0,0 +1,344 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "form.h" +#include "form_p.h" + +// qt includes +#include + +#include "action.h" + +using namespace Okular; + +FormFieldPrivate::FormFieldPrivate(FormField::FieldType type) + : m_type(type) + , m_activateAction(nullptr) +{ +} + +FormFieldPrivate::~FormFieldPrivate() +{ + delete m_activateAction; + qDeleteAll(m_additionalActions); + qDeleteAll(m_additionalAnnotActions); +} + +void FormFieldPrivate::setDefault() +{ + m_default = value(); +} + +FormField::FormField(FormFieldPrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} + +FormField::~FormField() +{ + delete d_ptr; +} + +FormField::FieldType FormField::type() const +{ + Q_D(const FormField); + return d->m_type; +} + +bool FormField::isReadOnly() const +{ + return false; +} + +void FormField::setReadOnly(bool) +{ +} + +bool FormField::isVisible() const +{ + return true; +} + +void FormField::setVisible(bool) +{ +} + +bool FormField::isPrintable() const +{ + return true; +} + +void FormField::setPrintable(bool) +{ +} + +Action *FormField::activationAction() const +{ + Q_D(const FormField); + return d->m_activateAction; +} + +void FormField::setActivationAction(Action *action) +{ + Q_D(FormField); + delete d->m_activateAction; + d->m_activateAction = action; +} + +Action *FormField::additionalAction(AdditionalActionType type) const +{ + Q_D(const FormField); + return d->m_additionalActions.value(type); +} + +void FormField::setAdditionalAction(AdditionalActionType type, Action *action) +{ + Q_D(FormField); + delete d->m_additionalActions.value(type); + d->m_additionalActions[type] = action; +} + +Action *FormField::additionalAction(Annotation::AdditionalActionType type) const +{ + Q_D(const FormField); + return d->m_additionalAnnotActions.value(type); +} + +void FormField::setAdditionalAction(Annotation::AdditionalActionType type, Action *action) +{ + Q_D(FormField); + delete d->m_additionalAnnotActions.value(type); + d->m_additionalAnnotActions[type] = action; +} + +class Okular::FormFieldButtonPrivate : public Okular::FormFieldPrivate +{ +public: + FormFieldButtonPrivate() + : FormFieldPrivate(FormField::FormButton) + { + } + + Q_DECLARE_PUBLIC(FormFieldButton) + + void setValue(const QString &v) override + { + Q_Q(FormFieldButton); + q->setState(QVariant(v).toBool()); + } + + QString value() const override + { + Q_Q(const FormFieldButton); + return QVariant::fromValue(q->state()).toString(); + } +}; + +FormFieldButton::FormFieldButton() + : FormField(*new FormFieldButtonPrivate()) +{ +} + +FormFieldButton::~FormFieldButton() +{ +} + +void FormFieldButton::setState(bool) +{ +} + +void FormFieldButton::setIcon(Okular::FormField *) +{ +} + +class Okular::FormFieldTextPrivate : public Okular::FormFieldPrivate +{ +public: + FormFieldTextPrivate() + : FormFieldPrivate(FormField::FormText) + { + } + + Q_DECLARE_PUBLIC(FormFieldText) + + void setValue(const QString &v) override + { + Q_Q(FormFieldText); + q->setText(v); + } + + QString value() const override + { + Q_Q(const FormFieldText); + return q->text(); + } +}; + +FormFieldText::FormFieldText() + : FormField(*new FormFieldTextPrivate()) +{ +} + +FormFieldText::~FormFieldText() +{ +} + +void FormFieldText::setText(const QString &) +{ +} + +bool FormFieldText::isPassword() const +{ + return false; +} + +bool FormFieldText::isRichText() const +{ + return false; +} + +int FormFieldText::maximumLength() const +{ + return -1; +} + +Qt::Alignment FormFieldText::textAlignment() const +{ + return Qt::AlignVCenter | Qt::AlignLeft; +} + +bool FormFieldText::canBeSpellChecked() const +{ + return false; +} + +class Okular::FormFieldChoicePrivate : public Okular::FormFieldPrivate +{ +public: + FormFieldChoicePrivate() + : FormFieldPrivate(FormField::FormChoice) + { + } + + Q_DECLARE_PUBLIC(FormFieldChoice) + + void setValue(const QString &v) override + { + Q_Q(FormFieldChoice); + const QStringList choices = v.split(QLatin1Char(';'), QString::SkipEmptyParts); + QList newchoices; + for (const QString &str : choices) { + bool ok = true; + int val = str.toInt(&ok); + if (ok) + newchoices.append(val); + } + if (!newchoices.isEmpty()) + q->setCurrentChoices(newchoices); + } + + QString value() const override + { + Q_Q(const FormFieldChoice); + QList choices = q->currentChoices(); + std::sort(choices.begin(), choices.end()); + QStringList list; + for (const int c : qAsConst(choices)) { + list.append(QString::number(c)); + } + return list.join(QStringLiteral(";")); + } + + QMap exportValues; +}; + +FormFieldChoice::FormFieldChoice() + : FormField(*new FormFieldChoicePrivate()) +{ +} + +FormFieldChoice::~FormFieldChoice() +{ +} + +bool FormFieldChoice::isEditable() const +{ + return false; +} + +bool FormFieldChoice::multiSelect() const +{ + return false; +} + +void FormFieldChoice::setCurrentChoices(const QList &) +{ +} + +QString FormFieldChoice::editChoice() const +{ + return QString(); +} + +void FormFieldChoice::setEditChoice(const QString &) +{ +} + +Qt::Alignment FormFieldChoice::textAlignment() const +{ + return Qt::AlignVCenter | Qt::AlignLeft; +} + +bool FormFieldChoice::canBeSpellChecked() const +{ + return false; +} + +void FormFieldChoice::setExportValues(const QMap &values) +{ + Q_D(FormFieldChoice); + d->exportValues = values; +} + +QString FormFieldChoice::exportValueForChoice(const QString &choice) const +{ + Q_D(const FormFieldChoice); + return d->exportValues.value(choice, choice); +} + +class Okular::FormFieldSignaturePrivate : public Okular::FormFieldPrivate +{ +public: + FormFieldSignaturePrivate() + : FormFieldPrivate(FormField::FormSignature) + { + } + + Q_DECLARE_PUBLIC(FormFieldSignature) + + void setValue(const QString &v) override + { + Q_UNUSED(v) + } + + QString value() const override + { + return QString(); + } +}; + +FormFieldSignature::FormFieldSignature() + : FormField(*new FormFieldSignaturePrivate()) +{ +} + +FormFieldSignature::~FormFieldSignature() +{ +} diff --git a/core/form.h b/core/form.h new file mode 100644 index 0000000..4308560 --- /dev/null +++ b/core/form.h @@ -0,0 +1,475 @@ +/*************************************************************************** + * Copyright (C) 2007 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_FORM_H_ +#define _OKULAR_FORM_H_ + +#include "annotations.h" +#include "area.h" +#include "okularcore_export.h" +#include "signatureutils.h" + +#include + +#include + +namespace Okular +{ +class Action; +class Page; +class PagePrivate; +class FormFieldPrivate; +class FormFieldButtonPrivate; +class FormFieldTextPrivate; +class FormFieldChoicePrivate; +class FormFieldSignaturePrivate; + +/** + * @short The base interface of a form field. + * + * This is the very basic interface to represent a field in a form. + * + * This is not meant to be used as a direct base for the form fields in a + * document, but its abstract subclasses are. + */ +class OKULARCORE_EXPORT FormField +{ + /// @cond PRIVATE + friend class Page; + friend class PagePrivate; + /// @endcond + +public: + /** + * The types of form field. + */ + enum FieldType { + FormButton, ///< A "button". See @ref FormFieldButton::ButtonType. + FormText, ///< A field of variable text. See @ref FormFieldText::TextType. + FormChoice, ///< A choice field. See @ref FormFieldChoice::ChoiceType. + FormSignature ///< A signature. + }; + + virtual ~FormField(); + + /** + * The type of the field. + */ + FieldType type() const; + + /** + * The bounding rect of the field, in normalized coordinates. + */ + virtual NormalizedRect rect() const = 0; + + /** + * The ID of the field. + */ + virtual int id() const = 0; + + /** + * The internal name of the field, to be used when referring to the + * field in eg scripts. + */ + virtual QString name() const = 0; + + /** + * The visible name of the field, to be used in the user interface + * (eg in error messages, etc). + */ + virtual QString uiName() const = 0; + + /** + * The fully qualified name of the field, is used in the JavaScript + * scripts. + * + * @since 1.9 + */ + virtual QString fullyQualifiedName() const = 0; + + /** + * Whether the field is read-only. + */ + virtual bool isReadOnly() const; + + /** + * Whether the field is read-only. + * + * @since 1.4 + */ + virtual void setReadOnly(bool value); + + /** + * Whether this form field is visible. + */ + virtual bool isVisible() const; + + /** + * Whether the field is visible. + * + * @since 1.5 + */ + virtual void setVisible(bool value); + + /** + Whether this field is printable. + + @since 1.9 + */ + virtual bool isPrintable() const; + + /** + Set this field printable + + @since 1.9 + */ + virtual void setPrintable(bool value); + + Action *activationAction() const; + + /** + * Describes the type of form additional action. + * + * @since 1.1 + */ + enum AdditionalActionType { + FieldModified, ///< An action to be performed when the user modifies the field + FormatField, ///< An action to be performed before the field is formatted to display its value + ValidateField, ///< An action to be performed when the field value changes + CalculateField, ///< An action to be performed when the field needs to be recalculated + }; + + /** + * Returns the additional action of the given @p type or @c nullptr if no action has been defined. + * + * @since 1.1 + */ + Action *additionalAction(AdditionalActionType type) const; + + /* Returns the additional action of the given @p type or @c nullptr if no action has been defined. + * + * This is for actions of annotation widgets associated with the FormField + * + * @since 1.5 + */ + Action *additionalAction(Annotation::AdditionalActionType type) const; + +protected: + /// @cond PRIVATE + FormField(FormFieldPrivate &dd); + Q_DECLARE_PRIVATE(FormField) + FormFieldPrivate *d_ptr; + /// @endcond + + void setActivationAction(Action *action); + void setAdditionalAction(AdditionalActionType type, Action *action); + void setAdditionalAction(Annotation::AdditionalActionType type, Action *action); + +private: + Q_DISABLE_COPY(FormField) +}; + +/** + * @short Interface of a button form field. + * + * This is the base interface to reimplement to represent a button field, like + * a push button, a check box or a radio button. + * + * @since 0.7 (KDE 4.1) + */ +class OKULARCORE_EXPORT FormFieldButton : public FormField +{ +public: + /** + * The types of button field. + */ + enum ButtonType { + Push, ///< A simple push button. + CheckBox, ///< A check box. + Radio ///< A radio button. + }; + + ~FormFieldButton() override; + + /** + The particular type of the button field. + */ + virtual ButtonType buttonType() const = 0; + + /** + * The caption to be used for the button. + */ + virtual QString caption() const = 0; + + /** + * The state of the button. + */ + virtual bool state() const = 0; + + /** + * Sets the state of the button to the new \p state . + */ + virtual void setState(bool state); + + /** + * The list with the IDs of siblings (ie, buttons belonging to the same + * group as the current one. + * + * Valid only for \ref Radio buttons, an empty list otherwise. + */ + virtual QList siblings() const = 0; + + /** + * Sets the icon of the Button to the Icon of the field parameter. + * + * @since 1.9 + */ + virtual void setIcon(Okular::FormField *field); + +protected: + FormFieldButton(); + +private: + Q_DECLARE_PRIVATE(FormFieldButton) + Q_DISABLE_COPY(FormFieldButton) +}; + +/** + * @short Interface of a text form field. + * + * This is the base interface to reimplement to represent a text field, ie a + * field where the user insert text. + */ +class OKULARCORE_EXPORT FormFieldText : public FormField +{ +public: + /** + * The types of text field. + */ + enum TextType { + Normal, ///< A simple singleline text field. + Multiline, ///< A multiline text field. + FileSelect ///< An input field to select the path of a file on disk. + }; + + ~FormFieldText() override; + + /** + * The particular type of the text field. + */ + virtual TextType textType() const = 0; + + /** + * The text of text field. + */ + virtual QString text() const = 0; + + /** + * Sets the new @p text in the text field. + * + * The default implementation does nothing. + * + * Reimplemented only if the setting of new text is supported. + */ + virtual void setText(const QString &text); + + /** + * Whether this text field is a password input, eg its text @b must be + * replaced with asterisks. + * + * Always false for @ref FileSelect text fields. + */ + virtual bool isPassword() const; + + /** + * Whether this text field should allow rich text. + */ + virtual bool isRichText() const; + + /** + * The maximum length allowed for the text of text field, or -1 if + * there is no limitation for the text. + */ + virtual int maximumLength() const; + + /** + * The alignment of the text within the field. + */ + virtual Qt::Alignment textAlignment() const; + + /** + * Whether the text inserted manually in the field (where possible) + * can be spell-checked. + * + * @note meaningful only if the field is editable. + */ + virtual bool canBeSpellChecked() const; + + /** + * Set the text which should be rendered by the PDF. + * + * @since 1.9 + */ + virtual void setAppearanceText(const QString &text) = 0; + +protected: + FormFieldText(); + +private: + Q_DECLARE_PRIVATE(FormFieldText) + Q_DISABLE_COPY(FormFieldText) +}; + +/** + * @short Interface of a choice form field. + * + * This is the base interface to reimplement to represent a choice field, ie a + * field where the user can select one (of more) element(s) among a set of + * choices. + */ +class OKULARCORE_EXPORT FormFieldChoice : public FormField +{ +public: + /** + * The types of choice field. + */ + enum ChoiceType { + ComboBox, ///< A combo box choice field. + ListBox ///< A list box choice field. + }; + + ~FormFieldChoice() override; + + /** + * The particular type of the choice field. + */ + virtual ChoiceType choiceType() const = 0; + + /** + * The possible choices of the choice field. + */ + virtual QStringList choices() const = 0; + + /** + * Whether this ComboBox is editable, ie the user can type in a custom + * value. + * + * Always false for the other types of choices. + */ + virtual bool isEditable() const; + + /** + * Whether more than one choice of this ListBox can be selected at the + * same time. + * + * Always false for the other types of choices. + */ + virtual bool multiSelect() const; + + /** + * The currently selected choices. + * + * Always one element in the list in case of single choice elements. + */ + virtual QList currentChoices() const = 0; + + /** + * Sets the selected choices to @p choices . + */ + virtual void setCurrentChoices(const QList &choices); + + /** + The text entered into an editable combo box choice field + + @since 0.16 (KDE 4.10) + */ + virtual QString editChoice() const; + + /** + Sets the text entered into an editable combo box choice field + + @since 0.16 (KDE 4.10) + */ + virtual void setEditChoice(const QString &text); + + /** + * The alignment of the text within the field. + */ + virtual Qt::Alignment textAlignment() const; + + /** + * Whether the text inserted manually in the field (where possible) + * can be spell-checked. + * + * @note meaningful only if the field is editable. + */ + virtual bool canBeSpellChecked() const; + + /** + * Returns the export value for a given choice + * + * @since 1.11 + */ + QString exportValueForChoice(const QString &choice) const; + +protected: + FormFieldChoice(); + + /** + * The possible choices of the choice field. + * The key is the display name of the choice, + * The value is the export value (i.e. for use in javascript, etc) of the choice + * + * @since 1.11 + */ + void setExportValues(const QMap &values); + +private: + Q_DECLARE_PRIVATE(FormFieldChoice) + Q_DISABLE_COPY(FormFieldChoice) +}; + +/** + * @short Interface of a signature form field. + * + * This is the base interface to reimplement to represent a signature field. + */ +class OKULARCORE_EXPORT FormFieldSignature : public FormField +{ +public: + /** + * The types of signature. + */ + enum SignatureType { AdbePkcs7sha1, AdbePkcs7detached, EtsiCAdESdetached, UnknownType }; + + ~FormFieldSignature() override; + + /** + * The signature type + */ + virtual SignatureType signatureType() const = 0; + + /** + * The signature info + */ + virtual const SignatureInfo &signatureInfo() const = 0; + +protected: + FormFieldSignature(); + +private: + Q_DECLARE_PRIVATE(FormFieldSignature) + Q_DISABLE_COPY(FormFieldSignature) +}; + +} + +Q_DECLARE_METATYPE(const Okular::FormFieldSignature *); + +#endif diff --git a/core/form_p.h b/core/form_p.h new file mode 100644 index 0000000..9710c2b --- /dev/null +++ b/core/form_p.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2007 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_FORM_P_H +#define OKULAR_FORM_P_H + +#include "form.h" + +#include + +namespace Okular +{ +class Action; +class FormField; + +class FormFieldPrivate +{ +public: + explicit FormFieldPrivate(FormField::FieldType type); + virtual ~FormFieldPrivate(); + + FormFieldPrivate(const FormFieldPrivate &) = delete; + FormFieldPrivate &operator=(const FormFieldPrivate &) = delete; + + void setDefault(); + + virtual void setValue(const QString &) = 0; + virtual QString value() const = 0; + + FormField::FieldType m_type; + QString m_default; + Action *m_activateAction; + QHash m_additionalActions; + QHash m_additionalAnnotActions; + + Q_DECLARE_PUBLIC(FormField) + FormField *q_ptr; +}; + +} + +#endif diff --git a/core/generator.cpp b/core/generator.cpp new file mode 100644 index 0000000..367241a --- /dev/null +++ b/core/generator.cpp @@ -0,0 +1,795 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymanski * + * Copyright (C) 2008 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "generator.h" +#include "generator_p.h" +#include "observer.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef WITH_KWALLET +#include +#endif + +#include "document_p.h" +#include "page.h" +#include "page_p.h" +#include "textpage.h" +#include "utils.h" + +using namespace Okular; + +GeneratorPrivate::GeneratorPrivate() + : m_document(nullptr) + , mPixmapGenerationThread(nullptr) + , mTextPageGenerationThread(nullptr) + , mPixmapReady(true) + , mTextPageReady(true) + , m_closing(false) + , m_closingLoop(nullptr) + , m_dpi(72.0, 72.0) +{ + qRegisterMetaType(); +} + +GeneratorPrivate::~GeneratorPrivate() +{ + if (mPixmapGenerationThread) + mPixmapGenerationThread->wait(); + + delete mPixmapGenerationThread; + + if (mTextPageGenerationThread) + mTextPageGenerationThread->wait(); + + delete mTextPageGenerationThread; +} + +PixmapGenerationThread *GeneratorPrivate::pixmapGenerationThread() +{ + if (mPixmapGenerationThread) + return mPixmapGenerationThread; + + Q_Q(Generator); + mPixmapGenerationThread = new PixmapGenerationThread(q); + QObject::connect( + mPixmapGenerationThread, &PixmapGenerationThread::finished, q, [this] { pixmapGenerationFinished(); }, Qt::QueuedConnection); + + return mPixmapGenerationThread; +} + +TextPageGenerationThread *GeneratorPrivate::textPageGenerationThread() +{ + if (mTextPageGenerationThread) + return mTextPageGenerationThread; + + Q_Q(Generator); + mTextPageGenerationThread = new TextPageGenerationThread(q); + QObject::connect( + mTextPageGenerationThread, &TextPageGenerationThread::finished, q, [this] { textpageGenerationFinished(); }, Qt::QueuedConnection); + + return mTextPageGenerationThread; +} + +void GeneratorPrivate::pixmapGenerationFinished() +{ + Q_Q(Generator); + PixmapRequest *request = mPixmapGenerationThread->request(); + const QImage &img = mPixmapGenerationThread->image(); + mPixmapGenerationThread->endGeneration(); + + QMutexLocker locker(threadsLock()); + + if (m_closing) { + mPixmapReady = true; + delete request; + if (mTextPageReady) { + locker.unlock(); + m_closingLoop->quit(); + } + return; + } + + if (!request->shouldAbortRender()) { + request->page()->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(img)), request->normalizedRect()); + const int pageNumber = request->page()->number(); + + if (mPixmapGenerationThread->calcBoundingBox()) + q->updatePageBoundingBox(pageNumber, mPixmapGenerationThread->boundingBox()); + } else { + // Cancel the text page generation too if it's still running + if (mTextPageGenerationThread && mTextPageGenerationThread->isRunning()) { + mTextPageGenerationThread->abortExtraction(); + mTextPageGenerationThread->wait(); + } + } + + mPixmapReady = true; + q->signalPixmapRequestDone(request); +} + +void GeneratorPrivate::textpageGenerationFinished() +{ + Q_Q(Generator); + Page *page = mTextPageGenerationThread->page(); + mTextPageGenerationThread->endGeneration(); + + QMutexLocker locker(threadsLock()); + mTextPageReady = true; + + if (m_closing) { + delete mTextPageGenerationThread->textPage(); + if (mPixmapReady) { + locker.unlock(); + m_closingLoop->quit(); + } + return; + } + + if (mTextPageGenerationThread->textPage()) { + TextPage *tp = mTextPageGenerationThread->textPage(); + page->setTextPage(tp); + q->signalTextGenerationDone(page, tp); + } +} + +QMutex *GeneratorPrivate::threadsLock() +{ + return &m_threadsMutex; +} + +QVariant GeneratorPrivate::metaData(const QString &, const QVariant &) const +{ + return QVariant(); +} + +QImage GeneratorPrivate::image(PixmapRequest *) +{ + return QImage(); +} + +Generator::Generator(QObject *parent, const QVariantList &args) + : Generator(*new GeneratorPrivate(), parent, args) +{ + // the delegated constructor does it all +} + +Generator::Generator(GeneratorPrivate &dd, QObject *parent, const QVariantList &args) + : QObject(parent) + , d_ptr(&dd) +{ + d_ptr->q_ptr = this; + Q_UNUSED(args) +} + +Generator::~Generator() +{ + delete d_ptr; +} + +bool Generator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + Q_UNUSED(fileName); + Q_UNUSED(pagesVector); + + return false; +} + +bool Generator::loadDocumentFromData(const QByteArray &, QVector &) +{ + return false; +} + +Document::OpenResult Generator::loadDocumentWithPassword(const QString &fileName, QVector &pagesVector, const QString &) +{ + return loadDocument(fileName, pagesVector) ? Document::OpenSuccess : Document::OpenError; +} + +Document::OpenResult Generator::loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector &pagesVector, const QString &) +{ + return loadDocumentFromData(fileData, pagesVector) ? Document::OpenSuccess : Document::OpenError; +} + +Generator::SwapBackingFileResult Generator::swapBackingFile(QString const & /*newFileName */, QVector & /*newPagesVector*/) +{ + return SwapBackingFileError; +} + +bool Generator::closeDocument() +{ + Q_D(Generator); + + d->m_closing = true; + + d->threadsLock()->lock(); + if (!(d->mPixmapReady && d->mTextPageReady)) { + QEventLoop loop; + d->m_closingLoop = &loop; + + d->threadsLock()->unlock(); + + loop.exec(); + + d->m_closingLoop = nullptr; + } else { + d->threadsLock()->unlock(); + } + + bool ret = doCloseDocument(); + + d->m_closing = false; + + return ret; +} + +bool Generator::canGeneratePixmap() const +{ + Q_D(const Generator); + return d->mPixmapReady; +} + +void Generator::generatePixmap(PixmapRequest *request) +{ + Q_D(Generator); + d->mPixmapReady = false; + + const bool calcBoundingBox = !request->isTile() && !request->page()->isBoundingBoxKnown(); + + if (request->asynchronous() && hasFeature(Threaded)) { + if (d->textPageGenerationThread()->isFinished() && !canGenerateTextPage()) { + // It can happen that the text generation has already finished but + // mTextPageReady is still false because textpageGenerationFinished + // didn't have time to run, if so queue ourselves + QTimer::singleShot(0, this, [this, request] { generatePixmap(request); }); + return; + } + + /** + * We create the text page for every page that is visible to the + * user, so he can use the text extraction tools without a delay. + */ + if (hasFeature(TextExtraction) && !request->page()->hasTextPage() && canGenerateTextPage() && !d->m_closing) { + d->mTextPageReady = false; + d->textPageGenerationThread()->setPage(request->page()); + + // dummy is used as a way to make sure the lambda gets disconnected each time it is executed + // since not all the times the pixmap generation thread starts we want the text generation thread to also start + QObject *dummy = new QObject(); + connect(d_ptr->pixmapGenerationThread(), &QThread::started, dummy, [this, dummy] { + delete dummy; + d_ptr->textPageGenerationThread()->startGeneration(); + }); + } + // pixmap generation thread must be started *after* connect(), else we may miss the start signal and get lock-ups (see bug 396137) + d->pixmapGenerationThread()->startGeneration(request, calcBoundingBox); + + return; + } + + const QImage &img = image(request); + request->page()->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(img)), request->normalizedRect()); + const int pageNumber = request->page()->number(); + + d->mPixmapReady = true; + + signalPixmapRequestDone(request); + if (calcBoundingBox) + updatePageBoundingBox(pageNumber, Utils::imageBoundingBox(&img)); +} + +bool Generator::canGenerateTextPage() const +{ + Q_D(const Generator); + return d->mTextPageReady; +} + +void Generator::generateTextPage(Page *page) +{ + TextRequest treq(page); + TextPage *tp = textPage(&treq); + page->setTextPage(tp); + signalTextGenerationDone(page, tp); +} + +QImage Generator::image(PixmapRequest *request) +{ + Q_D(Generator); + return d->image(request); +} + +TextPage *Generator::textPage(TextRequest *) +{ + return nullptr; +} + +DocumentInfo Generator::generateDocumentInfo(const QSet &keys) const +{ + Q_UNUSED(keys); + + return DocumentInfo(); +} + +const DocumentSynopsis *Generator::generateDocumentSynopsis() +{ + return nullptr; +} + +FontInfo::List Generator::fontsForPage(int) +{ + return FontInfo::List(); +} + +const QList *Generator::embeddedFiles() const +{ + return nullptr; +} + +Generator::PageSizeMetric Generator::pagesSizeMetric() const +{ + return None; +} + +bool Generator::isAllowed(Permission) const +{ + return true; +} + +void Generator::rotationChanged(Rotation, Rotation) +{ +} + +PageSize::List Generator::pageSizes() const +{ + return PageSize::List(); +} + +void Generator::pageSizeChanged(const PageSize &, const PageSize &) +{ +} + +bool Generator::print(QPrinter &) +{ + return false; +} + +Generator::PrintError Generator::printError() const +{ + return UnknownPrintError; +} + +void Generator::opaqueAction(const BackendOpaqueAction * /*action*/) +{ +} + +QVariant Generator::metaData(const QString &key, const QVariant &option) const +{ + Q_D(const Generator); + return d->metaData(key, option); +} + +ExportFormat::List Generator::exportFormats() const +{ + return ExportFormat::List(); +} + +bool Generator::exportTo(const QString &, const ExportFormat &) +{ + return false; +} + +void Generator::walletDataForFile(const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey) const +{ +#ifdef WITH_KWALLET + *walletKey = fileName.section(QLatin1Char('/'), -1, -1); + *walletName = KWallet::Wallet::NetworkWallet(); + *walletFolder = QStringLiteral("KPdf"); +#endif +} + +bool Generator::hasFeature(GeneratorFeature feature) const +{ + Q_D(const Generator); + return d->m_features.contains(feature); +} + +void Generator::signalPixmapRequestDone(PixmapRequest *request) +{ + Q_D(Generator); + if (d->m_document) + d->m_document->requestDone(request); + else { + delete request; + } +} + +void Generator::signalTextGenerationDone(Page *page, TextPage *textPage) +{ + Q_D(Generator); + if (d->m_document) + d->m_document->textGenerationDone(page); + else + delete textPage; +} + +void Generator::signalPartialPixmapRequest(PixmapRequest *request, const QImage &image) +{ + if (request->shouldAbortRender()) + return; + + PagePrivate *pagePrivate = PagePrivate::get(request->page()); + pagePrivate->setPixmap(request->observer(), new QPixmap(QPixmap::fromImage(image)), request->normalizedRect(), true /* isPartialPixmap */); + + const int pageNumber = request->page()->number(); + request->observer()->notifyPageChanged(pageNumber, Okular::DocumentObserver::Pixmap); +} + +const Document *Generator::document() const +{ + Q_D(const Generator); + if (d->m_document) { + return d->m_document->m_parent; + } + return nullptr; +} + +void Generator::setFeature(GeneratorFeature feature, bool on) +{ + Q_D(Generator); + if (on) + d->m_features.insert(feature); + else + d->m_features.remove(feature); +} + +QVariant Generator::documentMetaData(const QString &key, const QVariant &option) const +{ + Q_D(const Generator); + if (!d->m_document) + return QVariant(); + + if (key == QLatin1String("PaperColor")) + return documentMetaData(PaperColorMetaData, option); + if (key == QLatin1String("GraphicsAntialias")) + return documentMetaData(GraphicsAntialiasMetaData, option); + if (key == QLatin1String("TextAntialias")) + return documentMetaData(TextAntialiasMetaData, option); + if (key == QLatin1String("TextHinting")) + return documentMetaData(TextHintingMetaData, option); + + return QVariant(); +} + +QVariant Generator::documentMetaData(const DocumentMetaDataKey key, const QVariant &option) const +{ + Q_D(const Generator); + if (!d->m_document) + return QVariant(); + + return d->m_document->documentMetaData(key, option); +} + +QMutex *Generator::userMutex() const +{ + Q_D(const Generator); + return &d->m_mutex; +} + +void Generator::updatePageBoundingBox(int page, const NormalizedRect &boundingBox) +{ + Q_D(Generator); + if (d->m_document) // still connected to document? + d->m_document->setPageBoundingBox(page, boundingBox); +} + +void Generator::requestFontData(const Okular::FontInfo & /*font*/, QByteArray * /*data*/) +{ +} + +void Generator::setDPI(const QSizeF &dpi) // clazy:exclude=function-args-by-value TODO remove the & when we do a BIC change elsewhere +{ + Q_D(Generator); + d->m_dpi = dpi; +} + +QSizeF Generator::dpi() const +{ + Q_D(const Generator); + return d->m_dpi; +} + +QAbstractItemModel *Generator::layersModel() const +{ + return nullptr; +} + +TextRequest::TextRequest() + : d(new TextRequestPrivate) +{ + d->mPage = nullptr; + d->mShouldAbortExtraction = 0; +} + +TextRequest::TextRequest(Page *page) + : d(new TextRequestPrivate) +{ + d->mPage = page; + d->mShouldAbortExtraction = 0; +} + +TextRequest::~TextRequest() +{ + delete d; +} + +Page *TextRequest::page() const +{ + return d->mPage; +} + +bool TextRequest::shouldAbortExtraction() const +{ + return d->mShouldAbortExtraction != 0; +} + +TextRequestPrivate *TextRequestPrivate::get(const TextRequest *req) +{ + return req->d; +} + +PixmapRequest::PixmapRequest(DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features) + : d(new PixmapRequestPrivate) +{ + d->mObserver = observer; + d->mPageNumber = pageNumber; + d->mWidth = ceil(width * qApp->devicePixelRatio()); + d->mHeight = ceil(height * qApp->devicePixelRatio()); + d->mPriority = priority; + d->mFeatures = features; + d->mForce = false; + d->mTile = false; + d->mNormalizedRect = NormalizedRect(); + d->mPartialUpdatesWanted = false; + d->mShouldAbortRender = 0; +} + +PixmapRequest::~PixmapRequest() +{ + delete d; +} + +DocumentObserver *PixmapRequest::observer() const +{ + return d->mObserver; +} + +int PixmapRequest::pageNumber() const +{ + return d->mPageNumber; +} + +int PixmapRequest::width() const +{ + return d->mWidth; +} + +int PixmapRequest::height() const +{ + return d->mHeight; +} + +int PixmapRequest::priority() const +{ + return d->mPriority; +} + +bool PixmapRequest::asynchronous() const +{ + return d->mFeatures & Asynchronous; +} + +bool PixmapRequest::preload() const +{ + return d->mFeatures & Preload; +} + +Page *PixmapRequest::page() const +{ + return d->mPage; +} + +void PixmapRequest::setTile(bool tile) +{ + d->mTile = tile; +} + +bool PixmapRequest::isTile() const +{ + return d->mTile; +} + +void PixmapRequest::setNormalizedRect(const NormalizedRect &rect) +{ + if (d->mNormalizedRect == rect) + return; + + d->mNormalizedRect = rect; +} + +const NormalizedRect &PixmapRequest::normalizedRect() const +{ + return d->mNormalizedRect; +} + +void PixmapRequest::setPartialUpdatesWanted(bool partialUpdatesWanted) +{ + d->mPartialUpdatesWanted = partialUpdatesWanted; +} + +bool PixmapRequest::partialUpdatesWanted() const +{ + return d->mPartialUpdatesWanted; +} + +bool PixmapRequest::shouldAbortRender() const +{ + return d->mShouldAbortRender != 0; +} + +Okular::TilesManager *PixmapRequestPrivate::tilesManager() const +{ + return mPage->d->tilesManager(mObserver); +} + +PixmapRequestPrivate *PixmapRequestPrivate::get(const PixmapRequest *req) +{ + return req->d; +} + +void PixmapRequestPrivate::swap() +{ + qSwap(mWidth, mHeight); +} + +class Okular::ExportFormatPrivate : public QSharedData +{ +public: + ExportFormatPrivate(const QString &description, const QMimeType &mimeType, const QIcon &icon = QIcon()) + : QSharedData() + , mDescription(description) + , mMimeType(mimeType) + , mIcon(icon) + { + } + ~ExportFormatPrivate() + { + } + + QString mDescription; + QMimeType mMimeType; + QIcon mIcon; +}; + +ExportFormat::ExportFormat() + : d(new ExportFormatPrivate(QString(), QMimeType())) +{ +} + +ExportFormat::ExportFormat(const QString &description, const QMimeType &mimeType) + : d(new ExportFormatPrivate(description, mimeType)) +{ +} + +ExportFormat::ExportFormat(const QIcon &icon, const QString &description, const QMimeType &mimeType) + : d(new ExportFormatPrivate(description, mimeType, icon)) +{ +} + +ExportFormat::~ExportFormat() +{ +} + +ExportFormat::ExportFormat(const ExportFormat &other) + : d(other.d) +{ +} + +ExportFormat &ExportFormat::operator=(const ExportFormat &other) +{ + if (this == &other) + return *this; + + d = other.d; + + return *this; +} + +QString ExportFormat::description() const +{ + return d->mDescription; +} + +QMimeType ExportFormat::mimeType() const +{ + return d->mMimeType; +} + +QIcon ExportFormat::icon() const +{ + return d->mIcon; +} + +bool ExportFormat::isNull() const +{ + return !d->mMimeType.isValid() || d->mDescription.isNull(); +} + +ExportFormat ExportFormat::standardFormat(StandardExportFormat type) +{ + QMimeDatabase db; + switch (type) { + case PlainText: + return ExportFormat(QIcon::fromTheme(QStringLiteral("text-x-generic")), i18n("Plain &Text..."), db.mimeTypeForName(QStringLiteral("text/plain"))); + break; + case PDF: + return ExportFormat(QIcon::fromTheme(QStringLiteral("application-pdf")), i18n("PDF"), db.mimeTypeForName(QStringLiteral("application/pdf"))); + break; + case OpenDocumentText: + return ExportFormat( + QIcon::fromTheme(QStringLiteral("application-vnd.oasis.opendocument.text")), i18nc("This is the document format", "OpenDocument Text"), db.mimeTypeForName(QStringLiteral("application/vnd.oasis.opendocument.text"))); + break; + case HTML: + return ExportFormat(QIcon::fromTheme(QStringLiteral("text-html")), i18nc("This is the document format", "HTML"), db.mimeTypeForName(QStringLiteral("text/html"))); + break; + } + return ExportFormat(); +} + +bool ExportFormat::operator==(const ExportFormat &other) const +{ + return d == other.d; +} + +bool ExportFormat::operator!=(const ExportFormat &other) const +{ + return d != other.d; +} + +QDebug operator<<(QDebug str, const Okular::PixmapRequest &req) +{ + PixmapRequestPrivate *reqPriv = PixmapRequestPrivate::get(&req); + + str << "PixmapRequest:" << &req; + str << "- observer:" << (qulonglong)req.observer(); + str << "- page:" << req.pageNumber(); + str << "- width:" << req.width(); + str << "- height:" << req.height(); + str << "- priority:" << req.priority(); + str << "- async:" << (req.asynchronous() ? "true" : "false"); + str << "- tile:" << (req.isTile() ? "true" : "false"); + str << "- rect:" << req.normalizedRect(); + str << "- preload:" << (req.preload() ? "true" : "false"); + str << "- partialUpdates:" << (req.partialUpdatesWanted() ? "true" : "false"); + str << "- shouldAbort:" << (req.shouldAbortRender() ? "true" : "false"); + str << "- force:" << (reqPriv->mForce ? "true" : "false"); + return str; +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/generator.h b/core/generator.h new file mode 100644 index 0000000..8dcb6b0 --- /dev/null +++ b/core/generator.h @@ -0,0 +1,811 @@ +/*************************************************************************** + * Copyright (C) 2004-5 by Enrico Ros * + * Copyright (C) 2005 by Piotr Szymanski * + * Copyright (C) 2008 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_GENERATOR_H_ +#define _OKULAR_GENERATOR_H_ + +#include "document.h" +#include "fontinfo.h" +#include "global.h" +#include "okularcore_export.h" +#include "pagesize.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define OKULAR_EXPORT_PLUGIN(classname, json) \ + static_assert(json[0] != '\0', "arg2 must be a string literal"); \ + K_PLUGIN_CLASS_WITH_JSON(classname, json) + +class QByteArray; +class QMutex; +class QPrinter; +class QIcon; + +namespace Okular +{ +class BackendOpaqueAction; +class DocumentFonts; +class DocumentInfo; +class DocumentObserver; +class DocumentSynopsis; +class EmbeddedFile; +class ExportFormatPrivate; +class FontInfo; +class GeneratorPrivate; +class Page; +class PixmapRequest; +class PixmapRequestPrivate; +class TextPage; +class TextRequest; +class TextRequestPrivate; +class NormalizedRect; + +/* Note: on contents generation and asynchronous queries. + * Many observers may want to request data synchronously or asynchronously. + * - Sync requests. These should be done in-place. + * - Async request must be done in real background. That usually means a + * thread, such as QThread derived classes. + * Once contents are available, they must be immediately stored in the + * Page they refer to, and a signal is emitted as soon as storing + * (even for sync or async queries) has been done. + */ + +/** + * @short Defines an entry for the export menu + * + * This class encapsulates information about an export format. + * Every Generator can support 0 or more export formats which can be + * queried with @ref Generator::exportFormats(). + */ +class OKULARCORE_EXPORT ExportFormat +{ +public: + typedef QList List; + + /** + * Creates an empty export format. + * + * @see isNull() + */ + ExportFormat(); + + /** + * Creates a new export format. + * + * @param description The i18n'ed description of the format. + * @param mimeType The supported mime type of the format. + */ + ExportFormat(const QString &description, const QMimeType &mimeType); + + /** + * Creates a new export format. + * + * @param icon The icon used in the GUI for this format. + * @param description The i18n'ed description of the format. + * @param mimeType The supported mime type of the format. + */ + ExportFormat(const QIcon &icon, const QString &description, const QMimeType &mimeType); + + /** + * Destroys the export format. + */ + ~ExportFormat(); + + /** + * @internal + */ + ExportFormat(const ExportFormat &other); + + /** + * @internal + */ + ExportFormat &operator=(const ExportFormat &other); + + /** + * Returns the description of the format. + */ + QString description() const; + + /** + * Returns the mime type of the format. + */ + QMimeType mimeType() const; + + /** + * Returns the icon for GUI representations of the format. + */ + QIcon icon() const; + + /** + * Returns whether the export format is null/valid. + * + * An ExportFormat is null if the mimetype is not valid or the + * description is empty, or both. + */ + bool isNull() const; + + /** + * Type of standard export format. + */ + enum StandardExportFormat { + PlainText, ///< Plain text + PDF, ///< PDF, aka Portable Document Format + OpenDocumentText, ///< OpenDocument Text format @since 0.8 (KDE 4.2) + HTML ///< OpenDocument Text format @since 0.8 (KDE 4.2) + }; + + /** + * Builds a standard format for the specified @p type . + */ + static ExportFormat standardFormat(StandardExportFormat type); + + bool operator==(const ExportFormat &other) const; + + bool operator!=(const ExportFormat &other) const; + +private: + /// @cond PRIVATE + friend class ExportFormatPrivate; + /// @endcond + QSharedDataPointer d; +}; + +/** + * @short [Abstract Class] The information generator. + * + * Most of class members are virtuals and some of them pure virtual. The pure + * virtuals provide the minimal functionalities for a Generator, that is being + * able to generate QPixmap for the Page 's of the Document. + * + * Implementing the other functions will make the Generator able to provide + * more contents and/or functionalities (like text extraction). + * + * Generation/query is requested by the Document class only, and that + * class stores the resulting data into Page s. The data will then be + * displayed by the GUI components (PageView, ThumbnailList, etc..). + * + * @see PrintInterface, ConfigInterface, GuiInterface + */ +class OKULARCORE_EXPORT Generator : public QObject +{ + /// @cond PRIVATE + friend class PixmapGenerationThread; + friend class TextPageGenerationThread; + /// @endcond + + Q_OBJECT + +public: + /** + * Describe the possible optional features that a Generator can + * provide. + */ + enum GeneratorFeature { + Threaded, ///< Whether the Generator supports asynchronous generation of pictures or text pages + TextExtraction, ///< Whether the Generator can extract text from the document in the form of TextPage's + ReadRawData, ///< Whether the Generator can read a document directly from its raw data. + FontInfo, ///< Whether the Generator can provide information about the fonts used in the document + PageSizes, ///< Whether the Generator can change the size of the document pages. + PrintNative, ///< Whether the Generator supports native cross-platform printing (QPainter-based). + PrintPostscript, ///< Whether the Generator supports postscript-based file printing. + PrintToFile, ///< Whether the Generator supports export to PDF & PS through the Print Dialog + TiledRendering, ///< Whether the Generator can render tiles @since 0.16 (KDE 4.10) + SwapBackingFile, ///< Whether the Generator can hot-swap the file it's reading from @since 1.3 + SupportsCancelling ///< Whether the Generator can cancel requests @since 1.4 + }; + + /** + * Creates a new generator. + */ + explicit Generator(QObject *parent = nullptr, const QVariantList &args = QVariantList()); + + /** + * Destroys the generator. + */ + ~Generator() override; + + /** + * Loads the document with the given @p fileName and fills the + * @p pagesVector with the parsed pages. + * + * @note If you implement the WithPassword variants you don't need to implement this one + * + * @returns true on success, false otherwise. + */ + virtual bool loadDocument(const QString &fileName, QVector &pagesVector); + + /** + * Loads the document from the raw data @p fileData and fills the + * @p pagesVector with the parsed pages. + * + * @note If you implement the WithPassword variants you don't need to implement this one + * + * @note the Generator has to have the feature @ref ReadRawData enabled + * + * @returns true on success, false otherwise. + */ + virtual bool loadDocumentFromData(const QByteArray &fileData, QVector &pagesVector); + + /** + * Loads the document with the given @p fileName and @p password and fills the + * @p pagesVector with the parsed pages. + * + * @note Do not implement this if your format doesn't support passwords, it'll cleanly call loadDocument() + * + * @since 0.20 (KDE 4.14) + * + * @returns a LoadResult defining the result of the operation + */ + virtual Document::OpenResult loadDocumentWithPassword(const QString &fileName, QVector &pagesVector, const QString &password); + + /** + * Loads the document from the raw data @p fileData and @p password and fills the + * @p pagesVector with the parsed pages. + * + * @note Do not implement this if your format doesn't support passwords, it'll cleanly call loadDocumentFromData() + * + * @note the Generator has to have the feature @ref ReadRawData enabled + * + * @since 0.20 (KDE 4.14) + * + * @returns a LoadResult defining the result of the operation + */ + virtual Document::OpenResult loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector &pagesVector, const QString &password); + + /** + * Describes the result of an swap file operation. + * + * @since 1.3 + */ + enum SwapBackingFileResult { + SwapBackingFileError, //< The document could not be swapped + SwapBackingFileNoOp, //< The document was swapped and nothing needs to be done + SwapBackingFileReloadInternalData //< The document was swapped and internal data (forms, annotations, etc) needs to be reloaded + }; + + /** + * Changes the path of the file we are reading from. The new path must + * point to a copy of the same document. + * + * @note the Generator has to have the feature @ref SwapBackingFile enabled + * + * @since 1.3 + */ + virtual SwapBackingFileResult swapBackingFile(const QString &newFileName, QVector &newPagesVector); + + /** + * This method is called when the document is closed and not used + * any longer. + * + * @returns true on success, false otherwise. + */ + bool closeDocument(); + + /** + * This method returns whether the generator is ready to + * handle a new pixmap request. + */ + virtual bool canGeneratePixmap() const; + + /** + * This method can be called to trigger the generation of + * a new pixmap as described by @p request. + */ + virtual void generatePixmap(PixmapRequest *request); + + /** + * This method returns whether the generator is ready to + * handle a new text page request. + */ + virtual bool canGenerateTextPage() const; + + /** + * This method can be called to trigger the generation of + * a text page for the given @p page. + * + * The generation is done in the calling thread. + * + * @see TextPage + */ + void generateTextPage(Page *page); + + /** + * Returns the general information object of the document. + * + * Changed signature in okular version 0.21 + */ + virtual DocumentInfo generateDocumentInfo(const QSet &keys) const; + + /** + * Returns the 'table of content' object of the document or 0 if + * no table of content is available. + */ + virtual const DocumentSynopsis *generateDocumentSynopsis(); + + /** + * Returns the 'list of embedded fonts' object of the specified \p page + * of the document. + * + * \param page a page of the document, starting from 0 - -1 indicates all + * the other fonts + */ + virtual FontInfo::List fontsForPage(int page); + + /** + * Returns the 'list of embedded files' object of the document or 0 if + * no list of embedded files is available. + */ + virtual const QList *embeddedFiles() const; + + /** + * This enum identifies the metric of the page size. + */ + enum PageSizeMetric { + None, ///< The page size is not defined in a physical metric. + Points, ///< The page size is given in 1/72 inches. + Pixels ///< The page size is given in screen pixels @since 0.19 (KDE 4.13) + }; + + /** + * This method returns the metric of the page size. Default is @ref None. + */ + virtual PageSizeMetric pagesSizeMetric() const; + + /** + * Returns whether the given @p action is allowed in the document. + * @see @ref Okular::Permission + */ + virtual bool isAllowed(Permission action) const; + + /** + * This method is called when the orientation has been changed by the user. + */ + virtual void rotationChanged(Rotation orientation, Rotation oldOrientation); + + /** + * Returns the list of supported page sizes. + */ + virtual PageSize::List pageSizes() const; + + /** + * This method is called when the page size has been changed by the user. + */ + virtual void pageSizeChanged(const PageSize &pageSize, const PageSize &oldPageSize); + + /** + * This method is called to print the document to the given @p printer. + */ + virtual bool print(QPrinter &printer); + + /** + * Possible print errors + * @since 0.11 (KDE 4.5) + */ + enum PrintError { + NoPrintError, ///< There was no print error + UnknownPrintError, + TemporaryFileOpenPrintError, + FileConversionPrintError, + PrintingProcessCrashPrintError, + PrintingProcessStartPrintError, + PrintToFilePrintError, + InvalidPrinterStatePrintError, + UnableToFindFilePrintError, + NoFileToPrintError, + NoBinaryToPrintError, + InvalidPageSizePrintError ///< @since 0.18.2 (KDE 4.12.2) + }; + + /** + * This method returns the meta data of the given @p key with the given @p option + * of the document. + */ + virtual QVariant metaData(const QString &key, const QVariant &option) const; + + /** + * Returns the list of additional supported export formats. + */ + virtual ExportFormat::List exportFormats() const; + + /** + * This method is called to export the document in the given @p format and save it + * under the given @p fileName. The format must be one of the supported export formats. + */ + virtual bool exportTo(const QString &fileName, const ExportFormat &format); + + /** + * This method is called to know which wallet data should be used for the given file name. + * Unless you have very special requirements to where wallet data should be stored you + * don't need to reimplement this method. + */ + virtual void walletDataForFile(const QString &fileName, QString *walletName, QString *walletFolder, QString *walletKey) const; + + /** + * Query for the specified @p feature. + */ + bool hasFeature(GeneratorFeature feature) const; + + /** + * Update DPI of the generator + * + * @since 0.19 (KDE 4.13) + */ + void setDPI(const QSizeF &dpi); // TODO remove the & when we do a BIC change elsewhere + + /** + * Returns the 'layers model' object of the document or NULL if + * layers model is not available. + * + * @since 0.24 + */ + virtual QAbstractItemModel *layersModel() const; + + /** + * Calls the backend to execute an BackendOpaqueAction + */ + virtual void opaqueAction(const BackendOpaqueAction *action); + +Q_SIGNALS: + /** + * This signal should be emitted whenever an error occurred in the generator. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void error(const QString &message, int duration); + + /** + * This signal should be emitted whenever the user should be warned. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void warning(const QString &message, int duration); + + /** + * This signal should be emitted whenever the user should be noticed. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void notice(const QString &message, int duration); + +protected: + /** + * This method must be called when the pixmap request triggered by generatePixmap() + * has been finished. + */ + void signalPixmapRequestDone(PixmapRequest *request); + + /** + * This method must be called when a text generation has been finished. + */ + void signalTextGenerationDone(Page *page, TextPage *textPage); + + /** + * This method is called when the document is closed and not used + * any longer. + * + * @returns true on success, false otherwise. + */ + virtual bool doCloseDocument() = 0; + + /** + * Returns the image of the page as specified in + * the passed pixmap @p request. + * + * Must return a null image if the request was cancelled and the generator supports cancelling + * + * @warning this method may be executed in its own separated thread if the + * @ref Threaded is enabled! + */ + virtual QImage image(PixmapRequest *request); + + /** + * Returns the text page for the given @p request. + * + * Must return a null pointer if the request was cancelled and the generator supports cancelling + * + * @warning this method may be executed in its own separated thread if the + * @ref Threaded is enabled! + * + * @since 1.4 + */ + virtual TextPage *textPage(TextRequest *request); + + /** + * Returns a pointer to the document. + */ + const Document *document() const; + + /** + * Toggle the @p feature . + */ + void setFeature(GeneratorFeature feature, bool on = true); + + /** + * Internal document setting + */ + enum DocumentMetaDataKey { + PaperColorMetaData, ///< Returns (QColor) the paper color if set in Settings or the default color (white) if option is true (otherwise returns a non initialized QColor) + TextAntialiasMetaData, ///< Returns (bool) text antialias from Settings (option is not used) + GraphicsAntialiasMetaData, ///< Returns (bool)graphic antialias from Settings (option is not used) + TextHintingMetaData ///< Returns (bool)text hinting from Settings (option is not used) + }; + + /** + * Request a meta data of the Document, if available, like an internal + * setting. + * + * @since 1.1 + */ + QVariant documentMetaData(const DocumentMetaDataKey key, const QVariant &option = QVariant()) const; + + /** + * Request a meta data of the Document, if available, like an internal + * setting. + */ + OKULARCORE_DEPRECATED QVariant documentMetaData(const QString &key, const QVariant &option = QVariant()) const; + + /** + * Return the pointer to a mutex the generator can use freely. + */ + QMutex *userMutex() const; + + /** + * Set the bounding box of a page after the page has already been handed + * to the Document. Call this instead of Page::setBoundingBox() to ensure + * that all observers are notified. + * + * @since 0.7 (KDE 4.1) + */ + void updatePageBoundingBox(int page, const NormalizedRect &boundingBox); + + /** + * Returns DPI, previously set via setDPI() + * @since 0.19 (KDE 4.13) + */ + QSizeF dpi() const; + +protected Q_SLOTS: + /** + * Gets the font data for the given font + * + * @since 0.8 (KDE 4.1) + */ + // TODO Make it return a QByteArray and be virtual when a BIC change happens somewhere else + void requestFontData(const Okular::FontInfo &font, QByteArray *data); + + /** + * This method can be called to trigger a partial pixmap update for the given request + * Make sure you call it in a way it's executed in the main thread. + * @since 1.3 + */ + void signalPartialPixmapRequest(Okular::PixmapRequest *request, const QImage &image); + +protected: + /** + * Returns the last print error in case print() failed + * @since 0.11 (KDE 4.5) + */ + // TODO Make print() return a PrintError instead of bool and remove this function when a BIC change happens somewhere else + Q_INVOKABLE Okular::Generator::PrintError printError() const; + + /// @cond PRIVATE + Generator(GeneratorPrivate &dd, QObject *parent, const QVariantList &args); + Q_DECLARE_PRIVATE(Generator) + GeneratorPrivate *d_ptr; + + friend class Document; + friend class DocumentPrivate; + /// @endcond PRIVATE + +private: + Q_DISABLE_COPY(Generator) +}; + +/** + * @short Describes a pixmap type request. + */ +class OKULARCORE_EXPORT PixmapRequest +{ + friend class Document; + friend class DocumentPrivate; + +public: + enum PixmapRequestFeature { NoFeature = 0, Asynchronous = 1, Preload = 2 }; + Q_DECLARE_FLAGS(PixmapRequestFeatures, PixmapRequestFeature) + + /** + * Creates a new pixmap request. + * + * @param observer The observer. + * @param pageNumber The page number. + * @param width The width of the page. + * @param height The height of the page. + * @param priority The priority of the request. + * @param features The features of generation. + */ + PixmapRequest(DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features); + + /** + * Destroys the pixmap request. + */ + ~PixmapRequest(); + + /** + * Returns the observer of the request. + */ + DocumentObserver *observer() const; + + /** + * Returns the page number of the request. + */ + int pageNumber() const; + + /** + * Returns the page width of the requested pixmap. + */ + int width() const; + + /** + * Returns the page height of the requested pixmap. + */ + int height() const; + + /** + * Returns the priority (less it better, 0 is maximum) of the + * request. + */ + int priority() const; + + /** + * Returns whether the generation should be done synchronous or + * asynchronous. + * + * If asynchronous, the pixmap is created in a thread and the observer + * is notified when the job is done. + */ + bool asynchronous() const; + + /** + * Returns whether the generation request is for a page that is not important + * i.e. it's just for speeding up future rendering + */ + bool preload() const; + + /** + * Returns a pointer to the page where the pixmap shall be generated for. + */ + Page *page() const; + + /** + * Sets whether the generator should render only the given normalized + * rect or the entire page + * + * @since 0.16 (KDE 4.10) + */ + void setTile(bool tile); + + /** + * Returns whether the generator should render just the region given by + * normalizedRect() or the entire page. + * + * @since 0.16 (KDE 4.10) + */ + bool isTile() const; + + /** + * Sets the region of the page to request. + * + * @since 0.16 (KDE 4.10) + */ + void setNormalizedRect(const NormalizedRect &rect); + + /** + * Returns the normalized region of the page to request. + * + * @since 0.16 (KDE 4.10) + */ + const NormalizedRect &normalizedRect() const; + + /** + * Sets whether the request should report back updates if possible + * + * @since 1.3 + */ + void setPartialUpdatesWanted(bool partialUpdatesWanted); + + /** + * Should the request report back updates if possible? + * + * @since 1.3 + */ + bool partialUpdatesWanted() const; + + /** + * Should the request be aborted if possible? + * + * @since 1.4 + */ + bool shouldAbortRender() const; + +private: + Q_DISABLE_COPY(PixmapRequest) + + friend class PixmapRequestPrivate; + PixmapRequestPrivate *const d; +}; + +/** + * @short Describes a text request. + * + * @since 1.4 + */ +class OKULARCORE_EXPORT TextRequest +{ +public: + /** + * Creates a new text request. + */ + explicit TextRequest(Page *page); + + TextRequest(); + + /** + * Destroys the pixmap request. + */ + ~TextRequest(); + + /** + * Returns a pointer to the page where the pixmap shall be generated for. + */ + Page *page() const; + + /** + * Should the request be aborted if possible? + */ + bool shouldAbortExtraction() const; + +private: + Q_DISABLE_COPY(TextRequest) + + friend TextRequestPrivate; + TextRequestPrivate *const d; +}; + +} + +Q_DECLARE_METATYPE(Okular::Generator::PrintError) +Q_DECLARE_METATYPE(Okular::PixmapRequest *) + +#define OkularGeneratorInterface_iid "org.kde.okular.Generator" +Q_DECLARE_INTERFACE(Okular::Generator, OkularGeneratorInterface_iid) + +#ifndef QT_NO_DEBUG_STREAM +OKULARCORE_EXPORT QDebug operator<<(QDebug str, const Okular::PixmapRequest &req); +#endif + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/generator_p.cpp b/core/generator_p.cpp new file mode 100644 index 0000000..2df8102 --- /dev/null +++ b/core/generator_p.cpp @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright (C) 2007 Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "generator_p.h" + +#include + +#include "fontinfo.h" +#include "utils.h" + +using namespace Okular; + +PixmapGenerationThread::PixmapGenerationThread(Generator *generator) + : mGenerator(generator) + , mRequest(nullptr) + , mCalcBoundingBox(false) +{ +} + +void PixmapGenerationThread::startGeneration(PixmapRequest *request, bool calcBoundingBox) +{ + mRequest = request; + mCalcBoundingBox = calcBoundingBox; + + start(QThread::InheritPriority); +} + +void PixmapGenerationThread::endGeneration() +{ + mRequest = nullptr; +} + +PixmapRequest *PixmapGenerationThread::request() const +{ + return mRequest; +} + +QImage PixmapGenerationThread::image() const +{ + return mRequest ? PixmapRequestPrivate::get(mRequest)->mResultImage : QImage(); +} + +bool PixmapGenerationThread::calcBoundingBox() const +{ + return mCalcBoundingBox; +} + +NormalizedRect PixmapGenerationThread::boundingBox() const +{ + return mBoundingBox; +} + +void PixmapGenerationThread::run() +{ + if (mRequest) { + PixmapRequestPrivate::get(mRequest)->mResultImage = mGenerator->image(mRequest); + + if (mCalcBoundingBox) + mBoundingBox = Utils::imageBoundingBox(&PixmapRequestPrivate::get(mRequest)->mResultImage); + } +} + +TextPageGenerationThread::TextPageGenerationThread(Generator *generator) + : mGenerator(generator) + , mTextPage(nullptr) +{ + TextRequestPrivate *treqPriv = TextRequestPrivate::get(&mTextRequest); + treqPriv->mPage = nullptr; + treqPriv->mShouldAbortExtraction = 0; +} + +void TextPageGenerationThread::startGeneration() +{ + if (page()) { + start(QThread::InheritPriority); + } +} + +void TextPageGenerationThread::endGeneration() +{ + TextRequestPrivate *treqPriv = TextRequestPrivate::get(&mTextRequest); + treqPriv->mPage = nullptr; + treqPriv->mShouldAbortExtraction = 0; +} + +void TextPageGenerationThread::setPage(Page *page) +{ + TextRequestPrivate *treqPriv = TextRequestPrivate::get(&mTextRequest); + treqPriv->mPage = page; + treqPriv->mShouldAbortExtraction = 0; +} + +Page *TextPageGenerationThread::page() const +{ + return mTextRequest.page(); +} + +TextPage *TextPageGenerationThread::textPage() const +{ + return mTextPage; +} + +void TextPageGenerationThread::abortExtraction() +{ + // If extraction already finished no point in aborting + if (!mTextPage) { + TextRequestPrivate *treqPriv = TextRequestPrivate::get(&mTextRequest); + treqPriv->mShouldAbortExtraction = 1; + } +} + +bool TextPageGenerationThread::shouldAbortExtraction() const +{ + return mTextRequest.shouldAbortExtraction(); +} + +void TextPageGenerationThread::run() +{ + mTextPage = nullptr; + + Q_ASSERT(page()); + + mTextPage = mGenerator->textPage(&mTextRequest); + + if (mTextRequest.shouldAbortExtraction()) { + delete mTextPage; + mTextPage = nullptr; + } +} + +FontExtractionThread::FontExtractionThread(Generator *generator, int pages) + : mGenerator(generator) + , mNumOfPages(pages) + , mGoOn(true) +{ +} + +void FontExtractionThread::startExtraction(bool async) +{ + if (async) { + connect(this, &FontExtractionThread::finished, this, &FontExtractionThread::deleteLater); + start(QThread::InheritPriority); + } else { + run(); + deleteLater(); + } +} + +void FontExtractionThread::stopExtraction() +{ + mGoOn = false; +} + +void FontExtractionThread::run() +{ + for (int i = -1; i < mNumOfPages && mGoOn; ++i) { + const FontInfo::List list = mGenerator->fontsForPage(i); + for (const FontInfo &fi : list) { + emit gotFont(fi); + } + emit progress(i); + } +} diff --git a/core/generator_p.h b/core/generator_p.h new file mode 100644 index 0000000..1eeef36 --- /dev/null +++ b/core/generator_p.h @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2007 Tobias Koenig * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_THREADEDGENERATOR_P_H +#define OKULAR_THREADEDGENERATOR_P_H + +#include "area.h" + +#include +#include +#include +#include + +class QEventLoop; + +#include "generator.h" +#include "page.h" + +namespace Okular +{ +class DocumentObserver; +class DocumentPrivate; +class FontInfo; +class Generator; +class Page; +class PixmapGenerationThread; +class PixmapRequest; +class TextPage; +class TextPageGenerationThread; +class TilesManager; + +class GeneratorPrivate +{ +public: + GeneratorPrivate(); + + virtual ~GeneratorPrivate(); + + Q_DECLARE_PUBLIC(Generator) + Generator *q_ptr; + + PixmapGenerationThread *pixmapGenerationThread(); + TextPageGenerationThread *textPageGenerationThread(); + + void pixmapGenerationFinished(); + void textpageGenerationFinished(); + + QMutex *threadsLock(); + + virtual QVariant metaData(const QString &key, const QVariant &option) const; + virtual QImage image(PixmapRequest *); + + DocumentPrivate *m_document; + // NOTE: the following should be a QSet< GeneratorFeature >, + // but it is not to avoid #include'ing generator.h + QSet m_features; + PixmapGenerationThread *mPixmapGenerationThread; + TextPageGenerationThread *mTextPageGenerationThread; + mutable QMutex m_mutex; + QMutex m_threadsMutex; + bool mPixmapReady : 1; + bool mTextPageReady : 1; + bool m_closing : 1; + QEventLoop *m_closingLoop; + QSizeF m_dpi; +}; + +class PixmapRequestPrivate +{ +public: + void swap(); + TilesManager *tilesManager() const; + + static PixmapRequestPrivate *get(const PixmapRequest *req); + + DocumentObserver *mObserver; + int mPageNumber; + int mWidth; + int mHeight; + int mPriority; + int mFeatures; + bool mForce : 1; + bool mTile : 1; + bool mPartialUpdatesWanted : 1; + Page *mPage; + NormalizedRect mNormalizedRect; + QAtomicInt mShouldAbortRender; + QImage mResultImage; +}; + +class TextRequestPrivate +{ +public: + static TextRequestPrivate *get(const TextRequest *req); + + Page *mPage; + QAtomicInt mShouldAbortExtraction; +}; + +class PixmapGenerationThread : public QThread +{ + Q_OBJECT + +public: + explicit PixmapGenerationThread(Generator *generator); + + void startGeneration(PixmapRequest *request, bool calcBoundingBox); + + void endGeneration(); + + PixmapRequest *request() const; + + QImage image() const; + bool calcBoundingBox() const; + NormalizedRect boundingBox() const; + +protected: + void run() override; + +private: + Generator *mGenerator; + PixmapRequest *mRequest; + NormalizedRect mBoundingBox; + bool mCalcBoundingBox : 1; +}; + +class TextPageGenerationThread : public QThread +{ + Q_OBJECT + +public: + explicit TextPageGenerationThread(Generator *generator); + + void endGeneration(); + + void setPage(Page *page); + Page *page() const; + + TextPage *textPage() const; + + void abortExtraction(); + bool shouldAbortExtraction() const; + +public slots: + void startGeneration(); + +protected: + void run() override; + +private: + Generator *mGenerator; + TextPage *mTextPage; + TextRequest mTextRequest; +}; + +class FontExtractionThread : public QThread +{ + Q_OBJECT + +public: + FontExtractionThread(Generator *generator, int pages); + + void startExtraction(bool async); + void stopExtraction(); + +Q_SIGNALS: + void gotFont(const Okular::FontInfo &); + void progress(int page); + +protected: + void run() override; + +private: + Generator *mGenerator; + int mNumOfPages; + bool mGoOn; +}; + +} + +Q_DECLARE_METATYPE(Okular::Page *) + +#endif diff --git a/core/global.h b/core/global.h new file mode 100644 index 0000000..86dc93a --- /dev/null +++ b/core/global.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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_GLOBAL_H +#define OKULAR_GLOBAL_H + +#include + +/** + * \namespace Okular global.h + * + * \brief The documentation to the global Okular namespace. + */ + +namespace Okular +{ +/** + * Describes the DRM capabilities. + */ +enum Permission { + AllowModify = 1, ///< Allows to modify the document + AllowCopy = 2, ///< Allows to copy the document + AllowPrint = 4, ///< Allows to print the document + AllowNotes = 8, ///< Allows to add annotations to the document + AllowFillForms = 16 ///< Allows to fill the forms in the document +}; +Q_DECLARE_FLAGS(Permissions, Permission) + +/** + * Describes the direction of searching. + */ +enum SearchDirection { + FromTop, ///< Searching from top of the page, next result is to be found, there was no earlier search result. + FromBottom, ///< Searching from bottom of the page, next result is to be found, there was no earlier search result. + NextResult, ///< Searching for the next result on the page, earlier result should be located so we search from the last result not from the beginning of the page. + PreviousResult ///< Searching for the previous result on the page, earlier result should be located so we search from the last result not from the beginning of the page. +}; + +/** + * A rotation. + */ +enum Rotation { + Rotation0 = 0, ///< Not rotated. + Rotation90 = 1, ///< Rotated 90 degrees clockwise. + Rotation180 = 2, ///< Rotated 180 degrees clockwise. + Rotation270 = 3 ///< Rotated 2700 degrees clockwise. +}; + +/** + * Describes the type of generation of objects + */ +enum GenerationType { + Synchronous, ///< Will create the object in a synchronous way + Asynchronous ///< Will create the object in an asynchronous way +}; + +/** + * The side(s) to be considered when merging areas. + */ +enum MergeSide { + MergeRight = 0, ///< Merge only if the right side of the first area intersect. + MergeBottom = 1, ///< Merge only if the bottom side of the first area intersect. + MergeLeft = 2, ///< Merge only if the left side of the first area intersect. + MergeTop = 3, ///< Merge only if the top side of the first area intersect. + MergeAll = 4 ///< Merge if the areas intersects, no matter which side(s). +}; + +/** + * Describes the possible script types. + */ +enum ScriptType { + JavaScript = 0 ///< JavaScript code +}; + +} + +#endif diff --git a/core/misc.cpp b/core/misc.cpp new file mode 100644 index 0000000..c1f8b28 --- /dev/null +++ b/core/misc.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymanski * + * * + * 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. * + ***************************************************************************/ + +#include "core/misc.h" + +#include + +#include "debug_p.h" + +using namespace Okular; + +class TextSelection::Private +{ +public: + int direction; + int it[2]; + NormalizedPoint cur[2]; +}; + +TextSelection::TextSelection(const NormalizedPoint &start, const NormalizedPoint &end) + : d(new Private) +{ + if (end.y - start.y < 0 || (end.y - start.y == 0 && end.x - start.x < 0)) + d->direction = 1; + else + d->direction = 0; + + d->cur[0] = start; + d->cur[1] = end; + d->it[d->direction % 2] = -1; + d->it[(d->direction + 1) % 2] = -1; +} + +TextSelection::~TextSelection() +{ + delete d; +} + +void TextSelection::end(const NormalizedPoint &p) +{ + // changing direction as in 2b , assuming the bool->int conversion is correct + int dir1 = d->direction; + d->direction = (p.y - d->cur[0].y < 0 || (p.y - d->cur[0].y == 0 && p.x - d->cur[0].x < 0)); + if (d->direction != dir1) + qCDebug(OkularCoreDebug) << "changing direction in selection"; + + d->cur[1] = p; +} + +void TextSelection::itE(int p) +{ + d->it[(d->direction + 1) % 2] = p; +} + +void TextSelection::itB(int p) +{ + d->it[(d->direction) % 2] = p; +} + +int TextSelection::direction() const +{ + return d->direction; +} + +NormalizedPoint TextSelection::start() const +{ + return d->cur[d->direction % 2]; +} + +NormalizedPoint TextSelection::end() const +{ + return d->cur[(d->direction + 1) % 2]; +} + +int TextSelection::itB() const +{ + return d->it[d->direction % 2]; +} + +int TextSelection::itE() const +{ + return d->it[(d->direction + 1) % 2]; +} diff --git a/core/misc.h b/core/misc.h new file mode 100644 index 0000000..132f5d9 --- /dev/null +++ b/core/misc.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymanski * + * * + * 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_MISC_H_ +#define _OKULAR_MISC_H_ + +#include "area.h" +#include "okularcore_export.h" + +namespace Okular +{ +/** + @short Wrapper around the information needed to generate the selection area + There are two assumptions inside this class: + 1. the start never changes, one instance of this class is used for one selection, + therefore the start of the selection will not change, only end and direction of + the selection will change. + By direction we mean the direction in which the end moves in relation to the start, + forward selection is when end is after the start, backward when its before. + + 2. The following changes might appear during selection: + a. the end moves without changing the direction (it can move up and down but not past the start): + only itE will be updated + b. the end moves with changing the direction then itB becomes itE if the previous direction was forward + or itE becomes itB + + 3. Internally it that is related to the start cursor is always at it[0] while it related to end is it[1], + transition between meanings (itB/itE) is done with dir modifier; +*/ +class OKULARCORE_EXPORT TextSelection +{ +public: + /** + * Creates a new text selection with the given @p start and @p end point. + */ + TextSelection(const NormalizedPoint &start, const NormalizedPoint &end); + + /** + * Destroys the text selection. + */ + ~TextSelection(); + + TextSelection(const TextSelection &) = delete; + TextSelection &operator=(const TextSelection &) = delete; + + /** + * Changes the end point of the selection to the given @p point. + */ + void end(const NormalizedPoint &point); + + void itE(int pos); + void itB(int pos); + + /** + * Returns the direction of the selection. + */ + int direction() const; + + /** + * Returns the start point of the selection. + */ + NormalizedPoint start() const; + + /** + * Returns the end point of the selection. + */ + NormalizedPoint end() const; + + int itB() const; + int itE() const; + +private: + class Private; + Private *const d; +}; + +} + +#endif diff --git a/core/movie.cpp b/core/movie.cpp new file mode 100644 index 0000000..f28e1af --- /dev/null +++ b/core/movie.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2012 by Guillermo A. Amaral B. * + * * + * 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. * + ***************************************************************************/ + +#include "movie.h" + +// qt/kde includes +#include +#include +#include +#include + +#include + +#include "debug_p.h" + +using namespace Okular; + +class Movie::Private +{ +public: + Private(const QString &url) + : m_url(url) + , m_rotation(Rotation0) + , m_playMode(PlayLimited) + , m_playRepetitions(1.0) + , m_tmp(nullptr) + , m_showControls(false) + , m_autoPlay(false) + , m_showPosterImage(false) + { + } + + QString m_url; + QSize m_aspect; + Rotation m_rotation; + PlayMode m_playMode; + double m_playRepetitions; + QTemporaryFile *m_tmp; + QImage m_posterImage; + bool m_showControls : 1; + bool m_autoPlay : 1; + bool m_showPosterImage : 1; +}; + +Movie::Movie(const QString &fileName) + : d(new Private(fileName)) +{ +} + +Movie::Movie(const QString &fileName, const QByteArray &data) + : d(new Private(fileName)) +{ + /* Store movie data as temporary file. + * + * Originally loaded movie data directly using a QBuffer, but sadly phonon + * fails to play on a few of my test systems (I think it's the Phonon + * GStreamer backend). Storing the data in a temporary file works fine + * though, not to mention, it releases much needed memory. (gamaral) + */ + d->m_tmp = new QTemporaryFile(QStringLiteral("%1/okrXXXXXX").arg(QDir::tempPath())); + if (d->m_tmp->open()) { + d->m_tmp->write(data); + d->m_tmp->flush(); + } else + qCDebug(OkularCoreDebug) << "Failed to create temporary file for video data."; +} + +Movie::~Movie() +{ + delete d->m_tmp; + delete d; +} + +QString Movie::url() const +{ + if (d->m_tmp) + return d->m_tmp->fileName(); + else + return d->m_url; +} + +void Movie::setSize(const QSize &aspect) // clazy:exclude=function-args-by-value TODO remove the & when we do a BIC change elsewhere +{ + d->m_aspect = aspect; +} + +QSize Movie::size() const +{ + return d->m_aspect; +} + +void Movie::setRotation(Rotation rotation) +{ + d->m_rotation = rotation; +} + +Rotation Movie::rotation() const +{ + return d->m_rotation; +} + +void Movie::setShowControls(bool show) +{ + d->m_showControls = show; +} + +bool Movie::showControls() const +{ + return d->m_showControls; +} + +void Movie::setPlayMode(Movie::PlayMode mode) +{ + d->m_playMode = mode; +} + +Movie::PlayMode Movie::playMode() const +{ + return d->m_playMode; +} + +void Movie::setPlayRepetitions(double repetitions) +{ + d->m_playRepetitions = repetitions; +} + +double Movie::playRepetitions() const +{ + return d->m_playRepetitions; +} + +void Movie::setAutoPlay(bool autoPlay) +{ + d->m_autoPlay = autoPlay; +} + +bool Movie::autoPlay() const +{ + return d->m_autoPlay; +} + +void Movie::setShowPosterImage(bool show) +{ + d->m_showPosterImage = show; +} + +bool Movie::showPosterImage() const +{ + return d->m_showPosterImage; +} + +void Movie::setPosterImage(const QImage &image) +{ + d->m_posterImage = image; +} + +QImage Movie::posterImage() const +{ + return d->m_posterImage; +} diff --git a/core/movie.h b/core/movie.h new file mode 100644 index 0000000..e7818be --- /dev/null +++ b/core/movie.h @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2012 by Guillermo A. Amaral B. * + * * + * 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_MOVIE_H_ +#define _OKULAR_MOVIE_H_ + +#include "global.h" +#include "okularcore_export.h" + +#include + +class QImage; + +namespace Okular +{ +/** + * @short Contains information about a movie object. + * + * @since 0.8 (KDE 4.2) + */ +class OKULARCORE_EXPORT Movie +{ +public: + /** + * The play mode for playing the movie + */ + enum PlayMode { + PlayLimited, ///< Play a fixed amount of times, closing the movie controls at the end @since 0.24 + PlayOpen, ///< Like PlayLimited, but leaving the controls open + PlayRepeat, ///< Play continuously until stopped + PlayPalindrome ///< Play forward, then backward, then again forward and so on until stopped + }; + + /** + * Creates a new movie object with the given external @p fileName. + */ + explicit Movie(const QString &fileName); + + /** + * Creates a new movie object with the given movie data. + */ + explicit Movie(const QString &fileName, const QByteArray &data); + + /** + * Destroys the movie object. + */ + ~Movie(); + + /** + * Returns the url of the movie. + */ + QString url() const; + + /** + * Sets the size for the movie. + */ + void setSize(const QSize &aspect); // TODO remove the & when we do a BIC change elsewhere + + /** + * Returns the size of the movie. + */ + QSize size() const; + + /** + * Sets the @p rotation of the movie. + */ + void setRotation(Rotation rotation); + + /** + * Returns the rotation of the movie. + */ + Rotation rotation() const; + + /** + * Sets whether show a bar with movie controls + */ + void setShowControls(bool show); + + /** + * Whether show a bar with movie controls + */ + bool showControls() const; + + /** + * Sets the way the movie should be played + */ + void setPlayMode(PlayMode mode); + + /** + * How to play the movie + */ + PlayMode playMode() const; + + /** + * Sets how many times the movie should be played + * @since 0.24 + */ + void setPlayRepetitions(double repetitions); + + /** + * How many times to play the movie + * @since 0.24 + */ + double playRepetitions() const; + + /** + * Sets whether to play the movie automatically + */ + void setAutoPlay(bool autoPlay); + + /** + * Whether to play the movie automatically + */ + bool autoPlay() const; + + /** + * Sets whether to show a poster image. + * + * @since 4.10 + */ + void setShowPosterImage(bool show); + + /** + * Whether to show a poster image. + * + * @since 4.10 + */ + bool showPosterImage() const; + + /** + * Sets the poster image. + * + * @since 4.10 + */ + void setPosterImage(const QImage &image); + + /** + * Returns the poster image. + * + * @since 4.10 + */ + QImage posterImage() const; + +private: + class Private; + Private *const d; + + Q_DISABLE_COPY(Movie) +}; + +} + +#endif diff --git a/core/observer.cpp b/core/observer.cpp new file mode 100644 index 0000000..c9413a7 --- /dev/null +++ b/core/observer.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * Copyright (C) 2005 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "observer.h" + +using namespace Okular; + +DocumentObserver::DocumentObserver() +{ +} + +DocumentObserver::~DocumentObserver() +{ +} + +void DocumentObserver::notifySetup(const QVector &, int) +{ +} + +void DocumentObserver::notifyViewportChanged(bool) +{ +} + +void DocumentObserver::notifyPageChanged(int, int) +{ +} + +void DocumentObserver::notifyContentsCleared(int) +{ +} + +void DocumentObserver::notifyVisibleRectsChanged() +{ +} + +void DocumentObserver::notifyZoom(int) +{ +} + +bool DocumentObserver::canUnloadPixmap(int) const +{ + return true; +} + +void DocumentObserver::notifyCurrentPageChanged(int, int) +{ +} diff --git a/core/observer.h b/core/observer.h new file mode 100644 index 0000000..46c8551 --- /dev/null +++ b/core/observer.h @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * Copyright (C) 2005 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_DOCUMENTOBSERVER_H_ +#define _OKULAR_DOCUMENTOBSERVER_H_ + +#include + +#include "okularcore_export.h" + +namespace Okular +{ +class Page; + +/** + * @short Base class for objects being notified when something changes. + * + * Inherit this class and call Document->addObserver( yourClass ) to get + * notified of asynchronous events (new pixmap generated, or changed, etc..). + */ +class OKULARCORE_EXPORT DocumentObserver +{ +public: + DocumentObserver(); + /** + * Destroys the document observer. + */ + virtual ~DocumentObserver(); + + DocumentObserver(const DocumentObserver &) = delete; + DocumentObserver &operator=(const DocumentObserver &) = delete; + + /** + * Flags that can be sent from the document to all observers to + * inform them about the type of object that has been changed. + */ + enum ChangedFlags { + Pixmap = 1, ///< Pixmaps has been changed + Bookmark = 2, ///< Bookmarks has been changed + Highlights = 4, ///< Highlighting information has been changed + TextSelection = 8, ///< Text selection has been changed + Annotations = 16, ///< Annotations have been changed + BoundingBox = 32, ///< Bounding boxes have been changed + NeedSaveAs = 64 ///< Set when "Save" is needed or annotation/form changes will be lost @since 0.15 (KDE 4.9) @deprecated + }; + + /** + * ... + */ + enum SetupFlags { + DocumentChanged = 1, ///< The document is a new document. + NewLayoutForPages = 2, ///< All the pages have + UrlChanged = 4 ///< The URL has changed @since 1.3 + }; + + /** + * This method is called whenever the document is initialized or reconstructed. + * + * @param pages The vector of pages of the document. + * @param setupFlags the flags with the information about the setup + */ + virtual void notifySetup(const QVector &pages, int setupFlags); + + /** + * This method is called whenever the viewport has been changed. + * + * @param smoothMove If true, the move shall be animated. + */ + virtual void notifyViewportChanged(bool smoothMove); + + /** + * This method is called whenever the content on @p page described by the + * passed @p flags has been changed. + */ + virtual void notifyPageChanged(int page, int flags); + + /** + * This method is called whenever the content described by the passed @p flags + * has been cleared. + */ + virtual void notifyContentsCleared(int flags); + + /** + * This method is called whenever the visible rects have been changed. + */ + virtual void notifyVisibleRectsChanged(); + + /** + * This method is called whenever the zoom of the document has been changed. + */ + virtual void notifyZoom(int factor); + + /** + * Returns whether the observer agrees that all pixmaps for the given + * @p page can be unloaded to improve memory usage. + * + * Returns true per default. + */ + virtual bool canUnloadPixmap(int page) const; + + /** + * This method is called after the current page of the document has been entered. + * + * @param previous The number of the previous page (is @c -1 for the initial page change). + * @param current The number of the current page. + * + * @since 0.16 (KDE 4.10) + */ + virtual void notifyCurrentPageChanged(int previous, int current); + +private: + class Private; + const Private *d; +}; + +} + +#endif diff --git a/core/okularGenerator.desktop b/core/okularGenerator.desktop new file mode 100644 index 0000000..92d68b9 --- /dev/null +++ b/core/okularGenerator.desktop @@ -0,0 +1,72 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=okular/Generator +Comment=File format backend for Okular +Comment[ar]=المنتهى الخلفي لـنسق الملف لأوكلار +Comment[az]=Okulyar üçün fayl formatı modulu +Comment[bg]=Ядро на Okular за файлови формати +Comment[bs]=Pozadina formata datoteke za Okular +Comment[ca]=Dorsal del format de fitxer per a l'Okular +Comment[ca@valencia]=Dorsal del format de fitxer per a l'Okular +Comment[cs]=Podpůrná vrstva formátu souboru pro Okular +Comment[da]=Filformatmotor til Okular +Comment[de]=Dateiformat-Modul für Okular +Comment[el]=Σύστημα υποστήριξης τύπου αρχείων για το Okular +Comment[en_GB]=File format backend for Okular +Comment[es]=Motor de formatos de archivos para Okular +Comment[et]=Okulari failivormingu taustaprogramm +Comment[eu]=Okularrentzako Fitxategi formatuaren bizkarraldekoa +Comment[fi]=Tiedostomuototaustaosa Okularille +Comment[fr]=Moteur de formats de fichiers pour Okular +Comment[ga]=Inneall formáide comhaid le haghaidh Okular +Comment[gl]=Infraestrutura dun formato de ficheiro para Okular +Comment[hne]=ओकुलर बर फाइल प्रारूप बैकएंड +Comment[hr]=Podrška za oblike datoteka za Okular +Comment[hu]=Fájlformátumkezelő az Okularhoz +Comment[ia]=Retro-administration de formato de file pro Okular +Comment[is]=Skráasniðsstuðningur fyrir Okular +Comment[it]=Backend per i formati di file di Okular +Comment[ja]=Okular のファイル形式バックエンド +Comment[kk]=Okular-дың файл пішім тетігі +Comment[km]=ផ្នែក​ខាង​ក្រោយ​ទ្រង់ទ្រាយ​ឯកសារ​សម្រាប់ Okular +Comment[ko]=Okular용 파일 형식 백엔드 +Comment[ku]=Binesazî ya teşeya pelê Okular +Comment[lt]=Okular failų formato programinė sąsaja +Comment[lv]=Failu formātu Okular aizmugure +Comment[mr]=ओक्युलर करिता फाईल प्रकार बॅकएन्ड +Comment[nb]=Filformatmotor for Okular +Comment[nds]=Dateiformaat-Hülpprogramm för Okular +Comment[nl]=Bestandsformaat-backend voor Okular +Comment[nn]=Filformatmotor for Okular +Comment[pa]=ਓਕੁਲਾਰ ਲਈ ਫਾਇਲ ਫਾਰਮੈਟ ਬੈਕਐਂਡ +Comment[pl]=Obsługa formatu pliku dla Okulara +Comment[pt]=Infra-estrutura do formato de ficheiros para o Okular +Comment[pt_BR]=Infraestrutura de formato de arquivo para o Okular +Comment[ro]=Platformă Okular pentru formate de fișiere +Comment[ru]=Модуль поддержки формата для Okular +Comment[sk]=Backend formátu súborov pre Okular +Comment[sl]=Zaledje za vrste datotek za Okular +Comment[sq]=Mbështetës për formatet e skedarëve në Okular +Comment[sr]=Позадина формата фајла за Окулар +Comment[sr@ijekavian]=Позадина формата фајла за Окулар +Comment[sr@ijekavianlatin]=Pozadina formata fajla za Okular +Comment[sr@latin]=Pozadina formata fajla za Okular +Comment[sv]=Filformatgränssnitt för Okular +Comment[th]=แบ็กเอนด์รูปแบบแฟ้มสำหรับ Okular +Comment[tr]=Okular için dosya biçimi arka ucu +Comment[uk]=Модуль типів файлів для okular +Comment[x-test]=xxFile format backend for Okularxx +Comment[zh_CN]=Okular 文件格式后端 +Comment[zh_TW]=Okular 檔案格式後端 +# Priority of the plugin. 0 - disabled +[PropertyDef::X-KDE-Priority] +Type=int + +# Version of the API. +[PropertyDef::X-KDE-okularAPIVersion] +Type=int + +# Has configuration option +[PropertyDef::X-KDE-okularHasInternalSettings] +Type=bool + diff --git a/core/page.cpp b/core/page.cpp new file mode 100644 index 0000000..efe1c1b --- /dev/null +++ b/core/page.cpp @@ -0,0 +1,1067 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "page.h" +#include "page_p.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// local includes +#include "action.h" +#include "annotations.h" +#include "annotations_p.h" +#include "debug_p.h" +#include "document.h" +#include "document_p.h" +#include "form.h" +#include "form_p.h" +#include "observer.h" +#include "pagecontroller_p.h" +#include "pagesize.h" +#include "pagetransition.h" +#include "rotationjob_p.h" +#include "textpage_p.h" +#include "tile.h" +#include "tilesmanager_p.h" +#include "utils_p.h" + +#include + +#ifdef PAGE_PROFILE +#include +#endif + +using namespace Okular; + +static const double distanceConsideredEqual = 25; // 5px + +static void deleteObjectRects(QLinkedList &rects, const QSet &which) +{ + QLinkedList::iterator it = rects.begin(), end = rects.end(); + for (; it != end;) + if (which.contains((*it)->objectType())) { + delete *it; + it = rects.erase(it); + } else + ++it; +} + +PagePrivate::PagePrivate(Page *page, uint n, double w, double h, Rotation o) + : m_page(page) + , m_number(n) + , m_orientation(o) + , m_width(w) + , m_height(h) + , m_doc(nullptr) + , m_boundingBox(0, 0, 1, 1) + , m_rotation(Rotation0) + , m_text(nullptr) + , m_transition(nullptr) + , m_textSelections(nullptr) + , m_openingAction(nullptr) + , m_closingAction(nullptr) + , m_duration(-1) + , m_isBoundingBoxKnown(false) +{ + // avoid Division-By-Zero problems in the program + if (m_width <= 0) + m_width = 1; + + if (m_height <= 0) + m_height = 1; +} + +PagePrivate::~PagePrivate() +{ + qDeleteAll(formfields); + delete m_openingAction; + delete m_closingAction; + delete m_text; + delete m_transition; +} + +PagePrivate *PagePrivate::get(Page *page) +{ + return page ? page->d : nullptr; +} + +void PagePrivate::imageRotationDone(RotationJob *job) +{ + TilesManager *tm = tilesManager(job->observer()); + if (tm) { + QPixmap *pixmap = new QPixmap(QPixmap::fromImage(job->image())); + tm->setPixmap(pixmap, job->rect(), job->isPartialUpdate()); + delete pixmap; + return; + } + + QMap::iterator it = m_pixmaps.find(job->observer()); + if (it != m_pixmaps.end()) { + PixmapObject &object = it.value(); + (*object.m_pixmap) = QPixmap::fromImage(job->image()); + object.m_rotation = job->rotation(); + object.m_isPartialPixmap = job->isPartialUpdate(); + } else { + PixmapObject object; + object.m_pixmap = new QPixmap(QPixmap::fromImage(job->image())); + object.m_rotation = job->rotation(); + object.m_isPartialPixmap = job->isPartialUpdate(); + + m_pixmaps.insert(job->observer(), object); + } +} + +QTransform PagePrivate::rotationMatrix() const +{ + return Okular::buildRotationMatrix(m_rotation); +} + +/** class Page **/ + +Page::Page(uint pageNumber, double w, double h, Rotation o) + : d(new PagePrivate(this, pageNumber, w, h, o)) +{ +} + +Page::~Page() +{ + if (d) { + deletePixmaps(); + deleteRects(); + d->deleteHighlights(); + deleteAnnotations(); + d->deleteTextSelections(); + deleteSourceReferences(); + + delete d; + } +} + +int Page::number() const +{ + return d->m_number; +} + +Rotation Page::orientation() const +{ + return d->m_orientation; +} + +Rotation Page::rotation() const +{ + return d->m_rotation; +} + +Rotation Page::totalOrientation() const +{ + return (Rotation)(((int)d->m_orientation + (int)d->m_rotation) % 4); +} + +double Page::width() const +{ + return d->m_width; +} + +double Page::height() const +{ + return d->m_height; +} + +double Page::ratio() const +{ + return d->m_height / d->m_width; +} + +NormalizedRect Page::boundingBox() const +{ + return d->m_boundingBox; +} + +bool Page::isBoundingBoxKnown() const +{ + return d->m_isBoundingBoxKnown; +} + +void Page::setBoundingBox(const NormalizedRect &bbox) +{ + if (d->m_isBoundingBoxKnown && d->m_boundingBox == bbox) + return; + + // Allow tiny rounding errors (happens during rotation) + static const double epsilon = 0.00001; + Q_ASSERT(bbox.left >= -epsilon && bbox.top >= -epsilon && bbox.right <= 1 + epsilon && bbox.bottom <= 1 + epsilon); + + d->m_boundingBox = bbox & NormalizedRect(0., 0., 1., 1.); + d->m_isBoundingBoxKnown = true; +} + +bool Page::hasPixmap(DocumentObserver *observer, int width, int height, const NormalizedRect &rect) const +{ + TilesManager *tm = d->tilesManager(observer); + if (tm) { + if (width != tm->width() || height != tm->height()) { + // FIXME hasPixmap should not be calling setSize on the TilesManager this is not very "const" + // as this function claims to be + if (width != -1 && height != -1) { + tm->setSize(width, height); + } + return false; + } + + return tm->hasPixmap(rect); + } + + QMap::const_iterator it = d->m_pixmaps.constFind(observer); + if (it == d->m_pixmaps.constEnd()) + return false; + + if (width == -1 || height == -1) + return true; + + if (it.value().m_isPartialPixmap) + return false; + + const QPixmap *pixmap = it.value().m_pixmap; + + return (pixmap->width() == width && pixmap->height() == height); +} + +bool Page::hasTextPage() const +{ + return d->m_text != nullptr; +} + +RegularAreaRect *Page::wordAt(const NormalizedPoint &p, QString *word) const +{ + if (d->m_text) + return d->m_text->wordAt(p, word); + + return nullptr; +} + +RegularAreaRect *Page::textArea(TextSelection *selection) const +{ + if (d->m_text) + return d->m_text->textArea(selection); + + return nullptr; +} + +bool Page::hasObjectRect(double x, double y, double xScale, double yScale) const +{ + if (m_rects.isEmpty()) + return false; + + QLinkedList::const_iterator it = m_rects.begin(), end = m_rects.end(); + for (; it != end; ++it) + if ((*it)->distanceSqr(x, y, xScale, yScale) < distanceConsideredEqual) + return true; + + return false; +} + +bool Page::hasHighlights(int s_id) const +{ + // simple case: have no highlights + if (m_highlights.isEmpty()) + return false; + // simple case: we have highlights and no id to match + if (s_id == -1) + return true; + // iterate on the highlights list to find an entry by id + QLinkedList::const_iterator it = m_highlights.begin(), end = m_highlights.end(); + for (; it != end; ++it) + if ((*it)->s_id == s_id) + return true; + return false; +} + +bool Page::hasTransition() const +{ + return d->m_transition != nullptr; +} + +bool Page::hasAnnotations() const +{ + return !m_annotations.isEmpty(); +} + +RegularAreaRect *Page::findText(int id, const QString &text, SearchDirection direction, Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *lastRect) const +{ + RegularAreaRect *rect = nullptr; + if (text.isEmpty() || !d->m_text) + return rect; + + rect = d->m_text->findText(id, text, direction, caseSensitivity, lastRect); + return rect; +} + +QString Page::text(const RegularAreaRect *area) const +{ + return text(area, TextPage::AnyPixelTextAreaInclusionBehaviour); +} + +QString Page::text(const RegularAreaRect *area, TextPage::TextAreaInclusionBehaviour b) const +{ + QString ret; + + if (!d->m_text) + return ret; + + if (area) { + RegularAreaRect rotatedArea = *area; + rotatedArea.transform(d->rotationMatrix().inverted()); + + ret = d->m_text->text(&rotatedArea, b); + } else + ret = d->m_text->text(nullptr, b); + + return ret; +} + +TextEntity::List Page::words(const RegularAreaRect *area, TextPage::TextAreaInclusionBehaviour b) const +{ + TextEntity::List ret; + + if (!d->m_text) + return ret; + + if (area) { + RegularAreaRect rotatedArea = *area; + rotatedArea.transform(d->rotationMatrix().inverted()); + + ret = d->m_text->words(&rotatedArea, b); + } else + ret = d->m_text->words(nullptr, b); + + for (auto &retI : ret) { + const TextEntity *orig = retI; + retI = new TextEntity(orig->text(), new Okular::NormalizedRect(orig->transformedArea(d->rotationMatrix()))); + delete orig; + } + + return ret; +} + +void PagePrivate::rotateAt(Rotation orientation) +{ + if (orientation == m_rotation) + return; + + deleteTextSelections(); + + if (((int)m_orientation + (int)m_rotation) % 2 != ((int)m_orientation + (int)orientation) % 2) + qSwap(m_width, m_height); + + Rotation oldRotation = m_rotation; + m_rotation = orientation; + + /** + * Rotate the images of the page. + */ + QMapIterator it(m_pixmaps); + while (it.hasNext()) { + it.next(); + + const PagePrivate::PixmapObject &object = it.value(); + + RotationJob *job = new RotationJob(object.m_pixmap->toImage(), object.m_rotation, m_rotation, it.key()); + job->setPage(this); + m_doc->m_pageController->addRotationJob(job); + } + + /** + * Rotate tiles manager + */ + QMapIterator i(m_tilesManagers); + while (i.hasNext()) { + i.next(); + + TilesManager *tm = i.value(); + if (tm) + tm->setRotation(m_rotation); + } + + /** + * Rotate the object rects on the page. + */ + const QTransform matrix = rotationMatrix(); + for (ObjectRect *objRect : qAsConst(m_page->m_rects)) + objRect->transform(matrix); + + const QTransform highlightRotationMatrix = Okular::buildRotationMatrix((Rotation)(((int)m_rotation - (int)oldRotation + 4) % 4)); + for (HighlightAreaRect *hlar : qAsConst(m_page->m_highlights)) { + hlar->transform(highlightRotationMatrix); + } +} + +void PagePrivate::changeSize(const PageSize &size) +{ + if (size.isNull() || (size.width() == m_width && size.height() == m_height)) + return; + + m_page->deletePixmaps(); + // deleteHighlights(); + // deleteTextSelections(); + + m_width = size.width(); + m_height = size.height(); + if (m_rotation % 2) + qSwap(m_width, m_height); +} + +const ObjectRect *Page::objectRect(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale) const +{ + // Walk list in reverse order so that annotations in the foreground are preferred + QLinkedListIterator it(m_rects); + it.toBack(); + while (it.hasPrevious()) { + const ObjectRect *objrect = it.previous(); + if ((objrect->objectType() == type) && objrect->distanceSqr(x, y, xScale, yScale) < distanceConsideredEqual) + return objrect; + } + + return nullptr; +} + +QLinkedList Page::objectRects(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale) const +{ + QLinkedList result; + + QLinkedListIterator it(m_rects); + it.toBack(); + while (it.hasPrevious()) { + const ObjectRect *objrect = it.previous(); + if ((objrect->objectType() == type) && objrect->distanceSqr(x, y, xScale, yScale) < distanceConsideredEqual) + result.append(objrect); + } + + return result; +} + +const ObjectRect *Page::nearestObjectRect(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale, double *distance) const +{ + ObjectRect *res = nullptr; + double minDistance = std::numeric_limits::max(); + + QLinkedList::const_iterator it = m_rects.constBegin(), end = m_rects.constEnd(); + for (; it != end; ++it) { + if ((*it)->objectType() == type) { + double d = (*it)->distanceSqr(x, y, xScale, yScale); + if (d < minDistance) { + res = (*it); + minDistance = d; + } + } + } + + if (distance) + *distance = minDistance; + return res; +} + +const PageTransition *Page::transition() const +{ + return d->m_transition; +} + +QLinkedList Page::annotations() const +{ + return m_annotations; +} + +Annotation *Page::annotation(const QString &uniqueName) const +{ + for (Annotation *a : m_annotations) { + if (a->uniqueName() == uniqueName) + return a; + } + return nullptr; +} + +const Action *Page::pageAction(PageAction action) const +{ + switch (action) { + case Page::Opening: + return d->m_openingAction; + break; + case Page::Closing: + return d->m_closingAction; + break; + } + + return nullptr; +} + +QLinkedList Page::formFields() const +{ + return d->formfields; +} + +void Page::setPixmap(DocumentObserver *observer, QPixmap *pixmap, const NormalizedRect &rect) +{ + d->setPixmap(observer, pixmap, rect, false /*isPartialPixmap*/); +} + +void PagePrivate::setPixmap(DocumentObserver *observer, QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap) +{ + if (m_rotation == Rotation0) { + TilesManager *tm = tilesManager(observer); + if (tm) { + tm->setPixmap(pixmap, rect, isPartialPixmap); + delete pixmap; + return; + } + + QMap::iterator it = m_pixmaps.find(observer); + if (it != m_pixmaps.end()) { + delete it.value().m_pixmap; + } else { + it = m_pixmaps.insert(observer, PagePrivate::PixmapObject()); + } + it.value().m_pixmap = pixmap; + it.value().m_rotation = m_rotation; + it.value().m_isPartialPixmap = isPartialPixmap; + } else { + // it can happen that we get a setPixmap while closing and thus the page controller is gone + if (m_doc->m_pageController) { + RotationJob *job = new RotationJob(pixmap->toImage(), Rotation0, m_rotation, observer); + job->setPage(this); + job->setRect(TilesManager::toRotatedRect(rect, m_rotation)); + job->setIsPartialUpdate(isPartialPixmap); + m_doc->m_pageController->addRotationJob(job); + } + + delete pixmap; + } +} + +void Page::setTextPage(TextPage *textPage) +{ + delete d->m_text; + + d->m_text = textPage; + if (d->m_text) { + d->m_text->d->m_page = this; + // Correct/optimize text order for search and text selection + d->m_text->d->correctTextOrder(); + } +} + +void Page::setObjectRects(const QLinkedList &rects) +{ + QSet which; + which << ObjectRect::Action << ObjectRect::Image; + deleteObjectRects(m_rects, which); + + /** + * Rotate the object rects of the page. + */ + const QTransform matrix = d->rotationMatrix(); + + QLinkedList::const_iterator objectIt = rects.begin(), end = rects.end(); + for (; objectIt != end; ++objectIt) + (*objectIt)->transform(matrix); + + m_rects << rects; +} + +void PagePrivate::setHighlight(int s_id, RegularAreaRect *rect, const QColor &color) +{ + HighlightAreaRect *hr = new HighlightAreaRect(rect); + hr->s_id = s_id; + hr->color = color; + + m_page->m_highlights.append(hr); +} + +void PagePrivate::setTextSelections(RegularAreaRect *r, const QColor &color) +{ + deleteTextSelections(); + if (r) { + HighlightAreaRect *hr = new HighlightAreaRect(r); + hr->s_id = -1; + hr->color = color; + m_textSelections = hr; + delete r; + } +} + +void Page::setSourceReferences(const QLinkedList &refRects) +{ + deleteSourceReferences(); + for (SourceRefObjectRect *rect : refRects) { + m_rects << rect; + } +} + +void Page::setDuration(double seconds) +{ + d->m_duration = seconds; +} + +double Page::duration() const +{ + return d->m_duration; +} + +void Page::setLabel(const QString &label) +{ + d->m_label = label; +} + +QString Page::label() const +{ + return d->m_label; +} + +const RegularAreaRect *Page::textSelection() const +{ + return d->m_textSelections; +} + +QColor Page::textSelectionColor() const +{ + return d->m_textSelections ? d->m_textSelections->color : QColor(); +} + +void Page::addAnnotation(Annotation *annotation) +{ + // Generate uniqueName: okular-{UUID} + if (annotation->uniqueName().isEmpty()) { + QString uniqueName = QStringLiteral("okular-") + QUuid::createUuid().toString(); + annotation->setUniqueName(uniqueName); + } + annotation->d_ptr->m_page = d; + m_annotations.append(annotation); + + AnnotationObjectRect *rect = new AnnotationObjectRect(annotation); + + // Rotate the annotation on the page. + const QTransform matrix = d->rotationMatrix(); + annotation->d_ptr->annotationTransform(matrix); + + m_rects.append(rect); +} + +bool Page::removeAnnotation(Annotation *annotation) +{ + if (!d->m_doc->m_parent->canRemovePageAnnotation(annotation)) + return false; + + QLinkedList::iterator aIt = m_annotations.begin(), aEnd = m_annotations.end(); + for (; aIt != aEnd; ++aIt) { + if ((*aIt) && (*aIt)->uniqueName() == annotation->uniqueName()) { + int rectfound = false; + QLinkedList::iterator it = m_rects.begin(), end = m_rects.end(); + for (; it != end && !rectfound; ++it) + if (((*it)->objectType() == ObjectRect::OAnnotation) && ((*it)->object() == (*aIt))) { + delete *it; + it = m_rects.erase(it); + rectfound = true; + } + qCDebug(OkularCoreDebug) << "removed annotation:" << annotation->uniqueName(); + annotation->d_ptr->m_page = nullptr; + m_annotations.erase(aIt); + break; + } + } + + return true; +} + +void Page::setTransition(PageTransition *transition) +{ + delete d->m_transition; + d->m_transition = transition; +} + +void Page::setPageAction(PageAction action, Action *link) +{ + switch (action) { + case Page::Opening: + delete d->m_openingAction; + d->m_openingAction = link; + break; + case Page::Closing: + delete d->m_closingAction; + d->m_closingAction = link; + break; + } +} + +void Page::setFormFields(const QLinkedList &fields) +{ + qDeleteAll(d->formfields); + d->formfields = fields; + for (FormField *ff : qAsConst(d->formfields)) { + ff->d_ptr->setDefault(); + } +} + +void Page::deletePixmap(DocumentObserver *observer) +{ + TilesManager *tm = d->tilesManager(observer); + if (tm) { + delete tm; + d->m_tilesManagers.remove(observer); + } else { + PagePrivate::PixmapObject object = d->m_pixmaps.take(observer); + delete object.m_pixmap; + } +} + +void Page::deletePixmaps() +{ + QMapIterator it(d->m_pixmaps); + while (it.hasNext()) { + it.next(); + delete it.value().m_pixmap; + } + + d->m_pixmaps.clear(); + + qDeleteAll(d->m_tilesManagers); + d->m_tilesManagers.clear(); +} + +void Page::deleteRects() +{ + // delete ObjectRects of type Link and Image + QSet which; + which << ObjectRect::Action << ObjectRect::Image; + deleteObjectRects(m_rects, which); +} + +void PagePrivate::deleteHighlights(int s_id) +{ + // delete highlights by ID + QLinkedList::iterator it = m_page->m_highlights.begin(), end = m_page->m_highlights.end(); + while (it != end) { + HighlightAreaRect *highlight = *it; + if (s_id == -1 || highlight->s_id == s_id) { + it = m_page->m_highlights.erase(it); + delete highlight; + } else + ++it; + } +} + +void PagePrivate::deleteTextSelections() +{ + delete m_textSelections; + m_textSelections = nullptr; +} + +void Page::deleteSourceReferences() +{ + deleteObjectRects(m_rects, QSet() << ObjectRect::SourceRef); +} + +void Page::deleteAnnotations() +{ + // delete ObjectRects of type Annotation + deleteObjectRects(m_rects, QSet() << ObjectRect::OAnnotation); + // delete all stored annotations + qDeleteAll(m_annotations); + m_annotations.clear(); +} + +bool PagePrivate::restoreLocalContents(const QDomNode &pageNode) +{ + bool loadedAnything = false; // set if something actually gets loaded + + // iterate over all children (annotationList, ...) + QDomNode childNode = pageNode.firstChild(); + while (childNode.isElement()) { + QDomElement childElement = childNode.toElement(); + childNode = childNode.nextSibling(); + + // parse annotationList child element + if (childElement.tagName() == QLatin1String("annotationList")) { +#ifdef PAGE_PROFILE + QTime time; + time.start(); +#endif + // Clone annotationList as root node in restoredLocalAnnotationList + const QDomNode clonedNode = restoredLocalAnnotationList.importNode(childElement, true); + restoredLocalAnnotationList.appendChild(clonedNode); + + // iterate over all annotations + QDomNode annotationNode = childElement.firstChild(); + while (annotationNode.isElement()) { + // get annotation element and advance to next annot + QDomElement annotElement = annotationNode.toElement(); + annotationNode = annotationNode.nextSibling(); + + // get annotation from the dom element + Annotation *annotation = AnnotationUtils::createAnnotation(annotElement); + + // append annotation to the list or show warning + if (annotation) { + m_doc->performAddPageAnnotation(m_number, annotation); + qCDebug(OkularCoreDebug) << "restored annot:" << annotation->uniqueName(); + loadedAnything = true; + } else + qCWarning(OkularCoreDebug).nospace() << "page (" << m_number << "): can't restore an annotation from XML."; + } +#ifdef PAGE_PROFILE + qCDebug(OkularCoreDebug).nospace() << "annots: XML Load time: " << time.elapsed() << "ms"; +#endif + } + // parse formList child element + else if (childElement.tagName() == QLatin1String("forms")) { + // Clone forms as root node in restoredFormFieldList + const QDomNode clonedNode = restoredFormFieldList.importNode(childElement, true); + restoredFormFieldList.appendChild(clonedNode); + + if (formfields.isEmpty()) + continue; + + QHash hashedforms; + for (FormField *ff : qAsConst(formfields)) { + hashedforms[ff->id()] = ff; + } + + // iterate over all forms + QDomNode formsNode = childElement.firstChild(); + while (formsNode.isElement()) { + // get annotation element and advance to next annot + QDomElement formElement = formsNode.toElement(); + formsNode = formsNode.nextSibling(); + + if (formElement.tagName() != QLatin1String("form")) + continue; + + bool ok = true; + int index = formElement.attribute(QStringLiteral("id")).toInt(&ok); + if (!ok) + continue; + + QHash::const_iterator wantedIt = hashedforms.constFind(index); + if (wantedIt == hashedforms.constEnd()) + continue; + + QString value = formElement.attribute(QStringLiteral("value")); + (*wantedIt)->d_ptr->setValue(value); + loadedAnything = true; + } + } + } + + return loadedAnything; +} + +void PagePrivate::saveLocalContents(QDomNode &parentNode, QDomDocument &document, PageItems what) const +{ + // create the page node and set the 'number' attribute + QDomElement pageElement = document.createElement(QStringLiteral("page")); + pageElement.setAttribute(QStringLiteral("number"), m_number); + +#if 0 + // add bookmark info if is bookmarked + if ( d->m_bookmarked ) + { + // create the pageElement's 'bookmark' child + QDomElement bookmarkElement = document.createElement( "bookmark" ); + pageElement.appendChild( bookmarkElement ); + + // add attributes to the element + //bookmarkElement.setAttribute( "name", bookmark name ); + } +#endif + + // add annotations info if has got any + if ((what & AnnotationPageItems) && (what & OriginalAnnotationPageItems)) { + const QDomElement savedDocRoot = restoredLocalAnnotationList.documentElement(); + if (!savedDocRoot.isNull()) { + // Import and append node in target document + const QDomNode importedNode = document.importNode(savedDocRoot, true); + pageElement.appendChild(importedNode); + } + } else if ((what & AnnotationPageItems) && !m_page->m_annotations.isEmpty()) { + // create the annotationList + QDomElement annotListElement = document.createElement(QStringLiteral("annotationList")); + + // add every annotation to the annotationList + QLinkedList::const_iterator aIt = m_page->m_annotations.constBegin(), aEnd = m_page->m_annotations.constEnd(); + for (; aIt != aEnd; ++aIt) { + // get annotation + const Annotation *a = *aIt; + // only save okular annotations (not the embedded in file ones) + if (!(a->flags() & Annotation::External)) { + // append an filled-up element called 'annotation' to the list + QDomElement annElement = document.createElement(QStringLiteral("annotation")); + AnnotationUtils::storeAnnotation(a, annElement, document); + annotListElement.appendChild(annElement); + qCDebug(OkularCoreDebug) << "save annotation:" << a->uniqueName(); + } + } + + // append the annotationList element if annotations have been set + if (annotListElement.hasChildNodes()) + pageElement.appendChild(annotListElement); + } + + // add forms info if has got any + if ((what & FormFieldPageItems) && (what & OriginalFormFieldPageItems)) { + const QDomElement savedDocRoot = restoredFormFieldList.documentElement(); + if (!savedDocRoot.isNull()) { + // Import and append node in target document + const QDomNode importedNode = document.importNode(savedDocRoot, true); + pageElement.appendChild(importedNode); + } + } else if ((what & FormFieldPageItems) && !formfields.isEmpty()) { + // create the formList + QDomElement formListElement = document.createElement(QStringLiteral("forms")); + + // add every form data to the formList + QLinkedList::const_iterator fIt = formfields.constBegin(), fItEnd = formfields.constEnd(); + for (; fIt != fItEnd; ++fIt) { + // get the form field + const FormField *f = *fIt; + + QString newvalue = f->d_ptr->value(); + if (f->d_ptr->m_default == newvalue) + continue; + + // append an filled-up element called 'annotation' to the list + QDomElement formElement = document.createElement(QStringLiteral("form")); + formElement.setAttribute(QStringLiteral("id"), f->id()); + formElement.setAttribute(QStringLiteral("value"), newvalue); + formListElement.appendChild(formElement); + } + + // append the annotationList element if annotations have been set + if (formListElement.hasChildNodes()) + pageElement.appendChild(formListElement); + } + + // append the page element only if has children + if (pageElement.hasChildNodes()) + parentNode.appendChild(pageElement); +} + +const QPixmap *Page::_o_nearestPixmap(DocumentObserver *observer, int w, int h) const +{ + Q_UNUSED(h) + + const QPixmap *pixmap = nullptr; + + // if a pixmap is present for given id, use it + QMap::const_iterator itPixmap = d->m_pixmaps.constFind(observer); + if (itPixmap != d->m_pixmaps.constEnd()) + pixmap = itPixmap.value().m_pixmap; + // else find the closest match using pixmaps of other IDs (great optim!) + else if (!d->m_pixmaps.isEmpty()) { + int minDistance = -1; + QMap::const_iterator it = d->m_pixmaps.constBegin(), end = d->m_pixmaps.constEnd(); + for (; it != end; ++it) { + int pixWidth = (*it).m_pixmap->width(), distance = pixWidth > w ? pixWidth - w : w - pixWidth; + if (minDistance == -1 || distance < minDistance) { + pixmap = (*it).m_pixmap; + minDistance = distance; + } + } + } + + return pixmap; +} + +bool Page::hasTilesManager(const DocumentObserver *observer) const +{ + return d->tilesManager(observer) != nullptr; +} + +QList Page::tilesAt(const DocumentObserver *observer, const NormalizedRect &rect) const +{ + TilesManager *tm = d->m_tilesManagers.value(observer); + if (tm) + return tm->tilesAt(rect, TilesManager::PixmapTile); + else + return QList(); +} + +TilesManager *PagePrivate::tilesManager(const DocumentObserver *observer) const +{ + return m_tilesManagers.value(observer); +} + +void PagePrivate::setTilesManager(const DocumentObserver *observer, TilesManager *tm) +{ + TilesManager *old = m_tilesManagers.value(observer); + delete old; + + m_tilesManagers.insert(observer, tm); +} + +void PagePrivate::adoptGeneratedContents(PagePrivate *oldPage) +{ + rotateAt(oldPage->m_rotation); + + m_pixmaps = oldPage->m_pixmaps; + oldPage->m_pixmaps.clear(); + + m_tilesManagers = oldPage->m_tilesManagers; + oldPage->m_tilesManagers.clear(); + + m_boundingBox = oldPage->m_boundingBox; + m_isBoundingBoxKnown = oldPage->m_isBoundingBoxKnown; + m_text = oldPage->m_text; + oldPage->m_text = nullptr; + + m_textSelections = oldPage->m_textSelections; + oldPage->m_textSelections = nullptr; + + restoredLocalAnnotationList = oldPage->restoredLocalAnnotationList; + restoredFormFieldList = oldPage->restoredFormFieldList; +} + +FormField *PagePrivate::findEquivalentForm(const Page *p, FormField *oldField) +{ + // given how id is not very good of id (at least for pdf) we do a few passes + // same rect, type and id + for (FormField *f : qAsConst(p->d->formfields)) { + if (f->rect() == oldField->rect() && f->type() == oldField->type() && f->id() == oldField->id()) + return f; + } + // same rect and type + for (FormField *f : qAsConst(p->d->formfields)) { + if (f->rect() == oldField->rect() && f->type() == oldField->type()) + return f; + } + // fuzzy rect, same type and id + for (FormField *f : qAsConst(p->d->formfields)) { + if (f->type() == oldField->type() && f->id() == oldField->id() && qFuzzyCompare(f->rect().left, oldField->rect().left) && qFuzzyCompare(f->rect().top, oldField->rect().top) && + qFuzzyCompare(f->rect().right, oldField->rect().right) && qFuzzyCompare(f->rect().bottom, oldField->rect().bottom)) { + return f; + } + } + // fuzzy rect and same type + for (FormField *f : qAsConst(p->d->formfields)) { + if (f->type() == oldField->type() && qFuzzyCompare(f->rect().left, oldField->rect().left) && qFuzzyCompare(f->rect().top, oldField->rect().top) && qFuzzyCompare(f->rect().right, oldField->rect().right) && + qFuzzyCompare(f->rect().bottom, oldField->rect().bottom)) { + return f; + } + } + return nullptr; +} diff --git a/core/page.h b/core/page.h new file mode 100644 index 0000000..666b28c --- /dev/null +++ b/core/page.h @@ -0,0 +1,422 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_PAGE_H_ +#define _OKULAR_PAGE_H_ + +#include + +#include "area.h" +#include "global.h" +#include "okularcore_export.h" +#include "textpage.h" + +class QPixmap; + +class PagePainter; + +namespace Okular +{ +class Annotation; +class Document; +class DocumentObserver; +class DocumentPrivate; +class FormField; +class PagePrivate; +class PageTransition; +class SourceReference; +class TextSelection; +class Tile; + +/** + * @short Collector for all the data belonging to a page. + * + * The Page class contains pixmaps (referenced using observers id as key), + * a search page (a class used internally for retrieving text), rect classes + * (that describe links or other active areas in the current page) and more. + * + * All coordinates are normalized to the page, so {x,y} are valid in [0,1] + * range as long as NormalizedRect components. + * + * Note: The class takes ownership of all objects. + */ +class OKULARCORE_EXPORT Page +{ +public: + /** + * An action to be executed when particular events happen. + */ + enum PageAction { + Opening, ///< An action to be executed when the page is "opened". + Closing ///< An action to be executed when the page is "closed". + }; + + /** + * Creates a new page. + * + * @param pageNumber The number of the page in the document. + * @param width The width of the page. + * @param height The height of the page. + * @param orientation The orientation of the page + */ + Page(uint pageNumber, double width, double height, Rotation orientation); + + /** + * Destroys the page. + */ + ~Page(); + + /** + * Returns the number of the page in the document. + */ + int number() const; + + /** + * Returns the orientation of the page as defined by the document. + */ + Rotation orientation() const; + + /** + * Returns the rotation of the page as defined by the user. + */ + Rotation rotation() const; + + /** + * Returns the total orientation which is the original orientation plus + * the user defined rotation. + */ + Rotation totalOrientation() const; + + /** + * Returns the width of the page. + */ + double width() const; + + /** + * Returns the height of the page. + */ + double height() const; + + /** + * Returns the ration (height / width) of the page. + */ + double ratio() const; + + /** + * Returns the bounding box of the page content in normalized [0,1] coordinates, + * in terms of the upright orientation (Rotation0). + * If it has not been computed yet, returns the full page (i.e., (0, 0, 1, 1)). + * Note that the bounding box may be null if the page is blank. + * + * @since 0.7 (KDE 4.1) + */ + NormalizedRect boundingBox() const; + + /** + * Returns whether the bounding box of the page has been computed. + * Note that even if the bounding box is computed, it may be null if the page is blank. + * + * @since 0.7 (KDE 4.1) + */ + bool isBoundingBoxKnown() const; + + /** + * Sets the bounding box of the page content in normalized [0,1] coordinates, + * in terms of the upright orientation (Rotation0). + * (This does not inform the document's observers, call Document::SetPageBoundingBox + * instead if you want that.) + * + * @since 0.7 (KDE 4.1) + */ + void setBoundingBox(const NormalizedRect &bbox); + + /** + * Returns whether the page of size @p width x @p height has a @p pixmap + * in the region given by @p rect for the given @p observer + * If there is a partially rendered pixmap the answer is false. + */ + bool hasPixmap(DocumentObserver *observer, int width = -1, int height = -1, const NormalizedRect &rect = NormalizedRect()) const; + + /** + * Returns whether the page provides a text page (@ref TextPage). + */ + bool hasTextPage() const; + + /** + * Returns whether the page has an object rect which includes the point (@p x, @p y) + * at scale (@p xScale, @p yScale). + */ + bool hasObjectRect(double x, double y, double xScale, double yScale) const; + + /** + * Returns whether the page provides highlighting for the observer with the + * given @p id. + */ + bool hasHighlights(int id = -1) const; + + /** + * Returns whether the page provides a transition effect. + */ + bool hasTransition() const; + + /** + * Returns whether the page provides annotations. + */ + bool hasAnnotations() const; + + /** + * Returns the bounding rect of the text which matches the following criteria + * or 0 if the search is not successful. + * + * @param id An unique id for this search. + * @param text The search text. + * @param direction The direction of the search (@ref SearchDirection) + * @param caseSensitivity If Qt::CaseSensitive, the search is case sensitive; otherwise + * the search is case insensitive. + * @param lastRect If 0 (default) the search starts at the beginning of the page, otherwise + * right/below the coordinates of the given rect. + */ + RegularAreaRect *findText(int id, const QString &text, SearchDirection direction, Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *lastRect = nullptr) const; + + /** + * Returns the page text (or part of it). + * @see TextPage::text() + */ + QString text(const RegularAreaRect *area = nullptr) const; + + /** + * Returns the page text (or part of it). + * @see TextPage::text() + * @since 0.10 (KDE 4.4) + */ + QString text(const RegularAreaRect *area, TextPage::TextAreaInclusionBehaviour b) const; + + /** + * Returns the page text (or part of it) including the bounding + * rectangles. Note that ownership of the contents of the returned + * list belongs to the caller. + * @see TextPage::words() + * @since 0.14 (KDE 4.8) + */ + TextEntity::List words(const RegularAreaRect *area, TextPage::TextAreaInclusionBehaviour b) const; + + /** + * Returns the area and text of the word at the given point + * Note that ownership of the returned area belongs to the caller. + * @see TextPage::wordAt() + * @since 0.15 (KDE 4.9) + */ + RegularAreaRect *wordAt(const NormalizedPoint &p, QString *word = nullptr) const; + + /** + * Returns the rectangular area of the given @p selection. + */ + RegularAreaRect *textArea(TextSelection *selection) const; + + /** + * Returns the object rect of the given @p type which is at point (@p x, @p y) at scale (@p xScale, @p yScale). + */ + const ObjectRect *objectRect(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale) const; + + /** + * Returns all object rects of the given @p type which are at point (@p x, @p y) at scale (@p xScale, @p yScale). + * @since 0.16 (KDE 4.10) + */ + QLinkedList objectRects(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale) const; + + /** + * Returns the object rect of the given @p type which is nearest to the point (@p x, @p y) at scale (@p xScale, @p yScale). + * + * @since 0.8.2 (KDE 4.2.2) + */ + const ObjectRect *nearestObjectRect(ObjectRect::ObjectType type, double x, double y, double xScale, double yScale, double *distance) const; + + /** + * Returns the transition effect of the page or 0 if no transition + * effect is set (see hasTransition()). + */ + const PageTransition *transition() const; + + /** + * Returns the list of annotations of the page. + */ + QLinkedList annotations() const; + + /** + * Returns the annotation with the given unique name. + * @since 1.3 + */ + Annotation *annotation(const QString &uniqueName) const; + + /** + * Returns the @ref Action object which is associated with the given page @p action + * or 0 if no page action is set. + */ + const Action *pageAction(PageAction action) const; + + /** + * Returns the list of FormField of the page. + */ + QLinkedList formFields() const; + + /** + * Sets the region described by @p rect with @p pixmap for the + * given @p observer. + * If @p rect is not set (default) the @p pixmap is set to the entire + * page. + */ + void setPixmap(DocumentObserver *observer, QPixmap *pixmap, const NormalizedRect &rect = NormalizedRect()); + + /** + * Sets the @p text page. + */ + void setTextPage(TextPage *text); + + /** + * Sets the list of object @p rects of the page. + */ + void setObjectRects(const QLinkedList &rects); + + /** + * Sets the list of source reference objects @p rects. + */ + void setSourceReferences(const QLinkedList &rects); + + /** + * Sets the duration of the page to @p seconds when displayed in presentation mode. + * + * Setting a negative number disables the duration. + */ + void setDuration(double seconds); + + /** + * Returns the duration in seconds of the page when displayed in presentation mode. + * + * A negative number means that no time is set. + */ + double duration() const; + + /** + * Sets the labels for the page to @p label . + */ + void setLabel(const QString &label); + + /** + * Returns the label of the page, or a null string if not set. + */ + QString label() const; + + /** + * Returns the current text selection. + */ + const RegularAreaRect *textSelection() const; + + /** + * Returns the color of the current text selection, or an invalid color + * if no text selection has been set. + */ + QColor textSelectionColor() const; + + /** + * Adds a new @p annotation to the page. + */ + void addAnnotation(Annotation *annotation); + + /** + * Removes the @p annotation from the page. + */ + bool removeAnnotation(Annotation *annotation); + + /** + * Sets the page @p transition effect. + */ + void setTransition(PageTransition *transition); + + /** + * Sets the @p link object for the given page @p action. + */ + void setPageAction(PageAction action, Action *link); + + /** + * Sets @p fields as list of FormField of the page. + */ + void setFormFields(const QLinkedList &fields); + + /** + * Deletes the pixmap for the given @p observer + */ + void deletePixmap(DocumentObserver *observer); + + /** + * Deletes all pixmaps of the page. + */ + void deletePixmaps(); + + /** + * Deletes all object rects of the page. + */ + void deleteRects(); + + /** + * Deletes all source reference objects of the page. + */ + void deleteSourceReferences(); + + /** + * Deletes all annotations of the page. + */ + void deleteAnnotations(); + + /** + * Returns whether pixmaps for the tiled observer are handled by a + * tile manager. + * + * @since 0.19 (KDE 4.13) + */ + bool hasTilesManager(const DocumentObserver *observer) const; + + /** + * Returns a list of all tiles intersecting with @p rect. + * + * The list contains only tiles with a pixmap + * + * @since 0.19 (KDE 4.13) + */ + QList tilesAt(const DocumentObserver *observer, const NormalizedRect &rect) const; + +private: + PagePrivate *d; + /// @cond PRIVATE + friend class PagePrivate; + friend class Document; + friend class DocumentPrivate; + friend class PixmapRequestPrivate; + + /** + * To improve performance PagePainter accesses the following + * member variables directly. + */ + friend class ::PagePainter; + /// @endcond + + const QPixmap *_o_nearestPixmap(DocumentObserver *, int, int) const; + + QLinkedList m_rects; + QLinkedList m_highlights; + QLinkedList m_annotations; + + Q_DISABLE_COPY(Page) +}; + +} + +#endif diff --git a/core/page_p.h b/core/page_p.h new file mode 100644 index 0000000..405e4c4 --- /dev/null +++ b/core/page_p.h @@ -0,0 +1,179 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_PAGE_PRIVATE_H_ +#define _OKULAR_PAGE_PRIVATE_H_ + +// qt/kde includes +#include +#include +#include +#include +#include + +// local includes +#include "area.h" +#include "global.h" + +class QColor; + +namespace Okular +{ +class Action; +class Annotation; +class DocumentObserver; +class DocumentPrivate; +class FormField; +class HighlightAreaRect; +class Page; +class PageSize; +class PageTransition; +class RotationJob; +class TextPage; +class TilesManager; + +enum PageItem { + None = 0, + AnnotationPageItems = 0x01, + FormFieldPageItems = 0x02, + AllPageItems = 0xff, + + /* If set along with AnnotationPageItems, tells saveLocalContents to save + * the original annotations (if any) instead of the modified ones */ + OriginalAnnotationPageItems = 0x100, + + /* If set along with FormFieldPageItems, tells saveLocalContents to save + * the original form contents (if any) instead of the modified one */ + OriginalFormFieldPageItems = 0x200 +}; +Q_DECLARE_FLAGS(PageItems, PageItem) + +class PagePrivate +{ +public: + PagePrivate(Page *page, uint n, double w, double h, Rotation o); + ~PagePrivate(); + + static PagePrivate *get(Page *page); + + void imageRotationDone(RotationJob *job); + QTransform rotationMatrix() const; + + /** + * Loads the local contents (e.g. annotations) of the page. + */ + bool restoreLocalContents(const QDomNode &pageNode); + + /** + * Saves the local contents (e.g. annotations) of the page. + */ + void saveLocalContents(QDomNode &parentNode, QDomDocument &document, PageItems what = AllPageItems) const; + + /** + * Rotates the image and object rects of the page to the given @p orientation. + */ + void rotateAt(Rotation orientation); + + /** + * Changes the size of the page to the given @p size. + * + * The @p size is meant to be referred to the page not rotated. + */ + void changeSize(const PageSize &size); + + /** + * Clears current text selection highlight areas, + * creates new ones if @p r is not nullptr, + * and deletes @p r. + * + * @param r Areas of new text selections. + * @param color Color of new text selections. + */ + void setTextSelections(RegularAreaRect *r, const QColor &color); + + /** + * Sets the @p color and @p rect of the highlight for the observer with + * the given @p id. + */ + void setHighlight(int id, RegularAreaRect *rect, const QColor &color); + + /** + * Deletes all highlight objects for the observer with the given @p id. + */ + void deleteHighlights(int id = -1); + + /** + * Deletes all text selection objects of the page. + */ + void deleteTextSelections(); + + /** + * Get the tiles manager for the tiled @p observer + */ + TilesManager *tilesManager(const DocumentObserver *observer) const; + + /** + * Set the tiles manager for the tiled @p observer + */ + void setTilesManager(const DocumentObserver *observer, TilesManager *tm); + + /** + * Moves contents that are generated from oldPage to this. And clears them from page + * so it can be deleted fine. + */ + void adoptGeneratedContents(PagePrivate *oldPage); + + /* + * Tries to find an equivalent form field to oldField by looking into the rect, type and name + */ + OKULARCORE_EXPORT static FormField *findEquivalentForm(const Page *p, FormField *oldField); + + void setPixmap(DocumentObserver *observer, QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap); + + class PixmapObject + { + public: + QPixmap *m_pixmap = nullptr; + Rotation m_rotation; + bool m_isPartialPixmap = false; + }; + QMap m_pixmaps; + QMap m_tilesManagers; + + Page *m_page; + int m_number; + Rotation m_orientation; + double m_width, m_height; + DocumentPrivate *m_doc; + NormalizedRect m_boundingBox; + Rotation m_rotation; + + TextPage *m_text; + PageTransition *m_transition; + HighlightAreaRect *m_textSelections; + QLinkedList formfields; + Action *m_openingAction; + Action *m_closingAction; + double m_duration; + QString m_label; + + bool m_isBoundingBoxKnown : 1; + QDomDocument restoredLocalAnnotationList; // ... + QDomDocument restoredFormFieldList; // ... +}; + +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(Okular::PageItems) + +#endif diff --git a/core/pagecontroller.cpp b/core/pagecontroller.cpp new file mode 100644 index 0000000..aa4d318 --- /dev/null +++ b/core/pagecontroller.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "pagecontroller_p.h" + +// local includes +#include "page_p.h" +#include "rotationjob_p.h" + +#include + +using namespace Okular; + +PageController::PageController() + : QObject() +{ +} + +PageController::~PageController() +{ +} + +void PageController::addRotationJob(RotationJob *job) +{ + connect(job, &RotationJob::done, this, &PageController::imageRotationDone); + ThreadWeaver::enqueue(&m_weaver, job); +} + +void PageController::imageRotationDone(const ThreadWeaver::JobPointer &j) +{ + RotationJob *job = static_cast(j.data()); + + if (job->page()) { + job->page()->imageRotationDone(job); + + emit rotationFinished(job->page()->m_number, job->page()->m_page); + } +} diff --git a/core/pagecontroller_p.h b/core/pagecontroller_p.h new file mode 100644 index 0000000..bf5c4bb --- /dev/null +++ b/core/pagecontroller_p.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2007 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_PAGECONTROLLER_P_H_ +#define _OKULAR_PAGECONTROLLER_P_H_ + +#include + +#include + +namespace Okular +{ +class Page; +class RotationJob; + +/* There is one PageController per document. It receives notifications of + * completed RotationJobs */ +class PageController : public QObject +{ + Q_OBJECT + +public: + PageController(); + ~PageController() override; + + void addRotationJob(RotationJob *job); + +Q_SIGNALS: + void rotationFinished(int page, Okular::Page *okularPage); + +private Q_SLOTS: + void imageRotationDone(const ThreadWeaver::JobPointer &job); + +private: + ThreadWeaver::Queue m_weaver; +}; + +} + +#endif diff --git a/core/pagesize.cpp b/core/pagesize.cpp new file mode 100644 index 0000000..6f1f9c9 --- /dev/null +++ b/core/pagesize.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +// local includes +#include "pagesize.h" + +using namespace Okular; + +class Okular::PageSizePrivate : public QSharedData +{ +public: + PageSizePrivate() + : m_width(0) + , m_height(0) + { + } + + bool operator==(const PageSizePrivate &rhs) const + { + return m_width == rhs.m_width && m_height == rhs.m_height && m_name == rhs.m_name; + } + + double m_width; + double m_height; + QString m_name; +}; + +PageSize::PageSize() +{ +} + +PageSize::PageSize(double width, double height, const QString &name) + : d(new PageSizePrivate) +{ + d->m_width = width; + d->m_height = height; + d->m_name = name; +} + +PageSize::PageSize(const PageSize &pageSize) + : d(pageSize.d) +{ +} + +PageSize::~PageSize() +{ +} + +double PageSize::width() const +{ + if (!d) + return 0; + + return d->m_width; +} + +double PageSize::height() const +{ + if (!d) + return 0; + + return d->m_height; +} + +QString PageSize::name() const +{ + if (!d) + return QString(); + + return d->m_name; +} + +bool PageSize::isNull() const +{ + if (!d) + return true; + + return d->m_width == 0 && d->m_height == 0 && d->m_name.isEmpty(); +} + +bool PageSize::operator==(const PageSize &pageSize) const +{ + // 1st: we're null: check if the other is null too + if (!d) + return !pageSize.d; + // 2nd: we're not null, return if the other is null + if (!pageSize.d) + return false; + + // 3rd: normal == check + return *d == *pageSize.d; +} + +bool PageSize::operator!=(const PageSize &pageSize) const +{ + return !operator==(pageSize); +} + +PageSize &PageSize::operator=(const PageSize &pageSize) +{ + if (this == &pageSize) + return *this; + + d = pageSize.d; + return *this; +} diff --git a/core/pagesize.h b/core/pagesize.h new file mode 100644 index 0000000..5f5b4d3 --- /dev/null +++ b/core/pagesize.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2007 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_PAGESIZE_H_ +#define _OKULAR_PAGESIZE_H_ + +#include +#include +#include + +#include "okularcore_export.h" + +namespace Okular +{ +class PageSizePrivate; + +/** + * @short A small class that represents the size of a page. + */ +class OKULARCORE_EXPORT PageSize +{ +public: + typedef QList List; + + /** + * Construct a null page size. + * @see isNull() + */ + PageSize(); + /** + * Construct a page size with the specified @p width and @p height, + * having the ID @p name. + */ + PageSize(double width, double height, const QString &name); + /** + * Copy constructor. + */ + PageSize(const PageSize &pageSize); + ~PageSize(); + + /** + * Returns the width of the page size. + */ + double width() const; + /** + * Returns the height of the page size. + */ + double height() const; + /** + * Returns the ID of the page size. + */ + QString name() const; + + /** + * Whether the page size is null. + */ + bool isNull() const; + + PageSize &operator=(const PageSize &pageSize); + + /** + * Comparison operator. + */ + bool operator==(const PageSize &pageSize) const; + + bool operator!=(const PageSize &pageSize) const; + +private: + /// @cond PRIVATE + friend class PageSizePrivate; + /// @endcond + QSharedDataPointer d; +}; + +} + +#endif diff --git a/core/pagetransition.cpp b/core/pagetransition.cpp new file mode 100644 index 0000000..03ef7e2 --- /dev/null +++ b/core/pagetransition.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +// local includes +#include "pagetransition.h" + +using namespace Okular; + +/** class Okular::PageTransition **/ + +class PageTransition::Private +{ +public: + Private(Type type) + : m_type(type) + , m_duration(1) + , m_alignment(Horizontal) + , m_direction(Inward) + , m_angle(0) + , m_scale(1.0) + , m_rectangular(false) + { + } + + Type m_type; + double m_duration; + Alignment m_alignment; + Direction m_direction; + int m_angle; + double m_scale; + bool m_rectangular; +}; + +PageTransition::PageTransition(Type type) + : d(new Private(type)) +{ +} + +PageTransition::PageTransition(const PageTransition &other) + : d(new Private(*other.d)) +{ +} + +PageTransition &PageTransition::operator=(const PageTransition &other) +{ + if (this == &other) + return *this; + + *d = *other.d; + + return *this; +} + +PageTransition::~PageTransition() +{ + delete d; +} + +PageTransition::Type PageTransition::type() const +{ + return d->m_type; +} + +double PageTransition::duration() const +{ + return d->m_duration; +} + +PageTransition::Alignment PageTransition::alignment() const +{ + return d->m_alignment; +} + +PageTransition::Direction PageTransition::direction() const +{ + return d->m_direction; +} + +int PageTransition::angle() const +{ + return d->m_angle; +} + +double PageTransition::scale() const +{ + return d->m_scale; +} + +bool PageTransition::isRectangular() const +{ + return d->m_rectangular; +} + +void PageTransition::setType(Type type) +{ + d->m_type = type; +} + +void PageTransition::setDuration(double duration) +{ + d->m_duration = duration; +} + +void PageTransition::setAlignment(Alignment alignment) +{ + d->m_alignment = alignment; +} + +void PageTransition::setDirection(Direction direction) +{ + d->m_direction = direction; +} + +void PageTransition::setAngle(int angle) +{ + d->m_angle = angle; +} + +void PageTransition::setScale(double scale) +{ + d->m_scale = scale; +} + +void PageTransition::setIsRectangular(bool rectangular) +{ + d->m_rectangular = rectangular; +} diff --git a/core/pagetransition.h b/core/pagetransition.h new file mode 100644 index 0000000..d6af21e --- /dev/null +++ b/core/pagetransition.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tobias Koenig * + * * + * 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_PAGETRANSITION_H_ +#define _OKULAR_PAGETRANSITION_H_ + +#include "okularcore_export.h" + +namespace Okular +{ +/** + * @short Information object for the transition effect of a page. + * + * This class encapsulates the information about the effect of + * a page transition. It supports mainly the transition effects as + * defined in PDF specification 1.6. + */ +class OKULARCORE_EXPORT PageTransition +{ +public: + /** + * Describes the type of transition effect. + */ + enum Type { Replace, Split, Blinds, Box, Wipe, Dissolve, Glitter, Fly, Push, Cover, Uncover, Fade }; + + /** + * Describes the alignment that is applied to the @ref Type + * of transition effect. + */ + enum Alignment { Horizontal, Vertical }; + + /** + * Describes the direction that is applied to the @ref Type + * of transition effect. + */ + enum Direction { Inward, Outward }; + + /** + * Creates a new page transition of the given @p type. + * + * If no type is given, the normal @ref Replace transition is used. + */ + PageTransition(Type type = Replace); + + /** + * Creates a new page transition from an @p other. + */ + PageTransition(const PageTransition &other); + PageTransition &operator=(const PageTransition &other); + + /** + * Destroys the page transition. + */ + ~PageTransition(); + + /** + * Returns the type of the transition. + */ + Type type() const; + + /** + * Returns the duration of the transition in seconds. + */ + double duration() const; + + /** + * Returns the alignment of the transition. + */ + Alignment alignment() const; + + /** + * Returns the direction of motion of the transition. + */ + Direction direction() const; + + /** + * Returns the angle of rotation of the transition. + */ + int angle() const; + + /** + * Returns the starting or ending scale (Only if type == 'Fly'). + */ + double scale() const; + + /** + * Returns true if the area to be flown is rectangular and opaque (Only if type == 'Fly'). + */ + bool isRectangular() const; + + /** + * Sets the @p type of the transition (@ref Type). + */ + void setType(Type type); + + /** + * Sets the @p duration in seconds for the transition. + */ + void setDuration(double duration); + + /** + * Sets the @p alignment of the transition (@ref Alignment). + */ + void setAlignment(Alignment alignment); + + /** + * Sets the @p direction of the transition (@see Direction). + */ + void setDirection(Direction direction); + + /** + * Sets the moving @p angle of the transition. + */ + void setAngle(int angle); + + /** + * Sets the starting or ending scale of the transition (Only if type == 'Fly'). + */ + void setScale(double scale); + + /** + * Sets whether the area to be flown is rectangular and opaque (Only if type == 'Fly'). + */ + void setIsRectangular(bool rectangular); + +private: + class Private; + Private *const d; +}; + +} + +#endif diff --git a/core/printoptionswidget.cpp b/core/printoptionswidget.cpp new file mode 100644 index 0000000..72208c0 --- /dev/null +++ b/core/printoptionswidget.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2019 Michael Weghorn * + * * + * 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. * + ***************************************************************************/ + +#include "printoptionswidget.h" + +#include +#include + +#include + +namespace Okular +{ +DefaultPrintOptionsWidget::DefaultPrintOptionsWidget(QWidget *parent) + : PrintOptionsWidget(parent) +{ + setWindowTitle(i18n("Print Options")); + QFormLayout *layout = new QFormLayout(this); + m_ignorePrintMargins = new QComboBox; + // value indicates whether full page is enabled (i.e. print margins ignored) + m_ignorePrintMargins->insertItem(0, i18n("Fit to printable area"), false); + m_ignorePrintMargins->insertItem(1, i18n("Fit to full page"), true); + layout->addRow(i18n("Scale mode:"), m_ignorePrintMargins); +} + +bool DefaultPrintOptionsWidget::ignorePrintMargins() const +{ + return m_ignorePrintMargins->currentData().value(); +} + +} diff --git a/core/printoptionswidget.h b/core/printoptionswidget.h new file mode 100644 index 0000000..09076c5 --- /dev/null +++ b/core/printoptionswidget.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2019 Michael Weghorn * + * * + * 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 PRINTOPTIONSWIDGET_H +#define PRINTOPTIONSWIDGET_H + +#include + +#include "okularcore_export.h" + +class QComboBox; + +namespace Okular +{ +/** + * @short Abstract base class for an extra print options widget in the print dialog. + */ +class OKULARCORE_EXPORT PrintOptionsWidget : public QWidget +{ + Q_OBJECT +public: + explicit PrintOptionsWidget(QWidget *parent = nullptr) + : QWidget(parent) + { + } + virtual bool ignorePrintMargins() const = 0; +}; + +/** + * @short The default okular extra print options widget. + * + * It just implements the required method 'ignorePrintMargins()' from + * the base class 'PrintOptionsWidget'. + */ +class OKULARCORE_EXPORT DefaultPrintOptionsWidget : public PrintOptionsWidget +{ + Q_OBJECT + +public: + explicit DefaultPrintOptionsWidget(QWidget *parent = nullptr); + + bool ignorePrintMargins() const override; + +private: + QComboBox *m_ignorePrintMargins; +}; + +} + +#endif diff --git a/core/rotationjob.cpp b/core/rotationjob.cpp new file mode 100644 index 0000000..dda14e9 --- /dev/null +++ b/core/rotationjob.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2006 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "rotationjob_p.h" + +#include + +using namespace Okular; + +RotationJob::RotationJob(const QImage &image, Rotation oldRotation, Rotation newRotation, DocumentObserver *observer) + : ThreadWeaver::QObjectDecorator(new RotationJobInternal(image, oldRotation, newRotation)) + , mObserver(observer) + , m_pd(nullptr) + , mRect(NormalizedRect()) + , mIsPartialUpdate(false) +{ +} + +void RotationJob::setPage(PagePrivate *pd) +{ + m_pd = pd; +} + +void RotationJob::setRect(const NormalizedRect &rect) +{ + mRect = rect; +} + +void RotationJob::setIsPartialUpdate(bool partialUpdate) +{ + mIsPartialUpdate = partialUpdate; +} + +DocumentObserver *RotationJob::observer() const +{ + return mObserver; +} + +PagePrivate *RotationJob::page() const +{ + return m_pd; +} + +NormalizedRect RotationJob::rect() const +{ + return mRect; +} + +bool RotationJob::isPartialUpdate() const +{ + return mIsPartialUpdate; +} + +QTransform RotationJob::rotationMatrix(Rotation from, Rotation to) +{ + QTransform matrix; + + if (from == Rotation0) { + if (to == Rotation90) + matrix.rotate(90); + else if (to == Rotation180) + matrix.rotate(180); + else if (to == Rotation270) + matrix.rotate(270); + } else if (from == Rotation90) { + if (to == Rotation180) + matrix.rotate(90); + else if (to == Rotation270) + matrix.rotate(180); + else if (to == Rotation0) + matrix.rotate(270); + } else if (from == Rotation180) { + if (to == Rotation270) + matrix.rotate(90); + else if (to == Rotation0) + matrix.rotate(180); + else if (to == Rotation90) + matrix.rotate(270); + } else if (from == Rotation270) { + if (to == Rotation0) + matrix.rotate(90); + else if (to == Rotation90) + matrix.rotate(180); + else if (to == Rotation180) + matrix.rotate(270); + } + + return matrix; +} + +RotationJobInternal::RotationJobInternal(const QImage &image, Rotation oldRotation, Rotation newRotation) + : mImage(image) + , mOldRotation(oldRotation) + , mNewRotation(newRotation) +{ +} + +QImage RotationJobInternal::image() const +{ + return mRotatedImage; +} + +Rotation RotationJobInternal::rotation() const +{ + return mNewRotation; +} + +void RotationJobInternal::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) +{ + Q_UNUSED(self); + Q_UNUSED(thread); + + if (mOldRotation == mNewRotation) { + mRotatedImage = mImage; + return; + } + + const QTransform matrix = RotationJob::rotationMatrix(mOldRotation, mNewRotation); + + mRotatedImage = mImage.transformed(matrix); +} + +#include "moc_rotationjob_p.cpp" diff --git a/core/rotationjob_p.h b/core/rotationjob_p.h new file mode 100644 index 0000000..430476c --- /dev/null +++ b/core/rotationjob_p.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2006 by Tobias Koenig * + * * + * 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_ROTATIONJOB_P_H_ +#define _OKULAR_ROTATIONJOB_P_H_ + +#include +#include + +#include +#include + +#include "core/area.h" +#include "core/global.h" + +namespace Okular +{ +class DocumentObserver; +class PagePrivate; + +class RotationJobInternal : public ThreadWeaver::Job +{ + friend class RotationJob; + +public: + QImage image() const; + Rotation rotation() const; + NormalizedRect rect() const; + + RotationJobInternal(const RotationJobInternal &) = delete; + RotationJobInternal &operator=(const RotationJobInternal &) = delete; + +protected: + void run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) override; + +private: + RotationJobInternal(const QImage &image, Rotation oldRotation, Rotation newRotation); + + const QImage mImage; + Rotation mOldRotation; + Rotation mNewRotation; + QImage mRotatedImage; +}; + +class RotationJob : public ThreadWeaver::QObjectDecorator +{ + Q_OBJECT +public: + RotationJob(const QImage &image, Rotation oldRotation, Rotation newRotation, DocumentObserver *observer); + + void setPage(PagePrivate *pd); + void setRect(const NormalizedRect &rect); + void setIsPartialUpdate(bool partialUpdate); + + QImage image() const + { + return static_cast(job())->image(); + } + Rotation rotation() const + { + return static_cast(job())->rotation(); + } + DocumentObserver *observer() const; + PagePrivate *page() const; + NormalizedRect rect() const; + bool isPartialUpdate() const; + + static QTransform rotationMatrix(Rotation from, Rotation to); + +private: + DocumentObserver *mObserver; + PagePrivate *m_pd; + NormalizedRect mRect; + bool mIsPartialUpdate; +}; + +} + +#endif diff --git a/core/script/builtin.js b/core/script/builtin.js new file mode 100644 index 0000000..6686873 --- /dev/null +++ b/core/script/builtin.js @@ -0,0 +1,334 @@ +/*************************************************************************** + * Copyright (C) 2018 Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +/* Builtin functions for Okular's PDF JavaScript interpretation. */ + +/** AFSimple_Calculate + * + * cFunction is a string that identifies the operation. + * It is one of AVG, SUM, PRD, MIN, MAX + * cFields is an array of the names of the fields used to calculate. + */ +function AFSimple_Calculate( cFunction, cFields ) +{ + var ret = 0; + + if ( cFunction === "PRD" ) + { + ret = 1; + } + + for (i = 0; i < cFields.length; i++) + { + var field = Doc.getField( cFields[i] ); + var val = util.stringToNumber( field.value ); + + if ( cFunction === "SUM" || cFunction === "AVG" ) + { + ret += val; + } + else if ( cFunction === "PRD" ) + { + ret *= val; + } + else if ( cFunction === "MIN" ) + { + if ( i === 0 || val < ret ) + { + ret = val; + } + } + else if ( cFunction === "MAX" ) + { + if ( i === 0 || val > ret ) + { + ret = val; + } + } + } + + if ( cFunction === "AVG" ) + { + ret /= cFields.length; + } + + event.value = util.numberToString( ret, "g", 32 ); +} + + +/** AFNumber_Format + * + * Formats event.value based on parameters. + * + * Parameter description based on Acrobat Help: + * + * nDec is the number of places after the decimal point. + * + * sepStyle is an integer denoting whether to use a separator + * If it is 1 comma should be used. + * If it is 2 a dot should be used. + * The decimal seperator is changed accordingly. + * + * nexStyle is the formatting used for negative numbers: - not implemented. + * 0 = MinusBlack + * 1 = Red + * 2 = ParensBlack + * 3 = ParensRed + * + * currStyle is the currency style - not used. + * + * strCurrency is the currency symbol. + * + * bCurrencyPrepend is true to prepend the currency symbol; + * false to display on the end of the number. + */ +function AFNumber_Format( nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend ) +{ + if ( !event.value ) + { + return; + } + + var ret; + var localized = util.stringToNumber( event.value ); + + if ( sepStyle === 2 ) + { + // Use de_DE as the locale for the dot seperator format + ret = util.numberToString( localized, "f", nDec, 'de_DE' ); + } + else + { + // Otherwise US + ret = util.numberToString( localized, "f", nDec, 'en_US' ); + } + + if ( sepStyle === 0 ) + { + // No seperators. Remove all commas from the US format. + ret.replace( /,/g, '' ); + } + + if ( strCurrency ) + { + if ( bCurrencyPrepend ) + { + ret = strCurrency + ret; + } + else + { + ret = ret + strCurrency; + } + } + + event.value = ret; +} + +function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend) +{ + // TODO + return; +} + +function AFMakeNumber(string) +{ + var type = typeof string; + if ( type == "number" ) + return string; + if ( type != "string" ) + return 0; + return util.stringToNumber( string ); +} + +/** AFTime_Format + * + * Formats event.value based on parameters. + * + * Parameter description based on Acrobat Help: + * + * ptf is the number which should be used to format the time, is one of: + * 0 = 24HR_MM [ 14:30 ] + * 1 = 12HR_MM [ 2:30 PM ] + * 2 = 24HR_MM_SS [ 14:30:15 ] + * 3 = 12HR_MM_SS [ 2:30:15 PM ] + */ +function AFTime_Format( ptf ) +{ + if( !event.value ) + { + return; + } + var tokens = event.value.split( /\D/ ); + var invalidDate = false; + + // Remove empty elements of the array + tokens = tokens.filter(Boolean); + + if( tokens.length < 2 ) + invalidDate = true; + + // Check if every number is valid + for( i = 0 ; i < tokens.length ; ++i ) + { + if( isNaN( tokens[i] ) ) + { + invalidDate = true; + break; + } + switch( i ) + { + case 0: + { + if( tokens[i] > 23 || tokens[i] < 0 ) + invalidDate = true; + break; + } + case 1: + case 2: + { + if( tokens[i] > 59 || tokens[i] < 0 ) + invalidDate = true; + break; + } + } + } + if( invalidDate ) + { + event.value = ""; + return; + } + + // Make it of lenght 3, since we use hh, mm, ss + while( tokens.length < 3 ) + tokens.push( 0 ); + + // We get pm string in the user locale to search. + var dummyPm = util.printd( 'ap', new Date( 2018, 5, 11, 23, 11, 11) ).toLocaleLowerCase(); + // Add 12 to time if it's PM and less than 12 + if( event.value.toLocaleLowerCase().search( dummyPm ) !== -1 && Number( tokens[0] ) < 12 ) + tokens[0] = Number( tokens[0] ) + 12; + + // We use a random date, because we only care about time. + var date = new Date( 2019, 7, 12, tokens[0], tokens[1], tokens[2] ); + var ret; + switch( ptf ) + { + case 0: + ret = util.printd( "hh:MM", date ); + break; + case 1: + ret = util.printd( "h:MM ap", date ); + break; + case 2: + ret = util.printd( "hh:MM:ss", date ); + break; + case 3: + ret = util.printd( "h:MM:ss ap", date ); + break; + } + event.value = ret; +} + +/** AFTime_Keystroke + * + * Checks if the string in event.value is valid. Not used. + */ +function AFTime_Keystroke( ptf ) +{ + return; +} + +/** AFSpecial_Format + * psf is the type of formatting to use: + * 0 = zip code + * 1 = zip + 4 + * 2 = phone + * 3 = SSN + * + * These are all in the US format. +*/ +function AFSpecial_Format( psf ) +{ + if( !event.value || psf == 0 ) + { + return; + } + + var ret = event.value; + + if( psf === 1 ) + ret = ret.substr( 0, 5 ) + '-' + ret.substr( 5, 4 ); + + else if( psf === 2 ) + ret = '(' + ret.substr( 0, 3 ) + ') ' + ret.substr( 3, 3 ) + '-' + ret.substr( 6, 4 ); + + else if( psf === 3 ) + ret = ret.substr( 0, 3 ) + '-' + ret.substr( 3, 2 ) + '-' + ret.substr( 5, 4 ); + + event.value = ret; +} + +/** AFSpecial_Keystroke + * + * Checks if the String in event.value is valid. + * + * Parameter description based on Acrobat Help: + * + * psf is the type of formatting to use: + * 0 = zip code + * 1 = zip + 4 + * 2 = phone + * 3 = SSN + * + * These are all in the US format. We check to see if only numbers are inserted and the length of the string. +*/ +function AFSpecial_Keystroke( psf ) +{ + if ( !event.value ) + { + return; + } + + var str = event.value; + if( psf === 0 ) + { + if( str.length > 5 ) + { + event.rc = false; + return; + } + } + + else if( psf === 1 || psf === 3 ) + { + if( str.length > 9 ) + { + event.rc = false; + return; + } + } + + else if( psf === 2 ) + { + if( str.length > 10 ) + { + event.rc = false; + return; + } + } + + for( i = 0 ; i < str.length ; ++i ) + { + if( !( str[i] <= '9' && str[i] >= '0' ) ) + { + event.rc = false; + return; + } + } +} diff --git a/core/script/builtin.qrc b/core/script/builtin.qrc new file mode 100644 index 0000000..9c83d4f --- /dev/null +++ b/core/script/builtin.qrc @@ -0,0 +1,5 @@ + + + builtin.js + + diff --git a/core/script/event.cpp b/core/script/event.cpp new file mode 100644 index 0000000..97bd239 --- /dev/null +++ b/core/script/event.cpp @@ -0,0 +1,251 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +#include "event_p.h" +#include + +#include "../form.h" + +using namespace Okular; + +class Event::Private +{ +public: + Private(EventType eventType) + : m_target(nullptr) + , m_targetPage(nullptr) + , m_source(nullptr) + , m_sourcePage(nullptr) + , m_eventType(eventType) + , m_returnCode(false) + , m_shiftModifier(false) + { + } + + void *m_target; + Page *m_targetPage; + FormField *m_source; + Page *m_sourcePage; + EventType m_eventType; + QString m_targetName; + QVariant m_value; + bool m_returnCode; + bool m_shiftModifier; +}; + +Event::Event() + : d(new Private(UnknownEvent)) +{ +} + +Event::Event(EventType eventType) + : d(new Private(eventType)) +{ +} + +Event::EventType Event::eventType() const +{ + return d->m_eventType; +} + +QString Event::name() const +{ + switch (d->m_eventType) { + case (FieldCalculate): + return QStringLiteral("Calculate"); + case (FieldFormat): + return QStringLiteral("Format"); + case (FieldKeystroke): + return QStringLiteral("Keystroke"); + case (FieldFocus): + return QStringLiteral("Focus"); + case (FieldValidate): + return QStringLiteral("Validate"); + case (UnknownEvent): + default: + return QStringLiteral("Unknown"); + } +} + +QString Event::type() const +{ + switch (d->m_eventType) { + case (FieldCalculate): + case (FieldFormat): + case (FieldKeystroke): + case (FieldFocus): + case (FieldValidate): + return QStringLiteral("Field"); + case (UnknownEvent): + default: + return QStringLiteral("Unknown"); + } +} + +QString Event::targetName() const +{ + if (!d->m_targetName.isNull()) { + return d->m_targetName; + } + + return QStringLiteral("JavaScript for: ") + type() + name(); +} + +void Event::setTargetName(const QString &val) +{ + d->m_targetName = val; +} + +FormField *Event::source() const +{ + return d->m_source; +} + +void Event::setSource(FormField *val) +{ + d->m_source = val; +} + +Page *Event::sourcePage() const +{ + return d->m_sourcePage; +} + +void Event::setSourcePage(Page *val) +{ + d->m_sourcePage = val; +} + +void *Event::target() const +{ + return d->m_target; +} + +void Event::setTarget(void *target) +{ + d->m_target = target; +} + +Page *Event::targetPage() const +{ + return d->m_targetPage; +} + +void Event::setTargetPage(Page *val) +{ + d->m_targetPage = val; +} + +QVariant Event::value() const +{ + return d->m_value; +} + +void Event::setValue(const QVariant &val) +{ + d->m_value = val; +} + +bool Event::returnCode() const +{ + return d->m_returnCode; +} + +void Event::setReturnCode(bool returnCode) +{ + d->m_returnCode = returnCode; +} + +bool Event::shiftModifier() const +{ + return d->m_shiftModifier; +} + +void Event::setShiftModifier(bool shiftModifier) +{ + d->m_shiftModifier = shiftModifier; +} + +// static +std::shared_ptr Event::createFormCalculateEvent(FormField *target, Page *targetPage, FormField *source, Page *sourcePage, const QString &targetName) +{ + std::shared_ptr ret(new Event(Event::FieldCalculate)); + ret->setSource(source); + ret->setSourcePage(sourcePage); + ret->setTarget(target); + ret->setTargetPage(targetPage); + ret->setTargetName(targetName); + + FormFieldText *fft = dynamic_cast(target); + if (fft) { + ret->setValue(QVariant(fft->text())); + } + return ret; +} + +// static +std::shared_ptr Event::createFormatEvent(FormField *target, Page *targetPage, const QString &targetName) +{ + std::shared_ptr ret(new Event(Event::FieldFormat)); + ret->setTarget(target); + ret->setTargetPage(targetPage); + ret->setTargetName(targetName); + + FormFieldText *fft = dynamic_cast(target); + if (fft) { + ret->setValue(QVariant(fft->text())); + } + return ret; +} + +// static +std::shared_ptr Event::createKeystrokeEvent(FormField *target, Page *targetPage) +{ + std::shared_ptr ret(new Event(Event::FieldKeystroke)); + ret->setTarget(target); + ret->setTargetPage(targetPage); + + FormFieldText *fft = dynamic_cast(target); + if (fft) { + ret->setReturnCode(true); + ret->setValue(QVariant(fft->text())); + } + return ret; +} + +std::shared_ptr Event::createFormFocusEvent(FormField *target, Page *targetPage, const QString &targetName) +{ + std::shared_ptr ret(new Event(Event::FieldFocus)); + ret->setTarget(target); + ret->setTargetPage(targetPage); + ret->setTargetName(targetName); + ret->setShiftModifier(QApplication::keyboardModifiers() & Qt::ShiftModifier); + + FormFieldText *fft = dynamic_cast(target); + if (fft) { + ret->setValue(QVariant(fft->text())); + } + return ret; +} + +std::shared_ptr Event::createFormValidateEvent(FormField *target, Page *targetPage, const QString &targetName) +{ + std::shared_ptr ret(new Event(Event::FieldValidate)); + ret->setTarget(target); + ret->setTargetPage(targetPage); + ret->setTargetName(targetName); + ret->setShiftModifier(QApplication::keyboardModifiers() & Qt::ShiftModifier); + + FormFieldText *fft = dynamic_cast(target); + if (fft) { + ret->setValue(QVariant(fft->text())); + ret->setReturnCode(true); + } + return ret; +} diff --git a/core/script/event_p.h b/core/script/event_p.h new file mode 100644 index 0000000..0048491 --- /dev/null +++ b/core/script/event_p.h @@ -0,0 +1,124 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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_SCRIPT_EVENT_P_H +#define OKULAR_SCRIPT_EVENT_P_H + +#include +#include + +#include + +namespace Okular +{ +class FormField; +class Page; + +/** + * @short A JavaScript Event Object data container. + * + * Object to represet a JavaScript Event Object as described in the + * Acrobat JavaScript Scripting Reference. + * + * The implementation is currently limited. To implement support + * for a new event create the according data fields / getters + * and setters and update the handling in kjs_event + * accordingly. + * + * See Acrobat JavaScript Scripting Reference for the meaning + * the fields and add getter / setter according for the + * event you wish to implement. + */ +class Event +{ +private: + Event(); + +public: + enum EventType { + UnknownEvent, /// < Unknown + AppInit, /// < Not implemented. + BatchExec, /// < Not implemented. + BookmarkMouseUp, /// < Not implemented. + ConsoleExec, /// < Not implemented. + DocDidPrint, /// < Not implemented. + DocDidSave, /// < Not implemented. + DocOpen, /// < Not implemented. + DocWillClose, /// < Not implemented. + DocWillPrint, /// < Not implemented. + DocWillSave, /// < Not implemented. + ExternalExec, /// < Not implemented. + FieldBlur, /// < Not implemented. + FieldCalculate, /// < This event is defined in a field re-calculation. + FieldFocus, /// < This event is defined when the field gains or loses focus. + FieldFormat, /// < When a format action is executed + FieldKeystroke, /// < Checks if the entered value is valid. + FieldMouseDown, /// < Not implemented. + FieldMouseEnter, /// < Not implemented. + FieldMouseExit, /// < Not implemented. + FieldMouseUp, /// < Not implemented. + /* Validates the field after every change is committed + * (clicked outside or tabbed to another field). + * The enter event is not handled + */ + FieldValidate, + LinkMouseUp, /// < Not implemented. + MenuExec, /// < Not implemented. + PageOpen, /// < Not implemented. + PageClose, /// < Not implemented. + }; + + explicit Event(EventType type); + + /** One of the defined EventTypes */ + EventType eventType() const; + + QString name() const; + + QString type() const; + + QString targetName() const; + void setTargetName(const QString &val); + + Page *targetPage() const; + void setTargetPage(Page *val); + + FormField *source() const; + void setSource(FormField *val); + + Page *sourcePage() const; + void setSourcePage(Page *val); + + void *target() const; + void setTarget(void *target); + + QVariant value() const; + void setValue(const QVariant &val); + + bool returnCode() const; + void setReturnCode(bool returnCode); + + // Checks if the shift key was down when creating the event. + bool shiftModifier() const; + void setShiftModifier(bool shiftModifier); + + static std::shared_ptr createFormCalculateEvent(FormField *target, Page *targetPage, FormField *source = nullptr, Page *sourcePage = nullptr, const QString &targetName = QString()); + static std::shared_ptr createFormatEvent(FormField *target, Page *targetPage, const QString &targetName = QString()); + static std::shared_ptr createKeystrokeEvent(FormField *target, Page *targetPage); + static std::shared_ptr createFormFocusEvent(FormField *target, Page *targetPage, const QString &targetName = QString()); + static std::shared_ptr createFormValidateEvent(FormField *target, Page *targetPage, const QString &targetName = QString()); + +private: + class Private; + std::shared_ptr d; + Q_DISABLE_COPY(Event) +}; + +} // namespace Okular +#endif // OKULAR_SCRIPT_EVENT_P_H diff --git a/core/script/executor_kjs.cpp b/core/script/executor_kjs.cpp new file mode 100644 index 0000000..32272ca --- /dev/null +++ b/core/script/executor_kjs.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "executor_kjs_p.h" + +#include +#include +#include +#include +#include + +#include + +#include "../debug_p.h" +#include "../document_p.h" + +#include "config-okular.h" +#include "event_p.h" +#include "kjs_app_p.h" +#include "kjs_console_p.h" +#include "kjs_data_p.h" +#include "kjs_display_p.h" +#include "kjs_document_p.h" +#include "kjs_event_p.h" +#include "kjs_field_p.h" +#include "kjs_fullscreen_p.h" +#include "kjs_ocg_p.h" +#include "kjs_spell_p.h" +#include "kjs_util_p.h" + +using namespace Okular; + +class Okular::ExecutorKJSPrivate +{ +public: + ExecutorKJSPrivate(DocumentPrivate *doc) + : m_doc(doc) + { + initTypes(); + } + ~ExecutorKJSPrivate() + { + delete m_interpreter; + } + + void initTypes(); + + DocumentPrivate *m_doc; + KJSInterpreter *m_interpreter; + KJSGlobalObject m_docObject; +}; + +void ExecutorKJSPrivate::initTypes() +{ + m_docObject = JSDocument::wrapDocument(m_doc); + m_interpreter = new KJSInterpreter(m_docObject); + +#if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0) + m_interpreter->setTimeoutTime(2000); // max 2 secs allowed +#endif + KJSContext *ctx = m_interpreter->globalContext(); + + JSApp::initType(ctx); + JSFullscreen::initType(ctx); + JSConsole::initType(ctx); + JSData::initType(ctx); + JSDisplay::initType(ctx); + JSDocument::initType(ctx); + JSEvent::initType(ctx); + JSField::initType(ctx); + JSOCG::initType(ctx); + JSSpell::initType(ctx); + JSUtil::initType(ctx); + + m_docObject.setProperty(ctx, QStringLiteral("app"), JSApp::object(ctx, m_doc)); + m_docObject.setProperty(ctx, QStringLiteral("console"), JSConsole::object(ctx)); + m_docObject.setProperty(ctx, QStringLiteral("Doc"), m_docObject); + m_docObject.setProperty(ctx, QStringLiteral("display"), JSDisplay::object(ctx)); + m_docObject.setProperty(ctx, QStringLiteral("OCG"), JSOCG::object(ctx)); + m_docObject.setProperty(ctx, QStringLiteral("spell"), JSSpell::object(ctx)); + m_docObject.setProperty(ctx, QStringLiteral("util"), JSUtil::object(ctx)); +} + +ExecutorKJS::ExecutorKJS(DocumentPrivate *doc) + : d(new ExecutorKJSPrivate(doc)) +{ +} + +ExecutorKJS::~ExecutorKJS() +{ + JSField::clearCachedFields(); + JSApp::clearCachedFields(); + JSOCG::clearCachedFields(); + delete d; +} + +void ExecutorKJS::execute(const QString &script, Event *event) +{ +#if 0 + QString script2; + QString errMsg; + int errLine; + if ( !KJSInterpreter::normalizeCode( script, &script2, &errLine, &errMsg ) ) + { + qCWarning(OkularCoreDebug) << "Parse error during normalization!"; + script2 = script; + } +#endif + + KJSContext *ctx = d->m_interpreter->globalContext(); + + d->m_docObject.setProperty(ctx, QStringLiteral("event"), event ? JSEvent::wrapEvent(ctx, event) : KJSUndefined()); + +#if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0) + d->m_interpreter->startTimeoutCheck(); +#endif + KJSResult result = d->m_interpreter->evaluate(QStringLiteral("okular.js"), 1, script, &d->m_docObject); +#if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0) + d->m_interpreter->stopTimeoutCheck(); +#endif + + if (result.isException() || ctx->hasException()) { + qCDebug(OkularCoreDebug) << "JS exception" << result.errorMessage(); + } else { + qCDebug(OkularCoreDebug) << "result:" << result.value().toString(ctx); + + if (event) { + qCDebug(OkularCoreDebug) << "Event Result:" << event->name() << event->type() << "value:" << event->value(); + } + } +} diff --git a/core/script/executor_kjs_p.h b/core/script/executor_kjs_p.h new file mode 100644 index 0000000..4cbdbfc --- /dev/null +++ b/core/script/executor_kjs_p.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * 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_SCRIPT_EXECUTOR_KJS_P_H +#define OKULAR_SCRIPT_EXECUTOR_KJS_P_H + +class QString; + +namespace Okular +{ +class DocumentPrivate; +class ExecutorKJSPrivate; +class Event; + +class ExecutorKJS +{ +public: + explicit ExecutorKJS(DocumentPrivate *doc); + ~ExecutorKJS(); + + ExecutorKJS(const ExecutorKJS &) = delete; + ExecutorKJS &operator=(const ExecutorKJS &) = delete; + + void execute(const QString &script, Event *event); + +private: + friend class ExecutorKJSPrivate; + ExecutorKJSPrivate *d; +}; + +} + +#endif diff --git a/core/script/kjs_app.cpp b/core/script/kjs_app.cpp new file mode 100644 index 0000000..ae96d66 --- /dev/null +++ b/core/script/kjs_app.cpp @@ -0,0 +1,424 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_app_p.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include "../document_p.h" +#include "../scripter.h" +#include "config-okular.h" +#include "kjs_fullscreen_p.h" + +using namespace Okular; + +#define OKULAR_TIMERID QStringLiteral("okular_timerID") + +static KJSPrototype *g_appProto; +typedef QHash TimerCache; +Q_GLOBAL_STATIC(TimerCache, g_timerCache) + +// the acrobat version we fake +static const double fake_acroversion = 8.00; + +static const struct FakePluginInfo { + const char *name; + bool certified; + bool loaded; + const char *path; +} s_fake_plugins[] = {{"Annots", true, true, ""}, {"EFS", true, true, ""}, {"EScript", true, true, ""}, {"Forms", true, true, ""}, {"ReadOutLoud", true, true, ""}, {"WebLink", true, true, ""}}; +static const int s_num_fake_plugins = sizeof(s_fake_plugins) / sizeof(s_fake_plugins[0]); + +static KJSObject appGetFormsVersion(KJSContext *, void *) +{ + // faking a bit... + return KJSNumber(fake_acroversion); +} + +static KJSObject appGetLanguage(KJSContext *, void *) +{ + QLocale locale; + QString lang = QLocale::languageToString(locale.language()); + QString country = QLocale::countryToString(locale.country()); + QString acroLang = QStringLiteral("ENU"); + if (lang == QLatin1String("da")) + acroLang = QStringLiteral("DAN"); // Danish + else if (lang == QLatin1String("de")) + acroLang = QStringLiteral("DEU"); // German + else if (lang == QLatin1String("en")) + acroLang = QStringLiteral("ENU"); // English + else if (lang == QLatin1String("es")) + acroLang = QStringLiteral("ESP"); // Spanish + else if (lang == QLatin1String("fr")) + acroLang = QStringLiteral("FRA"); // French + else if (lang == QLatin1String("it")) + acroLang = QStringLiteral("ITA"); // Italian + else if (lang == QLatin1String("ko")) + acroLang = QStringLiteral("KOR"); // Korean + else if (lang == QLatin1String("ja")) + acroLang = QStringLiteral("JPN"); // Japanese + else if (lang == QLatin1String("nl")) + acroLang = QStringLiteral("NLD"); // Dutch + else if (lang == QLatin1String("pt") && country == QLatin1String("BR")) + acroLang = QStringLiteral("PTB"); // Brazilian Portuguese + else if (lang == QLatin1String("fi")) + acroLang = QStringLiteral("SUO"); // Finnish + else if (lang == QLatin1String("sv")) + acroLang = QStringLiteral("SVE"); // Swedish + else if (lang == QLatin1String("zh") && country == QLatin1String("CN")) + acroLang = QStringLiteral("CHS"); // Chinese Simplified + else if (lang == QLatin1String("zh") && country == QLatin1String("TW")) + acroLang = QStringLiteral("CHT"); // Chinese Traditional + return KJSString(acroLang); +} + +static KJSObject appGetNumPlugins(KJSContext *, void *) +{ + return KJSNumber(s_num_fake_plugins); +} + +static KJSObject appGetPlatform(KJSContext *, void *) +{ +#if defined(Q_OS_WIN) + return KJSString(QString::fromLatin1("WIN")); +#elif defined(Q_OS_MAC) + return KJSString(QString::fromLatin1("MAC")); +#else + return KJSString(QStringLiteral("UNIX")); +#endif +} + +static KJSObject appGetPlugIns(KJSContext *context, void *) +{ + KJSArray plugins(context, s_num_fake_plugins); + for (int i = 0; i < s_num_fake_plugins; ++i) { + const FakePluginInfo &info = s_fake_plugins[i]; + KJSObject plugin; + plugin.setProperty(context, QStringLiteral("certified"), info.certified); + plugin.setProperty(context, QStringLiteral("loaded"), info.loaded); + plugin.setProperty(context, QStringLiteral("name"), info.name); + plugin.setProperty(context, QStringLiteral("path"), info.path); + plugin.setProperty(context, QStringLiteral("version"), fake_acroversion); + plugins.setProperty(context, QString::number(i), plugin); + } + return plugins; +} + +static KJSObject appGetPrintColorProfiles(KJSContext *context, void *) +{ + return KJSArray(context, 0); +} + +static KJSObject appGetPrinterNames(KJSContext *context, void *) +{ + return KJSArray(context, 0); +} + +static KJSObject appGetViewerType(KJSContext *, void *) +{ + // faking a bit... + return KJSString(QStringLiteral("Reader")); +} + +static KJSObject appGetViewerVariation(KJSContext *, void *) +{ + // faking a bit... + return KJSString(QStringLiteral("Reader")); +} + +static KJSObject appGetViewerVersion(KJSContext *, void *) +{ + // faking a bit... + return KJSNumber(fake_acroversion); +} + +/* + Alert function defined in the reference, it shows a Dialog Box with options. + app.alert() +*/ +static KJSObject appAlert(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(i18n("Missing alert type")); + } + QString cMsg = arguments.at(0).toString(context); + int nIcon = 0; + int nType = 0; + QString cTitle = QStringLiteral("Okular"); + + if (arguments.count() >= 2) + nIcon = arguments.at(1).toInt32(context); + if (arguments.count() >= 3) + nType = arguments.at(2).toInt32(context); + if (arguments.count() >= 4) + cTitle = arguments.at(3).toString(context); + + QMessageBox::Icon icon; + switch (nIcon) { + case 0: + icon = QMessageBox::Critical; + break; + case 1: + icon = QMessageBox::Warning; + break; + case 2: + icon = QMessageBox::Question; + break; + case 3: + icon = QMessageBox::Information; + break; + } + + QMessageBox box(icon, cTitle, cMsg); + + switch (nType) { + case 0: + box.setStandardButtons(QMessageBox::Ok); + break; + case 1: + box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + break; + case 2: + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + break; + case 3: + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + break; + } + + QCheckBox *checkBox = nullptr; + KJSObject oCheckbox; + if (arguments.count() >= 6) { + oCheckbox = arguments.at(5); + KJSObject oMsg = oCheckbox.property(context, QStringLiteral("cMsg")); + QString msg = i18n("Do not show this message again"); + + if (oMsg.isString()) + msg = oMsg.toString(context); + + bool bInitialValue = false; + KJSObject value = oCheckbox.property(context, QStringLiteral("bInitialValue")); + if (value.isBoolean()) + bInitialValue = value.toBoolean(context); + checkBox = new QCheckBox(msg); + checkBox->setChecked(bInitialValue); + box.setCheckBox(checkBox); + } + +#if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0) + // halt timeout until the user has responded + context->interpreter().stopTimeoutCheck(); +#endif + + int button = box.exec(); + +#if KJS_VERSION > QT_VERSION_CHECK(5, 71, 0) + // restart max allowed time + context->interpreter().startTimeoutCheck(); +#endif + + int ret; + + switch (button) { + case QMessageBox::Ok: + ret = 1; + break; + case QMessageBox::Cancel: + ret = 2; + break; + case QMessageBox::No: + ret = 3; + break; + case QMessageBox::Yes: + ret = 4; + break; + } + + if (arguments.count() >= 6) + oCheckbox.setProperty(context, QStringLiteral("bAfterValue"), checkBox->isChecked()); + + delete checkBox; + + return KJSNumber(ret); +} + +static KJSObject appBeep(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(QStringLiteral("Missing beep type")); + } + QApplication::beep(); + return KJSUndefined(); +} + +static KJSObject appGetNthPlugInName(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(QStringLiteral("Missing plugin index")); + } + const int nIndex = arguments.at(0).toInt32(context); + + if (nIndex < 0 || nIndex >= s_num_fake_plugins) + return context->throwException(QStringLiteral("PlugIn index out of bounds")); + + const FakePluginInfo &info = s_fake_plugins[nIndex]; + return KJSString(info.name); +} + +static KJSObject appGoBack(KJSContext *, void *object, const KJSArguments &) +{ + const DocumentPrivate *doc = reinterpret_cast(object); + if (doc->m_parent->historyAtBegin()) + return KJSUndefined(); + + doc->m_parent->setPrevViewport(); + return KJSUndefined(); +} + +static KJSObject appGoForward(KJSContext *, void *object, const KJSArguments &) +{ + const DocumentPrivate *doc = reinterpret_cast(object); + if (doc->m_parent->historyAtEnd()) + return KJSUndefined(); + + doc->m_parent->setNextViewport(); + return KJSUndefined(); +} + +// app.setInterval() +static KJSObject appSetInterval(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + const QString function = arguments.at(0).toString(ctx) + ';'; + const int interval = arguments.at(1).toInt32(ctx); + + QTimer *timer = new QTimer(); + + QObject::connect(timer, &QTimer::timeout, doc->m_parent, [=]() { doc->executeScript(function); }); + + timer->start(interval); + + return JSApp::wrapTimer(ctx, timer); +} + +// app.clearInterval() +static KJSObject appClearInterval(KJSContext *ctx, void *, const KJSArguments &arguments) +{ + KJSObject timerObject = arguments.at(0); + const int timerId = timerObject.property(ctx, OKULAR_TIMERID).toInt32(ctx); + QTimer *timer = g_timerCache->value(timerId); + if (timer != nullptr) { + timer->stop(); + g_timerCache->remove(timerId); + delete timer; + } + + return KJSUndefined(); +} + +// app.setTimeOut() +static KJSObject appSetTimeOut(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + const QString function = arguments.at(0).toString(ctx) + ';'; + const int interval = arguments.at(1).toInt32(ctx); + + QTimer *timer = new QTimer(); + timer->setSingleShot(true); + + QObject::connect(timer, &QTimer::timeout, doc->m_parent, [=]() { doc->executeScript(function); }); + + timer->start(interval); + + return JSApp::wrapTimer(ctx, timer); +} + +// app.clearTimeOut() +static KJSObject appClearTimeOut(KJSContext *ctx, void *, const KJSArguments &arguments) +{ + KJSObject timerObject = arguments.at(0); + const int timerId = timerObject.property(ctx, OKULAR_TIMERID).toInt32(ctx); + QTimer *timer = g_timerCache->value(timerId); + + if (timer != nullptr) { + timer->stop(); + g_timerCache->remove(timerId); + delete timer; + } + + return KJSUndefined(); +} + +void JSApp::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_appProto = new KJSPrototype(); + + g_appProto->defineProperty(ctx, QStringLiteral("formsVersion"), appGetFormsVersion); + g_appProto->defineProperty(ctx, QStringLiteral("language"), appGetLanguage); + g_appProto->defineProperty(ctx, QStringLiteral("numPlugIns"), appGetNumPlugins); + g_appProto->defineProperty(ctx, QStringLiteral("platform"), appGetPlatform); + g_appProto->defineProperty(ctx, QStringLiteral("plugIns"), appGetPlugIns); + g_appProto->defineProperty(ctx, QStringLiteral("printColorProfiles"), appGetPrintColorProfiles); + g_appProto->defineProperty(ctx, QStringLiteral("printerNames"), appGetPrinterNames); + g_appProto->defineProperty(ctx, QStringLiteral("viewerType"), appGetViewerType); + g_appProto->defineProperty(ctx, QStringLiteral("viewerVariation"), appGetViewerVariation); + g_appProto->defineProperty(ctx, QStringLiteral("viewerVersion"), appGetViewerVersion); + + g_appProto->defineFunction(ctx, QStringLiteral("alert"), appAlert); + g_appProto->defineFunction(ctx, QStringLiteral("beep"), appBeep); + g_appProto->defineFunction(ctx, QStringLiteral("getNthPlugInName"), appGetNthPlugInName); + g_appProto->defineFunction(ctx, QStringLiteral("goBack"), appGoBack); + g_appProto->defineFunction(ctx, QStringLiteral("goForward"), appGoForward); + g_appProto->defineFunction(ctx, QStringLiteral("setInterval"), appSetInterval); + g_appProto->defineFunction(ctx, QStringLiteral("clearInterval"), appClearInterval); + g_appProto->defineFunction(ctx, QStringLiteral("setTimeOut"), appSetTimeOut); + g_appProto->defineFunction(ctx, QStringLiteral("clearTimeOut"), appClearTimeOut); +} + +KJSObject JSApp::object(KJSContext *ctx, DocumentPrivate *doc) +{ + return g_appProto->constructObject(ctx, doc); +} + +KJSObject JSApp::wrapTimer(KJSContext *ctx, QTimer *timer) +{ + KJSObject timerObject = g_appProto->constructObject(ctx, timer); + timerObject.setProperty(ctx, OKULAR_TIMERID, timer->timerId()); + + g_timerCache->insert(timer->timerId(), timer); + + return timerObject; +} + +void JSApp::clearCachedFields() +{ + if (g_timerCache) { + qDeleteAll(g_timerCache->begin(), g_timerCache->end()); + g_timerCache->clear(); + } +} diff --git a/core/script/kjs_app_p.h b/core/script/kjs_app_p.h new file mode 100644 index 0000000..c56aaab --- /dev/null +++ b/core/script/kjs_app_p.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_APP_P_H +#define OKULAR_SCRIPT_KJS_APP_P_H + +class KJSContext; +class KJSObject; +class QTimer; + +namespace Okular +{ +class DocumentPrivate; + +class JSApp +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx, DocumentPrivate *doc); + static KJSObject wrapTimer(KJSContext *ctx, QTimer *timer); + static void clearCachedFields(); +}; + +} + +#endif diff --git a/core/script/kjs_console.cpp b/core/script/kjs_console.cpp new file mode 100644 index 0000000..08eab9b --- /dev/null +++ b/core/script/kjs_console.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_console_p.h" + +#include +#include +#include + +#include + +#include "../debug_p.h" + +using namespace Okular; + +static KJSPrototype *g_consoleProto; + +#ifdef OKULAR_JS_CONSOLE + +#include +#include + +#include +#include + +K_GLOBAL_STATIC(KDialog, g_jsConsoleWindow) +static QPlainTextEdit *g_jsConsoleLog = 0; + +static void createConsoleWindow() +{ + if (g_jsConsoleWindow.exists()) + return; + + g_jsConsoleWindow->setButtons(KDialog::Close | KDialog::User1); + g_jsConsoleWindow->setButtonGuiItem(KDialog::User1, KStandardGuiItem::clear()); + + QVBoxLayout *mainLay = new QVBoxLayout(g_jsConsoleWindow->mainWidget()); + mainLay->setContentsMargins(0, 0, 0, 0); + g_jsConsoleLog = new QPlainTextEdit(g_jsConsoleWindow->mainWidget()); + g_jsConsoleLog->setReadOnly(true); + mainLay->addWidget(g_jsConsoleLog); + + QObject::connect(g_jsConsoleWindow, SIGNAL(closeClicked()), g_jsConsoleWindow, SLOT(close())); + QObject::connect(g_jsConsoleWindow, SIGNAL(user1Clicked()), g_jsConsoleLog, SLOT(clear())); +} + +static void showConsole() +{ + createConsoleWindow(); + g_jsConsoleWindow->show(); +} + +static void hideConsole() +{ + if (!g_jsConsoleWindow.exists()) + return; + + g_jsConsoleWindow->hide(); +} + +static void clearConsole() +{ + if (!g_jsConsoleWindow.exists()) + return; + + g_jsConsoleLog->clear(); +} + +static void outputToConsole(const QString &message) +{ + showConsole(); + g_jsConsoleLog->appendPlainText(message); +} + +#else /* OKULAR_JS_CONSOLE */ + +static void showConsole() +{ +} + +static void hideConsole() +{ +} + +static void clearConsole() +{ +} + +static void outputToConsole(const QString &cMessage) +{ + qCDebug(OkularCoreDebug) << "CONSOLE:" << cMessage; +} + +#endif /* OKULAR_JS_CONSOLE */ + +static KJSObject consoleClear(KJSContext *, void *, const KJSArguments &) +{ + clearConsole(); + return KJSUndefined(); +} + +static KJSObject consoleHide(KJSContext *, void *, const KJSArguments &) +{ + hideConsole(); + return KJSUndefined(); +} + +static KJSObject consolePrintln(KJSContext *ctx, void *, const KJSArguments &arguments) +{ + QString cMessage = arguments.at(0).toString(ctx); + outputToConsole(cMessage); + + return KJSUndefined(); +} + +static KJSObject consoleShow(KJSContext *, void *, const KJSArguments &) +{ + showConsole(); + return KJSUndefined(); +} + +void JSConsole::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_consoleProto = new KJSPrototype(); + + g_consoleProto->defineFunction(ctx, QStringLiteral("clear"), consoleClear); + g_consoleProto->defineFunction(ctx, QStringLiteral("hide"), consoleHide); + g_consoleProto->defineFunction(ctx, QStringLiteral("println"), consolePrintln); + g_consoleProto->defineFunction(ctx, QStringLiteral("hide"), consoleShow); +} + +KJSObject JSConsole::object(KJSContext *ctx) +{ + return g_consoleProto->constructObject(ctx, nullptr); +} diff --git a/core/script/kjs_console_p.h b/core/script/kjs_console_p.h new file mode 100644 index 0000000..6a11ab2 --- /dev/null +++ b/core/script/kjs_console_p.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_CONSOLE_P_H +#define OKULAR_SCRIPT_KJS_CONSOLE_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class JSConsole +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); +}; + +} + +#endif diff --git a/core/script/kjs_data.cpp b/core/script/kjs_data.cpp new file mode 100644 index 0000000..7bfd86b --- /dev/null +++ b/core/script/kjs_data.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_data_p.h" + +#include +#include + +#include + +#include "../document.h" + +using namespace Okular; + +static KJSPrototype *g_dataProto; + +static KJSObject dataGetCreationDate(KJSContext *ctx, void *object) +{ + const EmbeddedFile *file = reinterpret_cast(object); + + return KJSDate(ctx, file->creationDate()); +} + +static KJSObject dataGetDescription(KJSContext *, void *object) +{ + const EmbeddedFile *file = reinterpret_cast(object); + + return KJSString(file->description()); +} + +static KJSObject dataGetMIMEType(KJSContext *, void *) +{ + return KJSString(""); +} + +static KJSObject dataGetModDate(KJSContext *ctx, void *object) +{ + const EmbeddedFile *file = reinterpret_cast(object); + + return KJSDate(ctx, file->modificationDate()); +} + +static KJSObject dataGetName(KJSContext *, void *object) +{ + const EmbeddedFile *file = reinterpret_cast(object); + + return KJSString(file->name()); +} + +static KJSObject dataGetPath(KJSContext *, void *) +{ + return KJSString(""); +} + +static KJSObject dataGetSize(KJSContext *, void *object) +{ + const EmbeddedFile *file = reinterpret_cast(object); + return KJSNumber(file->size()); +} + +void JSData::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + if (!g_dataProto) + g_dataProto = new KJSPrototype(); + + g_dataProto->defineProperty(ctx, QStringLiteral("creationDate"), dataGetCreationDate); + g_dataProto->defineProperty(ctx, QStringLiteral("description"), dataGetDescription); + g_dataProto->defineProperty(ctx, QStringLiteral("MIMEType"), dataGetMIMEType); + g_dataProto->defineProperty(ctx, QStringLiteral("modDate"), dataGetModDate); + g_dataProto->defineProperty(ctx, QStringLiteral("name"), dataGetName); + g_dataProto->defineProperty(ctx, QStringLiteral("path"), dataGetPath); + g_dataProto->defineProperty(ctx, QStringLiteral("size"), dataGetSize); +} + +KJSObject JSData::wrapFile(KJSContext *ctx, EmbeddedFile *f) +{ + return g_dataProto->constructObject(ctx, f); +} diff --git a/core/script/kjs_data_p.h b/core/script/kjs_data_p.h new file mode 100644 index 0000000..940ebfe --- /dev/null +++ b/core/script/kjs_data_p.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_DATA_P_H +#define OKULAR_SCRIPT_KJS_DATA_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class EmbeddedFile; + +class JSData +{ +public: + static void initType(KJSContext *ctx); + static KJSObject wrapFile(KJSContext *ctx, EmbeddedFile *f); +}; + +} + +#endif diff --git a/core/script/kjs_display.cpp b/core/script/kjs_display.cpp new file mode 100644 index 0000000..659cedc --- /dev/null +++ b/core/script/kjs_display.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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. * + ***************************************************************************/ + +#include "../form.h" +#include "kjs_display_p.h" + +#include +#include + +#include + +using namespace Okular; + +static KJSPrototype *g_displayProto; + +// display.hidden +static KJSObject displayGetHidden(KJSContext *, void *) +{ + return KJSNumber(FormDisplay::FormHidden); +} + +// display.visible +static KJSObject displayGetVisible(KJSContext *, void *) +{ + return KJSNumber(FormDisplay::FormVisible); +} + +// display.noView +static KJSObject displayGetNoView(KJSContext *, void *) +{ + return KJSNumber(FormDisplay::FormNoView); +} + +// display.noPrint +static KJSObject displayGetNoPrint(KJSContext *, void *) +{ + return KJSNumber(FormDisplay::FormNoPrint); +} + +void JSDisplay::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_displayProto = new KJSPrototype(); + + g_displayProto->defineProperty(ctx, QStringLiteral("hidden"), displayGetHidden); + g_displayProto->defineProperty(ctx, QStringLiteral("visible"), displayGetVisible); + g_displayProto->defineProperty(ctx, QStringLiteral("noView"), displayGetNoView); + g_displayProto->defineProperty(ctx, QStringLiteral("noPrint"), displayGetNoPrint); +} + +KJSObject JSDisplay::object(KJSContext *ctx) +{ + return g_displayProto->constructObject(ctx, nullptr); +} diff --git a/core/script/kjs_display_p.h b/core/script/kjs_display_p.h new file mode 100644 index 0000000..7b57af6 --- /dev/null +++ b/core/script/kjs_display_p.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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_SCRIPT_KJS_DISPLAY_P_H +#define OKULAR_SCRIPT_KJS_DISPLAY_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +/** + * The display types of the field. + */ +enum FormDisplay { FormVisible, FormHidden, FormNoPrint, FormNoView }; + +class JSDisplay +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); +}; + +} + +#endif diff --git a/core/script/kjs_document.cpp b/core/script/kjs_document.cpp new file mode 100644 index 0000000..d773f3b --- /dev/null +++ b/core/script/kjs_document.cpp @@ -0,0 +1,334 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_document_p.h" + +#include + +#include +#include +#include + +#include +#include + +#include "../document_p.h" +#include "../form.h" +#include "../page.h" +#include "kjs_data_p.h" +#include "kjs_field_p.h" +#include "kjs_ocg_p.h" + +using namespace Okular; + +static KJSPrototype *g_docProto; + +// Document.numPages +static KJSObject docGetNumPages(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSNumber(doc->m_pagesVector.count()); +} + +// Document.pageNum (getter) +static KJSObject docGetPageNum(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSNumber(doc->m_parent->currentPage()); +} + +// Document.pageNum (setter) +static void docSetPageNum(KJSContext *ctx, void *object, KJSObject value) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + int page = value.toInt32(ctx); + + if (page == (int)doc->m_parent->currentPage()) + return; + + doc->m_parent->setViewportPage(page); +} + +// Document.documentFileName +static KJSObject docGetDocumentFileName(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSString(doc->m_url.fileName()); +} + +// Document.filesize +static KJSObject docGetFilesize(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSNumber(doc->m_docSize); +} + +// Document.path +static KJSObject docGetPath(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSString(doc->m_url.toDisplayString(QUrl::PreferLocalFile)); +} + +// Document.URL +static KJSObject docGetURL(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + return KJSString(doc->m_url.toDisplayString()); +} + +// Document.permStatusReady +static KJSObject docGetPermStatusReady(KJSContext *, void *) +{ + return KJSBoolean(true); +} + +// Document.dataObjects +static KJSObject docGetDataObjects(KJSContext *ctx, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + const QList *files = doc->m_generator->embeddedFiles(); + + KJSArray dataObjects(ctx, files ? files->count() : 0); + if (files) { + QList::ConstIterator it = files->begin(), itEnd = files->end(); + for (int i = 0; it != itEnd; ++it, ++i) { + KJSObject newdata = JSData::wrapFile(ctx, *it); + dataObjects.setProperty(ctx, QString::number(i), newdata); + } + } + return dataObjects; +} + +// Document.external +static KJSObject docGetExternal(KJSContext *, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + QWidget *widget = doc->m_widget; + + const bool isShell = (widget && widget->parentWidget() && widget->parentWidget()->objectName().startsWith(QLatin1String("okular::Shell"))); + return KJSBoolean(!isShell); +} + +// Document.numFields +static KJSObject docGetNumFields(KJSContext *, void *object) +{ + const DocumentPrivate *doc = reinterpret_cast(object); + + unsigned int numFields = 0; + + for (const Page *pIt : qAsConst(doc->m_pagesVector)) { + numFields += pIt->formFields().size(); + } + + return KJSNumber(numFields); +} + +static KJSObject docGetInfo(KJSContext *ctx, void *object) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + KJSObject obj; + QSet keys; + keys << DocumentInfo::Title << DocumentInfo::Author << DocumentInfo::Subject << DocumentInfo::Keywords << DocumentInfo::Creator << DocumentInfo::Producer; + const DocumentInfo docinfo = doc->m_parent->documentInfo(keys); +#define KEY_GET(key, property) \ + do { \ + const QString data = docinfo.get(key); \ + if (!data.isEmpty()) { \ + const KJSString newval(data); \ + obj.setProperty(ctx, QStringLiteral(property), newval); \ + obj.setProperty(ctx, QStringLiteral(property).toLower(), newval); \ + } \ + } while (0); + KEY_GET(DocumentInfo::Title, "Title"); + KEY_GET(DocumentInfo::Author, "Author"); + KEY_GET(DocumentInfo::Subject, "Subject"); + KEY_GET(DocumentInfo::Keywords, "Keywords"); + KEY_GET(DocumentInfo::Creator, "Creator"); + KEY_GET(DocumentInfo::Producer, "Producer"); +#undef KEY_GET + return obj; +} + +#define DOCINFO_GET_METHOD(key, name) \ + static KJSObject docGet##name(KJSContext *, void *object) \ + { \ + DocumentPrivate *doc = reinterpret_cast(object); \ + const DocumentInfo docinfo = doc->m_parent->documentInfo(QSet() << key); \ + return KJSString(docinfo.get(key)); \ + } + +DOCINFO_GET_METHOD(DocumentInfo::Author, Author) +DOCINFO_GET_METHOD(DocumentInfo::Creator, Creator) +DOCINFO_GET_METHOD(DocumentInfo::Keywords, Keywords) +DOCINFO_GET_METHOD(DocumentInfo::Producer, Producer) +DOCINFO_GET_METHOD(DocumentInfo::Title, Title) +DOCINFO_GET_METHOD(DocumentInfo::Subject, Subject) + +#undef DOCINFO_GET_METHOD + +// Document.getField() +static KJSObject docGetField(KJSContext *context, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + QString cName = arguments.at(0).toString(context); + + QVector::const_iterator pIt = doc->m_pagesVector.constBegin(), pEnd = doc->m_pagesVector.constEnd(); + for (; pIt != pEnd; ++pIt) { + const QLinkedList pageFields = (*pIt)->formFields(); + QLinkedList::const_iterator ffIt = pageFields.constBegin(), ffEnd = pageFields.constEnd(); + for (; ffIt != ffEnd; ++ffIt) { + if ((*ffIt)->fullyQualifiedName() == cName) { + return JSField::wrapField(context, *ffIt, *pIt); + } + } + } + return KJSUndefined(); +} + +// Document.getPageLabel() +static KJSObject docGetPageLabel(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + int nPage = arguments.at(0).toInt32(ctx); + Page *p = doc->m_pagesVector.value(nPage); + return KJSString(p ? p->label() : QString()); +} + +// Document.getPageRotation() +static KJSObject docGetPageRotation(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + int nPage = arguments.at(0).toInt32(ctx); + Page *p = doc->m_pagesVector.value(nPage); + return KJSNumber(p ? p->orientation() * 90 : 0); +} + +// Document.gotoNamedDest() +static KJSObject docGotoNamedDest(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + DocumentPrivate *doc = reinterpret_cast(object); + + QString dest = arguments.at(0).toString(ctx); + + DocumentViewport viewport(doc->m_generator->metaData(QStringLiteral("NamedViewport"), dest).toString()); + if (!viewport.isValid()) + return KJSUndefined(); + + doc->m_parent->setViewport(viewport); + + return KJSUndefined(); +} + +// Document.syncAnnotScan() +static KJSObject docSyncAnnotScan(KJSContext *, void *, const KJSArguments &) +{ + return KJSUndefined(); +} + +// Document.getNthFieldName +static KJSObject docGetNthFieldName(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + const DocumentPrivate *doc = reinterpret_cast(object); + + int numField = arguments.at(0).toInt32(ctx); + + for (const Page *pIt : qAsConst(doc->m_pagesVector)) { + const QLinkedList pageFields = pIt->formFields(); + + if (numField < pageFields.size()) { + const auto ffIt = pageFields.begin() + numField; + + return KJSString((*ffIt)->fullyQualifiedName()); + } + + numField -= pageFields.size(); + } + + return KJSUndefined(); +} + +static KJSObject docGetOCGs(KJSContext *ctx, void *object, const KJSArguments &) +{ + const DocumentPrivate *doc = reinterpret_cast(object); + + QAbstractItemModel *model = doc->m_parent->layersModel(); + + KJSArray array(ctx, model->rowCount()); + + for (int i = 0; i < model->rowCount(); ++i) { + for (int j = 0; j < model->columnCount(); ++j) { + const QModelIndex index = model->index(i, j); + + KJSObject item = JSOCG::wrapOCGObject(ctx, model, i, j); + item.setProperty(ctx, QStringLiteral("name"), model->data(index, Qt::DisplayRole).toString()); + item.setProperty(ctx, QStringLiteral("initState"), model->data(index, Qt::CheckStateRole).toBool()); + + array.setProperty(ctx, QString::number(i), item); + } + } + + return array; +} + +void JSDocument::initType(KJSContext *ctx) +{ + assert(g_docProto); + + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_docProto->defineProperty(ctx, QStringLiteral("numPages"), docGetNumPages); + g_docProto->defineProperty(ctx, QStringLiteral("pageNum"), docGetPageNum, docSetPageNum); + g_docProto->defineProperty(ctx, QStringLiteral("documentFileName"), docGetDocumentFileName); + g_docProto->defineProperty(ctx, QStringLiteral("filesize"), docGetFilesize); + g_docProto->defineProperty(ctx, QStringLiteral("path"), docGetPath); + g_docProto->defineProperty(ctx, QStringLiteral("URL"), docGetURL); + g_docProto->defineProperty(ctx, QStringLiteral("permStatusReady"), docGetPermStatusReady); + g_docProto->defineProperty(ctx, QStringLiteral("dataObjects"), docGetDataObjects); + g_docProto->defineProperty(ctx, QStringLiteral("external"), docGetExternal); + g_docProto->defineProperty(ctx, QStringLiteral("numFields"), docGetNumFields); + + // info properties + g_docProto->defineProperty(ctx, QStringLiteral("info"), docGetInfo); + g_docProto->defineProperty(ctx, QStringLiteral("author"), docGetAuthor); + g_docProto->defineProperty(ctx, QStringLiteral("creator"), docGetCreator); + g_docProto->defineProperty(ctx, QStringLiteral("keywords"), docGetKeywords); + g_docProto->defineProperty(ctx, QStringLiteral("producer"), docGetProducer); + g_docProto->defineProperty(ctx, QStringLiteral("title"), docGetTitle); + g_docProto->defineProperty(ctx, QStringLiteral("subject"), docGetSubject); + + g_docProto->defineFunction(ctx, QStringLiteral("getField"), docGetField); + g_docProto->defineFunction(ctx, QStringLiteral("getPageLabel"), docGetPageLabel); + g_docProto->defineFunction(ctx, QStringLiteral("getPageRotation"), docGetPageRotation); + g_docProto->defineFunction(ctx, QStringLiteral("gotoNamedDest"), docGotoNamedDest); + g_docProto->defineFunction(ctx, QStringLiteral("syncAnnotScan"), docSyncAnnotScan); + g_docProto->defineFunction(ctx, QStringLiteral("getNthFieldName"), docGetNthFieldName); + g_docProto->defineFunction(ctx, QStringLiteral("getOCGs"), docGetOCGs); +} + +KJSGlobalObject JSDocument::wrapDocument(DocumentPrivate *doc) +{ + if (!g_docProto) + g_docProto = new KJSPrototype(); + return g_docProto->constructGlobalObject(doc); +} diff --git a/core/script/kjs_document_p.h b/core/script/kjs_document_p.h new file mode 100644 index 0000000..ac65acb --- /dev/null +++ b/core/script/kjs_document_p.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_DOCUMENT_P_H +#define OKULAR_SCRIPT_KJS_DOCUMENT_P_H + +class KJSContext; +class KJSGlobalObject; + +namespace Okular +{ +class DocumentPrivate; + +class JSDocument +{ +public: + static void initType(KJSContext *ctx); + static KJSGlobalObject wrapDocument(DocumentPrivate *doc); +}; + +} + +#endif diff --git a/core/script/kjs_event.cpp b/core/script/kjs_event.cpp new file mode 100644 index 0000000..c42641a --- /dev/null +++ b/core/script/kjs_event.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_event_p.h" + +#include +#include +#include +#include + +#include "event_p.h" +#include "kjs_field_p.h" + +using namespace Okular; + +static KJSPrototype *g_eventProto; + +// Event.name +static KJSObject eventGetName(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSString(event->name()); +} + +// Event.type +static KJSObject eventGetType(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSString(event->type()); +} + +// Event.targetName (getter) +static KJSObject eventGetTargetName(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSString(event->targetName()); +} + +// Event.targetName (setter) +static void eventSetTargetName(KJSContext *ctx, void *object, KJSObject value) +{ + Event *event = reinterpret_cast(object); + event->setTargetName(value.toString(ctx)); +} + +// Event.shift +static KJSObject eventGetShift(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSBoolean(event->shiftModifier()); +} + +// Event.source +static KJSObject eventGetSource(KJSContext *ctx, void *object) +{ + const Event *event = reinterpret_cast(object); + if (event->eventType() == Event::FieldCalculate) { + FormField *src = event->source(); + if (src) + return JSField::wrapField(ctx, src, event->sourcePage()); + } + return KJSUndefined(); +} + +// Event.target +static KJSObject eventGetTarget(KJSContext *ctx, void *object) +{ + const Event *event = reinterpret_cast(object); + switch (event->eventType()) { + case Event::FieldCalculate: + case Event::FieldFormat: + case Event::FieldKeystroke: + case Event::FieldFocus: + case Event::FieldValidate: { + FormField *target = static_cast(event->target()); + if (target) + return JSField::wrapField(ctx, target, event->targetPage()); + break; + } + default: { + } + } + return KJSUndefined(); +} + +// Event.value (getter) +static KJSObject eventGetValue(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSString(event->value().toString()); +} + +// Event.value (setter) +static void eventSetValue(KJSContext *ctx, void *object, KJSObject value) +{ + Event *event = reinterpret_cast(object); + event->setValue(QVariant(value.toString(ctx))); +} + +// Event.rc (getter) +static KJSObject eventGetReturnCode(KJSContext *, void *object) +{ + const Event *event = reinterpret_cast(object); + return KJSBoolean(event->returnCode()); +} + +// Event.rc (setter) +static void eventSetReturnCode(KJSContext *ctx, void *object, KJSObject value) +{ + Event *event = reinterpret_cast(object); + event->setReturnCode(value.toBoolean(ctx)); +} + +// Event.willCommit (getter) +static KJSObject eventGetWillCommit(KJSContext *, void * /*object*/) +{ + // TODO Someone try to understand the defintion of willCommit better from js_api_reference.pdf + return KJSBoolean(true); +} + +void JSEvent::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + if (!g_eventProto) + g_eventProto = new KJSPrototype(); + + g_eventProto->defineProperty(ctx, QStringLiteral("name"), eventGetName); + g_eventProto->defineProperty(ctx, QStringLiteral("type"), eventGetType); + g_eventProto->defineProperty(ctx, QStringLiteral("targetName"), eventGetTargetName, eventSetTargetName); + g_eventProto->defineProperty(ctx, QStringLiteral("shift"), eventGetShift); + g_eventProto->defineProperty(ctx, QStringLiteral("source"), eventGetSource); + g_eventProto->defineProperty(ctx, QStringLiteral("target"), eventGetTarget); + g_eventProto->defineProperty(ctx, QStringLiteral("willCommit"), eventGetWillCommit); + g_eventProto->defineProperty(ctx, QStringLiteral("value"), eventGetValue, eventSetValue); + g_eventProto->defineProperty(ctx, QStringLiteral("rc"), eventGetReturnCode, eventSetReturnCode); +} + +KJSObject JSEvent::wrapEvent(KJSContext *ctx, Event *event) +{ + return g_eventProto->constructObject(ctx, event); +} diff --git a/core/script/kjs_event_p.h b/core/script/kjs_event_p.h new file mode 100644 index 0000000..fb014dc --- /dev/null +++ b/core/script/kjs_event_p.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2018 by Intevation GmbH * + * * + * 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_SCRIPT_KJS_EVENT_P_H +#define OKULAR_SCRIPT_KJS_EVENT_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class Event; + +class JSEvent +{ +public: + static void initType(KJSContext *ctx); + static KJSObject wrapEvent(KJSContext *ctx, Event *event); + static void clearCachedFields(); +}; + +} + +#endif diff --git a/core/script/kjs_field.cpp b/core/script/kjs_field.cpp new file mode 100644 index 0000000..f6135db --- /dev/null +++ b/core/script/kjs_field.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_field_p.h" + +#include +#include +#include + +#include + +#include +#include + +#include "../debug_p.h" +#include "../document_p.h" +#include "../form.h" +#include "../page.h" +#include "../page_p.h" +#include "kjs_display_p.h" + +using namespace Okular; + +#define OKULAR_NAME QStringLiteral("okular_name") + +static KJSPrototype *g_fieldProto; + +typedef QHash FormCache; +Q_GLOBAL_STATIC(FormCache, g_fieldCache) +typedef QHash ButtonCache; +Q_GLOBAL_STATIC(ButtonCache, g_buttonCache) + +// Helper for modified fields +static void updateField(FormField *field) +{ + Page *page = g_fieldCache->value(field); + if (page) { + Document *doc = PagePrivate::get(page)->m_doc->m_parent; + const int pageNumber = page->number(); + QTimer::singleShot(0, doc, [doc, pageNumber] { doc->refreshPixmaps(pageNumber); }); + emit doc->refreshFormWidget(field); + } else { + qWarning() << "Could not get page of field" << field; + } +} + +// Field.doc +static KJSObject fieldGetDoc(KJSContext *context, void *) +{ + return context->interpreter().globalObject(); +} + +// Field.name +static KJSObject fieldGetName(KJSContext *, void *object) +{ + const FormField *field = reinterpret_cast(object); + return KJSString(field->fullyQualifiedName()); +} + +// Field.readonly (getter) +static KJSObject fieldGetReadOnly(KJSContext *, void *object) +{ + const FormField *field = reinterpret_cast(object); + return KJSBoolean(field->isReadOnly()); +} + +// Field.readonly (setter) +static void fieldSetReadOnly(KJSContext *context, void *object, KJSObject value) +{ + FormField *field = reinterpret_cast(object); + bool b = value.toBoolean(context); + field->setReadOnly(b); + + updateField(field); +} + +static QString fieldGetTypeHelper(const FormField *field) +{ + switch (field->type()) { + case FormField::FormButton: { + const FormFieldButton *button = static_cast(field); + switch (button->buttonType()) { + case FormFieldButton::Push: + return QStringLiteral("button"); + case FormFieldButton::CheckBox: + return QStringLiteral("checkbox"); + case FormFieldButton::Radio: + return QStringLiteral("radiobutton"); + } + break; + } + case FormField::FormText: + return QStringLiteral("text"); + case FormField::FormChoice: { + const FormFieldChoice *choice = static_cast(field); + switch (choice->choiceType()) { + case FormFieldChoice::ComboBox: + return QStringLiteral("combobox"); + case FormFieldChoice::ListBox: + return QStringLiteral("listbox"); + } + break; + } + case FormField::FormSignature: + return QStringLiteral("signature"); + } + return QString(); +} + +// Field.type +static KJSObject fieldGetType(KJSContext *, void *object) +{ + const FormField *field = reinterpret_cast(object); + + return KJSString(fieldGetTypeHelper(field)); +} + +// Field.value (getter) +static KJSObject fieldGetValue(KJSContext * /*context*/, void *object) +{ + FormField *field = reinterpret_cast(object); + + switch (field->type()) { + case FormField::FormButton: { + const FormFieldButton *button = static_cast(field); + if (button->state()) { + return KJSString(QStringLiteral("Yes")); + } + return KJSString(QStringLiteral("Off")); + } + case FormField::FormText: { + const FormFieldText *text = static_cast(field); + return KJSString(text->text()); + } + case FormField::FormChoice: { + const FormFieldChoice *choice = static_cast(field); + const QList currentChoices = choice->currentChoices(); + if (currentChoices.count() == 1) { + return KJSString(choice->exportValueForChoice(choice->choices().at(currentChoices[0]))); + } + break; + } + case FormField::FormSignature: { + break; + } + } + + return KJSUndefined(); +} + +// Field.value (setter) +static void fieldSetValue(KJSContext *context, void *object, KJSObject value) +{ + FormField *field = reinterpret_cast(object); + + switch (field->type()) { + case FormField::FormButton: { + FormFieldButton *button = static_cast(field); + const QString text = value.toString(context); + if (text == QStringLiteral("Yes")) { + button->setState(true); + updateField(field); + } else if (text == QStringLiteral("Off")) { + button->setState(false); + updateField(field); + } + break; + } + case FormField::FormText: { + FormFieldText *textField = static_cast(field); + const QString text = value.toString(context); + if (text != textField->text()) { + textField->setText(text); + updateField(field); + } + break; + } + case FormField::FormChoice: { + FormFieldChoice *choice = static_cast(field); + Q_UNUSED(choice); // ### + break; + } + case FormField::FormSignature: { + break; + } + } +} + +// Field.hidden (getter) +static KJSObject fieldGetHidden(KJSContext *, void *object) +{ + const FormField *field = reinterpret_cast(object); + return KJSBoolean(!field->isVisible()); +} + +// Field.hidden (setter) +static void fieldSetHidden(KJSContext *context, void *object, KJSObject value) +{ + FormField *field = reinterpret_cast(object); + bool b = value.toBoolean(context); + field->setVisible(!b); + + updateField(field); +} + +// Field.display (getter) +static KJSObject fieldGetDisplay(KJSContext *, void *object) +{ + const FormField *field = reinterpret_cast(object); + bool visible = field->isVisible(); + if (visible) { + return KJSNumber(field->isPrintable() ? FormDisplay::FormVisible : FormDisplay::FormNoPrint); + } + return KJSNumber(field->isPrintable() ? FormDisplay::FormNoView : FormDisplay::FormHidden); +} + +// Field.display (setter) +static void fieldSetDisplay(KJSContext *context, void *object, KJSObject value) +{ + FormField *field = reinterpret_cast(object); + const unsigned int b = value.toInt32(context); + switch (b) { + case FormDisplay::FormVisible: + field->setVisible(true); + field->setPrintable(true); + break; + case FormDisplay::FormHidden: + field->setVisible(false); + field->setPrintable(false); + break; + case FormDisplay::FormNoPrint: + field->setVisible(true); + field->setPrintable(false); + break; + case FormDisplay::FormNoView: + field->setVisible(false); + field->setPrintable(true); + break; + } + updateField(field); +} + +// Instead of getting the Icon, we pick the field. +static KJSObject fieldButtonGetIcon(KJSContext *ctx, void *object, const KJSArguments &) +{ + FormField *field = reinterpret_cast(object); + + KJSObject fieldObject; + fieldObject.setProperty(ctx, OKULAR_NAME, field->fullyQualifiedName()); + g_buttonCache->insert(field->fullyQualifiedName(), field); + + return fieldObject; +} + +/* + * Now we send to the button what Icon should be drawn on it + */ +static KJSObject fieldButtonSetIcon(KJSContext *ctx, void *object, const KJSArguments &arguments) +{ + FormField *field = reinterpret_cast(object); + + const QString fieldName = arguments.at(0).property(ctx, OKULAR_NAME).toString(ctx); + + if (field->type() == Okular::FormField::FormButton) { + FormFieldButton *button = static_cast(field); + button->setIcon(g_buttonCache->value(fieldName)); + } + + updateField(field); + + return KJSUndefined(); +} + +void JSField::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + if (!g_fieldProto) + g_fieldProto = new KJSPrototype(); + + g_fieldProto->defineProperty(ctx, QStringLiteral("doc"), fieldGetDoc); + g_fieldProto->defineProperty(ctx, QStringLiteral("name"), fieldGetName); + g_fieldProto->defineProperty(ctx, QStringLiteral("readonly"), fieldGetReadOnly, fieldSetReadOnly); + g_fieldProto->defineProperty(ctx, QStringLiteral("type"), fieldGetType); + g_fieldProto->defineProperty(ctx, QStringLiteral("value"), fieldGetValue, fieldSetValue); + g_fieldProto->defineProperty(ctx, QStringLiteral("hidden"), fieldGetHidden, fieldSetHidden); + g_fieldProto->defineProperty(ctx, QStringLiteral("display"), fieldGetDisplay, fieldSetDisplay); + + g_fieldProto->defineFunction(ctx, QStringLiteral("buttonGetIcon"), fieldButtonGetIcon); + g_fieldProto->defineFunction(ctx, QStringLiteral("buttonSetIcon"), fieldButtonSetIcon); +} + +KJSObject JSField::wrapField(KJSContext *ctx, FormField *field, Page *page) +{ + // ### cache unique wrapper + KJSObject f = g_fieldProto->constructObject(ctx, field); + f.setProperty(ctx, QStringLiteral("page"), page->number()); + g_fieldCache->insert(field, page); + return f; +} + +void JSField::clearCachedFields() +{ + if (g_fieldCache.exists()) + g_fieldCache->clear(); + + if (g_buttonCache.exists()) + g_buttonCache->clear(); +} diff --git a/core/script/kjs_field_p.h b/core/script/kjs_field_p.h new file mode 100644 index 0000000..558bcf8 --- /dev/null +++ b/core/script/kjs_field_p.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_FIELD_P_H +#define OKULAR_SCRIPT_KJS_FIELD_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class FormField; +class Page; + +class JSField +{ +public: + static void initType(KJSContext *ctx); + static KJSObject wrapField(KJSContext *ctx, FormField *field, Page *page); + static void clearCachedFields(); +}; + +} + +#endif diff --git a/core/script/kjs_fullscreen.cpp b/core/script/kjs_fullscreen.cpp new file mode 100644 index 0000000..588e90b --- /dev/null +++ b/core/script/kjs_fullscreen.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_fullscreen_p.h" + +#include + +#include +#include + +#include "settings_core.h" + +using namespace Okular; + +static KJSPrototype *g_fsProto; + +static KJSObject fsGetLoop(KJSContext *, void *) +{ + return KJSBoolean(SettingsCore::slidesLoop()); +} + +static void fsSetLoop(KJSContext *ctx, void *, KJSObject value) +{ + bool loop = value.toBoolean(ctx); + SettingsCore::setSlidesLoop(loop); +} + +static KJSObject fsGetUseTimer(KJSContext *, void *) +{ + return KJSBoolean(SettingsCore::slidesAdvance()); +} + +static void fsSetUseTimer(KJSContext *ctx, void *, KJSObject value) +{ + bool use = value.toBoolean(ctx); + SettingsCore::setSlidesAdvance(use); +} + +static KJSObject fsGetTimeDelay(KJSContext *, void *) +{ + return KJSNumber(SettingsCore::slidesAdvanceTime()); +} + +static void fsSetTimeDelay(KJSContext *ctx, void *, KJSObject value) +{ + int time = static_cast(value.toNumber(ctx)); + SettingsCore::setSlidesAdvanceTime(time); +} + +void JSFullscreen::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + if (!g_fsProto) + g_fsProto = new KJSPrototype(); + + g_fsProto->defineProperty(ctx, QStringLiteral("loop"), fsGetLoop, fsSetLoop); + g_fsProto->defineProperty(ctx, QStringLiteral("useTimer"), fsGetUseTimer, fsSetUseTimer); + g_fsProto->defineProperty(ctx, QStringLiteral("timeDelay"), fsGetTimeDelay, fsSetTimeDelay); +} + +KJSObject JSFullscreen::object(KJSContext *ctx) +{ + assert(g_fsProto); + return g_fsProto->constructObject(ctx); +} diff --git a/core/script/kjs_fullscreen_p.h b/core/script/kjs_fullscreen_p.h new file mode 100644 index 0000000..5e5795f --- /dev/null +++ b/core/script/kjs_fullscreen_p.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_FULLSCREEN_P_H +#define OKULAR_SCRIPT_KJS_FULLSCREEN_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class JSFullscreen +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); +}; + +} + +#endif diff --git a/core/script/kjs_ocg.cpp b/core/script/kjs_ocg.cpp new file mode 100644 index 0000000..50fc352 --- /dev/null +++ b/core/script/kjs_ocg.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_ocg_p.h" + +#include +#include +#include + +#include +#include +#include +#include + +using namespace Okular; + +static KJSPrototype *g_OCGProto; + +typedef QHash *, QAbstractItemModel *> OCGCache; +Q_GLOBAL_STATIC(OCGCache, g_OCGCache) + +// OCG.state (getter) +static KJSObject OCGGetState(KJSContext *, void *object) +{ + QPair *pair = reinterpret_cast *>(object); + QAbstractItemModel *model = g_OCGCache->value(pair); + + const QModelIndex index = model->index(pair->first, pair->second); + + const bool state = model->data(index, Qt::CheckStateRole).toBool(); + + return KJSBoolean(state); +} + +// OCG.state (setter) +static void OCGSetState(KJSContext *ctx, void *object, KJSObject value) +{ + QPair *pair = reinterpret_cast *>(object); + QAbstractItemModel *model = g_OCGCache->value(pair); + + const QModelIndex index = model->index(pair->first, pair->second); + + const bool state = value.toBoolean(ctx); + + model->setData(index, QVariant(state ? Qt::Checked : Qt::Unchecked), Qt::CheckStateRole); +} + +void JSOCG::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_OCGProto = new KJSPrototype(); + + g_OCGProto->defineProperty(ctx, QStringLiteral("state"), OCGGetState, OCGSetState); +} + +KJSObject JSOCG::object(KJSContext *ctx) +{ + return g_OCGProto->constructObject(ctx, nullptr); +} + +KJSObject JSOCG::wrapOCGObject(KJSContext *ctx, QAbstractItemModel *model, const int i, const int j) +{ + QPair *pair = new QPair(i, j); + g_OCGCache->insert(pair, model); + return g_OCGProto->constructObject(ctx, pair); +} + +void JSOCG::clearCachedFields() +{ + if (g_OCGCache.exists()) { + g_OCGCache->clear(); + } +} diff --git a/core/script/kjs_ocg_p.h b/core/script/kjs_ocg_p.h new file mode 100644 index 0000000..9987cc8 --- /dev/null +++ b/core/script/kjs_ocg_p.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2019 by João Netto * + * * + * 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_SCRIPT_KJS_OCG_P_H +#define OKULAR_SCRIPT_KJS_OCG_P_H + +class KJSContext; +class KJSObject; +class QAbstractItemModel; + +namespace Okular +{ +class JSOCG +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); + static KJSObject wrapOCGObject(KJSContext *ctx, QAbstractItemModel *model, const int i, const int j); + static void clearCachedFields(); +}; + +} + +#endif diff --git a/core/script/kjs_spell.cpp b/core/script/kjs_spell.cpp new file mode 100644 index 0000000..cac0d19 --- /dev/null +++ b/core/script/kjs_spell.cpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_spell_p.h" + +#include +#include + +#include + +using namespace Okular; + +static KJSPrototype *g_spellProto; + +// Spell.available +static KJSObject spellGetAvailable(KJSContext *, void *) +{ + return KJSBoolean(false); +} + +void JSSpell::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_spellProto = new KJSPrototype(); + g_spellProto->defineProperty(ctx, QStringLiteral("available"), spellGetAvailable); +} + +KJSObject JSSpell::object(KJSContext *ctx) +{ + return g_spellProto->constructObject(ctx, nullptr); +} diff --git a/core/script/kjs_spell_p.h b/core/script/kjs_spell_p.h new file mode 100644 index 0000000..002710b --- /dev/null +++ b/core/script/kjs_spell_p.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_SPELL_P_H +#define OKULAR_SCRIPT_KJS_SPELL_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class JSSpell +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); +}; + +} + +#endif diff --git a/core/script/kjs_util.cpp b/core/script/kjs_util.cpp new file mode 100644 index 0000000..25f4153 --- /dev/null +++ b/core/script/kjs_util.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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. * + ***************************************************************************/ + +#include "kjs_util_p.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +using namespace Okular; + +static KJSPrototype *g_utilProto; + +static KJSObject crackURL(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(QStringLiteral("Missing URL argument")); + } + QString cURL = arguments.at(0).toString(context); + QUrl url(QUrl::fromLocalFile(cURL)); + if (!url.isValid()) { + return context->throwException(QStringLiteral("Invalid URL")); + } + if (url.scheme() != QLatin1String("file") || url.scheme() != QLatin1String("http") || url.scheme() != QLatin1String("https")) { + return context->throwException(QStringLiteral("Protocol not valid: '") + url.scheme() + QLatin1Char('\'')); + } + + KJSObject obj; + obj.setProperty(context, QStringLiteral("cScheme"), url.scheme()); + if (!url.userName().isEmpty()) + obj.setProperty(context, QStringLiteral("cUser"), url.userName()); + if (!url.password().isEmpty()) + obj.setProperty(context, QStringLiteral("cPassword"), url.password()); + obj.setProperty(context, QStringLiteral("cHost"), url.host()); + obj.setProperty(context, QStringLiteral("nPort"), url.port(80)); + // TODO cPath (Optional) The path portion of the URL. + // TODO cParameters (Optional) The parameter string portion of the URL. + if (url.hasFragment()) + obj.setProperty(context, QStringLiteral("cFragments"), url.fragment(QUrl::FullyDecoded)); + + return obj; +} + +static KJSObject printd(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 2) { + return context->throwException(QStringLiteral("Invalid arguments")); + } + + KJSObject oFormat = arguments.at(0); + QString format; + QLocale defaultLocale; + + if (oFormat.isNumber()) { + int formatType = oFormat.toInt32(context); + switch (formatType) { + case 0: + format = QStringLiteral("D:yyyyMMddHHmmss"); + break; + case 1: + format = QStringLiteral("yyyy.MM.dd HH:mm:ss"); + break; + case 2: + format = defaultLocale.dateTimeFormat(QLocale::ShortFormat); + if (!format.contains(QStringLiteral("ss"))) + format.insert(format.indexOf(QStringLiteral("mm")) + 2, QStringLiteral(":ss")); + break; + } + } else { + format = arguments.at(0).toString(context).replace(QLatin1String("tt"), QLatin1String("ap")); + format.replace('t', 'a'); + for (QChar &formatChar : format) { + if (formatChar == 'M') + formatChar = 'm'; + else if (formatChar == 'm') + formatChar = 'M'; + } + } + + QLocale locale(QStringLiteral("en_US")); + const QStringList str = arguments.at(1).toString(context).split(QRegularExpression(QStringLiteral("\\W"))); + QString myStr = QStringLiteral("%1/%2/%3 %4:%5:%6").arg(str[1], str[2], str[3], str[4], str[5], str[6]); + QDateTime date = locale.toDateTime(myStr, QStringLiteral("MMM/d/yyyy H:m:s")); + + return KJSString(defaultLocale.toString(date, format)); +} + +/** Converts a Number to a String using l10n + * + * String numberToString( Number number, String format = 'g', int precision = 6, + * String LocaleName = system ) + */ +static KJSObject numberToString(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(QStringLiteral("Invalid arguments")); + } + + const double number = arguments.at(0).toNumber(context); + if (std::isnan(number)) { + return KJSString("NaN"); + } + + QChar format = QLatin1Char('g'); + if (arguments.count() >= 2) { + const QString fmt = arguments.at(1).toString(context); + if (!fmt.isEmpty()) { + format = fmt[0]; + } + } + + int precision = 6; + if (arguments.count() >= 3) { + precision = arguments.at(2).toInt32(context); + } + + QLocale locale; + if (arguments.count() == 4) { + locale = QLocale(arguments.at(3).toString(context)); + } + + return KJSString(locale.toString(number, format.toLatin1(), precision)); +} + +/** Converts a String to a Number trying with the current locale first and + * if that fails trying with the reverse locale for the decimal separator + * + * Number stringToNumber( String number ) */ +static KJSObject stringToNumber(KJSContext *context, void *, const KJSArguments &arguments) +{ + if (arguments.count() < 1) { + return context->throwException(QStringLiteral("Invalid arguments")); + } + + const QString number = arguments.at(0).toString(context); + if (number.isEmpty()) { + return KJSNumber(0); + } + + const QLocale locale; + bool ok; + double converted = locale.toDouble(number, &ok); + + if (!ok) { + const QLocale locale2(locale.decimalPoint() == QLatin1Char('.') ? QStringLiteral("de") : QStringLiteral("en")); + converted = locale2.toDouble(number, &ok); + if (!ok) { + return KJSNumber(std::nan("")); + } + } + + return KJSNumber(converted); +} + +void JSUtil::initType(KJSContext *ctx) +{ + static bool initialized = false; + if (initialized) + return; + initialized = true; + + g_utilProto = new KJSPrototype(); + g_utilProto->defineFunction(ctx, QStringLiteral("crackURL"), crackURL); + g_utilProto->defineFunction(ctx, QStringLiteral("printd"), printd); + g_utilProto->defineFunction(ctx, QStringLiteral("stringToNumber"), stringToNumber); + g_utilProto->defineFunction(ctx, QStringLiteral("numberToString"), numberToString); +} + +KJSObject JSUtil::object(KJSContext *ctx) +{ + return g_utilProto->constructObject(ctx, nullptr); +} diff --git a/core/script/kjs_util_p.h b/core/script/kjs_util_p.h new file mode 100644 index 0000000..a4dab88 --- /dev/null +++ b/core/script/kjs_util_p.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2008 by Harri Porten * + * * + * 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_SCRIPT_KJS_UTIL_P_H +#define OKULAR_SCRIPT_KJS_UTIL_P_H + +class KJSContext; +class KJSObject; + +namespace Okular +{ +class JSUtil +{ +public: + static void initType(KJSContext *ctx); + static KJSObject object(KJSContext *ctx); +}; + +} + +#endif diff --git a/core/scripter.cpp b/core/scripter.cpp new file mode 100644 index 0000000..16c6794 --- /dev/null +++ b/core/scripter.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "scripter.h" + +#include +#include + +#include "debug_p.h" +#include "script/executor_kjs_p.h" + +using namespace Okular; + +class Okular::ScripterPrivate +{ +public: + ScripterPrivate(DocumentPrivate *doc) + : m_doc(doc) +#ifdef WITH_KJS + , m_kjs(nullptr) +#endif + , m_event(nullptr) + { + } + + DocumentPrivate *m_doc; +#ifdef WITH_KJS + QScopedPointer m_kjs; +#endif + Event *m_event; +}; + +Scripter::Scripter(DocumentPrivate *doc) + : d(new ScripterPrivate(doc)) +{ +} + +Scripter::~Scripter() +{ + delete d; +} + +void Scripter::execute(ScriptType type, const QString &script) +{ + qCDebug(OkularCoreDebug) << "executing the script:"; +#ifdef WITH_KJS +#if 0 + if ( script.length() < 1000 ) + qDebug() << script; + else + qDebug() << script.left( 1000 ) << "[...]"; +#endif + static QString builtInScript; + if (builtInScript.isNull()) { + QFile builtInResource(QStringLiteral(":/script/builtin.js")); + if (!builtInResource.open(QIODevice::ReadOnly)) { + qCDebug(OkularCoreDebug) << "failed to load builtin script"; + } else { + builtInScript = QString::fromUtf8(builtInResource.readAll()); + builtInResource.close(); + } + } + + switch (type) { + case JavaScript: + if (!d->m_kjs) { + d->m_kjs.reset(new ExecutorKJS(d->m_doc)); + } + d->m_kjs->execute(builtInScript + script, d->m_event); + } +#endif +} + +void Scripter::setEvent(Event *event) +{ + d->m_event = event; +} + +Event *Scripter::event() const +{ + return d->m_event; +} diff --git a/core/scripter.h b/core/scripter.h new file mode 100644 index 0000000..ac52ecf --- /dev/null +++ b/core/scripter.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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_SCRIPTER_H +#define OKULAR_SCRIPTER_H + +#include "global.h" + +class QString; + +namespace Okular +{ +class Document; +class DocumentPrivate; +class Event; +class ScripterPrivate; + +class Scripter +{ + friend class Document; + friend class DocumentPrivate; + +public: + ~Scripter(); + + Scripter(const Scripter &) = delete; + Scripter &operator=(const Scripter &) = delete; + + void execute(ScriptType type, const QString &script); + + void setEvent(Event *event); + Event *event() const; + +private: + friend class ScripterPrivate; + ScripterPrivate *d; + + explicit Scripter(DocumentPrivate *doc); +}; + +} + +#endif diff --git a/core/signatureutils.cpp b/core/signatureutils.cpp new file mode 100644 index 0000000..48d7799 --- /dev/null +++ b/core/signatureutils.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "signatureutils.h" + +using namespace Okular; + +CertificateInfo::CertificateInfo() +{ +} + +CertificateInfo::~CertificateInfo() +{ +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(CertificateInfo::KeyUsageExtensions) + +bool CertificateInfo::isNull() const +{ + return true; +} + +int CertificateInfo::version() const +{ + return -1; +} + +QByteArray CertificateInfo::serialNumber() const +{ + return QByteArray(); +} + +QString CertificateInfo::issuerInfo(EntityInfoKey) const +{ + return QString(); +} + +QString CertificateInfo::subjectInfo(EntityInfoKey) const +{ + return QString(); +} + +QDateTime CertificateInfo::validityStart() const +{ + return QDateTime(); +} + +QDateTime CertificateInfo::validityEnd() const +{ + return QDateTime(); +} + +CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const +{ + return KuNone; +} + +QByteArray CertificateInfo::publicKey() const +{ + return QByteArray(); +} + +CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const +{ + return OtherKey; +} + +int CertificateInfo::publicKeyStrength() const +{ + return -1; +} + +bool CertificateInfo::isSelfSigned() const +{ + return false; +} + +QByteArray CertificateInfo::certificateData() const +{ + return QByteArray(); +} + +SignatureInfo::SignatureInfo() +{ +} + +SignatureInfo::~SignatureInfo() +{ +} + +SignatureInfo::SignatureStatus SignatureInfo::signatureStatus() const +{ + return SignatureStatusUnknown; +} + +SignatureInfo::CertificateStatus SignatureInfo::certificateStatus() const +{ + return CertificateStatusUnknown; +} + +SignatureInfo::HashAlgorithm SignatureInfo::hashAlgorithm() const +{ + return HashAlgorithmUnknown; +} + +QString SignatureInfo::signerName() const +{ + return QString(); +} + +QString SignatureInfo::signerSubjectDN() const +{ + return QString(); +} + +QString SignatureInfo::location() const +{ + return QString(); +} + +QString SignatureInfo::reason() const +{ + return QString(); +} + +QDateTime SignatureInfo::signingTime() const +{ + return QDateTime(); +} + +QByteArray SignatureInfo::signature() const +{ + return QByteArray(); +} + +QList SignatureInfo::signedRangeBounds() const +{ + return QList(); +} + +bool SignatureInfo::signsTotalDocument() const +{ + return false; +} + +const CertificateInfo &SignatureInfo::certificateInfo() const +{ + static CertificateInfo dummy; + return dummy; +} diff --git a/core/signatureutils.h b/core/signatureutils.h new file mode 100644 index 0000000..a087f62 --- /dev/null +++ b/core/signatureutils.h @@ -0,0 +1,244 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_SIGNATUREUTILS_H +#define OKULAR_SIGNATUREUTILS_H + +#include "okularcore_export.h" + +#include +#include +#include +#include +#include + +namespace Okular +{ +class SignatureInfoPrivate; + +/** + * @short A helper class to store information about x509 certificate + */ +class OKULARCORE_EXPORT CertificateInfo +{ +public: + /** + * The algorithm of public key. + */ + enum PublicKeyType { RsaKey, DsaKey, EcKey, OtherKey }; + + /** + * Certificate key usage extensions. + */ + enum KeyUsageExtension { KuDigitalSignature = 0x80, KuNonRepudiation = 0x40, KuKeyEncipherment = 0x20, KuDataEncipherment = 0x10, KuKeyAgreement = 0x08, KuKeyCertSign = 0x04, KuClrSign = 0x02, KuEncipherOnly = 0x01, KuNone = 0x00 }; + Q_DECLARE_FLAGS(KeyUsageExtensions, KeyUsageExtension) + + /** + * Predefined keys for elements in an entity's distinguished name. + */ + enum EntityInfoKey { + CommonName, + DistinguishedName, + EmailAddress, + Organization, + }; + + /** + * Destructor + */ + virtual ~CertificateInfo(); + + /** + * Returns true if certificate has no contents; otherwise returns false. + */ + virtual bool isNull() const; + + /** + * The certificate version string. + */ + virtual int version() const; + + /** + * The certificate serial number. + */ + virtual QByteArray serialNumber() const; + + /** + * Information about the issuer. + */ + virtual QString issuerInfo(EntityInfoKey key) const; + + /** + * Information about the subject + */ + virtual QString subjectInfo(EntityInfoKey key) const; + + /** + * The date-time when certificate becomes valid. + */ + virtual QDateTime validityStart() const; + + /** + * The date-time when certificate expires. + */ + virtual QDateTime validityEnd() const; + + /** + * The uses allowed for the certificate. + */ + virtual KeyUsageExtensions keyUsageExtensions() const; + + /** + * The public key value. + */ + virtual QByteArray publicKey() const; + + /** + * The public key type. + */ + virtual PublicKeyType publicKeyType() const; + + /** + * The strength of public key in bits. + */ + virtual int publicKeyStrength() const; + + /** + * Returns true if certificate is self-signed otherwise returns false. + */ + virtual bool isSelfSigned() const; + + /** + * The DER encoded certificate. + */ + virtual QByteArray certificateData() const; + +protected: + friend class SignatureInfo; + CertificateInfo(); + +private: + Q_DISABLE_COPY(CertificateInfo) +}; + +/** + * @short A helper class to store information about digital signature + */ +class OKULARCORE_EXPORT SignatureInfo +{ +public: + /** + * The verification result of the signature. + */ + enum SignatureStatus { + SignatureStatusUnknown, ///< The signature status is unknown for some reason. + SignatureValid, ///< The signature is cryptographically valid. + SignatureInvalid, ///< The signature is cryptographically invalid. + SignatureDigestMismatch, ///< The document content was changed after the signature was applied. + SignatureDecodingError, ///< The signature CMS/PKCS7 structure is malformed. + SignatureGenericError, ///< The signature could not be verified. + SignatureNotFound, ///< The requested signature is not present in the document. + SignatureNotVerified ///< The signature is not yet verified. + }; + + /** + * The verification result of the certificate. + */ + enum CertificateStatus { + CertificateStatusUnknown, ///< The certificate status is unknown for some reason. + CertificateTrusted, ///< The certificate is considered trusted. + CertificateUntrustedIssuer, ///< The issuer of this certificate has been marked as untrusted by the user. + CertificateUnknownIssuer, ///< The certificate trust chain has not finished in a trusted root certificate. + CertificateRevoked, ///< The certificate was revoked by the issuing certificate authority. + CertificateExpired, ///< The signing time is outside the validity bounds of this certificate. + CertificateGenericError, ///< The certificate could not be verified. + CertificateNotVerified ///< The certificate is not yet verified. + }; + + /** + * The hash algorithm of the signature + */ + enum HashAlgorithm { HashAlgorithmUnknown, HashAlgorithmMd2, HashAlgorithmMd5, HashAlgorithmSha1, HashAlgorithmSha256, HashAlgorithmSha384, HashAlgorithmSha512, HashAlgorithmSha224 }; + + /** + * Destructor. + */ + virtual ~SignatureInfo(); + + /** + * The signature status of the signature. + */ + virtual SignatureStatus signatureStatus() const; + + /** + * The certificate status of the signature. + */ + virtual CertificateStatus certificateStatus() const; + + /** + * The signer subject common name associated with the signature. + */ + virtual QString signerName() const; + + /** + * The signer subject distinguished name associated with the signature. + */ + virtual QString signerSubjectDN() const; + + /** + * Get signing location. + */ + virtual QString location() const; + + /** + * Get signing reason. + */ + virtual QString reason() const; + + /** + * The hash algorithm used for the signature. + */ + virtual HashAlgorithm hashAlgorithm() const; + + /** + * The signing time associated with the signature. + */ + virtual QDateTime signingTime() const; + + /** + * Get the signature binary data. + */ + virtual QByteArray signature() const; + + /** + * Get the bounds of the ranges of the document which are signed. + */ + virtual QList signedRangeBounds() const; + + /** + * Checks whether the signature authenticates the total document + * except for the signature itself. + */ + virtual bool signsTotalDocument() const; + + /** + * Get certificate details. + */ + virtual const CertificateInfo &certificateInfo() const; + +protected: + SignatureInfo(); + +private: + Q_DISABLE_COPY(SignatureInfo) +}; + +} + +#endif diff --git a/core/sound.cpp b/core/sound.cpp new file mode 100644 index 0000000..c9370a0 --- /dev/null +++ b/core/sound.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "sound.h" + +#include + +using namespace Okular; + +class Sound::Private +{ +public: + Private(const QByteArray &data) + : m_data(QVariant(data)) + , m_type(Sound::Embedded) + { + init(); + } + + Private(const QString &url) + : m_data(QVariant(url)) + , m_type(Sound::External) + { + init(); + } + + void init() + { + m_samplingRate = 44100.0; + m_channels = 1; + m_bitsPerSample = 8; + m_soundEncoding = Sound::Raw; + } + + QVariant m_data; + Sound::SoundType m_type; + double m_samplingRate; + int m_channels; + int m_bitsPerSample; + SoundEncoding m_soundEncoding; +}; + +Sound::Sound(const QByteArray &data) + : d(new Private(data)) +{ +} + +Sound::Sound(const QString &url) + : d(new Private(url)) +{ +} + +Sound::~Sound() +{ + delete d; +} + +Sound::SoundType Sound::soundType() const +{ + return d->m_type; +} + +QString Sound::url() const +{ + return d->m_type == Sound::External ? d->m_data.toString() : QString(); +} + +QByteArray Sound::data() const +{ + return d->m_type == Sound::Embedded ? d->m_data.toByteArray() : QByteArray(); +} + +double Sound::samplingRate() const +{ + return d->m_samplingRate; +} + +void Sound::setSamplingRate(double samplingRate) +{ + d->m_samplingRate = samplingRate; +} + +int Sound::channels() const +{ + return d->m_channels; +} + +void Sound::setChannels(int channels) +{ + d->m_channels = channels; +} + +int Sound::bitsPerSample() const +{ + return d->m_bitsPerSample; +} + +void Sound::setBitsPerSample(int bitsPerSample) +{ + d->m_bitsPerSample = bitsPerSample; +} + +Sound::SoundEncoding Sound::soundEncoding() const +{ + return d->m_soundEncoding; +} + +void Sound::setSoundEncoding(Sound::SoundEncoding soundEncoding) +{ + d->m_soundEncoding = soundEncoding; +} diff --git a/core/sound.h b/core/sound.h new file mode 100644 index 0000000..fd9a06f --- /dev/null +++ b/core/sound.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2006 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_SOUND_H_ +#define _OKULAR_SOUND_H_ + +#include "okularcore_export.h" + +#include +#include + +namespace Okular +{ +/** + * @short Contains information about a sound object. + * + * This class encapsulates the information about a sound object + * which is used for links on enter/leave page event. + */ +class OKULARCORE_EXPORT Sound +{ +public: + /** + * Describes where the sound is stored. + */ + enum SoundType { + External, ///< Is stored at external resource (e.g. url) + Embedded ///< Is stored embedded in the document + }; + + /** + * Describes the encoding of the sound data. + */ + enum SoundEncoding { + Raw, ///< Is not encoded + Signed, ///< Is encoded with twos-complement values + muLaw, ///< Is µ-law encoded + ALaw ///< Is A-law encoded + }; + + /** + * Creates a new sound object with the given embedded + * sound @p data. + */ + explicit Sound(const QByteArray &data); + + /** + * Creates a new sound object with the given external @p url. + */ + explicit Sound(const QString &url); + + /** + * Destroys the sound object. + */ + ~Sound(); + + /** + * Returns the type of the sound object. + */ + SoundType soundType() const; + + /** + * Returns the external storage url of the sound data. + */ + QString url() const; + + /** + * Returns the embedded sound data. + */ + QByteArray data() const; + + /** + * Sets the sampling @p rate. + */ + void setSamplingRate(double rate); + + /** + * Returns the sampling rate. + */ + double samplingRate() const; + + /** + * Sets the number of @p channels. + */ + void setChannels(int channels); + + /** + * Returns the number of channels. + */ + int channels() const; + + /** + * Sets the bits per sample @p bitsPerSample. + */ + void setBitsPerSample(int bitsPerSample); + + /** + * Returns the bits per sample rate. + */ + int bitsPerSample() const; + + /** + * Sets the type of sound @p encoding. + */ + void setSoundEncoding(SoundEncoding encoding); + + /** + * Returns the sound encoding. + */ + SoundEncoding soundEncoding() const; + +private: + class Private; + Private *const d; + + Q_DISABLE_COPY(Sound) +}; + +} + +#endif diff --git a/core/sourcereference.cpp b/core/sourcereference.cpp new file mode 100644 index 0000000..9db306d --- /dev/null +++ b/core/sourcereference.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (C) 2007,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. * + ***************************************************************************/ + +#include "sourcereference.h" +#include "sourcereference_p.h" + +#include +#include +#include + +using namespace Okular; + +class SourceReference::Private +{ +public: + Private() + : row(0) + , column(0) + { + } + + QString filename; + int row; + int column; +}; + +SourceReference::SourceReference(const QString &fileName, int row, int column) + : d(new Private) +{ + d->filename = fileName; + d->row = row; + d->column = column; +} + +SourceReference::~SourceReference() +{ + delete d; +} + +QString SourceReference::fileName() const +{ + return d->filename; +} + +int SourceReference::row() const +{ + return d->row; +} + +int SourceReference::column() const +{ + return d->column; +} + +bool Okular::extractLilyPondSourceReference(const QUrl &url, QString *file, int *row, int *col) +{ + // Example URL is: textedit:///home/foo/bar.ly:42:42:42 + // The three numbers are apparently: line:beginning of column:end of column + + if (url.scheme() != QStringLiteral("textedit")) + return false; + + // There can be more, in case the filename contains : + if (url.fileName().count(':') < 3) { + return false; + } + + QStringList parts(url.path().split(':')); + + bool ok; + // Take out the things we need + int columnEnd = parts.takeLast().toInt(&ok); // apparently we don't use this + Q_UNUSED(columnEnd); + if (!ok) { + return false; + } + + *col = parts.takeLast().toInt(&ok); + if (!ok) { + return false; + } + + *row = parts.takeLast().toInt(&ok); + if (!ok) { + return false; + } + + // In case the path itself contains :, we need to reconstruct it after removing all the numbers + *file = parts.join(':'); + return (!file->isEmpty()); +} + +QString Okular::sourceReferenceToolTip(const QString &source, int row, int col) +{ + Q_UNUSED(row); + Q_UNUSED(col); + return i18nc("'source' is a source file", "Source: %1", source); +} diff --git a/core/sourcereference.h b/core/sourcereference.h new file mode 100644 index 0000000..d596d72 --- /dev/null +++ b/core/sourcereference.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2007 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_SOURCEREFERENCE_H +#define OKULAR_SOURCEREFERENCE_H + +#include "okularcore_export.h" +#include +class QString; + +namespace Okular +{ +/** + * @short Defines a source reference + * + * A source reference is a reference to one of the source(s) of the loaded + * document. + */ +class OKULARCORE_EXPORT SourceReference +{ +public: + /** + * Creates a reference to the row @p row and column @p column of the + * source @p fileName + */ + SourceReference(const QString &fileName, int row, int column = 0); + + /** + * Destroys the source reference. + */ + ~SourceReference(); + + /** + * Returns the filename of the source. + */ + QString fileName() const; + + /** + * Returns the row of the position in the source file. + */ + int row() const; + + /** + * Returns the column of the position in the source file. + */ + int column() const; + +private: + class Private; + Private *const d; + + Q_DISABLE_COPY(SourceReference) +}; + +} + +#endif diff --git a/core/sourcereference_p.h b/core/sourcereference_p.h new file mode 100644 index 0000000..9f8c8d0 --- /dev/null +++ b/core/sourcereference_p.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * 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_SOURCEREFERENCE_P_H +#define OKULAR_SOURCEREFERENCE_P_H + +class QString; +class QUrl; + +namespace Okular +{ +bool extractLilyPondSourceReference(const QUrl &url, QString *file, int *row, int *col); +QString sourceReferenceToolTip(const QString &source, int row, int col); + +} + +#endif diff --git a/core/synctex/patches/00-disable-SYNCTEX_INLINE.diff b/core/synctex/patches/00-disable-SYNCTEX_INLINE.diff new file mode 100644 index 0000000..d822fad --- /dev/null +++ b/core/synctex/patches/00-disable-SYNCTEX_INLINE.diff @@ -0,0 +1,17 @@ +Disable SYNCTEX_INLINE on non-MSVC compilers. It is misplaced +in the code (before "static"), so it causes compiling errors. +Author: Pino Toscano + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -91,7 +91,7 @@ + # if defined(_MSC_VER) + # define SYNCTEX_INLINE __inline + # else +-# define SYNCTEX_INLINE inline ++# define SYNCTEX_INLINE + # endif + # endif + diff --git a/core/synctex/patches/04-gcc-specify-printf-format.diff b/core/synctex/patches/04-gcc-specify-printf-format.diff new file mode 100644 index 0000000..24cc67e --- /dev/null +++ b/core/synctex/patches/04-gcc-specify-printf-format.diff @@ -0,0 +1,77 @@ +_synctex_error has a printf-like format, so use the proper gcc extensions +to check its arguments (doing nothing for other compilers) +Author: Pino Toscano + +Index: synctex/synctex_parser_utils.h +=================================================================== +--- synctex.orig/synctex_parser_utils.h ++++ synctex/synctex_parser_utils.h +@@ -83,6 +83,12 @@ extern "C" { + # else + # define SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(left,right) (toupper(left) != toupper(right)) + # endif ++ ++# ifdef __GNUC__ ++# define SYNCTEX_PRINTF_FORMAT(si, ftc) __attribute__ ((format (printf, si, ftc))) ++# else ++# define SYNCTEX_PRINTF_FORMAT(si, ftc) ++# endif + + /* This custom malloc functions initializes to 0 the newly allocated memory. + * There is no bzero function on windows. */ +@@ -95,8 +101,8 @@ void _synctex_free(void * ptr); + /* This is used to log some informational message to the standard error stream. + * On Windows, the stderr stream is not exposed and another method is used. + * The return value is the number of characters printed. */ +- int _synctex_error(const char * reason,...); +- int _synctex_debug(const char * reason,...); ++ int _synctex_error(const char * reason,...) SYNCTEX_PRINTF_FORMAT(1, 2); ++ int _synctex_debug(const char * reason,...) SYNCTEX_PRINTF_FORMAT(1, 2); + + /* strip the last extension of the given string, this string is modified! + * This function depends on the OS because the path separator may differ. +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -8148,6 +8148,7 @@ struct synctex_updater_t { + int length; /* the number of chars appended */ + }; + ++static int _synctex_updater_print(synctex_updater_p updater, const char * format, ...) SYNCTEX_PRINTF_FORMAT(2, 3); + static int _synctex_updater_print(synctex_updater_p updater, const char * format, ...) { + int result = 0; + if (updater) { +@@ -8184,6 +8185,7 @@ static int vasprintf(char **ret, + /** + * gzvprintf is not available until OSX 10.10 + */ ++static int _synctex_updater_print_gz(synctex_updater_p updater, const char * format, ...) SYNCTEX_PRINTF_FORMAT(2, 3); + static int _synctex_updater_print_gz(synctex_updater_p updater, const char * format, ...) { + int result = 0; + if (updater) { +Index: synctex/synctex_parser_utils.c +=================================================================== +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -87,8 +87,11 @@ void _synctex_free(void * ptr) { + # include + #endif + +-int _synctex_log(int level, const char * prompt, const char * reason, va_list arg;) { ++int _synctex_log(int level, const char * prompt, const char * reason, ...) SYNCTEX_PRINTF_FORMAT(3, 4); ++int _synctex_log(int level, const char * prompt, const char * reason, ...) { ++ va_list arg; + int result; ++ va_start(arg, reason); + # ifdef SYNCTEX_RECENT_WINDOWS + {/* This code is contributed by William Blum. + As it does not work on some older computers, +@@ -130,6 +133,7 @@ int _synctex_log(int level, const char * + result += vfprintf(where, reason, arg); + result += fprintf(where,"\n"); + # endif ++ va_end(arg); + return result; + } + diff --git a/core/synctex/patches/06-mingw-_synctex_error.diff b/core/synctex/patches/06-mingw-_synctex_error.diff new file mode 100644 index 0000000..75f0aaf --- /dev/null +++ b/core/synctex/patches/06-mingw-_synctex_error.diff @@ -0,0 +1,36 @@ +_vscprintf() is specific for MSVC; thus in _synctex_error(), for any other +compiler on Windows, use _vsnprintf() and grow the buffer until necessary. + +Patch provided by Patrick Spendrin . + +Index: synctex/synctex_parser_utils.c +=================================================================== +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -104,8 +104,26 @@ int _synctex_log(int level, const char * + char *buff; + size_t len; + OutputDebugStringA(prompt); ++# ifdef _MSC_VER + len = _vscprintf(reason, arg) + 1; + buff = (char*)malloc( len * sizeof(char) ); ++# else /* MinGW */ ++ size_t buffersize = 1024; ++ size_t max_buffersize = 1024 * buffersize; ++ int result; ++ buff = (char*)malloc(buffersize * sizeof(char)); ++ result = _vsnprintf(buff, buffersize - 1, reason, arg); ++ while(-1 == result && buffersize <= max_buffersize) { ++ buffersize = buffersize * 2; ++ buff = (char*)realloc(buff, buffersize * sizeof(char)); ++ result = _vsnprintf(buff, buffersize - 1, reason, arg); ++ } ++ if(-1 == result) { ++ // could not make the buffer big enough or simply could not write to it ++ free(buff); ++ return -1; ++ } ++# endif + result = vsprintf(buff, reason, arg) +strlen(prompt); + OutputDebugStringA(buff); + OutputDebugStringA("\n"); diff --git a/core/synctex/patches/08-fix_cpp_comments.diff b/core/synctex/patches/08-fix_cpp_comments.diff new file mode 100644 index 0000000..05dd81c --- /dev/null +++ b/core/synctex/patches/08-fix_cpp_comments.diff @@ -0,0 +1,37 @@ +Fix cpp comments +Author: Albert Astals Cid + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -6048,7 +6048,7 @@ static int _synctex_scanner_get_tag(sync + } + } while((input = __synctex_tree_sibling(input))); + } +- // 2011 version ++ /* 2011 version */ + name = _synctex_base_name(name); + if ((input = scanner->input)) { + do { +@@ -6058,7 +6058,7 @@ static int _synctex_scanner_get_tag(sync + if (_synctex_is_equivalent_file_name(name,_synctex_base_name(_synctex_data_name(other_input))) + && (strlen(_synctex_data_name(input))!=strlen(_synctex_data_name(other_input)) + || strncmp(_synctex_data_name(other_input),_synctex_data_name(input),strlen(_synctex_data_name(input))))) { +- // There is a second possible candidate ++ /* There is a second possible candidate */ + return 0; + } + } +Index: synctex/synctex_parser_utils.c +=================================================================== +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -587,6 +587,6 @@ int _synctex_get_name(const char * outpu + + const char * _synctex_get_io_mode_name(synctex_io_mode_t io_mode) { + static const char * synctex_io_modes[4] = {"r","rb","a","ab"}; +- unsigned index = ((io_mode & synctex_io_gz_mask)?1:0) + ((io_mode & synctex_io_append_mask)?2:0);// bug pointed out by Jose Alliste ++ unsigned index = ((io_mode & synctex_io_gz_mask)?1:0) + ((io_mode & synctex_io_append_mask)?2:0);/* bug pointed out by Jose Alliste */ + return synctex_io_modes[index]; + } diff --git a/core/synctex/patches/10-fix-typo.diff b/core/synctex/patches/10-fix-typo.diff new file mode 100644 index 0000000..93387b4 --- /dev/null +++ b/core/synctex/patches/10-fix-typo.diff @@ -0,0 +1,17 @@ +Fix some typos found by Krazy2 +Author: Yuri Chornoivan +Original commit: 3b73357 + +Index: synctex/synctex_parser_utils.c +=================================================================== +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -410,7 +410,7 @@ char * _synctex_merge_strings(const char + + /* The purpose of _synctex_get_name is to find the name of the synctex file. + * There is a list of possible filenames from which we return the most recent one and try to remove all the others. +- * With two runs of pdftex or xetex we are sure the the synctex file is really the most appropriate. ++ * With two runs of pdftex or xetex we are sure the synctex file is really the most appropriate. + */ + int _synctex_get_name(const char * output, const char * build_directory, char ** synctex_name_ref, synctex_io_mode_t * io_mode_ref) + { diff --git a/core/synctex/patches/11-fix-unused-parameters-warnings.diff b/core/synctex/patches/11-fix-unused-parameters-warnings.diff new file mode 100644 index 0000000..db65649 --- /dev/null +++ b/core/synctex/patches/11-fix-unused-parameters-warnings.diff @@ -0,0 +1,49 @@ +Fix low hanging unused parameters warnings +Author: Martin T. H. Sandsmark +Original commit: d5bdca6 + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -198,9 +198,7 @@ typedef struct synctex_tlcpector_t { + } synctex_tlcpector_s; + typedef const synctex_tlcpector_s * synctex_tlcpector_p; + static int _synctex_int_none(synctex_node_p node) { +-# ifdef __DARWIN_UNIX03 +-# pragma unused(node) +-# endif ++ (void)node; /* unused */ + return 0; + } + static const synctex_tlcpector_s synctex_tlcpector_none = { +@@ -234,9 +232,7 @@ typedef struct synctex_vispector_t { + synctex_float_getter_f depth; + } synctex_vispector_s; + static float _synctex_float_none(synctex_node_p node) { +-# ifdef __DARWIN_UNIX03 +-# pragma unused(node) +-# endif ++ (void)node; /* unused */ + return 0; + } + static const synctex_vispector_s synctex_vispector_none = { +@@ -7206,9 +7202,7 @@ static synctex_node_p _synctex_display_q + return first_handle; + } + synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint) { +-# ifdef __DARWIN_UNIX03 +-# pragma unused(column) +-# endif ++ (void)column; /* unused */ + if (scanner) { + int tag = synctex_scanner_get_tag(scanner,name);/* parse if necessary */ + int max_line = 0; +@@ -7977,6 +7971,7 @@ SYNCTEX_INLINE static synctex_nd_lr_s __ + } + #endif + SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_vbox_v2(synctex_point_p hitP, synctex_node_p nodeP) { ++ (void)nodeP; /* unused */ + synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0}; + synctex_nd_s nd = SYNCTEX_ND_0; + if ((nd.node = synctex_node_child(nd.node))) { diff --git a/core/synctex/patches/12-omit-no-file-warning.diff b/core/synctex/patches/12-omit-no-file-warning.diff new file mode 100644 index 0000000..c4cfa5d --- /dev/null +++ b/core/synctex/patches/12-omit-no-file-warning.diff @@ -0,0 +1,17 @@ +Omit warning message when opening non-synctex pdf +Author: Henrik Fehlauer + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -5838,7 +5838,9 @@ synctex_scanner_p synctex_scanner_new_wi + if ((scanner->reader = synctex_reader_init_with_output_file(scanner->reader, output, build_directory))) { + return parse? synctex_scanner_parse(scanner):scanner; + } ++#if defined(SYNCTEX_DEBUG) + _synctex_error("No file?"); ++#endif + return NULL; + } + diff --git a/core/synctex/patches/13-fix-Wundef-warnings.diff b/core/synctex/patches/13-fix-Wundef-warnings.diff new file mode 100644 index 0000000..e5c1924 --- /dev/null +++ b/core/synctex/patches/13-fix-Wundef-warnings.diff @@ -0,0 +1,326 @@ +Fix compiler warnings for -Wundef +Author: Henrik Fehlauer + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -362,7 +362,7 @@ __synctex_scanner_register_handle_to(NOD + # pragma mark Tree SETGET + # endif + +-#if SYNCTEX_DEBUG > 1000 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 1000 + #define SYNCTEX_PARAMETER_ASSERT(WHAT) \ + do { \ + if (!(WHAT)) { \ +@@ -459,11 +459,11 @@ DEFINE_SYNCTEX_TREE_GETSET(next_hbox) + DEFINE_SYNCTEX_TREE_GETSET(arg_sibling) + DEFINE_SYNCTEX_TREE_GETSET(target) + +-#if SYNCTEX_DEBUG>1000 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>1000 + # undef SYNCTEX_USE_NODE_COUNT + # define SYNCTEX_USE_NODE_COUNT 1 + #endif +-#if SYNCTEX_USE_NODE_COUNT>0 ++#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT>0 + # define SYNCTEX_DECLARE_NODE_COUNT int node_count; + # define SYNCTEX_INIT_NODE_COUNT \ + do { node_count = 0; } while(synctex_NO) +@@ -472,7 +472,7 @@ DEFINE_SYNCTEX_TREE_GETSET(target) + # define SYNCTEX_INIT_NODE_COUNT + #endif + +-#if SYNCTEX_USE_NODE_COUNT>10 ++#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT>10 + # define SYNCTEX_DID_NEW(N) _synctex_did_new(N) + # define SYNCTEX_WILL_FREE(N) _synctex_will_free(N) + #else +@@ -865,7 +865,7 @@ SYNCTEX_INLINE static void __synctex_sca + node->class->scanner->handle = NNN; + } + #endif +-#if SYNCTEX_USE_NODE_COUNT>10 ++#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT>10 + SYNCTEX_INLINE static void _synctex_did_new(synctex_node_p node) { + printf("NODE CREATED # %i, %s, %p\n", + (node->class->scanner->node_count)++, +@@ -2516,7 +2516,7 @@ SYNCTEX_INLINE static synctex_nns_s _syn + } + static char * _synctex_node_abstract(synctex_node_p node); + SYNCTEX_INLINE static synctex_node_p synctex_tree_set_friend(synctex_node_p node,synctex_node_p new_friend) { +-#if SYNCTEX_DEBUG ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG + synctex_node_p F = new_friend; + while (F) { + if (node == F) { +@@ -2545,7 +2545,7 @@ SYNCTEX_INLINE static synctex_node_p __s + i = i%(node->class->scanner->number_of_lists); + old = synctex_tree_set_friend(node,(node->class->scanner->lists_of_friends)[i]); + (node->class->scanner->lists_of_friends)[i] = node; +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("tl(%i)=>",i); + synctex_node_log(node); + if (synctex_node_parent_form(node)) { +@@ -4186,7 +4186,7 @@ static synctex_ns_s __synctex_parse_new_ + /* Prepend this input node to the input linked list of the scanner */ + __synctex_tree_set_sibling(input,scanner->input);/* input has no parent */ + scanner->input = input; +-# if SYNCTEX_VERBOSE ++# ifdef SYNCTEX_VERBOSE + synctex_node_log(input); + # endif + return (synctex_ns_s){input,_synctex_next_line(scanner)};/* read the line termination character, if any */ +@@ -5083,10 +5083,10 @@ content_loop: + */ + /* forms are everywhere */ + ns = SYNCTEX_NS_NULL; +-#if SYNCTEX_VERBOSE ++#ifdef SYNCTEX_VERBOSE + synctex_scanner_set_display_switcher(scanner,-1); + printf("NEW CONTENT LOOP\n"); +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + synctex_node_display(sheet); + #endif + #endif +@@ -5106,7 +5106,7 @@ content_loop: + } + parent = ns.node; + child = _synctex_tree_last(parent); +-# if SYNCTEX_VERBOSE ++# ifdef SYNCTEX_VERBOSE + synctex_node_log(parent); + # endif + input.node = _synctex_input_register_line(input.node,parent); +@@ -5124,7 +5124,7 @@ content_loop: + } + child = parent; + parent = _synctex_tree_parent(child); +-# if SYNCTEX_VERBOSE ++# ifdef SYNCTEX_VERBOSE + synctex_node_log(child); + # endif + if (_synctex_next_line(scanner)500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + synctex_node_display(parent); + synctex_node_display(child); + #endif +@@ -5406,7 +5406,7 @@ _synctex_make_hbox_contain_box(parent,_s + } + scanner->ref_in_sheet = child; + } +-# if SYNCTEX_VERBOSE ++# ifdef SYNCTEX_VERBOSE + synctex_node_log(child); + # endif + goto content_loop; +@@ -5427,7 +5427,7 @@ _synctex_make_hbox_contain_box(parent,_s + __synctex_node_make_friend_tlc(child); + } + _synctex_make_hbox_contain_point(parent,_synctex_data_point(child)); +-# if SYNCTEX_VERBOSE ++# ifdef SYNCTEX_VERBOSE + synctex_node_log(child); + # endif + input.node = _synctex_input_register_line(input.node,child); +@@ -5536,7 +5536,7 @@ SYNCTEX_INLINE static synctex_ns_s __syn + sibling->line_index = arg_sibling->line_index; + } + #endif +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("! Ref replacement:\n"); + synctex_node_log(ref); + synctex_node_display(synctex_node_sibling(ref)); +@@ -5600,7 +5600,7 @@ SYNCTEX_INLINE static synctex_status_t _ + } + } + do { +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("POST PROCESSING %s\n",_synctex_node_abstract(proxy)); + { + int i,j = 0; +@@ -5619,7 +5619,7 @@ SYNCTEX_INLINE static synctex_status_t _ + } + #endif + f(proxy); +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + { + int i,j = 0; + for (i=0;iclass->scanner->number_of_lists;++i) { +@@ -5638,7 +5638,7 @@ SYNCTEX_INLINE static synctex_status_t _ + #endif + /* Side effect: create the hierarchy on the fly */ + proxy = synctex_node_next(proxy); /* Change is here */ +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + if (proxy) { + int i,j = 0; + for (i=0;iclass->scanner->number_of_lists;++i) { +@@ -5670,7 +5670,7 @@ SYNCTEX_INLINE static synctex_status_t _ + SYNCTEX_INLINE static synctex_status_t _synctex_post_process(synctex_scanner_p scanner) { + synctex_status_t status = SYNCTEX_STATUS_OK; + synctex_ns_s ns = {NULL,SYNCTEX_STATUS_NOT_OK}; +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("! entering _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +@@ -5681,7 +5681,7 @@ SYNCTEX_INLINE static synctex_status_t _ + if (ns.status500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("! ref replaced in form _synctex_post_process.\n"); + synctex_node_display(scanner->form); + #endif +@@ -5703,7 +5703,7 @@ SYNCTEX_INLINE static synctex_status_t _ + status = ns.status; + } + scanner->ref_in_sheet = NULL; +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("! ref replaced in sheet _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); + #endif +@@ -5725,7 +5725,7 @@ SYNCTEX_INLINE static synctex_status_t _ + } + } + #endif +-#if SYNCTEX_DEBUG>10000 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>10000 + { + int i; + for (i=0;inumber_of_lists;++i) { +@@ -5746,7 +5746,7 @@ SYNCTEX_INLINE static synctex_status_t _ + if (ns.status500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + printf("! exiting _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +@@ -5861,7 +5861,7 @@ int synctex_scanner_free(synctex_scanner + synctex_iterator_free(scanner->iterator); + free(scanner->output_fmt); + free(scanner->lists_of_friends); +-#if SYNCTEX_USE_NODE_COUNT>0 ++#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT>0 + node_count = scanner->node_count; + #endif + free(scanner); +@@ -5919,7 +5919,7 @@ synctex_scanner_p synctex_scanner_parse( + if (status500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + synctex_scanner_set_display_switcher(scanner, 100); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +@@ -8048,7 +8048,7 @@ static synctex_nd_s __synctex_closest_de + SYNCTEX_LINEINDEX(node)); + #endif + do { +-#if SYNCTEX_DEBUG>500 ++#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG>500 + synctex_node_display(child); + #endif + synctex_nd_s nd = SYNCTEX_ND_0; +Index: synctex/synctex_parser_utils.c +=================================================================== +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -129,7 +129,7 @@ int _synctex_log(int level, const char * + OutputDebugStringA("\n"); + free(buff); + } +-# elif SYNCTEX_USE_SYSLOG ++# elif defined SYNCTEX_USE_SYSLOG + char * buffer1 = NULL; + char * buffer2 = NULL; + openlog ("SyncTeX", LOG_CONS | LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_LOCAL0); diff --git a/core/synctex/patches/14-fix-misc-compiler-warnings.diff b/core/synctex/patches/14-fix-misc-compiler-warnings.diff new file mode 100644 index 0000000..9b4959d --- /dev/null +++ b/core/synctex/patches/14-fix-misc-compiler-warnings.diff @@ -0,0 +1,62 @@ +Fix even more compiler warnings +Author: Henrik Fehlauer + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -529,8 +529,8 @@ typedef struct synctex_reader_t { + char * current; /* current location in the buffer */ + char * start; /* start of the buffer */ + char * end; /* end of the buffer */ +- int min_size; +- int size; ++ size_t min_size; ++ size_t size; + int lastv; + int line_number; + SYNCTEX_DECLARE_CHAR_OFFSET +@@ -759,7 +759,6 @@ synctex_reader_p synctex_reader_init_wit + (char *)_synctex_malloc(reader->size+1); /* one more character for null termination */ + if (NULL == reader->start) { + _synctex_error("! malloc error in synctex_reader_init_with_output_file."); +- bailey: + #ifdef SYNCTEX_DEBUG + return reader; + #else +@@ -5293,7 +5292,7 @@ content_loop: + # pragma mark + SCAN KERN + # endif + ns = _synctex_parse_new_kern(scanner); +- continue_scan: ++ /* continue_scan: */ + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child,ns.node); +@@ -6531,7 +6530,7 @@ SYNCTEX_INLINE static synctex_point_s _s + return old; + } + SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node) { +- synctex_box_s box = {0,0,0,0}; ++ synctex_box_s box = {{0,0},{0,0}}; + int n; + n = synctex_node_width(node); + if (n<0) { +@@ -6547,7 +6546,7 @@ SYNCTEX_INLINE static synctex_box_s _syn + return box; + } + SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node) { +- synctex_box_s box = {0,0,0,0}; ++ synctex_box_s box = {{0,0},{0,0}}; + int n; + n = synctex_node_width(node); + if (n>0) { +@@ -6563,7 +6562,7 @@ SYNCTEX_INLINE static synctex_box_s _syn + return box; + } + SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node) { +- synctex_box_s box = {0,0,0,0}; ++ synctex_box_s box = {{0,0},{0,0}}; + int n; + n = _synctex_node_width_V(node); + if (n<0) { diff --git a/core/synctex/patches/15-prevent-leaks-and-segfault.diff b/core/synctex/patches/15-prevent-leaks-and-segfault.diff new file mode 100644 index 0000000..25441c4 --- /dev/null +++ b/core/synctex/patches/15-prevent-leaks-and-segfault.diff @@ -0,0 +1,54 @@ +Plug multiple leaks and prevent a segfault: +- When the returned value to be assigned to reader is NULL, reader should be freed beforehand. +- Do not leak memory when scanner creation succeeded, but no synctex file was found. +- A valid reader is the prerequisite for accessing SYNCTEX_FILE. +- Two calls to malloc() for reader->start also require two calls to free(). + +Author: Henrik Fehlauer + + +Index: synctex/synctex_parser.c +=================================================================== +--- synctex.orig/synctex_parser.c ++++ synctex/synctex_parser.c +@@ -739,6 +739,7 @@ synctex_reader_p synctex_reader_init_wit + if (open.statusreader && SYNCTEX_FILE) { + gzclose(SYNCTEX_FILE); + SYNCTEX_FILE = NULL; + } +@@ -5883,6 +5885,15 @@ synctex_scanner_p synctex_scanner_parse( + scanner->x_offset = scanner->y_offset = 6.027e23f; + scanner->reader->line_number = 1; + ++ /* TODO: cleanup ++ * In some (all?) cases SYNCTEX_START is already initialized ++ * in synctex_reader_init_with_output_file(). Much of the ++ * following code seems like a duplicate and is perhaps a ++ * candidate for deletion. To be on the safe side though, we ++ * keep it for now and just free() any prior malloc() if ++ * existing. */ ++ _synctex_free(SYNCTEX_START); ++ + SYNCTEX_START = (char *)malloc(SYNCTEX_BUFFER_SIZE+1); /* one more character for null termination */ + if (NULL == SYNCTEX_START) { + _synctex_error("! malloc error in synctex_scanner_parse."); diff --git a/core/synctex/patches/16-use-windows-ansi-api-path-find.diff b/core/synctex/patches/16-use-windows-ansi-api-path-find.diff new file mode 100644 index 0000000..de2e3c4 --- /dev/null +++ b/core/synctex/patches/16-use-windows-ansi-api-path-find.diff @@ -0,0 +1,19 @@ +Use Windows ANSI versions of the PathFind... methods + +Author: Michel Ludwig + + +Index: synctex/synctex_parser_utils.c +--- synctex.orig/synctex_parser_utils.c ++++ synctex/synctex_parser_utils.c +@@ -187,8 +187,8 @@ void _synctex_strip_last_path_extension(char * string) { + char * last_component = NULL; + char * last_extension = NULL; + # if defined(SYNCTEX_WINDOWS) +- last_component = PathFindFileName(string); +- last_extension = PathFindExtension(string); ++ last_component = PathFindFileNameA(string); ++ last_extension = PathFindExtensionA(string); + if(last_extension == NULL)return; + if(last_component == NULL)last_component = string; + if(last_extension>last_component){/* filter out paths like "my/dir/.hidden" */ diff --git a/core/synctex/patches/series b/core/synctex/patches/series new file mode 100644 index 0000000..4be2c20 --- /dev/null +++ b/core/synctex/patches/series @@ -0,0 +1,11 @@ +00-disable-SYNCTEX_INLINE.diff +04-gcc-specify-printf-format.diff +06-mingw-_synctex_error.diff +08-fix_cpp_comments.diff +10-fix-typo.diff +11-fix-unused-parameters-warnings.diff +12-omit-no-file-warning.diff +13-fix-Wundef-warnings.diff +14-fix-misc-compiler-warnings.diff +15-prevent-leaks-and-segfault.diff +16-use-windows-ansi-api-path-find.diff diff --git a/core/synctex/synctex_parser.c b/core/synctex/synctex_parser.c new file mode 100644 index 0000000..0db22a2 --- /dev/null +++ b/core/synctex/synctex_parser.c @@ -0,0 +1,8659 @@ +/* + Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + + This file is part of the __SyncTeX__ package. + + [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) + [//]: # (Version: 1.19) + + See `synctex_parser_readme.md` for more details + + ## License + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE + + Except as contained in this notice, the name of the copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization from the copyright holder. + + Acknowledgments: + ---------------- + The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh, + and significant help from XeTeX developer Jonathan Kew + + Nota Bene: + ---------- + If you include or use a significant part of the synctex package into a software, + I would appreciate to be listed as contributor and see "SyncTeX" highlighted. + + */ + +/* We assume that high level application like pdf viewers will want + * to embed this code as is. We assume that they also have locale.h and setlocale. + * For other tools such as TeXLive tools, you must define SYNCTEX_USE_LOCAL_HEADER, + * when building. You also have to create and customize synctex_parser_local.h to fit your system. + * In particular, the HAVE_LOCALE_H and HAVE_SETLOCALE macros should be properly defined. + * With this design, you should not need to edit this file. */ + +/** + * \file synctex_parser.c + * \brief SyncTeX file parser and controller. + * - author: Jérôme LAURENS + * \version 1.19 + * \date Mon Apr 24 07:08:56 UTC 2017 + * + * Reads and parse *.synctex[.gz] files, + * performs edit and display queries. + * + * See + * - synctex_scanner_new_with_output_file + * - synctex_scanner_parse + * - synctex_scanner_free + * - synctex_display_query + * - synctex_edit_query + * - synctex_scanner_next_result + * - synctex_scanner_reset_result + * + * The data is organized in a graph with multiple entries. + * The root object is a scanner, it is created with the contents on a synctex file. + * Each node of the tree is a synctex_node_t object. + * There are 3 subtrees, two of them sharing the same leaves. + * The first tree is the list of input records, where input file names are associated with tags. + * The second tree is the box tree as given by TeX when shipping pages out. + * First level objects are sheets and forms, containing boxes, glues, kerns... + * The third tree allows to browse leaves according to tag and line. + */ +#if defined(SYNCTEX_USE_LOCAL_HEADER) +#include "synctex_parser_local.h" +#else +#define HAVE_LOCALE_H 1 +#define HAVE_SETLOCALE 1 +#if defined(_MSC_VER) +#define SYNCTEX_INLINE __inline +#else +#define SYNCTEX_INLINE +#endif +#endif + +#include +#include +#include +#include +#include + +#if defined(HAVE_LOCALE_H) +#include +#endif + +#include "synctex_parser_advanced.h" + +SYNCTEX_INLINE static int _synctex_abs(int x) +{ + return x > 0 ? x : -x; +} +/* These are the possible extensions of the synctex file */ +const char *synctex_suffix = ".synctex"; +const char *synctex_suffix_gz = ".gz"; + +typedef synctex_node_p (*synctex_node_new_f)(synctex_scanner_p); +typedef void (*synctex_node_fld_f)(synctex_node_p); +typedef char *(*synctex_node_str_f)(synctex_node_p); + +/** + * Pseudo class. + * - author: J. Laurens + * + * Each nodes has a class, it is therefore called an object. + * Each class has a unique scanner. + * Each class has a type which is a unique identifier. + * Each class has a node mask which identifies node's attributes. + * Each class has an info mask which info's attributes. + * The class points to various methods, + * each of them vary amongst objects. + * The navigator records the offsets of the tree members getters. + * The modelator records the offsets of the data members getters, relative to the last navigator getter. + */ + +/* 8 fields + size: spcflnat */ +typedef struct synctex_tree_model_t { + int sibling; + int parent; + int child; + int friend; + int last; + int next_hbox; + int arg_sibling; + int target; + int size; +} synctex_tree_model_s; +typedef const synctex_tree_model_s *synctex_tree_model_p; + +typedef struct synctex_data_model_t { + int tag; + int line; + int column; + int h; + int v; + int width; + int height; + int depth; + int mean_line; + int weight; + int h_V; + int v_V; + int width_V; + int height_V; + int depth_V; + int name; + int page; + int size; +} synctex_data_model_s; + +static const synctex_data_model_s synctex_data_model_none = {-1, /* tag */ + -1, /* line */ + -1, /* column */ + -1, /* h */ + -1, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + 0}; +typedef const synctex_data_model_s *synctex_data_model_p; + +typedef int (*synctex_int_getter_f)(synctex_node_p); +typedef struct synctex_tlcpector_t { + synctex_int_getter_f tag; + synctex_int_getter_f line; + synctex_int_getter_f column; +} synctex_tlcpector_s; +typedef const synctex_tlcpector_s *synctex_tlcpector_p; +static int _synctex_int_none(synctex_node_p node) +{ + (void)node; /* unused */ + return 0; +} +static const synctex_tlcpector_s synctex_tlcpector_none = { + &_synctex_int_none, /* tag */ + &_synctex_int_none, /* line */ + &_synctex_int_none, /* column */ +}; + +typedef struct synctex_inspector_t { + synctex_int_getter_f h; + synctex_int_getter_f v; + synctex_int_getter_f width; + synctex_int_getter_f height; + synctex_int_getter_f depth; +} synctex_inspector_s; +typedef const synctex_inspector_s *synctex_inspector_p; +static const synctex_inspector_s synctex_inspector_none = { + &_synctex_int_none, /* h */ + &_synctex_int_none, /* v */ + &_synctex_int_none, /* width */ + &_synctex_int_none, /* height */ + &_synctex_int_none, /* depth */ +}; + +typedef float (*synctex_float_getter_f)(synctex_node_p); +typedef struct synctex_vispector_t { + synctex_float_getter_f h; + synctex_float_getter_f v; + synctex_float_getter_f width; + synctex_float_getter_f height; + synctex_float_getter_f depth; +} synctex_vispector_s; +static float _synctex_float_none(synctex_node_p node) +{ + (void)node; /* unused */ + return 0; +} +static const synctex_vispector_s synctex_vispector_none = { + &_synctex_float_none, /* h */ + &_synctex_float_none, /* v */ + &_synctex_float_none, /* width */ + &_synctex_float_none, /* height */ + &_synctex_float_none, /* depth */ +}; +typedef const synctex_vispector_s *synctex_vispector_p; + +struct synctex_class_t { + synctex_scanner_p scanner; + synctex_node_type_t type; + synctex_node_new_f new; + synctex_node_fld_f free; + synctex_node_fld_f log; + synctex_node_fld_f display; + synctex_node_str_f abstract; + synctex_tree_model_p navigator; + synctex_data_model_p modelator; + synctex_tlcpector_p tlcpector; + synctex_inspector_p inspector; + synctex_vispector_p vispector; +}; + +/** + * Nota bene: naming convention. + * For static API, when the name contains proxy, it applies to proxies. + * When the name contains noxy, it applies to non proxies only. + * When the name contains node, weel it depends... + */ + +typedef synctex_node_p synctex_proxy_p; +typedef synctex_node_p synctex_noxy_p; + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Abstract OBJECTS and METHODS +#endif + +/** + * \def SYNCTEX_MSG_SEND + * \brief Takes care of sending the given message if possible. + * - parameter NODE: of type synctex_node_p + * - parameter SELECTOR: one of the class pointer properties + */ +#define SYNCTEX_MSG_SEND(NODE, SELECTOR) \ + do { \ + synctex_node_p N__ = NODE; \ + if (N__ && N__->class->SELECTOR) { \ + (*(N__->class->SELECTOR))(N__); \ + } \ + } while (synctex_NO) + +/** + * Free the given node by sending the free message. + * - parameter NODE: of type synctex_node_p + */ +void synctex_node_free(synctex_node_p node) +{ + SYNCTEX_MSG_SEND(node, free); +} +#if defined(SYNCTEX_TESTING) +#if !defined(SYNCTEX_USE_HANDLE) +#define SYNCTEX_USE_HANDLE 1 +#endif +#if !defined(SYNCTEX_USE_CHARINDEX) +#define SYNCTEX_USE_CHARINDEX 1 +#endif +#endif +SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target); +#if defined(SYNCTEX_USE_HANDLE) +#define SYNCTEX_SCANNER_FREE_HANDLE(SCANR) __synctex_scanner_free_handle(SCANR) +#define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT) __synctex_scanner_remove_handle_to(WHAT) +#define SYNCTEX_REGISTER_HANDLE_TO(NODE) __synctex_scanner_register_handle_to(NODE) +#else +#define SYNCTEX_SCANNER_FREE_HANDLE(SCANR) +#define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT) +#define SYNCTEX_REGISTER_HANDLE_TO(NODE) +#endif + +#if defined(SYNCTEX_USE_CHARINDEX) +#define SYNCTEX_CHARINDEX(NODE) (NODE->char_index) +#define SYNCTEX_LINEINDEX(NODE) (NODE->line_index) +#define SYNCTEX_PRINT_CHARINDEX_FMT "#%i" +#define SYNCTEX_PRINT_CHARINDEX_WHAT , SYNCTEX_CHARINDEX(node) +#define SYNCTEX_PRINT_CHARINDEX printf(SYNCTEX_PRINT_CHARINDEX_FMT SYNCTEX_PRINT_CHARINDEX_WHAT) +#define SYNCTEX_PRINT_LINEINDEX_FMT "L#%i" +#define SYNCTEX_PRINT_LINEINDEX_WHAT , SYNCTEX_LINEINDEX(node) +#define SYNCTEX_PRINT_LINEINDEX printf(SYNCTEX_PRINT_LINEINDEX_FMT SYNCTEX_PRINT_LINEINDEX_WHAT) +#define SYNCTEX_PRINT_CHARINDEX_NL printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n" SYNCTEX_PRINT_CHARINDEX_WHAT) +#define SYNCTEX_PRINT_LINEINDEX_NL printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n" SYNCTEX_PRINT_LINEINDEX_WHAT) +#define SYNCTEX_IMPLEMENT_CHARINDEX(NODE, CORRECTION) \ + NODE->char_index = (synctex_charindex_t)(scanner->reader->charindex_offset + SYNCTEX_CUR - SYNCTEX_START + (CORRECTION)); \ + NODE->line_index = scanner->reader->line_number; +#else +#define SYNCTEX_CHARINDEX(NODE) 0 +#define SYNCTEX_LINEINDEX(NODE) 0 +#define SYNCTEX_PRINT_CHARINDEX_FMT +#define SYNCTEX_PRINT_CHARINDEX_WHAT +#define SYNCTEX_PRINT_CHARINDEX +#define SYNCTEX_PRINT_CHARINDEX +#define SYNCTEX_PRINT_LINEINDEX_FMT +#define SYNCTEX_PRINT_LINEINDEX_WHAT +#define SYNCTEX_PRINT_LINEINDEX +#define SYNCTEX_PRINT_CHARINDEX_NL printf("\n") +#define SYNCTEX_PRINT_LINEINDEX_NL printf("\n") +#define SYNCTEX_IMPLEMENT_CHARINDEX(NODE, CORRECTION) +#endif + +/** + * The next macros are used to access the node tree info + * SYNCTEX_DATA(node) points to the first synctex integer or pointer data of node + * SYNCTEX_DATA(node)[index] is the information at index + * for example, the page of a sheet is stored in SYNCTEX_DATA(sheet)[_synctex_data_page_idx] + * - parameter NODE: of type synctex_node_p + * If the name starts with "__", the argument is nonullable + */ +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Tree SETGET +#endif + +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 1000 +#define SYNCTEX_PARAMETER_ASSERT(WHAT) \ + do { \ + if (!(WHAT)) { \ + printf("! Parameter failure: %s\n", #WHAT); \ + } \ + } while (synctex_NO) +#define DEFINE_SYNCTEX_TREE_HAS(WHAT) \ + static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) \ + { \ + if (node) { \ + if (node->class->navigator->WHAT >= 0) { \ + return synctex_YES; \ + } else { \ + printf("WARNING: NO tree %s for %s\n", #WHAT, synctex_node_isa(node)); \ + } \ + } \ + return synctex_NO; \ + } +#else +#define SYNCTEX_PARAMETER_ASSERT(WHAT) +#define DEFINE_SYNCTEX_TREE_HAS(WHAT) \ + static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) \ + { \ + return (node && (node->class->navigator->WHAT >= 0)); \ + } +#endif + +#define DEFINE_SYNCTEX_TREE__GET(WHAT) \ + SYNCTEX_INLINE static synctex_node_p __synctex_tree_##WHAT(synctex_non_null_node_p node) \ + { \ + return node->data[node->class->navigator->WHAT].as_node; \ + } +#define DEFINE_SYNCTEX_TREE_GET(WHAT) \ + DEFINE_SYNCTEX_TREE__GET(WHAT) \ + static synctex_node_p _synctex_tree_##WHAT(synctex_node_p node) \ + { \ + if (_synctex_tree_has_##WHAT(node)) { \ + return __synctex_tree_##WHAT(node); \ + } \ + return 0; \ + } +#define DEFINE_SYNCTEX_TREE__RESET(WHAT) \ + SYNCTEX_INLINE static synctex_node_p __synctex_tree_reset_##WHAT(synctex_non_null_node_p node) \ + { \ + synctex_node_p old = node->data[node->class->navigator->WHAT].as_node; \ + node->data[node->class->navigator->WHAT].as_node = NULL; \ + return old; \ + } +#define DEFINE_SYNCTEX_TREE_RESET(WHAT) \ + DEFINE_SYNCTEX_TREE__RESET(WHAT) \ + SYNCTEX_INLINE static synctex_node_p _synctex_tree_reset_##WHAT(synctex_node_p node) \ + { \ + return _synctex_tree_has_##WHAT(node) ? __synctex_tree_reset_##WHAT(node) : NULL; \ + } +#define DEFINE_SYNCTEX_TREE__SET(WHAT) \ + SYNCTEX_INLINE static synctex_node_p __synctex_tree_set_##WHAT(synctex_non_null_node_p node, synctex_node_p new_value) \ + { \ + synctex_node_p old = __synctex_tree_##WHAT(node); \ + node->data[node->class->navigator->WHAT].as_node = new_value; \ + return old; \ + } +#define DEFINE_SYNCTEX_TREE_SET(WHAT) \ + DEFINE_SYNCTEX_TREE__SET(WHAT) \ + SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_##WHAT(synctex_node_p node, synctex_node_p new_value) \ + { \ + return _synctex_tree_has_##WHAT(node) ? __synctex_tree_set_##WHAT(node, new_value) : NULL; \ + } +#define DEFINE_SYNCTEX_TREE__GETSETRESET(WHAT) \ + DEFINE_SYNCTEX_TREE__GET(WHAT) \ + DEFINE_SYNCTEX_TREE__SET(WHAT) \ + DEFINE_SYNCTEX_TREE__RESET(WHAT) + +#define DEFINE_SYNCTEX_TREE_GETSET(WHAT) \ + DEFINE_SYNCTEX_TREE_HAS(WHAT) \ + DEFINE_SYNCTEX_TREE_GET(WHAT) \ + DEFINE_SYNCTEX_TREE_SET(WHAT) + +#define DEFINE_SYNCTEX_TREE_GETRESET(WHAT) \ + DEFINE_SYNCTEX_TREE_HAS(WHAT) \ + DEFINE_SYNCTEX_TREE_GET(WHAT) \ + DEFINE_SYNCTEX_TREE_RESET(WHAT) + +#define DEFINE_SYNCTEX_TREE_GETSETRESET(WHAT) \ + DEFINE_SYNCTEX_TREE_HAS(WHAT) \ + DEFINE_SYNCTEX_TREE_GET(WHAT) \ + DEFINE_SYNCTEX_TREE_SET(WHAT) \ + DEFINE_SYNCTEX_TREE_RESET(WHAT) + +/* + * _synctex_tree_set_... methods return the old value. + * The return value of _synctex_tree_set_child and + * _synctex_tree_set_sibling must be released somehown. + */ +DEFINE_SYNCTEX_TREE__GETSETRESET(sibling) +DEFINE_SYNCTEX_TREE_GETSETRESET(parent) +DEFINE_SYNCTEX_TREE_GETSETRESET(child) +DEFINE_SYNCTEX_TREE_GETSETRESET(friend) +DEFINE_SYNCTEX_TREE_GETSET(last) +DEFINE_SYNCTEX_TREE_GETSET(next_hbox) +DEFINE_SYNCTEX_TREE_GETSET(arg_sibling) +DEFINE_SYNCTEX_TREE_GETSET(target) + +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 1000 +#undef SYNCTEX_USE_NODE_COUNT +#define SYNCTEX_USE_NODE_COUNT 1 +#endif +#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT > 0 +#define SYNCTEX_DECLARE_NODE_COUNT int node_count; +#define SYNCTEX_INIT_NODE_COUNT \ + do { \ + node_count = 0; \ + } while (synctex_NO) +#else +#define SYNCTEX_DECLARE_NODE_COUNT +#define SYNCTEX_INIT_NODE_COUNT +#endif + +#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT > 10 +#define SYNCTEX_DID_NEW(N) _synctex_did_new(N) +#define SYNCTEX_WILL_FREE(N) _synctex_will_free(N) +#else +#define SYNCTEX_DID_NEW(N) +#define SYNCTEX_WILL_FREE(N) +#endif + +#define SYNCTEX_HAS_CHILDREN(NODE) (NODE && _synctex_tree_child(NODE)) +#ifdef __SYNCTEX_WORK__ +#include "/usr/include/zlib.h" +#else +#include +#endif + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark STATUS +#endif +/* When the end of the synctex file has been reached: */ +#define SYNCTEX_STATUS_EOF 0 +/* When the function could not return the value it was asked for: */ +#define SYNCTEX_STATUS_NOT_OK (SYNCTEX_STATUS_EOF + 1) +/* When the function returns the value it was asked for: + It must be the biggest one */ +#define SYNCTEX_STATUS_OK (SYNCTEX_STATUS_NOT_OK + 1) +/* Generic error: */ +#define SYNCTEX_STATUS_ERROR (SYNCTEX_STATUS_EOF - 1) +/* Parameter error: */ +#define SYNCTEX_STATUS_BAD_ARGUMENT (SYNCTEX_STATUS_ERROR - 1) + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark File reader +#endif + +/* We ensure that SYNCTEX_BUFFER_SIZE < UINT_MAX, I don't know if it makes sense... */ +/* Actually, the minimum buffer size is driven by integer and float parsing, including the unit. + * ±0.123456789e123?? + */ +#define SYNCTEX_BUFFER_MIN_SIZE 32 +#define SYNCTEX_BUFFER_SIZE 32768 + +#if SYNCTEX_BUFFER_SIZE >= UINT_MAX +#error BAD BUFFER SIZE(1) +#endif +#if SYNCTEX_BUFFER_SIZE < SYNCTEX_BUFFER_MIN_SIZE +#error BAD BUFFER SIZE(2) +#endif + +typedef struct synctex_reader_t { + gzFile file; /* The (possibly compressed) file */ + char *output; + char *synctex; + char *current; /* current location in the buffer */ + char *start; /* start of the buffer */ + char *end; /* end of the buffer */ + size_t min_size; + size_t size; + int lastv; + int line_number; + SYNCTEX_DECLARE_CHAR_OFFSET +} synctex_reader_s; + +typedef synctex_reader_s *synctex_reader_p; + +typedef struct { + synctex_status_t status; + char *synctex; + gzFile file; + synctex_io_mode_t io_mode; +} synctex_open_s; + +/* This functions opens the file at the "output" given location. + * It manages the problem of quoted filenames that appear with pdftex and filenames containing the space character. + * In TeXLive 2008, the synctex file created with pdftex did contain unexpected quotes. + * This function will remove them if possible. + * All the reference arguments will take a value on return. They must be non NULL. + * - returns: an open structure which status is + * SYNCTEX_STATUS_OK on success, + * SYNCTEX_STATUS_ERROR on failure. + * - note: on success, the caller is the owner + * of the fields of the returned open structure. + */ +static synctex_open_s __synctex_open_v2(const char *output, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) +{ + synctex_open_s open = {SYNCTEX_STATUS_ERROR, NULL, NULL, io_mode}; + char *quoteless_synctex_name = NULL; + const char *mode = _synctex_get_io_mode_name(open.io_mode); + size_t size = strlen(output) + strlen(synctex_suffix) + strlen(synctex_suffix_gz) + 1; + if (NULL == (open.synctex = (char *)malloc(size))) { + _synctex_error("! __synctex_open_v2: Memory problem (1)\n"); + return open; + } + /* we have reserved for synctex enough memory to copy output (including its 2 eventual quotes), both suffices, + * including the terminating character. size is free now. */ + if (open.synctex != strcpy(open.synctex, output)) { + _synctex_error("! __synctex_open_v2: Copy problem\n"); + return_on_error: + free(open.synctex); + open.synctex = NULL; + free(quoteless_synctex_name); /* We MUST have quoteless_synctex_name<>synctex_name */ + return open; + } + /* remove the last path extension if any */ + _synctex_strip_last_path_extension(open.synctex); + if (!strlen(open.synctex)) { + goto return_on_error; + } + /* now insert quotes. */ + if (add_quotes) { + char *quoted = NULL; + if (_synctex_copy_with_quoting_last_path_component(open.synctex, "ed, size) || quoted == NULL) { + /* There was an error or quoting does not make sense: */ + goto return_on_error; + } + quoteless_synctex_name = open.synctex; + open.synctex = quoted; + } + /* Now add to open.synctex the first path extension. */ + if (open.synctex != strcat(open.synctex, synctex_suffix)) { + _synctex_error("! __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n", synctex_suffix); + goto return_on_error; + } + /* Add to quoteless_synctex_name as well, if relevant. */ + if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name, synctex_suffix))) { + free(quoteless_synctex_name); + quoteless_synctex_name = NULL; + } + if (NULL == (open.file = gzopen(open.synctex, mode))) { + /* Could not open this file */ + if (errno != ENOENT) { + /* The file does exist, this is a lower level error, I can't do anything. */ + _synctex_error("could not open %s, error %i\n", open.synctex, errno); + goto return_on_error; + } + /* Apparently, there is no uncompressed synctex file. Try the compressed version */ + if (open.synctex != strcat(open.synctex, synctex_suffix_gz)) { + _synctex_error("! __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n", synctex_suffix_gz); + goto return_on_error; + } + open.io_mode |= synctex_io_gz_mask; + mode = _synctex_get_io_mode_name(open.io_mode); /* the file is a compressed and is a binary file, this caused errors on Windows */ + /* Add the suffix to the quoteless_synctex_name as well. */ + if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name, synctex_suffix_gz))) { + free(quoteless_synctex_name); + quoteless_synctex_name = NULL; + } + if (NULL == (open.file = gzopen(open.synctex, mode))) { + /* Could not open this file */ + if (errno != ENOENT) { + /* The file does exist, this is a lower level error, I can't do anything. */ + _synctex_error("Could not open %s, error %i\n", open.synctex, errno); + } + goto return_on_error; + } + } + /* At this point, the file is properly open. + * If we are in the add_quotes mode, we change the file name by removing the quotes. */ + if (quoteless_synctex_name) { + gzclose(open.file); + if (rename(open.synctex, quoteless_synctex_name)) { + _synctex_error("Could not rename %s to %s, error %i\n", open.synctex, quoteless_synctex_name, errno); + /* We could not rename, reopen the file with the quoted name. */ + if (NULL == (open.file = gzopen(open.synctex, mode))) { + /* No luck, could not re open this file, something has happened meanwhile */ + if (errno != ENOENT) { + /* The file does not exist any more, it has certainly be removed somehow + * this is a lower level error, I can't do anything. */ + _synctex_error("Could not open again %s, error %i\n", open.synctex, errno); + } + goto return_on_error; + } + } else { + /* The file has been successfully renamed */ + if (NULL == (open.file = gzopen(quoteless_synctex_name, mode))) { + /* Could not open this file */ + if (errno != ENOENT) { + /* The file does exist, this is a lower level error, I can't do anything. */ + _synctex_error("Could not open renamed %s, error %i\n", quoteless_synctex_name, errno); + } + goto return_on_error; + } + /* The quote free file name should replace the old one:*/ + free(open.synctex); + open.synctex = quoteless_synctex_name; + quoteless_synctex_name = NULL; + } + } + /* The operation is successful, return the arguments by value. */ + open.status = SYNCTEX_STATUS_OK; + return open; +} + +/* Opens the output file, taking into account the eventual build_directory. + * - returns: an open structure which status is + * SYNCTEX_STATUS_OK on success, + * SYNCTEX_STATUS_ERROR on failure. + * - note: on success, the caller is the owner + * of the fields of the returned open structure. + */ +static synctex_open_s _synctex_open_v2(const char *output, const char *build_directory, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) +{ + synctex_open_s open = __synctex_open_v2(output, io_mode, add_quotes); + if (open.status == SYNCTEX_STATUS_OK) { + return open; + } + if (build_directory && strlen(build_directory)) { + char *build_output; + const char *lpc; + size_t size; + synctex_bool_t is_absolute; + build_output = NULL; + lpc = _synctex_last_path_component(output); + size = strlen(build_directory) + strlen(lpc) + 2; /* One for the '/' and one for the '\0'. */ + is_absolute = _synctex_path_is_absolute(build_directory); + if (!is_absolute) { + size += strlen(output); + } + if ((build_output = (char *)_synctex_malloc(size))) { + if (is_absolute) { + build_output[0] = '\0'; + } else { + if (build_output != strcpy(build_output, output)) { + _synctex_free(build_output); + return open; + } + build_output[lpc - output] = '\0'; + } + if (build_output == strcat(build_output, build_directory)) { + /* Append a path separator if necessary. */ + if (!SYNCTEX_IS_PATH_SEPARATOR(build_output[strlen(build_directory) - 1])) { + if (build_output != strcat(build_output, "/")) { + _synctex_free(build_output); + return open; + } + } + /* Append the last path component of the output. */ + if (build_output != strcat(build_output, lpc)) { + _synctex_free(build_output); + return open; + } + open = __synctex_open_v2(build_output, io_mode, add_quotes); + } + _synctex_free(build_output); + } /* if ((build_output... */ + } /* if (build_directory...) */ + return open; +} +void synctex_reader_free(synctex_reader_p reader) +{ + if (reader) { + _synctex_free(reader->output); + _synctex_free(reader->synctex); + _synctex_free(reader->start); + gzclose(reader->file); + _synctex_free(reader); + } +} +/* + * Return reader on success. + * Deallocate reader and return NULL on failure. + */ +synctex_reader_p synctex_reader_init_with_output_file(synctex_reader_p reader, const char *output, const char *build_directory) +{ + if (reader) { + /* now open the synctex file */ + synctex_open_s open = _synctex_open_v2(output, build_directory, 0, synctex_ADD_QUOTES); + if (open.status < SYNCTEX_STATUS_OK) { + open = _synctex_open_v2(output, build_directory, 0, synctex_DONT_ADD_QUOTES); + if (open.status < SYNCTEX_STATUS_OK) { + synctex_reader_free(reader); + return NULL; + } + } + reader->synctex = open.synctex; + reader->file = open.file; + /* make a private copy of output */ + if (NULL == (reader->output = (char *)_synctex_malloc(strlen(output) + 1))) { + _synctex_error("! synctex_scanner_new_with_output_file: Memory problem (2), reader's output is not reliable."); + } else if (reader->output != strcpy(reader->output, output)) { + _synctex_free(reader->output); + reader->output = NULL; + _synctex_error("! synctex_scanner_new_with_output_file: Copy problem, reader's output is not reliable."); + } + reader->start = reader->end = reader->current = NULL; + reader->min_size = SYNCTEX_BUFFER_MIN_SIZE; + reader->size = SYNCTEX_BUFFER_SIZE; + reader->start = reader->current = (char *)_synctex_malloc(reader->size + 1); /* one more character for null termination */ + if (NULL == reader->start) { + _synctex_error("! malloc error in synctex_reader_init_with_output_file."); +#ifdef SYNCTEX_DEBUG + return reader; +#else + synctex_reader_free(reader); + return NULL; +#endif + } + reader->end = reader->start + reader->size; + /* reader->end always points to a null terminating character. + * Maybe there is another null terminating character between reader->current and reader->end-1. + * At least, we are sure that reader->current points to a string covering a valid part of the memory. */ +#if defined(SYNCTEX_USE_CHARINDEX) + reader->charindex_offset = -reader->size; +#endif + } + return reader; +} + +#if defined(SYNCTEX_USE_HANDLE) +#define SYNCTEX_DECLARE_HANDLE synctex_node_p handle; +#else +#define SYNCTEX_DECLARE_HANDLE +#endif + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark SCANNER +#endif +/** + * The synctex scanner is the root object. + * Is is initialized with the contents of a text file or a gzipped file. + * The buffer_.* are first used to parse the text. + */ +struct synctex_scanner_t { + synctex_reader_p reader; + SYNCTEX_DECLARE_NODE_COUNT + SYNCTEX_DECLARE_HANDLE + char *output_fmt; /* dvi or pdf, not yet used */ + synctex_iterator_p iterator; /* result iterator */ + int version; /* 1, not yet used */ + struct { + unsigned has_parsed : 1; /* Whether the scanner has parsed its underlying synctex file. */ + unsigned postamble : 1; /* Whether the scanner has parsed its underlying synctex file. */ + unsigned reserved : sizeof(unsigned) - 2; /* alignment */ + } flags; + int pre_magnification; /* magnification from the synctex preamble */ + int pre_unit; /* unit from the synctex preamble */ + int pre_x_offset; /* X offset from the synctex preamble */ + int pre_y_offset; /* Y offset from the synctex preamble */ + int count; /* Number of records, from the synctex postamble */ + float unit; /* real unit, from synctex preamble or post scriptum */ + float x_offset; /* X offset, from synctex preamble or post scriptum */ + float y_offset; /* Y Offset, from synctex preamble or post scriptum */ + synctex_node_p input; /* The first input node, its siblings are the other input nodes */ + synctex_node_p sheet; /* The first sheet node, its siblings are the other sheet nodes */ + synctex_node_p form; /* The first form, its siblings are the other forms */ + synctex_node_p ref_in_sheet; /* The first form ref node in sheet, its friends are the other form ref nodes */ + synctex_node_p ref_in_form; /* The first form ref node, its friends are the other form ref nodes in sheet */ + int number_of_lists; /* The number of friend lists */ + synctex_node_r lists_of_friends; /* The friend lists */ + synctex_class_s class[synctex_node_number_of_types]; /* The classes of the nodes of the scanner */ + int display_switcher; + char *display_prompt; +}; + +/** + * Create a new node of the given type. + * - parameter scanner: of type synctex_node_p + * - parameter type: a type, the client is responsible + * to ask for an acceptable type. + */ +synctex_node_p synctex_node_new(synctex_scanner_p scanner, synctex_node_type_t type) +{ + return scanner ? scanner->class[type].new(scanner) : NULL; +} +#if defined(SYNCTEX_USE_HANDLE) +SYNCTEX_INLINE static void __synctex_scanner_free_handle(synctex_scanner_p scanner) +{ + synctex_node_free(scanner->handle); +} +SYNCTEX_INLINE static void __synctex_scanner_remove_handle_to(synctex_node_p node) +{ + synctex_node_p arg_sibling = NULL; + synctex_node_p handle = node->class->scanner->handle; + while (handle) { + synctex_node_p sibling; + if (node == _synctex_tree_target(handle)) { + sibling = __synctex_tree_reset_sibling(handle); + if (arg_sibling) { + __synctex_tree_set_sibling(arg_sibling, sibling); + } else { + node->class->scanner->handle = sibling; + } + synctex_node_free(handle); + break; + } else { + sibling = __synctex_tree_sibling(handle); + } + arg_sibling = handle; + handle = sibling; + } +} +SYNCTEX_INLINE static void __synctex_scanner_register_handle_to(synctex_node_p node) +{ + synctex_node_p NNN = _synctex_new_handle_with_target(node); + __synctex_tree_set_sibling(NNN, node->class->scanner->handle); + node->class->scanner->handle = NNN; +} +#endif +#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT > 10 +SYNCTEX_INLINE static void _synctex_did_new(synctex_node_p node) +{ + printf("NODE CREATED # %i, %s, %p\n", (node->class->scanner->node_count)++, synctex_node_isa(node), node); +} +SYNCTEX_INLINE static void _synctex_will_free(synctex_node_p node) +{ + printf("NODE DELETED # %i, %s, %p\n", --(node->class->scanner->node_count), synctex_node_isa(node), node); +} +#endif + +/** + * Free the given node. + * - parameter node: of type synctex_node_p + * - note: a node is meant to own its child and sibling. + * It is not owned by its parent, unless it is its first child. + * This destructor is for all nodes with children. + */ +static void _synctex_free_node(synctex_node_p node) +{ + if (node) { + SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node); + SYNCTEX_WILL_FREE(node); + synctex_node_free(__synctex_tree_sibling(node)); + synctex_node_free(_synctex_tree_child(node)); + _synctex_free(node); + } + return; +} + +/** + * Free the given leaf node. + * - parameter node: of type synctex_node_p, with no child nor sibling. + * - note: a node is meant to own its child and sibling. + * It is not owned by its parent, unless it is its first child. + * This destructor is for all nodes with no children. + */ +static void _synctex_free_leaf(synctex_node_p node) +{ + if (node) { + SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node); + SYNCTEX_WILL_FREE(node); + synctex_node_free(__synctex_tree_sibling(node)); + _synctex_free(node); + } + return; +} + +/** + SYNCTEX_CUR, SYNCTEX_START and SYNCTEX_END are convenient shortcuts + */ +#define SYNCTEX_CUR (scanner->reader->current) +#define SYNCTEX_START (scanner->reader->start) +#define SYNCTEX_END (scanner->reader->end) + +/* Here are gathered all the possible status that the next scanning functions will return. + * All these functions return a status, and pass their result through pointers. + * Negative values correspond to errors. + * The management of the buffer is causing some significant overhead. + * Every function that may access the buffer returns a status related to the buffer and file state. + * status >= SYNCTEX_STATUS_OK means the function worked as expected + * status < SYNCTEX_STATUS_OK means the function did not work as expected + * status == SYNCTEX_STATUS_NOT_OK means the function did not work as expected but there is still some material to parse. + * status == SYNCTEX_STATUS_EOF means the function did not work as expected and there is no more material. + * statushandle : NULL; +} +#endif + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Decoding prototypes +#endif + +typedef struct { + int integer; + synctex_status_t status; +} synctex_is_s; + +static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner); +static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value); +static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner); + +typedef struct { + char *string; + synctex_status_t status; +} synctex_ss_s; + +static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner); + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Data SETGET +#endif + +/** + * The next macros are used to access the node data info + * through the class modelator integer fields. + * - parameter NODE: of type synctex_node_p + */ +#define SYNCTEX_DATA(NODE) ((*((((NODE)->class))->info))(NODE)) +#if defined SYNCTEX_DEBUG > 1000 +#define DEFINE_SYNCTEX_DATA_HAS(WHAT) \ + SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) \ + { \ + return (node && (node->class->modelator->WHAT >= 0)); \ + } \ + SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) \ + { \ + if (node && (node->class->modelator->WHAT < 0)) { \ + printf("WARNING: NO %s for %s\n", #WHAT, synctex_node_isa(node)); \ + } \ + return __synctex_data_has_##WHAT(node); \ + } +#else +#define DEFINE_SYNCTEX_DATA_HAS(WHAT) \ + SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) \ + { \ + return (node && (node->class->modelator->WHAT >= 0)); \ + } \ + SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) \ + { \ + return __synctex_data_has_##WHAT(node); \ + } +#endif + +SYNCTEX_INLINE static synctex_data_p __synctex_data(synctex_node_p node) +{ + return node->data + node->class->navigator->size; +} +#define DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \ + DEFINE_SYNCTEX_DATA_HAS(WHAT) \ + static int _synctex_data_##WHAT(synctex_node_p node) \ + { \ + if (_synctex_data_has_##WHAT(node)) { \ + return __synctex_data(node)[node->class->modelator->WHAT].as_integer; \ + } \ + return 0; \ + } \ + static int _synctex_data_set_##WHAT(synctex_node_p node, int new_value) \ + { \ + int old = 0; \ + if (_synctex_data_has_##WHAT(node)) { \ + old = __synctex_data(node)[node->class->modelator->WHAT].as_integer; \ + __synctex_data(node)[node->class->modelator->WHAT].as_integer = new_value; \ + } \ + return old; \ + } +#define DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT) \ + static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) \ + { \ + if (_synctex_data_has_##WHAT(node)) { \ + synctex_is_s is = _synctex_decode_int(node->class->scanner); \ + if (is.status == SYNCTEX_STATUS_OK) { \ + _synctex_data_set_##WHAT(node, is.integer); \ + } \ + return is.status; \ + } \ + return SYNCTEX_STATUS_BAD_ARGUMENT; \ + } +#define DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT) \ + static synctex_status_t _synctex_data_decode_##WHAT##_v(synctex_node_p node) \ + { \ + if (_synctex_data_has_##WHAT(node)) { \ + synctex_is_s is = _synctex_decode_int_v(node->class->scanner); \ + if (is.status == SYNCTEX_STATUS_OK) { \ + _synctex_data_set_##WHAT(node, is.integer); \ + } \ + return is.status; \ + } \ + return SYNCTEX_STATUS_BAD_ARGUMENT; \ + } +#define DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \ + DEFINE_SYNCTEX_DATA_HAS(WHAT) \ + static char *_synctex_data_##WHAT(synctex_node_p node) \ + { \ + if (_synctex_data_has_##WHAT(node)) { \ + return node->data[node->class->navigator->size + node->class->modelator->WHAT].as_string; \ + } \ + return NULL; \ + } \ + static char *_synctex_data_set_##WHAT(synctex_node_p node, char *new_value) \ + { \ + char *old = ""; \ + if (_synctex_data_has_##WHAT(node)) { \ + old = node->data[node->class->navigator->size + node->class->modelator->WHAT].as_string; \ + node->data[node->class->navigator->size + node->class->modelator->WHAT].as_string = new_value; \ + } \ + return old; \ + } +#define DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT) \ + static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) \ + { \ + if (_synctex_data_has_##WHAT(node)) { \ + synctex_ss_s ss = _synctex_decode_string(node->class->scanner); \ + if (ss.status == SYNCTEX_STATUS_OK) { \ + _synctex_data_set_##WHAT(node, ss.string); \ + } \ + return ss.status; \ + } \ + return SYNCTEX_STATUS_BAD_ARGUMENT; \ + } +#define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(WHAT) \ + DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \ + DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT) +#define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(WHAT) \ + DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \ + DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT) +#define DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(WHAT) \ + DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \ + DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT) + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark OBJECTS, their creators and destructors. +#endif + +#ifdef SYNCTEX_NOTHING +#pragma mark input. +#endif + +DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(tag) +DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(line) +DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(name) + +/* Input nodes only know about their sibling, which is another input node. + * The synctex information is the _synctex_data_tag and _synctex_data_name + * note: the input owns its name. */ + +#define SYNCTEX_INPUT_MARK "Input:" + +static const synctex_tree_model_s synctex_tree_model_input = {synctex_tree_sibling_idx, /* sibling */ + -1, /* parent */ + -1, /* child */ + -1, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + -1, /* target */ + synctex_tree_s_input_max}; +static const synctex_data_model_s synctex_data_model_input = {synctex_data_input_tag_idx, /* tag */ + synctex_data_input_line_idx, /* line */ + -1, /* column */ + -1, /* h */ + -1, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + synctex_data_input_name_idx, /* name */ + -1, /* page */ + synctex_data_input_tln_max}; + +#define SYNCTEX_INSPECTOR_GETTER_F(WHAT) &_synctex_data_##WHAT, &_synctex_data_set_##WHAT + +static synctex_node_p _synctex_new_input(synctex_scanner_p scanner); +static void _synctex_free_input(synctex_node_p node); +static void _synctex_log_input(synctex_node_p node); +static char *_synctex_abstract_input(synctex_node_p node); +static void _synctex_display_input(synctex_node_p node); + +static const synctex_tlcpector_s synctex_tlcpector_input = { + &_synctex_data_tag, /* tag */ + &_synctex_int_none, /* line */ + &_synctex_int_none, /* column */ +}; + +static synctex_class_s synctex_class_input = { + NULL, /* No scanner yet */ + synctex_node_type_input, /* Node type */ + &_synctex_new_input, /* creator */ + &_synctex_free_input, /* destructor */ + &_synctex_log_input, /* log */ + &_synctex_display_input, /* display */ + &_synctex_abstract_input, /* abstract */ + &synctex_tree_model_input, /* tree model */ + &synctex_data_model_input, /* data model */ + &synctex_tlcpector_input, /* inspector */ + &synctex_inspector_none, /* inspector */ + &synctex_vispector_none, /* vispector */ +}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_s_input_max + synctex_data_input_tln_max]; +} synctex_input_s; + +static synctex_node_p _synctex_new_input(synctex_scanner_p scanner) +{ + if (scanner) { + synctex_node_p node = _synctex_malloc(sizeof(synctex_input_s)); + if (node) { + node->class = scanner->class + synctex_node_type_input; + SYNCTEX_DID_NEW(node); + SYNCTEX_IMPLEMENT_CHARINDEX(node, 0); + SYNCTEX_REGISTER_HANDLE_TO(node); + } + return node; + } + return NULL; +} + +static void _synctex_free_input(synctex_node_p node) +{ + if (node) { + SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node); + SYNCTEX_WILL_FREE(node); + synctex_node_free(__synctex_tree_sibling(node)); + _synctex_free(_synctex_data_name(node)); + _synctex_free(node); + } +} + +/* The sheet is a first level node. + * It has no parent (the owner is the scanner itself) + * Its sibling points to another sheet. + * Its child points to its first child, in general a box. + * A sheet node contains only one synctex information: the page. + * This is the 1 based page index as given by TeX. + */ + +#ifdef SYNCTEX_NOTHING +#pragma mark sheet. +#endif +/** + * Every node has the same structure, but not the same size. + */ + +DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(page) + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_scn_sheet_max + synctex_data_p_sheet_max]; +} synctex_node_sheet_s; + +/* sheet node creator */ + +#define DEFINE_synctex_new_scanned_NODE(NAME) \ + static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) \ + { \ + if (scanner) { \ + ++SYNCTEX_CUR; \ + synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s)); \ + if (node) { \ + node->class = scanner->class + synctex_node_type_##NAME; \ + SYNCTEX_DID_NEW(node); \ + SYNCTEX_IMPLEMENT_CHARINDEX(node, -1); \ + SYNCTEX_REGISTER_HANDLE_TO(node); \ + } \ + return node; \ + } \ + return NULL; \ + } +/* NB: -1 in SYNCTEX_IMPLEMENT_CHARINDEX above because + * the first char of the line has been scanned + */ +DEFINE_synctex_new_scanned_NODE(sheet) static void _synctex_log_sheet(synctex_node_p node); +static char *_synctex_abstract_sheet(synctex_node_p node); +static void _synctex_display_sheet(synctex_node_p node); + +static const synctex_tree_model_s synctex_tree_model_sheet = {synctex_tree_sibling_idx, /* sibling */ + -1, /* parent */ + synctex_tree_s_child_idx, /* child */ + -1, /* friend */ + -1, /* last */ + synctex_tree_sc_next_hbox_idx, /* next_hbox */ + -1, /* arg_sibling */ + -1, /* target */ + synctex_tree_scn_sheet_max}; +static const synctex_data_model_s synctex_data_model_sheet = {-1, /* tag */ + -1, /* line */ + -1, /* column */ + -1, /* h */ + -1, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + synctex_data_sheet_page_idx, /* page */ + synctex_data_p_sheet_max}; +static synctex_class_s synctex_class_sheet = { + NULL, /* No scanner yet */ + synctex_node_type_sheet, /* Node type */ + &_synctex_new_sheet, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_sheet, /* log */ + &_synctex_display_sheet, /* display */ + &_synctex_abstract_sheet, /* abstract */ + &synctex_tree_model_sheet, /* tree model */ + &synctex_data_model_sheet, /* data model */ + &synctex_tlcpector_none, /* tlcpector */ + &synctex_inspector_none, /* inspector */ + &synctex_vispector_none, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark form. +#endif +/** + * Every node has the same structure, but not the same size. + */ +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_sct_form_max + synctex_data_t_form_max]; +} synctex_node_form_s; + +DEFINE_synctex_new_scanned_NODE(form) + + static char *_synctex_abstract_form(synctex_node_p node); +static void _synctex_display_form(synctex_node_p node); +static void _synctex_log_form(synctex_node_p node); + +static const synctex_tree_model_s synctex_tree_model_form = {synctex_tree_sibling_idx, /* sibling */ + -1, /* parent */ + synctex_tree_s_child_idx, /* child */ + -1, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + synctex_tree_sc_target_idx, /* target */ + synctex_tree_sct_form_max}; +static const synctex_data_model_s synctex_data_model_form = {synctex_data_form_tag_idx, /* tag */ + -1, /* line */ + -1, /* column */ + -1, /* h */ + -1, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_t_form_max}; +static synctex_class_s synctex_class_form = { + NULL, /* No scanner yet */ + synctex_node_type_form, /* Node type */ + &_synctex_new_form, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_form, /* log */ + &_synctex_display_form, /* display */ + &_synctex_abstract_form, /* abstract */ + &synctex_tree_model_form, /* tree model */ + &synctex_data_model_form, /* data model */ + &synctex_tlcpector_none, /* tlcpector */ + &synctex_inspector_none, /* inspector */ + &synctex_vispector_none, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark vbox. +#endif + +/* A box node contains navigation and synctex information + * There are different kinds of boxes. + * Only horizontal boxes are treated differently because of their visible size. + */ +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spcfl_vbox_max + synctex_data_box_max]; +} synctex_node_vbox_s; + +/* vertical box node creator */ +DEFINE_synctex_new_scanned_NODE(vbox) + + static char *_synctex_abstract_vbox(synctex_node_p node); +static void _synctex_display_vbox(synctex_node_p node); +static void _synctex_log_vbox(synctex_node_p node); + +static const synctex_tree_model_s synctex_tree_model_vbox = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + synctex_tree_sp_child_idx, /* child */ + synctex_tree_spc_friend_idx, /* friend */ + synctex_tree_spcf_last_idx, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + -1, /* target */ + synctex_tree_spcfl_vbox_max}; + +DEFINE_SYNCTEX_DATA_INT_GETSET(column) +static synctex_status_t _synctex_data_decode_column(synctex_node_p node) +{ + if (_synctex_data_has_column(node)) { + synctex_is_s is = _synctex_decode_int_opt(node->class->scanner, -1); + if (is.status == SYNCTEX_STATUS_OK) { + _synctex_data_set_column(node, is.integer); + } + return is.status; + } + return SYNCTEX_STATUS_BAD_ARGUMENT; +} +DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(h) +DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(v) DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(width) DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(height) DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(depth) + + static const synctex_data_model_s synctex_data_model_box = {synctex_data_tag_idx, /* tag */ + synctex_data_line_idx, /* line */ + synctex_data_column_idx, /* column */ + synctex_data_h_idx, /* h */ + synctex_data_v_idx, /* v */ + synctex_data_width_idx, /* width */ + synctex_data_height_idx, /* height */ + synctex_data_depth_idx, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_box_max}; +static const synctex_tlcpector_s synctex_tlcpector_default = { + &_synctex_data_tag, /* tag */ + &_synctex_data_line, /* line */ + &_synctex_data_column, /* column */ +}; +static const synctex_inspector_s synctex_inspector_box = { + &_synctex_data_h, + &_synctex_data_v, + &_synctex_data_width, + &_synctex_data_height, + &_synctex_data_depth, +}; +static float __synctex_node_visible_h(synctex_node_p node); +static float __synctex_node_visible_v(synctex_node_p node); +static float __synctex_node_visible_width(synctex_node_p node); +static float __synctex_node_visible_height(synctex_node_p node); +static float __synctex_node_visible_depth(synctex_node_p node); +static synctex_vispector_s synctex_vispector_box = { + &__synctex_node_visible_h, + &__synctex_node_visible_v, + &__synctex_node_visible_width, + &__synctex_node_visible_height, + &__synctex_node_visible_depth, +}; +/* These are static class objects, each scanner will make a copy of them and setup the scanner field. + */ +static synctex_class_s synctex_class_vbox = { + NULL, /* No scanner yet */ + synctex_node_type_vbox, /* Node type */ + &_synctex_new_vbox, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_vbox, /* log */ + &_synctex_display_vbox, /* display */ + &_synctex_abstract_vbox, /* abstract */ + &synctex_tree_model_vbox, /* tree model */ + &synctex_data_model_box, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_box, /* inspector */ + &synctex_vispector_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark hbox. +#endif + +/* Horizontal boxes must contain visible size, because 0 width does not mean emptiness. + * They also contain an average of the line numbers of the containing nodes. */ + +static const synctex_tree_model_s synctex_tree_model_hbox = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + synctex_tree_sp_child_idx, /* child */ + synctex_tree_spc_friend_idx, /* friend */ + synctex_tree_spcf_last_idx, /* last */ + synctex_tree_spcfl_next_hbox_idx, /* next_hbox */ + -1, /* arg_sibling */ + -1, /* target */ + synctex_tree_spcfln_hbox_max}; + +DEFINE_SYNCTEX_DATA_INT_GETSET(mean_line) +DEFINE_SYNCTEX_DATA_INT_GETSET(weight) +DEFINE_SYNCTEX_DATA_INT_GETSET(h_V) +DEFINE_SYNCTEX_DATA_INT_GETSET(v_V) +DEFINE_SYNCTEX_DATA_INT_GETSET(width_V) +DEFINE_SYNCTEX_DATA_INT_GETSET(height_V) +DEFINE_SYNCTEX_DATA_INT_GETSET(depth_V) + +/** + * The hbox model. + * It contains V variants of geometrical information. + * It happens that hboxes contain material that is not used to compute + * the bounding box. Some letters may appear out of the box given by TeX. + * In such a situation, the visible bounding box is bigger than the V variant. + * Only hboxes have such variant. It does not make sense for void boxes + * and it is not used here for vboxes. + * - author: JL + */ + +static const synctex_data_model_s synctex_data_model_hbox = {synctex_data_tag_idx, /* tag */ + synctex_data_line_idx, /* line */ + synctex_data_column_idx, /* column */ + synctex_data_h_idx, /* h */ + synctex_data_v_idx, /* v */ + synctex_data_width_idx, /* width */ + synctex_data_height_idx, /* height */ + synctex_data_depth_idx, /* depth */ + synctex_data_mean_line_idx, /* mean_line */ + synctex_data_weight_idx, /* weight */ + synctex_data_h_V_idx, /* h_V */ + synctex_data_v_V_idx, /* v_V */ + synctex_data_width_V_idx, /* width_V */ + synctex_data_height_V_idx, /* height_V */ + synctex_data_depth_V_idx, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_hbox_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spcfln_hbox_max + synctex_data_hbox_max]; +} synctex_node_hbox_s; + +/* horizontal box node creator */ +DEFINE_synctex_new_scanned_NODE(hbox) + + static void _synctex_log_hbox(synctex_node_p node); +static char *_synctex_abstract_hbox(synctex_node_p node); +static void _synctex_display_hbox(synctex_node_p node); + +static synctex_class_s synctex_class_hbox = { + NULL, /* No scanner yet */ + synctex_node_type_hbox, /* Node type */ + &_synctex_new_hbox, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_hbox, /* log */ + &_synctex_display_hbox, /* display */ + &_synctex_abstract_hbox, /* abstract */ + &synctex_tree_model_hbox, /* tree model */ + &synctex_data_model_hbox, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_box, /* inspector */ + &synctex_vispector_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark void vbox. +#endif + +/* This void box node implementation is either horizontal or vertical + * It does not contain a child field. + */ +static const synctex_tree_model_s synctex_tree_model_spf = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + -1, /* child */ + synctex_tree_sp_friend_idx, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + -1, /* target */ + synctex_tree_spf_max}; +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spf_max + synctex_data_box_max]; +} synctex_node_void_vbox_s; + +/* vertical void box node creator */ +DEFINE_synctex_new_scanned_NODE(void_vbox) + + static void _synctex_log_void_box(synctex_node_p node); +static char *_synctex_abstract_void_vbox(synctex_node_p node); +static void _synctex_display_void_vbox(synctex_node_p node); + +static synctex_class_s synctex_class_void_vbox = { + NULL, /* No scanner yet */ + synctex_node_type_void_vbox, /* Node type */ + &_synctex_new_void_vbox, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_void_box, /* log */ + &_synctex_display_void_vbox, /* display */ + &_synctex_abstract_void_vbox, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_box, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_box, /* inspector */ + &synctex_vispector_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark void hbox. +#endif + +typedef synctex_node_void_vbox_s synctex_node_void_hbox_s; + +/* horizontal void box node creator */ +DEFINE_synctex_new_scanned_NODE(void_hbox) + + static char *_synctex_abstract_void_hbox(synctex_node_p node); +static void _synctex_display_void_hbox(synctex_node_p node); + +static synctex_class_s synctex_class_void_hbox = { + NULL, /* No scanner yet */ + synctex_node_type_void_hbox, /* Node type */ + &_synctex_new_void_hbox, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_void_box, /* log */ + &_synctex_display_void_hbox, /* display */ + &_synctex_abstract_void_hbox, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_box, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_box, /* inspector */ + &synctex_vispector_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark form ref. +#endif + +/* The form ref node. */ +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spfa_max + synctex_data_ref_thv_max]; +} synctex_node_ref_s; + +/* form ref node creator */ +DEFINE_synctex_new_scanned_NODE(ref) + + static void _synctex_log_ref(synctex_node_p node); +static char *_synctex_abstract_ref(synctex_node_p node); +static void _synctex_display_ref(synctex_node_p node); + +static const synctex_tree_model_s synctex_tree_model_spfa = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + -1, /* child */ + synctex_tree_sp_friend_idx, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + synctex_tree_spf_arg_sibling_idx, /* arg_sibling */ + -1, /* target */ + synctex_tree_spfa_max}; +static const synctex_data_model_s synctex_data_model_ref = {synctex_data_tag_idx, /* tag */ + -1, /* line */ + -1, /* column */ + synctex_data_ref_h_idx, /* h */ + synctex_data_ref_v_idx, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + synctex_data_ref_thv_max}; +static synctex_class_s synctex_class_ref = { + NULL, /* No scanner yet */ + synctex_node_type_ref, /* Node type */ + &_synctex_new_ref, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_ref, /* log */ + &_synctex_display_ref, /* display */ + &_synctex_abstract_ref, /* abstract */ + &synctex_tree_model_spfa, /* navigator */ + &synctex_data_model_ref, /* data model */ + &synctex_tlcpector_none, /* tlcpector */ + &synctex_inspector_none, /* inspector */ + &synctex_vispector_none, /* vispector */ +}; +#ifdef SYNCTEX_NOTHING +#pragma mark small node. +#endif + +/* The small nodes correspond to glue, penalty, math and boundary nodes. */ +static const synctex_data_model_s synctex_data_model_tlchv = {synctex_data_tag_idx, /* tag */ + synctex_data_line_idx, /* line */ + synctex_data_column_idx, /* column */ + synctex_data_h_idx, /* h */ + synctex_data_v_idx, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_tlchv_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spf_max + synctex_data_tlchv_max]; +} synctex_node_tlchv_s; + +static void _synctex_log_tlchv_node(synctex_node_p node); + +#ifdef SYNCTEX_NOTHING +#pragma mark math. +#endif + +typedef synctex_node_tlchv_s synctex_node_math_s; + +/* math node creator */ +DEFINE_synctex_new_scanned_NODE(math) + + static char *_synctex_abstract_math(synctex_node_p node); +static void _synctex_display_math(synctex_node_p node); +static synctex_inspector_s synctex_inspector_hv = { + &_synctex_data_h, + &_synctex_data_v, + &_synctex_int_none, + &_synctex_int_none, + &_synctex_int_none, +}; +static synctex_vispector_s synctex_vispector_hv = { + &__synctex_node_visible_h, + &__synctex_node_visible_v, + &_synctex_float_none, + &_synctex_float_none, + &_synctex_float_none, +}; + +static synctex_class_s synctex_class_math = { + NULL, /* No scanner yet */ + synctex_node_type_math, /* Node type */ + &_synctex_new_math, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_tlchv_node, /* log */ + &_synctex_display_math, /* display */ + &_synctex_abstract_math, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_tlchv, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_hv, /* inspector */ + &synctex_vispector_hv, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark kern node. +#endif + +static const synctex_data_model_s synctex_data_model_tlchvw = {synctex_data_tag_idx, /* tag */ + synctex_data_line_idx, /* line */ + synctex_data_column_idx, /* column */ + synctex_data_h_idx, /* h */ + synctex_data_v_idx, /* v */ + synctex_data_width_idx, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_tlchvw_max}; +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spf_max + synctex_data_tlchvw_max]; +} synctex_node_kern_s; + +/* kern node creator */ +DEFINE_synctex_new_scanned_NODE(kern) + + static void _synctex_log_kern_node(synctex_node_p node); +static char *_synctex_abstract_kern(synctex_node_p node); +static void _synctex_display_kern(synctex_node_p node); + +static synctex_inspector_s synctex_inspector_kern = { + &_synctex_data_h, + &_synctex_data_v, + &_synctex_data_width, + &_synctex_int_none, + &_synctex_int_none, +}; +static float __synctex_kern_visible_h(synctex_node_p node); +static float __synctex_kern_visible_width(synctex_node_p node); +static synctex_vispector_s synctex_vispector_kern = { + &__synctex_kern_visible_h, + &__synctex_node_visible_v, + &__synctex_kern_visible_width, + &_synctex_float_none, + &_synctex_float_none, +}; + +static synctex_class_s synctex_class_kern = { + NULL, /* No scanner yet */ + synctex_node_type_kern, /* Node type */ + &_synctex_new_kern, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_kern_node, /* log */ + &_synctex_display_kern, /* display */ + &_synctex_abstract_kern, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_tlchvw, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_kern, /* inspector */ + &synctex_vispector_kern, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark glue. +#endif + +/* glue node creator */ +typedef synctex_node_tlchv_s synctex_node_glue_s; +DEFINE_synctex_new_scanned_NODE(glue) + + static char *_synctex_abstract_glue(synctex_node_p node); +static void _synctex_display_glue(synctex_node_p node); + +static synctex_class_s synctex_class_glue = { + NULL, /* No scanner yet */ + synctex_node_type_glue, /* Node type */ + &_synctex_new_glue, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_tlchv_node, /* log */ + &_synctex_display_glue, /* display */ + &_synctex_abstract_glue, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_tlchv, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_hv, /* inspector */ + &synctex_vispector_hv, /* vispector */ +}; + +/* The small nodes correspond to glue and boundary nodes. */ + +#ifdef SYNCTEX_NOTHING +#pragma mark rule. +#endif + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spf_max + synctex_data_box_max]; +} synctex_node_rule_s; + +DEFINE_synctex_new_scanned_NODE(rule) + + static void _synctex_log_rule(synctex_node_p node); +static char *_synctex_abstract_rule(synctex_node_p node); +static void _synctex_display_rule(synctex_node_p node); + +static float __synctex_rule_visible_h(synctex_node_p node); +static float __synctex_rule_visible_v(synctex_node_p node); +static float __synctex_rule_visible_width(synctex_node_p node); +static float __synctex_rule_visible_height(synctex_node_p node); +static float __synctex_rule_visible_depth(synctex_node_p node); +static synctex_vispector_s synctex_vispector_rule = { + &__synctex_rule_visible_h, + &__synctex_rule_visible_v, + &__synctex_rule_visible_width, + &__synctex_rule_visible_height, + &__synctex_rule_visible_depth, +}; + +static synctex_class_s synctex_class_rule = { + NULL, /* No scanner yet */ + synctex_node_type_rule, /* Node type */ + &_synctex_new_rule, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_rule, /* log */ + &_synctex_display_rule, /* display */ + &_synctex_abstract_rule, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_box, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_box, /* inspector */ + &synctex_vispector_rule, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark boundary. +#endif + +/* boundary node creator */ +typedef synctex_node_tlchv_s synctex_node_boundary_s; +DEFINE_synctex_new_scanned_NODE(boundary) + + static char *_synctex_abstract_boundary(synctex_node_p node); +static void _synctex_display_boundary(synctex_node_p node); + +static synctex_class_s synctex_class_boundary = { + NULL, /* No scanner yet */ + synctex_node_type_boundary, /* Node type */ + &_synctex_new_boundary, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_tlchv_node, /* log */ + &_synctex_display_boundary, /* display */ + &_synctex_abstract_boundary, /* abstract */ + &synctex_tree_model_spf, /* tree model */ + &synctex_data_model_tlchv, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_hv, /* inspector */ + &synctex_vispector_hv, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark box boundary. +#endif + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spfa_max + synctex_data_tlchv_max]; +} synctex_node_box_bdry_s; + +#define DEFINE_synctex_new_unscanned_NODE(NAME) \ + SYNCTEX_INLINE static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) \ + { \ + if (scanner) { \ + synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s)); \ + if (node) { \ + node->class = scanner->class + synctex_node_type_##NAME; \ + SYNCTEX_DID_NEW(node); \ + } \ + return node; \ + } \ + return NULL; \ + } +DEFINE_synctex_new_unscanned_NODE(box_bdry) + + static char *_synctex_abstract_box_bdry(synctex_node_p node); +static void _synctex_display_box_bdry(synctex_node_p node); + +static synctex_class_s synctex_class_box_bdry = { + NULL, /* No scanner yet */ + synctex_node_type_box_bdry, /* Node type */ + &_synctex_new_box_bdry, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_tlchv_node, /* log */ + &_synctex_display_box_bdry, /* display */ + &_synctex_abstract_box_bdry, /* display */ + &synctex_tree_model_spfa, /* tree model */ + &synctex_data_model_tlchv, /* data model */ + &synctex_tlcpector_default, /* tlcpector */ + &synctex_inspector_hv, /* inspector */ + &synctex_vispector_hv, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark hbox proxy. +#endif + +/** + * Standard nodes refer to TeX nodes: math, kern, boxes... + * Proxy nodes are used to support forms. + * A form is parsed as a tree of standard nodes starting + * at the top left position. + * When a reference is used, the form is duplicated + * to the location specified by the reference. + * As the same form can be duplicated at different locations, + * the geometrical information is relative to its own top left point. + * As we need absolute locations, we use proxy nodes. + * A proxy node records an offset and the target node. + * The target partly acts as a delegate. + * The h and v position of the proxy node is the h and v + * position of the target shifted by the proxy's offset. + * The width, height and depth are not sensitive to offsets. + * When are proxies created ? + * 1) when the synctex file has been parsed, all the form refs + * are replaced by proxies to the content of a form. + * This content is a node with siblings (actually none). + * Those root proxies have the parent of the ref they replace, + * so their parents exist and are no proxy. + * Moreover, if they have no sibling, it means that their target have no + * sibling as well. + * Such nodes are called root proxies. + * 2) On the fly, when a proxy is asked for its child + * (or sibling) and has none, a proxy to its target's child + * (or sibling) is created if any. There are only 2 possible situations: + * either the newly created proxy is the child of a proxy, + * or it is the sibling of a proxy created on the fly. + * In both cases, the parent is a proxy with children. + * Such nodes are called child proxies. + * How to compute the offset of a proxy ? + * The offset of root proxy objects is exactly + * the offset of the ref they replace. + * The offset of other proxies is their owner's, + * except when pointing to a root proxy. + * What happens for cascading forms ? + * Here is an example diagram + * + * At parse time, the arrow means "owns": + * sheet0 -> ref_to1 + * + * target1 -> ref_to2 + * + * target2 -> child22 + * + * After replacing the refs: + * sheet0 -> proxy00 -> proxy01 -> proxy02 + * | | | + * target1 -> proxy11 -> proxy12 + * | | + * target2 -> proxy22 + * + * proxy00, proxy11 and proxy22 are root proxies. + * Their offset is the one of the ref they replace + * proxy01, proxy02 and proxy12 are child proxies. + * Their proxy is the one of their parent. + * Optimization. + * After all the refs are replaced, there are only root nodes + * targeting standard node. We make sure that each child proxy + * also targets a standard node. + * It is possible for a proxy to have a standard sibling + * whereas its target has no sibling at all. Root proxies + * are such nodes, and are the only ones. + * The consequence is that proxies created on the fly + * must take into account this situation. + */ + +/* A proxy to a hbox. + * A proxy do have a target, which can be a proxy + */ + +static const synctex_tree_model_s synctex_tree_model_proxy_hbox = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + synctex_tree_sp_child_idx, /* child */ + synctex_tree_spc_friend_idx, /* friend */ + synctex_tree_spcf_last_idx, /* last */ + synctex_tree_spcfl_next_hbox_idx, /* next_hbox */ + -1, /* arg_sibling */ + synctex_tree_spcfln_target_idx, /* target */ + synctex_tree_spcflnt_proxy_hbox_max}; +static const synctex_data_model_s synctex_data_model_proxy = {-1, /* tag */ + -1, /* line */ + -1, /* column */ + synctex_data_proxy_h_idx, /* h */ + synctex_data_proxy_v_idx, /* v */ + -1, /* width */ + -1, /* height */ + -1, /* depth */ + -1, /* mean_line */ + -1, /* weight */ + -1, /* h_V */ + -1, /* v_V */ + -1, /* width_V */ + -1, /* height_V */ + -1, /* depth_V */ + -1, /* name */ + -1, /* page */ + synctex_data_proxy_hv_max}; +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spcflnt_proxy_hbox_max + synctex_data_proxy_hv_max]; +} synctex_node_proxy_hbox_s; + +/* box proxy node creator */ +DEFINE_synctex_new_unscanned_NODE(proxy_hbox) + + static void _synctex_log_proxy(synctex_node_p node); +static char *_synctex_abstract_proxy_hbox(synctex_node_p node); +static void _synctex_display_proxy_hbox(synctex_node_p node); + +static int _synctex_proxy_tag(synctex_node_p); +static int _synctex_proxy_line(synctex_node_p); +static int _synctex_proxy_column(synctex_node_p); + +static synctex_tlcpector_s synctex_tlcpector_proxy = { + &_synctex_proxy_tag, + &_synctex_proxy_line, + &_synctex_proxy_column, +}; +static int _synctex_proxy_h(synctex_node_p); +static int _synctex_proxy_v(synctex_node_p); +static int _synctex_proxy_width(synctex_node_p); +static int _synctex_proxy_height(synctex_node_p); +static int _synctex_proxy_depth(synctex_node_p); +static synctex_inspector_s synctex_inspector_proxy_box = { + &_synctex_proxy_h, + &_synctex_proxy_v, + &_synctex_proxy_width, + &_synctex_proxy_height, + &_synctex_proxy_depth, +}; + +static float __synctex_proxy_visible_h(synctex_node_p); +static float __synctex_proxy_visible_v(synctex_node_p); +static float __synctex_proxy_visible_width(synctex_node_p); +static float __synctex_proxy_visible_height(synctex_node_p); +static float __synctex_proxy_visible_depth(synctex_node_p); + +static synctex_vispector_s synctex_vispector_proxy_box = { + &__synctex_proxy_visible_h, + &__synctex_proxy_visible_v, + &__synctex_proxy_visible_width, + &__synctex_proxy_visible_height, + &__synctex_proxy_visible_depth, +}; + +static synctex_class_s synctex_class_proxy_hbox = { + NULL, /* No scanner yet */ + synctex_node_type_proxy_hbox, /* Node type */ + &_synctex_new_proxy_hbox, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_proxy, /* log */ + &_synctex_display_proxy_hbox, /* display */ + &_synctex_abstract_proxy_hbox, /* abstract */ + &synctex_tree_model_proxy_hbox, /* tree model */ + &synctex_data_model_proxy, /* data model */ + &synctex_tlcpector_proxy, /* tlcpector */ + &synctex_inspector_proxy_box, /* inspector */ + &synctex_vispector_proxy_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark vbox proxy. +#endif + +/* A proxy to a vbox. */ + +static const synctex_tree_model_s synctex_tree_model_proxy_vbox = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + synctex_tree_sp_child_idx, /* child */ + synctex_tree_spc_friend_idx, /* friend */ + synctex_tree_spcf_last_idx, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + synctex_tree_spcfl_target_idx, /* target */ + synctex_tree_spcflt_proxy_vbox_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spcflt_proxy_vbox_max + synctex_data_proxy_hv_max]; +} synctex_node_proxy_vbox_s; + +/* box proxy node creator */ +DEFINE_synctex_new_unscanned_NODE(proxy_vbox) + + static void _synctex_log_proxy(synctex_node_p node); +static char *_synctex_abstract_proxy_vbox(synctex_node_p node); +static void _synctex_display_proxy_vbox(synctex_node_p node); + +static synctex_class_s synctex_class_proxy_vbox = { + NULL, /* No scanner yet */ + synctex_node_type_proxy_vbox, /* Node type */ + &_synctex_new_proxy_vbox, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_proxy, /* log */ + &_synctex_display_proxy_vbox, /* display */ + &_synctex_abstract_proxy_vbox, /* abstract */ + &synctex_tree_model_proxy_vbox, /* tree model */ + &synctex_data_model_proxy, /* data model */ + &synctex_tlcpector_proxy, /* tlcpector */ + &synctex_inspector_proxy_box, /* inspector */ + &synctex_vispector_proxy_box, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark proxy. +#endif + +/** + * A proxy to a node but a box. + */ + +static const synctex_tree_model_s synctex_tree_model_proxy = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + -1, /* child */ + synctex_tree_sp_friend_idx, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + synctex_tree_spf_target_idx, /* target */ + synctex_tree_spft_proxy_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spft_proxy_max + synctex_data_proxy_hv_max]; +} synctex_node_proxy_s; + +/* proxy node creator */ +DEFINE_synctex_new_unscanned_NODE(proxy) + + static void _synctex_log_proxy(synctex_node_p node); +static char *_synctex_abstract_proxy(synctex_node_p node); +static void _synctex_display_proxy(synctex_node_p node); + +static synctex_vispector_s synctex_vispector_proxy = { + &__synctex_proxy_visible_h, + &__synctex_proxy_visible_v, + &__synctex_proxy_visible_width, + &_synctex_float_none, + &_synctex_float_none, +}; + +static synctex_class_s synctex_class_proxy = { + NULL, /* No scanner yet */ + synctex_node_type_proxy, /* Node type */ + &_synctex_new_proxy, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_proxy, /* log */ + &_synctex_display_proxy, /* display */ + &_synctex_abstract_proxy, /* abstract */ + &synctex_tree_model_proxy, /* tree model */ + &synctex_data_model_proxy, /* data model */ + &synctex_tlcpector_proxy, /* tlcpector */ + &synctex_inspector_proxy_box, /* inspector */ + &synctex_vispector_proxy, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark last proxy. +#endif + +/** + * A proxy to the last proxy/box boundary. + */ + +static const synctex_tree_model_s synctex_tree_model_proxy_last = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + -1, /* child */ + synctex_tree_sp_friend_idx, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + synctex_tree_spf_arg_sibling_idx, /* arg_sibling */ + synctex_tree_spfa_target_idx, /* target */ + synctex_tree_spfat_proxy_last_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spfat_proxy_last_max + synctex_data_proxy_hv_max]; +} synctex_node_proxy_last_s; + +/* proxy node creator */ +DEFINE_synctex_new_unscanned_NODE(proxy_last) + + static void _synctex_log_proxy(synctex_node_p node); +static char *_synctex_abstract_proxy(synctex_node_p node); +static void _synctex_display_proxy(synctex_node_p node); + +static synctex_class_s synctex_class_proxy_last = { + NULL, /* No scanner yet */ + synctex_node_type_proxy_last, /* Node type */ + &_synctex_new_proxy, /* creator */ + &_synctex_free_leaf, /* destructor */ + &_synctex_log_proxy, /* log */ + &_synctex_display_proxy, /* display */ + &_synctex_abstract_proxy, /* abstract */ + &synctex_tree_model_proxy_last, /* tree model */ + &synctex_data_model_proxy, /* data model */ + &synctex_tlcpector_proxy, /* tlcpector */ + &synctex_inspector_proxy_box, /* inspector */ + &synctex_vispector_proxy, /* vispector */ +}; + +#ifdef SYNCTEX_NOTHING +#pragma mark handle. +#endif + +/** + * A result node. + */ + +static const synctex_tree_model_s synctex_tree_model_handle = {synctex_tree_sibling_idx, /* sibling */ + synctex_tree_s_parent_idx, /* parent */ + synctex_tree_sp_child_idx, /* child */ + -1, /* friend */ + -1, /* last */ + -1, /* next_hbox */ + -1, /* arg_sibling */ + synctex_tree_spc_target_idx, /* target */ + synctex_tree_spct_handle_max}; + +typedef struct { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; + synctex_data_u data[synctex_tree_spct_handle_max + 0]; +} synctex_node_handle_s; + +/* result node creator */ +DEFINE_synctex_new_unscanned_NODE(handle) + + static void _synctex_log_handle(synctex_node_p node); +static char *_synctex_abstract_handle(synctex_node_p node); +static void _synctex_display_handle(synctex_node_p node); + +static synctex_class_s synctex_class_handle = { + NULL, /* No scanner yet */ + synctex_node_type_handle, /* Node type */ + &_synctex_new_handle, /* creator */ + &_synctex_free_node, /* destructor */ + &_synctex_log_handle, /* log */ + &_synctex_display_handle, /* display */ + &_synctex_abstract_handle, /* abstract */ + &synctex_tree_model_handle, /* tree model */ + &synctex_data_model_none, /* data model */ + &synctex_tlcpector_proxy, /* tlcpector */ + &synctex_inspector_proxy_box, /* inspector */ + &synctex_vispector_proxy_box, /* vispector */ +}; + +SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target) +{ + if (target) { + synctex_node_p result = _synctex_new_handle(target->class->scanner); + if (result) { + _synctex_tree_set_target(result, target); + return result; + } + } + return NULL; +} + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Navigation +#endif +synctex_node_p synctex_node_parent(synctex_node_p node) +{ + return _synctex_tree_parent(node); +} +synctex_node_p synctex_node_parent_sheet(synctex_node_p node) +{ + while (node && synctex_node_type(node) != synctex_node_type_sheet) { + node = _synctex_tree_parent(node); + } + /* exit the while loop either when node is NULL or node is a sheet */ + return node; +} +synctex_node_p synctex_node_parent_form(synctex_node_p node) +{ + while (node && synctex_node_type(node) != synctex_node_type_form) { + node = _synctex_tree_parent(node); + } + /* exit the while loop either when node is NULL or node is a form */ + return node; +} + +/** + * The returned proxy will be the child or a sibling of source. + * The returned proxy has no parent, child nor sibling. + * Used only by __synctex_replace_ref. + * argument to_node: a box, not a proxy nor anything else. + */ +SYNCTEX_INLINE static synctex_node_p __synctex_new_proxy_from_ref_to(synctex_node_p ref, synctex_node_p to_node) +{ + synctex_node_p proxy = NULL; + if (!ref || !to_node) { + return NULL; + } + switch (synctex_node_type(to_node)) { + case synctex_node_type_vbox: + proxy = _synctex_new_proxy_vbox(ref->class->scanner); + break; + case synctex_node_type_hbox: + proxy = _synctex_new_proxy_hbox(ref->class->scanner); + break; + default: + _synctex_error("! __synctex_new_proxy_from_ref_to. Unexpected form child (%s). Please report.", synctex_node_isa(to_node)); + return NULL; + } + if (!proxy) { + _synctex_error("! __synctex_new_proxy_from_ref_to. Internal error. Please report."); + return NULL; + } + _synctex_data_set_h(proxy, _synctex_data_h(ref)); + _synctex_data_set_v(proxy, _synctex_data_v(ref)); + _synctex_tree_set_target(proxy, to_node); +#if defined(SYNCTEX_USE_CHARINDEX) + proxy->line_index = to_node ? to_node->line_index : 0; + proxy->char_index = to_node ? to_node->char_index : 0; +#endif + return proxy; +} +/** + * The returned proxy will be the child or a sibling of owning_proxy. + * The returned proxy has no parent, nor child. + * Used only by synctex_node_child and synctex_node_sibling + * to create proxies on the fly. + * If the to_node has an already computed sibling, + * then the returned proxy has itself a sibling + * pointing to that already computed sibling. + */ +SYNCTEX_INLINE static synctex_node_p __synctex_new_child_proxy_to(synctex_node_p owner, synctex_node_p to_node) +{ + synctex_node_p proxy = NULL; + synctex_node_p target = to_node; + if (!owner) { + return NULL; + } + switch (synctex_node_type(target)) { + case synctex_node_type_vbox: + if ((proxy = _synctex_new_proxy_vbox(owner->class->scanner))) { + exit_standard: + _synctex_data_set_h(proxy, _synctex_data_h(owner)); + _synctex_data_set_v(proxy, _synctex_data_v(owner)); + exit0: + _synctex_tree_set_target(proxy, target); +#if defined(SYNCTEX_USE_CHARINDEX) + proxy->line_index = to_node ? to_node->line_index : 0; + proxy->char_index = to_node ? to_node->char_index : 0; +#endif + return proxy; + }; + break; + case synctex_node_type_proxy_vbox: + if ((proxy = _synctex_new_proxy_vbox(owner->class->scanner))) { + exit_proxy: + target = _synctex_tree_target(to_node); + _synctex_data_set_h(proxy, _synctex_data_h(owner) + _synctex_data_h(to_node)); + _synctex_data_set_v(proxy, _synctex_data_v(owner) + _synctex_data_v(to_node)); + goto exit0; + }; + break; + case synctex_node_type_hbox: + if ((proxy = _synctex_new_proxy_hbox(owner->class->scanner))) { + goto exit_standard; + }; + break; + case synctex_node_type_proxy_hbox: + if ((proxy = _synctex_new_proxy_hbox(owner->class->scanner))) { + goto exit_proxy; + }; + break; + case synctex_node_type_proxy: + case synctex_node_type_proxy_last: + if ((proxy = _synctex_new_proxy(owner->class->scanner))) { + goto exit_proxy; + }; + break; + default: + if ((proxy = _synctex_new_proxy(owner->class->scanner))) { + goto exit_standard; + }; + break; + } + _synctex_error( + "! __synctex_new_child_proxy_to. " + "Internal error. " + "Please report."); + return NULL; +} +SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling); +typedef struct synctex_nns_t { + synctex_node_p first; + synctex_node_p last; + synctex_status_t status; +} synctex_nns_s; +/** + * Given a target node, create a list of proxies. + * The first proxy points to the target node, + * its sibling points to the target's sibling and so on. + * Returns the first created proxy, the last one and + * an error status. + */ +SYNCTEX_INLINE static synctex_nns_s _synctex_new_child_proxies_to(synctex_node_p owner, synctex_node_p to_node) +{ + synctex_nns_s nns = {NULL, NULL, SYNCTEX_STATUS_OK}; + if ((nns.first = nns.last = __synctex_new_child_proxy_to(owner, to_node))) { + synctex_node_p to_next_sibling = __synctex_tree_sibling(to_node); + synctex_node_p to_sibling; + while ((to_sibling = to_next_sibling)) { + synctex_node_p sibling; + if ((to_next_sibling = __synctex_tree_sibling(to_sibling))) { + /* This is not the last sibling */ + if ((sibling = __synctex_new_child_proxy_to(owner, to_sibling))) { + _synctex_tree_set_sibling(nns.last, sibling); + nns.last = sibling; + continue; + } else { + _synctex_error( + "! _synctex_new_child_proxy_to. " + "Internal error (1). " + "Please report."); + nns.status = SYNCTEX_STATUS_ERROR; + } + } else if ((sibling = _synctex_new_proxy_last(owner->class->scanner))) { + _synctex_tree_set_sibling(nns.last, sibling); + nns.last = sibling; + _synctex_data_set_h(nns.last, _synctex_data_h(nns.first)); + _synctex_data_set_v(nns.last, _synctex_data_v(nns.first)); + _synctex_tree_set_target(nns.last, to_sibling); +#if defined(SYNCTEX_USE_CHARINDEX) + nns.last->line_index = to_sibling->line_index; + nns.last->char_index = to_sibling->char_index; +#endif + } else { + _synctex_error( + "! _synctex_new_child_proxy_to. " + "Internal error (2). " + "Please report."); + nns.status = SYNCTEX_STATUS_ERROR; + } + break; + } + } + return nns; +} +static char *_synctex_node_abstract(synctex_node_p node); +SYNCTEX_INLINE static synctex_node_p synctex_tree_set_friend(synctex_node_p node, synctex_node_p new_friend) +{ +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG + synctex_node_p F = new_friend; + while (F) { + if (node == F) { + printf("THIS IS AN ERROR\n"); + F = new_friend; + while (F) { + printf("%s\n", _synctex_node_abstract(F)); + if (node == F) { + return NULL; + } + F = _synctex_tree_friend(F); + } + return NULL; + } + F = _synctex_tree_friend(F); + } +#endif + return new_friend ? _synctex_tree_set_friend(node, new_friend) : _synctex_tree_reset_friend(node); +} +/** + * + */ +SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend(synctex_node_p node, int i) +{ + synctex_node_p old = NULL; + if (i >= 0) { + i = i % (node->class->scanner->number_of_lists); + old = synctex_tree_set_friend(node, (node->class->scanner->lists_of_friends)[i]); + (node->class->scanner->lists_of_friends)[i] = node; +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("tl(%i)=>", i); + synctex_node_log(node); + if (synctex_node_parent_form(node)) { + printf("! ERROR. No registration expected!\n"); + } +#endif + } + return old; +} +/** + * All proxies have tlc attributes, on behalf of their target. + * The purpose is to register all af them. + * - argument node: is the proxy, must not be NULL + */ +SYNCTEX_INLINE static synctex_node_p __synctex_proxy_make_friend_and_next_hbox(synctex_node_p node) +{ + synctex_node_p old = NULL; + synctex_node_p target = _synctex_tree_target(node); + if (target) { + int i = _synctex_data_tag(target) + _synctex_data_line(target); + old = __synctex_node_make_friend(node, i); + } else { + old = __synctex_tree_reset_friend(node); + } + if (synctex_node_type(node) == synctex_node_type_proxy_hbox) { + synctex_node_p sheet = synctex_node_parent_sheet(node); + if (sheet) { + _synctex_tree_set_next_hbox(node, _synctex_tree_next_hbox(sheet)); + _synctex_tree_set_next_hbox(sheet, node); + } + } + return old; +} +/** + * Register a node which have tag, line and column. + * - argument node: the node + */ +SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node) +{ + int i = synctex_node_tag(node) + synctex_node_line(node); + return __synctex_node_make_friend(node, i); +} +/** + * Register a node which have tag, line and column. + * Does nothing if the argument is NULL. + * Calls __synctex_node_make_friend_tlc. + * - argument node: the node + */ +SYNCTEX_INLINE static void _synctex_node_make_friend_tlc(synctex_node_p node) +{ + if (node) { + __synctex_node_make_friend_tlc(node); + } +} +static synctex_node_p _synctex_node_set_child(synctex_node_p node, synctex_node_p new_child); +/** + * The (first) child of the node, if any, NULL otherwise. + * At parse time, non void box nodes have children. + * All other nodes have no children. + * In order to support pdf forms, proxies are created + * to place form nodes at real locations. + * Ref nodes are replaced by root proxies targeting + * form contents. If root proxies have no children, + * they are created on the fly as proxies to the + * children of the targeted box. + * As such, proxies created here are targeting a + * node that belongs to a form. + * This is the only place where child proxies are created. + */ +synctex_node_p synctex_node_child(synctex_node_p node) +{ + synctex_node_p child = NULL; + synctex_node_p target = NULL; + if ((child = _synctex_tree_child(node))) { + return child; + } else if ((target = _synctex_tree_target(node))) { + if ((child = synctex_node_child(target))) { + /* This is a proxy with no child + * which target does have a child. */ + synctex_nns_s nns = _synctex_new_child_proxies_to(node, child); + if (nns.first) { + _synctex_node_set_child(node, nns.first); + return nns.first; + } else { + _synctex_error("! synctex_node_child. Internal inconsistency. Please report."); + } + } + } + return NULL; +} +/* + * Set the parent/child bound. + * Things get complicated when new_child has siblings. + * The caller is responsible for releasing the returned value. + */ +static synctex_node_p _synctex_node_set_child(synctex_node_p parent, synctex_node_p new_child) +{ + if (parent) { + synctex_node_p old = _synctex_tree_set_child(parent, new_child); + synctex_node_p last_child = NULL; + synctex_node_p child; + if ((child = old)) { + do { + _synctex_tree_reset_parent(child); + } while ((child = __synctex_tree_sibling(child))); + } + if ((child = new_child)) { + do { + _synctex_tree_set_parent(child, parent); + last_child = child; + } while ((child = __synctex_tree_sibling(child))); + } + _synctex_tree_set_last(parent, last_child); + return old; + } + return NULL; +} + +/* The last child of the given node, or NULL. + */ +synctex_node_p synctex_node_last_child(synctex_node_p node) +{ + return _synctex_tree_last(node); +} +/** + * All nodes siblings are properly set up at parse time + * except for non root proxies. + */ +synctex_node_p synctex_node_sibling(synctex_node_p node) +{ + return node ? __synctex_tree_sibling(node) : NULL; +} +/** + * All the _synctex_tree_... methods refer to the tree model. + * __synctex_tree_... methods are low level. + */ +/** + * Replace the sibling. + * Connect to the arg_sibling of the new_sibling if relevant. + * - returns the old sibling. + * The caller is responsible for releasing the old sibling. + * The bound to the parent is managed below. + */ +SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling) +{ + if (node == new_sibling) { + printf("BOF\n"); + } + synctex_node_p old = node ? __synctex_tree_set_sibling(node, new_sibling) : NULL; + _synctex_tree_set_arg_sibling(new_sibling, node); + return old; +} +/** + * Replace the sibling. + * Set the parent of the new sibling (and further siblings) + * to the parent of the receiver. + * Also set the last sibling of parent. + * - argument new_sibling: must not be NULL. + * - returns the old sibling. + * The caller is responsible for releasing the old sibling. + */ +static synctex_node_p _synctex_node_set_sibling(synctex_node_p node, synctex_node_p new_sibling) +{ + if (node && new_sibling) { + synctex_node_p old = _synctex_tree_set_sibling(node, new_sibling); + if (_synctex_tree_has_parent(node)) { + synctex_node_p parent = __synctex_tree_parent(node); + if (parent) { + synctex_node_p N = new_sibling; + while (synctex_YES) { + if (_synctex_tree_has_parent(N)) { + __synctex_tree_set_parent(N, parent); + _synctex_tree_set_last(parent, N); + N = __synctex_tree_sibling(N); + continue; + } else if (N) { + _synctex_error( + "! synctex_node_sibling. " + "Internal inconsistency. " + "Please report."); + } + break; + } + } + } + return old; + } + return NULL; +} +/** + * The last sibling of the given node, or NULL with node. + */ +synctex_node_p synctex_node_last_sibling(synctex_node_p node) +{ + synctex_node_p sibling; + do { + sibling = node; + } while ((node = synctex_node_sibling(node))); + return sibling; +} +/** + * The next nodes corresponds to a deep first tree traversal. + * Does not create child proxies as side effect contrary to + * the synctex_node_next method above. + * May loop infinitely many times if the tree + * is not properly built (contains loops). + */ +SYNCTEX_INLINE static synctex_node_p _synctex_node_sibling_or_parents(synctex_node_p node) +{ + while (node) { + synctex_node_p N; + if ((N = __synctex_tree_sibling(node))) { + return N; + } else if ((node = _synctex_tree_parent(node))) { + if (synctex_node_type(node) == synctex_node_type_sheet) { /* EXC_BAD_ACCESS? */ + return NULL; + } else if (synctex_node_type(node) == synctex_node_type_form) { + return NULL; + } + } else { + return NULL; + } + } + return NULL; +} +/** + * The next nodes corresponds to a deep first tree traversal. + * Creates child proxies as side effect. + * May loop infinitely many times if the tree + * is not properly built (contains loops). + */ +synctex_node_p synctex_node_next(synctex_node_p node) +{ + synctex_node_p N = synctex_node_child(node); + if (N) { + return N; + } + return _synctex_node_sibling_or_parents(node); +} +/** + * The next nodes corresponds to a deep first tree traversal. + * Does not create child proxies as side effect contrary to + * the synctex_node_next method above. + * May loop infinitely many times if the tree + * is not properly built (contains loops). + */ +synctex_node_p _synctex_node_next(synctex_node_p node) +{ + synctex_node_p N = _synctex_tree_child(node); + if (N) { + return N; + } + return _synctex_node_sibling_or_parents(node); +} +/** + * The node which argument is the sibling. + * - return: NULL if the argument has no parent or + * is the first child of its parent. + * - Input nodes have no arg siblings + */ +synctex_node_p synctex_node_arg_sibling(synctex_node_p node) +{ +#if 1 + return _synctex_tree_arg_sibling(node); +#else + synctex_node_p N = _synctex_tree_parent(node); + if ((N = _synctex_tree_child(N))) { + do { + synctex_node_p NN = __synctex_tree_sibling(N); + if (NN == node) { + return N; + } + N = NN; + } while (N); + } + return N; +#endif +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark CLASS +#endif + +/* Public node accessor: the type */ +synctex_node_type_t synctex_node_type(synctex_node_p node) +{ + return node ? node->class->type : synctex_node_type_none; +} + +/* Public node accessor: the type */ +synctex_node_type_t synctex_node_target_type(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + return (((target)->class))->type; + } else if (node) { + return (((node)->class))->type; + } + return synctex_node_type_none; +} + +/* Public node accessor: the human readable type */ +const char *synctex_node_isa(synctex_node_p node) +{ + static const char *isa[synctex_node_number_of_types] = {"Not a node", "input", "sheet", "form", "ref", "vbox", "void vbox", "hbox", "void hbox", "kern", + "glue", "rule", "math", "boundary", "box_bdry", "proxy", "last proxy", "vbox proxy", "hbox proxy", "handle"}; + return isa[synctex_node_type(node)]; +} + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark LOG +#endif + +/* Public node logger */ +void synctex_node_log(synctex_node_p node) +{ + SYNCTEX_MSG_SEND(node, log); +} + +static void _synctex_log_input(synctex_node_p node) +{ + if (node) { + printf("%s:%i,%s(%i)\n", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_name(node), _synctex_data_line(node)); + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + } +} + +static void _synctex_log_sheet(synctex_node_p node) +{ + if (node) { + printf("%s:%i", synctex_node_isa(node), _synctex_data_page(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + printf(" NEXT_hbox:%p\n", (void *)_synctex_tree_next_hbox(node)); + } +} + +static void _synctex_log_form(synctex_node_p node) +{ + if (node) { + printf("%s:%i", synctex_node_isa(node), _synctex_data_tag(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + } +} + +static void _synctex_log_ref(synctex_node_p node) +{ + if (node) { + printf("%s:%i:%i,%i", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_h(node), _synctex_data_v(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + } +} + +static void _synctex_log_tlchv_node(synctex_node_p node) +{ + if (node) { + printf("%s:%i,%i:%i,%i", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + } +} + +static void _synctex_log_kern_node(synctex_node_p node) +{ + if (node) { + printf("%s:%i,%i:%i,%i:%i", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node), _synctex_data_width(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + } +} + +static void _synctex_log_rule(synctex_node_p node) +{ + if (node) { + printf("%s:%i,%i:%i,%i", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node)); + printf(":%i", _synctex_data_width(node)); + printf(",%i", _synctex_data_height(node)); + printf(",%i", _synctex_data_depth(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + } +} + +static void _synctex_log_void_box(synctex_node_p node) +{ + if (node) { + printf("%s", synctex_node_isa(node)); + printf(":%i", _synctex_data_tag(node)); + printf(",%i", _synctex_data_line(node)); + printf(",%i", 0); + printf(":%i", _synctex_data_h(node)); + printf(",%i", _synctex_data_v(node)); + printf(":%i", _synctex_data_width(node)); + printf(",%i", _synctex_data_height(node)); + printf(",%i", _synctex_data_depth(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + } +} + +static void _synctex_log_vbox(synctex_node_p node) +{ + if (node) { + printf("%s", synctex_node_isa(node)); + printf(":%i", _synctex_data_tag(node)); + printf(",%i", _synctex_data_line(node)); + printf(",%i", 0); + printf(":%i", _synctex_data_h(node)); + printf(",%i", _synctex_data_v(node)); + printf(":%i", _synctex_data_width(node)); + printf(",%i", _synctex_data_height(node)); + printf(",%i", _synctex_data_depth(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + printf(" NEXT_hbox:%p\n", (void *)_synctex_tree_next_hbox(node)); + } +} + +static void _synctex_log_hbox(synctex_node_p node) +{ + if (node) { + printf("%s", synctex_node_isa(node)); + printf(":%i", _synctex_data_tag(node)); + printf(",%i~%i*%i", _synctex_data_line(node), _synctex_data_mean_line(node), _synctex_data_weight(node)); + printf(",%i", 0); + printf(":%i", _synctex_data_h(node)); + printf(",%i", _synctex_data_v(node)); + printf(":%i", _synctex_data_width(node)); + printf(",%i", _synctex_data_height(node)); + printf(",%i", _synctex_data_depth(node)); + printf("/%i", _synctex_data_h_V(node)); + printf(",%i", _synctex_data_v_V(node)); + printf(":%i", _synctex_data_width_V(node)); + printf(",%i", _synctex_data_height_V(node)); + printf(",%i", _synctex_data_depth_V(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" PARENT:%p\n", (void *)_synctex_tree_parent(node)); + printf(" CHILD:%p\n", (void *)_synctex_tree_child(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + printf(" NEXT_hbox:%p\n", (void *)_synctex_tree_next_hbox(node)); + } +} +static void _synctex_log_proxy(synctex_node_p node) +{ + if (node) { + synctex_node_p N = _synctex_tree_target(node); + printf("%s", synctex_node_isa(node)); + printf(":%i", _synctex_data_h(node)); + printf(",%i", _synctex_data_v(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" LEFT:%p\n", (void *)_synctex_tree_friend(node)); + printf(" ->%s\n", _synctex_node_abstract(N)); + } +} +static void _synctex_log_handle(synctex_node_p node) +{ + if (node) { + synctex_node_p N = _synctex_tree_target(node); + printf("%s", synctex_node_isa(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + printf("SELF:%p\n", (void *)node); + printf(" SIBLING:%p\n", (void *)__synctex_tree_sibling(node)); + printf(" ->%s\n", _synctex_node_abstract(N)); + } +} + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark SYNCTEX_DISPLAY +#endif + +int synctex_scanner_display_switcher(synctex_scanner_p scanR) +{ + return scanR->display_switcher; +} +void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher) +{ + scanR->display_switcher = switcher; +} +static const char *const _synctex_display_prompt = "................................"; + +static char *_synctex_scanner_display_prompt_down(synctex_scanner_p scanR) +{ + if (scanR->display_prompt > _synctex_display_prompt) { + --scanR->display_prompt; + } + return scanR->display_prompt; +} +static char *_synctex_scanner_display_prompt_up(synctex_scanner_p scanR) +{ + if (scanR->display_prompt + 1 < _synctex_display_prompt + strlen(_synctex_display_prompt)) { + ++scanR->display_prompt; + } + return scanR->display_prompt; +} + +void synctex_node_display(synctex_node_p node) +{ + if (node) { + synctex_scanner_p scanR = node->class->scanner; + if (scanR) { + if (scanR->display_switcher < 0) { + SYNCTEX_MSG_SEND(node, display); + } else if (scanR->display_switcher > 0 && --scanR->display_switcher > 0) { + SYNCTEX_MSG_SEND(node, display); + } else if (scanR->display_switcher-- >= 0) { + printf("%s Next display skipped. Reset display switcher.\n", node->class->scanner->display_prompt); + } + } else { + SYNCTEX_MSG_SEND(node, display); + } + } +} +static char *_synctex_node_abstract(synctex_node_p node) +{ + SYNCTEX_PARAMETER_ASSERT(node || node->class); + return (node && node->class->abstract) ? node->class->abstract(node) : "none"; +} + +SYNCTEX_INLINE static void _synctex_display_child(synctex_node_p node) +{ + synctex_node_p N = _synctex_tree_child(node); + if (N) { + _synctex_scanner_display_prompt_down(N->class->scanner); + synctex_node_display(N); + _synctex_scanner_display_prompt_up(N->class->scanner); + } +} + +SYNCTEX_INLINE static void _synctex_display_sibling(synctex_node_p node) +{ + synctex_node_display(__synctex_tree_sibling(node)); +} +#define SYNCTEX_ABSTRACT_MAX 128 +static char *_synctex_abstract_input(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "Input:%i:%s(%i)" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_name(node), _synctex_data_line(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_input(synctex_node_p node) +{ + if (node) { + printf("Input:%i:%s(%i)" SYNCTEX_PRINT_CHARINDEX_FMT "\n", _synctex_data_tag(node), _synctex_data_name(node), _synctex_data_line(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + synctex_node_display(__synctex_tree_sibling(node)); + } +} + +static char *_synctex_abstract_sheet(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "{%i...}" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_page(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_sheet(synctex_node_p node) +{ + if (node) { + printf("%s{%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", node->class->scanner->display_prompt, _synctex_data_page(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s}\n", node->class->scanner->display_prompt); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_form(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "<%i...>" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + SYNCTEX_PRINT_CHARINDEX; + } + return abstract; +} + +static void _synctex_display_form(synctex_node_p node) +{ + if (node) { + printf("%s<%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", node->class->scanner->display_prompt, _synctex_data_tag(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s>\n", node->class->scanner->display_prompt); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_vbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "[%i,%i:%i,%i:%i,%i,%i...]" SYNCTEX_PRINT_CHARINDEX_FMT, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_vbox(synctex_node_p node) +{ + if (node) { + printf("%s[%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s]\n%slast:%s\n", node->class->scanner->display_prompt, node->class->scanner->display_prompt, _synctex_node_abstract(_synctex_tree_last(node))); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_hbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "(%i,%i~%i*%i:%i,%i:%i,%i,%i...)" SYNCTEX_PRINT_CHARINDEX_FMT, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_mean_line(node), + _synctex_data_weight(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_hbox(synctex_node_p node) +{ + if (node) { + printf("%s(%i,%i~%i*%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_mean_line(node), + _synctex_data_weight(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s)\n%slast:%s\n", node->class->scanner->display_prompt, node->class->scanner->display_prompt, _synctex_node_abstract(_synctex_tree_last(node))); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_void_vbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "v%i,%i;%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_void_vbox(synctex_node_p node) +{ + if (node) { + printf("%sv%i,%i;%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_void_hbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "h%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_void_hbox(synctex_node_p node) +{ + if (node) { + printf("%sh%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_glue(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "glue:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_glue(synctex_node_p node) +{ + if (node) { + printf("%sglue:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", node->class->scanner->display_prompt, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_rule(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "rule:%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_rule(synctex_node_p node) +{ + if (node) { + printf("%srule:%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node), + _synctex_data_height(node), + _synctex_data_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_math(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "math:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_math(synctex_node_p node) +{ + if (node) { + printf("%smath:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", node->class->scanner->display_prompt, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_kern(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "kern:%i,%i:%i,%i:%i" SYNCTEX_PRINT_CHARINDEX_FMT, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_kern(synctex_node_p node) +{ + if (node) { + printf("%skern:%i,%i:%i,%i:%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + _synctex_data_tag(node), + _synctex_data_line(node), + _synctex_data_h(node), + _synctex_data_v(node), + _synctex_data_width(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_boundary(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "boundary:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_boundary(synctex_node_p node) +{ + if (node) { + printf("%sboundary:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", node->class->scanner->display_prompt, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_box_bdry(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "box bdry:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_box_bdry(synctex_node_p node) +{ + if (node) { + printf("%sbox bdry:%i,%i:%i,%i", node->class->scanner->display_prompt, _synctex_data_tag(node), _synctex_data_line(node), _synctex_data_h(node), _synctex_data_v(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_ref(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "form ref:%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT, _synctex_data_tag(node), _synctex_data_h(node), _synctex_data_v(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_ref(synctex_node_p node) +{ + if (node) { + printf("%sform ref:%i:%i,%i", node->class->scanner->display_prompt, _synctex_data_tag(node), _synctex_data_h(node), _synctex_data_v(node)); + SYNCTEX_PRINT_CHARINDEX_NL; + _synctex_display_sibling(node); + } +} +static char *_synctex_abstract_proxy(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + synctex_node_p N = _synctex_tree_target(node); + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "%s:%i,%i:%i,%i/%p%s", synctex_node_isa(node), synctex_node_tag(node), synctex_node_line(node), _synctex_data_h(node), _synctex_data_v(node), node, _synctex_node_abstract(N)); + } + return abstract; +} +static void _synctex_display_proxy(synctex_node_p node) +{ + if (node) { + synctex_node_p N = _synctex_tree_target(node); + printf("%s%s:%i,%i:%i,%i", node->class->scanner->display_prompt, synctex_node_isa(node), synctex_node_tag(node), synctex_node_line(node), _synctex_data_h(node), _synctex_data_v(node)); + if (N) { + printf("=%i,%i:%i,%i,%i->%s", synctex_node_h(node), synctex_node_v(node), synctex_node_width(node), synctex_node_height(node), synctex_node_depth(node), _synctex_node_abstract(N)); + } + printf("\n"); + _synctex_display_child(node); + _synctex_display_sibling(node); + } +} +static char *_synctex_abstract_proxy_vbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "[*%i,%i:%i,%i:%i,%i,%i...*]" SYNCTEX_PRINT_CHARINDEX_FMT, + synctex_node_tag(node), + synctex_node_line(node), + synctex_node_h(node), + synctex_node_v(node), + synctex_node_width(node), + synctex_node_height(node), + synctex_node_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_proxy_vbox(synctex_node_p node) +{ + if (node) { + printf("%s[*%i,%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + synctex_node_tag(node), + synctex_node_line(node), + synctex_node_h(node), + synctex_node_v(node), + synctex_node_width(node), + synctex_node_height(node), + synctex_node_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s*]\n%slast:%s\n", node->class->scanner->display_prompt, node->class->scanner->display_prompt, _synctex_node_abstract(_synctex_tree_last(node))); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_proxy_hbox(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + snprintf(abstract, + SYNCTEX_ABSTRACT_MAX, + "(*%i,%i~%i*%i:%i,%i:%i,%i,%i...*)/%p" SYNCTEX_PRINT_CHARINDEX_FMT, + synctex_node_tag(node), + synctex_node_line(node), + synctex_node_mean_line(node), + synctex_node_weight(node), + synctex_node_h(node), + synctex_node_v(node), + synctex_node_width(node), + synctex_node_height(node), + synctex_node_depth(node), + node SYNCTEX_PRINT_CHARINDEX_WHAT); + } + return abstract; +} + +static void _synctex_display_proxy_hbox(synctex_node_p node) +{ + if (node) { + printf("%s(*%i,%i~%i*%i:%i,%i:%i,%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT "\n", + node->class->scanner->display_prompt, + synctex_node_tag(node), + synctex_node_line(node), + synctex_node_mean_line(node), + synctex_node_weight(node), + synctex_node_h(node), + synctex_node_v(node), + synctex_node_width(node), + synctex_node_height(node), + synctex_node_depth(node) SYNCTEX_PRINT_CHARINDEX_WHAT); + _synctex_display_child(node); + printf("%s*)\n%slast:%s\n", node->class->scanner->display_prompt, node->class->scanner->display_prompt, _synctex_node_abstract(_synctex_tree_last(node))); + _synctex_display_sibling(node); + } +} + +static char *_synctex_abstract_handle(synctex_node_p node) +{ + static char abstract[SYNCTEX_ABSTRACT_MAX] = "none"; + if (node) { + synctex_node_p N = _synctex_tree_target(node); + if (N && !N->class) { + exit(1); + } + snprintf(abstract, SYNCTEX_ABSTRACT_MAX, "%s:%s", synctex_node_isa(node), (N ? _synctex_node_abstract(N) : "")); + } + return abstract; +} +static void _synctex_display_handle(synctex_node_p node) +{ + if (node) { + synctex_node_p N = _synctex_tree_target(node); + printf("%s%s:->%s\n", node->class->scanner->display_prompt, synctex_node_isa(node), _synctex_node_abstract(N)); + _synctex_display_child(node); + _synctex_display_sibling(node); + } +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark STATUS +#endif + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Prototypes +#endif +typedef struct { + size_t size; + synctex_status_t status; +} synctex_zs_s; +static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t size); +static synctex_status_t _synctex_next_line(synctex_scanner_p scanner); +static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char *the_string); + +typedef struct synctex_ns_t { + synctex_node_p node; + synctex_status_t status; +} synctex_ns_s; +static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner); +static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner); +typedef struct { + float value; + synctex_status_t status; +} synctex_fs_s; +static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner); +static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner); +static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner); +static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box); +static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner); +int synctex_scanner_pre_x_offset(synctex_scanner_p scanner); +int synctex_scanner_pre_y_offset(synctex_scanner_p scanner); +const char *synctex_scanner_get_output_fmt(synctex_scanner_p scanner); + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark SCANNER UTILITIES +#endif + +#define SYNCTEX_FILE (scanner->reader->file) + +/** + * Try to ensure that the buffer contains at least size bytes. + * Passing a huge size argument means the whole buffer length. + * Passing a 0 size argument means return the available buffer length, without reading the file. + * In that case, the return status is always SYNCTEX_STATUS_OK unless the given scanner is NULL. + * The size_t value returned is the number of bytes now available in the buffer. This is a nonnegative integer, it may take the value 0. + * It is the responsibility of the caller to test whether this size is conforming to its needs. + * Negative values may return in case of error, actually + * when there was an error reading the synctex file. + * - parameter scanner: The owning scanner. When NULL, returns SYNCTEX_STATUS_BAD_ARGUMENT. + * - parameter expected: expected number of bytes. + * - returns: a size and a status. + */ +static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t expected) +{ + size_t size = 0; + if (NULL == scanner) { + return (synctex_zs_s) {0, SYNCTEX_STATUS_BAD_ARGUMENT}; + } + if (expected > scanner->reader->size) { + expected = scanner->reader->size; + } + size = SYNCTEX_END - SYNCTEX_CUR; /* available is the number of unparsed chars in the buffer */ + if (expected <= size) { + /* There are already sufficiently many characters in the buffer */ + return (synctex_zs_s) {size, SYNCTEX_STATUS_OK}; + } + if (SYNCTEX_FILE) { + /* Copy the remaining part of the buffer to the beginning, + * then read the next part of the file */ + int already_read = 0; +#if defined(SYNCTEX_USE_CHARINDEX) + scanner->reader->charindex_offset += SYNCTEX_CUR - SYNCTEX_START; +#endif + if (size) { + memmove(SYNCTEX_START, SYNCTEX_CUR, size); + } + SYNCTEX_CUR = SYNCTEX_START + size; /* the next character after the move, will change. */ + /* Fill the buffer up to its end */ + already_read = gzread(SYNCTEX_FILE, (void *)SYNCTEX_CUR, (int)(SYNCTEX_BUFFER_SIZE - size)); + if (already_read > 0) { + /* We assume that 0 already_read) { + /* There is a possible error in reading the file */ + int errnum = 0; + const char *error_string = gzerror(SYNCTEX_FILE, &errnum); + if (Z_ERRNO == errnum) { + /* There is an error in zlib caused by the file system */ + _synctex_error("gzread error from the file system (%i)", errno); + return (synctex_zs_s) {0, SYNCTEX_STATUS_ERROR}; + } else if (errnum) { + _synctex_error("gzread error (%i:%i,%s)", already_read, errnum, error_string); + return (synctex_zs_s) {0, SYNCTEX_STATUS_ERROR}; + } + } + /* Nothing was read, we are at the end of the file. */ + gzclose(SYNCTEX_FILE); + SYNCTEX_FILE = NULL; + SYNCTEX_END = SYNCTEX_CUR; + SYNCTEX_CUR = SYNCTEX_START; + *SYNCTEX_END = '\0'; /* Terminate the string properly.*/ + /* there might be a bit of text left */ + return (synctex_zs_s) {SYNCTEX_END - SYNCTEX_CUR, SYNCTEX_STATUS_EOF}; + } + /* We cannot enlarge the buffer because the end of the file was reached. */ + return (synctex_zs_s) {size, SYNCTEX_STATUS_EOF}; +} + +/* Used when parsing the synctex file. + * Advance to the next character starting a line. + * Actually, only '\n' is recognized as end of line marker. + * On normal completion, the returned value is the number of unparsed characters available in the buffer. + * In general, it is a positive value, 0 meaning that the end of file was reached. + * -1 is returned in case of error, actually because there was an error while feeding the buffer. + * When the function returns with no error, SYNCTEX_CUR points to the first character of the next line, if any. + * J. Laurens: Sat May 10 07:52:31 UTC 2008 + */ +static synctex_status_t _synctex_next_line(synctex_scanner_p scanner) +{ + synctex_status_t status = SYNCTEX_STATUS_OK; + if (NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } +infinite_loop: + while (SYNCTEX_CUR < SYNCTEX_END) { + if (*SYNCTEX_CUR == '\n') { + ++SYNCTEX_CUR; + ++scanner->reader->line_number; + return _synctex_buffer_get_available_size(scanner, 1).status; + } + ++SYNCTEX_CUR; + } + /* Here, we have SYNCTEX_CUR == SYNCTEX_END, such that the next call to _synctex_buffer_get_available_size + * will read another bunch of synctex file. Little by little, we advance to the end of the file. */ + status = _synctex_buffer_get_available_size(scanner, 1).status; + if (status <= SYNCTEX_STATUS_EOF) { + return status; + } + goto infinite_loop; +} + +/* Scan the given string. + * Both scanner and the_string must not be NULL, and the_string must not be 0 length. + * SYNCTEX_STATUS_OK is returned if the string is found, + * SYNCTEX_STATUS_EOF is returned when the EOF is reached, + * SYNCTEX_STATUS_NOT_OK is returned is the string is not found, + * an error status is returned otherwise. + * This is a critical method because buffering renders things more difficult. + * The given string might be as long as the maximum size_t value. + * As side effect, the buffer state may have changed if the given argument string can't fit into the buffer. + */ +static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char *the_string) +{ + size_t tested_len = 0; /* the number of characters at the beginning of the_string that match */ + size_t remaining_len = 0; /* the number of remaining characters of the_string that should match */ + size_t available = 0; + synctex_zs_s zs = {0, 0}; + if (NULL == scanner || NULL == the_string) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + remaining_len = strlen(the_string); /* All the_string should match */ + if (0 == remaining_len) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + /* How many characters available in the buffer? */ + zs = _synctex_buffer_get_available_size(scanner, remaining_len); + if (zs.status < SYNCTEX_STATUS_EOF) { + return zs.status; + } + /* Maybe we have less characters than expected because the buffer is too small. */ + if (zs.size >= remaining_len) { + /* The buffer is sufficiently big to hold the expected number of characters. */ + if (strncmp((char *)SYNCTEX_CUR, the_string, remaining_len)) { + return SYNCTEX_STATUS_NOT_OK; + } + return_OK: + /* Advance SYNCTEX_CUR to the next character after the_string. */ + SYNCTEX_CUR += remaining_len; + return SYNCTEX_STATUS_OK; + } else if (strncmp((char *)SYNCTEX_CUR, the_string, zs.size)) { + /* No need to go further, this is not the expected string in the buffer. */ + return SYNCTEX_STATUS_NOT_OK; + } else if (SYNCTEX_FILE) { + /* The buffer was too small to contain remaining_len characters. + * We have to cut the string into pieces. */ + z_off_t offset = 0L; + /* the first part of the string is found, advance the_string to the next untested character. */ + the_string += zs.size; + /* update the remaining length and the parsed length. */ + remaining_len -= zs.size; + tested_len += zs.size; + SYNCTEX_CUR += zs.size; /* We validate the tested characters. */ + if (0 == remaining_len) { + /* Nothing left to test, we have found the given string. */ + return SYNCTEX_STATUS_OK; + } + /* We also have to record the current state of the file cursor because + * if the_string does not match, all this should be a totally blank operation, + * for which the file and buffer states should not be modified at all. + * In fact, the states of the buffer before and after this function are in general different + * but they are totally equivalent as long as the values of the buffer before SYNCTEX_CUR + * can be safely discarded. */ + offset = gztell(SYNCTEX_FILE); + /* offset now corresponds to the first character of the file that was not buffered. */ + /* SYNCTEX_CUR - SYNCTEX_START is the number of chars that where already buffered and + * that match the head of the_string. If in fine the_string does not match, all these chars must be recovered + * because the whole buffer contents is replaced in _synctex_buffer_get_available_size. + * They were buffered from offset-len location in the file. */ + offset -= SYNCTEX_CUR - SYNCTEX_START; + more_characters: + /* There is still some work to be done, so read another bunch of file. + * This is the second call to _synctex_buffer_get_available_size, + * which means that the actual contents of the buffer will be discarded. + * We will definitely have to recover the previous state in case we do not find the expected string. */ + zs = _synctex_buffer_get_available_size(scanner, remaining_len); + if (zs.status < SYNCTEX_STATUS_EOF) { + return zs.status; /* This is an error, no need to go further. */ + } + if (zs.size == 0) { + /* Missing characters: recover the initial state of the file and return. */ + return_NOT_OK: + if (offset != gzseek(SYNCTEX_FILE, offset, SEEK_SET)) { + /* This is a critical error, we could not recover the previous state. */ + _synctex_error("Can't seek file"); + return SYNCTEX_STATUS_ERROR; + } + /* Next time we are asked to fill the buffer, + * we will read a complete bunch of text from the file. */ + SYNCTEX_CUR = SYNCTEX_END; + return SYNCTEX_STATUS_NOT_OK; + } + if (zs.size < remaining_len) { + /* We'll have to loop one more time. */ + if (strncmp((char *)SYNCTEX_CUR, the_string, zs.size)) { + /* This is not the expected string, recover the previous state and return. */ + goto return_NOT_OK; + } + /* Advance the_string to the first untested character. */ + the_string += available; + /* update the remaining length and the parsed length. */ + remaining_len -= zs.size; + tested_len += zs.size; + SYNCTEX_CUR += zs.size; /* We validate the tested characters. */ + goto more_characters; + } + /* This is the last step. */ + if (strncmp((char *)SYNCTEX_CUR, the_string, remaining_len)) { + /* This is not the expected string, recover the previous state and return. */ + goto return_NOT_OK; + } + goto return_OK; + } else { + /* The buffer can't contain the given string argument, and the EOF was reached */ + return SYNCTEX_STATUS_EOF; + } +} + +/* Used when parsing the synctex file. + * Decode an integer. + * First, field separators, namely ':' and ',' characters are skipped + * The returned value is negative if there is an unrecoverable error. + * It is SYNCTEX_STATUS_NOT_OK if an integer could not be parsed, for example + * if the characters at the current cursor position are not digits or + * if the end of the file has been reached. + * It is SYNCTEX_STATUS_OK if an int has been successfully parsed. + * The given scanner argument must not be NULL, on the contrary, value_ref may be NULL. + */ +static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner) +{ + char *ptr = NULL; + char *end = NULL; + synctex_zs_s zs = {0, 0}; + int result; + if (NULL == scanner) { + return (synctex_is_s) {0, SYNCTEX_STATUS_BAD_ARGUMENT}; + } + zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE); + if (zs.status < SYNCTEX_STATUS_EOF) { + return (synctex_is_s) {0, zs.status}; + } + if (zs.size == 0) { + return (synctex_is_s) {0, SYNCTEX_STATUS_NOT_OK}; + } + ptr = SYNCTEX_CUR; + /* Optionally parse the separator */ + if (*ptr == ':' || *ptr == ',') { + ++ptr; + --zs.size; + if (zs.size == 0) { + return (synctex_is_s) {0, SYNCTEX_STATUS_NOT_OK}; + } + } + result = (int)strtol(ptr, &end, 10); + if (end > ptr) { + SYNCTEX_CUR = end; + return (synctex_is_s) {result, SYNCTEX_STATUS_OK}; + } + return (synctex_is_s) {result, SYNCTEX_STATUS_NOT_OK}; +} +static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value) +{ + char *ptr = NULL; + char *end = NULL; + synctex_zs_s zs = {0, 0}; + if (NULL == scanner) { + return (synctex_is_s) {default_value, SYNCTEX_STATUS_BAD_ARGUMENT}; + } + zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE); + if (zs.status < SYNCTEX_STATUS_EOF) { + return (synctex_is_s) {default_value, zs.status}; + } + if (zs.size == 0) { + return (synctex_is_s) {default_value, SYNCTEX_STATUS_OK}; + } + ptr = SYNCTEX_CUR; + /* Comma separator required */ + if (*ptr == ',') { + int result; + ++ptr; + --zs.size; + if (zs.size == 0) { + return (synctex_is_s) {default_value, SYNCTEX_STATUS_NOT_OK}; + } + result = (int)strtol(ptr, &end, 10); + if (end > ptr) { + SYNCTEX_CUR = end; + return (synctex_is_s) {result, SYNCTEX_STATUS_OK}; + } + return (synctex_is_s) {default_value, SYNCTEX_STATUS_NOT_OK}; + } + return (synctex_is_s) {default_value, SYNCTEX_STATUS_OK}; +} +/* Used when parsing the synctex file. + * Decode an integer for a v field. + * Try the _synctex_decode_int version and set the last v field scanned. + * If it does not succeed, tries to match an '=' sign, + * which is a shortcut for the last v field scanned. + */ +#define SYNCTEX_INPUT_COMEQUALS ",=" +static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner) +{ + synctex_is_s is = _synctex_decode_int(scanner); + if (SYNCTEX_STATUS_OK == is.status) { + scanner->reader->lastv = is.integer; + return is; + } + is.status = _synctex_match_string(scanner, SYNCTEX_INPUT_COMEQUALS); + if (is.status < SYNCTEX_STATUS_OK) { + return is; + } + is.integer = scanner->reader->lastv; + return is; +} + +/* The purpose of this function is to read a string. + * A string is an array of characters from the current parser location + * and before the next '\n' character. + * If a string was properly decoded, it is returned in value_ref and + * the cursor points to the new line marker. + * The returned string was alloced on the heap, the caller is the owner and + * is responsible to free it in due time, + * unless it transfers the ownership to another object. + * If no string is parsed, * value_ref is undefined. + * The maximum length of a string that a scanner can decode is platform dependent, namely UINT_MAX. + * If you just want to blindly parse the file up to the end of the current line, + * use _synctex_next_line instead. + * On return, the scanner cursor is unchanged if a string could not be scanned or + * points to the terminating '\n' character otherwise. As a consequence, + * _synctex_next_line is necessary after. + * If either scanner or value_ref is NULL, it is considered as an error and + * SYNCTEX_STATUS_BAD_ARGUMENT is returned. + */ +static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner) +{ + char *end = NULL; + size_t len = 0; /* The number of bytes to copy */ + size_t already_len = 0; + synctex_zs_s zs = {0, 0}; + char *string = NULL; + if (NULL == scanner) { + return (synctex_ss_s) {NULL, SYNCTEX_STATUS_BAD_ARGUMENT}; + } + /* The buffer must at least contain one character: the '\n' end of line marker */ + if (SYNCTEX_CUR >= SYNCTEX_END) { + more_characters: + zs = _synctex_buffer_get_available_size(scanner, 1); + if (zs.status < SYNCTEX_STATUS_EOF) { + return (synctex_ss_s) {NULL, zs.status}; + } else if (0 == zs.size) { + return (synctex_ss_s) {NULL, SYNCTEX_STATUS_EOF}; + } + } + /* Now we are sure that there is at least one available character, either because + * SYNCTEX_CUR was already < SYNCTEX_END, or because the buffer has been properly filled. */ + /* end will point to the next unparsed '\n' character in the file, when mapped to the buffer. */ + end = SYNCTEX_CUR; + /* We scan all the characters up to the next '\n' */ + while (end < SYNCTEX_END && *end != '\n') { + ++end; + } + /* OK, we found where to stop: + * either end == SYNCTEX_END + * or *end == '\n' */ + len = end - SYNCTEX_CUR; + if (len < UINT_MAX - already_len) { + if ((string = realloc(string, len + already_len + 1)) != NULL) { + if (memcpy(string + already_len, SYNCTEX_CUR, len)) { + already_len += len; + string[already_len] = '\0'; /* Terminate the string */ + SYNCTEX_CUR += len; /* Eventually advance to the terminating '\n' */ + if (SYNCTEX_CUR == SYNCTEX_END) { + /* No \n found*/ + goto more_characters; + } + /* trim the trailing whites */ + len = already_len; + while (len > 0) { + already_len = len--; + if (string[len] != ' ') { + break; + } + } + string[already_len] = '\0'; + return (synctex_ss_s) {string, SYNCTEX_STATUS_OK}; + } + free(string); + _synctex_error("could not copy memory (1)."); + return (synctex_ss_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + } + _synctex_error("could not (re)allocate memory (1)."); + return (synctex_ss_s) {NULL, SYNCTEX_STATUS_ERROR}; +} + +/* Used when parsing the synctex file. + * Read an Input record. + * - parameter scanner: non NULL scanner + * - returns SYNCTEX_STATUS_OK on successful completions, others values otherwise. + */ +static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner) +{ + synctex_node_p input = NULL; + synctex_status_t status = SYNCTEX_STATUS_BAD_ARGUMENT; + synctex_zs_s zs = {0, 0}; + if (NULL == scanner) { + return (synctex_ns_s) {NULL, status}; + } + if ((status = _synctex_match_string(scanner, SYNCTEX_INPUT_MARK)) < SYNCTEX_STATUS_OK) { + return (synctex_ns_s) {NULL, status}; + } + /* Create a node */ + if (NULL == (input = _synctex_new_input(scanner))) { + _synctex_error("Could not create an input node."); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + /* Decode the tag */ + if ((status = _synctex_data_decode_tag(input)) < SYNCTEX_STATUS_OK) { + _synctex_error("Bad format of input node."); + synctex_node_free(input); + return (synctex_ns_s) {NULL, status}; + } + /* The next character is a field separator, we expect one character in the buffer. */ + zs = _synctex_buffer_get_available_size(scanner, 1); + if (zs.status <= SYNCTEX_STATUS_ERROR) { + return (synctex_ns_s) {NULL, status}; + } + if (0 == zs.size) { + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_EOF}; + } + /* We can now safely advance to the next character, stepping over the field separator. */ + ++SYNCTEX_CUR; + --zs.size; + /* Then we scan the file name */ + if ((status = _synctex_data_decode_name(input)) < SYNCTEX_STATUS_OK) { + synctex_node_free(input); + _synctex_next_line(scanner); /* Ignore this whole line */ + return (synctex_ns_s) {NULL, status}; + } + /* Prepend this input node to the input linked list of the scanner */ + __synctex_tree_set_sibling(input, scanner->input); /* input has no parent */ + scanner->input = input; +#ifdef SYNCTEX_VERBOSE + synctex_node_log(input); +#endif + return (synctex_ns_s) {input, _synctex_next_line(scanner)}; /* read the line termination character, if any */ +} + +typedef synctex_is_s (*synctex_decoder_t)(synctex_scanner_p); + +/* Used when parsing the synctex file. + * Read one of the settings. + * On normal completion, returns SYNCTEX_STATUS_OK. + * On error, returns SYNCTEX_STATUS_ERROR. + * Both arguments must not be NULL. + * On return, the scanner points to the next character after the decoded object whatever it is. + * It is the responsibility of the caller to prepare the scanner for the next line. + */ +static synctex_status_t _synctex_scan_named(synctex_scanner_p scanner, const char *name) +{ + synctex_status_t status = 0; + if (NULL == scanner || NULL == name) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } +not_found: + status = _synctex_match_string(scanner, name); + if (status < SYNCTEX_STATUS_NOT_OK) { + return status; + } else if (status == SYNCTEX_STATUS_NOT_OK) { + status = _synctex_next_line(scanner); + if (status < SYNCTEX_STATUS_OK) { + return status; + } + goto not_found; + } + return SYNCTEX_STATUS_OK; +} + +/* Used when parsing the synctex file. + * Read the preamble. + */ +static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner) +{ + synctex_status_t status = 0; + synctex_is_s is = {0, 0}; + synctex_ss_s ss = {NULL, 0}; + if (NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + status = _synctex_scan_named(scanner, "SyncTeX Version:"); + if (status < SYNCTEX_STATUS_OK) { + return status; + } + is = _synctex_decode_int(scanner); + if (is.status < SYNCTEX_STATUS_OK) { + return is.status; + } + status = _synctex_next_line(scanner); + if (status < SYNCTEX_STATUS_OK) { + return status; + } + scanner->version = is.integer; + /* Read all the input records */ + do { + status = __synctex_parse_new_input(scanner).status; + if (status < SYNCTEX_STATUS_NOT_OK) { + return status; + } + } while (status == SYNCTEX_STATUS_OK); + /* the loop exits when status == SYNCTEX_STATUS_NOT_OK */ + /* Now read all the required settings. */ + if ((status = _synctex_scan_named(scanner, "Output:")) < SYNCTEX_STATUS_OK) { + return status; + } + if ((ss = _synctex_decode_string(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->output_fmt = ss.string; + if ((status = _synctex_scan_named(scanner, "Magnification:")) < SYNCTEX_STATUS_OK) { + return status; + } + if ((is = _synctex_decode_int(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->pre_magnification = is.integer; + if ((status = _synctex_scan_named(scanner, "Unit:")) < SYNCTEX_STATUS_OK) { + return status; + } + if ((is = _synctex_decode_int(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->pre_unit = is.integer; + if ((status = _synctex_scan_named(scanner, "X Offset:")) < SYNCTEX_STATUS_OK) { + return status; + } + if ((is = _synctex_decode_int(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->pre_x_offset = is.integer; + if ((status = _synctex_scan_named(scanner, "Y Offset:")) < SYNCTEX_STATUS_OK) { + return status; + } + if ((is = _synctex_decode_int(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->pre_y_offset = is.integer; + return SYNCTEX_STATUS_OK; +} + +/* parse a float with a dimension */ +static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner) +{ + synctex_fs_s fs = {0, 0}; + synctex_zs_s zs = {0, 0}; + char *endptr = NULL; +#ifdef HAVE_SETLOCALE + char *loc = setlocale(LC_NUMERIC, NULL); +#endif + if (NULL == scanner) { + return (synctex_fs_s) {0, SYNCTEX_STATUS_BAD_ARGUMENT}; + } + zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE); + if (zs.status < SYNCTEX_STATUS_EOF) { + _synctex_error("Problem with float."); + return (synctex_fs_s) {0, zs.status}; + } +#ifdef HAVE_SETLOCALE + setlocale(LC_NUMERIC, "C"); +#endif + fs.value = strtod(SYNCTEX_CUR, &endptr); +#ifdef HAVE_SETLOCALE + setlocale(LC_NUMERIC, loc); +#endif + if (endptr == SYNCTEX_CUR) { + _synctex_error("A float was expected."); + return (synctex_fs_s) {0, SYNCTEX_STATUS_ERROR}; + } + SYNCTEX_CUR = endptr; + if ((fs.status = _synctex_match_string(scanner, "in")) >= SYNCTEX_STATUS_OK) { + fs.value *= 72.27f * 65536; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + report_unit_error: + _synctex_error("problem with unit."); + return fs; + } else if ((fs.status = _synctex_match_string(scanner, "cm")) >= SYNCTEX_STATUS_OK) { + fs.value *= 72.27f * 65536 / 2.54f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "mm")) >= SYNCTEX_STATUS_OK) { + fs.value *= 72.27f * 65536 / 25.4f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "pt")) >= SYNCTEX_STATUS_OK) { + fs.value *= 65536.0f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "bp")) >= SYNCTEX_STATUS_OK) { + fs.value *= 72.27f / 72 * 65536.0f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "pc")) >= SYNCTEX_STATUS_OK) { + fs.value *= 12.0 * 65536.0f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "sp")) >= SYNCTEX_STATUS_OK) { + fs.value *= 1.0f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "dd")) >= SYNCTEX_STATUS_OK) { + fs.value *= 1238.0f / 1157 * 65536.0f; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "cc")) >= SYNCTEX_STATUS_OK) { + fs.value *= 14856.0f / 1157 * 65536; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "nd")) >= SYNCTEX_STATUS_OK) { + fs.value *= 685.0f / 642 * 65536; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } else if ((fs.status = _synctex_match_string(scanner, "nc")) >= SYNCTEX_STATUS_OK) { + fs.value *= 1370.0f / 107 * 65536; + } else if (fs.status < SYNCTEX_STATUS_EOF) { + goto report_unit_error; + } + return fs; +} + +/* parse the post scriptum + * SYNCTEX_STATUS_OK is returned on completion + * a negative error is returned otherwise */ +static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner) +{ + synctex_status_t status = 0; + synctex_fs_s fs = {0, 0}; + char *endptr = NULL; +#ifdef HAVE_SETLOCALE + char *loc = setlocale(LC_NUMERIC, NULL); +#endif + if (NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + /* Scan the file until a post scriptum line is found */ +post_scriptum_not_found: + status = _synctex_match_string(scanner, "Post scriptum:"); + if (status < SYNCTEX_STATUS_NOT_OK) { + return status; + } + if (status == SYNCTEX_STATUS_NOT_OK) { + status = _synctex_next_line(scanner); + if (status < SYNCTEX_STATUS_EOF) { + return status; + } else if (status < SYNCTEX_STATUS_OK) { + return SYNCTEX_STATUS_OK; /* The EOF is found, we have properly scanned the file */ + } + goto post_scriptum_not_found; + } + /* We found the name, advance to the next line. */ +next_line: + status = _synctex_next_line(scanner); + if (status < SYNCTEX_STATUS_EOF) { + return status; + } else if (status < SYNCTEX_STATUS_OK) { + return SYNCTEX_STATUS_OK; /* The EOF is found, we have properly scanned the file */ + } + /* Scanning the information */ + status = _synctex_match_string(scanner, "Magnification:"); + if (status == SYNCTEX_STATUS_OK) { +#ifdef HAVE_SETLOCALE + setlocale(LC_NUMERIC, "C"); +#endif + scanner->unit = strtod(SYNCTEX_CUR, &endptr); +#ifdef HAVE_SETLOCALE + setlocale(LC_NUMERIC, loc); +#endif + if (endptr == SYNCTEX_CUR) { + _synctex_error("bad magnification in the post scriptum, a float was expected."); + return SYNCTEX_STATUS_ERROR; + } + if (scanner->unit <= 0) { + _synctex_error("bad magnification in the post scriptum, a positive float was expected."); + return SYNCTEX_STATUS_ERROR; + } + SYNCTEX_CUR = endptr; + goto next_line; + } + if (status < SYNCTEX_STATUS_EOF) { + report_record_problem: + _synctex_error("Problem reading the Post Scriptum records"); + return status; /* echo the error. */ + } + status = _synctex_match_string(scanner, "X Offset:"); + if (status == SYNCTEX_STATUS_OK) { + fs = _synctex_scan_float_and_dimension(scanner); + if (fs.status < SYNCTEX_STATUS_OK) { + _synctex_error("Problem with X offset in the Post Scriptum."); + return fs.status; + } + scanner->x_offset = fs.value; + goto next_line; + } else if (status < SYNCTEX_STATUS_EOF) { + goto report_record_problem; + } + status = _synctex_match_string(scanner, "Y Offset:"); + if (status == SYNCTEX_STATUS_OK) { + fs = _synctex_scan_float_and_dimension(scanner); + if (fs.status < SYNCTEX_STATUS_OK) { + _synctex_error("Problem with Y offset in the Post Scriptum."); + return fs.status; + } + scanner->x_offset = fs.value; + goto next_line; + } else if (status < SYNCTEX_STATUS_EOF) { + goto report_record_problem; + } + goto next_line; +} + +/* SYNCTEX_STATUS_OK is returned if the postamble is read + * SYNCTEX_STATUS_NOT_OK is returned if the postamble is not at the current location + * a negative error otherwise + * The postamble comprises the post scriptum section. + */ +static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner) +{ + synctex_status_t status = 0; + synctex_is_s is = {0, 0}; + if (NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + if (!scanner->flags.postamble && (status = _synctex_match_string(scanner, "Postamble:")) < SYNCTEX_STATUS_OK) { + return status; + } +count_again: + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + if ((status = _synctex_scan_named(scanner, "Count:")) < SYNCTEX_STATUS_EOF) { + return status; /* forward the error */ + } else if (status < SYNCTEX_STATUS_OK) { /* No Count record found */ + goto count_again; + } + if ((is = _synctex_decode_int(scanner)).status < SYNCTEX_STATUS_OK) { + return is.status; + } + if ((status = _synctex_next_line(scanner)) < SYNCTEX_STATUS_OK) { + return status; + } + scanner->count = is.integer; + /* Now we scan the last part of the SyncTeX file: the Post Scriptum section. */ + return _synctex_scan_post_scriptum(scanner); +} + +/* Horizontal boxes also have visible size. + * Visible size are bigger than real size. + * For example 0 width boxes may contain text. + * At creation time, the visible size is set to the values of the real size. + */ +static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box) +{ + if (box) { + switch (synctex_node_type(box)) { + case synctex_node_type_hbox: + _synctex_data_set_h_V(box, _synctex_data_h(box)); + _synctex_data_set_v_V(box, _synctex_data_v(box)); + _synctex_data_set_width_V(box, _synctex_data_width(box)); + _synctex_data_set_height_V(box, _synctex_data_height(box)); + _synctex_data_set_depth_V(box, _synctex_data_depth(box)); + return SYNCTEX_STATUS_OK; + default: + break; + } + } + return SYNCTEX_STATUS_BAD_ARGUMENT; +} + +/* This method is sent to an horizontal box to setup the visible size + * Some box have 0 width but do contain text material. + * With this method, one can enlarge the box to contain the given point (h,v). + */ +static synctex_status_t _synctex_make_hbox_contain_point(synctex_node_p node, synctex_point_s point) +{ + int min, max, n; + if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + if ((n = _synctex_data_width_V(node)) < 0) { + max = _synctex_data_h_V(node); + min = max + n; + if (point.h < min) { + _synctex_data_set_width_V(node, point.h - max); + } else if (point.h > max) { + _synctex_data_set_h_V(node, point.h); + _synctex_data_set_width_V(node, min - point.h); + } + } else { + min = _synctex_data_h_V(node); + max = min + n; + if (point.h < min) { + _synctex_data_set_h_V(node, point.h); + _synctex_data_set_width_V(node, max - point.h); + } else if (point.h > max) { + _synctex_data_set_width_V(node, point.h - min); + } + } + n = _synctex_data_v_V(node); + min = n - _synctex_data_height_V(node); + max = n + _synctex_data_depth_V(node); + if (point.v < min) { + _synctex_data_set_height_V(node, n - point.v); + } else if (point.v > max) { + _synctex_data_set_depth_V(node, point.v - n); + } + return SYNCTEX_STATUS_OK; +} +static synctex_status_t _synctex_make_hbox_contain_box(synctex_node_p node, synctex_box_s box) +{ + int min, max, n; + if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + if ((n = _synctex_data_width_V(node)) < 0) { + max = _synctex_data_h_V(node); + min = max + n; + if (box.min.h < min) { + _synctex_data_set_width_V(node, box.min.h - max); + } else if (box.max.h > max) { + _synctex_data_set_h_V(node, box.max.h); + _synctex_data_set_width_V(node, min - box.max.h); + } + } else { + min = _synctex_data_h_V(node); + max = min + n; + if (box.min.h < min) { + _synctex_data_set_h_V(node, box.min.h); + _synctex_data_set_width_V(node, max - box.min.h); + } else if (box.max.h > max) { + _synctex_data_set_width_V(node, box.max.h - min); + } + } + n = _synctex_data_v_V(node); + min = n - _synctex_data_height_V(node); + max = n + _synctex_data_depth_V(node); + if (box.min.v < min) { + _synctex_data_set_height_V(node, n - box.min.v); + } else if (box.max.v > max) { + _synctex_data_set_depth_V(node, box.max.v - n); + } + return SYNCTEX_STATUS_OK; +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark SPECIAL CHARACTERS +#endif + +/* Here are the control characters that strat each line of the synctex output file. + * Their values define the meaning of the line. + */ +#define SYNCTEX_CHAR_BEGIN_SHEET '{' +#define SYNCTEX_CHAR_END_SHEET '}' +#define SYNCTEX_CHAR_BEGIN_FORM '<' +#define SYNCTEX_CHAR_END_FORM '>' +#define SYNCTEX_CHAR_BEGIN_VBOX '[' +#define SYNCTEX_CHAR_END_VBOX ']' +#define SYNCTEX_CHAR_BEGIN_HBOX '(' +#define SYNCTEX_CHAR_END_HBOX ')' +#define SYNCTEX_CHAR_ANCHOR '!' +#define SYNCTEX_CHAR_VOID_VBOX 'v' +#define SYNCTEX_CHAR_VOID_HBOX 'h' +#define SYNCTEX_CHAR_KERN 'k' +#define SYNCTEX_CHAR_GLUE 'g' +#define SYNCTEX_CHAR_RULE 'r' +#define SYNCTEX_CHAR_MATH '$' +#define SYNCTEX_CHAR_FORM_REF 'f' +#define SYNCTEX_CHAR_BOUNDARY 'x' +#define SYNCTEX_CHAR_CHARACTER 'c' +#define SYNCTEX_CHAR_COMMENT '%' + +#define SYNCTEX_RETURN(STATUS) return STATUS; + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark SCANNERS & PARSERS +#endif + +#define SYNCTEX_DECODE_FAILED(NODE, WHAT) (_synctex_data_decode_##WHAT(NODE) < SYNCTEX_STATUS_OK) +#define SYNCTEX_DECODE_FAILED_V(NODE, WHAT) (_synctex_data_decode_##WHAT##_v(NODE) < SYNCTEX_STATUS_OK) + +#define SYNCTEX_NS_NULL \ + (synctex_ns_s) \ + { \ + NULL, SYNCTEX_STATUS_NOT_OK \ + } +static synctex_ns_s _synctex_parse_new_sheet(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_sheet(scanner))) { + if (SYNCTEX_DECODE_FAILED(node, page)) { + _synctex_error("Bad sheet record."); + } else if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of sheet."); + } else { + /* Now set the owner */ + if (scanner->sheet) { + synctex_node_p last_sheet = scanner->sheet; + synctex_node_p next_sheet = NULL; + while ((next_sheet = __synctex_tree_sibling(last_sheet))) { + last_sheet = next_sheet; + } + __synctex_tree_set_sibling(last_sheet, node); /* sheets have no parent */ + } else { + scanner->sheet = node; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_free_node(node); + } + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +/** + * - requirement: scanner != NULL + */ +static synctex_ns_s _synctex_parse_new_form(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_form(scanner))) { + if (SYNCTEX_DECODE_FAILED(node, tag)) { + _synctex_error("Bad sheet record."); + } else if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of form."); + } else { + /* Now set the owner */ + if (scanner->form) { + synctex_node_p last_form = scanner->form; + synctex_node_p next_form = NULL; + while ((next_form = __synctex_tree_sibling(last_form))) { + last_form = next_form; + } + __synctex_tree_set_sibling(last_form, node); + } else { + scanner->form = node; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_free_node(node); + } + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +#define SYNCTEX_SHOULD_DECODE_FAILED(NODE, WHAT) (_synctex_data_has_##WHAT(NODE) && (_synctex_data_decode_##WHAT(NODE) < SYNCTEX_STATUS_OK)) +#define SYNCTEX_SHOULD_DECODE_FAILED_V(NODE, WHAT) (_synctex_data_has_##WHAT(NODE) && (_synctex_data_decode_##WHAT##_v(NODE) < SYNCTEX_STATUS_OK)) + +static synctex_status_t _synctex_data_decode_tlchvwhd(synctex_node_p node) +{ + return SYNCTEX_SHOULD_DECODE_FAILED(node, tag) || SYNCTEX_SHOULD_DECODE_FAILED(node, line) || SYNCTEX_SHOULD_DECODE_FAILED(node, column) || SYNCTEX_SHOULD_DECODE_FAILED(node, h) || SYNCTEX_SHOULD_DECODE_FAILED_V(node, v) || + SYNCTEX_SHOULD_DECODE_FAILED(node, width) || SYNCTEX_SHOULD_DECODE_FAILED(node, height) || SYNCTEX_SHOULD_DECODE_FAILED(node, depth); +} +static synctex_ns_s _synctex_parse_new_vbox(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_vbox(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad vbox record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of vbox."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node); +static synctex_ns_s _synctex_parse_new_hbox(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_hbox(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad hbox record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of hbox."); + goto out; + } + if (_synctex_setup_visible_hbox(node) < SYNCTEX_STATUS_OK) { + _synctex_error("Unexpected error (_synctex_parse_new_hbox)."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_void_vbox(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_void_vbox(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad void vbox record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_void_hbox(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_void_hbox(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad void hbox record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_kern(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_kern(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad kern record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_glue(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_glue(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad glue record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_rule(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_rule(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad rule record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_math(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_math(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad math record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +static synctex_ns_s _synctex_parse_new_boundary(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_boundary(scanner))) { + if (_synctex_data_decode_tlchvwhd(node)) { + _synctex_error("Bad boundary record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +SYNCTEX_INLINE static synctex_ns_s _synctex_parse_new_ref(synctex_scanner_p scanner) +{ + synctex_node_p node; + if ((node = _synctex_new_ref(scanner))) { + if (SYNCTEX_DECODE_FAILED(node, tag) || SYNCTEX_DECODE_FAILED(node, h) || SYNCTEX_DECODE_FAILED_V(node, v)) { + _synctex_error("Bad form ref record."); + _synctex_next_line(scanner); + out: + _synctex_free_node(node); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + goto out; + } + return (synctex_ns_s) {node, SYNCTEX_STATUS_OK}; + } + _synctex_next_line(scanner); + return (synctex_ns_s) {NULL, SYNCTEX_STATUS_ERROR}; +} +#undef SYNCTEX_DECODE_FAILED +#undef SYNCTEX_DECODE_FAILED_V + +SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node); +SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node); +SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point); +SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node); +SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node); +SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node); + +SYNCTEX_INLINE static synctex_node_p _synctex_input_register_line(synctex_node_p input, synctex_node_p node) +{ + if (node && _synctex_data_tag(input) != _synctex_data_tag(node)) { + input = synctex_scanner_input_with_tag(node->class->scanner, _synctex_data_tag(node)); + } + if (_synctex_data_line(node) > _synctex_data_line(input)) { + _synctex_data_set_line(input, _synctex_data_line(node)); + } + return input; +} +/** + * Scan sheets, forms and input records. + * - parameter scanner: owning scanner + * - returns: status + */ +static synctex_status_t __synctex_parse_sfi(synctex_scanner_p scanner) +{ + synctex_status_t status = SYNCTEX_STATUS_OK; + synctex_zs_s zs = {0, 0}; + synctex_ns_s input = SYNCTEX_NS_NULL; + synctex_node_p sheet = NULL; + synctex_node_p form = NULL; + synctex_node_p parent = NULL; + synctex_node_p child = NULL; + synctex_ns_s ns = SYNCTEX_NS_NULL; + int form_depth = 0; + int ignored_form_depth = 0; + synctex_bool_t try_input = synctex_YES; +#ifdef SYNCTEX_NOTHING +#pragma mark MAIN LOOP +#endif +main_loop: + status = SYNCTEX_STATUS_OK; + sheet = form = parent = child = NULL; +#define SYNCTEX_START_SCAN(WHAT) (*SYNCTEX_CUR == SYNCTEX_CHAR_##WHAT) + if (SYNCTEX_CUR < SYNCTEX_END) { + if (SYNCTEX_START_SCAN(BEGIN_FORM)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN FORM +#endif + scan_form: + ns = _synctex_parse_new_form(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + ++form_depth; + if (_synctex_tree_parent(form)) { + /* This form is already being parsed */ + ++ignored_form_depth; + goto ignore_loop; + } + _synctex_tree_set_parent(ns.node, form); + form = ns.node; + parent = form; + child = NULL; + goto content_loop; + } + if (form || sheet) { + goto content_loop; + } + try_input = synctex_YES; + goto main_loop; + } else if (SYNCTEX_START_SCAN(BEGIN_SHEET)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN SHEET +#endif + try_input = synctex_YES; + ns = _synctex_parse_new_sheet(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + sheet = ns.node; + parent = sheet; + goto content_loop; + } + goto main_loop; + } else if (SYNCTEX_START_SCAN(ANCHOR)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN ANCHOR +#endif + scan_anchor: + ++SYNCTEX_CUR; + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing anchor."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + if (form || sheet) { + goto content_loop; + } + try_input = synctex_YES; + goto main_loop; + } else if (SYNCTEX_START_SCAN(ANCHOR)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN COMMENT +#endif + ++SYNCTEX_CUR; + _synctex_next_line(scanner); + try_input = synctex_YES; + goto main_loop; + } else if (try_input) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN INPUT +#endif + try_input = synctex_NO; + do { + input = __synctex_parse_new_input(scanner); + } while (input.status == SYNCTEX_STATUS_OK); + goto main_loop; + } + status = _synctex_match_string(scanner, "Postamble:"); + if (status == SYNCTEX_STATUS_OK) { + scanner->flags.postamble = 1; + return status; + } + status = _synctex_next_line(scanner); + if (status < SYNCTEX_STATUS_OK) { + return status; + } + } + /* At least 1 more character */ + zs = _synctex_buffer_get_available_size(scanner, 1); + if (zs.size == 0) { + _synctex_error("Uncomplete synctex file, postamble missing."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto main_loop; + /* Unreachable. */ +#ifdef SYNCTEX_NOTHING +#pragma mark IGNORE LOOP +#endif +ignore_loop: + ns = SYNCTEX_NS_NULL; + if (SYNCTEX_CUR < SYNCTEX_END) { + if (SYNCTEX_START_SCAN(BEGIN_FORM)) { + ++ignored_form_depth; + } else if (SYNCTEX_START_SCAN(END_FORM)) { + --ignored_form_depth; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Uncomplete container."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + } else { + zs = _synctex_buffer_get_available_size(scanner, 1); + if (zs.size == 0) { + _synctex_error("Uncomplete synctex file, postamble missing."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + } + if (ignored_form_depth) { + goto ignore_loop; + } else { + goto content_loop; + } + +#ifdef SYNCTEX_NOTHING +#pragma mark CONTENT LOOP +#endif +content_loop: + /* Either in a form, a sheet or a box. + * - in a sheet, "{" is not possible, only boxes and "}" at top level. + * - in a form, "{" is not possible, only boxes, "<" and ">" at top level. + * - in a box, the unique possibility is '<', '[', '(' or ">". + * We still keep the '(' for a sheet, because that dos not cost too much. + * We must also consider void boxes as children. + */ + /* forms are everywhere */ + ns = SYNCTEX_NS_NULL; +#ifdef SYNCTEX_VERBOSE + synctex_scanner_set_display_switcher(scanner, -1); + printf("NEW CONTENT LOOP\n"); +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + synctex_node_display(sheet); +#endif +#endif + if (SYNCTEX_CUR < SYNCTEX_END) { + if (SYNCTEX_START_SCAN(BEGIN_FORM)) { + goto scan_form; + } else if (SYNCTEX_START_SCAN(BEGIN_VBOX)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN VBOX +#endif + ns = _synctex_parse_new_vbox(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + parent = ns.node; + child = _synctex_tree_last(parent); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(parent); +#endif + input.node = _synctex_input_register_line(input.node, parent); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(END_VBOX)) { + if (synctex_node_type(parent) == synctex_node_type_vbox) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN XOBV +#endif + ++SYNCTEX_CUR; + if (NULL == _synctex_tree_child(parent) && !form) { + /* only void v boxes are friends */ + _synctex_node_make_friend_tlc(parent); + } + child = parent; + parent = _synctex_tree_parent(child); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Uncomplete container."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(BEGIN_HBOX)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN HBOX +#endif +#if defined(SYNCTEX_USE_CHARINDEX) + synctex_charindex_t char_index = (synctex_charindex_t)(scanner->reader->charindex_offset + SYNCTEX_CUR - SYNCTEX_START); + synctex_lineindex_t line_index = scanner->reader->line_number; +#endif + ns = _synctex_parse_new_hbox(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + parent = ns.node; + /* add a box boundary node at the start */ + if ((child = _synctex_new_box_bdry(scanner))) { +#if defined(SYNCTEX_USE_CHARINDEX) + child->line_index = line_index; + child->char_index = char_index; +#endif + _synctex_node_set_child(parent, child); + _synctex_data_set_tag(child, _synctex_data_tag(parent)); + _synctex_data_set_line(child, _synctex_data_line(parent)); + _synctex_data_set_h(child, _synctex_data_h(parent)); + _synctex_data_set_v(child, _synctex_data_v(parent)); + if (!form) { + __synctex_node_make_friend_tlc(child); + } + } else { + _synctex_error("Can't create box bdry record."); + } +#ifdef SYNCTEX_VERBOSE + synctex_node_log(parent); +#endif + input.node = _synctex_input_register_line(input.node, parent); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(END_HBOX)) { + if (synctex_node_type(parent) == synctex_node_type_hbox) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN XOBH +#endif + ++SYNCTEX_CUR; + { + /* setting the next horizontal box at the end ensures + * that a child is recorded before any of its ancestors. + */ + if (form == NULL /* && sheet != NULL*/) { + _synctex_tree_set_next_hbox(parent, _synctex_tree_next_hbox(sheet)); + _synctex_tree_set_next_hbox(sheet, parent); + } + /* Update the mean line number */ + synctex_node_p node = _synctex_tree_child(parent); + synctex_node_p sibling = NULL; + /* Ignore the first node (a box_bdry) */ + if (node && (node = __synctex_tree_sibling(node))) { + unsigned int node_weight = 0; + unsigned int cumulated_line_numbers = 0; + do { + if (synctex_node_type(node) == synctex_node_type_hbox) { + if (_synctex_data_weight(node)) { + node_weight += _synctex_data_weight(node); + cumulated_line_numbers += _synctex_data_mean_line(node) * _synctex_data_weight(node); + } else { + ++node_weight; + cumulated_line_numbers += _synctex_data_mean_line(node); + } + } else { + ++node_weight; + cumulated_line_numbers += synctex_node_line(node); + } + } while ((node = __synctex_tree_sibling(node))); + _synctex_data_set_mean_line(parent, (cumulated_line_numbers + node_weight / 2) / node_weight); + _synctex_data_set_weight(parent, node_weight); + } else { + _synctex_data_set_mean_line(parent, _synctex_data_line(parent)); + _synctex_data_set_weight(parent, 1); + } + if ((sibling = _synctex_new_box_bdry(scanner))) { +#if defined(SYNCTEX_USE_CHARINDEX) + sibling->line_index = child->line_index; + sibling->char_index = child->char_index; +#endif + _synctex_node_set_sibling(child, sibling); + { + synctex_node_p N = child; + while (synctex_node_type(N) == synctex_node_type_ref) { + N = _synctex_tree_arg_sibling(N); + } + _synctex_data_set_tag(sibling, _synctex_data_tag(N)); + _synctex_data_set_line(sibling, _synctex_data_line(N)); + } + _synctex_data_set_h(sibling, _synctex_data_h_V(parent) + _synctex_data_width_V(parent)); + _synctex_data_set_v(sibling, _synctex_data_v_V(parent)); + child = sibling; + } else { + _synctex_error("Can't create box bdry record."); + } + sibling = _synctex_tree_child(parent); + _synctex_data_set_point(sibling, _synctex_data_point_V(parent)); + child = parent; + parent = _synctex_tree_parent(child); + _synctex_make_hbox_contain_box(parent, _synctex_data_box_V(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Uncomplete container."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(VOID_VBOX)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN VOID VBOX +#endif + ns = _synctex_parse_new_void_vbox(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(VOID_HBOX)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN VOID HBOX +#endif + ns = _synctex_parse_new_void_hbox(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (_synctex_data_width(ns.node) < 0) { + printf("Negative width\n"); + } + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + _synctex_make_hbox_contain_box(parent, _synctex_data_box(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(KERN)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN KERN +#endif + ns = _synctex_parse_new_kern(scanner); + /* continue_scan: */ + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (!form) { + __synctex_node_make_friend_tlc(child); + } + _synctex_make_hbox_contain_box(parent, _synctex_data_xob(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(GLUE)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN GLUE +#endif + ns = _synctex_parse_new_glue(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (!form) { + __synctex_node_make_friend_tlc(child); + } + _synctex_make_hbox_contain_point(parent, _synctex_data_point(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(RULE)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN RULE +#endif + ns = _synctex_parse_new_rule(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (!form) { + __synctex_node_make_friend_tlc(child); + } + /* Rules are sometimes far too big +_synctex_make_hbox_contain_box(parent,_synctex_data_box(child)); + */ +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(MATH)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN MATH +#endif + ns = _synctex_parse_new_math(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (!form) { + __synctex_node_make_friend_tlc(child); + } + _synctex_make_hbox_contain_point(parent, _synctex_data_point(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(FORM_REF)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN FORM REF +#endif +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + synctex_node_display(parent); + synctex_node_display(child); +#endif + ns = _synctex_parse_new_ref(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (form) { + if (scanner->ref_in_form) { + synctex_tree_set_friend(child, scanner->ref_in_form); + } + scanner->ref_in_form = child; + } else { + if (scanner->ref_in_sheet) { + synctex_tree_set_friend(child, scanner->ref_in_sheet); + } + scanner->ref_in_sheet = child; + } +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(BOUNDARY)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN BOUNDARY +#endif + ns = _synctex_parse_new_boundary(scanner); + if (ns.status == SYNCTEX_STATUS_OK) { + if (child) { + _synctex_node_set_sibling(child, ns.node); + } else { + _synctex_node_set_child(parent, ns.node); + } + child = ns.node; + if (!form) { + __synctex_node_make_friend_tlc(child); + } + _synctex_make_hbox_contain_point(parent, _synctex_data_point(child)); +#ifdef SYNCTEX_VERBOSE + synctex_node_log(child); +#endif + input.node = _synctex_input_register_line(input.node, child); + goto content_loop; + } + } else if (SYNCTEX_START_SCAN(CHARACTER)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN CHARACTER +#endif + ++SYNCTEX_CUR; + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of container."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto content_loop; + } else if (SYNCTEX_START_SCAN(ANCHOR)) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN ANCHOR +#endif + goto scan_anchor; + } else if (SYNCTEX_START_SCAN(END_SHEET)) { + if (sheet && parent == sheet) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN TEEHS +#endif + ++SYNCTEX_CUR; + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing anchor."); + } + parent = sheet = NULL; + goto main_loop; + } + } else if (SYNCTEX_START_SCAN(END_FORM)) { + if (parent == form && form_depth > 0) { +#ifdef SYNCTEX_NOTHING +#pragma mark + SCAN MROF +#endif + ++SYNCTEX_CUR; + --form_depth; + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK && (form_depth || sheet)) { + _synctex_error("Missing end of container."); + return SYNCTEX_STATUS_ERROR; + } + if ((parent = _synctex_tree_parent(form))) { + _synctex_tree_reset_parent(form); + child = form; + form = parent; + goto content_loop; + } else if (sheet) { + form = NULL; + parent = sheet; + child = synctex_node_last_sibling(child); + goto content_loop; + } + goto main_loop; + } + } + _synctex_error("Ignored record <%.20s...>(line %i)\n", SYNCTEX_CUR, scanner->reader->line_number + 1); + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Missing end of sheet/form."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto content_loop; + } + zs = _synctex_buffer_get_available_size(scanner, 1); + if (zs.size == 0) { + _synctex_error("Uncomplete synctex file, postamble missing."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto content_loop; +} +/** + * Replace ref in its tree hierarchy by a single box + * proxy to the contents of the associated form. + * - argument ref: a ref node with no friend + * - return the proxy created. + * - note: Does nothing if ref is not owned. + * - note: On return, ref will have no parent nor sibling. + * The caller is responsible for releasing ref. + * - note: this is where root proxies are created. + * - note: the target of the root proxy is the content + * of a form. + */ +SYNCTEX_INLINE static synctex_ns_s __synctex_replace_ref(synctex_node_p ref) +{ + synctex_ns_s ns = {NULL, SYNCTEX_STATUS_OK}; + synctex_node_p parent; + if ((parent = _synctex_tree_parent(ref))) { + synctex_node_p sibling = __synctex_tree_reset_sibling(ref); + synctex_node_p arg_sibling = synctex_node_arg_sibling(ref); + /* arg_sibling != NULL because the child of a box + * is always a box boundary, not a ref. */ + synctex_node_p target = synctex_form_content(ref->class->scanner, _synctex_data_tag(ref)); + /* The target is a single node (box) + * with children and no siblings. */ + if ((ns.node = __synctex_new_proxy_from_ref_to(ref, target))) { + /* Insert this proxy instead of ref. */ + _synctex_node_set_sibling(arg_sibling, ns.node); + /* Then append the original sibling of ref. */ + _synctex_node_set_sibling(ns.node, sibling); +#if defined(SYNCTEX_USE_CHARINDEX) + if (synctex_node_type(sibling) == synctex_node_type_box_bdry) { + /* The sibling is the last box boundary + * which may have a less accurate information */ + sibling->char_index = arg_sibling->char_index; + sibling->line_index = arg_sibling->line_index; + } +#endif +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("! Ref replacement:\n"); + synctex_node_log(ref); + synctex_node_display(synctex_node_sibling(ref)); +#endif + } else /* simply remove ref */ { + _synctex_tree_set_sibling(arg_sibling, sibling); + } + __synctex_tree_reset_parent(ref); + } else { + _synctex_error( + "! Missing parent in __synctex_replace_ref. " + "Please report."); + ns.status = SYNCTEX_STATUS_BAD_ARGUMENT; + } + return ns; +} +/** + * - argument ref: is the starting point of a linked list + * of refs. The link is made through the friend field. + * - returns: the status and the list of all the proxies + * created. The link is made through the friend field. + * - note: All refs are freed + */ +SYNCTEX_INLINE static synctex_ns_s _synctex_post_process_ref(synctex_node_p ref) +{ + synctex_ns_s ns = {NULL, SYNCTEX_STATUS_OK}; + while (ref) { + synctex_node_p next_ref = _synctex_tree_reset_friend(ref); + synctex_ns_s sub_ns = __synctex_replace_ref(ref); + if (sub_ns.status < ns.status) { + ns.status = sub_ns.status; + } else { + /* Insert all the created proxies in the list + * sub_ns.node is the last friend, + */ + synctex_tree_set_friend(sub_ns.node, ns.node); + ns.node = sub_ns.node; + } + synctex_node_free(ref); + ref = next_ref; + } + return ns; +} +typedef synctex_node_p (*synctex_processor_f)(synctex_node_p node); +/** + * Apply the processor f to the tree hierarchy rooted at proxy. + * proxy has replaced a form ref, no children yet. + * As a side effect all the hierarchy of nodes will be created. + */ +SYNCTEX_INLINE static synctex_status_t _synctex_post_process_proxy(synctex_node_p proxy, synctex_processor_f f) +{ + while (proxy) { + synctex_node_p next_proxy = _synctex_tree_friend(proxy); + synctex_node_p halt = __synctex_tree_sibling(proxy); + /* if proxy is the last sibling, halt is NULL. + * Find what should be a next node, + * without creating new nodes. */ + if (!halt) { + synctex_node_p parent = _synctex_tree_parent(proxy); + halt = __synctex_tree_sibling(parent); + while (!halt && parent) { + parent = _synctex_tree_parent(parent); + halt = __synctex_tree_sibling(parent); + } + } + do { +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("POST PROCESSING %s\n", _synctex_node_abstract(proxy)); + { + int i, j = 0; + for (i = 0; i < proxy->class->scanner->number_of_lists; ++i) { + synctex_node_p N = proxy->class->scanner->lists_of_friends[i]; + do { + if (N == proxy) { + ++j; + printf("%s", _synctex_node_abstract(N)); + } + } while ((N = _synctex_tree_friend(N))); + } + if (j) { + printf("\nBeforehand %i match\n", j); + } + } +#endif + f(proxy); +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + { + int i, j = 0; + for (i = 0; i < proxy->class->scanner->number_of_lists; ++i) { + synctex_node_p N = proxy->class->scanner->lists_of_friends[i]; + do { + if (N == proxy) { + ++j; + printf("%s", _synctex_node_abstract(N)); + } + } while ((N = _synctex_tree_friend(N))); + } + if (j) { + printf("\n%i match\n", j); + } + } +#endif + /* Side effect: create the hierarchy on the fly */ + proxy = synctex_node_next(proxy); /* Change is here */ +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + if (proxy) { + int i, j = 0; + for (i = 0; i < proxy->class->scanner->number_of_lists; ++i) { + synctex_node_p N = proxy->class->scanner->lists_of_friends[i]; + do { + if (N == proxy) { + ++j; + printf("%s", _synctex_node_abstract(N)); + } + } while ((N = _synctex_tree_friend(N))); + } + if (j) { + printf("\nnext %i match\n", j); + } + } +#endif + } while (proxy && proxy != halt); + proxy = next_proxy; + } + return SYNCTEX_STATUS_OK; +} +/** + * Replace all the form refs by root box proxies. + * Create the node hierarchy and update the friends. + * On entry, the refs are collected as a friend list + * in either a form or a sheet + * - parameter: the owning scanner + */ +SYNCTEX_INLINE static synctex_status_t _synctex_post_process(synctex_scanner_p scanner) +{ + synctex_status_t status = SYNCTEX_STATUS_OK; + synctex_ns_s ns = {NULL, SYNCTEX_STATUS_NOT_OK}; +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("! entering _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +#endif + /* replace form refs inside forms by box proxies */ + ns = _synctex_post_process_ref(scanner->ref_in_form); + scanner->ref_in_form = NULL; /* it was just released */ + if (ns.status < status) { + status = ns.status; + } +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("! ref replaced in form _synctex_post_process.\n"); + synctex_node_display(scanner->form); +#endif + /* Create all the form proxy nodes on the fly. + * ns.node is the root of the list of + * newly created proxies. + * There might be a problem with cascading proxies. + * In order to be properly managed, the data must + * be organized in the right way. + * The inserted form must be defined before + * the inserting one. *TeX will take care of that. */ + ns.status = _synctex_post_process_proxy(ns.node, &_synctex_tree_reset_friend); + if (ns.status < status) { + status = ns.status; + } + /* replace form refs inside sheets by box proxies */ + ns = _synctex_post_process_ref(scanner->ref_in_sheet); + if (ns.status < status) { + status = ns.status; + } + scanner->ref_in_sheet = NULL; +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("! ref replaced in sheet _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); +#endif +#if 0 + { + int i; + for (i=0;inumber_of_lists;++i) { + synctex_node_p P = ns.node; + do { + synctex_node_p N = scanner->lists_of_friends[i]; + do { + if (P == N) { + printf("Already registered.\n"); + synctex_node_display(N); + break; + } + } while ((N = _synctex_tree_friend(N))); + } while((P = _synctex_tree_friend(P))); + } + } +#endif +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 10000 + { + int i; + for (i = 0; i < scanner->number_of_lists; ++i) { + synctex_node_p P = scanner->lists_of_friends[i]; + int j = 0; + while (P) { + ++j; + synctex_node_log(P); + P = _synctex_tree_friend(P); + } + if (j) { + printf("friends %i -> # %i\n", i, j); + } + } + } +#endif + ns.status = _synctex_post_process_proxy(ns.node, &__synctex_proxy_make_friend_and_next_hbox); + if (ns.status < status) { + status = ns.status; + } +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + printf("! exiting _synctex_post_process.\n"); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); + printf("! display all.\n"); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +#endif + return status; +} +/* Used when parsing the synctex file + */ +static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner) +{ + scanner->reader->lastv = -1; + synctex_status_t status = 0; + if (NULL == scanner) { + return SYNCTEX_STATUS_BAD_ARGUMENT; + } + /* Find where this section starts */ +content_not_found: + status = _synctex_match_string(scanner, "Content:"); + if (status < SYNCTEX_STATUS_EOF) { + return status; + } + if (_synctex_next_line(scanner) < SYNCTEX_STATUS_OK) { + _synctex_error("Uncomplete Content."); + return SYNCTEX_STATUS_ERROR; + } + if (status == SYNCTEX_STATUS_NOT_OK) { + goto content_not_found; + } + status = __synctex_parse_sfi(scanner); + if (status == SYNCTEX_STATUS_OK) { + status = _synctex_post_process(scanner); + } + return status; +} +synctex_scanner_p synctex_scanner_new() +{ + synctex_scanner_p scanner = (synctex_scanner_p)_synctex_malloc(sizeof(synctex_scanner_s)); + if (scanner) { + if (!(scanner->reader = _synctex_malloc(sizeof(synctex_reader_s)))) { + _synctex_free(scanner); + return NULL; + } +#ifdef SYNCTEX_NOTHING +#pragma mark - +#endif +#define DEFINE_synctex_scanner_class(NAME) \ + scanner->class[synctex_node_type_##NAME] = synctex_class_##NAME; \ + (scanner->class[synctex_node_type_##NAME]).scanner = scanner + DEFINE_synctex_scanner_class(input); + DEFINE_synctex_scanner_class(sheet); + DEFINE_synctex_scanner_class(form); + DEFINE_synctex_scanner_class(hbox); + DEFINE_synctex_scanner_class(void_hbox); + DEFINE_synctex_scanner_class(vbox); + DEFINE_synctex_scanner_class(void_vbox); + DEFINE_synctex_scanner_class(kern); + DEFINE_synctex_scanner_class(glue); + DEFINE_synctex_scanner_class(rule); + DEFINE_synctex_scanner_class(math); + DEFINE_synctex_scanner_class(boundary); + DEFINE_synctex_scanner_class(box_bdry); + DEFINE_synctex_scanner_class(ref); + DEFINE_synctex_scanner_class(proxy_hbox); + DEFINE_synctex_scanner_class(proxy_vbox); + DEFINE_synctex_scanner_class(proxy); + DEFINE_synctex_scanner_class(proxy_last); + DEFINE_synctex_scanner_class(handle); + /* set up the lists of friends */ + scanner->number_of_lists = 1024; + scanner->lists_of_friends = (synctex_node_r)_synctex_malloc(scanner->number_of_lists * sizeof(synctex_node_p)); + if (NULL == scanner->lists_of_friends) { + synctex_scanner_free(scanner); + _synctex_error("malloc:2"); + return NULL; + } + scanner->display_switcher = 100; + scanner->display_prompt = (char *)_synctex_display_prompt + strlen(_synctex_display_prompt) - 1; + } + return scanner; +} +/* Where the synctex scanner is created. */ +synctex_scanner_p synctex_scanner_new_with_output_file(const char *output, const char *build_directory, int parse) +{ + synctex_scanner_p scanner = synctex_scanner_new(); + if (NULL == scanner) { + _synctex_error("malloc problem"); + return NULL; + } + if ((scanner->reader = synctex_reader_init_with_output_file(scanner->reader, output, build_directory))) { + return parse ? synctex_scanner_parse(scanner) : scanner; + } +#if defined(SYNCTEX_DEBUG) + _synctex_error("No file?"); +#endif + synctex_scanner_free(scanner); + return NULL; +} + +/* The scanner destructor + */ +int synctex_scanner_free(synctex_scanner_p scanner) +{ + int node_count = 0; + if (scanner) { + if (scanner->reader && SYNCTEX_FILE) { + gzclose(SYNCTEX_FILE); + SYNCTEX_FILE = NULL; + } + synctex_node_free(scanner->sheet); + synctex_node_free(scanner->form); + synctex_node_free(scanner->input); + synctex_reader_free(scanner->reader); + SYNCTEX_SCANNER_FREE_HANDLE(scanner); + synctex_iterator_free(scanner->iterator); + free(scanner->output_fmt); + free(scanner->lists_of_friends); +#if defined SYNCTEX_USE_NODE_COUNT && SYNCTEX_USE_NODE_COUNT > 0 + node_count = scanner->node_count; +#endif + free(scanner); + } + return node_count; +} + +/* Where the synctex scanner parses the contents of the file. */ +synctex_scanner_p synctex_scanner_parse(synctex_scanner_p scanner) +{ + synctex_status_t status = 0; + if (!scanner || scanner->flags.has_parsed) { + return scanner; + } + scanner->flags.has_parsed = 1; + scanner->pre_magnification = 1000; + scanner->pre_unit = 8192; + scanner->pre_x_offset = scanner->pre_y_offset = 578; + /* initialize the offset with a fake unprobable value, + * If there is a post scriptum section, this value will be overridden by the real life value */ + scanner->x_offset = scanner->y_offset = 6.027e23f; + scanner->reader->line_number = 1; + + /* TODO: cleanup + * In some (all?) cases SYNCTEX_START is already initialized + * in synctex_reader_init_with_output_file(). Much of the + * following code seems like a duplicate and is perhaps a + * candidate for deletion. To be on the safe side though, we + * keep it for now and just free() any prior malloc() if + * existing. */ + _synctex_free(SYNCTEX_START); + + SYNCTEX_START = (char *)malloc(SYNCTEX_BUFFER_SIZE + 1); /* one more character for null termination */ + if (NULL == SYNCTEX_START) { + _synctex_error("! malloc error in synctex_scanner_parse."); + bailey: +#ifdef SYNCTEX_DEBUG + return scanner; +#else + synctex_scanner_free(scanner); + return NULL; +#endif + } + synctex_scanner_set_display_switcher(scanner, 1000); + SYNCTEX_END = SYNCTEX_START + SYNCTEX_BUFFER_SIZE; + /* SYNCTEX_END always points to a null terminating character. + * Maybe there is another null terminating character between SYNCTEX_CUR and SYNCTEX_END-1. + * At least, we are sure that SYNCTEX_CUR points to a string covering a valid part of the memory. */ + *SYNCTEX_END = '\0'; + SYNCTEX_CUR = SYNCTEX_END; +#if defined(SYNCTEX_USE_CHARINDEX) + scanner->reader->charindex_offset = -SYNCTEX_BUFFER_SIZE; +#endif + status = _synctex_scan_preamble(scanner); + if (status < SYNCTEX_STATUS_OK) { + _synctex_error("Bad preamble\n"); + goto bailey; + } + status = _synctex_scan_content(scanner); + if (status < SYNCTEX_STATUS_OK) { + _synctex_error("Bad content\n"); + goto bailey; + } + status = _synctex_scan_postamble(scanner); + if (status < SYNCTEX_STATUS_OK) { + _synctex_error("Bad postamble. Ignored\n"); + } +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + synctex_scanner_set_display_switcher(scanner, 100); + synctex_node_display(scanner->sheet); + synctex_node_display(scanner->form); +#endif + synctex_scanner_set_display_switcher(scanner, 1000); + /* Everything is finished, free the buffer, close the file */ + free((void *)SYNCTEX_START); + SYNCTEX_START = SYNCTEX_CUR = SYNCTEX_END = NULL; + gzclose(SYNCTEX_FILE); + SYNCTEX_FILE = NULL; + /* Final tuning: set the default values for various parameters */ + /* 1 pre_unit = (scanner->pre_unit)/65536 pt = (scanner->pre_unit)/65781.76 bp + * 1 pt = 65536 sp */ + if (scanner->pre_unit <= 0) { + scanner->pre_unit = 8192; + } + if (scanner->pre_magnification <= 0) { + scanner->pre_magnification = 1000; + } + if (scanner->unit <= 0) { + /* no post magnification */ + scanner->unit = scanner->pre_unit / 65781.76; /* 65781.76 or 65536.0*/ + } else { + /* post magnification */ + scanner->unit *= scanner->pre_unit / 65781.76; + } + scanner->unit *= scanner->pre_magnification / 1000.0; + if (scanner->x_offset > 6e23) { + /* no post offset */ + scanner->x_offset = scanner->pre_x_offset * (scanner->pre_unit / 65781.76); + scanner->y_offset = scanner->pre_y_offset * (scanner->pre_unit / 65781.76); + } else { + /* post offset */ + scanner->x_offset /= 65781.76f; + scanner->y_offset /= 65781.76f; + } + return scanner; +#undef SYNCTEX_FILE +} + +/* Scanner accessors. + */ +int synctex_scanner_pre_x_offset(synctex_scanner_p scanner) +{ + return scanner ? scanner->pre_x_offset : 0; +} +int synctex_scanner_pre_y_offset(synctex_scanner_p scanner) +{ + return scanner ? scanner->pre_y_offset : 0; +} +int synctex_scanner_x_offset(synctex_scanner_p scanner) +{ + return scanner ? scanner->x_offset : 0; +} +int synctex_scanner_y_offset(synctex_scanner_p scanner) +{ + return scanner ? scanner->y_offset : 0; +} +float synctex_scanner_magnification(synctex_scanner_p scanner) +{ + return scanner ? scanner->unit : 1; +} +void synctex_scanner_display(synctex_scanner_p scanner) +{ + if (NULL == scanner) { + return; + } + printf("The scanner:\noutput:%s\noutput_fmt:%s\nversion:%i\n", scanner->reader->output, scanner->output_fmt, scanner->version); + printf("pre_unit:%i\nx_offset:%i\ny_offset:%i\n", scanner->pre_unit, scanner->pre_x_offset, scanner->pre_y_offset); + printf("count:%i\npost_magnification:%f\npost_x_offset:%f\npost_y_offset:%f\n", scanner->count, scanner->unit, scanner->x_offset, scanner->y_offset); + printf("The input:\n"); + synctex_node_display(scanner->input); + if (scanner->count < 1000) { + printf("The sheets:\n"); + synctex_node_display(scanner->sheet); + printf("The friends:\n"); + if (scanner->lists_of_friends) { + int i = scanner->number_of_lists; + synctex_node_p node; + while (i--) { + printf("Friend index:%i\n", i); + node = (scanner->lists_of_friends)[i]; + while (node) { + printf("%s:%i,%i\n", synctex_node_isa(node), _synctex_data_tag(node), _synctex_data_line(node)); + node = _synctex_tree_friend(node); + } + } + } + } else { + printf("SyncTeX Warning: Too many objects\n"); + } +} +/* Public */ +const char *synctex_scanner_get_name(synctex_scanner_p scanner, int tag) +{ + synctex_node_p input = NULL; + if (NULL == scanner) { + return NULL; + } + if ((input = scanner->input)) { + ; + do { + if (tag == _synctex_data_tag(input)) { + return (_synctex_data_name(input)); + } + } while ((input = __synctex_tree_sibling(input))); + } + return NULL; +} +const char *synctex_node_get_name(synctex_node_p node) +{ + if (node) { + return synctex_scanner_get_name(node->class->scanner, _synctex_data_tag(node)); + } + return NULL; +} + +static int _synctex_scanner_get_tag(synctex_scanner_p scanner, const char *name); +static int _synctex_scanner_get_tag(synctex_scanner_p scanner, const char *name) +{ + synctex_node_p input = NULL; + if (NULL == scanner) { + return 0; + } + if ((input = scanner->input)) { + do { + if (_synctex_is_equivalent_file_name(name, (_synctex_data_name(input)))) { + return _synctex_data_tag(input); + } + } while ((input = __synctex_tree_sibling(input))); + } + /* 2011 version */ + name = _synctex_base_name(name); + if ((input = scanner->input)) { + do { + if (_synctex_is_equivalent_file_name(name, _synctex_base_name(_synctex_data_name(input)))) { + synctex_node_p other_input = input; + while ((other_input = __synctex_tree_sibling(other_input))) { + if (_synctex_is_equivalent_file_name(name, _synctex_base_name(_synctex_data_name(other_input))) && + (strlen(_synctex_data_name(input)) != strlen(_synctex_data_name(other_input)) || strncmp(_synctex_data_name(other_input), _synctex_data_name(input), strlen(_synctex_data_name(input))))) { + /* There is a second possible candidate */ + return 0; + } + } + return _synctex_data_tag(input); + } + } while ((input = __synctex_tree_sibling(input))); + } + return 0; +} + +int synctex_scanner_get_tag(synctex_scanner_p scanner, const char *name) +{ + size_t char_index = strlen(name); + if ((scanner = synctex_scanner_parse(scanner)) && (0 < char_index)) { + /* the name is not void */ + char_index -= 1; + if (!SYNCTEX_IS_PATH_SEPARATOR(name[char_index])) { + /* the last character of name is not a path separator */ + int result = _synctex_scanner_get_tag(scanner, name); + if (result) { + return result; + } else { + /* the given name was not the one known by TeX + * try a name relative to the enclosing directory of the scanner->output file */ + const char *relative = name; + const char *ptr = scanner->reader->output; + while ((strlen(relative) > 0) && (strlen(ptr) > 0) && (*relative == *ptr)) { + relative += 1; + ptr += 1; + } + /* Find the last path separator before relative */ + while (relative > name) { + if (SYNCTEX_IS_PATH_SEPARATOR(*(relative - 1))) { + break; + } + relative -= 1; + } + if ((relative > name) && (result = _synctex_scanner_get_tag(scanner, relative))) { + return result; + } + if (SYNCTEX_IS_PATH_SEPARATOR(name[0])) { + /* No tag found for the given absolute name, + * Try each relative path starting from the shortest one */ + while (0 < char_index) { + char_index -= 1; + if (SYNCTEX_IS_PATH_SEPARATOR(name[char_index]) && (result = _synctex_scanner_get_tag(scanner, name + char_index + 1))) { + return result; + } + } + } + } + return result; + } + } + return 0; +} +synctex_node_p synctex_scanner_input(synctex_scanner_p scanner) +{ + return scanner ? scanner->input : NULL; +} +synctex_node_p synctex_scanner_input_with_tag(synctex_scanner_p scanner, int tag) +{ + synctex_node_p input = scanner ? scanner->input : NULL; + while (_synctex_data_tag(input) != tag) { + if ((input = __synctex_tree_sibling(input))) { + continue; + } + break; + } + return input; +} +const char *synctex_scanner_get_output_fmt(synctex_scanner_p scanner) +{ + return NULL != scanner && scanner->output_fmt ? scanner->output_fmt : ""; +} +const char *synctex_scanner_get_output(synctex_scanner_p scanner) +{ + return NULL != scanner && scanner->reader->output ? scanner->reader->output : ""; +} +const char *synctex_scanner_get_synctex(synctex_scanner_p scanner) +{ + return NULL != scanner && scanner->reader->synctex ? scanner->reader->synctex : ""; +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Public node attributes +#endif + +#define SYNCTEX_DEFINE_NODE_HVWHD(WHAT) \ + int synctex_node_##WHAT(synctex_node_p node) \ + { \ + return (node && node->class->inspector->WHAT) ? node->class->inspector->WHAT(node) : 0; \ + } +#define SYNCTEX_DEFINE_PROXY_HV(WHAT) \ + static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) \ + { \ + synctex_node_p target = _synctex_tree_target(proxy); \ + if (target) { \ + return _synctex_data_##WHAT(proxy) + synctex_node_##WHAT(target); \ + } else { \ + return proxy ? _synctex_data_##WHAT(proxy) : 0; \ + } \ + } +#define SYNCTEX_DEFINE_PROXY_TLCWVD(WHAT) \ + static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) \ + { \ + synctex_node_p target = _synctex_tree_target(proxy); \ + return target ? synctex_node_##WHAT(target) : 0; \ + } + +/** + * The horizontal location of the node. + * Idem for v, width, height and depth. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - requires: every proxy node has a target. + * - note: recursive call if the parameter has a proxy. + * - author: JL + */ +SYNCTEX_DEFINE_NODE_HVWHD(h) +SYNCTEX_DEFINE_NODE_HVWHD(v) +SYNCTEX_DEFINE_NODE_HVWHD(width) +SYNCTEX_DEFINE_NODE_HVWHD(height) +SYNCTEX_DEFINE_NODE_HVWHD(depth) +SYNCTEX_DEFINE_PROXY_TLCWVD(tag) +SYNCTEX_DEFINE_PROXY_TLCWVD(line) +SYNCTEX_DEFINE_PROXY_TLCWVD(column) +SYNCTEX_DEFINE_PROXY_HV(h) +SYNCTEX_DEFINE_PROXY_HV(v) +SYNCTEX_DEFINE_PROXY_TLCWVD(width) +SYNCTEX_DEFINE_PROXY_TLCWVD(height) +SYNCTEX_DEFINE_PROXY_TLCWVD(depth) + +/** + * Whether the argument is a box, + * either vertical or horizontal, + * either void or not, + * or a proxy to such a box. + * - parameter NODE: of type synctex_node_p + * - returns: yorn + */ + +SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_box(synctex_node_p node) +{ + return node && + (node->class->type == synctex_node_type_hbox || node->class->type == synctex_node_type_void_hbox || node->class->type == synctex_node_type_vbox || node->class->type == synctex_node_type_void_vbox || + _synctex_node_is_box(_synctex_tree_target(node))); +} + +/** + * Whether the argument is a handle. + * Handles are similar to proxies because they have a target. + * They are used for query results. + * - parameter NODE: of type synctex_node_p + * - returns: yorn + */ + +SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_handle(synctex_node_p node) +{ + return node && (node->class->type == synctex_node_type_handle); +} + +/** + * Resolves handle indirection. + * - parameter node: of type synctex_node_p + * - returns: node if it is not a handle, + * its target otherwise. + */ + +SYNCTEX_INLINE static synctex_node_p _synctex_node_or_handle_target(synctex_node_p node) +{ + return _synctex_node_is_handle(node) ? _synctex_tree_target(node) : node; +} + +/** + * Whether the argument is an hbox. + * - parameter NODE: of type synctex_node_p + * - returns: yorn + */ + +SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_hbox(synctex_node_p node) +{ + return node && (node->class->type == synctex_node_type_hbox || node->class->type == synctex_node_type_void_hbox || _synctex_node_is_hbox(_synctex_tree_target(node))); +} + +/** + * The horizontal location of the first box enclosing node. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - author: JL + */ +int synctex_node_box_h(synctex_node_p node) +{ + if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) { + return synctex_node_h(node); + } + return 0; +} +/** + * The vertical location of the first box enclosing node. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - author: JL + */ +int synctex_node_box_v(synctex_node_p node) +{ + if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) { + return synctex_node_v(node); + } + return 0; +} +/** + * The width of the first box enclosing node. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - author: JL + */ +int synctex_node_box_width(synctex_node_p node) +{ + if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) { + return synctex_node_width(node); + } + return 0; +} +/** + * The height of the first box enclosing node. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - author: JL + */ +int synctex_node_box_height(synctex_node_p node) +{ + if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) { + return synctex_node_height(node); + } + return 0; +} +/** + * The depth of the first box enclosing node. + * - parameter node: a node with geometrical information. + * - returns: an integer. + * - author: JL + */ +int synctex_node_box_depth(synctex_node_p node) +{ + if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) { + return synctex_node_depth(node); + } + return 0; +} +/** + * The horizontal location of an hbox, corrected with contents. + * - parameter node: an hbox node. + * - returns: an integer, 0 if node is not an hbox or an hbox proxy. + * - note: recursive call when node is an hbox proxy. + * - author: JL + */ +int synctex_node_hbox_h(synctex_node_p node) +{ + switch (synctex_node_type(node)) { + case synctex_node_type_hbox: + return _synctex_data_h_V(node); + case synctex_node_type_proxy_hbox: + return _synctex_data_h(node) + synctex_node_hbox_h(_synctex_tree_target(node)); + default: + return 0; + } +} +/** + * The vertical location of an hbox, corrected with contents. + * - parameter node: an hbox node. + * - returns: an integer, 0 if node is not an hbox or an hbox proxy. + * - note: recursive call when node is an hbox proxy. + * - author: JL + */ +int synctex_node_hbox_v(synctex_node_p node) +{ + switch (synctex_node_type(node)) { + case synctex_node_type_hbox: + return _synctex_data_v_V(node); + case synctex_node_type_proxy_hbox: + return _synctex_data_v(node) + synctex_node_hbox_v(_synctex_tree_target(node)); + default: + return 0; + } +} +/** + * The width of an hbox, corrected with contents. + * - parameter node: an hbox node, 0 if node is not an hbox or an hbox proxy. + * - returns: an integer. + * - author: JL + */ +int synctex_node_hbox_width(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return synctex_node_type(node) == synctex_node_type_hbox ? _synctex_data_width_V(node) : 0; +} +/** + * The height of an hbox, corrected with contents. + * - parameter node: an hbox node. + * - returns: an integer, 0 if node is not an hbox or an hbox proxy. + * - author: JL + */ +int synctex_node_hbox_height(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return synctex_node_type(node) == synctex_node_type_hbox ? _synctex_data_height_V(node) : 0; +} +/** + * The depth of an hbox, corrected with contents. + * - parameter node: an hbox node. + * - returns: an integer, 0 if node is not an hbox or an hbox proxy. + * - note: recursive call when node is an hbox proxy. + * - author: JL + */ +int synctex_node_hbox_depth(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return synctex_node_type(node) == synctex_node_type_hbox ? _synctex_data_depth_V(node) : 0; +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Public node visible attributes +#endif + +#define SYNCTEX_VISIBLE_SIZE(node, s) (s) * node->class->scanner->unit +#define SYNCTEX_VISIBLE_DISTANCE_h(node, d) ((d)*node->class->scanner->unit + node->class->scanner->x_offset) +#define SYNCTEX_VISIBLE_DISTANCE_v(node, d) ((d)*node->class->scanner->unit + node->class->scanner->y_offset) +static float __synctex_node_visible_h(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_h(node, synctex_node_h(node)); +} +static float __synctex_node_visible_v(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_v(node, synctex_node_v(node)); +} +static float __synctex_node_visible_width(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, synctex_node_width(node)); +} +static float __synctex_node_visible_height(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, synctex_node_height(node)); +} +static float __synctex_node_visible_depth(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, synctex_node_depth(node)); +} +static float __synctex_proxy_visible_h(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_h(node, synctex_node_h(node)); +} +static float __synctex_proxy_visible_v(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_v(node, synctex_node_v(node)); +} +static float __synctex_proxy_visible_width(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + return __synctex_node_visible_width(target); +} +static float __synctex_proxy_visible_height(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + return __synctex_node_visible_height(target); +} +static float __synctex_proxy_visible_depth(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + return __synctex_node_visible_depth(target); +} +static float __synctex_kern_visible_h(synctex_noxy_p noxy) +{ + int h = _synctex_data_h(noxy); + int width = _synctex_data_width(noxy); + return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width > 0 ? h - width : h); +} +static float __synctex_kern_visible_width(synctex_noxy_p noxy) +{ + int width = _synctex_data_width(noxy); + return SYNCTEX_VISIBLE_SIZE(noxy, width > 0 ? width : -width); +} +static float __synctex_rule_visible_h(synctex_noxy_p noxy) +{ + int h = _synctex_data_h(noxy); + int width = _synctex_data_width(noxy); + return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width > 0 ? h : h - width); +} +static float __synctex_rule_visible_width(synctex_noxy_p noxy) +{ + int width = _synctex_data_width(noxy); + return SYNCTEX_VISIBLE_SIZE(noxy, width > 0 ? width : -width); +} +static float __synctex_rule_visible_v(synctex_noxy_p noxy) +{ + return __synctex_node_visible_v(noxy); +} +static float __synctex_rule_visible_height(synctex_noxy_p noxy) +{ + return __synctex_node_visible_height(noxy); +} +static float __synctex_rule_visible_depth(synctex_noxy_p noxy) +{ + return __synctex_node_visible_depth(noxy); +} + +/** + * The horizontal location of node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_visible_h(synctex_node_p node) +{ + return node ? node->class->vispector->h(node) : 0; +} +/** + * The vertical location of node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_visible_v(synctex_node_p node) +{ + return node ? node->class->vispector->v(node) : 0; +} +/** + * The width of node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_visible_width(synctex_node_p node) +{ + return node ? node->class->vispector->width(node) : 0; +} +/** + * The height of node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_visible_height(synctex_node_p node) +{ + return node ? node->class->vispector->height(node) : 0; +} +/** + * The depth of node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_visible_depth(synctex_node_p node) +{ + return node ? node->class->vispector->depth(node) : 0; +} + +/** + * The V variant of geometrical information. + * - parameter node: a node. + * - returns: an integer. + * - author: JL + */ +#define SYNCTEX_DEFINE_V(WHAT) \ + SYNCTEX_INLINE static int _synctex_node_##WHAT##_V(synctex_node_p node) \ + { \ + synctex_node_p target = _synctex_tree_target(node); \ + if (target) { \ + return _synctex_data_##WHAT(node) + _synctex_node_##WHAT##_V(target); \ + } else if (_synctex_data_has_##WHAT##_V(node)) { \ + return _synctex_data_##WHAT##_V(node); \ + } else { \ + return _synctex_data_##WHAT(node); \ + } \ + } +SYNCTEX_DEFINE_V(h) +SYNCTEX_DEFINE_V(v) +SYNCTEX_DEFINE_V(width) +SYNCTEX_DEFINE_V(height) +SYNCTEX_DEFINE_V(depth) + +SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node) +{ + return (synctex_point_s) {synctex_node_h(node), synctex_node_v(node)}; +} +SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node) +{ + return (synctex_point_s) {_synctex_node_h_V(node), _synctex_node_v_V(node)}; +} +SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point) +{ + synctex_point_s old = _synctex_data_point(node); + _synctex_data_set_h(node, point.h); + _synctex_data_set_v(node, point.v); + return old; +} +SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node) +{ + synctex_box_s box = {{0, 0}, {0, 0}}; + int n; + n = synctex_node_width(node); + if (n < 0) { + box.max.h = synctex_node_h(node); + box.min.h = box.max.h + n; + } else { + box.min.h = synctex_node_h(node); + box.max.h = box.min.h + n; + } + n = synctex_node_v(node); + box.min.v = n - synctex_node_height(node); + box.max.v = n + synctex_node_depth(node); + return box; +} +SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node) +{ + synctex_box_s box = {{0, 0}, {0, 0}}; + int n; + n = synctex_node_width(node); + if (n > 0) { + box.max.h = synctex_node_h(node); + box.min.h = box.max.h - n; + } else { + box.min.h = synctex_node_h(node); + box.max.h = box.min.h - n; + } + n = synctex_node_v(node); + box.min.v = n - synctex_node_height(node); + box.max.v = n + synctex_node_depth(node); + return box; +} +SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node) +{ + synctex_box_s box = {{0, 0}, {0, 0}}; + int n; + n = _synctex_node_width_V(node); + if (n < 0) { + box.max.h = _synctex_node_h_V(node); + box.min.h = box.max.h + n; + } else { + box.min.h = _synctex_node_h_V(node); + box.max.h = box.min.h + n; + } + n = _synctex_node_v_V(node); + box.min.v = n - _synctex_node_height_V(node); + box.max.v = n + _synctex_node_depth_V(node); + return box; +} + +/** + * The higher box node in the parent hierarchy which + * mean line number is the one of node ±1. + * This enclosing box is computed as follows + * 1) get the first hbox in the parent linked list + * starting at node. + * If there is none, simply return the parent of node. + * 2) compute the mean line number + * 3) scans up the tree for the higher hbox with + * the same mean line number, ±1 eventually + * - parameter node: a node. + * - returns: a (proxy to a) box node. + * - author: JL + */ +static synctex_node_p _synctex_node_box_visible(synctex_node_p node) +{ + if ((node = _synctex_node_or_handle_target(node))) { + int mean = 0; + int bound = 1500000 / (node->class->scanner->pre_magnification / 1000); + synctex_node_p parent = NULL; + /* get the first enclosing parent + * then get the highest enclosing parent with the same mean line ±1 */ + node = _synctex_node_or_handle_target(node); + if (!_synctex_node_is_box(node)) { + if ((parent = _synctex_tree_parent(node))) { + node = parent; + } else if ((node = _synctex_tree_target(node))) { + if (!_synctex_node_is_box(node)) { + if ((parent = _synctex_tree_parent(node))) { + node = parent; + } else { + return NULL; + } + } + } + } + parent = node; + mean = synctex_node_mean_line(node); + while ((parent = _synctex_tree_parent(parent))) { + if (_synctex_node_is_hbox(parent)) { + if (_synctex_abs(mean - synctex_node_mean_line(parent)) > 1) { + return node; + } else if (synctex_node_width(parent) > bound) { + return parent; + } else if (synctex_node_height(parent) + synctex_node_depth(parent) > bound) { + return parent; + } + node = parent; + } + } + } + return node; +} +/** + * The horizontal location of the first box enclosing node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_h(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_h(node, _synctex_node_h_V(_synctex_node_box_visible(node))); +} +/** + * The vertical location of the first box enclosing node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_v(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_DISTANCE_v(node, _synctex_node_v_V(_synctex_node_box_visible(node))); +} +/** + * The width of the first box enclosing node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_width(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, _synctex_node_width_V(_synctex_node_box_visible(node))); +} +/** + * The height of the first box enclosing node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_height(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, _synctex_node_height_V(_synctex_node_box_visible(node))); +} +/** + * The depth of the first box enclosing node, in page coordinates. + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_depth(synctex_node_p node) +{ + return SYNCTEX_VISIBLE_SIZE(node, _synctex_node_depth_V(_synctex_node_box_visible(node))); +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Other public node attributes +#endif + +/** + * The page number of the sheet enclosing node. + * - parameter node: a node. + * - returns: the page number or -1 if node does not belong to a sheet tree. + * - note: a proxy target does not belong to a sheet + * but a form, its page number is always -1. + * - note: a handles does not belong to a sheet not a form. + * its page number is -1. + * - author: JL + */ +int synctex_node_page(synctex_node_p node) +{ + synctex_node_p parent = NULL; + while ((parent = _synctex_tree_parent(node))) { + node = parent; + } + if (synctex_node_type(node) == synctex_node_type_sheet) { + return _synctex_data_page(node); + } + return -1; +} +/** + * The page number of the target. + * - author: JL + */ +SYNCTEX_INLINE static int _synctex_node_target_page(synctex_node_p node) +{ + return synctex_node_page(_synctex_tree_target(node)); +} + +#if defined(SYNCTEX_USE_CHARINDEX) +synctex_charindex_t synctex_node_charindex(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + return target ? SYNCTEX_CHARINDEX(target) : (node ? SYNCTEX_CHARINDEX(node) : 0); +} +#endif + +/** + * The tag of the node. + * - parameter node: a node. + * - returns: the tag or -1 if node is NULL. + * - author: JL + */ +int synctex_node_tag(synctex_node_p node) +{ + return node ? node->class->tlcpector->tag(node) : -1; +} +/** + * The line of the node. + * - parameter node: a node. + * - returns: the line or -1 if node is NULL. + * - author: JL + */ +int synctex_node_line(synctex_node_p node) +{ + return node ? node->class->tlcpector->line(node) : -1; +} +/** + * The column of the node. + * - parameter node: a node. + * - returns: the column or -1 if node is NULL. + * - author: JL + */ +int synctex_node_column(synctex_node_p node) +{ + return node ? node->class->tlcpector->column(node) : -1; +} +/** + * The mean line number of the node. + * - parameter node: a node. + * - returns: the mean line or -1 if node is NULL. + * - author: JL + */ +int synctex_node_mean_line(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return _synctex_data_has_mean_line(node) ? _synctex_data_mean_line(node) : _synctex_data_line(node); +} +/** + * The weight of the node. + * - parameter node: a node. + * - returns: the weight or -1 if node is NULL. + * - author: JL + */ +int synctex_node_weight(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return node ? (synctex_node_type(node) == synctex_node_type_hbox ? _synctex_data_weight(node) : 0) : -1; +} +/** + * The number of children of the node. + * - parameter node: a node. + * - returns: the count or -1 if node is NULL. + * - author: JL + */ +int synctex_node_child_count(synctex_node_p node) +{ + synctex_node_p target = _synctex_tree_target(node); + if (target) { + node = target; + } + return node ? (synctex_node_type(node) == synctex_node_type_hbox ? _synctex_data_weight(node) : 0) : -1; +} +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Sheet & Form +#endif + +/** + * The sheet of the scanner with a given page number. + * - parameter scanner: a scanner. + * - parameter page: a 1 based page number. + * If page == 0, returns the first sheet. + * - returns: a sheet or NULL. + * - author: JL + */ +synctex_node_p synctex_sheet(synctex_scanner_p scanner, int page) +{ + if (scanner) { + synctex_node_p sheet = scanner->sheet; + while (sheet) { + if (page == _synctex_data_page(sheet)) { + return sheet; + } + sheet = __synctex_tree_sibling(sheet); + } + if (page == 0) { + return scanner->sheet; + } + } + return NULL; +} +/** + * The form of the scanner with a given tag. + * - parameter scanner: a scanner. + * - parameter tag: an integer identifier. + * If tag == 0, returns the first form. + * - returns: a form. + * - author: JL + */ +synctex_node_p synctex_form(synctex_scanner_p scanner, int tag) +{ + if (scanner) { + synctex_node_p form = scanner->form; + while (form) { + if (tag == _synctex_data_tag(form)) { + return form; + } + form = __synctex_tree_sibling(form); + } + if (tag == 0) { + return scanner->form; + } + } + return NULL; +} + +/** + * The content of the sheet with given page number. + * - parameter scanner: a scanner. + * - parameter page: a 1 based page number. + * - returns: a (vertical) box node. + * - author: JL + */ +synctex_node_p synctex_sheet_content(synctex_scanner_p scanner, int page) +{ + if (scanner) { + return _synctex_tree_child(synctex_sheet(scanner, page)); + } + return NULL; +} + +/** + * The content of the sheet with given page number. + * - parameter scanner: a scanner. + * - parameter tag: an integer identifier. + * - returns: a box node. + * - author: JL + */ +synctex_node_p synctex_form_content(synctex_scanner_p scanner, int tag) +{ + if (scanner) { + return _synctex_tree_child(synctex_form(scanner, tag)); + } + return NULL; +} + +SYNCTEX_INLINE static synctex_node_p _synctex_scanner_friend(synctex_scanner_p scanner, int i) +{ + if (i >= 0) { + i = _synctex_abs(i) % (scanner->number_of_lists); + return (scanner->lists_of_friends)[i]; + } + return NULL; +} +SYNCTEX_INLINE static synctex_bool_t _synctex_nodes_are_friend(synctex_node_p left, synctex_node_p right) +{ + return synctex_node_tag(left) == synctex_node_tag(right) && synctex_node_line(left) == synctex_node_line(right); +} +SYNCTEX_INLINE static synctex_node_p _synctex_vertically_sorted_v2(synctex_node_p sibling) +{ + synctex_node_p child = NULL; + synctex_node_p best_child = sibling; + synctex_node_p next_child = _synctex_tree_reset_child(best_child); + synctex_node_p target = _synctex_tree_target(best_child); + synctex_node_p parent = _synctex_tree_parent(target); + unsigned int best_count = 0; + unsigned int count = 0; + synctex_node_p N = _synctex_tree_child(parent); + do { + if (_synctex_nodes_are_friend(N, best_child)) { + ++best_count; + } + } while ((N = __synctex_tree_sibling(N))); + /* Navigate through the other children */ + while ((child = next_child)) { + next_child = _synctex_tree_reset_child(child); + target = _synctex_tree_target(child); + parent = _synctex_tree_parent(target); + count = 0; + N = _synctex_tree_child(parent); + do { + if (_synctex_nodes_are_friend(N, best_child)) { + ++count; + } + } while ((N = __synctex_tree_sibling(N))); + if (count > best_count) { + best_count = count; + synctex_node_free(best_child); + best_child = child; + } else { + synctex_node_free(child); + } + } + return best_child; +} + +SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hitP, synctex_node_p node); + +/* This struct records distances, the left one is non negative and the right one is non positive. + * When comparing the locations of 2 different graphical objects on the page, we will have to also record the + * horizontal distance as signed to keep track of the typesetting order.*/ + +typedef struct { + synctex_node_p node; + int distance; +} synctex_nd_s; + +#define SYNCTEX_ND_0 \ + (synctex_nd_s) \ + { \ + NULL, INT_MAX \ + } + +typedef synctex_nd_s *synctex_nd_p; + +typedef struct { + synctex_nd_s l; + synctex_nd_s r; +} synctex_nd_lr_s; + +/* The best container is the deeper box that contains the hit point (H,V). + * _synctex_eq_deepest_container_v2 starts with node whereas + * _synctex_box_child_deepest starts with node's children, if any + * if node is not a box, or a void box, NULL is returned. + * We traverse the node tree in a deep first manner and stop as soon as a result is found. */ +static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hitP, synctex_node_p node); + +SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node); + +/* Closest child, recursive. */ +static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node); + +/* The smallest container between two has the smallest width or height. + * This comparison is used when there are 2 overlapping boxes that contain the hit point. + * For ConTeXt, the problem appears at each page. + * The chosen box is the one with the smallest height, then the smallest width. */ +SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node); + +/* Returns the distance between the hit point hit point=(H,V) and the given node. */ + +static int _synctex_point_node_distance_v2(synctex_point_p hitP, synctex_node_p node); + +/* The closest container is the box that is the one closest to the given point. + * The "visible" version takes into account the visible dimensions instead of the real ones given by TeX. */ +static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node); + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Queries +#endif + +struct synctex_iterator_t { + synctex_node_p seed; + synctex_node_p next; + int count0; + int count; +}; + +SYNCTEX_INLINE static synctex_iterator_p _synctex_iterator_new(synctex_node_p result, int count) +{ + synctex_iterator_p iterator; + if ((iterator = _synctex_malloc(sizeof(synctex_iterator_s)))) { + iterator->seed = iterator->next = result; + iterator->count0 = iterator->count = count; + } + return iterator; +}; + +void synctex_iterator_free(synctex_iterator_p iterator) +{ + if (iterator) { + synctex_node_free(iterator->seed); + _synctex_free(iterator); + } +} +synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator) +{ + return iterator ? iterator->count > 0 : 0; +} +int synctex_iterator_count(synctex_iterator_p iterator) +{ + return iterator ? iterator->count : 0; +} + +/** + * The next result of the iterator. + * Internally, the iterator stores handles to nodes. + * Externally, it returns the targets, + * such that the caller only sees nodes. + */ +synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator) +{ + if (iterator && iterator->count > 0) { + synctex_node_p N = iterator->next; + iterator->next = __synctex_tree_sibling(N); + --iterator->count; + return _synctex_tree_target(N); + } + return NULL; +} +int synctex_iterator_reset(synctex_iterator_p iterator) +{ + if (iterator) { + iterator->next = iterator->seed; + return iterator->count = iterator->count0; + } + return 0; +} + +synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner, int page, float h, float v) +{ + if (scanner) { + synctex_node_p sheet = NULL; + synctex_point_s hit; + synctex_node_p node = NULL; + synctex_nd_lr_s nds = {{NULL, 0}, {NULL, 0}}; + if (NULL == (scanner = synctex_scanner_parse(scanner)) || 0 >= scanner->unit) { /* scanner->unit must be >0 */ + return NULL; + } + /* Find the proper sheet */ + sheet = synctex_sheet(scanner, page); + if (NULL == sheet) { + return NULL; + } + /* Now sheet points to the sheet node with proper page number. */ + /* Now that scanner has been initialized, we can convert + * the given point to scanner integer coordinates */ + hit = (synctex_point_s) {(h - scanner->x_offset) / scanner->unit, (v - scanner->y_offset) / scanner->unit}; + /* At first, we browse all the horizontal boxes of the sheet + * until we find one containing the hit point. */ + if ((node = _synctex_tree_next_hbox(sheet))) { + do { + if (_synctex_point_in_box_v2(&hit, node)) { + /* Maybe the hit point belongs to a contained vertical box. + * This is the most likely situation. + */ + synctex_node_p next = node; +#if defined(SYNCTEX_DEBUG) + printf("--- We are lucky\n"); +#endif + /* This trick is for catching overlapping boxes */ + while ((next = _synctex_tree_next_hbox(next))) { + if (_synctex_point_in_box_v2(&hit, next)) { + node = _synctex_smallest_container_v2(next, node); + } + } + /* node is the smallest horizontal box that contains hit, + * unless there is no hbox at all. + */ + node = _synctex_eq_deepest_container_v2(&hit, node); + nds = _synctex_eq_get_closest_children_in_box_v2(&hit, node); + end: + if (nds.r.node && nds.l.node) { + if ((_synctex_data_tag(nds.r.node) != _synctex_data_tag(nds.l.node)) || (_synctex_data_line(nds.r.node) != _synctex_data_line(nds.l.node)) || (_synctex_data_column(nds.r.node) != _synctex_data_column(nds.l.node))) { + if (nds.l.distance > nds.r.distance) { + node = nds.r.node; + nds.r.node = nds.l.node; + nds.l.node = node; + } + if ((node = _synctex_new_handle_with_target(nds.l.node))) { + synctex_node_p other_handle; + if ((other_handle = _synctex_new_handle_with_target(nds.r.node))) { + _synctex_tree_set_sibling(node, other_handle); + return _synctex_iterator_new(node, 2); + } + return _synctex_iterator_new(node, 1); + } + return NULL; + } + /* both nodes have the same input coordinates + * We choose the one closest to the hit point */ + if (nds.l.distance > nds.r.distance) { + nds.l.node = nds.r.node; + } + nds.r.node = NULL; + } else if (nds.r.node) { + nds.l = nds.r; + } else if (!nds.l.node) { + nds.l.node = node; + } + if ((node = _synctex_new_handle_with_target(nds.l.node))) { + return _synctex_iterator_new(node, 1); + } + return 0; + } + } while ((node = _synctex_tree_next_hbox(node))); + /* All the horizontal boxes have been tested, + * None of them contains the hit point. + */ + } + /* We are not lucky, + * we test absolutely all the node + * to find the closest... */ + if ((node = _synctex_tree_child(sheet))) { +#if defined(SYNCTEX_DEBUG) + printf("--- We are not lucky\n"); +#endif + nds.l = __synctex_closest_deep_child_v2(&hit, node); +#if defined(SYNCTEX_DEBUG) + printf("Edit query best: %i\n", nds.l.distance); +#endif + goto end; + } + } + return NULL; +} + +/** + * Loop the candidate friendly list to find the ones with the proper + * tag and line. + * Returns a tree of results targeting the found candidates. + * At the top level each sibling has its own page number. + * All the results with the same page number are linked by child/parent entry. + * - parameter candidate: a friendly list of candidates + */ +static synctex_node_p _synctex_display_query_v2(synctex_node_p target, int tag, int line, synctex_bool_t exclude_box) +{ + synctex_node_p first_handle = NULL; + /* Search the first match */ + if (target == NULL) { + return first_handle; + } + do { + int page; + if ((exclude_box && _synctex_node_is_box(target)) || (tag != synctex_node_tag(target)) || (line != synctex_node_line(target))) { + continue; + } + /* We found a first match, create + * a result handle targeting that candidate. */ + first_handle = _synctex_new_handle_with_target(target); + if (first_handle == NULL) { + return first_handle; + } + /* target is either a node, + * or a proxy to some node, in which case, + * the target's target belongs to a form, + * not a sheet. */ + page = synctex_node_page(target); + /* Now create all the other results */ + while ((target = _synctex_tree_friend(target))) { + synctex_node_p result = NULL; + if ((exclude_box && _synctex_node_is_box(target)) || (tag != synctex_node_tag(target)) || (line != synctex_node_line(target))) { + continue; + } + /* Another match, same page number ? */ + result = _synctex_new_handle_with_target(target); + if (NULL == result) { + return first_handle; + } + /* is it the same page number ? */ + if (synctex_node_page(target) == page) { + __synctex_tree_set_child(result, first_handle); + first_handle = result; + } else { + /* We have 2 page numbers involved */ + __synctex_tree_set_sibling(first_handle, result); + while ((target = _synctex_tree_friend(target))) { + synctex_node_p same_page_node; + if ((exclude_box && _synctex_node_is_box(target)) || (tag != synctex_node_tag(target)) || (line != synctex_node_line(target))) { + continue; + } + /* New match found, which page? */ + result = _synctex_new_handle_with_target(target); + if (NULL == result) { + return first_handle; + } + same_page_node = first_handle; + page = synctex_node_page(target); + /* Find a result with the same page number */; + do { + if (_synctex_node_target_page(same_page_node) == page) { + _synctex_tree_set_child(result, _synctex_tree_set_child(same_page_node, result)); + } else if ((same_page_node = __synctex_tree_sibling(same_page_node))) { + continue; + } else { + /* This is a new page number */ + __synctex_tree_set_sibling(result, first_handle); + first_handle = result; + } + break; + } while (synctex_YES); + } + return first_handle; + } + } + } while ((target = _synctex_tree_friend(target))); + return first_handle; +} +synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint) +{ + (void)column; /* unused */ + if (scanner) { + int tag = synctex_scanner_get_tag(scanner, name); /* parse if necessary */ + int max_line = 0; + int line_offset = 1; + int try_count = 100; + synctex_node_p node = NULL; + synctex_node_p result = NULL; + if (tag == 0) { + printf("SyncTeX Warning: No tag for %s\n", name); + return NULL; + } + node = synctex_scanner_input_with_tag(scanner, tag); + max_line = _synctex_data_line(node); + /* node = NULL; */ + if (line > max_line) { + line = max_line; + } + while (try_count--) { + if (line <= max_line) { + /* This loop will only be performed once for advanced viewers */ + synctex_node_p friend = _synctex_scanner_friend(scanner, tag + line); + if ((node = friend)) { + result = _synctex_display_query_v2(node, tag, line, synctex_YES); + if (!result) { + /* We did not find any matching boundary, retry including boxes */ + node = friend; /* no need to test it again, already done */ + result = _synctex_display_query_v2(node, tag, line, synctex_NO); + } + /* Now reverse the order to have nodes in display order, and then keep just a few nodes. + * Order first the best node. */ + /* The result is a tree. At the root level, all nodes + * correspond to different page numbers. + * Each node has a child which corresponds to the same + * page number if relevant. + * Then reorder the nodes to put first the one which fits best. + * The idea is to count the number of nodes + * with the same tag and line number in the parents + * and choose the one with the biggest count. + */ + if (result) { + /* navigate through siblings, + then children */ + int count = 1; + synctex_node_p next_sibling = __synctex_tree_reset_sibling(result); + int best_match = abs(page_hint - _synctex_node_target_page(result)); + synctex_node_p sibling; + int match; + result = _synctex_vertically_sorted_v2(result); + while ((sibling = next_sibling)) { + /* What is next? Do not miss that step! */ + next_sibling = __synctex_tree_reset_sibling(sibling); + sibling = _synctex_vertically_sorted_v2(sibling); + match = abs(page_hint - _synctex_node_target_page(sibling)); + if (match < best_match) { + /* Order this node first */ + __synctex_tree_set_sibling(sibling, result); + result = sibling; + best_match = match; + } else /*if (match>best_match)*/ { + __synctex_tree_set_sibling(sibling, __synctex_tree_sibling(result)); + __synctex_tree_set_sibling(result, sibling); + } + ++count; + } + /* Now order first the result closest to the page hint */ + return _synctex_iterator_new(result, count); + } + } +#if defined(__SYNCTEX_STRONG_DISPLAY_QUERY__) + break; +#else + line += line_offset; + line_offset = line_offset < 0 ? -(line_offset - 1) : -(line_offset + 1); + if (line <= 0) { + line += line_offset; + line_offset = line_offset < 0 ? -(line_offset - 1) : -(line_offset + 1); + } +#endif + } + } + } + return NULL; +} +synctex_status_t synctex_display_query(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint) +{ + if (scanner) { + synctex_iterator_free(scanner->iterator); + scanner->iterator = synctex_iterator_new_display(scanner, name, line, column, page_hint); + return synctex_iterator_count(scanner->iterator); + } + return SYNCTEX_STATUS_ERROR; +} +synctex_status_t synctex_edit_query(synctex_scanner_p scanner, int page, float h, float v) +{ + if (scanner) { + synctex_iterator_free(scanner->iterator); + scanner->iterator = synctex_iterator_new_edit(scanner, page, h, v); + return synctex_iterator_count(scanner->iterator); + } + return SYNCTEX_STATUS_ERROR; +} +/** + * The next result of a query. + */ +synctex_node_p synctex_scanner_next_result(synctex_scanner_p scanner) +{ + return scanner ? synctex_iterator_next_result(scanner->iterator) : NULL; +} +synctex_status_t synctex_scanner_reset_result(synctex_scanner_p scanner) +{ + return scanner ? synctex_iterator_reset(scanner->iterator) : SYNCTEX_STATUS_ERROR; +} + +synctex_node_p synctex_node_target(synctex_node_p node) +{ + return _synctex_tree_target(node); +} + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Geometric utilities +#endif + +/** Rougly speaking, this is: + * node's h coordinate - hit point's h coordinate. + * If node is to the right of the hit point, then this distance is positive, + * if node is to the left of the hit point, this distance is negative. + * If the argument is a pdf form reference, then the child is used and returned instead. + * Last Revision: Mon Apr 24 07:05:27 UTC 2017 + */ +static synctex_nd_s _synctex_point_h_ordered_distance_v2(synctex_point_p hit, synctex_node_p node) +{ + synctex_nd_s nd = {node, INT_MAX}; + if (node) { + int min, med, max, width; + switch (synctex_node_type(node)) { + /* The distance between a point and a box is special. + * It is not the euclidian distance, nor something similar. + * We have to take into account the particular layout, + * and the box hierarchy. + * Given a box, there are 9 regions delimited by the lines of the edges of the box. + * The origin being at the top left corner of the page, + * we also give names to the vertices of the box. + * + * 1 | 2 | 3 + * ---A---B---> + * 4 | 5 | 6 + * ---C---D---> + * 7 | 8 | 9 + * v v + */ + case synctex_node_type_vbox: + case synctex_node_type_void_vbox: + case synctex_node_type_void_hbox: + /* getting the box bounds, taking into account negative width, height and depth. */ + width = _synctex_data_width(node); + min = _synctex_data_h(node); + max = min + (width > 0 ? width : -width); + /* We always have min <= max */ + if (hit->h < min) { + nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */ + } else if (hit->h > max) { + nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */ + } + break; + case synctex_node_type_proxy_vbox: + /* getting the box bounds, taking into account negative width, height and depth. */ + width = synctex_node_width(node); + min = synctex_node_h(node); + max = min + (width > 0 ? width : -width); + /* We always have min <= max */ + if (hit->h < min) { + nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */ + } else if (hit->h > max) { + nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */ + } + break; + case synctex_node_type_hbox: + case synctex_node_type_proxy_hbox: + /* getting the box bounds, taking into account negative width, height and depth. */ + width = synctex_node_hbox_width(node); + min = synctex_node_hbox_h(node); + max = min + (width > 0 ? width : -width); + /* We always have min <= max */ + if (hit->h < min) { + nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */ + } else if (hit->h > max) { + nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */ + } + break; + case synctex_node_type_kern: + /* IMPORTANT NOTICE: the location of the kern is recorded AFTER the move. + * The distance to the kern is very special, + * in general, there is no text material in the kern, + * this is why we compute the offset relative to the closest edge of the kern.*/ + max = _synctex_data_width(node); + if (max < 0) { + min = _synctex_data_h(node); + max = min - max; + } else { + min = -max; + max = _synctex_data_h(node); + min += max; + } + med = (min + max) / 2; + /* positive kern: '.' means text, '>' means kern offset + * ............. + * min>>>>med>>>>max + * ............... + * negative kern: '.' means text, '<' means kern offset + * ............................ + * min<<<h < min) { + nd.distance = min - hit->h + 1; /* penalty to ensure other nodes are chosen first in case of overlapping ones */ + } else if (hit->h > max) { + nd.distance = max - hit->h - 1; /* same kind of penalty */ + } else if (hit->h > med) { + /* do things like if the node had 0 width and was placed at the max edge + 1*/ + nd.distance = max - hit->h + 1; /* positive, the kern is to the right of the hit point */ + } else { + nd.distance = min - hit->h - 1; /* negative, the kern is to the left of the hit point */ + } + break; + case synctex_node_type_rule: /* to do: special management */ + case synctex_node_type_glue: + case synctex_node_type_math: + case synctex_node_type_boundary: + case synctex_node_type_box_bdry: + nd.distance = _synctex_data_h(node) - hit->h; + break; + case synctex_node_type_ref: + nd.node = synctex_node_child(node); + nd = _synctex_point_h_ordered_distance_v2(hit, nd.node); + break; + case synctex_node_type_proxy: + case synctex_node_type_proxy_last: { + /* shift the hit point to be relative to the proxy origin, + * then compute the distance to the target + */ + synctex_point_s otherHit = *hit; + otherHit.h -= _synctex_data_h(node); + otherHit.v -= _synctex_data_v(node); + nd.node = _synctex_tree_target(node); + nd = _synctex_point_h_ordered_distance_v2(&otherHit, nd.node); + nd.node = node; + } + default: + break; + } + } + return nd; +} +/** Rougly speaking, this is: + * node's v coordinate - hit point's v coordinate. + * If node is at the top of the hit point, then this distance is positive, + * if node is at the bottom of the hit point, this distance is negative. + */ +static synctex_nd_s _synctex_point_v_ordered_distance_v2(synctex_point_p hit, synctex_node_p node) +{ + synctex_nd_s nd = {node, INT_MAX}; + int min, max, depth, height; + switch (synctex_node_type(node)) { + /* The distance between a point and a box is special. + * It is not the euclidian distance, nor something similar. + * We have to take into account the particular layout, + * and the box hierarchy. + * Given a box, there are 9 regions delimited by the lines of the edges of the box. + * The origin being at the top left corner of the page, + * we also give names to the vertices of the box. + * + * 1 | 2 | 3 + * ---A---B---> + * 4 | 5 | 6 + * ---C---D---> + * 7 | 8 | 9 + * v v + */ + case synctex_node_type_vbox: + case synctex_node_type_void_vbox: + case synctex_node_type_void_hbox: + /* getting the box bounds, taking into account negative width, height and depth. */ + min = synctex_node_v(node); + max = min + _synctex_abs(_synctex_data_depth(node)); + min -= _synctex_abs(_synctex_data_height(node)); + /* We always have min <= max */ + if (hit->v < min) { + nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */ + } else if (hit->v > max) { + nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */ + } + break; + case synctex_node_type_proxy_vbox: + /* getting the box bounds, taking into account negative width, height and depth. */ + min = synctex_node_v(node); + max = min + _synctex_abs(synctex_node_depth(node)); + min -= _synctex_abs(synctex_node_height(node)); + /* We always have min <= max */ + if (hit->v < min) { + nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */ + } else if (hit->v > max) { + nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */ + } + break; + case synctex_node_type_hbox: + case synctex_node_type_proxy_hbox: + /* getting the box bounds, taking into account negative height and depth. */ + min = synctex_node_hbox_v(node); + depth = synctex_node_hbox_depth(node); + max = min + (depth > 0 ? depth : -depth); + height = synctex_node_hbox_height(node); + min -= (height > 0 ? height : -height); + /* We always have min <= max */ + if (hit->v < min) { + nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */ + } else if (hit->v > max) { + nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */ + } + break; + case synctex_node_type_rule: /* to do: special management */ + case synctex_node_type_kern: + case synctex_node_type_glue: + case synctex_node_type_math: + min = _synctex_data_v(node); + max = min + _synctex_abs(_synctex_data_depth(_synctex_tree_parent(node))); + min -= _synctex_abs(_synctex_data_height(_synctex_tree_parent(node))); + /* We always have min <= max */ + if (hit->v < min) { + nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */ + } else if (hit->v > max) { + nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */ + } else { + nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */ + } + break; + case synctex_node_type_ref: + nd.node = synctex_node_child(node); + nd = _synctex_point_v_ordered_distance_v2(hit, nd.node); + break; + case synctex_node_type_proxy: + case synctex_node_type_proxy_last: { + synctex_point_s otherHit = *hit; + otherHit.h -= _synctex_data_h(node); + otherHit.v -= _synctex_data_v(node); + nd.node = _synctex_tree_target(node); + nd = _synctex_point_v_ordered_distance_v2(&otherHit, nd.node); + nd.node = node; + } + default: + break; + } + return nd; +} +/** + * The best is the one with the smallest area. + * The area is width*height where width and height may be big. + * So there is a real risk of overflow if we stick with ints. + */ +SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node) +{ + long total_height, other_total_height; + unsigned long area, other_area; + long width = synctex_node_hbox_width(node); + long other_width = synctex_node_hbox_width(other_node); + if (width < 0) { + width = -width; + } + if (other_width < 0) { + other_width = -other_width; + } + total_height = _synctex_abs(synctex_node_hbox_depth(node)) + _synctex_abs(synctex_node_hbox_height(node)); + other_total_height = _synctex_abs(synctex_node_hbox_depth(other_node)) + _synctex_abs(synctex_node_hbox_height(other_node)); + area = total_height * width; + other_area = other_total_height * other_width; + if (area < other_area) { + return node; + } + if (area > other_area) { + return other_node; + } + if (_synctex_abs(_synctex_data_width(node)) > _synctex_abs(_synctex_data_width(other_node))) { + return node; + } + if (_synctex_abs(_synctex_data_width(node)) < _synctex_abs(_synctex_data_width(other_node))) { + return other_node; + } + if (total_height < other_total_height) { + return node; + } + if (total_height > other_total_height) { + return other_node; + } + return node; +} + +SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hit, synctex_node_p node) +{ + if (node) { + if (0 == _synctex_point_h_ordered_distance_v2(hit, node).distance && 0 == _synctex_point_v_ordered_distance_v2(hit, node).distance) { + return synctex_YES; + } + } + return synctex_NO; +} + +static int _synctex_distance_to_box_v2(synctex_point_p hit, synctex_box_p box) +{ + /* The distance between a point and a box is special. + * It is not the euclidian distance, nor something similar. + * We have to take into account the particular layout, + * and the box hierarchy. + * Given a box, there are 9 regions delimited by the lines of the edges of the box. + * The origin being at the top left corner of the page, + * we also give names to the vertices of the box. + * + * 1 | 2 | 3 + * ---A---B---> + * 4 | 5 | 6 + * ---C---D---> + * 7 | 8 | 9 + * v v + * In each region, there is a different formula. + * In the end we have a continuous distance which may not be a mathematical distance but who cares. */ + if (hit->v < box->min.v) { + /* Regions 1, 2 or 3 */ + if (hit->h < box->min.h) { + /* This is region 1. The distance to the box is the L1 distance PA. */ + return box->min.v - hit->v + box->min.h - hit->h; /* Integer overflow? probability epsilon */ + } else if (hit->h <= box->max.h) { + /* This is region 2. The distance to the box is the geometrical distance to the top edge. */ + return box->min.v - hit->v; + } else { + /* This is region 3. The distance to the box is the L1 distance PB. */ + return box->min.v - hit->v + hit->h - box->max.h; + } + } else if (hit->v <= box->max.v) { + /* Regions 4, 5 or 6 */ + if (hit->h < box->min.h) { + /* This is region 4. The distance to the box is the geometrical distance to the left edge. */ + return box->min.h - hit->h; + } else if (hit->h <= box->max.h) { + /* This is region 5. We are inside the box. */ + return 0; + } else { + /* This is region 6. The distance to the box is the geometrical distance to the right edge. */ + return hit->h - box->max.h; + } + } else { + /* Regions 7, 8 or 9 */ + if (hit->h < box->min.h) { + /* This is region 7. The distance to the box is the L1 distance PC. */ + return hit->v - box->max.v + box->min.h - hit->h; + } else if (hit->h <= box->max.h) { + /* This is region 8. The distance to the box is the geometrical distance to the top edge. */ + return hit->v - box->max.v; + } else { + /* This is region 9. The distance to the box is the L1 distance PD. */ + return hit->v - box->max.v + hit->h - box->max.h; + } + } +} + +/** + * The distance from the hit point to the node. + */ +static int _synctex_point_node_distance_v2(synctex_point_p hit, synctex_node_p node) +{ + int d = INT_MAX; + if (node) { + synctex_box_s box = {{0, 0}, {0, 0}}; + int dd = INT_MAX; + switch (synctex_node_type(node)) { + case synctex_node_type_vbox: + box.min.h = _synctex_data_h(node); + box.max.h = box.min.h + _synctex_abs(_synctex_data_width(node)); + box.min.v = synctex_node_v(node); + box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node)); + box.min.v -= _synctex_abs(_synctex_data_height(node)); + return _synctex_distance_to_box_v2(hit, &box); + case synctex_node_type_proxy_vbox: + box.min.h = synctex_node_h(node); + box.max.h = box.min.h + _synctex_abs(synctex_node_width(node)); + box.min.v = synctex_node_v(node); + box.max.v = box.min.v + _synctex_abs(synctex_node_depth(node)); + box.min.v -= _synctex_abs(synctex_node_height(node)); + return _synctex_distance_to_box_v2(hit, &box); + case synctex_node_type_hbox: + case synctex_node_type_proxy_hbox: + box.min.h = synctex_node_hbox_h(node); + box.max.h = box.min.h + _synctex_abs(synctex_node_hbox_width(node)); + box.min.v = synctex_node_hbox_v(node); + box.max.v = box.min.v + _synctex_abs(synctex_node_hbox_depth(node)); + box.min.v -= _synctex_abs(synctex_node_hbox_height(node)); + return _synctex_distance_to_box_v2(hit, &box); + case synctex_node_type_void_vbox: + case synctex_node_type_void_hbox: + /* best of distances from the left edge and right edge*/ + box.min.h = _synctex_data_h(node); + box.max.h = box.min.h; + box.min.v = _synctex_data_v(node); + box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node)); + box.min.v -= _synctex_abs(_synctex_data_height(node)); + d = _synctex_distance_to_box_v2(hit, &box); + box.min.h = box.min.h + _synctex_abs(_synctex_data_width(node)); + box.max.h = box.min.h; + dd = _synctex_distance_to_box_v2(hit, &box); + return d < dd ? d : dd; + case synctex_node_type_kern: + box.min.h = _synctex_data_h(node); + box.max.h = box.min.h; + box.max.v = _synctex_data_v(node); + box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node))); + d = _synctex_distance_to_box_v2(hit, &box); + box.min.h -= _synctex_data_width(node); + box.max.h = box.min.h; + dd = _synctex_distance_to_box_v2(hit, &box); + return d < dd ? d : dd; + case synctex_node_type_glue: + case synctex_node_type_math: + case synctex_node_type_boundary: + case synctex_node_type_box_bdry: + box.min.h = _synctex_data_h(node); + box.max.h = box.min.h; + box.max.v = _synctex_data_v(node); + box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node))); + return _synctex_distance_to_box_v2(hit, &box); + case synctex_node_type_proxy: + case synctex_node_type_proxy_last: { + synctex_point_s otherHit = *hit; + otherHit.h -= _synctex_data_h(node); + otherHit.v -= _synctex_data_v(node); + return _synctex_point_node_distance_v2(&otherHit, _synctex_tree_target(node)); + } + default: + break; + } + } + return d; +} +static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hit, synctex_node_p node) +{ + if (node) { + /**/ + synctex_node_p child; + if ((child = synctex_node_child(node))) { + /* Non void hbox or vbox, form ref or proxy */ + /* We go deep first because some boxes have 0 dimensions + * despite they do contain some black material. + */ + do { + if ((_synctex_point_in_box_v2(hit, child))) { + synctex_node_p deep = _synctex_eq_deepest_container_v2(hit, child); + if (deep) { + /* One of the children contains the hit. */ + return deep; + } + } + } while ((child = synctex_node_sibling(child))); + /* is the hit point inside the box? */ + if (synctex_node_type(node) == synctex_node_type_vbox || synctex_node_type(node) == synctex_node_type_proxy_vbox) { + /* For vboxes we try to use some node inside. + * Walk through the list of siblings until we find the closest one. + * Only consider siblings with children inside. */ + if ((child = _synctex_tree_child(node))) { + synctex_nd_s best = SYNCTEX_ND_0; + do { + if (_synctex_tree_child(child)) { + int d = _synctex_point_node_distance_v2(hit, child); + if (d <= best.distance) { + best = (synctex_nd_s) {child, d}; + } + } + } while ((child = __synctex_tree_sibling(child))); + if (best.node) { + return best.node; + } + } + } + if (_synctex_point_in_box_v2(hit, node)) { + return node; + } + } + } + return NULL; +} +static synctex_nd_s _synctex_eq_deepest_container_v3(synctex_point_p hit, synctex_node_p node) +{ + if (node) { + synctex_node_p child = NULL; + if ((child = synctex_node_child(node))) { + /* Non void hbox, vbox, box proxy or form ref */ + /* We go deep first because some boxes have 0 dimensions + * despite they do contain some black material. + */ + do { + synctex_nd_s deep = _synctex_eq_deepest_container_v3(hit, child); + if (deep.node) { + /* One of the children contains the hit-> */ + return deep; + } + } while ((child = synctex_node_sibling(child))); + /* For vboxes we try to use some node inside. + * Walk through the list of siblings until we find the closest one. + * Only consider siblings with children inside. */ + if (synctex_node_type(node) == synctex_node_type_vbox || synctex_node_type(node) == synctex_node_type_proxy_vbox) { + if ((child = synctex_node_child(node))) { + synctex_nd_s best = SYNCTEX_ND_0; + do { + if (synctex_node_child(child)) { + int d = _synctex_point_node_distance_v2(hit, child); + if (d < best.distance) { + best = (synctex_nd_s) {child, d}; + } + } + } while ((child = synctex_node_sibling(child))); + if (best.node) { + return best; + } + } + } + /* is the hit point inside the box? */ + if (_synctex_point_in_box_v2(hit, node)) { + return (synctex_nd_s) {node, 0}; + } + } + } + return SYNCTEX_ND_0; +} + +/* Compares the locations of the hit point with the locations of + * the various nodes contained in the box. + * As it is an horizontal box, we only compare horizontal coordinates. + */ +SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v2(synctex_point_p hitP, synctex_node_p node) +{ + synctex_nd_s childd = SYNCTEX_ND_0; + synctex_nd_lr_s nds = {SYNCTEX_ND_0, SYNCTEX_ND_0}; + if ((childd.node = synctex_node_child(node))) { + synctex_nd_s nd = SYNCTEX_ND_0; + do { + childd = _synctex_point_h_ordered_distance_v2(hitP, childd.node); + if (childd.distance > 0) { + /* node is to the right of the hit point. + * We compare node and the previously recorded one, through the recorded distance. + * If the nodes have the same tag, prefer the one with the smallest line number, + * if the nodes also have the same line number, prefer the one with the smallest column. */ + if (nds.r.distance > childd.distance) { + nds.r = childd; + } else if (nds.r.distance == childd.distance && nds.r.node) { + if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(childd.node) && + (_synctex_data_line(nds.r.node) > _synctex_data_line(childd.node) || (_synctex_data_line(nds.r.node) == _synctex_data_line(childd.node) && _synctex_data_column(nds.r.node) > _synctex_data_column(childd.node)))) { + nds.r = childd; + } + } + } else if (childd.distance == 0) { + /* hit point is inside node. */ + return _synctex_eq_get_closest_children_in_box_v2(hitP, childd.node); + } else { /* here childd.distance < 0, the hit point is to the right of node */ + childd.distance = -childd.distance; + if (nds.l.distance > childd.distance) { + nds.l = childd; + } else if (nds.l.distance == childd.distance && nds.l.node) { + if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(childd.node) && + (_synctex_data_line(nds.l.node) > _synctex_data_line(childd.node) || (_synctex_data_line(nds.l.node) == _synctex_data_line(childd.node) && _synctex_data_column(nds.l.node) > _synctex_data_column(childd.node)))) { + nds.l = childd; + } + } + } + } while ((childd.node = synctex_node_sibling(childd.node))); + if (nds.l.node) { + /* the left node is new, try to narrow the result */ + if ((nd = _synctex_eq_deepest_container_v3(hitP, nds.l.node)).node) { + nds.l = nd; + } + if ((nd = __synctex_closest_deep_child_v2(hitP, nds.l.node)).node) { + nds.l.node = nd.node; + } + } + if (nds.r.node) { + /* the right node is new, try to narrow the result */ + if ((nd = _synctex_eq_deepest_container_v3(hitP, nds.r.node)).node) { + nds.r = nd; + } + if ((nd = __synctex_closest_deep_child_v2(hitP, nds.r.node)).node) { + nds.r.node = nd.node; + } + } + } + return nds; +} + +#if 0 +SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v3(synctex_point_p hitP, synctex_node_p nodeP) { + synctex_nd_s nd = SYNCTEX_ND_0; + synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0}; + if ((nd.node = _synctex_tree_child(nodeP))) { + do { + nd = _synctex_point_h_ordered_distance_v2(hitP,nd.node); + if (nd.distance > 0) { + /* node is to the right of the hit point. + * We compare node and the previously recorded one, through the recorded distance. + * If the nodes have the same tag, prefer the one with the smallest line number, + * if the nodes also have the same line number, prefer the one with the smallest column. */ + if (nds.r.distance > nd.distance) { + nds.r = nd; + } else if (nds.r.distance == nd.distance && nds.r.node) { + if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node) + && (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node) + || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node) + && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) { + nds.r = nd; + } + } + } else if (nd.distance == 0) { + /* hit point is inside node. */ + nds.l = nd; + } else { /* here nd.d < 0, the hit point is to the right of node */ + nd.distance = -nd.distance; + if (nds.l.distance > nd.distance) { + nds.l = nd; + } else if (nds.l.distance == nd.distance && nds.l.node) { + if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node) + && (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node) + || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node) + && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) { + nds.l = nd; + } + } + } + } while((nd.node = __synctex_tree_sibling(nd.node))); + if (nds.l.node) { + /* the left node is new, try to narrow the result */ + if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.l.node))) { + nds.l.node = nd.node; + } + if((nd = _synctex_eq_closest_child_v2(hitP,nds.l.node)).node) { + nds.l.node = nd.node; + } + } + if (nds.r.node) { + /* the right node is new, try to narrow the result */ + if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.r.node))) { + nds.r.node = nd.node; + } + if((nd = _synctex_eq_closest_child_v2(hitP,nds.r.node)).node) { + nds.r.node = nd.node; + } + } + } + return nds; +} +#endif +SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_vbox_v2(synctex_point_p hitP, synctex_node_p nodeP) +{ + (void)nodeP; /* unused */ + synctex_nd_lr_s nds = {SYNCTEX_ND_0, SYNCTEX_ND_0}; + synctex_nd_s nd = SYNCTEX_ND_0; + if ((nd.node = synctex_node_child(nd.node))) { + do { + nd = _synctex_point_v_ordered_distance_v2(hitP, nd.node); + /* this is what makes the difference with the h version above */ + if (nd.distance > 0) { + /* node is to the top of the hit point (below because TeX is oriented from top to bottom. + * We compare node and the previously recorded one, through the recorded distance. + * If the nodes have the same tag, prefer the one with the smallest line number, + * if the nodes also have the same line number, prefer the one with the smallest column. */ + if (nds.r.distance > nd.distance) { + nds.r = nd; + } else if (nds.r.distance == nd.distance && nds.r.node) { + if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node) && + (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node) || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node) && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) { + nds.r = nd; + } + } + } else if (nd.distance == 0) { + nds.l = nd; + } else { /* here nd < 0 */ + nd.distance = -nd.distance; + if (nds.l.distance > nd.distance) { + nds.l = nd; + } else if (nds.l.distance == nd.distance && nds.l.node) { + if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node) && + (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node) || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node) && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) { + nds.l = nd; + } + } + } + } while ((nd.node = synctex_node_sibling(nd.node))); + if (nds.l.node) { + if ((nd.node = _synctex_eq_deepest_container_v2(hitP, nds.l.node))) { + nds.l.node = nd.node; + } + if ((nd = _synctex_eq_closest_child_v2(hitP, nds.l.node)).node) { + nds.l.node = nd.node; + } + } + if (nds.r.node) { + if ((nd.node = _synctex_eq_deepest_container_v2(hitP, nds.r.node))) { + nds.r.node = nd.node; + } + if ((nd = _synctex_eq_closest_child_v2(hitP, nds.r.node)).node) { + nds.r.node = nd.node; + } + } + } + return nds; +} + +/** + * Get the child closest to the hit point. + * - parameter: hit point + * - parameter: containing node + * - returns: the child and the distance to the hit point. + * SYNCTEX_ND_0 if the parameter node has no children. + * - note: recursive call. + */ +static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node) +{ + synctex_nd_s best = SYNCTEX_ND_0; + synctex_node_p child = NULL; + if ((child = synctex_node_child(node))) { +#if defined(SYNCTEX_DEBUG) + printf("Closest deep child on box at line %i\n", SYNCTEX_LINEINDEX(node)); +#endif + do { +#if defined SYNCTEX_DEBUG && SYNCTEX_DEBUG > 500 + synctex_node_display(child); +#endif + synctex_nd_s nd = SYNCTEX_ND_0; + if (_synctex_node_is_box(child)) { + nd = __synctex_closest_deep_child_v2(hitP, child); + } else { + nd = (synctex_nd_s) {child, _synctex_point_node_distance_v2(hitP, child)}; + } + if (nd.distance < best.distance || (nd.distance == best.distance && synctex_node_type(nd.node) != synctex_node_type_kern)) { +#if defined(SYNCTEX_DEBUG) + if (nd.node) { + printf("New best %i<=%i line %i\n", nd.distance, best.distance, SYNCTEX_LINEINDEX(nd.node)); + } +#endif + best = nd; + } + } while ((child = synctex_node_sibling(child))); +#if defined(SYNCTEX_DEBUG) + if (best.node) { + printf("Found new best %i line %i\n", best.distance, SYNCTEX_LINEINDEX(best.node)); + } +#endif + } + return best; +} + +/** + * Return the closest child. + * - parameter: a pointer to the hit point, + * - parameter: the container + * - return: SYNCTEX_ND_0 if node has no child, + * the __synctex_closest_deep_child_v2 otherwise. + */ +static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node) +{ + synctex_nd_s nd = SYNCTEX_ND_0; + if (_synctex_node_is_box(node)) { + nd = __synctex_closest_deep_child_v2(hitP, node); + if (_synctex_node_is_box(nd.node)) { + synctex_node_p child = NULL; + if ((child = synctex_node_child(nd.node))) { + synctex_nd_s best = {child, _synctex_point_node_distance_v2(hitP, child)}; + while ((child = synctex_node_sibling(child))) { + int d = _synctex_point_node_distance_v2(hitP, child); + if (d < best.distance) { + best = (synctex_nd_s) {child, d}; + } else if (d == best.distance && synctex_node_type(child) != synctex_node_type_kern) { + best.node = child; + } + } + return best; + } + } + return nd; + } + return SYNCTEX_ND_0; +} +SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node) +{ + synctex_nd_lr_s nds = {SYNCTEX_ND_0, SYNCTEX_ND_0}; + if (_synctex_tree_has_child(node)) { /* node != NULL */ + if (node->class->type == synctex_node_type_hbox || node->class->type == synctex_node_type_proxy_hbox) { + return __synctex_eq_get_closest_children_in_hbox_v2(hitP, node); + } else { + return __synctex_eq_get_closest_children_in_vbox_v2(hitP, node); + } + } + return nds; +} + +#ifndef SYNCTEX_NO_UPDATER + +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Updater +#endif + +typedef int (*synctex_print_f)(synctex_updater_p, const char *, ...); /* print formatted to either FILE * or gzFile */ +typedef void (*synctex_close_f)(synctex_updater_p); /* close FILE * or gzFile */ + +#define SYNCTEX_BITS_PER_BYTE 8 + +typedef union { + gzFile as_gzFile; + FILE *as_FILE_p; + void *as_ptr; +} syncex_file_u; + +struct synctex_updater_t { + syncex_file_u file; + synctex_print_f print; + synctex_close_f close; + int length; /* the number of chars appended */ +}; + +static int _synctex_updater_print(synctex_updater_p updater, const char *format, ...) SYNCTEX_PRINTF_FORMAT(2, 3); +static int _synctex_updater_print(synctex_updater_p updater, const char *format, ...) +{ + int result = 0; + if (updater) { + va_list va; + va_start(va, format); + result = vfprintf(updater->file.as_FILE_p, format, va); + va_end(va); + } + return result; +} +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#include +#include + +static int vasprintf(char **ret, const char *format, va_list ap) +{ + int len; + len = _vsnprintf(NULL, 0, format, ap); + if (len < 0) + return -1; + *ret = malloc(len + 1); + if (!*ret) + return -1; + _vsnprintf(*ret, len + 1, format, ap); + (*ret)[len] = '\0'; + return len; +} + +#endif + +/** + * gzvprintf is not available until OSX 10.10 + */ +static int _synctex_updater_print_gz(synctex_updater_p updater, const char *format, ...) SYNCTEX_PRINTF_FORMAT(2, 3); +static int _synctex_updater_print_gz(synctex_updater_p updater, const char *format, ...) +{ + int result = 0; + if (updater) { + char *buffer; + va_list va; + va_start(va, format); + if (vasprintf(&buffer, format, va) < 0) { + _synctex_error("Out of memory..."); + } else if ((result = (int)strlen(buffer))) { + result = gzwrite(updater->file.as_gzFile, buffer, (unsigned)result); + } + va_end(va); + free(buffer); + } + return result; +} + +static void _synctex_updater_close(synctex_updater_p updater) +{ + if (updater) { + fclose(updater->file.as_FILE_p); + } +} + +static void _synctex_updater_close_gz(synctex_updater_p updater) +{ + if (updater) { + gzclose(updater->file.as_gzFile); + } +} + +synctex_updater_p synctex_updater_new_with_output_file(const char *output, const char *build_directory) +{ + synctex_updater_p updater = NULL; + const char *mode = NULL; + synctex_open_s open; + /* prepare the updater, the memory is the only one dynamically allocated */ + updater = (synctex_updater_p)_synctex_malloc(sizeof(synctex_updater_s)); + if (NULL == updater) { + _synctex_error("! synctex_updater_new_with_file: malloc problem"); + return NULL; + } + open = _synctex_open_v2(output, build_directory, 0, synctex_ADD_QUOTES); + if (open.status < SYNCTEX_STATUS_OK) { + open = _synctex_open_v2(output, build_directory, 0, synctex_DONT_ADD_QUOTES); + if (open.status < SYNCTEX_STATUS_OK) { + return_on_error: + _synctex_free(updater); + return updater = NULL; + } + } + /* OK, the file exists, we close it and reopen it with the correct mode. + * The receiver is now the owner of the "synctex" variable. */ + gzclose(open.file); + updater->file.as_ptr = NULL; + mode = _synctex_get_io_mode_name(open.io_mode | synctex_io_append_mask); /* either "a" or "ab", depending on the file extension */ + if (open.io_mode & synctex_io_gz_mask) { + if (NULL == (updater->file.as_FILE_p = fopen(open.synctex, mode))) { + no_write_error: + _synctex_error("! synctex_updater_new_with_file: Can't append to %s", open.synctex); + free(open.synctex); + goto return_on_error; + } + updater->print = &_synctex_updater_print; + updater->close = &_synctex_updater_close; + } else { + if (NULL == (updater->file.as_gzFile = gzopen(open.synctex, mode))) { + goto no_write_error; + } + updater->print = &_synctex_updater_print_gz; + updater->close = &_synctex_updater_close_gz; + } + printf("SyncTeX: updating %s...", open.synctex); + _synctex_free(open.synctex); + return updater; +} + +void synctex_updater_append_magnification(synctex_updater_p updater, char *magnification) +{ + if (NULL == updater) { + return; + } + if (magnification && strlen(magnification)) { + updater->length += updater->print(updater, "Magnification:%s\n", magnification); + } +} + +void synctex_updater_append_x_offset(synctex_updater_p updater, char *x_offset) +{ + if (NULL == updater) { + return; + } + if (x_offset && strlen(x_offset)) { + updater->length += updater->print(updater, "X Offset:%s\n", x_offset); + } +} + +void synctex_updater_append_y_offset(synctex_updater_p updater, char *y_offset) +{ + if (NULL == updater) { + return; + } + if (y_offset && strlen(y_offset)) { + updater->length += updater->print(updater, "Y Offset:%s\n", y_offset); + } +} + +void synctex_updater_free(synctex_updater_p updater) +{ + if (NULL == updater) { + return; + } + if (updater->length > 0) { + updater->print(updater, "!%i\n", updater->length); + } + updater->close(updater); + _synctex_free(updater); + printf("... done.\n"); + return; +} +#endif + +#if defined(SYNCTEX_TESTING) +#ifdef SYNCTEX_NOTHING +#pragma mark - +#pragma mark Testers +#endif +static int _synctex_input_copy_name(synctex_node_p input, char *name) +{ + char *copy = _synctex_malloc(strlen(name) + 1); + memcpy(copy, name, strlen(name) + 1); + _synctex_data_set_name(input, copy); + return 0; +} +int synctex_test_setup_scanner_sheets_421(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p sheet = synctex_node_new(scanner, synctex_node_type_sheet); + _synctex_data_set_page(sheet, 4); + SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet) == 4, ""); + synctex_node_free(scanner->sheet); + scanner->sheet = sheet; + sheet = synctex_node_new(scanner, synctex_node_type_sheet); + _synctex_data_set_page(sheet, 2); + SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet) == 2, ""); + __synctex_tree_set_sibling(sheet, scanner->sheet); + scanner->sheet = sheet; + sheet = synctex_node_new(scanner, synctex_node_type_sheet); + _synctex_data_set_page(sheet, 1); + SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet) == 1, ""); + __synctex_tree_set_sibling(sheet, scanner->sheet); + scanner->sheet = sheet; + return TC; +} +int synctex_test_input(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p input = synctex_node_new(scanner, synctex_node_type_input); + _synctex_data_set_tag(input, 421); + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input) == 421, ""); + _synctex_data_set_tag(input, 124); + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input) == 124, ""); + _synctex_data_set_line(input, 421); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(input) == 421, ""); + _synctex_data_set_line(input, 214); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(input) == 214, ""); + _synctex_data_set_line(input, 214); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(input) == 214, ""); + _synctex_input_copy_name(input, "214"); + SYNCTEX_TEST_BODY(TC, 0 == memcmp(_synctex_data_name(input), "214", 4), ""); + _synctex_input_copy_name(input, "421421"); + + SYNCTEX_TEST_BODY(TC, 0 == memcmp(_synctex_data_name(input), "421421", 4), ""); + synctex_node_free(input); + return TC; +} +int synctex_test_proxy(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p proxy = synctex_node_new(scanner, synctex_node_type_proxy); + synctex_node_p target = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_tree_set_target(proxy, target); + _synctex_data_set_tag(target, 421); + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target) == 421, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(target) == 421, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(proxy) == 421, ""); + synctex_node_free(proxy); + synctex_node_free(target); + return TC; +} +int synctex_test_handle(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p handle = synctex_node_new(scanner, synctex_node_type_handle); + synctex_node_p proxy = synctex_node_new(scanner, synctex_node_type_proxy); + synctex_node_p target = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_tree_set_target(handle, target); + _synctex_data_set_tag(target, 421); + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target) == 421, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(target) == 421, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle) == 421, ""); + _synctex_data_set_line(target, 214); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(target) == 214, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_line(target) == 214, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_line(handle) == 214, ""); + _synctex_data_set_column(target, 142); + SYNCTEX_TEST_BODY(TC, _synctex_data_column(target) == 142, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_column(target) == 142, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_column(handle) == 142, ""); + _synctex_tree_set_target(proxy, target); + _synctex_tree_set_target(handle, proxy); + _synctex_data_set_tag(target, 412); + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target) == 412, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(target) == 412, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle) == 412, ""); + _synctex_data_set_line(target, 124); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(target) == 124, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_line(target) == 124, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_line(handle) == 124, ""); + _synctex_data_set_column(target, 241); + SYNCTEX_TEST_BODY(TC, _synctex_data_column(target) == 241, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_column(target) == 241, ""); + SYNCTEX_TEST_BODY(TC, synctex_node_column(handle) == 241, ""); + synctex_node_free(handle); + synctex_node_free(proxy); + synctex_node_free(target); + return TC; +} +int synctex_test_setup_scanner_input(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p input = synctex_node_new(scanner, synctex_node_type_input); + _synctex_data_set_tag(input, 4); + _synctex_input_copy_name(input, "21"); + _synctex_data_set_line(input, 421); + synctex_node_free(scanner->input); + scanner->input = input; + SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input) == 4, ""); + SYNCTEX_TEST_BODY(TC, strcmp(_synctex_data_name(input), "21") == 0, ""); + SYNCTEX_TEST_BODY(TC, _synctex_data_line(input) == 421, ""); + return TC; +} +int synctex_test_setup_nodes(synctex_scanner_p scanner, synctex_node_r nodes) +{ + int TC = 0; + int n; + for (n = 0; n < synctex_node_number_of_types; ++n) { + nodes[n] = synctex_node_new(scanner, n); + SYNCTEX_TEST_BODY(TC, nodes[n] != NULL, ""); + } + return TC; +} +int synctex_test_teardown_nodes(synctex_scanner_p scanner, synctex_node_r nodes) +{ + int n; + for (n = 0; n < synctex_node_number_of_types; ++n) { + synctex_node_free(nodes[n]); + nodes[n] = NULL; + } + return 1; +} +int synctex_test_tree(synctex_scanner_p scanner) +{ + int TC = 0; + synctex_node_p nodes1[synctex_node_number_of_types]; + synctex_node_p nodes2[synctex_node_number_of_types]; + synctex_node_p nodes3[synctex_node_number_of_types]; + int i, j; + TC += synctex_test_setup_nodes(scanner, nodes1); + TC += synctex_test_setup_nodes(scanner, nodes2); + TC += synctex_test_setup_nodes(scanner, nodes3); + /* Every node has a sibling */ + for (i = 0; i < synctex_node_number_of_types; ++i) { + for (j = 0; j < synctex_node_number_of_types; ++j) { + _synctex_tree_set_sibling(nodes1[i], nodes2[i]); + SYNCTEX_TEST_BODY(TC, nodes2[i] == synctex_node_sibling(nodes1[i]), ""); + } + } + synctex_test_teardown_nodes(scanner, nodes3); + synctex_test_teardown_nodes(scanner, nodes2); + synctex_test_teardown_nodes(scanner, nodes1); + return TC; +} +int synctex_test_page(synctex_scanner_p scanner) +{ + int TC = synctex_test_setup_scanner_sheets_421(scanner); + synctex_node_p sheet = scanner->sheet; + synctex_node_p node = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_data_set_tag(node, 4); + _synctex_data_set_line(node, 21); + synctex_node_free(_synctex_node_set_child(sheet, node)); + SYNCTEX_TEST_BODY(TC, synctex_node_page(node) == synctex_node_page(sheet), ""); + return TC; +} +int synctex_test_display_query(synctex_scanner_p scanner) +{ + int TC = synctex_test_setup_scanner_sheets_421(scanner); + synctex_node_p sheet = scanner->sheet; + synctex_node_p node = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_data_set_tag(node, 4); + _synctex_data_set_line(node, 21); + synctex_node_free(_synctex_node_set_child(sheet, node)); + SYNCTEX_TEST_BODY(TC, node == synctex_node_child(sheet), ""); + __synctex_node_make_friend_tlc(node); + SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25) == node, ""); + sheet = __synctex_tree_sibling(sheet); + node = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_data_set_tag(node, 4); + _synctex_data_set_line(node, 21); + synctex_node_free(_synctex_node_set_child(sheet, node)); + SYNCTEX_TEST_BODY(TC, node == synctex_node_child(sheet), ""); + __synctex_node_make_friend_tlc(node); + SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25) == node, ""); + sheet = __synctex_tree_sibling(sheet); + node = synctex_node_new(scanner, synctex_node_type_rule); + _synctex_data_set_tag(node, 4); + _synctex_data_set_line(node, 21); + synctex_node_free(_synctex_node_set_child(sheet, node)); + SYNCTEX_TEST_BODY(TC, node == synctex_node_child(sheet), ""); + __synctex_node_make_friend_tlc(node); + SYNCTEX_TEST_BODY(TC, (_synctex_scanner_friend(scanner, 25) == node), ""); + synctex_test_setup_scanner_input(scanner); + scanner->flags.has_parsed = synctex_YES; +#if 1 + SYNCTEX_TEST_BODY(TC, (synctex_display_query(scanner, "21", 21, 4, -1) == 3), ""); +#endif + return TC; +} +typedef struct { + int s; /* status */ + char n[25]; /* name */ +} synctex_test_sn_s; + +synctex_test_sn_s synctex_test_tmp_sn(char *content) +{ + synctex_test_sn_s sn = {0, "/tmp/test.XXXXXX.synctex"}; + FILE *sfp; + int fd = mkstemps(sn.n, 8); + if (fd < 0) { + fprintf(stderr, "%s: %s\n", sn.n, strerror(errno)); + sn.s = -1; + return sn; + } + if ((sfp = fdopen(fd, "w+")) == NULL) { + unlink(sn.n); + close(fd); + fprintf(stderr, "%s: %s\n", sn.n, strerror(errno)); + sn.s = -2; + return sn; + } + sn.s = fputs(content, sfp); + printf("temp:%s\n%i\n", sn.n, sn.s); + fclose(sfp); + if (sn.s == 0) { + sn.s = -2; + unlink(sn.n); + } + return sn; +} +int synctex_test_sheet_1() +{ + int TC = 0; + char *content = + "SyncTeX Version:1 \n" /*00-19*/ + "Input:1:./1.tex \n" /*20-39*/ + "Output:pdf \n" /*40-59*/ + "Magnification:100000000 \n" /*60-89*/ + "Unit:1 \n" /*90-99*/ + "X Offset:0 \n" /*00-19*/ + "Y Offset:0 \n" /*20-39*/ + "Content: \n" /*40-49*/ + "{1 \n" /*50-59*/ + "[1,10:20,350:330,330,0 \n" /*60-89*/ + "] \n" /*90-99*/ + "} \n" /*00-09*/ + "Postamble:\n"; + synctex_test_sn_s sn = synctex_test_tmp_sn(content); + if (sn.s > 0) { + synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES); + synctex_node_p node = synctex_scanner_handle(scanner); + printf("Created nodes:\n"); + while (node) { + printf("%s\n", _synctex_node_abstract(node)); + node = synctex_node_next(node); + } + synctex_scanner_free(scanner); + unlink(sn.n); + } else { + ++TC; + } + return TC; +} +int synctex_test_sheet_2() +{ + int TC = 0; + char *content = + "SyncTeX Version:1 \n" /*00-19*/ + "Input:1:./1.tex \n" /*20-39*/ + "Output:pdf \n" /*40-59*/ + "Magnification:100000000 \n" /*60-89*/ + "Unit:1 \n" /*90-99*/ + "X Offset:0 \n" /*00-19*/ + "Y Offset:0 \n" /*20-39*/ + "Content: \n" /*40-49*/ + "{1 \n" /*50-59*/ + "(1,10:20,350:330,330,0 \n" /*60-89*/ + ") \n" /*90-99*/ + "} \n" /*00-09*/ + "Postamble:\n"; + synctex_test_sn_s sn = synctex_test_tmp_sn(content); + if (sn.s > 0) { + synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES); + synctex_node_p node = synctex_scanner_handle(scanner); + printf("Created nodes:\n"); + while (node) { + printf("%s\n", _synctex_node_abstract(node)); + node = _synctex_node_next(node); + } + TC += synctex_scanner_free(scanner); + unlink(sn.n); + } else { + ++TC; + } + return TC; +} +int synctex_test_charindex() +{ + int TC = 0; + char *content = + "SyncTeX Version:1 \n" /*00-19*/ + "Input:1:./1.tex \n" /*20-39*/ + "Output:pdf \n" /*40-59*/ + "Magnification:100000000 \n" /*60-89*/ + "Unit:1 \n" /*90-99*/ + "X Offset:0 \n" /*00-19*/ + "Y Offset:0 \n" /*20-39*/ + "Content: \n" /*40-49*/ + "{1 \n" /*50-59*/ + "[1,10:20,350:330,330,0 \n" /*60-89*/ + "(1,58:20,100:250,10,5 \n" /*90-119*/ + "f1000:50,100 \n" /*20-39*/ + ") \n" /*40-49*/ + "] \n" /*50-59*/ + "} \n" /*60-69*/ + "Postamble:\n"; + synctex_test_sn_s sn = synctex_test_tmp_sn(content); + if (sn.s > 0) { + synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES); + synctex_node_p node = synctex_scanner_handle(scanner); + printf("Created nodes:\n"); + while (node) { + printf("%s\n", _synctex_node_abstract(node)); + node = synctex_node_next(node); + } + TC += synctex_scanner_free(scanner); + unlink(sn.n); + } else { + ++TC; + } + return TC; +} +int synctex_test_form() +{ + int TC = 0; + char *content = + "SyncTeX Version:1 \n" /*00-19*/ + "Input:1:./1.tex \n" /*20-39*/ + "Output:pdf \n" /*40-59*/ + "Magnification:100000000 \n" /*60-89*/ + "Unit:1 \n" /*90-99*/ + "X Offset:0 \n" /*00-19*/ + "Y Offset:0 \n" /*20-39*/ + "Content: \n" /*40-49*/ + "{1 \n" /*50-59*/ + "[1,10:20,350:330,330,0 \n" /*60-89*/ + "(1,58:20,100:250,10,5 \n" /*90-119*/ + "f1000:50,100 \n" /*20-39*/ + ") \n" /*40-49*/ + "] \n" /*50-59*/ + "} \n" /*60-69*/ + "<1000 \n" /*70-79*/ + "(1,63:0,0:100,8,3 \n" /*80-99*/ + ") \n" /*00-09*/ + "> \n" /*10-19*/ + "Postamble:\n"; + synctex_test_sn_s sn = synctex_test_tmp_sn(content); + if (sn.s > 0) { + synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES); + synctex_node_p node = synctex_scanner_handle(scanner); + while (node) { + printf("%s\n", _synctex_node_abstract(node)); + node = _synctex_node_next(node); + } + TC += synctex_scanner_free(scanner); + unlink(sn.n); + } else { + ++TC; + } + return TC; +} +#endif diff --git a/core/synctex/synctex_parser.h b/core/synctex/synctex_parser.h new file mode 100644 index 0000000..19e0b34 --- /dev/null +++ b/core/synctex/synctex_parser.h @@ -0,0 +1,423 @@ +/* + Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + + This file is part of the __SyncTeX__ package. + + [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) + [//]: # (Version: 1.19) + + See `synctex_parser_readme.md` for more details + + ## License + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE + + Except as contained in this notice, the name of the copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization from the copyright holder. + + ## Acknowledgments: + + The author received useful remarks from the __pdfTeX__ developers, especially Hahn The Thanh, + and significant help from __XeTeX__ developer Jonathan Kew. + + ## Nota Bene: + + If you include or use a significant part of the __SyncTeX__ package into a software, + I would appreciate to be listed as contributor and see "__SyncTeX__" highlighted. +*/ + +#ifndef __SYNCTEX_PARSER__ +#define __SYNCTEX_PARSER__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SYNCTEX_VERSION_STRING "1.19" + +/* The main synctex object is a scanner. + * Its implementation is considered private. + * The basic workflow is + * - create a "synctex scanner" with the contents of a file + * - perform actions on that scanner like + synctex_display_query or synctex_edit_query below. + * - perform actions on nodes returned by the scanner + * - free the scanner when the work is done + */ +typedef struct synctex_scanner_t synctex_scanner_s; +typedef synctex_scanner_s *synctex_scanner_p; + +/** + * This is the designated method to create + * a new synctex scanner object. + * - argument output: the pdf/dvi/xdv file associated + * to the synctex file. + * If necessary, it can be the tex file that + * originated the synctex file but this might cause + * problems if the \\jobname has a custom value. + * Despite this method can accept a relative path + * in practice, you should only pass full paths. + * The path should be encoded by the underlying + * file system, assuming that it is based on + * 8 bits characters, including UTF8, + * not 16 bits nor 32 bits. + * The last file extension is removed and + * replaced by the proper extension, + * either synctex or synctex.gz. + * - argument build_directory: It is the directory where + * all the auxiliary stuff is created. + * If no synctex file is found in the same directory + * as the output file, then we try to find one in + * this build directory. + * It is the directory where all the auxiliary + * stuff is created. Sometimes, the synctex output + * file and the pdf, dvi or xdv files are not + * created in the same location. See MikTeX. + * This directory path can be NULL, + * it will be ignored then. + * It can be either absolute or relative to the + * directory of the output pdf (dvi or xdv) file. + * Please note that this new argument is provided + * as a convenience but should not be used. + * Available since version 1.5. + * - argument parse: In general, use 1. + * Use 0 only if you do not want to parse the + * content but just check for existence. + * Available since version 1.5 + * - resturn: a scanner. NULL is returned in case + * of an error or non existent file. + */ +synctex_scanner_p synctex_scanner_new_with_output_file(const char *output, const char *build_directory, int parse); + +/** + * Designated method to delete a synctex scanner object, + * including all its internal resources. + * Frees all the memory, you must call it when you are finished with the scanner. + * - argument scanner: a scanner. + * - returns: an integer used for testing purposes. + */ +int synctex_scanner_free(synctex_scanner_p scanner); + +/** + * Send this message to force the scanner to + * parse the contents of the synctex output file. + * Nothing is performed if the file was already parsed. + * In each query below, this message is sent, + * but if you need to access information more directly, + * you must ensure that the parsing did occur. + * Usage: + * if((my_scanner = synctex_scanner_parse(my_scanner))) { + * continue with my_scanner... + * } else { + * there was a problem + * } + * - returns: the argument on success. + * On failure, frees scanner and returns NULL. + */ +synctex_scanner_p synctex_scanner_parse(synctex_scanner_p scanner); + +/* synctex_node_p is the type for all synctex nodes. + * Its implementation is considered private. + * The synctex file is parsed into a tree of nodes, either sheet, form, boxes, math nodes... */ + +typedef struct synctex_node_t synctex_node_s; +typedef synctex_node_s *synctex_node_p; + +/* The main entry points. + * Given the file name, a line and a column number, synctex_display_query returns the number of nodes + * satisfying the contrain. Use code like + * + * if(synctex_display_query(scanner,name,line,column,page_hint)>0) { + * synctex_node_p node; + * while((node = synctex_scanner_next_result(scanner))) { + * // do something with node + * ... + * } + * } + * + * Please notice that since version 1.19, + * there is a new argument page_hint. + * The results in pages closer to page_hint are given first. + * For example, one can + * - highlight each resulting node in the output, using synctex_node_visible_h and synctex_node_visible_v + * - highlight all the rectangles enclosing those nodes, using synctex_node_box_visible_... functions + * - highlight just the character using that information + * + * Given the page and the position in the page, synctex_edit_query returns the number of nodes + * satisfying the contrain. Use code like + * + * if(synctex_edit_query(scanner,page,h,v)>0) { + * synctex_node_p node; + * while(node = synctex_scanner_next_result(scanner)) { + * // do something with node + * ... + * } + * } + * + * For example, one can + * - highlight each resulting line in the input, + * - highlight just the character using that information + * + * page is 1 based + * h and v are coordinates in 72 dpi unit, relative to the top left corner of the page. + * If you make a new query, the result of the previous one is discarded. If you need to make more than one query + * in parallel, use the iterator API exposed in + * the synctex_parser_private.h header. + * If one of this function returns a negative integer, + * it means that an error occurred. + * + * Both methods are conservative, in the sense that matching is weak. + * If the exact column number is not found, there will be an answer with the whole line. + * + * Sumatra-PDF, Skim, iTeXMac2, TeXShop and Texworks are examples of open source software that use this library. + * You can browse their code for a concrete implementation. + */ +typedef long synctex_status_t; +/* The page_hint argument is used to resolve ambiguities. + * Whenever, different matches occur, the ones closest + * to the page will be given first. Pass a negative number + * when in doubt. Using pdf forms may lead to ambiguities. + */ +synctex_status_t synctex_display_query(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint); +synctex_status_t synctex_edit_query(synctex_scanner_p scanner, int page, float h, float v); +synctex_node_p synctex_scanner_next_result(synctex_scanner_p scanner); +synctex_status_t synctex_scanner_reset_result(synctex_scanner_p scanner); + +/** + * The horizontal and vertical location, + * the width, height and depth of a box enclosing node. + * All dimensions are given in page coordinates + * as opposite to TeX coordinates. + * The origin is at the top left corner of the page. + * Code example for Qt5: + * (from TeXworks source TWSynchronize.cpp) + * QRectF nodeRect(synctex_node_box_visible_h(node), + * synctex_node_box_visible_v(node) - + * synctex_node_box_visible_height(node), + * synctex_node_box_visible_width(node), + * synctex_node_box_visible_height(node) + + * synctex_node_box_visible_depth(node)); + * Code example for Cocoa: + * NSRect bounds = [pdfPage + * boundsForBox:kPDFDisplayBoxMediaBox]; + * NSRect nodeRect = NSMakeRect( + * synctex_node_box_visible_h(node), + * NSMaxY(bounds)-synctex_node_box_visible_v(node) + + * synctex_node_box_visible_height(node), + * synctex_node_box_visible_width(node), + * synctex_node_box_visible_height(node) + + * synctex_node_box_visible_depth(node) + * ); + * The visible dimensions are bigger than real ones + * to compensate 0 width boxes or nodes intentionally + * put outside the box (using \\kern for example). + * - parameter node: a node. + * - returns: a float. + * - author: JL + */ +float synctex_node_box_visible_h(synctex_node_p node); +float synctex_node_box_visible_v(synctex_node_p node); +float synctex_node_box_visible_width(synctex_node_p node); +float synctex_node_box_visible_height(synctex_node_p node); +float synctex_node_box_visible_depth(synctex_node_p node); + +/** + * For quite all nodes, horizontal and vertical coordinates, and width. + * All dimensions are given in page coordinates + * as opposite to TeX coordinates. + * The origin is at the top left corner of the page. + * The visible dimensions are bigger than real ones + * to compensate 0 width boxes or nodes intentionally + * put outside the box (using \\kern for example). + * All nodes have coordinates, but all nodes don't + * have non null size. For example, math nodes + * have no width according to TeX, and in that case + * synctex_node_visible_width simply returns 0. + * The same holds for kern nodes that do not have + * height nor depth, etc... + */ +float synctex_node_visible_h(synctex_node_p node); +float synctex_node_visible_v(synctex_node_p node); +float synctex_node_visible_width(synctex_node_p node); +float synctex_node_visible_height(synctex_node_p node); +float synctex_node_visible_depth(synctex_node_p node); + +/** + * Given a node, access to its tag, line and column. + * The line and column numbers are 1 based. + * The latter is not yet fully supported in TeX, + * the default implementation returns 0 + * which means the whole line. + * synctex_node_get_name returns the path of the + * TeX source file that was used to create the node. + * When the tag is known, the scanner of the node + * will also give that same file name, see + * synctex_scanner_get_name below. + */ +int synctex_node_tag(synctex_node_p node); +int synctex_node_line(synctex_node_p node); +int synctex_node_column(synctex_node_p node); +const char *synctex_node_get_name(synctex_node_p node); + +/** + This is the page where the node appears. + * This is a 1 based index as given by TeX. + */ +int synctex_node_page(synctex_node_p node); + +/** + * Display all the information contained in the scanner. + * If the records are too numerous, only the first ones are displayed. + * This is mainly for informational purpose to help developers. + */ +void synctex_scanner_display(synctex_scanner_p scanner); + +/* Managing the input file names. + * Given a tag, synctex_scanner_get_name will return the corresponding file name. + * Conversely, given a file name, synctex_scanner_get_tag will return, the corresponding tag. + * The file name must be the very same as understood by TeX. + * For example, if you \input myDir/foo.tex, the file name is myDir/foo.tex. + * No automatic path expansion is performed. + * Finally, synctex_scanner_input is the first input node of the scanner. + * To browse all the input node, use a loop like + * ... + * synctex_node_p = input_node; + * ... + * if((input_node = synctex_scanner_input(scanner))) { + * do { + * blah + * } while((input_node=synctex_node_sibling(input_node))); + * } + * + * The output is the name that was used to create the scanner. + * The synctex is the real name of the synctex file, + * it was obtained from output by setting the proper file extension. + */ +const char *synctex_scanner_get_name(synctex_scanner_p scanner, int tag); + +int synctex_scanner_get_tag(synctex_scanner_p scanner, const char *name); + +synctex_node_p synctex_scanner_input(synctex_scanner_p scanner); +synctex_node_p synctex_scanner_input_with_tag(synctex_scanner_p scanner, int tag); +const char *synctex_scanner_get_output(synctex_scanner_p scanner); +const char *synctex_scanner_get_synctex(synctex_scanner_p scanner); + +/* The x and y offset of the origin in TeX coordinates. The magnification + These are used by pdf viewers that want to display the real box size. + For example, getting the horizontal coordinates of a node would require + synctex_node_box_h(node)*synctex_scanner_magnification(scanner)+synctex_scanner_x_offset(scanner) + Getting its TeX width would simply require + synctex_node_box_width(node)*synctex_scanner_magnification(scanner) + but direct methods are available for that below. + */ +int synctex_scanner_x_offset(synctex_scanner_p scanner); +int synctex_scanner_y_offset(synctex_scanner_p scanner); +float synctex_scanner_magnification(synctex_scanner_p scanner); + +/** + * ## Browsing the nodes + * parent, child and sibling are standard names for tree nodes. + * The parent is one level higher, + * the child is one level deeper, + * and the sibling is at the same level. + * A node and its sibling have the same parent. + * A node is the parent of its children. + * A node is either the child of its parent, + * or belongs to the sibling chain of its parent's child. + * The sheet or form of a node is the topmost ancestor, + * it is of type sheet or form. + * The next node is either the child, the sibling or the parent's sibling, + * unless the parent is a sheet, a form or NULL. + * This allows to navigate through all the nodes of a given sheet node: + * + * synctex_node_p node = sheet; + * while((node = synctex_node_next(node))) { + * // do something with node + * } + * + * With synctex_sheet_content and synctex_form_content, + * you can retrieve the sheet node given the page + * or form tag. + * The page is 1 based, according to TeX standards. + * Conversely synctex_node_parent_sheet or + * synctex_node_parent_form allows to retrieve + * the sheet or the form containing a given node. + * Notice that a node is not contained in a sheet + * and a form at the same time. + * Some nodes are not contained in either (handles). + */ + +synctex_node_p synctex_node_parent(synctex_node_p node); +synctex_node_p synctex_node_parent_sheet(synctex_node_p node); +synctex_node_p synctex_node_parent_form(synctex_node_p node); +synctex_node_p synctex_node_child(synctex_node_p node); +synctex_node_p synctex_node_last_child(synctex_node_p node); +synctex_node_p synctex_node_sibling(synctex_node_p node); +synctex_node_p synctex_node_last_sibling(synctex_node_p node); +synctex_node_p synctex_node_arg_sibling(synctex_node_p node); +synctex_node_p synctex_node_next(synctex_node_p node); + +/** + * Top level entry points. + * The scanner owns a list of sheet siblings and + * a list of form siblings. + * Sheets or forms have one child which is a box: + * theie contents. + * - argument page: 1 based sheet page number. + * - argument tag: 1 based form tag number. + */ +synctex_node_p synctex_sheet(synctex_scanner_p scanner, int page); +synctex_node_p synctex_sheet_content(synctex_scanner_p scanner, int page); +synctex_node_p synctex_form(synctex_scanner_p scanner, int tag); +synctex_node_p synctex_form_content(synctex_scanner_p scanner, int tag); + +/* This is primarily used for debugging purpose. + * The second one logs information for the node and recursively displays information for its next node */ +void synctex_node_log(synctex_node_p node); +void synctex_node_display(synctex_node_p node); + +/* For quite all nodes, horizontal, vertical coordinates, and width. + * These are expressed in TeX small points coordinates, with origin at the top left corner. + */ +int synctex_node_h(synctex_node_p node); +int synctex_node_v(synctex_node_p node); +int synctex_node_width(synctex_node_p node); +int synctex_node_height(synctex_node_p node); +int synctex_node_depth(synctex_node_p node); + +/* For all nodes, dimensions of the enclosing box. + * These are expressed in TeX small points coordinates, with origin at the top left corner. + * A box is enclosing itself. + */ +int synctex_node_box_h(synctex_node_p node); +int synctex_node_box_v(synctex_node_p node); +int synctex_node_box_width(synctex_node_p node); +int synctex_node_box_height(synctex_node_p node); +int synctex_node_box_depth(synctex_node_p node); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/synctex/synctex_parser_advanced.h b/core/synctex/synctex_parser_advanced.h new file mode 100644 index 0000000..0fe4fe5 --- /dev/null +++ b/core/synctex/synctex_parser_advanced.h @@ -0,0 +1,484 @@ +/* + Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + + This file is part of the __SyncTeX__ package. + + [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) + [//]: # (Version: 1.19) + + See `synctex_parser_readme.md` for more details + + ## License + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE + + Except as contained in this notice, the name of the copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization from the copyright holder. + */ + +#include "synctex_parser.h" +#include "synctex_parser_utils.h" + +#ifndef __SYNCTEX_PARSER_PRIVATE__ +#define __SYNCTEX_PARSER_PRIVATE__ + +#ifdef __cplusplus +extern "C" { +#endif +/* Reminder that the argument must not be NULL */ +typedef synctex_node_p synctex_non_null_node_p; + +/* Each node of the tree, except the scanner itself belongs to a class. + * The class object is just a struct declaring the owning scanner + * This is a pointer to the scanner as root of the tree. + * The type is used to identify the kind of node. + * The class declares pointers to a creator and a destructor method. + * The log and display fields are used to log and display the node. + * display will also display the child, sibling and parent sibling. + * parent, child and sibling are used to navigate the tree, + * from TeX box hierarchy point of view. + * The friend field points to a method which allows to navigate from friend to friend. + * A friend is a node with very close tag and line numbers. + * Finally, the info field point to a method giving the private node info offset. + */ + +/** + * These are the masks for the synctex node types. + * int's are 32 bits at least. + */ +enum { synctex_shift_root, synctex_shift_no_root, synctex_shift_void, synctex_shift_no_void, synctex_shift_box, synctex_shift_no_box, synctex_shift_proxy, synctex_shift_no_proxy, synctex_shift_h, synctex_shift_v }; +enum { + synctex_mask_root = 1, + synctex_mask_no_root = synctex_mask_root << 1, + synctex_mask_void = synctex_mask_no_root << 1, + synctex_mask_no_void = synctex_mask_void << 1, + synctex_mask_box = synctex_mask_no_void << 1, + synctex_mask_no_box = synctex_mask_box << 1, + synctex_mask_proxy = synctex_mask_no_box << 1, + synctex_mask_no_proxy = synctex_mask_proxy << 1, + synctex_mask_h = synctex_mask_no_proxy << 1, + synctex_mask_v = synctex_mask_h << 1, +}; +enum { synctex_mask_non_void_hbox = synctex_mask_no_void | synctex_mask_box | synctex_mask_h, synctex_mask_non_void_vbox = synctex_mask_no_void | synctex_mask_box | synctex_mask_v }; +typedef enum { + synctex_node_mask_sf = synctex_mask_root | synctex_mask_no_void | synctex_mask_no_box | synctex_mask_no_proxy, + synctex_node_mask_vbox = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_v, + synctex_node_mask_hbox = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_h, + synctex_node_mask_void_vbox = synctex_mask_no_root | synctex_mask_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_v, + synctex_node_mask_void_hbox = synctex_mask_no_root | synctex_mask_void | synctex_mask_box | synctex_mask_no_proxy | synctex_mask_h, + synctex_node_mask_vbox_proxy = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_proxy | synctex_mask_v, + synctex_node_mask_hbox_proxy = synctex_mask_no_root | synctex_mask_no_void | synctex_mask_box | synctex_mask_proxy | synctex_mask_h, + synctex_node_mask_nvnn = synctex_mask_no_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_no_proxy, + synctex_node_mask_input = synctex_mask_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_no_proxy, + synctex_node_mask_proxy = synctex_mask_no_root | synctex_mask_void | synctex_mask_no_box | synctex_mask_proxy +} synctex_node_mask_t; + +enum { + /* input */ + synctex_tree_sibling_idx = 0, + synctex_tree_s_input_max = 1, + /* All */ + synctex_tree_s_parent_idx = 1, + synctex_tree_sp_child_idx = 2, + synctex_tree_spc_friend_idx = 3, + synctex_tree_spcf_last_idx = 4, + synctex_tree_spcfl_vbox_max = 5, + /* hbox supplement */ + synctex_tree_spcfl_next_hbox_idx = 5, + synctex_tree_spcfln_hbox_max = 6, + /* hbox proxy supplement */ + synctex_tree_spcfln_target_idx = 6, + synctex_tree_spcflnt_proxy_hbox_max = 7, + /* vbox proxy supplement */ + synctex_tree_spcfl_target_idx = 5, + synctex_tree_spcflt_proxy_vbox_max = 6, + /* spf supplement*/ + synctex_tree_sp_friend_idx = 2, + synctex_tree_spf_max = 3, + /* box boundary supplement */ + synctex_tree_spf_arg_sibling_idx = 3, + synctex_tree_spfa_max = 4, + /* proxy supplement */ + synctex_tree_spf_target_idx = 3, + synctex_tree_spft_proxy_max = 4, + /* last proxy supplement */ + synctex_tree_spfa_target_idx = 4, + synctex_tree_spfat_proxy_last_max = 5, + /* sheet supplement */ + synctex_tree_s_child_idx = 1, + synctex_tree_sc_next_hbox_idx = 2, + synctex_tree_scn_sheet_max = 3, + /* form supplement */ + synctex_tree_sc_target_idx = 2, + synctex_tree_sct_form_max = 3, + /* spct */ + synctex_tree_spc_target_idx = 3, + synctex_tree_spct_handle_max = 4, +}; + +enum { + /* input */ + synctex_data_input_tag_idx = 0, + synctex_data_input_line_idx = 1, + synctex_data_input_name_idx = 2, + synctex_data_input_tln_max = 3, + /* sheet */ + synctex_data_sheet_page_idx = 0, + synctex_data_p_sheet_max = 1, + /* form */ + synctex_data_form_tag_idx = 0, + synctex_data_t_form_max = 1, + /* tlchv */ + synctex_data_tag_idx = 0, + synctex_data_line_idx = 1, + synctex_data_column_idx = 2, + synctex_data_h_idx = 3, + synctex_data_v_idx = 4, + synctex_data_tlchv_max = 5, + /* tlchvw */ + synctex_data_width_idx = 5, + synctex_data_tlchvw_max = 6, + /* box */ + synctex_data_height_idx = 6, + synctex_data_depth_idx = 7, + synctex_data_box_max = 8, + /* hbox supplement */ + synctex_data_mean_line_idx = 8, + synctex_data_weight_idx = 9, + synctex_data_h_V_idx = 10, + synctex_data_v_V_idx = 11, + synctex_data_width_V_idx = 12, + synctex_data_height_V_idx = 13, + synctex_data_depth_V_idx = 14, + synctex_data_hbox_max = 15, + /* ref */ + synctex_data_ref_tag_idx = 0, + synctex_data_ref_h_idx = 1, + synctex_data_ref_v_idx = 2, + synctex_data_ref_thv_max = 3, + /* proxy */ + synctex_data_proxy_h_idx = 0, + synctex_data_proxy_v_idx = 1, + synctex_data_proxy_hv_max = 2, +}; + +/* each synctex node has a class */ +typedef struct synctex_class_t synctex_class_s; +typedef synctex_class_s *synctex_class_p; + +/* synctex_node_p is a pointer to a node + * synctex_node_s is the target of the synctex_node_p pointer + * It is a pseudo object oriented program. + * class is a pointer to the class object the node belongs to. + * implementation is meant to contain the private data of the node + * basically, there are 2 kinds of information: navigation information and + * synctex information. Both will depend on the type of the node, + * thus different nodes will have different private data. + * There is no inheritancy overhead. + */ +typedef union { + synctex_node_p as_node; + int as_integer; + char *as_string; + void *as_pointer; +} synctex_data_u; +typedef synctex_data_u *synctex_data_p; + +#if defined(SYNCTEX_USE_CHARINDEX) +typedef unsigned int synctex_charindex_t; +synctex_charindex_t synctex_node_charindex(synctex_node_p node); +typedef synctex_charindex_t synctex_lineindex_t; +synctex_lineindex_t synctex_node_lineindex(synctex_node_p node); +synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner); +#define SYNCTEX_DECLARE_CHARINDEX \ + synctex_charindex_t char_index; \ + synctex_lineindex_t line_index; +#define SYNCTEX_DECLARE_CHAR_OFFSET synctex_charindex_t charindex_offset; +#else +#define SYNCTEX_DECLARE_CHARINDEX +#define SYNCTEX_DECLARE_CHAR_OFFSET +#endif +struct synctex_node_t { + SYNCTEX_DECLARE_CHARINDEX + synctex_class_p class; +#ifdef DEBUG + synctex_data_u data[22]; +#else + synctex_data_u data[1]; +#endif +}; + +typedef synctex_node_p *synctex_node_r; + +typedef struct { + int h; + int v; +} synctex_point_s; + +typedef synctex_point_s *synctex_point_p; + +typedef struct { + synctex_point_s min; /* top left */ + synctex_point_s max; /* bottom right */ +} synctex_box_s; + +typedef synctex_box_s *synctex_box_p; +/** + * These are the types of the synctex nodes. + * No need to use them but the compiler needs them here. + * There are 3 kinds of nodes. + * - primary nodes + * - proxies + * - handles + * Primary nodes are created at parse time + * of the synctex file. + * Proxies are used to support pdf forms. + * The ref primary nodes are replaced by a tree + * of proxy nodes which duplicate the tree of primary + * nodes available in the referred form. + * Roughly speaking, the primary nodes of the form + * know what to display, the proxy nodes know where. + * Handles are used in queries. They point to either + * primary nodes or proxies. + */ +typedef enum { + synctex_node_type_none = 0, + synctex_node_type_input, + synctex_node_type_sheet, + synctex_node_type_form, + synctex_node_type_ref, + synctex_node_type_vbox, + synctex_node_type_void_vbox, + synctex_node_type_hbox, + synctex_node_type_void_hbox, + synctex_node_type_kern, + synctex_node_type_glue, + synctex_node_type_rule, + synctex_node_type_math, + synctex_node_type_boundary, + synctex_node_type_box_bdry, + synctex_node_type_proxy, + synctex_node_type_proxy_last, + synctex_node_type_proxy_vbox, + synctex_node_type_proxy_hbox, + synctex_node_type_handle, + synctex_node_number_of_types +} synctex_node_type_t; +/* synctex_node_type gives the type of a given node, + * synctex_node_isa gives the same information as a human readable text. */ +synctex_node_type_t synctex_node_type(synctex_node_p node); +const char *synctex_node_isa(synctex_node_p node); + +synctex_node_type_t synctex_node_target_type(synctex_node_p node); + +synctex_node_type_t synctex_node_type(synctex_node_p node); +const char *synctex_node_isa(synctex_node_p node); + +void synctex_node_log(synctex_node_p node); +void synctex_node_display(synctex_node_p node); + +/* Given a node, access to the location in the synctex file where it is defined. + */ + +int synctex_node_form_tag(synctex_node_p node); + +int synctex_node_mean_line(synctex_node_p node); +int synctex_node_weight(synctex_node_p node); +int synctex_node_child_count(synctex_node_p node); + +int synctex_node_h(synctex_node_p node); +int synctex_node_v(synctex_node_p node); +int synctex_node_width(synctex_node_p node); + +int synctex_node_box_h(synctex_node_p node); +int synctex_node_box_v(synctex_node_p node); +int synctex_node_box_width(synctex_node_p node); +int synctex_node_box_height(synctex_node_p node); +int synctex_node_box_depth(synctex_node_p node); + +int synctex_node_hbox_h(synctex_node_p node); +int synctex_node_hbox_v(synctex_node_p node); +int synctex_node_hbox_width(synctex_node_p node); +int synctex_node_hbox_height(synctex_node_p node); +int synctex_node_hbox_depth(synctex_node_p node); + +synctex_scanner_p synctex_scanner_new(); +synctex_node_p synctex_node_new(synctex_scanner_p scanner, synctex_node_type_t type); + +/** + * Scanner display switcher getter. + * If the switcher is 0, synctex_node_display is disabled. + * If the switcher is <0, synctex_node_display has no limit. + * If the switcher is >0, only the first switcher (as number) nodes are displayed. + * - parameter: a scanner + * - returns: an integer + */ +int synctex_scanner_display_switcher(synctex_scanner_p scanR); +void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher); + +/** + * Iterator is the structure used to traverse + * the answer to client queries. + * First answers are the best matches, according + * to criteria explained below. + * Next answers are not ordered. + * Objects are handles to nodes in the synctex node tree starting at scanner. + */ +typedef struct synctex_iterator_t synctex_iterator_s; +typedef synctex_iterator_s *synctex_iterator_p; + +/** + * Designated creator for a display query, id est, + * forward navigation from source to output. + * Returns NULL if the query has no answer. + * Code example: + * synctex_iterator_p iterator = NULL; + * if ((iterator = synctex_iterator_new_display(...)) { + * synctex_node_p node = NULL; + * while((node = synctex_iterator_next_result(iterator))) { + * do something with node... + * } + */ +synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner, const char *name, int line, int column, int page_hint); +/** + * Designated creator for an edit query, id est, + * backward navigation from output to source. + * Code example: + * synctex_iterator_p iterator = NULL; + * if ((iterator = synctex_iterator_new_edit(...)) { + * synctex_node_p node = NULL; + * while((node = synctex_iterator_next_result(iterator))) { + * do something with node... + * } + */ +synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner, int page, float h, float v); +/** + * Free all the resources. + * - argument iterator: the object to free... + * You should free the iterator before the scanner + * owning the nodes it iterates with. + */ +void synctex_iterator_free(synctex_iterator_p iterator); +/** + * Whether the iterator actually points to an object. + * - argument iterator: the object to iterate on... + */ +synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator); +/** + * Returns the pointed object and advance the cursor + * to the next object. Returns NULL and does nothing + * if the end has already been reached. + * - argument iterator: the object to iterate on... + */ +synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator); +/** + * Reset the cursor position to the first result. + * - argument iterator: the object to iterate on... + */ +int synctex_iterator_reset(synctex_iterator_p iterator); +/** + * The number of objects left for traversal. + * - argument iterator: the object to iterate on... + */ +int synctex_iterator_count(synctex_iterator_p iterator); + +/** + * The target of the node, either a handle or a proxy. + */ +synctex_node_p synctex_node_target(synctex_node_p node); + +#ifndef SYNCTEX_NO_UPDATER +/* The main synctex updater object. + * This object is used to append information to the synctex file. + * Its implementation is considered private. + * It is used by the synctex command line tool to take into account modifications + * that could occur while postprocessing files by dvipdf like filters. + */ +typedef struct synctex_updater_t synctex_updater_s; +typedef synctex_updater_s *synctex_updater_p; + +/* Designated initializer. + * Once you are done with your whole job, + * free the updater */ +synctex_updater_p synctex_updater_new_with_output_file(const char *output, const char *directory); + +/* Use the next functions to append records to the synctex file, + * no consistency tests made on the arguments */ +void synctex_updater_append_magnification(synctex_updater_p updater, char *magnification); +void synctex_updater_append_x_offset(synctex_updater_p updater, char *x_offset); +void synctex_updater_append_y_offset(synctex_updater_p updater, char *y_offset); + +/* You MUST free the updater, once everything is properly appended */ +void synctex_updater_free(synctex_updater_p updater); +#endif + +#if defined(SYNCTEX_DEBUG) +#include "assert.h" +#define SYNCTEX_ASSERT assert +#else +#define SYNCTEX_ASSERT(UNUSED) +#endif + +#if defined(SYNCTEX_TESTING) +#warning TESTING IS PROHIBITED +#if __clang__ +#define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wformat-extra-args\"") + +#define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS _Pragma("clang diagnostic pop") +#else +#define __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS +#define __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS +#endif + +#define SYNCTEX_TEST_BODY(counter, condition, desc, ...) \ + do { \ + __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \ + if (!(condition)) { \ + ++counter; \ + printf("**** Test failed: %s\nfile %s\nfunction %s\nline %i\n", #condition, __FILE__, __FUNCTION__, __LINE__); \ + printf((desc), ##__VA_ARGS__); \ + } \ + __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \ + } while (0) + +#define SYNCTEX_TEST_PARAMETER(counter, condition) SYNCTEX_TEST_BODY(counter, (condition), "Invalid parameter not satisfying: %s", #condition) + +int synctex_test_input(synctex_scanner_p scanner); +int synctex_test_proxy(synctex_scanner_p scanner); +int synctex_test_tree(synctex_scanner_p scanner); +int synctex_test_page(synctex_scanner_p scanner); +int synctex_test_handle(synctex_scanner_p scanner); +int synctex_test_display_query(synctex_scanner_p scanner); +int synctex_test_charindex(); +int synctex_test_sheet_1(); +int synctex_test_sheet_2(); +int synctex_test_sheet_3(); +int synctex_test_form(); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/synctex/synctex_parser_local.h b/core/synctex/synctex_parser_local.h new file mode 100644 index 0000000..28880c7 --- /dev/null +++ b/core/synctex/synctex_parser_local.h @@ -0,0 +1,45 @@ +/* +Copyright (c) 2008, 2009, 2010 , 2011 jerome DOT laurens AT u-bourgogne DOT fr + +This file is part of the SyncTeX package. + +Latest Revision: Tue Jun 14 08:23:30 UTC 2011 + +Version: 1.18 + +See synctex_parser_readme.txt for more details + +License: +-------- +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE + +Except as contained in this notice, the name of the copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from the copyright holder. + +*/ + +/* This local header file is for TEXLIVE, use your own header to fit your system */ +#include /* for inline && HAVE_xxx */ +/* No inlining for synctex tool in texlive. */ +#define SYNCTEX_INLINE diff --git a/core/synctex/synctex_parser_readme.md b/core/synctex/synctex_parser_readme.md new file mode 100644 index 0000000..7dae3a9 --- /dev/null +++ b/core/synctex/synctex_parser_readme.md @@ -0,0 +1,246 @@ +# __SyncTeX__ + +This file is part of the __SyncTeX__ package. + +[//]: # (Version: 1.19) +[//]: # (Date: Fri Jul 14 16:20:41 UTC 2017) + +## Important + +* Changes in version `1.19` + + A long standing bug affecting only pdftex has been fixed by adding support to pdf forms. As a side effect, the synchronization algorithm gains in accuracy for all the engines, especially from pdf to source. Of course, there is a small cost in both memory footprint and computational time, but none is noticeable. + + Some technical changes in the API. + * more consistent type naming convention + * `_s` suffix for struct's + * `_p` suffix for pointers + * `_t` suffix for standard types + * `_f` suffix for functions... + + thus `synctex_node_t` has become `synctex_node_p`. + + * supplemental argument in `synctex_display_query`. Set `page_hint` to the currently displayed pdf page number (0 based). If this info is not available, set `page_hint` to 0, it corresponds to the old behaviour. + * rename `synctex_next_result` to `synctex_scanner_next_result` + * additional `synctex_parser_private.h` header where + more API are exposed. For an advanced usage only (eg parallel synchronizations). + * `SYNCTEX_NO_UPDATER` preprocessor macro to deactivate some code useless to frontends. + +## What is it ? + +The *Synchronization TeXnology* named __SyncTeX__ is a new feature +of recent __TeX__ engines designed by Jérôme Laurens. +It allows to synchronize between input and output, which means to +navigate from the source document to the typeset material and vice versa. +Browse the source code for more information. + +## Contents +This package is mainly for developers, it contains the following files: + +* `synctex_parser_readme.md` (this file) +* `synctex_parser_version.txt` +* `synctex_parser_utils.c` +* `synctex_parser_utils.h` +* `synctex_parser_local.h` +* `synctex_parser.h` +* `synctex_parser_advanced.h` +* `synctex_parser.c` + +The file you are reading contains more informations about the __SyncTeX__ parser history. + +## Source + +All stable sources are available from [TeXLive repository](http://www.tug.org/svn/texlive/trunk/Build/source/texk/web2c/synctexdir/). + +Latest development sources are available from GitHub. + +Please notice that due to the complexity of the TeXLive TeX distribution, there might be some delay before synchronization occurs between various repositories. + +## Usage + +In order to support __SyncTeX__ in a viewer, it is sufficient to include +in the source the files `synctex_parser.c` and `synctex_parser_utils.c`. +The synctex parser usage is described in `synctex_parser.h` header file. + +More advanced usage is found in `synctex_parser_advanced.h` + +The other files are used by tex engines or by the synctex command line utility: + +``` +ChangeLog +README.txt +am +man1 +man5 +synctex-common.h +synctex-convert.sh +synctex-e-mem.ch0 +synctex-e-mem.ch1 +synctex-e-rec.ch0 +synctex-e-rec.ch1 +synctex-etex.h +synctex-mem.ch0 +synctex-mem.ch1 +synctex-mem.ch2 +synctex-pdf-rec.ch2 +synctex-pdftex.h +synctex-rec.ch0 +synctex-rec.ch1 +synctex-rec.ch2 +synctex-tex.h +synctex-xe-mem.ch2 +synctex-xe-rec.ch2 +synctex-xe-rec.ch3 +synctex-xetex.h +synctex.c +synctex.defines +synctex.h +synctex_main.c +tests +... +``` + +## Version: + +This is version 1, which refers to the synctex output file format. + +The files are identified by a build number. +In order to help developers to automatically manage the version and build numbers +and download the parser only when necessary, the `synctex_parser_version.txt` +is an ASCII text file just containing the current version and build numbers eg `1.19`. + +## History: + +* 1.1: Thu Jul 17 09:28:13 UTC 2008 + - First official version available in TeXLive 2008 DVD. + Unfortunately, the backwards synchronization is not working properly mainly for ConTeXt users, see below. +* 1.2: Tue Sep 2 10:28:32 UTC 2008 + - Correction for ConTeXt support in the edit query. + The previous method was assuming that TeX boxes do not overlap, + which is reasonable for LaTeX but not for ConTeXt. + This assumption is no longer considered. +* 1.3: Fri Sep 5 09:39:57 UTC 2008 + - Local variable "read" renamed to "already_read" to avoid conflicts. + - "inline" compiler directive renamed to "SYNCTEX_INLINE" for code support and maintenance + - _synctex_error cannot be inlined due to variable arguments (thanks Christiaan Hofman) + - Correction in the display query, extra boundary nodes are used for a more precise forwards synchronization +* 1.4: Fri Sep 12 08:12:34 UTC 2008 + - For an unknown reason, the previous version was not the real 1.3 (as used in iTeXMac2 build 747). + As a consequence, a crash was observed. + - Some typos are fixed. +* 1.6: Mon Nov 3 20:20:02 UTC 2008 + - The bug that prevented synchronization with compressed files on windows has been fixed. + - New interface to allow system specific customization. + - Note that some APIs have changed. +* 1.8: Mer 8 jul 2009 11:32:38 UTC +Note that version 1.7 was delivered privately. + - bug fix: synctex was causing a memory leak in pdftex and xetex, thus some processing speed degradation + - bug fix: the synctex command line tool was broken when updating a .synctex file + - enhancement: better accuracy of the synchronization process + - enhancement: the pdf output file and the associated .synctex file no longer need to live in the same directory. + The new -d option of the synctex command line tool manages this situation. + This is handy when using something like tex -output-directory=DIR ... +* 1.9: Wed Nov 4 11:52:35 UTC 2009 + - Various typo fixed + - OutputDebugString replaced by OutputDebugStringA to deliberately disable unicode preprocessing + - New conditional created because OutputDebugStringA is only available since Windows 2K professional +* 1.10: Sun Jan 10 10:12:32 UTC 2010 + - Bug fix in synctex_parser.c to solve a synchronization problem with amsmath's gather environment. + Concerns the synctex tool. +* 1.11: Sun Jan 17 09:12:31 UTC 2010 + - Bug fix in synctex_parser.c, function synctex_node_box_visible_v: 'x' replaced by 'y'. + Only 3rd party tools are concerned. +* 1.12: Mon Jul 19 21:52:10 UTC 2010 + - Bug fix in synctex_parser.c, function __synctex_open: the io_mode was modified even in case of a non zero return, +causing a void .synctex.gz file to be created even if it was not expected. Reported by Marek Kasik concerning a bug on evince. +* 1.13: Fri Mar 11 07:39:12 UTC 2011 + - Bug fix in synctex_parser.c, better synchronization as suggested by Jan Sundermeyer (near line 3388). + - Stronger code design in synctex_parser_utils.c, function _synctex_get_name (really neutral behavior). + Only 3rd party tools are concerned. +* 1.14: Fri Apr 15 19:10:57 UTC 2011 + - taking output_directory into account + - Replaced FOPEN_WBIN_MODE by FOPEN_W_MODE when opening the text version of the .synctex file. + - Merging with LuaTeX's version of synctex.c +* 1.15: Fri Jun 10 14:10:17 UTC 2011 +This concerns the synctex command line tool and 3rd party developers. +TeX and friends are not concerned by these changes. + - Bug fixed in _synctex_get_io_mode_name, sometimes the wrong mode was returned + - Support for LuaTeX convention of './' file prefixing +* 1.16: Tue Jun 14 08:23:30 UTC 2011 +This concerns the synctex command line tool and 3rd party developers. +TeX and friends are not concerned by these changes. + - Better forward search (thanks Jose Alliste) + - Support for LuaTeX convention of './' file prefixing now for everyone, not only for Windows +* 1.17: Fri Oct 14 08:15:16 UTC 2011 +This concerns the synctex command line tool and 3rd party developers. +TeX and friends are not concerned by these changes. + - synctex_parser.c: cosmetic changes to enhance code readability + - Better forward synchronization. + The problem occurs for example with LaTeX \item command. + The fact is that this command creates nodes at parse time but these nodes are used only + after the text material of the \item is displayed on the page. The consequence is that sometimes, + forward synchronization spots an irrelevant point from the point of view of the editing process. + This was due to some very basic filtering policy, where a somehow arbitrary choice was made when + many different possibilities where offered for synchronisation. + Now, forward synchronization prefers nodes inside an hbox with as many acceptable spots as possible. + This is achieved with the notion of mean line and node weight. + - Adding support for the new file naming convention with './' + - function `synctex_ignore_leading_dot_slash_in_path replaces` `synctex_ignore_leading_dot_slash` + - function `_synctex_is_equivalent_file_name` is more permissive + Previously, the function synctex_scanner_get_tag would give an answer only when + the given file name was EXACTLY one of the file names listed in the synctex file. + The we added some changes accepting for example 'foo.tex' instead of './foo.tex'. + Now we have an even looser policy for dealing with file names. + If the given file name does not match exactly one the file names of the synctex file, + then we try to match the base names. If there is only one match of the base names, + then it is taken as a match for the whole names. + The base name is defined as following: + + `./foo => foo + /my///.////foo => foo + /foo => /foo + /my//.foo => /my//.foo` + +* 1.17: Tue Mar 13 10:10:03 UTC 2012 + - minor changes, no version changes + - syntax man pages are fixed as suggested by M. Shimata + see mail to tex-live@tug.org titled "syntax.5 has many warnings from groff" and "syntax.1 use invalid macro for mdoc" + - 1.17: Tue Jan 14 09:55:00 UTC 2014, fixed a segfault, patch from Sebastian Ramacher + - 1.17: Mon Aug 04, fixed a memory leak +* 1.18: Thu Jun 25 11:36:05 UTC 2015 + - nested sheets now fully supported (does it make sense in TeX) + - cosmetic changes: uniform indentation + - suppression of warnings, mainly long/int ones. In short, zlib likes ints when size_t likes longs. + - CLI synctex tool can build out of TeXLive (modulo appropriate options passed to the compiler) +* 1.19: Mon Jul 3 20:03:56 UTC 2017 + - the nested sheets patch was not a good solution. + It has been moved from the parser to the engine. + See the `synctex.c` source file for detailed explanations. + - there is a new synctex format specification. + We can see that a `.synctex` file can contain many times + the same vertical position because many objects belong + to the same line. When the options read `-synctex=±2` or more, + a very basic compression algorithm is used: + if synctex is about to write the same number then it writes + an `=` sign instead. This saves approximately 10% of the + synctex output file, either compressed or not. + The new synctex parser has been updated accordingly. + Actual tex frontend won't see any difference with the + TeX engines that include this new feature. + Frontends with the new parser won't see any difference + with the older TeX engines. + Frontends with the new parser will only see a difference + with new TeX engines if `-synctex=±2` or more is used. + +## Acknowledgments: + +The author received useful remarks from the __pdfTeX__ developers, especially Hahn The Thanh, +and significant help from __XeTeX__ developer Jonathan Kew. + +## Nota Bene: + +If you include or use a significant part of the __SyncTeX__ package into a software, +I would appreciate to be listed as contributor and see __SyncTeX__" highlighted. + +Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + diff --git a/core/synctex/synctex_parser_utils.c b/core/synctex/synctex_parser_utils.c new file mode 100644 index 0000000..850307d --- /dev/null +++ b/core/synctex/synctex_parser_utils.c @@ -0,0 +1,603 @@ +/* + Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + + This file is part of the __SyncTeX__ package. + + [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) + [//]: # (Version: 1.19) + + See `synctex_parser_readme.md` for more details + + ## License + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE + + Except as contained in this notice, the name of the copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization from the copyright holder. + +*/ + +/* In this file, we find all the functions that may depend on the operating system. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) +#define SYNCTEX_WINDOWS 1 +#endif + +#if defined(__OS2__) +#define SYNCTEX_OS2 1 +#endif + +#if defined(_WIN32) +#define SYNCTEX_RECENT_WINDOWS 1 +#endif + +#ifdef SYNCTEX_WINDOWS +#include /* Use shlwapi.lib */ +#include +#endif + +void *_synctex_malloc(size_t size) +{ + void *ptr = malloc(size); + if (ptr) { + memset(ptr, 0, size); /* ensures null termination of strings */ + } + return (void *)ptr; +} + +void _synctex_free(void *ptr) +{ + if (ptr) { + free(ptr); + } +} + +#if !defined(_WIN32) +#include +#endif + +int _synctex_log(int level, const char *prompt, const char *reason, ...) SYNCTEX_PRINTF_FORMAT(3, 4); +int _synctex_log(int level, const char *prompt, const char *reason, ...) +{ + va_list arg; + int result; + va_start(arg, reason); +#ifdef SYNCTEX_RECENT_WINDOWS + { /* This code is contributed by William Blum. + As it does not work on some older computers, + the _WIN32 conditional here is replaced with a SYNCTEX_RECENT_WINDOWS one. + According to http://msdn.microsoft.com/en-us/library/aa363362(VS.85).aspx + Minimum supported client Windows 2000 Professional + Minimum supported server Windows 2000 Server + People running Windows 2K standard edition will not have OutputDebugStringA. + JL.*/ + char *buff; + size_t len; + OutputDebugStringA(prompt); +#ifdef _MSC_VER + len = _vscprintf(reason, arg) + 1; + buff = (char *)malloc(len * sizeof(char)); +#else /* MinGW */ + size_t buffersize = 1024; + size_t max_buffersize = 1024 * buffersize; + int result; + buff = (char *)malloc(buffersize * sizeof(char)); + result = _vsnprintf(buff, buffersize - 1, reason, arg); + while (-1 == result && buffersize <= max_buffersize) { + buffersize = buffersize * 2; + buff = (char *)realloc(buff, buffersize * sizeof(char)); + result = _vsnprintf(buff, buffersize - 1, reason, arg); + } + if (-1 == result) { + // could not make the buffer big enough or simply could not write to it + free(buff); + return -1; + } +#endif + result = vsprintf(buff, reason, arg) + strlen(prompt); + OutputDebugStringA(buff); + OutputDebugStringA("\n"); + free(buff); + } +#elif defined SYNCTEX_USE_SYSLOG + char *buffer1 = NULL; + char *buffer2 = NULL; + openlog("SyncTeX", LOG_CONS | LOG_PID | LOG_PERROR | LOG_NDELAY, LOG_LOCAL0); + if (vasprintf(&buffer1, reason, arg) >= 0 && asprintf(&buffer2, "%s%s", prompt, buffer1) >= 0) { + syslog(level, "%s", buffer2); + result = (int)strlen(buffer2); + } else { + syslog(level, "%s", prompt); + vsyslog(level, reason, arg); + result = (int)strlen(prompt); + } + free(buffer1); + free(buffer2); + closelog(); +#else + FILE *where = level == LOG_ERR ? stderr : stdout; + result = fputs(prompt, where); + result += vfprintf(where, reason, arg); + result += fprintf(where, "\n"); +#endif + va_end(arg); + return result; +} + +int _synctex_error(const char *reason, ...) +{ + va_list arg; + int result; + va_start(arg, reason); +#if defined(SYNCTEX_RECENT_WINDOWS) /* LOG_ERR is not used */ + result = _synctex_log(0, "! SyncTeX Error : ", reason, arg); +#else + result = _synctex_log(LOG_ERR, "! SyncTeX Error : ", reason, arg); +#endif + va_end(arg); + return result; +} + +int _synctex_debug(const char *reason, ...) +{ + va_list arg; + int result; + va_start(arg, reason); +#if defined(SYNCTEX_RECENT_WINDOWS) /* LOG_DEBUG is not used */ + result = _synctex_log(0, "! SyncTeX Error : ", reason, arg); +#else + result = _synctex_log(LOG_DEBUG, "! SyncTeX Error : ", reason, arg); +#endif + va_end(arg); + return result; +} + +/* strip the last extension of the given string, this string is modified! */ +void _synctex_strip_last_path_extension(char *string) +{ + if (NULL != string) { + char *last_component = NULL; + char *last_extension = NULL; +#if defined(SYNCTEX_WINDOWS) + last_component = PathFindFileNameA(string); + last_extension = PathFindExtensionA(string); + if (last_extension == NULL) + return; + if (last_component == NULL) + last_component = string; + if (last_extension > last_component) { /* filter out paths like "my/dir/.hidden" */ + last_extension[0] = '\0'; + } +#else + char *next = NULL; + /* first we find the last path component */ + if (NULL == (last_component = strstr(string, "/"))) { + last_component = string; + } else { + ++last_component; + while ((next = strstr(last_component, "/"))) { + last_component = next + 1; + } + } +#if defined(SYNCTEX_OS2) + /* On OS2, the '\' is also a path separator. */ + while ((next = strstr(last_component, "\\"))) { + last_component = next + 1; + } +#endif /* SYNCTEX_OS2 */ + /* then we find the last path extension */ + if ((last_extension = strstr(last_component, "."))) { + ++last_extension; + while ((next = strstr(last_extension, "."))) { + last_extension = next + 1; + } + --last_extension; /* back to the "." */ + if (last_extension > last_component) { /* filter out paths like ....my/dir/.hidden"*/ + last_extension[0] = '\0'; + } + } +#endif /* SYNCTEX_WINDOWS */ + } +} + +synctex_bool_t synctex_ignore_leading_dot_slash_in_path(const char **name_ref) +{ + if (SYNCTEX_IS_DOT((*name_ref)[0]) && SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[1])) { + do { + (*name_ref) += 2; + while (SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[0])) { + ++(*name_ref); + } + } while (SYNCTEX_IS_DOT((*name_ref)[0]) && SYNCTEX_IS_PATH_SEPARATOR((*name_ref)[1])); + return synctex_YES; + } + return synctex_NO; +} + +/* The base name is necessary to deal with the 2011 file naming convention... + * path is a '\0' terminated string + * The return value is the trailing part of the argument, + * just following the first occurrence of the regexp pattern "[^|/|\].[\|/]+".*/ +const char *_synctex_base_name(const char *path) +{ + const char *ptr = path; + do { + if (synctex_ignore_leading_dot_slash_in_path(&ptr)) { + return ptr; + } + do { + if (!*(++ptr)) { + return path; + } + } while (!SYNCTEX_IS_PATH_SEPARATOR(*ptr)); + } while (*(++ptr)); + return path; +} + +/* Compare two file names, windows is sometimes case insensitive... */ +synctex_bool_t _synctex_is_equivalent_file_name(const char *lhs, const char *rhs) +{ + /* Remove the leading regex '(\./+)*' in both rhs and lhs */ + synctex_ignore_leading_dot_slash_in_path(&lhs); + synctex_ignore_leading_dot_slash_in_path(&rhs); +next_character: + if (SYNCTEX_IS_PATH_SEPARATOR(*lhs)) { /* lhs points to a path separator */ + if (!SYNCTEX_IS_PATH_SEPARATOR(*rhs)) { /* but not rhs */ + return synctex_NO; + } + ++lhs; + ++rhs; + synctex_ignore_leading_dot_slash_in_path(&lhs); + synctex_ignore_leading_dot_slash_in_path(&rhs); + goto next_character; + } else if (SYNCTEX_IS_PATH_SEPARATOR(*rhs)) { /* rhs points to a path separator but not lhs */ + return synctex_NO; + } else if (SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(*lhs, *rhs)) { /* uppercase do not match */ + return synctex_NO; + } else if (!*lhs) { /* lhs is at the end of the string */ + return *rhs ? synctex_NO : synctex_YES; + } else if (!*rhs) { /* rhs is at the end of the string but not lhs */ + return synctex_NO; + } + ++lhs; + ++rhs; + goto next_character; +} + +synctex_bool_t _synctex_path_is_absolute(const char *name) +{ + if (!strlen(name)) { + return synctex_NO; + } +#if defined(SYNCTEX_WINDOWS) || defined(SYNCTEX_OS2) + if (strlen(name) > 2) { + return (name[1] == ':' && SYNCTEX_IS_PATH_SEPARATOR(name[2])) ? synctex_YES : synctex_NO; + } + return synctex_NO; +#else + return SYNCTEX_IS_PATH_SEPARATOR(name[0]) ? synctex_YES : synctex_NO; +#endif +} + +/* We do not take care of UTF-8 */ +const char *_synctex_last_path_component(const char *name) +{ + const char *c = name + strlen(name); + if (c > name) { + if (!SYNCTEX_IS_PATH_SEPARATOR(*c)) { + do { + --c; + if (SYNCTEX_IS_PATH_SEPARATOR(*c)) { + return c + 1; + } + } while (c > name); + } + return c; /* the last path component is the void string*/ + } + return c; +} + +int _synctex_copy_with_quoting_last_path_component(const char *src, char **dest_ref, size_t size) +{ + if (src && dest_ref) { + const char *lpc; +#define dest (*dest_ref) + dest = NULL; /* Default behavior: no change and success. */ + lpc = _synctex_last_path_component(src); + if (strlen(lpc)) { + if (strchr(lpc, ' ') && lpc[0] != '"' && lpc[strlen(lpc) - 1] != '"') { + /* We are in the situation where adding the quotes is allowed. */ + /* Time to add the quotes. */ + /* Consistency test: we must have dest+size>dest+strlen(dest)+2 + * or equivalently: strlen(dest)+2 0) { + char *result = NULL; + ++size; + /* Create the memory storage */ + if (NULL != (result = (char *)malloc(size))) { + char *dest = result; + va_start(arg, first); + temp = first; + do { + if ((size = strlen(temp)) > 0) { + /* There is something to merge */ + if (dest != strncpy(dest, temp, size)) { + _synctex_error("! _synctex_merge_strings: Copy problem"); + free(result); + result = NULL; + return NULL; + } + dest += size; + } + } while ((temp = va_arg(arg, const char *)) != NULL); + va_end(arg); + dest[0] = '\0'; /* Terminate the merged string */ + return result; + } + _synctex_error("! _synctex_merge_strings: Memory problem"); + return NULL; + } + return NULL; +} + +/* The purpose of _synctex_get_name is to find the name of the synctex file. + * There is a list of possible filenames from which we return the most recent one and try to remove all the others. + * With two runs of pdftex or xetex we are sure the synctex file is really the most appropriate. + */ +int _synctex_get_name(const char *output, const char *build_directory, char **synctex_name_ref, synctex_io_mode_t *io_mode_ref) +{ + if (output && synctex_name_ref && io_mode_ref) { + /* If output is already absolute, we just have to manage the quotes and the compress mode */ + size_t size = 0; + char *synctex_name = NULL; + synctex_io_mode_t io_mode = *io_mode_ref; + const char *base_name = _synctex_last_path_component(output); /* do not free, output is the owner. base name of output*/ + /* Do we have a real base name ? */ + if (strlen(base_name) > 0) { + /* Yes, we do. */ + const char *temp = NULL; + char *core_name = NULL; /* base name of output without path extension. */ + char *dir_name = NULL; /* dir name of output */ + char *quoted_core_name = NULL; + char *basic_name = NULL; + char *gz_name = NULL; + char *quoted_name = NULL; + char *quoted_gz_name = NULL; + char *build_name = NULL; + char *build_gz_name = NULL; + char *build_quoted_name = NULL; + char *build_quoted_gz_name = NULL; + struct stat buf; + time_t the_time = 0; + /* Create core_name: let temp point to the dot before the path extension of base_name; + * We start form the \0 terminating character and scan the string upward until we find a dot. + * The leading dot is not accepted. */ + if ((temp = strrchr(base_name, '.')) && (size = temp - base_name) > 0) { + /* There is a dot and it is not at the leading position */ + if (NULL == (core_name = (char *)malloc(size + 1))) { + _synctex_error("! _synctex_get_name: Memory problem 1"); + return -1; + } + if (core_name != strncpy(core_name, base_name, size)) { + _synctex_error("! _synctex_get_name: Copy problem 1"); + free(core_name); + dir_name = NULL; + return -2; + } + core_name[size] = '\0'; + } else { + /* There is no path extension, + * Just make a copy of base_name */ + core_name = _synctex_merge_strings(base_name); + } + /* core_name is properly set up, owned by "self". */ + /* creating dir_name. */ + size = strlen(output) - strlen(base_name); + if (size > 0) { + /* output contains more than one path component */ + if (NULL == (dir_name = (char *)malloc(size + 1))) { + _synctex_error("! _synctex_get_name: Memory problem"); + free(core_name); + return -1; + } + if (dir_name != strncpy(dir_name, output, size)) { + _synctex_error("! _synctex_get_name: Copy problem"); + free(dir_name); + dir_name = NULL; + free(core_name); + dir_name = NULL; + return -2; + } + dir_name[size] = '\0'; + } + /* dir_name is properly set up. It ends with a path separator, if non void. */ + /* creating quoted_core_name. */ + if (strchr(core_name, ' ')) { + quoted_core_name = _synctex_merge_strings("\"", core_name, "\""); + } + /* quoted_core_name is properly set up. */ + if (dir_name && strlen(dir_name) > 0) { + basic_name = _synctex_merge_strings(dir_name, core_name, synctex_suffix, NULL); + if (quoted_core_name && strlen(quoted_core_name) > 0) { + quoted_name = _synctex_merge_strings(dir_name, quoted_core_name, synctex_suffix, NULL); + } + } else { + basic_name = _synctex_merge_strings(core_name, synctex_suffix, NULL); + if (quoted_core_name && strlen(quoted_core_name) > 0) { + quoted_name = _synctex_merge_strings(quoted_core_name, synctex_suffix, NULL); + } + } + if (!_synctex_path_is_absolute(output) && build_directory && (size = strlen(build_directory))) { + temp = build_directory + size - 1; + if (_synctex_path_is_absolute(temp)) { + build_name = _synctex_merge_strings(build_directory, basic_name, NULL); + if (quoted_core_name && strlen(quoted_core_name) > 0) { + build_quoted_name = _synctex_merge_strings(build_directory, quoted_name, NULL); + } + } else { + build_name = _synctex_merge_strings(build_directory, "/", basic_name, NULL); + if (quoted_core_name && strlen(quoted_core_name) > 0) { + build_quoted_name = _synctex_merge_strings(build_directory, "/", quoted_name, NULL); + } + } + } + if (basic_name) { + gz_name = _synctex_merge_strings(basic_name, synctex_suffix_gz, NULL); + } + if (quoted_name) { + quoted_gz_name = _synctex_merge_strings(quoted_name, synctex_suffix_gz, NULL); + } + if (build_name) { + build_gz_name = _synctex_merge_strings(build_name, synctex_suffix_gz, NULL); + } + if (build_quoted_name) { + build_quoted_gz_name = _synctex_merge_strings(build_quoted_name, synctex_suffix_gz, NULL); + } + /* All the others names are properly set up... */ + /* retain the most recently modified file */ +#define TEST(FILENAME, COMPRESS_MODE) \ + if (FILENAME) { \ + if (stat(FILENAME, &buf)) { \ + free(FILENAME); \ + FILENAME = NULL; \ + } else if (buf.st_mtime > the_time) { \ + the_time = buf.st_mtime; \ + synctex_name = FILENAME; \ + if (COMPRESS_MODE) { \ + io_mode |= synctex_io_gz_mask; \ + } else { \ + io_mode &= ~synctex_io_gz_mask; \ + } \ + } \ + } + TEST(basic_name, synctex_DONT_COMPRESS); + TEST(gz_name, synctex_COMPRESS); + TEST(quoted_name, synctex_DONT_COMPRESS); + TEST(quoted_gz_name, synctex_COMPRESS); + TEST(build_name, synctex_DONT_COMPRESS); + TEST(build_gz_name, synctex_COMPRESS); + TEST(build_quoted_name, synctex_DONT_COMPRESS); + TEST(build_quoted_gz_name, synctex_COMPRESS); +#undef TEST + /* Free all the intermediate filenames, except the one that will be used as returned value. */ +#define CLEAN_AND_REMOVE(FILENAME) \ + if (FILENAME && (FILENAME != synctex_name)) { \ + remove(FILENAME); \ + printf("synctex tool info: %s removed\n", FILENAME); \ + free(FILENAME); \ + FILENAME = NULL; \ + } + CLEAN_AND_REMOVE(basic_name); + CLEAN_AND_REMOVE(gz_name); + CLEAN_AND_REMOVE(quoted_name); + CLEAN_AND_REMOVE(quoted_gz_name); + CLEAN_AND_REMOVE(build_name); + CLEAN_AND_REMOVE(build_gz_name); + CLEAN_AND_REMOVE(build_quoted_name); + CLEAN_AND_REMOVE(build_quoted_gz_name); +#undef CLEAN_AND_REMOVE + /* set up the returned values */ + *synctex_name_ref = synctex_name; + /* synctex_name won't always end in .gz, even when compressed. */ + FILE *F = fopen(synctex_name, "r"); + if (F != NULL) { + if (!feof(F) && 31 == fgetc(F) && !feof(F) && 139 == fgetc(F)) { + io_mode = synctex_compress_mode_gz; + } + fclose(F); + } + *io_mode_ref = io_mode; + return 0; + } + return -1; /* bad argument */ + } + return -2; +} + +const char *_synctex_get_io_mode_name(synctex_io_mode_t io_mode) +{ + static const char *synctex_io_modes[4] = {"r", "rb", "a", "ab"}; + unsigned index = ((io_mode & synctex_io_gz_mask) ? 1 : 0) + ((io_mode & synctex_io_append_mask) ? 2 : 0); /* bug pointed out by Jose Alliste */ + return synctex_io_modes[index]; +} diff --git a/core/synctex/synctex_parser_utils.h b/core/synctex/synctex_parser_utils.h new file mode 100644 index 0000000..8b2a0cf --- /dev/null +++ b/core/synctex/synctex_parser_utils.h @@ -0,0 +1,161 @@ +/* + Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr + + This file is part of the __SyncTeX__ package. + + [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) + [//]: # (Version: 1.19) + + See `synctex_parser_readme.md` for more details + + ## License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE + +Except as contained in this notice, the name of the copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from the copyright holder. + +*/ + +#ifndef SYNCTEX_PARSER_UTILS_H +#define SYNCTEX_PARSER_UTILS_H + +/* The utilities declared here are subject to conditional implementation. + * All the operating system special stuff goes here. + * The problem mainly comes from file name management: path separator, encoding... + */ + +typedef int synctex_bool_t; +#define synctex_YES (0 == 0) +#define synctex_NO (0 == 1) + +#define synctex_ADD_QUOTES -1 +#define synctex_COMPRESS -1 +#define synctex_DONT_ADD_QUOTES 0 +#define synctex_DONT_COMPRESS 0 + +#ifndef __SYNCTEX_PARSER_UTILS__ +#define __SYNCTEX_PARSER_UTILS__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) || defined(__OS2__) +#define SYNCTEX_CASE_SENSITIVE_PATH 0 +#define SYNCTEX_IS_PATH_SEPARATOR(c) ('/' == c || '\\' == c) +#else +#define SYNCTEX_CASE_SENSITIVE_PATH 1 +#define SYNCTEX_IS_PATH_SEPARATOR(c) ('/' == c) +#endif + +#if defined(_WIN32) || defined(__OS2__) +#define SYNCTEX_IS_DOT(c) ('.' == c) +#else +#define SYNCTEX_IS_DOT(c) ('.' == c) +#endif + +#if SYNCTEX_CASE_SENSITIVE_PATH +#define SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(left, right) (left != right) +#else +#define SYNCTEX_ARE_PATH_CHARACTERS_EQUAL(left, right) (toupper(left) != toupper(right)) +#endif + +#ifdef __GNUC__ +#define SYNCTEX_PRINTF_FORMAT(si, ftc) __attribute__((format(printf, si, ftc))) +#else +#define SYNCTEX_PRINTF_FORMAT(si, ftc) +#endif + +/* This custom malloc functions initializes to 0 the newly allocated memory. + * There is no bzero function on windows. */ +void *_synctex_malloc(size_t size); + +/* To balance _synctex_malloc. + * ptr might be NULL. */ +void _synctex_free(void *ptr); + +/* This is used to log some informational message to the standard error stream. + * On Windows, the stderr stream is not exposed and another method is used. + * The return value is the number of characters printed. */ +int _synctex_error(const char *reason, ...) SYNCTEX_PRINTF_FORMAT(1, 2); +int _synctex_debug(const char *reason, ...) SYNCTEX_PRINTF_FORMAT(1, 2); + +/* strip the last extension of the given string, this string is modified! + * This function depends on the OS because the path separator may differ. + * This should be discussed more precisely. */ +void _synctex_strip_last_path_extension(char *string); + +/* Compare two file names, windows is sometimes case insensitive... + * The given strings may differ stricto sensu, but represent the same file name. + * It might not be the real way of doing things. + * The return value is an undefined non 0 value when the two file names are equivalent. + * It is 0 otherwise. */ +synctex_bool_t _synctex_is_equivalent_file_name(const char *lhs, const char *rhs); + +/* Description forthcoming.*/ +synctex_bool_t _synctex_path_is_absolute(const char *name); + +/* Description forthcoming...*/ +const char *_synctex_last_path_component(const char *name); + +/* Description forthcoming...*/ +const char *_synctex_base_name(const char *path); + +/* If the core of the last path component of src is not already enclosed with double quotes ('"') + * and contains a space character (' '), then a new buffer is created, the src is copied and quotes are added. + * In all other cases, no destination buffer is created and the src is not copied. + * 0 on success, which means no error, something non 0 means error, mainly due to memory allocation failure, or bad parameter. + * This is used to fix a bug in the first version of pdftex with synctex (1.40.9) for which names with spaces + * were not managed in a standard way. + * On success, the caller owns the buffer pointed to by dest_ref (is any) and + * is responsible of freeing the memory when done. + * The size argument is the size of the src buffer. On return the dest_ref points to a buffer sized size+2.*/ +int _synctex_copy_with_quoting_last_path_component(const char *src, char **dest_ref, size_t size); + +/* These are the possible extensions of the synctex file */ +extern const char *synctex_suffix; +extern const char *synctex_suffix_gz; + +typedef unsigned int synctex_io_mode_t; + +typedef enum { synctex_io_append_mask = 1, synctex_io_gz_mask = synctex_io_append_mask << 1 } synctex_io_mode_masks_t; + +typedef enum { synctex_compress_mode_none = 0, synctex_compress_mode_gz = 1 } synctex_compress_mode_t; + +int _synctex_get_name(const char *output, const char *build_directory, char **synctex_name_ref, synctex_io_mode_t *io_mode_ref); + +/* returns the correct mode required by fopen and gzopen from the given io_mode */ +const char *_synctex_get_io_mode_name(synctex_io_mode_t io_mode); + +synctex_bool_t synctex_ignore_leading_dot_slash_in_path(const char **name); + +#ifdef __cplusplus +} +#endif + +#endif +#endif /* SYNCTEX_PARSER_UTILS_H */ diff --git a/core/synctex/synctex_parser_version.txt b/core/synctex/synctex_parser_version.txt new file mode 100644 index 0000000..bc44934 --- /dev/null +++ b/core/synctex/synctex_parser_version.txt @@ -0,0 +1 @@ +1.19 diff --git a/core/textdocumentgenerator.cpp b/core/textdocumentgenerator.cpp new file mode 100644 index 0000000..5505f4f --- /dev/null +++ b/core/textdocumentgenerator.cpp @@ -0,0 +1,566 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "textdocumentgenerator.h" +#include "textdocumentgenerator_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "action.h" +#include "annotations.h" +#include "document_p.h" +#include "page.h" +#include "textpage.h" + +#include + +using namespace Okular; + +/** + * Generic Converter Implementation + */ +TextDocumentConverter::TextDocumentConverter() + : QObject(nullptr) + , d_ptr(new TextDocumentConverterPrivate) +{ +} + +TextDocumentConverter::~TextDocumentConverter() +{ + delete d_ptr; +} + +QTextDocument *TextDocumentConverter::convert(const QString &) +{ + return nullptr; +} + +Document::OpenResult TextDocumentConverter::convertWithPassword(const QString &fileName, const QString &) +{ + QTextDocument *doc = convert(fileName); + setDocument(doc); + return doc != nullptr ? Document::OpenSuccess : Document::OpenError; +} + +QTextDocument *TextDocumentConverter::document() +{ + return d_ptr->mDocument; +} + +void TextDocumentConverter::setDocument(QTextDocument *document) +{ + d_ptr->mDocument = document; +} + +DocumentViewport TextDocumentConverter::calculateViewport(QTextDocument *document, const QTextBlock &block) +{ + return TextDocumentUtils::calculateViewport(document, block); +} + +TextDocumentGenerator *TextDocumentConverter::generator() const +{ + return d_ptr->mParent ? d_ptr->mParent->q_func() : nullptr; +} + +/** + * Generic Generator Implementation + */ +Okular::TextPage *TextDocumentGeneratorPrivate::createTextPage(int pageNumber) const +{ +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + Q_Q(const TextDocumentGenerator); +#endif + + Okular::TextPage *textPage = new Okular::TextPage; + + int start, end; + +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + q->userMutex()->lock(); +#endif + TextDocumentUtils::calculatePositions(mDocument, pageNumber, start, end); + + { + QTextCursor cursor(mDocument); + for (int i = start; i < end - 1; ++i) { + cursor.setPosition(i); + cursor.setPosition(i + 1, QTextCursor::KeepAnchor); + + QString text = cursor.selectedText(); + if (text.length() == 1) { + QRectF rect; + TextDocumentUtils::calculateBoundingRect(mDocument, i, i + 1, rect, pageNumber); + if (pageNumber == -1) + text = QStringLiteral("\n"); + + textPage->append(text, new Okular::NormalizedRect(rect.left(), rect.top(), rect.right(), rect.bottom())); + } + } + } +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + q->userMutex()->unlock(); +#endif + + return textPage; +} + +void TextDocumentGeneratorPrivate::addAction(Action *action, int cursorBegin, int cursorEnd) +{ + if (!action) + return; + + LinkPosition position; + position.link = action; + position.startPosition = cursorBegin; + position.endPosition = cursorEnd; + + mLinkPositions.append(position); +} + +void TextDocumentGeneratorPrivate::addAnnotation(Annotation *annotation, int cursorBegin, int cursorEnd) +{ + if (!annotation) + return; + + annotation->setFlags(annotation->flags() | Okular::Annotation::External); + + AnnotationPosition position; + position.annotation = annotation; + position.startPosition = cursorBegin; + position.endPosition = cursorEnd; + + mAnnotationPositions.append(position); +} + +void TextDocumentGeneratorPrivate::addTitle(int level, const QString &title, const QTextBlock &block) +{ + TitlePosition position; + position.level = level; + position.title = title; + position.block = block; + + mTitlePositions.append(position); +} + +void TextDocumentGeneratorPrivate::addMetaData(const QString &key, const QString &value, const QString &title) +{ + mDocumentInfo.set(key, value, title); +} + +void TextDocumentGeneratorPrivate::addMetaData(DocumentInfo::Key key, const QString &value) +{ + mDocumentInfo.set(key, value); +} + +QList TextDocumentGeneratorPrivate::generateLinkInfos() const +{ + QList result; + + for (int i = 0; i < mLinkPositions.count(); ++i) { + const LinkPosition &linkPosition = mLinkPositions[i]; + + const QVector rects = TextDocumentUtils::calculateBoundingRects(mDocument, linkPosition.startPosition, linkPosition.endPosition); + + for (int i = 0; i < rects.count(); ++i) { + const QRectF &rect = rects[i]; + + LinkInfo info; + info.link = linkPosition.link; + info.ownsLink = i == 0; + info.page = std::floor(rect.y()); + info.boundingRect = QRectF(rect.x(), rect.y() - info.page, rect.width(), rect.height()); + result.append(info); + } + } + + return result; +} + +QList TextDocumentGeneratorPrivate::generateAnnotationInfos() const +{ + QList result; + + for (int i = 0; i < mAnnotationPositions.count(); ++i) { + const AnnotationPosition &annotationPosition = mAnnotationPositions[i]; + + AnnotationInfo info; + info.annotation = annotationPosition.annotation; + + TextDocumentUtils::calculateBoundingRect(mDocument, annotationPosition.startPosition, annotationPosition.endPosition, info.boundingRect, info.page); + + if (info.page >= 0) + result.append(info); + } + + return result; +} + +void TextDocumentGeneratorPrivate::generateTitleInfos() +{ + QStack> parentNodeStack; + + QDomNode parentNode = mDocumentSynopsis; + + parentNodeStack.push(qMakePair(0, parentNode)); + + for (int i = 0; i < mTitlePositions.count(); ++i) { + const TitlePosition &position = mTitlePositions[i]; + + Okular::DocumentViewport viewport = TextDocumentUtils::calculateViewport(mDocument, position.block); + + QDomElement item = mDocumentSynopsis.createElement(position.title); + item.setAttribute(QStringLiteral("Viewport"), viewport.toString()); + + int headingLevel = position.level; + + // we need a parent, which has to be at a higher heading level than this heading level + // so we just work through the stack + while (!parentNodeStack.isEmpty()) { + int parentLevel = parentNodeStack.top().first; + if (parentLevel < headingLevel) { + // this is OK as a parent + parentNode = parentNodeStack.top().second; + break; + } else { + // we'll need to be further into the stack + parentNodeStack.pop(); + } + } + parentNode.appendChild(item); + parentNodeStack.push(qMakePair(headingLevel, QDomNode(item))); + } +} + +void TextDocumentGeneratorPrivate::initializeGenerator() +{ + Q_Q(TextDocumentGenerator); + + mConverter->d_ptr->mParent = q->d_func(); + + if (mGeneralSettings) { + mFont = mGeneralSettings->font(); + } + + q->setFeature(Generator::TextExtraction); + q->setFeature(Generator::PrintNative); + q->setFeature(Generator::PrintToFile); +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + q->setFeature(Generator::Threaded); +#endif + + QObject::connect(mConverter, &TextDocumentConverter::addAction, q, [this](Action *a, int cb, int ce) { addAction(a, cb, ce); }); + QObject::connect(mConverter, &TextDocumentConverter::addAnnotation, q, [this](Annotation *a, int cb, int ce) { addAnnotation(a, cb, ce); }); + QObject::connect(mConverter, &TextDocumentConverter::addTitle, q, [this](int l, const QString &t, const QTextBlock &b) { addTitle(l, t, b); }); + QObject::connect(mConverter, QOverload::of(&TextDocumentConverter::addMetaData), q, [this](const QString &k, const QString &v, const QString &t) { addMetaData(k, v, t); }); + QObject::connect(mConverter, QOverload::of(&TextDocumentConverter::addMetaData), q, [this](DocumentInfo::Key k, const QString &v) { addMetaData(k, v); }); + + QObject::connect(mConverter, &TextDocumentConverter::error, q, &Generator::error); + QObject::connect(mConverter, &TextDocumentConverter::warning, q, &Generator::warning); + QObject::connect(mConverter, &TextDocumentConverter::notice, q, &Generator::notice); +} + +TextDocumentGenerator::TextDocumentGenerator(TextDocumentConverter *converter, const QString &configName, QObject *parent, const QVariantList &args) + : Okular::Generator(*new TextDocumentGeneratorPrivate(converter), parent, args) +{ + Q_D(TextDocumentGenerator); + d->mGeneralSettings = new TextDocumentSettings(configName, this); + + d->initializeGenerator(); +} + +TextDocumentGenerator::~TextDocumentGenerator() +{ +} + +Document::OpenResult TextDocumentGenerator::loadDocumentWithPassword(const QString &fileName, QVector &pagesVector, const QString &password) +{ + Q_D(TextDocumentGenerator); + const Document::OpenResult openResult = d->mConverter->convertWithPassword(fileName, password); + + if (openResult != Document::OpenSuccess) { + d->mDocument = nullptr; + + // loading failed, cleanup all the stuff eventually gathered from the converter + d->mTitlePositions.clear(); + for (const TextDocumentGeneratorPrivate::LinkPosition &linkPos : qAsConst(d->mLinkPositions)) { + delete linkPos.link; + } + d->mLinkPositions.clear(); + for (const TextDocumentGeneratorPrivate::AnnotationPosition &annPos : qAsConst(d->mAnnotationPositions)) { + delete annPos.annotation; + } + d->mAnnotationPositions.clear(); + + return openResult; + } + d->mDocument = d->mConverter->document(); + + d->generateTitleInfos(); + const QList linkInfos = d->generateLinkInfos(); + const QList annotationInfos = d->generateAnnotationInfos(); + + pagesVector.resize(d->mDocument->pageCount()); + + const QSize size = d->mDocument->pageSize().toSize(); + + QVector> objects(d->mDocument->pageCount()); + for (const TextDocumentGeneratorPrivate::LinkInfo &info : linkInfos) { + // in case that the converter report bogus link info data, do not assert here + if (info.page < 0 || info.page >= objects.count()) + continue; + + const QRectF rect = info.boundingRect; + if (info.ownsLink) { + objects[info.page].append(new Okular::ObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link)); + } else { + objects[info.page].append(new Okular::NonOwningObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, info.link)); + } + } + + QVector> annots(d->mDocument->pageCount()); + for (const TextDocumentGeneratorPrivate::AnnotationInfo &info : annotationInfos) { + annots[info.page].append(info.annotation); + } + + for (int i = 0; i < d->mDocument->pageCount(); ++i) { + Okular::Page *page = new Okular::Page(i, size.width(), size.height(), Okular::Rotation0); + pagesVector[i] = page; + + if (!objects.at(i).isEmpty()) { + page->setObjectRects(objects.at(i)); + } + QLinkedList::ConstIterator annIt = annots.at(i).begin(), annEnd = annots.at(i).end(); + for (; annIt != annEnd; ++annIt) { + page->addAnnotation(*annIt); + } + } + + return openResult; +} + +bool TextDocumentGenerator::doCloseDocument() +{ + Q_D(TextDocumentGenerator); + delete d->mDocument; + d->mDocument = nullptr; + + d->mTitlePositions.clear(); + d->mLinkPositions.clear(); + d->mAnnotationPositions.clear(); + // do not use clear() for the following two, otherwise they change type + d->mDocumentInfo = Okular::DocumentInfo(); + d->mDocumentSynopsis = Okular::DocumentSynopsis(); + + return true; +} + +bool TextDocumentGenerator::canGeneratePixmap() const +{ + return Generator::canGeneratePixmap(); +} + +void TextDocumentGenerator::generatePixmap(Okular::PixmapRequest *request) +{ + Generator::generatePixmap(request); +} + +QImage TextDocumentGeneratorPrivate::image(PixmapRequest *request) +{ + if (!mDocument) + return QImage(); + +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + Q_Q(TextDocumentGenerator); +#endif + + QImage image(request->width(), request->height(), QImage::Format_ARGB32); + image.fill(Qt::white); + + QPainter p; + p.begin(&image); + + qreal width = request->width(); + qreal height = request->height(); + + const QSize size = mDocument->pageSize().toSize(); + + p.scale(width / (qreal)size.width(), height / (qreal)size.height()); + + QRect rect; + rect = QRect(0, request->pageNumber() * size.height(), size.width(), size.height()); + p.translate(QPoint(0, request->pageNumber() * size.height() * -1)); + p.setClipRect(rect); +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + q->userMutex()->lock(); +#endif + QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor(QPalette::Text, Qt::black); + // FIXME Fix Qt, this doesn't work, we have horrible hacks + // in the generators that return html, remove that code + // if Qt ever gets fixed + // context.palette.setColor( QPalette::Link, Qt::blue ); + context.clip = rect; + mDocument->setDefaultFont(mFont); + mDocument->documentLayout()->draw(&p, context); +#ifdef OKULAR_TEXTDOCUMENT_THREADED_RENDERING + q->userMutex()->unlock(); +#endif + p.end(); + + return image; +} + +Okular::TextPage *TextDocumentGenerator::textPage(Okular::TextRequest *request) +{ + Q_D(TextDocumentGenerator); + return d->createTextPage(request->page()->number()); +} + +bool TextDocumentGenerator::print(QPrinter &printer) +{ + Q_D(TextDocumentGenerator); + if (!d->mDocument) + return false; + + d->mDocument->print(&printer); + + return true; +} + +Okular::DocumentInfo TextDocumentGenerator::generateDocumentInfo(const QSet & /*keys*/) const +{ + Q_D(const TextDocumentGenerator); + return d->mDocumentInfo; +} + +const Okular::DocumentSynopsis *TextDocumentGenerator::generateDocumentSynopsis() +{ + Q_D(TextDocumentGenerator); + if (!d->mDocumentSynopsis.hasChildNodes()) + return nullptr; + else + return &d->mDocumentSynopsis; +} + +QVariant TextDocumentGeneratorPrivate::metaData(const QString &key, const QVariant &option) const +{ + Q_UNUSED(option) + if (key == QLatin1String("DocumentTitle")) { + return mDocumentInfo.get(DocumentInfo::Title); + } + return QVariant(); +} + +Okular::ExportFormat::List TextDocumentGenerator::exportFormats() const +{ + static Okular::ExportFormat::List formats; + if (formats.isEmpty()) { + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText)); + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PDF)); + if (QTextDocumentWriter::supportedDocumentFormats().contains("ODF")) { + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::OpenDocumentText)); + } + if (QTextDocumentWriter::supportedDocumentFormats().contains("HTML")) { + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::HTML)); + } + } + + return formats; +} + +bool TextDocumentGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format) +{ + Q_D(TextDocumentGenerator); + if (!d->mDocument) + return false; + + if (format.mimeType().name() == QLatin1String("application/pdf")) { + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + return false; + + QPrinter printer(QPrinter::HighResolution); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOutputFileName(fileName); + d->mDocument->print(&printer); + + return true; + } else if (format.mimeType().name() == QLatin1String("text/plain")) { + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + return false; + + QTextStream out(&file); + out << d->mDocument->toPlainText(); + + return true; + } else if (format.mimeType().name() == QLatin1String("application/vnd.oasis.opendocument.text")) { + QTextDocumentWriter odfWriter(fileName, "odf"); + + return odfWriter.write(d->mDocument); + } else if (format.mimeType().name() == QLatin1String("text/html")) { + QTextDocumentWriter odfWriter(fileName, "html"); + + return odfWriter.write(d->mDocument); + } + return false; +} + +bool TextDocumentGenerator::reparseConfig() +{ + Q_D(TextDocumentGenerator); + const QFont newFont = d->mGeneralSettings->font(); + + if (newFont != d->mFont) { + d->mFont = newFont; + return true; + } + + return false; +} + +void TextDocumentGenerator::addPages(KConfigDialog * /*dlg*/) +{ + qCWarning(OkularCoreDebug) << "You forgot to reimplement addPages in your TextDocumentGenerator"; + return; +} + +TextDocumentSettings *TextDocumentGenerator::generalSettings() +{ + Q_D(TextDocumentGenerator); + + return d->mGeneralSettings; +} + +TextDocumentConverter *TextDocumentGenerator::converter() +{ + Q_D(TextDocumentGenerator); + + return d->mConverter; +} + +void TextDocumentGenerator::setTextDocument(QTextDocument *textDocument) +{ + Q_D(TextDocumentGenerator); + + d->mDocument = textDocument; + + for (Page *p : qAsConst(d->m_document->m_pagesVector)) { + p->setTextPage(nullptr); + } +} diff --git a/core/textdocumentgenerator.h b/core/textdocumentgenerator.h new file mode 100644 index 0000000..8cc1a02 --- /dev/null +++ b/core/textdocumentgenerator.h @@ -0,0 +1,230 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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_TEXTDOCUMENTGENERATOR_H_ +#define _OKULAR_TEXTDOCUMENTGENERATOR_H_ + +#include "okularcore_export.h" + +#include "../interfaces/configinterface.h" +#include "document.h" +#include "generator.h" +#include "textdocumentsettings.h" + +class QTextBlock; +class QTextDocument; + +namespace Okular +{ +class TextDocumentConverterPrivate; +class TextDocumentGenerator; +class TextDocumentGeneratorPrivate; + +class OKULARCORE_EXPORT TextDocumentConverter : public QObject +{ + Q_OBJECT + + friend class TextDocumentGenerator; + friend class TextDocumentGeneratorPrivate; + +public: + /** + * Creates a new generic converter. + */ + TextDocumentConverter(); + + /** + * Destroys the generic converter. + */ + ~TextDocumentConverter() override; + + /** + * Returns the generated QTextDocument object. The caller takes ownership of the QTextDocument + * + * @note there is no need to implement this one if you implement convertWithPassword + */ + virtual QTextDocument *convert(const QString &fileName); + + /** + * Returns the generated QTextDocument object. + */ + virtual Document::OpenResult convertWithPassword(const QString &fileName, const QString &password); + + /** + * Returns the generated QTextDocument object. Will be null if convert didn't succeed + */ + QTextDocument *document(); + +Q_SIGNALS: + /** + * Adds a new link object which is located between cursorBegin and + * cursorEnd to the generator. + */ + void addAction(Okular::Action *link, int cursorBegin, int cursorEnd); + + /** + * Adds a new annotation object which is located between cursorBegin and + * cursorEnd to the generator. + */ + void addAnnotation(Okular::Annotation *annotation, int cursorBegin, int cursorEnd); + + /** + * Adds a new title at the given level which is located as position to the generator. + */ + void addTitle(int level, const QString &title, const QTextBlock &position); + + /** + * Adds a set of meta data to the generator. + */ + void addMetaData(const QString &key, const QString &value, const QString &title); // clazy:exclude=overloaded-signal + + // TODO When we can do a BIC change rename one of the two addMetaData functions (or see if we can kill one) + /** + * Adds a set of meta data to the generator. + * + * @since 0.7 (KDE 4.1) + */ + void addMetaData(DocumentInfo::Key key, const QString &value); // clazy:exclude=overloaded-signal + + /** + * This signal should be emitted whenever an error occurred in the converter. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void error(const QString &message, int duration); + + /** + * This signal should be emitted whenever the user should be warned. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void warning(const QString &message, int duration); + + /** + * This signal should be emitted whenever the user should be noticed. + * + * @param message The message which should be shown to the user. + * @param duration The time that the message should be shown to the user. + */ + void notice(const QString &message, int duration); + +protected: + /** + * Sets the converted QTextDocument object. + */ + void setDocument(QTextDocument *document); + + /** + * This method can be used to calculate the viewport for a given text block. + * + * @note This method should be called at the end of the conversion, because it + * triggers QTextDocument to do the layout calculation. + */ + DocumentViewport calculateViewport(QTextDocument *document, const QTextBlock &block); + + /** + * Returns the generator that owns this converter. + * + * @note May be null if the converter was not created for a generator. + * + * @since 0.7 (KDE 4.1) + */ + TextDocumentGenerator *generator() const; + +private: + TextDocumentConverterPrivate *d_ptr; + Q_DECLARE_PRIVATE(TextDocumentConverter) + Q_DISABLE_COPY(TextDocumentConverter) +}; + +/** + * @brief QTextDocument-based Generator + * + * This generator provides a document in the form of a QTextDocument object, + * parsed using a specialized TextDocumentConverter. + */ +class OKULARCORE_EXPORT TextDocumentGenerator : public Generator, public Okular::ConfigInterface +{ + /// @cond PRIVATE + friend class TextDocumentConverter; + /// @endcond + + Q_OBJECT + Q_INTERFACES(Okular::ConfigInterface) + +public: + /** + * Creates a new generator that uses the specified @p converter. + * + * @param converter The text document converter. + * @param configName - see Okular::TextDocumentSettings + * @param parent The parent object. + * @param args The arguments. + * + * @note the generator will take ownership of the converter, so you + * don't have to delete it yourself + * @since 0.17 (KDE 4.11) + */ + TextDocumentGenerator(TextDocumentConverter *converter, const QString &configName, QObject *parent, const QVariantList &args); + + ~TextDocumentGenerator() override; + + // [INHERITED] load a document and fill up the pagesVector + Document::OpenResult loadDocumentWithPassword(const QString &fileName, QVector &pagesVector, const QString &password) override; + + // [INHERITED] perform actions on document / pages + bool canGeneratePixmap() const override; + void generatePixmap(Okular::PixmapRequest *request) override; + + // [INHERITED] print document using already configured QPrinter + bool print(QPrinter &printer) override; + + // [INHERITED] text exporting + Okular::ExportFormat::List exportFormats() const override; + bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override; + + // [INHERITED] config interface + /// By default checks if the default font has changed or not + bool reparseConfig() override; + /// Does nothing by default. You need to reimplement it in your generator + void addPages(KConfigDialog *dlg) override; + + /** + * Config skeleton for TextDocumentSettingsWidget + * + * You must use new construtor to initialize TextDocumentSettings, + * that contain @p configName . + * + * @since 0.17 (KDE 4.11) + */ + TextDocumentSettings *generalSettings(); + + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + +protected: + bool doCloseDocument() override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + + /* @since 1.8 */ + TextDocumentConverter *converter(); + + /* @since 1.8 */ + void setTextDocument(QTextDocument *textDocument); + +private: + Q_DECLARE_PRIVATE(TextDocumentGenerator) + Q_DISABLE_COPY(TextDocumentGenerator) +}; + +} + +#endif diff --git a/core/textdocumentgenerator_p.h b/core/textdocumentgenerator_p.h new file mode 100644 index 0000000..87079dc --- /dev/null +++ b/core/textdocumentgenerator_p.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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_TEXTDOCUMENTGENERATOR_P_H_ +#define _OKULAR_TEXTDOCUMENTGENERATOR_P_H_ + +#include +#include +#include + +#include "action.h" +#include "debug_p.h" +#include "document.h" +#include "generator_p.h" +#include "textdocumentgenerator.h" + +namespace Okular +{ +namespace TextDocumentUtils +{ +static void calculateBoundingRect(QTextDocument *document, int startPosition, int endPosition, QRectF &rect, int &page) +{ + const QSizeF pageSize = document->pageSize(); + + const QTextBlock startBlock = document->findBlock(startPosition); + const QRectF startBoundingRect = document->documentLayout()->blockBoundingRect(startBlock); + + const QTextBlock endBlock = document->findBlock(endPosition); + const QRectF endBoundingRect = document->documentLayout()->blockBoundingRect(endBlock); + + const QTextLayout *startLayout = startBlock.layout(); + const QTextLayout *endLayout = endBlock.layout(); + if (!startLayout || !endLayout) { + qCWarning(OkularCoreDebug) << "Start or end layout not found" << startLayout << endLayout; + page = -1; + return; + } + + const int startPos = startPosition - startBlock.position(); + const int endPos = endPosition - endBlock.position(); + const QTextLine startLine = startLayout->lineForTextPosition(startPos); + const QTextLine endLine = endLayout->lineForTextPosition(endPos); + + const double x = startBoundingRect.x() + startLine.cursorToX(startPos); + const double y = startBoundingRect.y() + startLine.y(); + const double r = endBoundingRect.x() + endLine.cursorToX(endPos); + const double b = endBoundingRect.y() + endLine.y() + endLine.height(); + + const int offset = qRound(y) % qRound(pageSize.height()); + + if (x > r) { // line break, so return a pseudo character on the start line + rect = QRectF(x / pageSize.width(), offset / pageSize.height(), 3 / pageSize.width(), startLine.height() / pageSize.height()); + page = -1; + return; + } + + page = qRound(y) / qRound(pageSize.height()); + rect = QRectF(x / pageSize.width(), offset / pageSize.height(), (r - x) / pageSize.width(), (b - y) / pageSize.height()); +} + +static QVector calculateBoundingRects(QTextDocument *document, int startPosition, int endPosition) +{ + QVector result; + + const QSizeF pageSize = document->pageSize(); + + const QTextBlock startBlock = document->findBlock(startPosition); + const QRectF startBoundingRect = document->documentLayout()->blockBoundingRect(startBlock); + + const QTextBlock endBlock = document->findBlock(endPosition); + const QRectF endBoundingRect = document->documentLayout()->blockBoundingRect(endBlock); + + const QTextLayout *startLayout = startBlock.layout(); + const QTextLayout *endLayout = endBlock.layout(); + if (!startLayout || !endLayout) { + qCWarning(OkularCoreDebug) << "Start or end layout not found" << startLayout << endLayout; + return {}; + } + + const int startPos = startPosition - startBlock.position(); + const int endPos = endPosition - endBlock.position(); + const QTextLine startLine = startLayout->lineForTextPosition(startPos); + const QTextLine endLine = endLayout->lineForTextPosition(endPos); + + // This only works if both start and end layout are the same + if (startLayout == endLayout) { + Q_ASSERT(startBoundingRect == endBoundingRect); + for (int i = startLine.lineNumber(); i < endLine.lineNumber(); ++i) { + const QTextLine line = startLayout->lineAt(i); + // using startPos and endPos is fine, if the pos is out of bounds for that line, it'll return beginning and end of line respectively + const double x = endBoundingRect.x() + line.cursorToX(startPos); + const double y = endBoundingRect.y() + line.y(); + const double r = endBoundingRect.x() + line.cursorToX(endPos); + const double b = endBoundingRect.y() + line.y() + endLine.height(); + + result.append(QRectF(x / pageSize.width(), y / pageSize.height(), (r - x) / pageSize.width(), (b - y) / pageSize.height())); + } + + // The last line + const double x = endBoundingRect.x() + endLine.cursorToX(startPos); + const double y = endBoundingRect.y() + endLine.y(); + const double r = endBoundingRect.x() + endLine.cursorToX(endPos); + const double b = endBoundingRect.y() + endLine.y() + endLine.height(); + + result.append(QRectF(x / pageSize.width(), y / pageSize.height(), (r - x) / pageSize.width(), (b - y) / pageSize.height())); + } else { + const double x = startBoundingRect.x() + startLine.cursorToX(startPos); + const double y = startBoundingRect.y() + startLine.y(); + const double r = endBoundingRect.x() + endLine.cursorToX(endPos); + const double b = endBoundingRect.y() + endLine.y() + endLine.height(); + + result.append(QRectF(x / pageSize.width(), y / pageSize.height(), (r - x) / pageSize.width(), (b - y) / pageSize.height())); + } + + return result; +} + +static void calculatePositions(QTextDocument *document, int page, int &start, int &end) +{ + const QAbstractTextDocumentLayout *layout = document->documentLayout(); + const QSizeF pageSize = document->pageSize(); + const double margin = document->rootFrame()->frameFormat().margin(); + + /** + * Take the upper left and lower left corner including the margin + */ + start = layout->hitTest(QPointF(margin, (page * pageSize.height()) + margin), Qt::FuzzyHit); + end = layout->hitTest(QPointF(margin, ((page + 1) * pageSize.height()) - margin), Qt::FuzzyHit); +} + +static Okular::DocumentViewport calculateViewport(QTextDocument *document, const QTextBlock &block) +{ + const QSizeF pageSize = document->pageSize(); + const QRectF rect = document->documentLayout()->blockBoundingRect(block); + + const int page = qRound(rect.y()) / qRound(pageSize.height()); + const int offset = qRound(rect.y()) % qRound(pageSize.height()); + + Okular::DocumentViewport viewport(page); + viewport.rePos.normalizedX = (double)rect.x() / (double)pageSize.width(); + viewport.rePos.normalizedY = (double)offset / (double)pageSize.height(); + viewport.rePos.enabled = true; + viewport.rePos.pos = Okular::DocumentViewport::Center; + + return viewport; +} +} + +class TextDocumentConverterPrivate +{ +public: + TextDocumentConverterPrivate() + : mParent(nullptr) + { + } + + TextDocumentGeneratorPrivate *mParent; + QTextDocument *mDocument; +}; + +class TextDocumentGeneratorPrivate : public GeneratorPrivate +{ + friend class TextDocumentConverter; + +public: + explicit TextDocumentGeneratorPrivate(TextDocumentConverter *converter) + : mConverter(converter) + , mDocument(nullptr) + , mGeneralSettings(nullptr) + { + } + + ~TextDocumentGeneratorPrivate() override + { + delete mConverter; + delete mDocument; + } + + void initializeGenerator(); + + struct LinkInfo { + int page; + QRectF boundingRect; + Action *link; + bool ownsLink; + }; + + struct AnnotationInfo { + int page; + QRectF boundingRect; + Annotation *annotation; + }; + + Q_DECLARE_PUBLIC(TextDocumentGenerator) + + /* reimp */ QVariant metaData(const QString &key, const QVariant &option) const override; + /* reimp */ QImage image(PixmapRequest *) override; + + void calculateBoundingRect(int startPosition, int endPosition, QRectF &rect, int &page) const; + void calculatePositions(int page, int &start, int &end) const; + Okular::TextPage *createTextPage(int) const; + + void addAction(Action *action, int cursorBegin, int cursorEnd); + void addAnnotation(Annotation *annotation, int cursorBegin, int cursorEnd); + void addTitle(int level, const QString &title, const QTextBlock &block); + void addMetaData(const QString &key, const QString &value, const QString &title); + void addMetaData(DocumentInfo::Key, const QString &value); + + QList generateLinkInfos() const; + QList generateAnnotationInfos() const; + void generateTitleInfos(); + + TextDocumentConverter *mConverter; + + QTextDocument *mDocument; + Okular::DocumentInfo mDocumentInfo; + Okular::DocumentSynopsis mDocumentSynopsis; + + struct TitlePosition { + int level; + QString title; + QTextBlock block; + }; + QList mTitlePositions; + + struct LinkPosition { + int startPosition; + int endPosition; + Action *link; + }; + QList mLinkPositions; + + struct AnnotationPosition { + int startPosition; + int endPosition; + Annotation *annotation; + }; + QList mAnnotationPositions; + + TextDocumentSettings *mGeneralSettings; + + QFont mFont; +}; + +} + +#endif diff --git a/core/textdocumentsettings.cpp b/core/textdocumentsettings.cpp new file mode 100644 index 0000000..b7c84b5 --- /dev/null +++ b/core/textdocumentsettings.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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. * + ***************************************************************************/ + +#include "textdocumentsettings.h" +#include "textdocumentsettings_p.h" +#include "ui_textdocumentsettings.h" + +#include +#include + +using namespace Okular; + +/** + * TextDocumentSettingsWidget + */ + +TextDocumentSettingsWidget::TextDocumentSettingsWidget(QWidget *parent) + : QWidget(parent) + , d_ptr(new TextDocumentSettingsWidgetPrivate(new Ui_TextDocumentSettings())) +{ + Q_D(TextDocumentSettingsWidget); + + d->mUi->setupUi(this); + + // @notice I think this will be useful in future. +#define ADD_WIDGET(property, widget, objectName, labelName) \ + d->property = new widget(this); \ + d->property->setObjectName(QString::fromUtf8(objectName)); \ + addRow(labelName, d->property); + + ADD_WIDGET(mFont, KFontRequester, "kcfg_Font", i18n("&Default Font:")); +#undef ADD_WIDGET +} + +TextDocumentSettingsWidget::~TextDocumentSettingsWidget() +{ + Q_D(TextDocumentSettingsWidget); + + delete d->mUi; + delete d; +} + +void TextDocumentSettingsWidget::addRow(const QString &labelText, QWidget *widget) +{ + Q_D(TextDocumentSettingsWidget); + + d->mUi->formLayout->addRow(labelText, widget); +} + +/** + * TextDocumentSettings + */ + +TextDocumentSettings::TextDocumentSettings(const QString &config, QObject *parent) + : KConfigSkeleton(config, parent) + , d_ptr(new TextDocumentSettingsPrivate(this)) +{ + Q_D(TextDocumentSettings); + + addItemFont(QStringLiteral("Font"), d->mFont); +} + +QFont TextDocumentSettings::font() const +{ + Q_D(const TextDocumentSettings); + return d->mFont; +} diff --git a/core/textdocumentsettings.h b/core/textdocumentsettings.h new file mode 100644 index 0000000..c928ed4 --- /dev/null +++ b/core/textdocumentsettings.h @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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_TEXTDOCUMENTSETTINGS_H_ +#define _OKULAR_TEXTDOCUMENTSETTINGS_H_ + +#include "okularcore_export.h" + +#include +#include +#include +#include + +namespace Okular +{ +class TextDocumentSettingsWidgetPrivate; +class TextDocumentSettingsPrivate; + +/** + * Here is example of how you can add custom settings per-backend: + * + * In .h header: + * \code + * class KIntSpinBox; + * ... + * + * class YourGenerator + * { + * ... + * public: + * bool reparseConfig(); + * void addPages( KConfigDialog* dlg ); + * ... + * private: + * QString customArgument; + * KIntSpinBox *customArgumentWidget; + * ... + * } + * \endcode + * + * In .cpp module: + * \code + * #include + * ... + * bool YourGenerator::reparseConfig() + * { + * ... Do something with customArgumentWidget and customArgument ... + * } + * void YourGenerator::addPages( KConfigDialog* dlg ) + * { + * Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + * + * KIntSpinBox *customArgumentWidget = new KIntSpinBox( dlg ); + * customArgumentWidget->setObjectName( QString::fromUtf8( "kcfg_CustomArgument" ) ); + * widget->addRow( "Custom argument", customArgumentWidget ); + * + * Okular::TextDocumentSettings *settings = generalSettings(); + * settings->addItemString( "CustomArgument", customArgument ); + * + * dlg->addPage( widget, settings, ... ); + * } + * \endcode + */ + +/** + * TextDocumentSettingsWidget + * + * Contain default settings for text based documents. + * (all generators that inherited from TextDocumentGenerator) + * Generator can add settings to this object individually. + * + * @since 0.17 (KDE 4.11) + */ +class OKULARCORE_EXPORT TextDocumentSettingsWidget : public QWidget +{ + Q_OBJECT + +public: + explicit TextDocumentSettingsWidget(QWidget *parent = nullptr); + ~TextDocumentSettingsWidget() override; + + void addRow(const QString &labelText, QWidget *widget); + +private: + friend class TextDocumentGenerator; + + TextDocumentSettingsWidgetPrivate *d_ptr; + Q_DECLARE_PRIVATE(TextDocumentSettingsWidget) + Q_DISABLE_COPY(TextDocumentSettingsWidget) +}; + +/** + * TextDocumentSettings + * + * Contain default settings/config skeleton + * To save/restore settings. + * + * @since 0.17 (KDE 4.11) + */ +class OKULARCORE_EXPORT TextDocumentSettings : public KConfigSkeleton +{ + Q_OBJECT + +public: + QFont font() const; + +private: + friend class TextDocumentGenerator; + + TextDocumentSettings(const QString &config, QObject *parent); + + TextDocumentSettingsPrivate *d_ptr; + Q_DECLARE_PRIVATE(TextDocumentSettings) + Q_DISABLE_COPY(TextDocumentSettings) +}; + +} + +#endif diff --git a/core/textdocumentsettings_p.h b/core/textdocumentsettings_p.h new file mode 100644 index 0000000..e606d45 --- /dev/null +++ b/core/textdocumentsettings_p.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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_TEXTDOCUMENTSETTINGS_P_H_ +#define _OKULAR_TEXTDOCUMENTSETTINGS_P_H_ + +class KFontRequester; +class Ui_TextDocumentSettings; + +namespace Okular +{ +class TextDocumentSettingsWidgetPrivate +{ +public: + /** + * @note the private class won't take ownership of the ui, so you + * must delete it yourself + */ + explicit TextDocumentSettingsWidgetPrivate(Ui_TextDocumentSettings *ui) + : mUi(ui) + { + } + + KFontRequester *mFont; + Ui_TextDocumentSettings *mUi; +}; + +class TextDocumentSettingsPrivate : public QObject +{ + Q_OBJECT + +public: + explicit TextDocumentSettingsPrivate(QObject *parent) + : QObject(parent) + { + } + + QFont mFont; +}; + +} + +#endif diff --git a/core/texteditors_p.h b/core/texteditors_p.h new file mode 100644 index 0000000..3fa8149 --- /dev/null +++ b/core/texteditors_p.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * 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_TEXTEDITORS_P_H +#define OKULAR_TEXTEDITORS_P_H + +#include "settings_core.h" + +#include +#include + +namespace Okular +{ +static inline QHash buildEditorsMap() +{ + QHash editors; + editors.insert(SettingsCore::EnumExternalEditor::Kate, QStringLiteral("kate --line %l --column %c")); + editors.insert(SettingsCore::EnumExternalEditor::Kile, QStringLiteral("kile --line %l")); + editors.insert(SettingsCore::EnumExternalEditor::Scite, QStringLiteral("scite %f \"-goto:%l,%c\"")); + editors.insert(SettingsCore::EnumExternalEditor::Emacsclient, QStringLiteral("emacsclient -a emacs --no-wait +%l %f")); + editors.insert(SettingsCore::EnumExternalEditor::Lyxclient, QStringLiteral("lyxclient -g %f %l")); + editors.insert(SettingsCore::EnumExternalEditor::Texstudio, QStringLiteral("texstudio --line %l")); + editors.insert(SettingsCore::EnumExternalEditor::Texifyidea, QStringLiteral("idea --line %l")); + return editors; +} + +} + +#endif diff --git a/core/textpage.cpp b/core/textpage.cpp new file mode 100644 index 0000000..2d6506a --- /dev/null +++ b/core/textpage.cpp @@ -0,0 +1,1891 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymanski * + * * + * 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. * + ***************************************************************************/ + +#include "textpage.h" +#include "textpage_p.h" + +#include + +#include "area.h" +#include "debug_p.h" +#include "misc.h" +#include "page.h" +#include "page_p.h" + +#include + +#include +#include + +using namespace Okular; + +class SearchPoint +{ +public: + SearchPoint() + : offset_begin(-1) + , offset_end(-1) + { + } + + /** The TinyTextEntity containing the first character of the match. */ + TextList::ConstIterator it_begin; + + /** The TinyTextEntity containing the last character of the match. */ + TextList::ConstIterator it_end; + + /** The index of the first character of the match in (*it_begin)->text(). + * Satisfies 0 <= offset_begin < (*it_begin)->text().length(). + */ + int offset_begin; + + /** One plus the index of the last character of the match in (*it_end)->text(). + * Satisfies 0 < offset_end <= (*it_end)->text().length(). + */ + int offset_end; +}; + +/* text comparison functions */ + +static bool CaseInsensitiveCmpFn(const QStringRef &from, const QStringRef &to) +{ +#ifdef DEBUG_TEXTPAGE + qDebug(OkularCoreDebug) << from << ":" << to << "(case insensitive)"; +#endif + return from.compare(to, Qt::CaseInsensitive) == 0; +} + +static bool CaseSensitiveCmpFn(const QStringRef &from, const QStringRef &to) +{ +#ifdef DEBUG_TEXTPAGE + qDebug(OkularCoreDebug) << from << ":" << to << "(case sensitive)"; +#endif + return from.compare(to, Qt::CaseSensitive) == 0; +} + +/** + * Returns true iff segments [@p left1, @p right1] and [@p left2, @p right2] on the real line + * overlap within @p threshold percent, i. e. iff the ratio of the length of the + * intersection of the segments to the length of the shortest of the two input segments + * is not smaller than the threshold. + */ +static bool segmentsOverlap(double left1, double right1, double left2, double right2, int threshold) +{ + // check if one consumes another fully (speed optimization) + + if (left1 <= left2 && right1 >= right2) + return true; + + if (left1 >= left2 && right1 <= right2) + return true; + + // check if there is overlap above threshold + if (right2 >= left1 && right1 >= left2) { + double overlap = (right2 >= right1) ? right1 - left2 : right2 - left1; + + double length1 = right1 - left1, length2 = right2 - left2; + + return overlap * 100 >= threshold * qMin(length1, length2); + } + + return false; +} + +static bool doesConsumeY(const QRect first, const QRect second, int threshold) +{ + return segmentsOverlap(first.top(), first.bottom(), second.top(), second.bottom(), threshold); +} + +static bool doesConsumeY(const NormalizedRect &first, const NormalizedRect &second, int threshold) +{ + return segmentsOverlap(first.top, first.bottom, second.top, second.bottom, threshold); +} + +/* + Rationale behind TinyTextEntity: + + instead of storing directly a QString for the text of an entity, + we store the UTF-16 data and their length. This way, we save about + 4 int's wrt a QString, and we can create a new string from that + raw data (that's the only penalty of that). + Even better, if the string we need to store has at most + MaxStaticChars characters, then we store those in place of the QChar* + that would be used (with new[] + free[]) for the data. + */ +class TinyTextEntity +{ + static const int MaxStaticChars = sizeof(void *) / sizeof(QChar); + +public: + TinyTextEntity(const QString &text, const NormalizedRect &rect) + : area(rect) + { + Q_ASSERT_X(!text.isEmpty(), "TinyTextEntity", "empty string"); + Q_ASSERT_X(sizeof(d) == sizeof(void *), "TinyTextEntity", "internal storage is wider than QChar*, fix it!"); + length = text.length(); + switch (length) { +#if QT_POINTER_SIZE >= 8 + case 4: + d.qc[3] = text.at(3).unicode(); + // fall through + case 3: + d.qc[2] = text.at(2).unicode(); +#endif + // fall through + case 2: + d.qc[1] = text.at(1).unicode(); + // fall through + case 1: + d.qc[0] = text.at(0).unicode(); + break; + default: + d.data = new QChar[length]; + std::memcpy(d.data, text.constData(), length * sizeof(QChar)); + } + } + + ~TinyTextEntity() + { + if (length > MaxStaticChars) { + delete[] d.data; + } + } + + inline QString text() const + { + return length <= MaxStaticChars ? QString::fromRawData((const QChar *)&d.qc[0], length) : QString::fromRawData(d.data, length); + } + + inline NormalizedRect transformedArea(const QTransform &matrix) const + { + NormalizedRect transformed_area = area; + transformed_area.transform(matrix); + return transformed_area; + } + + NormalizedRect area; + +private: + Q_DISABLE_COPY(TinyTextEntity) + + union { + QChar *data; + ushort qc[MaxStaticChars]; + } d; + int length; +}; + +TextEntity::TextEntity(const QString &text, NormalizedRect *area) + : m_text(text) + , m_area(area) + , d(nullptr) +{ +} + +TextEntity::~TextEntity() +{ + delete m_area; +} + +QString TextEntity::text() const +{ + return m_text; +} + +NormalizedRect *TextEntity::area() const +{ + return m_area; +} + +NormalizedRect TextEntity::transformedArea(const QTransform &matrix) const +{ + NormalizedRect transformed_area = *m_area; + transformed_area.transform(matrix); + return transformed_area; +} + +TextPagePrivate::TextPagePrivate() + : m_page(nullptr) +{ +} + +TextPagePrivate::~TextPagePrivate() +{ + qDeleteAll(m_searchPoints); + qDeleteAll(m_words); +} + +TextPage::TextPage() + : d(new TextPagePrivate()) +{ +} + +TextPage::TextPage(const TextEntity::List &words) + : d(new TextPagePrivate()) +{ + TextEntity::List::ConstIterator it = words.constBegin(), itEnd = words.constEnd(); + for (; it != itEnd; ++it) { + TextEntity *e = *it; + if (!e->text().isEmpty()) + d->m_words.append(new TinyTextEntity(e->text(), *e->area())); + delete e; + } +} + +TextPage::~TextPage() +{ + delete d; +} + +void TextPage::append(const QString &text, NormalizedRect *area) +{ + if (!text.isEmpty()) { + if (!d->m_words.isEmpty()) { + TinyTextEntity *lastEntity = d->m_words.last(); + const QString concatText = lastEntity->text() + text.normalized(QString::NormalizationForm_KC); + if (concatText != concatText.normalized(QString::NormalizationForm_KC)) { + // If this happens it means that the new text + old one have combined, for example A and ◌̊ form Å + NormalizedRect newArea = *area | lastEntity->area; + delete area; + delete lastEntity; + d->m_words.removeLast(); + d->m_words.append(new TinyTextEntity(concatText.normalized(QString::NormalizationForm_KC), newArea)); + return; + } + } + + d->m_words.append(new TinyTextEntity(text.normalized(QString::NormalizationForm_KC), *area)); + } + delete area; +} + +struct WordWithCharacters { + WordWithCharacters(TinyTextEntity *w, const TextList &c) + : word(w) + , characters(c) + { + } + + inline QString text() const + { + return word->text(); + } + + inline const NormalizedRect &area() const + { + return word->area; + } + + TinyTextEntity *word; + TextList characters; +}; +typedef QList WordsWithCharacters; + +/** + * We will divide the whole page in some regions depending on the horizontal and + * vertical spacing among different regions. Each region will have an area and an + * associated WordsWithCharacters in sorted order. + */ +class RegionText +{ +public: + RegionText() {}; + + RegionText(const WordsWithCharacters &wordsWithCharacters, const QRect area) + : m_region_wordWithCharacters(wordsWithCharacters) + , m_area(area) + { + } + + inline QString string() const + { + QString res; + for (const WordWithCharacters &word : m_region_wordWithCharacters) { + res += word.text(); + } + return res; + } + + inline WordsWithCharacters text() const + { + return m_region_wordWithCharacters; + } + + inline QRect area() const + { + return m_area; + } + + inline void setArea(const QRect area) + { + m_area = area; + } + + inline void setText(const WordsWithCharacters &wordsWithCharacters) + { + m_region_wordWithCharacters = wordsWithCharacters; + } + +private: + WordsWithCharacters m_region_wordWithCharacters; + QRect m_area; +}; + +RegularAreaRect *TextPage::textArea(TextSelection *sel) const +{ + if (d->m_words.isEmpty()) + return new RegularAreaRect(); + + /** + It works like this: + There are two cursors, we need to select all the text between them. The coordinates are normalised, leftTop is (0,0) + rightBottom is (1,1), so for cursors start (sx,sy) and end (ex,ey) we start with finding text rectangles under those + points, if not we search for the first that is to the right to it in the same baseline, if none found, then we search + for the first rectangle with a baseline under the cursor, having two points that are the best rectangles to both + of the cursors: (rx,ry)x(tx,ty) for start and (ux,uy)x(vx,vy) for end, we do a + 1. (rx,ry)x(1,ty) + 2. (0,ty)x(1,uy) + 3. (0,uy)x(vx,vy) + + To find the closest rectangle to cursor (cx,cy) we search for a rectangle that either contains the cursor + or that has a left border >= cx and bottom border >= cy. + */ + RegularAreaRect *ret = new RegularAreaRect; + + PagePrivate *pagePrivate = PagePrivate::get(d->m_page); + const QTransform matrix = pagePrivate ? pagePrivate->rotationMatrix() : QTransform(); +#if 0 + int it = -1; + int itB = -1; + int itE = -1; + + // ending cursor is higher than start cursor, we need to find positions in reverse + NormalizedRect tmp; + NormalizedRect start; + NormalizedRect end; + + NormalizedPoint startC = sel->start(); + double startCx = startC.x; + double startCy = startC.y; + + NormalizedPoint endC = sel->end(); + double endCx = endC.x; + double endCy = endC.y; + + if ( sel->direction() == 1 || ( sel->itB() == -1 && sel->direction() == 0 ) ) + { +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "running first loop"; +#endif + const int count = d->m_words.count(); + for ( it = 0; it < count; it++ ) + { + tmp = *d->m_words[ it ]->area(); + if ( tmp.contains( startCx, startCy ) + || ( tmp.top <= startCy && tmp.bottom >= startCy && tmp.left >= startCx ) + || ( tmp.top >= startCy)) + { + /// we have found the (rx,ry)x(tx,ty) + itB = it; +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "start is" << itB << "count is" << d->m_words.count(); +#endif + break; + } + } + sel->itB( itB ); + } + itB = sel->itB(); +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "direction is" << sel->direction(); + qCWarning(OkularCoreDebug) << "reloaded start is" << itB << "against" << sel->itB(); +#endif + if ( sel->direction() == 0 || ( sel->itE() == -1 && sel->direction() == 1 ) ) + { +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "running second loop"; +#endif + for ( it = d->m_words.count() - 1; it >= itB; it-- ) + { + tmp = *d->m_words[ it ]->area(); + if ( tmp.contains( endCx, endCy ) + || ( tmp.top <= endCy && tmp.bottom >= endCy && tmp.right <= endCx ) + || ( tmp.bottom <= endCy ) ) + { + /// we have found the (ux,uy)x(vx,vy) + itE = it; +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "ending is" << itE << "count is" << d->m_words.count(); + qCWarning(OkularCoreDebug) << "conditions" << tmp.contains( endCx, endCy ) << " " + << ( tmp.top <= endCy && tmp.bottom >= endCy && tmp.right <= endCx ) << " " << + ( tmp.top >= endCy); +#endif + break; + } + } + sel->itE( itE ); + } +#ifdef DEBUG_TEXTPAGE + qCWarning(OkularCoreDebug) << "reloaded ending is" << itE << "against" << sel->itE(); +#endif + + if ( sel->itB() != -1 && sel->itE() != -1 ) + { + start = *d->m_words[ sel->itB() ]->area(); + end = *d->m_words[ sel->itE() ]->area(); + + NormalizedRect first, second, third; + /// finding out if there is more than one baseline between them is a hard and discussable task + /// we will create a rectangle (rx,0)x(tx,1) and will check how many times does it intersect the + /// areas, if more than one -> we have a three or over line selection + first = start; + second.top = start.bottom; + first.right = second.right = 1; + third = end; + third.left = second.left = 0; + second.bottom = end.top; + int selMax = qMax( sel->itB(), sel->itE() ); + for ( it = qMin( sel->itB(), sel->itE() ); it <= selMax; ++it ) + { + tmp = *d->m_words[ it ]->area(); + if ( tmp.intersects( &first ) || tmp.intersects( &second ) || tmp.intersects( &third ) ) + ret->appendShape( d->m_words.at( it )->transformedArea( matrix ) ); + } + } +#else + const double scaleX = d->m_page->width(); + const double scaleY = d->m_page->height(); + + NormalizedPoint startC = sel->start(); + NormalizedPoint endC = sel->end(); + NormalizedPoint temp; + + // if startPoint is right to endPoint swap them + if (startC.x > endC.x) { + temp = startC; + startC = endC; + endC = temp; + } + + // minX,maxX,minY,maxY gives the bounding rectangle coordinates of the document + const NormalizedRect boundingRect = d->m_page->boundingBox(); + const QRect content = boundingRect.geometry(scaleX, scaleY); + const double minX = content.left(); + const double maxX = content.right(); + const double minY = content.top(); + const double maxY = content.bottom(); + + /** + * We will now find out the TinyTextEntity for the startRectangle and TinyTextEntity for + * the endRectangle. We have four cases: + * + * Case 1(a): both startpoint and endpoint are out of the bounding Rectangle and at one side, so the rectangle made of start + * and endPoint are outof the bounding rect (do not intersect) + * + * Case 1(b): both startpoint and endpoint are out of bounding rect, but they are in different side, so is their rectangle + * + * Case 2(a): find the rectangle which contains start and endpoint and having some + * TextEntity + * + * Case 2(b): if 2(a) fails (if startPoint and endPoint both are unchanged), then we check whether there is any + * TextEntity within the rect made by startPoint and endPoint + * + * Case 3: Now, we may have two type of selection. + * 1. startpoint is left-top of start_end and endpoint is right-bottom + * 2. startpoint is left-bottom of start_end and endpoint is top-right + * + * Also, as 2(b) is passed, we might have it,itEnd or both unchanged, but the fact is that we have + * text within them. so, we need to search for the best suitable textposition for start and end. + * + * Case 3(a): We search the nearest rectangle consisting of some + * TinyTextEntity right to or bottom of the startPoint for selection 01. + * And, for selection 02, we have to search for right and top + * + * Case 3(b): For endpoint, we have to find the point top of or left to + * endpoint if we have selection 01. + * Otherwise, the search will be left and bottom + */ + + // we know that startC.x > endC.x, we need to decide which is top and which is bottom + const NormalizedRect start_end = (startC.y < endC.y) ? NormalizedRect(startC.x, startC.y, endC.x, endC.y) : NormalizedRect(startC.x, endC.y, endC.x, startC.y); + + // Case 1(a) + if (!boundingRect.intersects(start_end)) + return ret; + + // case 1(b) + /** + note that, after swapping of start and end, we know that, + start is always left to end. but, we cannot say start is + positioned upper than end. + **/ + else { + // if start is left to content rect take it to content rect boundary + if (startC.x * scaleX < minX) + startC.x = minX / scaleX; + if (endC.x * scaleX > maxX) + endC.x = maxX / scaleX; + + // if start is top to end (selection type 01) + if (startC.y * scaleY < minY) + startC.y = minY / scaleY; + if (endC.y * scaleY > maxY) + endC.y = maxY / scaleY; + + // if start is bottom to end (selection type 02) + if (startC.y * scaleY > maxY) + startC.y = maxY / scaleY; + if (endC.y * scaleY < minY) + endC.y = minY / scaleY; + } + + TextList::ConstIterator it = d->m_words.constBegin(), itEnd = d->m_words.constEnd(); + TextList::ConstIterator start = it, end = itEnd, tmpIt = it; //, tmpItEnd = itEnd; + const MergeSide side = d->m_page ? (MergeSide)d->m_page->totalOrientation() : MergeRight; + + NormalizedRect tmp; + // case 2(a) + for (; it != itEnd; ++it) { + tmp = (*it)->area; + if (tmp.contains(startC.x, startC.y)) { + start = it; + } + if (tmp.contains(endC.x, endC.y)) { + end = it; + } + } + + // case 2(b) + it = tmpIt; + if (start == it && end == itEnd) { + for (; it != itEnd; ++it) { + // is there any text rectangle within the start_end rect + tmp = (*it)->area; + if (start_end.intersects(tmp)) + break; + } + + // we have searched every text entities, but none is within the rectangle created by start and end + // so, no selection should be done + if (it == itEnd) { + return ret; + } + } + it = tmpIt; + bool selection_two_start = false; + + // case 3.a + if (start == it) { + bool flagV = false; + NormalizedRect rect; + + // selection type 01 + if (startC.y <= endC.y) { + for (; it != itEnd; ++it) { + rect = (*it)->area; + rect.isBottom(startC) ? flagV = false : flagV = true; + + if (flagV && rect.isRight(startC)) { + start = it; + break; + } + } + } + + // selection type 02 + else { + selection_two_start = true; + int distance = scaleX + scaleY + 100; + int count = 0; + + for (; it != itEnd; ++it) { + rect = (*it)->area; + + if (rect.isBottomOrLevel(startC) && rect.isRight(startC)) { + count++; + QRect entRect = rect.geometry(scaleX, scaleY); + int xdist, ydist; + xdist = entRect.center().x() - startC.x * scaleX; + ydist = entRect.center().y() - startC.y * scaleY; + + // make them positive + if (xdist < 0) + xdist = -xdist; + if (ydist < 0) + ydist = -ydist; + + if ((xdist + ydist) < distance) { + distance = xdist + ydist; + start = it; + } + } + } + } + } + + // case 3.b + if (end == itEnd) { + it = tmpIt; + itEnd = itEnd - 1; + + bool flagV = false; + NormalizedRect rect; + + if (startC.y <= endC.y) { + for (; itEnd >= it; itEnd--) { + rect = (*itEnd)->area; + rect.isTop(endC) ? flagV = false : flagV = true; + + if (flagV && rect.isLeft(endC)) { + end = itEnd; + break; + } + } + } + + else { + int distance = scaleX + scaleY + 100; + for (; itEnd >= it; itEnd--) { + rect = (*itEnd)->area; + + if (rect.isTopOrLevel(endC) && rect.isLeft(endC)) { + QRect entRect = rect.geometry(scaleX, scaleY); + int xdist, ydist; + xdist = entRect.center().x() - endC.x * scaleX; + ydist = entRect.center().y() - endC.y * scaleY; + + // make them positive + if (xdist < 0) + xdist = -xdist; + if (ydist < 0) + ydist = -ydist; + + if ((xdist + ydist) < distance) { + distance = xdist + ydist; + end = itEnd; + } + } + } + } + } + + /* if start and end in selection 02 are in the same column, and we + start at an empty space we have to remove the selection of last + character + */ + if (selection_two_start) { + if (start > end) { + start = start - 1; + } + } + + // if start is less than end swap them + if (start > end) { + it = start; + start = end; + end = it; + } + + // removes the possibility of crash, in case none of 1 to 3 is true + if (end == d->m_words.constEnd()) + end--; + + for (; start <= end; start++) { + ret->appendShape((*start)->transformedArea(matrix), side); + } + +#endif + + return ret; +} + +RegularAreaRect *TextPage::findText(int searchID, const QString &query, SearchDirection direct, Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *area) +{ + SearchDirection dir = direct; + // invalid search request + if (d->m_words.isEmpty() || query.isEmpty() || (area && area->isNull())) + return nullptr; + TextList::ConstIterator start; + int start_offset = 0; + TextList::ConstIterator end; + const QMap::const_iterator sIt = d->m_searchPoints.constFind(searchID); + if (sIt == d->m_searchPoints.constEnd()) { + // if no previous run of this search is found, then set it to start + // from the beginning (respecting the search direction) + if (dir == NextResult) + dir = FromTop; + else if (dir == PreviousResult) + dir = FromBottom; + } + bool forward = true; + switch (dir) { + case FromTop: + start = d->m_words.constBegin(); + start_offset = 0; + end = d->m_words.constEnd(); + break; + case FromBottom: + start = d->m_words.constEnd(); + start_offset = 0; + end = d->m_words.constBegin(); + forward = false; + break; + case NextResult: + start = (*sIt)->it_end; + start_offset = (*sIt)->offset_end; + end = d->m_words.constEnd(); + break; + case PreviousResult: + start = (*sIt)->it_begin; + start_offset = (*sIt)->offset_begin; + end = d->m_words.constBegin(); + forward = false; + break; + }; + RegularAreaRect *ret = nullptr; + const TextComparisonFunction cmpFn = caseSensitivity == Qt::CaseSensitive ? CaseSensitiveCmpFn : CaseInsensitiveCmpFn; + if (forward) { + ret = d->findTextInternalForward(searchID, query, cmpFn, start, start_offset, end); + } else { + ret = d->findTextInternalBackward(searchID, query, cmpFn, start, start_offset, end); + } + return ret; +} + +// hyphenated '-' must be at the end of a word, so hyphenation means +// we have a '-' just followed by a '\n' character +// check if the string contains a '-' character +// if the '-' is the last entry +static int stringLengthAdaptedWithHyphen(const QString &str, const TextList::ConstIterator &it, const TextList::ConstIterator &textListEnd) +{ + const int len = str.length(); + + // hyphenated '-' must be at the end of a word, so hyphenation means + // we have a '-' just followed by a '\n' character + // check if the string contains a '-' character + // if the '-' is the last entry + if (str.endsWith(QLatin1Char('-'))) { + // validity chek of it + 1 + if ((it + 1) != textListEnd) { + // 1. if the next character is '\n' + const QString &lookahedStr = (*(it + 1))->text(); + if (lookahedStr.startsWith(QLatin1Char('\n'))) { + return len - 1; + } + + // 2. if the next word is in a different line or not + const NormalizedRect &hyphenArea = (*it)->area; + const NormalizedRect &lookaheadArea = (*(it + 1))->area; + + // lookahead to check whether both the '-' rect and next character rect overlap + if (!doesConsumeY(hyphenArea, lookaheadArea, 70)) { + return len - 1; + } + } + } + // else if it is the second last entry - for example in pdf format + else if (str.endsWith(QLatin1String("-\n"))) { + return len - 2; + } + + return len; +} + +RegularAreaRect *TextPagePrivate::searchPointToArea(const SearchPoint *sp) +{ + PagePrivate *pagePrivate = PagePrivate::get(m_page); + const QTransform matrix = pagePrivate ? pagePrivate->rotationMatrix() : QTransform(); + RegularAreaRect *ret = new RegularAreaRect; + + for (TextList::ConstIterator it = sp->it_begin;; it++) { + const TinyTextEntity *curEntity = *it; + ret->append(curEntity->transformedArea(matrix)); + + if (it == sp->it_end) { + break; + } + } + + ret->simplify(); + return ret; +} + +RegularAreaRect *TextPagePrivate::findTextInternalForward(int searchID, const QString &_query, TextComparisonFunction comparer, const TextList::ConstIterator &start, int start_offset, const TextList::ConstIterator &end) +{ + // normalize query search all unicode (including glyphs) + const QString query = _query.normalized(QString::NormalizationForm_KC); + + // j is the current position in our query + // queryLeft is the length of the query we have left to match + int j = 0, queryLeft = query.length(); + + TextList::ConstIterator it = start; + int offset = start_offset; + + TextList::ConstIterator it_begin = TextList::ConstIterator(); + int offset_begin = 0; // dummy initial value to suppress compiler warnings + + while (it != end) { + const TinyTextEntity *curEntity = *it; + const QString &str = curEntity->text(); + const int strLen = str.length(); + const int adjustedLen = stringLengthAdaptedWithHyphen(str, it, m_words.constEnd()); + // adjustedLen <= strLen + + if (offset >= strLen) { + it++; + offset = 0; + continue; + } + + if (it_begin == TextList::ConstIterator()) { + it_begin = it; + offset_begin = offset; + } + + // Let the user write the hyphen or not when searching for text + int matchedLen = -1; + for (int matchingLen = strLen; matchingLen >= adjustedLen; matchingLen--) { + // we have equal (or less than) area of the query left as the length of the current + // entity + const int min = qMin(queryLeft, matchingLen - offset); + if (comparer(str.midRef(offset, min), query.midRef(j, min))) { + matchedLen = min; + break; + } + } + + if (matchedLen == -1) { + // we have not matched + // this means we do not have a complete match + // we need to get back to query start + // and continue the search from this place +#ifdef DEBUG_TEXTPAGE + qCDebug(OkularCoreDebug) << "\tnot matched"; +#endif + j = 0; + queryLeft = query.length(); + it = it_begin; + offset = offset_begin + 1; + it_begin = TextList::ConstIterator(); + } else { + // we have a match + // move the current position in the query + // to the position after the length of this string + // we matched + // subtract the length of the current entity from + // the left length of the query +#ifdef DEBUG_TEXTPAGE + qCDebug(OkularCoreDebug) << "\tmatched" << matchedLen; +#endif + j += matchedLen; + queryLeft -= matchedLen; + + if (queryLeft == 0) { + // save or update the search point for the current searchID + QMap::iterator sIt = m_searchPoints.find(searchID); + if (sIt == m_searchPoints.end()) { + sIt = m_searchPoints.insert(searchID, new SearchPoint); + } + SearchPoint *sp = *sIt; + sp->it_begin = it_begin; + sp->it_end = it; + sp->offset_begin = offset_begin; + sp->offset_end = offset + matchedLen; + return searchPointToArea(sp); + } + + it++; + offset = 0; + } + } + // end of loop - it means that we've ended the textentities + + const QMap::iterator sIt = m_searchPoints.find(searchID); + if (sIt != m_searchPoints.end()) { + SearchPoint *sp = *sIt; + m_searchPoints.erase(sIt); + delete sp; + } + return nullptr; +} + +RegularAreaRect *TextPagePrivate::findTextInternalBackward(int searchID, const QString &_query, TextComparisonFunction comparer, const TextList::ConstIterator &start, int start_offset, const TextList::ConstIterator &end) +{ + // normalize query to search all unicode (including glyphs) + const QString query = _query.normalized(QString::NormalizationForm_KC); + + // j is the current position in our query + // len is the length of the string in TextEntity + // queryLeft is the length of the query we have left + int j = query.length(), queryLeft = query.length(); + + TextList::ConstIterator it = start; + int offset = start_offset; + + TextList::ConstIterator it_begin = TextList::ConstIterator(); + int offset_begin = 0; // dummy initial value to suppress compiler warnings + + while (true) { + if (offset <= 0) { + if (it == end) { + break; + } + it--; + } + + const TinyTextEntity *curEntity = *it; + const QString &str = curEntity->text(); + const int strLen = str.length(); + const int adjustedLen = stringLengthAdaptedWithHyphen(str, it, m_words.constEnd()); + // adjustedLen <= strLen + + if (offset <= 0) { + offset = strLen; + } + + if (it_begin == TextList::ConstIterator()) { + it_begin = it; + offset_begin = offset; + } + + // Let the user write the hyphen or not when searching for text + int matchedLen = -1; + // we have equal (or less than) area of the query left as the length of the current + // entity + for (int matchingLen = strLen; matchingLen >= adjustedLen; matchingLen--) { + const int hyphenOffset = (strLen - matchingLen); + const int min = qMin(queryLeft + hyphenOffset, offset); + if (comparer(str.midRef(offset - min, min - hyphenOffset), query.midRef(j - min + hyphenOffset, min - hyphenOffset))) { + matchedLen = min - hyphenOffset; + break; + } + } + + if (matchedLen == -1) { + // we have not matched + // this means we do not have a complete match + // we need to get back to query start + // and continue the search from this place +#ifdef DEBUG_TEXTPAGE + qCDebug(OkularCoreDebug) << "\tnot matched"; +#endif + + j = query.length(); + queryLeft = query.length(); + it = it_begin; + offset = offset_begin - 1; + it_begin = TextList::ConstIterator(); + } else { + // we have a match + // move the current position in the query + // to the position after the length of this string + // we matched + // subtract the length of the current entity from + // the left length of the query +#ifdef DEBUG_TEXTPAGE + qCDebug(OkularCoreDebug) << "\tmatched"; +#endif + j -= matchedLen; + queryLeft -= matchedLen; + + if (queryLeft == 0) { + // save or update the search point for the current searchID + QMap::iterator sIt = m_searchPoints.find(searchID); + if (sIt == m_searchPoints.end()) { + sIt = m_searchPoints.insert(searchID, new SearchPoint); + } + SearchPoint *sp = *sIt; + sp->it_begin = it; + sp->it_end = it_begin; + sp->offset_begin = offset - matchedLen; + sp->offset_end = offset_begin; + return searchPointToArea(sp); + } + + offset = 0; + } + } + // end of loop - it means that we've ended the textentities + + const QMap::iterator sIt = m_searchPoints.find(searchID); + if (sIt != m_searchPoints.end()) { + SearchPoint *sp = *sIt; + m_searchPoints.erase(sIt); + delete sp; + } + return nullptr; +} + +QString TextPage::text(const RegularAreaRect *area) const +{ + return text(area, AnyPixelTextAreaInclusionBehaviour); +} + +QString TextPage::text(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const +{ + if (area && area->isNull()) + return QString(); + + TextList::ConstIterator it = d->m_words.constBegin(), itEnd = d->m_words.constEnd(); + QString ret; + if (area) { + for (; it != itEnd; ++it) { + if (b == AnyPixelTextAreaInclusionBehaviour) { + if (area->intersects((*it)->area)) { + ret += (*it)->text(); + } + } else { + NormalizedPoint center = (*it)->area.center(); + if (area->contains(center.x, center.y)) { + ret += (*it)->text(); + } + } + } + } else { + for (; it != itEnd; ++it) + ret += (*it)->text(); + } + return ret; +} + +static bool compareTinyTextEntityX(const WordWithCharacters &first, const WordWithCharacters &second) +{ + QRect firstArea = first.area().roundedGeometry(1000, 1000); + QRect secondArea = second.area().roundedGeometry(1000, 1000); + + return firstArea.left() < secondArea.left(); +} + +static bool compareTinyTextEntityY(const WordWithCharacters &first, const WordWithCharacters &second) +{ + const QRect firstArea = first.area().roundedGeometry(1000, 1000); + const QRect secondArea = second.area().roundedGeometry(1000, 1000); + + return firstArea.top() < secondArea.top(); +} + +/** + * Sets a new world list. Deleting the contents of the old one + */ +void TextPagePrivate::setWordList(const TextList &list) +{ + qDeleteAll(m_words); + m_words = list; +} + +/** + * Remove all the spaces in between texts. It will make all the generators + * same, whether they save spaces(like pdf) or not(like djvu). + */ +static void removeSpace(TextList *words) +{ + TextList::Iterator it = words->begin(); + const QString str(QLatin1Char(' ')); + + while (it != words->end()) { + if ((*it)->text() == str) { + it = words->erase(it); + } else { + ++it; + } + } +} + +/** + * We will read the TinyTextEntity from characters and try to create words from there. + * Note: characters might be already characters for some generators, but we will keep + * the nomenclature characters for the generator produced data. The resulting + * WordsWithCharacters memory has to be managed by the caller, both the + * WordWithCharacters::word and WordWithCharacters::characters contents + */ +static WordsWithCharacters makeWordFromCharacters(const TextList &characters, int pageWidth, int pageHeight) +{ + /** + * We will traverse characters and try to create words from the TinyTextEntities in it. + * We will search TinyTextEntity blocks and merge them until we get a + * space between two consecutive TinyTextEntities. When we get a space + * we can take it as a end of word. Then we store the word as a TinyTextEntity + * and keep it in newList. + + * We create a RegionText named regionWord that contains the word and the characters associated with it and + * a rectangle area of the element in newList. + + */ + WordsWithCharacters wordsWithCharacters; + + TextList::ConstIterator it = characters.begin(), itEnd = characters.end(), tmpIt; + int newLeft, newRight, newTop, newBottom; + int index = 0; + + for (; it != itEnd; it++) { + QString textString = (*it)->text(); + QString newString; + QRect lineArea = (*it)->area.roundedGeometry(pageWidth, pageHeight), elementArea; + TextList wordCharacters; + tmpIt = it; + int space = 0; + + while (!space) { + if (!textString.isEmpty()) { + newString.append(textString); + + // when textString is the start of the word + if (tmpIt == it) { + NormalizedRect newRect(lineArea, pageWidth, pageHeight); + wordCharacters.append(new TinyTextEntity(textString.normalized(QString::NormalizationForm_KC), newRect)); + } else { + NormalizedRect newRect(elementArea, pageWidth, pageHeight); + wordCharacters.append(new TinyTextEntity(textString.normalized(QString::NormalizationForm_KC), newRect)); + } + } + + ++it; + + /* + we must have to put this line before the if condition of it==itEnd + otherwise the last character can be missed + */ + if (it == itEnd) + break; + elementArea = (*it)->area.roundedGeometry(pageWidth, pageHeight); + if (!doesConsumeY(elementArea, lineArea, 60)) { + --it; + break; + } + + const int text_y1 = elementArea.top(), text_x1 = elementArea.left(), text_y2 = elementArea.y() + elementArea.height(), text_x2 = elementArea.x() + elementArea.width(); + const int line_y1 = lineArea.top(), line_x1 = lineArea.left(), line_y2 = lineArea.y() + lineArea.height(), line_x2 = lineArea.x() + lineArea.width(); + + space = elementArea.left() - lineArea.right(); + + if (space != 0) { + it--; + break; + } + + newLeft = text_x1 < line_x1 ? text_x1 : line_x1; + newRight = line_x2 > text_x2 ? line_x2 : text_x2; + newTop = text_y1 > line_y1 ? line_y1 : text_y1; + newBottom = text_y2 > line_y2 ? text_y2 : line_y2; + + lineArea.setLeft(newLeft); + lineArea.setTop(newTop); + lineArea.setWidth(newRight - newLeft); + lineArea.setHeight(newBottom - newTop); + + textString = (*it)->text(); + } + + // if newString is not empty, save it + if (!newString.isEmpty()) { + const NormalizedRect newRect(lineArea, pageWidth, pageHeight); + TinyTextEntity *word = new TinyTextEntity(newString.normalized(QString::NormalizationForm_KC), newRect); + wordsWithCharacters.append(WordWithCharacters(word, wordCharacters)); + + index++; + } + + if (it == itEnd) + break; + } + + return wordsWithCharacters; +} + +/** + * Create Lines from the words and sort them + */ +QList> makeAndSortLines(const WordsWithCharacters &wordsTmp, int pageWidth, int pageHeight) +{ + /** + * We cannot assume that the generator will give us texts in the right order. + * We can only assume that we will get texts in the page and their bounding + * rectangle. The texts can be character, word, half-word anything. + * So, we need to: + ** + * 1. Sort rectangles/boxes containing texts by y0(top) + * 2. Create textline where there is y overlap between TinyTextEntity 's + * 3. Within each line sort the TinyTextEntity 's by x0(left) + */ + + QList> lines; + + /* + Make a new copy of the TextList in the words, so that the wordsTmp and lines do + not contain same pointers for all the TinyTextEntity. + */ + QList words = wordsTmp; + + // Step 1 + std::sort(words.begin(), words.end(), compareTinyTextEntityY); + + // Step 2 + QList::Iterator it = words.begin(), itEnd = words.end(); + + // for every non-space texts(characters/words) in the textList + for (; it != itEnd; it++) { + const QRect elementArea = (*it).area().roundedGeometry(pageWidth, pageHeight); + bool found = false; + + for (QPair &linesI : lines) { + /* the line area which will be expanded + line_rects is only necessary to preserve the topmin and bottommax of all + the texts in the line, left and right is not necessary at all + */ + QRect &lineArea = linesI.second; + const int text_y1 = elementArea.top(), text_y2 = elementArea.top() + elementArea.height(), text_x1 = elementArea.left(), text_x2 = elementArea.left() + elementArea.width(); + const int line_y1 = lineArea.top(), line_y2 = lineArea.top() + lineArea.height(), line_x1 = lineArea.left(), line_x2 = lineArea.left() + lineArea.width(); + + /* + if the new text and the line has y overlapping parts of more than 70%, + the text will be added to this line + */ + if (doesConsumeY(elementArea, lineArea, 70)) { + WordsWithCharacters &line = linesI.first; + line.append(*it); + + const int newLeft = line_x1 < text_x1 ? line_x1 : text_x1; + const int newRight = line_x2 > text_x2 ? line_x2 : text_x2; + const int newTop = line_y1 < text_y1 ? line_y1 : text_y1; + const int newBottom = text_y2 > line_y2 ? text_y2 : line_y2; + + lineArea = QRect(newLeft, newTop, newRight - newLeft, newBottom - newTop); + found = true; + } + + if (found) + break; + } + + /* when we have found a new line create a new TextList containing + only one element and append it to the lines + */ + if (!found) { + WordsWithCharacters tmp; + tmp.append((*it)); + lines.append(QPair(tmp, elementArea)); + } + } + + // Step 3 + for (QPair &line : lines) { + WordsWithCharacters &list = line.first; + std::sort(list.begin(), list.end(), compareTinyTextEntityX); + } + + return lines; +} + +/** + * Calculate Statistical information from the lines we made previously + */ +static void calculateStatisticalInformation(const QList &words, int pageWidth, int pageHeight, int *word_spacing, int *line_spacing, int *col_spacing) +{ + /** + * For the region, defined by line_rects and lines + * 1. Make line statistical analysis to find the line spacing + * 2. Make character statistical analysis to differentiate between + * word spacing and column spacing. + */ + + /** + * Step 0 + */ + const QList> sortedLines = makeAndSortLines(words, pageWidth, pageHeight); + + /** + * Step 1 + */ + QMap line_space_stat; + for (int i = 0; i < sortedLines.length(); i++) { + const QRect rectUpper = sortedLines.at(i).second; + + if (i + 1 == sortedLines.length()) + break; + const QRect rectLower = sortedLines.at(i + 1).second; + + int linespace = rectLower.top() - (rectUpper.top() + rectUpper.height()); + if (linespace < 0) + linespace = -linespace; + + if (line_space_stat.contains(linespace)) + line_space_stat[linespace]++; + else + line_space_stat[linespace] = 1; + } + + *line_spacing = 0; + int weighted_count = 0; + QMapIterator iterate_linespace(line_space_stat); + + while (iterate_linespace.hasNext()) { + iterate_linespace.next(); + *line_spacing += iterate_linespace.value() * iterate_linespace.key(); + weighted_count += iterate_linespace.value(); + } + if (*line_spacing != 0) + *line_spacing = (int)((double)*line_spacing / (double)weighted_count + 0.5); + + /** + * Step 2 + */ + // We would like to use QMap instead of QHash as it will keep the keys sorted + QMap hor_space_stat; + QMap col_space_stat; + QList> space_rects; + QVector max_hor_space_rects; + + // Space in every line + for (const QPair &sortedLine : sortedLines) { + const WordsWithCharacters list = sortedLine.first; + QList line_space_rects; + int maxSpace = 0, minSpace = pageWidth; + + // for every TinyTextEntity element in the line + WordsWithCharacters::ConstIterator it = list.begin(), itEnd = list.end(); + QRect max_area1, max_area2; + QString before_max, after_max; + + // for every line + for (; it != itEnd; it++) { + const QRect area1 = (*it).area().roundedGeometry(pageWidth, pageHeight); + if (it + 1 == itEnd) + break; + + const QRect area2 = (*(it + 1)).area().roundedGeometry(pageWidth, pageHeight); + int space = area2.left() - area1.right(); + + if (space > maxSpace) { + max_area1 = area1; + max_area2 = area2; + maxSpace = space; + before_max = (*it).text(); + after_max = (*(it + 1)).text(); + } + + if (space < minSpace && space != 0) + minSpace = space; + + // if we found a real space, whose length is not zero and also less than the pageWidth + if (space != 0 && space != pageWidth) { + // increase the count of the space amount + if (hor_space_stat.contains(space)) + hor_space_stat[space]++; + else + hor_space_stat[space] = 1; + + int left, right, top, bottom; + + left = area1.right(); + right = area2.left(); + + top = area2.top() < area1.top() ? area2.top() : area1.top(); + bottom = area2.bottom() > area1.bottom() ? area2.bottom() : area1.bottom(); + + QRect rect(left, top, right - left, bottom - top); + line_space_rects.append(rect); + } + } + + space_rects.append(line_space_rects); + + if (hor_space_stat.contains(maxSpace)) { + if (hor_space_stat[maxSpace] != 1) + hor_space_stat[maxSpace]--; + else + hor_space_stat.remove(maxSpace); + } + + if (maxSpace != 0) { + if (col_space_stat.contains(maxSpace)) + col_space_stat[maxSpace]++; + else + col_space_stat[maxSpace] = 1; + + // store the max rect of each line + const int left = max_area1.right(); + const int right = max_area2.left(); + const int top = (max_area1.top() > max_area2.top()) ? max_area2.top() : max_area1.top(); + const int bottom = (max_area1.bottom() < max_area2.bottom()) ? max_area2.bottom() : max_area1.bottom(); + + const QRect rect(left, top, right - left, bottom - top); + max_hor_space_rects.append(rect); + } else + max_hor_space_rects.append(QRect(0, 0, 0, 0)); + } + + // All the between word space counts are in hor_space_stat + *word_spacing = 0; + weighted_count = 0; + QMapIterator iterate(hor_space_stat); + + while (iterate.hasNext()) { + iterate.next(); + + if (iterate.key() > 0) { + *word_spacing += iterate.value() * iterate.key(); + weighted_count += iterate.value(); + } + } + if (weighted_count) + *word_spacing = (int)((double)*word_spacing / (double)weighted_count + 0.5); + + *col_spacing = 0; + QMapIterator iterate_col(col_space_stat); + + while (iterate_col.hasNext()) { + iterate_col.next(); + if (iterate_col.value() > *col_spacing) + *col_spacing = iterate_col.value(); + } + *col_spacing = col_space_stat.key(*col_spacing); + + // if there is just one line in a region, there is no point in dividing it + if (sortedLines.length() == 1) + *word_spacing = *col_spacing; +} + +/** + * Implements the XY Cut algorithm for textpage segmentation + * The resulting RegionTextList will contain RegionText whose WordsWithCharacters::word and + * WordsWithCharacters::characters are reused from wordsWithCharacters (i.e. no new nor delete happens in this function) + */ +static RegionTextList XYCutForBoundingBoxes(const QList &wordsWithCharacters, const NormalizedRect &boundingBox, int pageWidth, int pageHeight) +{ + RegionTextList tree; + QRect contentRect(boundingBox.geometry(pageWidth, pageHeight)); + const RegionText root(wordsWithCharacters, contentRect); + + // start the tree with the root, it is our only region at the start + tree.push_back(root); + + int i = 0; + + // while traversing the tree has not been ended + while (i < tree.length()) { + const RegionText node = tree.at(i); + QRect regionRect = node.area(); + + /** + * 1. calculation of projection profiles + */ + // allocate the size of proj profiles and initialize with 0 + int size_proj_y = node.area().height(); + int size_proj_x = node.area().width(); + // dynamic memory allocation + QVarLengthArray proj_on_xaxis(size_proj_x); + QVarLengthArray proj_on_yaxis(size_proj_y); + + for (int j = 0; j < size_proj_y; ++j) + proj_on_yaxis[j] = 0; + for (int j = 0; j < size_proj_x; ++j) + proj_on_xaxis[j] = 0; + + const QList list = node.text(); + + // Calculate tcx and tcy locally for each new region + int word_spacing, line_spacing, column_spacing; + calculateStatisticalInformation(list, pageWidth, pageHeight, &word_spacing, &line_spacing, &column_spacing); + + const int tcx = word_spacing * 2; + const int tcy = line_spacing * 2; + + int maxX = 0, maxY = 0; + int avgX = 0; + int count; + + // for every text in the region + for (const WordWithCharacters &wwc : list) { + TinyTextEntity *ent = wwc.word; + const QRect entRect = ent->area.geometry(pageWidth, pageHeight); + + // calculate vertical projection profile proj_on_xaxis1 + for (int k = entRect.left(); k <= entRect.left() + entRect.width(); ++k) { + if ((k - regionRect.left()) < size_proj_x && (k - regionRect.left()) >= 0) + proj_on_xaxis[k - regionRect.left()] += entRect.height(); + } + + // calculate horizontal projection profile in the same way + for (int k = entRect.top(); k <= entRect.top() + entRect.height(); ++k) { + if ((k - regionRect.top()) < size_proj_y && (k - regionRect.top()) >= 0) + proj_on_yaxis[k - regionRect.top()] += entRect.width(); + } + } + + for (int j = 0; j < size_proj_y; ++j) { + if (proj_on_yaxis[j] > maxY) + maxY = proj_on_yaxis[j]; + } + + avgX = count = 0; + for (int j = 0; j < size_proj_x; ++j) { + if (proj_on_xaxis[j] > maxX) + maxX = proj_on_xaxis[j]; + if (proj_on_xaxis[j]) { + count++; + avgX += proj_on_xaxis[j]; + } + } + if (count) + avgX /= count; + + /** + * 2. Cleanup Boundary White Spaces and removal of noise + */ + int xbegin = 0, xend = size_proj_x - 1; + int ybegin = 0, yend = size_proj_y - 1; + while (xbegin < size_proj_x && proj_on_xaxis[xbegin] <= 0) + xbegin++; + while (xend >= 0 && proj_on_xaxis[xend] <= 0) + xend--; + while (ybegin < size_proj_y && proj_on_yaxis[ybegin] <= 0) + ybegin++; + while (yend >= 0 && proj_on_yaxis[yend] <= 0) + yend--; + + // update the regionRect + int old_left = regionRect.left(), old_top = regionRect.top(); + regionRect.setLeft(old_left + xbegin); + regionRect.setRight(old_left + xend); + regionRect.setTop(old_top + ybegin); + regionRect.setBottom(old_top + yend); + + int tnx = (int)((double)avgX * 10.0 / 100.0 + 0.5), tny = 0; + for (int j = 0; j < size_proj_x; ++j) + proj_on_xaxis[j] -= tnx; + for (int j = 0; j < size_proj_y; ++j) + proj_on_yaxis[j] -= tny; + + /** + * 3. Find the Widest gap + */ + int gap_hor = -1, pos_hor = -1; + int begin = -1, end = -1; + + // find all hor_gaps and find the maximum between them + for (int j = 1; j < size_proj_y; ++j) { + // transition from white to black + if (begin >= 0 && proj_on_yaxis[j - 1] <= 0 && proj_on_yaxis[j] > 0) + end = j; + + // transition from black to white + if (proj_on_yaxis[j - 1] > 0 && proj_on_yaxis[j] <= 0) + begin = j; + + if (begin > 0 && end > 0 && end - begin > gap_hor) { + gap_hor = end - begin; + pos_hor = (end + begin) / 2; + begin = -1; + end = -1; + } + } + + begin = -1, end = -1; + int gap_ver = -1, pos_ver = -1; + + // find all the ver_gaps and find the maximum between them + for (int j = 1; j < size_proj_x; ++j) { + // transition from white to black + if (begin >= 0 && proj_on_xaxis[j - 1] <= 0 && proj_on_xaxis[j] > 0) { + end = j; + } + + // transition from black to white + if (proj_on_xaxis[j - 1] > 0 && proj_on_xaxis[j] <= 0) + begin = j; + + if (begin > 0 && end > 0 && end - begin > gap_ver) { + gap_ver = end - begin; + pos_ver = (end + begin) / 2; + begin = -1; + end = -1; + } + } + + int cut_pos_x = pos_ver, cut_pos_y = pos_hor; + int gap_x = gap_ver, gap_y = gap_hor; + + /** + * 4. Cut the region and make nodes (left,right) or (up,down) + */ + bool cut_hor = false, cut_ver = false; + + // For horizontal cut + const int topHeight = cut_pos_y - (regionRect.top() - old_top); + const QRect topRect(regionRect.left(), regionRect.top(), regionRect.width(), topHeight); + const QRect bottomRect(regionRect.left(), regionRect.top() + topHeight, regionRect.width(), regionRect.height() - topHeight); + + // For vertical Cut + const int leftWidth = cut_pos_x - (regionRect.left() - old_left); + const QRect leftRect(regionRect.left(), regionRect.top(), leftWidth, regionRect.height()); + const QRect rightRect(regionRect.left() + leftWidth, regionRect.top(), regionRect.width() - leftWidth, regionRect.height()); + + if (gap_y >= gap_x && gap_y >= tcy) + cut_hor = true; + else if (gap_y >= gap_x && gap_y <= tcy && gap_x >= tcx) + cut_ver = true; + else if (gap_x >= gap_y && gap_x >= tcx) + cut_ver = true; + else if (gap_x >= gap_y && gap_x <= tcx && gap_y >= tcy) + cut_hor = true; + // no cut possible + else { + // we can now update the node rectangle with the shrinked rectangle + RegionText tmpNode = tree.at(i); + tmpNode.setArea(regionRect); + tree.replace(i, tmpNode); + i++; + continue; + } + + WordsWithCharacters list1, list2; + + // horizontal cut, topRect and bottomRect + if (cut_hor) { + for (const WordWithCharacters &word : list) { + const QRect wordRect = word.area().geometry(pageWidth, pageHeight); + + if (topRect.intersects(wordRect)) + list1.append(word); + else + list2.append(word); + } + + RegionText node1(list1, topRect); + RegionText node2(list2, bottomRect); + + tree.replace(i, node1); + tree.insert(i + 1, node2); + } + + // vertical cut, leftRect and rightRect + else if (cut_ver) { + for (const WordWithCharacters &word : list) { + const QRect wordRect = word.area().geometry(pageWidth, pageHeight); + + if (leftRect.intersects(wordRect)) + list1.append(word); + else + list2.append(word); + } + + RegionText node1(list1, leftRect); + RegionText node2(list2, rightRect); + + tree.replace(i, node1); + tree.insert(i + 1, node2); + } + } + + return tree; +} + +/** + * Add spaces in between words in a line. It reuses the pointers passed in tree and might add new ones. You will need to take care of deleting them if needed + */ +WordsWithCharacters addNecessarySpace(RegionTextList tree, int pageWidth, int pageHeight) +{ + /** + * 1. Call makeAndSortLines before adding spaces in between words in a line + * 2. Now add spaces between every two words in a line + * 3. Finally, extract all the space separated texts from each region and return it + */ + + // Only change the texts under RegionTexts, not the area + for (RegionText &tmpRegion : tree) { + // Step 01 + QList> sortedLines = makeAndSortLines(tmpRegion.text(), pageWidth, pageHeight); + + // Step 02 + for (QPair &sortedLine : sortedLines) { + WordsWithCharacters &list = sortedLine.first; + for (int k = 0; k < list.length(); k++) { + const QRect area1 = list.at(k).area().roundedGeometry(pageWidth, pageHeight); + if (k + 1 >= list.length()) + break; + + const QRect area2 = list.at(k + 1).area().roundedGeometry(pageWidth, pageHeight); + const int space = area2.left() - area1.right(); + + if (space != 0) { + // Make a TinyTextEntity of string space and push it between it and it+1 + const int left = area1.right(); + const int right = area2.left(); + const int top = area2.top() < area1.top() ? area2.top() : area1.top(); + const int bottom = area2.bottom() > area1.bottom() ? area2.bottom() : area1.bottom(); + + const QString spaceStr(QStringLiteral(" ")); + const QRect rect(QPoint(left, top), QPoint(right, bottom)); + const NormalizedRect entRect(rect, pageWidth, pageHeight); + TinyTextEntity *ent1 = new TinyTextEntity(spaceStr, entRect); + TinyTextEntity *ent2 = new TinyTextEntity(spaceStr, entRect); + WordWithCharacters word(ent1, QList() << ent2); + + list.insert(k + 1, word); + + // Skip the space + k++; + } + } + } + + WordsWithCharacters tmpList; + for (const QPair &sortedLine : qAsConst(sortedLines)) { + tmpList += sortedLine.first; + } + tmpRegion.setText(tmpList); + } + + // Step 03 + WordsWithCharacters tmp; + for (const RegionText &tmpRegion : qAsConst(tree)) { + tmp += tmpRegion.text(); + } + return tmp; +} + +/** + * Correct the textOrder, all layout recognition works here + */ +void TextPagePrivate::correctTextOrder() +{ + // m_page->width() and m_page->height() are in pixels at + // 100% zoom level, and thus depend on display DPI. + // To avoid Okular failing on lowDPI displays, + // we scale pageWidth and pageHeight so their sum equals 2000. + const double scalingFactor = 2000.0 / (m_page->width() + m_page->height()); + const int pageWidth = (int)(scalingFactor * m_page->width()); + const int pageHeight = (int)(scalingFactor * m_page->height()); + + TextList characters = m_words; + + /** + * Remove spaces from the text + */ + removeSpace(&characters); + + /** + * Construct words from characters + */ + const QList wordsWithCharacters = makeWordFromCharacters(characters, pageWidth, pageHeight); + + /** + * Make a XY Cut tree for segmentation of the texts + */ + const RegionTextList tree = XYCutForBoundingBoxes(wordsWithCharacters, m_page->boundingBox(), pageWidth, pageHeight); + + /** + * Add spaces to the word + */ + const WordsWithCharacters listWithWordsAndSpaces = addNecessarySpace(tree, pageWidth, pageHeight); + + /** + * Break the words into characters + */ + TextList listOfCharacters; + for (const WordWithCharacters &word : listWithWordsAndSpaces) { + delete word.word; + listOfCharacters.append(word.characters); + } + setWordList(listOfCharacters); +} + +TextEntity::List TextPage::words(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const +{ + if (area && area->isNull()) + return TextEntity::List(); + + TextEntity::List ret; + if (area) { + for (const TinyTextEntity *te : qAsConst(d->m_words)) { + if (b == AnyPixelTextAreaInclusionBehaviour) { + if (area->intersects(te->area)) { + ret.append(new TextEntity(te->text(), new Okular::NormalizedRect(te->area))); + } + } else { + const NormalizedPoint center = te->area.center(); + if (area->contains(center.x, center.y)) { + ret.append(new TextEntity(te->text(), new Okular::NormalizedRect(te->area))); + } + } + } + } else { + for (const TinyTextEntity *te : qAsConst(d->m_words)) { + ret.append(new TextEntity(te->text(), new Okular::NormalizedRect(te->area))); + } + } + return ret; +} + +RegularAreaRect *TextPage::wordAt(const NormalizedPoint &p, QString *word) const +{ + TextList::ConstIterator itBegin = d->m_words.constBegin(), itEnd = d->m_words.constEnd(); + TextList::ConstIterator it = itBegin; + TextList::ConstIterator posIt = itEnd; + for (; it != itEnd; ++it) { + if ((*it)->area.contains(p.x, p.y)) { + posIt = it; + break; + } + } + QString text; + if (posIt != itEnd) { + if ((*posIt)->text().simplified().isEmpty()) { + return nullptr; + } + // Find the first TinyTextEntity of the word + while (posIt != itBegin) { + --posIt; + const QString itText = (*posIt)->text(); + if (itText.right(1).at(0).isSpace()) { + if (itText.endsWith(QLatin1String("-\n"))) { + // Is an hyphenated word + // continue searching the start of the word back + continue; + } + + if (itText == QLatin1String("\n") && posIt != itBegin) { + --posIt; + if ((*posIt)->text().endsWith(QLatin1String("-"))) { + // Is an hyphenated word + // continue searching the start of the word back + continue; + } + ++posIt; + } + + ++posIt; + break; + } + } + RegularAreaRect *ret = new RegularAreaRect(); + for (; posIt != itEnd; ++posIt) { + const QString itText = (*posIt)->text(); + if (itText.simplified().isEmpty()) { + break; + } + + ret->appendShape((*posIt)->area); + text += (*posIt)->text(); + if (itText.right(1).at(0).isSpace()) { + if (!text.endsWith(QLatin1String("-\n"))) { + break; + } + } + } + + if (word) { + *word = text; + } + return ret; + } else { + return nullptr; + } +} diff --git a/core/textpage.h b/core/textpage.h new file mode 100644 index 0000000..58a0e52 --- /dev/null +++ b/core/textpage.h @@ -0,0 +1,211 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymanski * + * * + * 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_TEXTPAGE_H_ +#define _OKULAR_TEXTPAGE_H_ + +#include +#include + +#include "global.h" +#include "okularcore_export.h" + +class QTransform; + +namespace Okular +{ +class NormalizedPoint; +class NormalizedRect; +class Page; +class PagePrivate; +class TextPagePrivate; +class TextSelection; +class RegularAreaRect; + +/*! @class TextEntity + * @short Represents a piece of text on a TextPage, containing its textual representation and its bounding box. + * + * To enable searching and text selection, a generator can give information about the textual + * content of a Page using a TextPage. + * A TextPage is created using TextEntity objects. + * A TextEntity can represent a single character/glyph, a word, a line, or even the whole page. + * + * Ideally, every single glyph is represented by its own TextEntity. + * If the textual representation of a graphical glyph contains more than one character, + * the TextEntity must contain the whole string which represents the glyph. + * + * When the Generator has created the TextPage, and it is added to a Page, + * the text entities are reordered to words, lines, and paragraphs, to optimize search and text selection. + * This way, the Generator does not need to care about the logical order of lines or paragraphs. + * + * @par Text Selection/Highlighting + * A TextEntity is the smallest piece of text, which the user can select, or which can be highlighted. + * That is, if the TextEntity represents a word, only the whole word can be selected. + * It would not be possible to select a single glyph of the word, because its bounding box is not known. + * + * @see TextPage, Generator + */ +class OKULARCORE_EXPORT TextEntity +{ +public: + typedef QList List; + + /** + * Creates a new text entity with the given @p text and the + * given @p area. + */ + TextEntity(const QString &text, NormalizedRect *area); + + /** + * Destroys the text entity. + */ + ~TextEntity(); + + /** + * Returns the text of the text entity. + */ + QString text() const; + + /** + * Returns the bounding area of the text entity. + */ + NormalizedRect *area() const; + + /** + * Returns the transformed area of the text entity. + */ + NormalizedRect transformedArea(const QTransform &matrix) const; + +private: + QString m_text; + NormalizedRect *m_area; + + class Private; + const Private *d; + + Q_DISABLE_COPY(TextEntity) +}; + +/** + * @short Represents the textual information of a Page. Makes search and text selection possible. + * + * A Generator with text support should add a TextPage to every Page. + * For every piece of text, a TextEntity is added, holding the string representation and the bounding box. + * + * Ideally, every TextEntity describes only one glyph. + * A "glyph" is one character in the graphical representation, but the textual representation may consist of multiple characters (like diacritic modifiers). + * + * When the TextPage is added to the Page, the TextEntitys are restructured to optimize text selection. + * + * @see TextEntity + */ +class OKULARCORE_EXPORT TextPage +{ + /// @cond PRIVATE + friend class Page; + friend class PagePrivate; + /// @endcond + +public: + /** + * Defines the behaviour of adding characters to text() result + * @since 0.10 (KDE 4.4) + */ + enum TextAreaInclusionBehaviour { + AnyPixelTextAreaInclusionBehaviour, ///< A character is included into text() result if any pixel of his bounding box is in the given area + CentralPixelTextAreaInclusionBehaviour ///< A character is included into text() result if the central pixel of his bounding box is in the given area + }; + + /** + * Creates a new text page. + */ + TextPage(); + + /** + * Creates a new text page with the given @p words. + */ + explicit TextPage(const TextEntity::List &words); + + /** + * Destroys the text page. + */ + ~TextPage(); + + /** + * Appends the given @p text with the given @p area as new + * @ref TextEntity to the page. + */ + void append(const QString &text, NormalizedRect *area); + + /** + * Returns the bounding rect of the text which matches the following criteria + * or 0 if the search is not successful. + * + * @param searchID An unique id for this search. + * @param query The search text. + * @param direction The direction of the search (@ref SearchDirection) + * @param caseSensitivity If Qt::CaseSensitive, the search is case sensitive; otherwise + * the search is case insensitive. + * @param area If null the search starts at the beginning of the page, otherwise + * right/below the coordinates of the given rect. + */ + RegularAreaRect *findText(int searchID, const QString &query, SearchDirection direction, Qt::CaseSensitivity caseSensitivity, const RegularAreaRect *area); + + /** + * Text extraction function. Looks for text in the given @p area. + * + * @return + * - If @p area points to a valid null area, a null string. + * - If @p area is nullptr, the whole page text as a single string. + * - Otherwise, the text which is included by @p area, as a single string. + * Uses AnyPixelTextAreaInclusionBehaviour + */ + QString text(const RegularAreaRect *area = nullptr) const; + + /** + * Text extraction function. Looks for text in the given @p area. + * + * @return + * - If @p area points to a valid null area, a null string. + * - If @p area is nullptr, the whole page text as a single string. + * - Otherwise, the text which is included by @p area, as a single string. + * @since 0.10 (KDE 4.4) + */ + QString text(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const; + + /** + * Text entity extraction function. Similar to text() but returns + * the words including their bounding rectangles. Note that + * ownership of the contents of the returned list belongs to the + * caller. + * @since 0.14 (KDE 4.8) + */ + TextEntity::List words(const RegularAreaRect *area, TextAreaInclusionBehaviour b) const; + + /** + * Returns the area and text of the word at the given point + * Note that ownership of the returned area belongs to the caller. + * @since 0.15 (KDE 4.9) + */ + RegularAreaRect *wordAt(const NormalizedPoint &p, QString *word = nullptr) const; + + /** + * Returns the rectangular area of the given @p selection. + */ + RegularAreaRect *textArea(TextSelection *selection) const; + +private: + TextPagePrivate *const d; + + Q_DISABLE_COPY(TextPage) +}; + +} + +#endif diff --git a/core/textpage_p.h b/core/textpage_p.h new file mode 100644 index 0000000..2f1cf1a --- /dev/null +++ b/core/textpage_p.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2006 by Tobias Koenig * + * Copyright (C) 2007 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_TEXTPAGE_P_H_ +#define _OKULAR_TEXTPAGE_P_H_ + +#include +#include +#include +#include + +class SearchPoint; + +/** + * Memory-optimized storage of a TextEntity. Stores a string and its bounding box. + * + * When a generator adds a TextEntity to a TextPage, it is internally stored as TinyTextEntity. + * TinyTextEntity is also internally used to get the geometry of text selections and highlight areas. + * + * @see TextEntity + */ +class TinyTextEntity; +class RegionText; + +namespace Okular +{ +class PagePrivate; +typedef QList TextList; + +/** + * Returns whether the two strings match. + * Satisfies the condition that if two strings match then their lengths are equal. + */ +typedef bool (*TextComparisonFunction)(const QStringRef &from, const QStringRef &to); + +/** + * A list of RegionText. It keeps a bunch of TextList with their bounding rectangles + */ +typedef QList RegionTextList; + +class TextPagePrivate +{ +public: + TextPagePrivate(); + ~TextPagePrivate(); + + RegularAreaRect *findTextInternalForward(int searchID, const QString &query, TextComparisonFunction comparer, const TextList::ConstIterator &start, int start_offset, const TextList::ConstIterator &end); + RegularAreaRect *findTextInternalBackward(int searchID, const QString &query, TextComparisonFunction comparer, const TextList::ConstIterator &start, int start_offset, const TextList::ConstIterator &end); + + /** + * Copy a TextList to m_words, the pointers of list are adopted + */ + void setWordList(const TextList &list); + + /** + * Make necessary modifications in the TextList to make the text order correct, so + * that textselection works fine + */ + void correctTextOrder(); + + // variables those can be accessed directly from TextPage + TextList m_words; + QMap m_searchPoints; + Page *m_page; + +private: + RegularAreaRect *searchPointToArea(const SearchPoint *sp); +}; + +} + +#endif diff --git a/core/tile.h b/core/tile.h new file mode 100644 index 0000000..5c4c942 --- /dev/null +++ b/core/tile.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * 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_TILE_H_ +#define _OKULAR_TILE_H_ + +#include "area.h" + +class QPixmap; + +namespace Okular +{ +/** + * This class represents a rectangular portion of a page. + * + * It doesn't take ownership of pixmap + * + * @since 0.16 (KDE 4.10) + */ +class OKULARCORE_EXPORT Tile +{ +public: + Tile(const NormalizedRect &rect, QPixmap *pixmap, bool isValid); + Tile(const Tile &t); + ~Tile(); + + /** + * Location of the tile + */ + NormalizedRect rect() const; + + /** + * Pixmap (may also be NULL) + */ + QPixmap *pixmap() const; + + /** + * True if the pixmap is available and updated + */ + bool isValid() const; + + Tile &operator=(const Tile &other); + +private: + class Private; + Private *d; +}; + +} + +#endif // _OKULAR_TILE_H_ diff --git a/core/tilesmanager.cpp b/core/tilesmanager.cpp new file mode 100644 index 0000000..4ae8628 --- /dev/null +++ b/core/tilesmanager.cpp @@ -0,0 +1,675 @@ +/*************************************************************************** + * Copyright (C) 2012 by Mailson Menezes * + * 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. * + ***************************************************************************/ + +#include "tilesmanager_p.h" + +#include +#include +#include +#include + +#include "tile.h" + +#define TILES_MAXSIZE 2000000 + +using namespace Okular; + +static bool rankedTilesLessThan(TileNode *t1, TileNode *t2) +{ + // Order tiles by its dirty state and then by distance from the viewport. + if (t1->dirty == t2->dirty) + return t1->distance < t2->distance; + + return !t1->dirty; +} + +class TilesManager::Private +{ +public: + Private(); + + bool hasPixmap(const NormalizedRect &rect, const TileNode &tile) const; + void tilesAt(const NormalizedRect &rect, TileNode &tile, QList &result, TileLeaf tileLeaf); + void setPixmap(const QPixmap *pixmap, const NormalizedRect &rect, TileNode &tile, bool isPartialPixmap); + + /** + * Mark @p tile and all its children as dirty + */ + static void markDirty(TileNode &tile); + + /** + * Deletes all tiles, recursively + */ + void deleteTiles(const TileNode &tile); + + void markParentDirty(const TileNode &tile); + void rankTiles(TileNode &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber); + /** + * Since the tile can be large enough to occupy a significant amount of + * space, they may be split in more tiles. This operation is performed + * when the tiles of a certain region is requested and they are bigger + * than an arbitrary value. Only tiles intersecting the desired region + * are split. There's no need to do this for the entire page. + */ + void split(TileNode &tile, const NormalizedRect &rect); + + /** + * Checks whether the tile's size is bigger than an arbitrary value and + * performs the split operation returning true. + * Otherwise it just returns false, without performing any operation. + */ + bool splitBigTiles(TileNode &tile, const NormalizedRect &rect); + + // The page is split in a 4x4 grid of tiles + TileNode tiles[16]; + int width; + int height; + int pageNumber; + qulonglong totalPixels; + Rotation rotation; + NormalizedRect visibleRect; + NormalizedRect requestRect; + int requestWidth; + int requestHeight; +}; + +TilesManager::Private::Private() + : width(0) + , height(0) + , pageNumber(0) + , totalPixels(0) + , rotation(Rotation0) + , requestRect(NormalizedRect()) + , requestWidth(0) + , requestHeight(0) +{ +} + +TilesManager::TilesManager(int pageNumber, int width, int height, Rotation rotation) + : d(new Private) +{ + d->pageNumber = pageNumber; + d->width = width; + d->height = height; + d->rotation = rotation; + + // The page is split in a 4x4 grid of tiles + const double dim = 0.25; + for (int i = 0; i < 16; ++i) { + int x = i % 4; + int y = i / 4; + d->tiles[i].rect = NormalizedRect(x * dim, y * dim, x * dim + dim, y * dim + dim); + } +} + +TilesManager::~TilesManager() +{ + for (const TileNode &tile : d->tiles) + d->deleteTiles(tile); + + delete d; +} + +void TilesManager::Private::deleteTiles(const TileNode &tile) +{ + if (tile.pixmap) { + totalPixels -= tile.pixmap->width() * tile.pixmap->height(); + delete tile.pixmap; + } + + if (tile.nTiles > 0) { + for (int i = 0; i < tile.nTiles; ++i) + deleteTiles(tile.tiles[i]); + + delete[] tile.tiles; + } +} + +void TilesManager::setSize(int width, int height) +{ + if (width == d->width && height == d->height) + return; + + d->width = width; + d->height = height; + + markDirty(); +} + +int TilesManager::width() const +{ + return d->width; +} + +int TilesManager::height() const +{ + return d->height; +} + +void TilesManager::setRotation(Rotation rotation) +{ + if (rotation == d->rotation) + return; + + d->rotation = rotation; +} + +Rotation TilesManager::rotation() const +{ + return d->rotation; +} + +void TilesManager::markDirty() +{ + for (TileNode &tile : d->tiles) { + TilesManager::Private::markDirty(tile); + } +} + +void TilesManager::Private::markDirty(TileNode &tile) +{ + tile.dirty = true; + + for (int i = 0; i < tile.nTiles; ++i) { + markDirty(tile.tiles[i]); + } +} + +void TilesManager::setPixmap(const QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap) +{ + const NormalizedRect rotatedRect = TilesManager::fromRotatedRect(rect, d->rotation); + if (!d->requestRect.isNull()) { + if (!(d->requestRect == rect)) + return; + + if (pixmap) { + // Check whether the pixmap has the same absolute size of the expected + // request. + // If the document is rotated, rotate requestRect back to the original + // rotation before comparing to pixmap's size. This is to avoid + // conversion issues. The pixmap request was made using an unrotated + // rect. + QSize pixmapSize = pixmap->size(); + int w = width(); + int h = height(); + if (d->rotation % 2) { + qSwap(w, h); + pixmapSize.transpose(); + } + + if (rotatedRect.geometry(w, h).size() != pixmapSize) + return; + } + + d->requestRect = NormalizedRect(); + } + + for (TileNode &tile : d->tiles) { + d->setPixmap(pixmap, rotatedRect, tile, isPartialPixmap); + } +} + +void TilesManager::Private::setPixmap(const QPixmap *pixmap, const NormalizedRect &rect, TileNode &tile, bool isPartialPixmap) +{ + QRect pixmapRect = TilesManager::toRotatedRect(rect, rotation).geometry(width, height); + + // Exclude tiles outside the viewport + if (!tile.rect.intersects(rect)) + return; + + // if the tile is not entirely within the viewport (the tile intersects an + // edged of the viewport), attempt to set the pixmap in the children tiles + if (!((tile.rect & rect) == tile.rect)) { + // paint children tiles + if (tile.nTiles > 0) { + for (int i = 0; i < tile.nTiles; ++i) + setPixmap(pixmap, rect, tile.tiles[i], isPartialPixmap); + + delete tile.pixmap; + tile.pixmap = nullptr; + } + + return; + } + + // the tile lies entirely within the viewport + if (tile.nTiles == 0) { + tile.dirty = isPartialPixmap; + + // check whether the tile size is big and split it if necessary + if (!splitBigTiles(tile, rect)) { + if (tile.pixmap) { + totalPixels -= tile.pixmap->width() * tile.pixmap->height(); + delete tile.pixmap; + } + tile.rotation = rotation; + if (pixmap) { + const NormalizedRect rotatedRect = TilesManager::toRotatedRect(tile.rect, rotation); + tile.pixmap = new QPixmap(pixmap->copy(rotatedRect.geometry(width, height).translated(-pixmapRect.topLeft()))); + totalPixels += tile.pixmap->width() * tile.pixmap->height(); + } else { + tile.pixmap = nullptr; + } + } else { + if (tile.pixmap) { + totalPixels -= tile.pixmap->width() * tile.pixmap->height(); + delete tile.pixmap; + tile.pixmap = nullptr; + } + + for (int i = 0; i < tile.nTiles; ++i) + setPixmap(pixmap, rect, tile.tiles[i], isPartialPixmap); + } + } else { + QRect tileRect = tile.rect.geometry(width, height); + // sets the pixmap of the children tiles. if the tile's size is too + // small, discards the children tiles and use the current one + if (tileRect.width() * tileRect.height() >= TILES_MAXSIZE) { + tile.dirty = isPartialPixmap; + if (tile.pixmap) { + totalPixels -= tile.pixmap->width() * tile.pixmap->height(); + delete tile.pixmap; + tile.pixmap = nullptr; + } + + for (int i = 0; i < tile.nTiles; ++i) + setPixmap(pixmap, rect, tile.tiles[i], isPartialPixmap); + } else { + // remove children tiles + for (int i = 0; i < tile.nTiles; ++i) { + deleteTiles(tile.tiles[i]); + tile.tiles[i].pixmap = nullptr; + } + + delete[] tile.tiles; + tile.tiles = nullptr; + tile.nTiles = 0; + + // paint tile + if (tile.pixmap) { + totalPixels -= tile.pixmap->width() * tile.pixmap->height(); + delete tile.pixmap; + } + tile.rotation = rotation; + if (pixmap) { + const NormalizedRect rotatedRect = TilesManager::toRotatedRect(tile.rect, rotation); + tile.pixmap = new QPixmap(pixmap->copy(rotatedRect.geometry(width, height).translated(-pixmapRect.topLeft()))); + totalPixels += tile.pixmap->width() * tile.pixmap->height(); + } else { + tile.pixmap = nullptr; + } + tile.dirty = isPartialPixmap; + } + } +} + +bool TilesManager::hasPixmap(const NormalizedRect &rect) +{ + NormalizedRect rotatedRect = fromRotatedRect(rect, d->rotation); + for (const TileNode &tile : qAsConst(d->tiles)) { + if (!d->hasPixmap(rotatedRect, tile)) + return false; + } + + return true; +} + +bool TilesManager::Private::hasPixmap(const NormalizedRect &rect, const TileNode &tile) const +{ + const NormalizedRect rectIntersection = tile.rect & rect; + if (rectIntersection.width() <= 0 || rectIntersection.height() <= 0) + return true; + + if (tile.nTiles == 0) + return tile.isValid(); + + // all children tiles are clean. doesn't need to go deeper + if (!tile.dirty) + return true; + + for (int i = 0; i < tile.nTiles; ++i) { + if (!hasPixmap(rect, tile.tiles[i])) + return false; + } + + return true; +} + +QList TilesManager::tilesAt(const NormalizedRect &rect, TileLeaf tileLeaf) +{ + QList result; + + NormalizedRect rotatedRect = fromRotatedRect(rect, d->rotation); + for (TileNode &tile : d->tiles) { + d->tilesAt(rotatedRect, tile, result, tileLeaf); + } + + return result; +} + +void TilesManager::Private::tilesAt(const NormalizedRect &rect, TileNode &tile, QList &result, TileLeaf tileLeaf) +{ + if (!tile.rect.intersects(rect)) + return; + + // split big tiles before the requests are made, otherwise we would end up + // requesting huge areas unnecessarily + splitBigTiles(tile, rect); + + if ((tileLeaf == TerminalTile && tile.nTiles == 0) || (tileLeaf == PixmapTile && tile.pixmap)) { + NormalizedRect rotatedRect; + if (rotation != Rotation0) + rotatedRect = TilesManager::toRotatedRect(tile.rect, rotation); + else + rotatedRect = tile.rect; + + if (tile.pixmap && tileLeaf == PixmapTile && tile.rotation != rotation) { + // Lazy tiles rotation + int angleToRotate = (rotation - tile.rotation) * 90; + int xOffset = 0, yOffset = 0; + int w = 0, h = 0; + switch (angleToRotate) { + case 0: + xOffset = 0; + yOffset = 0; + w = tile.pixmap->width(); + h = tile.pixmap->height(); + break; + case 90: + case -270: + xOffset = 0; + yOffset = -tile.pixmap->height(); + w = tile.pixmap->height(); + h = tile.pixmap->width(); + break; + case 180: + case -180: + xOffset = -tile.pixmap->width(); + yOffset = -tile.pixmap->height(); + w = tile.pixmap->width(); + h = tile.pixmap->height(); + break; + case 270: + case -90: + xOffset = -tile.pixmap->width(); + yOffset = 0; + w = tile.pixmap->height(); + h = tile.pixmap->width(); + break; + } + QPixmap *rotatedPixmap = new QPixmap(w, h); + QPainter p(rotatedPixmap); + p.rotate(angleToRotate); + p.translate(xOffset, yOffset); + p.drawPixmap(0, 0, *tile.pixmap); + p.end(); + + delete tile.pixmap; + tile.pixmap = rotatedPixmap; + tile.rotation = rotation; + } + result.append(Tile(rotatedRect, tile.pixmap, tile.isValid())); + } else { + for (int i = 0; i < tile.nTiles; ++i) + tilesAt(rect, tile.tiles[i], result, tileLeaf); + } +} + +qulonglong TilesManager::totalMemory() const +{ + return 4 * d->totalPixels; +} + +void TilesManager::cleanupPixmapMemory(qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber) +{ + QList rankedTiles; + for (TileNode &tile : d->tiles) { + d->rankTiles(tile, rankedTiles, visibleRect, visiblePageNumber); + } + std::sort(rankedTiles.begin(), rankedTiles.end(), rankedTilesLessThan); + + while (numberOfBytes > 0 && !rankedTiles.isEmpty()) { + TileNode *tile = rankedTiles.takeLast(); + if (!tile->pixmap) + continue; + + // do not evict visible pixmaps + if (tile->rect.intersects(visibleRect)) + continue; + + qulonglong pixels = tile->pixmap->width() * tile->pixmap->height(); + d->totalPixels -= pixels; + if (numberOfBytes < 4 * pixels) + numberOfBytes = 0; + else + numberOfBytes -= 4 * pixels; + + delete tile->pixmap; + tile->pixmap = nullptr; + + d->markParentDirty(*tile); + } +} + +void TilesManager::Private::markParentDirty(const TileNode &tile) +{ + if (!tile.parent) + return; + + if (!tile.parent->dirty) { + tile.parent->dirty = true; + markParentDirty(*tile.parent); + } +} + +void TilesManager::Private::rankTiles(TileNode &tile, QList &rankedTiles, const NormalizedRect &visibleRect, int visiblePageNumber) +{ + // If the page is visible, visibleRect is not null. + // Otherwise we use the number of one of the visible pages to calculate the + // distance. + // Note that the current page may be visible and yet its pageNumber is + // different from visiblePageNumber. Since we only use this value on hidden + // pages, any visible page number will fit. + if (visibleRect.isNull() && visiblePageNumber < 0) + return; + + if (tile.pixmap) { + // Update distance + if (!visibleRect.isNull()) { + NormalizedPoint viewportCenter = visibleRect.center(); + NormalizedPoint tileCenter = tile.rect.center(); + // Manhattan distance. It's a good and fast approximation. + tile.distance = qAbs(viewportCenter.x - tileCenter.x) + qAbs(viewportCenter.y - tileCenter.y); + } else { + // For non visible pages only the vertical distance is used + if (pageNumber < visiblePageNumber) + tile.distance = 1 - tile.rect.bottom; + else + tile.distance = tile.rect.top; + } + rankedTiles.append(&tile); + } else { + for (int i = 0; i < tile.nTiles; ++i) { + rankTiles(tile.tiles[i], rankedTiles, visibleRect, visiblePageNumber); + } + } +} + +bool TilesManager::isRequesting(const NormalizedRect &rect, int pageWidth, int pageHeight) const +{ + return rect == d->requestRect && pageWidth == d->requestWidth && pageHeight == d->requestHeight; +} + +void TilesManager::setRequest(const NormalizedRect &rect, int pageWidth, int pageHeight) +{ + d->requestRect = rect; + d->requestWidth = pageWidth; + d->requestHeight = pageHeight; +} + +bool TilesManager::Private::splitBigTiles(TileNode &tile, const NormalizedRect &rect) +{ + QRect tileRect = tile.rect.geometry(width, height); + if (tileRect.width() * tileRect.height() < TILES_MAXSIZE) + return false; + + split(tile, rect); + return true; +} + +void TilesManager::Private::split(TileNode &tile, const NormalizedRect &rect) +{ + if (tile.nTiles != 0) + return; + + if (rect.isNull() || !tile.rect.intersects(rect)) + return; + + tile.nTiles = 4; + tile.tiles = new TileNode[4]; + double hCenter = (tile.rect.left + tile.rect.right) / 2; + double vCenter = (tile.rect.top + tile.rect.bottom) / 2; + + tile.tiles[0].rect = NormalizedRect(tile.rect.left, tile.rect.top, hCenter, vCenter); + tile.tiles[1].rect = NormalizedRect(hCenter, tile.rect.top, tile.rect.right, vCenter); + tile.tiles[2].rect = NormalizedRect(tile.rect.left, vCenter, hCenter, tile.rect.bottom); + tile.tiles[3].rect = NormalizedRect(hCenter, vCenter, tile.rect.right, tile.rect.bottom); + + for (int i = 0; i < tile.nTiles; ++i) { + tile.tiles[i].parent = &tile; + splitBigTiles(tile.tiles[i], rect); + } +} + +NormalizedRect TilesManager::fromRotatedRect(const NormalizedRect &rect, Rotation rotation) +{ + if (rotation == Rotation0) + return rect; + + NormalizedRect newRect; + switch (rotation) { + case Rotation90: + newRect = NormalizedRect(rect.top, 1 - rect.right, rect.bottom, 1 - rect.left); + break; + case Rotation180: + newRect = NormalizedRect(1 - rect.right, 1 - rect.bottom, 1 - rect.left, 1 - rect.top); + break; + case Rotation270: + newRect = NormalizedRect(1 - rect.bottom, rect.left, 1 - rect.top, rect.right); + break; + default: + newRect = rect; + break; + } + + return newRect; +} + +NormalizedRect TilesManager::toRotatedRect(const NormalizedRect &rect, Rotation rotation) +{ + if (rotation == Rotation0) + return rect; + + NormalizedRect newRect; + switch (rotation) { + case Rotation90: + newRect = NormalizedRect(1 - rect.bottom, rect.left, 1 - rect.top, rect.right); + break; + case Rotation180: + newRect = NormalizedRect(1 - rect.right, 1 - rect.bottom, 1 - rect.left, 1 - rect.top); + break; + case Rotation270: + newRect = NormalizedRect(rect.top, 1 - rect.right, rect.bottom, 1 - rect.left); + break; + default: + newRect = rect; + break; + } + + return newRect; +} + +TileNode::TileNode() + : pixmap(nullptr) + , rotation(Rotation0) + , dirty(true) + , distance(-1) + , tiles(nullptr) + , nTiles(0) + , parent(nullptr) +{ +} + +bool TileNode::isValid() const +{ + return pixmap && !dirty; +} + +class Tile::Private +{ +public: + Private(); + + NormalizedRect rect; + QPixmap *pixmap; + bool isValid; +}; + +Tile::Private::Private() + : pixmap(nullptr) + , isValid(false) +{ +} + +Tile::Tile(const NormalizedRect &rect, QPixmap *pixmap, bool isValid) + : d(new Tile::Private) +{ + d->rect = rect; + d->pixmap = pixmap; + d->isValid = isValid; +} + +Tile::Tile(const Tile &t) + : d(new Tile::Private) +{ + d->rect = t.d->rect; + d->pixmap = t.d->pixmap; + d->isValid = t.d->isValid; +} + +Tile &Tile::operator=(const Tile &other) +{ + if (this == &other) + return *this; + + d->rect = other.d->rect; + d->pixmap = other.d->pixmap; + d->isValid = other.d->isValid; + + return *this; +} + +Tile::~Tile() +{ + delete d; +} + +NormalizedRect Tile::rect() const +{ + return d->rect; +} + +QPixmap *Tile::pixmap() const +{ + return d->pixmap; +} + +bool Tile::isValid() const +{ + return d->isValid; +} diff --git a/core/tilesmanager_p.h b/core/tilesmanager_p.h new file mode 100644 index 0000000..ac36bb5 --- /dev/null +++ b/core/tilesmanager_p.h @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2012 by Mailson Menezes * + * 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_TILES_MANAGER_P_H_ +#define _OKULAR_TILES_MANAGER_P_H_ + +#include "area.h" +#include "okularcore_export.h" + +class QPixmap; + +namespace Okular +{ +class Tile; + +/** + * Node in the quadtree structure used by the tiles manager to store tiles. + * + * Except for the first level, the tiles manager stores tiles in a quadtree + * structure. + * Each node stores the pixmap of a tile and its location on the page. + * There's a limit on the size of the pixmaps (TILES_MAXSIZE, defined in + * tilesmanager.cpp), and tiles that are bigger than that value are split into + * four children tiles, which are stored as children of the original tile. + * If children tiles are still too big, they are recursively split again. + * If the zoom level changes and a big tile goes below the limit, it is merged + * back into a leaf tile. + */ +class TileNode +{ +public: + TileNode(); + + bool isValid() const; + + /** + * Location on the page in normalized coords + */ + NormalizedRect rect; + + /** + * Associated pixmap or NULL if not present + * + * For each node, it is guaranteed that there's no more than one pixmap + * along the path from the root to the node itself. + * In fact, it is very frequent that a leaf node has no pixmap and one + * of its ancestors has. Such a situation shows, for example, when the + * parent tile still has a dirty tile from a previous lower zoom level. + */ + QPixmap *pixmap; + + /** + * Rotation of this individual tile. + * + * A rotation to the page does not immediately rotates the pixmaps in + * cache. This operation happens when pixmaps are going to be used. + */ + Rotation rotation; + + /** + * Whether the tile needs to be repainted (after a zoom or rotation) + * If a tile doesn't have a pixmap but all its children are updated + * (dirty = false), the parent tile is also considered updated. + */ + bool dirty; + + /** + * Distance between the tile and the viewport. + * This is used by the evicting algorithm. + */ + double distance; + + /** + * Children tiles + * When a tile is split into multiple tiles, they're added as children. + * nTiles can be either 0 (in leaf tiles) or 4 (in split tiles). + */ + TileNode *tiles; + int nTiles; + TileNode *parent; +}; + +/** + * @short Tiles management + * + * This class has direct access to all tiles and handles how they should be + * stored, deleted and retrieved. Each tiles manager only handles one page. + * + * The tiles manager is a tree of tiles. At first the page is divided in a 4x4 + * grid of 16 tiles. Then each of these tiles can be recursively split in 4 + * subtiles so that we keep the size of each pixmap inside a safe interval. + */ +class TilesManager +{ +public: + enum TileLeaf { + TerminalTile, ///< Return tiles without children + PixmapTile ///< Return only tiles with pixmap + }; + + TilesManager(int pageNumber, int width, int height, Rotation rotation = Rotation0); + ~TilesManager(); + + TilesManager(const TilesManager &) = delete; + TilesManager &operator=(const TilesManager &) = delete; + + /** + * Sets the pixmap of the tiles covered by @p rect (which represents + * the location of @p pixmap on the page). + * @p pixmap may cover an area which contains multiple tiles. So each + * tile we get a cropped part of the @p pixmap. + * + * Also it checks the dimensions of the given parameters against the + * current request as to avoid setting pixmaps of late requests. + */ + void setPixmap(const QPixmap *pixmap, const NormalizedRect &rect, bool isPartialPixmap); + + /** + * Checks whether all tiles intersecting with @p rect are available. + * Returns false if at least one tile needs to be repainted (the tile + * is dirty). + */ + bool hasPixmap(const NormalizedRect &rect); + + /** + * Returns a list of all tiles intersecting with @p rect. + * + * As to avoid requests of big areas, each traversed tile is checked + * for its size and split if necessary. + * + * @param rect The normalized rectangular area + * @param tileLeaf Indicate the type of tile to return + */ + QList tilesAt(const NormalizedRect &rect, TileLeaf tileLeaf); + + /** + * The total memory consumed by the tiles manager + */ + qulonglong totalMemory() const; + + /** + * Removes at least @p numberOfBytes bytes worth of tiles (least ranked + * tiles are removed first). + * Set @p visibleRect to the visible region of the page. Set a + * @p visiblePageNumber if the current page is not visible. + * Visible tiles are not discarded. + */ + void cleanupPixmapMemory(qulonglong numberOfBytes, const NormalizedRect &visibleRect, int visiblePageNumber); + + /** + * Checks whether a given region has already been requested + */ + bool isRequesting(const NormalizedRect &rect, int pageWidth, int pageHeight) const; + + /** + * Sets a region to be requested so the tiles manager knows which + * pixmaps to expect and discard those not useful anymore (late pixmaps) + */ + void setRequest(const NormalizedRect &rect, int pageWidth, int pageHeight); + + /** + * Inform the new size of the page and mark all tiles to repaint + */ + void setSize(int width, int height); + + /** + * Gets the width of the page in tiles manager + */ + int width() const; + + /** + * Gets the height of the page in tiles manager + */ + int height() const; + + /** + * Inform the new rotation of the page + */ + void setRotation(Rotation rotation); + Rotation rotation() const; + + /** + * Mark all tiles as dirty + */ + void markDirty(); + + /** + * Returns a rotated NormalizedRect given a @p rotation + */ + static NormalizedRect toRotatedRect(const NormalizedRect &rect, Rotation rotation); + + /** + * Returns a non rotated version of @p rect, which is rotated by @p rotation + */ + static NormalizedRect fromRotatedRect(const NormalizedRect &rect, Rotation rotation); + +private: + class Private; + Private *const d; + friend class Private; +}; + +} + +#endif // _OKULAR_TILES_MANAGER_P_H_ diff --git a/core/utils.cpp b/core/utils.cpp new file mode 100644 index 0000000..0111ac7 --- /dev/null +++ b/core/utils.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi Toscano * + * 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. * + ***************************************************************************/ + +#include "utils.h" +#include "utils_p.h" + +#include "debug_p.h" +#include "settings_core.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace Okular; + +QRect Utils::rotateRect(const QRect &source, int width, int height, int orientation) // clazy:exclude=function-args-by-value TODO remove the & when we do a BIC change elsewhere +{ + QRect ret; + + // adapt the coordinates of the boxes to the rotation + switch (orientation) { + case 1: + ret = QRect(width - source.y() - source.height(), source.x(), source.height(), source.width()); + break; + case 2: + ret = QRect(width - source.x() - source.width(), height - source.y() - source.height(), source.width(), source.height()); + break; + case 3: + ret = QRect(source.y(), height - source.x() - source.width(), source.height(), source.width()); + break; + case 0: // no modifications + default: // other cases + ret = source; + } + + return ret; +} + +QSizeF Utils::realDpi(QWidget *widgetOnScreen) +{ + const QScreen *screen = widgetOnScreen && widgetOnScreen->window() && widgetOnScreen->window()->windowHandle() ? widgetOnScreen->window()->windowHandle()->screen() : qGuiApp->primaryScreen(); + + if (screen) { + const QSizeF res(screen->physicalDotsPerInchX(), screen->physicalDotsPerInchY()); + if (res.width() > 0 && res.height() > 0) { + if (qAbs(res.width() - res.height()) / qMin(res.height(), res.width()) < 0.05) { + return res; + } else { + qCDebug(OkularCoreDebug) << "QScreen calculation returned a non square dpi." << res << ". Falling back"; + } + } + } + return QSizeF(72, 72); +} + +inline static bool isPaperColor(QRgb argb, QRgb paperColor) +{ + return (argb & 0xFFFFFF) == (paperColor & 0xFFFFFF); // ignore alpha +} + +NormalizedRect Utils::imageBoundingBox(const QImage *image) +{ + if (!image) + return NormalizedRect(); + + const int width = image->width(); + const int height = image->height(); + const QRgb paperColor = SettingsCore::paperColor().rgb(); + int left, top, bottom, right, x, y; + +#ifdef BBOX_DEBUG + QTime time; + time.start(); +#endif + + // Scan pixels for top non-white + for (top = 0; top < height; ++top) + for (x = 0; x < width; ++x) + if (!isPaperColor(image->pixel(x, top), paperColor)) + goto got_top; + return NormalizedRect(0, 0, 0, 0); // the image is blank +got_top: + left = right = x; + + // Scan pixels for bottom non-white + for (bottom = height - 1; bottom >= top; --bottom) + for (x = width - 1; x >= 0; --x) + if (!isPaperColor(image->pixel(x, bottom), paperColor)) + goto got_bottom; + Q_ASSERT(0); // image changed?! +got_bottom: + if (x < left) + left = x; + if (x > right) + right = x; + + // Scan for leftmost and rightmost (we already found some bounds on these): + for (y = top; y <= bottom && (left > 0 || right < width - 1); ++y) { + for (x = 0; x < left; ++x) + if (!isPaperColor(image->pixel(x, y), paperColor)) + left = x; + for (x = width - 1; x > right + 1; --x) + if (!isPaperColor(image->pixel(x, y), paperColor)) + right = x; + } + + NormalizedRect bbox(QRect(left, top, (right - left + 1), (bottom - top + 1)), image->width(), image->height()); + +#ifdef BBOX_DEBUG + qCDebug(OkularCoreDebug) << "Computed bounding box" << bbox << "in" << time.elapsed() << "ms"; +#endif + + return bbox; +} + +void Okular::copyQIODevice(QIODevice *from, QIODevice *to) +{ + QByteArray buffer(65536, '\0'); + qint64 read = 0; + qint64 written = 0; + while ((read = from->read(buffer.data(), buffer.size())) > 0) { + written = to->write(buffer.constData(), read); + if (read != written) + break; + } +} + +QTransform Okular::buildRotationMatrix(Rotation rotation) +{ + QTransform matrix; + matrix.rotate((int)rotation * 90); + + switch (rotation) { + case Rotation90: + matrix.translate(0, -1); + break; + case Rotation180: + matrix.translate(-1, -1); + break; + case Rotation270: + matrix.translate(-1, 0); + break; + default:; + } + + return matrix; +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/utils.h b/core/utils.h new file mode 100644 index 0000000..5cd78c5 --- /dev/null +++ b/core/utils.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi 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_UTILS_H_ +#define _OKULAR_UTILS_H_ + +#include "area.h" +#include "okularcore_export.h" + +class QRect; +class QImage; +class QWidget; + +namespace Okular +{ +/** + * @short General utility functions. + * + * This class contains some static functions of general utility. + */ +class OKULARCORE_EXPORT Utils +{ +public: + /** + * Rotate the rect \p source in the area \p width x \p height with the + * specified \p orientation . + */ + static QRect rotateRect(const QRect &source, int width, int height, int orientation); // TODO remove the & when we do a BIC change elsewhere + + /** + * Return the real DPI of the display containing given widget + * + * On X11, it can indicate the real horizontal DPI value without any Xrdb + * setting. Otherwise, returns the same as realDpiX/Y(), + * + * @since 0.19 (KDE 4.13) + */ + static QSizeF realDpi(QWidget *widgetOnScreen); + + /** + * Compute the smallest rectangle that contains all non-white pixels in image), + * in normalized [0,1] coordinates. + * + * @since 0.7 (KDE 4.1) + */ + static NormalizedRect imageBoundingBox(const QImage *image); +}; + +} + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/core/utils_p.h b/core/utils_p.h new file mode 100644 index 0000000..fb6feac --- /dev/null +++ b/core/utils_p.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * 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_UTILS_P_H_ +#define _OKULAR_UTILS_P_H_ + +class QIODevice; + +namespace Okular +{ +void copyQIODevice(QIODevice *from, QIODevice *to); + +/** + * Return a rotation matrix corresponding to the @p rotation enumeration. + */ +QTransform buildRotationMatrix(Rotation rotation); + +} + +#endif diff --git a/core/view.cpp b/core/view.cpp new file mode 100644 index 0000000..caea83a --- /dev/null +++ b/core/view.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "view.h" +#include "view_p.h" + +// local includes +#include "document_p.h" + +using namespace Okular; + +ViewPrivate::ViewPrivate() + : document(nullptr) +{ +} + +ViewPrivate::~ViewPrivate() +{ +} + +View::View(const QString &name) + : d_ptr(new ViewPrivate()) +{ + d_ptr->name = name; +} + +View::~View() +{ + if (d_ptr->document) { + d_ptr->document->m_views.remove(this); + } + + delete d_ptr; +} + +Document *View::viewDocument() const +{ + return d_ptr->document ? d_ptr->document->m_parent : nullptr; +} + +QString View::name() const +{ + return d_ptr->name; +} + +bool View::supportsCapability(View::ViewCapability capability) const +{ + Q_UNUSED(capability) + return false; +} + +View::CapabilityFlags View::capabilityFlags(View::ViewCapability capability) const +{ + Q_UNUSED(capability) + return NoFlag; +} + +QVariant View::capability(View::ViewCapability capability) const +{ + Q_UNUSED(capability) + return QVariant(); +} + +void View::setCapability(View::ViewCapability capability, const QVariant &option) +{ + Q_UNUSED(capability) + Q_UNUSED(option) +} diff --git a/core/view.h b/core/view.h new file mode 100644 index 0000000..6e6d3ad --- /dev/null +++ b/core/view.h @@ -0,0 +1,114 @@ +/*************************************************************************** + * 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_VIEW_H +#define OKULAR_VIEW_H + +#include "okularcore_export.h" +#include +class QString; +class QVariant; + +namespace Okular +{ +class Document; +class DocumentPrivate; +class ViewPrivate; + +/** + * @short View on the document + * + * The View class represents a "view" on a document. + * A view can be registered with only a document at a time. + * + * @since 0.7 (KDE 4.1) + */ +class OKULARCORE_EXPORT View +{ + /// @cond PRIVATE + friend class Document; + friend class DocumentPrivate; + /// @endcond + +public: + /** + * The capabilities of a view + */ + enum ViewCapability { + Zoom, ///< Possibility to get/set the zoom of the view + ZoomModality, ///< Possibility to get/set the zoom mode of the view + Continuous, ///< Possibility to toggle continuous mode @since 1.9 + ViewModeModality, ///< Possibility to get/set the view mode @since 1.9 + TrimMargins ///< Possibility to toggle trim-margins mode @since 1.9 + }; + + /** + * The access type of a capability + */ + enum CapabilityFlag { + NoFlag = 0, + CapabilityRead = 0x01, ///< Possibility to read a capability + CapabilityWrite = 0x02, ///< Possibility to write a capability + CapabilitySerializable = 0x04 ///< The capability is suitable for being serialized/deserialized + }; + Q_DECLARE_FLAGS(CapabilityFlags, CapabilityFlag) + + virtual ~View(); + + /** + * Return the document which this view is associated to, + * or null if it is not associated with any document. + */ + Document *viewDocument() const; + + /** + * Return the name of this view. + */ + QString name() const; + + /** + * Query whether the view support the specified @p capability. + */ + virtual bool supportsCapability(ViewCapability capability) const; + + /** + * Query the flags for the specified @p capability. + */ + virtual CapabilityFlags capabilityFlags(ViewCapability capability) const; + + /** + * Query the value of the specified @p capability. + */ + virtual QVariant capability(ViewCapability capability) const; + + /** + * Sets a new value for the specified @p capability. + */ + virtual void setCapability(ViewCapability capability, const QVariant &option); + +protected: + /** + * Construct a new view with the specified @p name. + */ + View(const QString &name); + + /// @cond PRIVATE + Q_DECLARE_PRIVATE(View) + ViewPrivate *d_ptr; + /// @endcond + +private: + Q_DISABLE_COPY(View) +}; + +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(Okular::View::CapabilityFlags) + +#endif diff --git a/core/view_p.h b/core/view_p.h new file mode 100644 index 0000000..d5be94d --- /dev/null +++ b/core/view_p.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * 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_VIEW_P_H +#define OKULAR_VIEW_P_H + +#include +#include + +namespace Okular +{ +class DocumentPrivate; +class View; + +class ViewPrivate +{ +public: + ViewPrivate(); + virtual ~ViewPrivate(); + + ViewPrivate(const ViewPrivate &) = delete; + ViewPrivate &operator=(const ViewPrivate &) = delete; + + QString name; + DocumentPrivate *document; +}; + +} + +#endif diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 0000000..2e4fab6 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,5 @@ +########### install files ############### +# +# +kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR okular) +kdoctools_create_manpage(man-okular.1.docbook 1 INSTALL_DESTINATION ${KDE_INSTALL_MANDIR}) diff --git a/doc/annotation-properties.png b/doc/annotation-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..873e631e6771b2c82db88c26151c5b4d827a326a GIT binary patch literal 15095 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 a&Z%9zm92TRQpVrEuc8ew`qg^Q5&sJ+827dS literal 0 HcmV?d00001 diff --git a/doc/annotations.png b/doc/annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..ae4c5d9e37979946d6258b3a0e23e02104a89350 GIT binary patch literal 42525 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
(O zlP$OLQsH>e9bea5pEX7_wokk5+Bp^an)0 zdd67>#ee$vWmxh?A$I-+33Sfb*pBBC_TYNYb`d0N6;U(%7ju^4dr+6_7-27Z(WSof zg03ppF$krx$2+VXR4UtFB!VnF82pJ9fiC94E|e(bze=n?3Wq{to!~3ykx}*e=t`X< z5n@L+HD4m^v4wAHbga)MPQA_49~+U+zM1&ACOl)q^8g6)_#9a;JxO*6E4_E`+s}~k z>wO`TG6tLM)+GgxDR0%dg+K@Ep|z*XsdjKWgvNx?p0XY7)UUjabky~QB}v26t)7I7 z)&9AqTP5Ak^aGn`x0){{_Q+KWLeI?k<(_CxPt{$Se$VckN^PN8&4y)lVZK}JdVM&t zvR~&dG_bg!$e&{r^*y3HQTO-zxq(!J>X!mU&@xrxp6l<9`>7b(*~2kY90$yI#+F>K z7;K)tfDehAJV1)p9tfogOeNKB4BvbUUJuZb)UW?~r`&R}Ahl5o`!+Snk2$&`Juyj7 z73g_^@4O9_uRu3`=4ug{?t|6nAY?7rY~omjOmdD?Us0ERSq)P_vn=qZ5xel^=nl=Z zi&Pd!?$30B(?8jsO`|?N<|^Vz50(@uMXn%tvtOT0($IY7>;9!@mkrdoDFfP{2Qvra z=Jg+=Ci?VS55+LYqetG{rY$XJ-nS4ZTla26fAV@*GHYy3D|Dxvby}BpRPS{$sy!9o zSO_D225ri{Vq>y<>~79+7YjACeYdC4K8a6%wOV5^#Y8>->Qs=@3V+GBnU-e$(&~aX zf-145)l{?G!Lhw@4=#X}E&)Fsbp|@}v^giqq-v)!wV68WKgZ=`Wzo&w(7x^gO-3&h zO{5+H`WZsEyVKg`+a1nqSrP2b;8fwq#9EybD<10@{>h{+bZ_+UTd;0}s1fd7%BM*= z!Sp}ll8^L{YD=ImKA%lKEc(Sfg3>`a4SwGUe+^DXhqbtfetl+XE*!>g?bLFgM@R5q z6^8bb+WYPPFrdd7`J&j?#JH#G&$y0r8vBl%pOdRL;;r)p%vW2)?zI!yu7m`V?$e38 z2f^YA{e=I=SHT{M=Z-gWSsej8cpGRh2$aw7dw9Ko@4B7cJ8YOqUbS*+nIVUkNa(+a zs>C*3w<@oVg2s-(ehfUcM!K?)4_P`r7g^s5lQ44C_w8qpa72ES3VW=nyLo#u+Z5O# z#Y&UDhAx^(kpSgYP-lkU{x9&Op>=K_^dkf3W)2Wv+oj%4=|Y=Y$WhzUD=eI2%pVwL zb-%wwSRwQd-{Ll#2{b-uJu@7~A1l|X*w1_FnrchUm0nx%{;8Azt&My(NGe+2lUYy} zDyjx-p_3&1KDT zY5nU*tQa+D0$2+GfKY9kt`y{38o4})pntY*91|2(D0dOK!9v0~a=L|4`$KIk6;zXo zdwHPUZ2QiM7mzb`)g8&qtWA62^ZW&8#;@r9ezb2v`S04OL$}TAjZ8a?PEIS|xle<5 zFb&>T_|tf>Lox^E(zf|arwTl@Yl-@^t@l%Ld7d*zz=CHtImg*9JA>G4P-ZWzDfj4C zJh;oAqj0_?wW3`W@8oZ2#e+G(sSv?3Vh-@c{~fS9NhC_&tRjSuOv0+@&DG`NJbd5Zb~9QxWjP}^ZSsb#wiM@&>p&l@)9ngdAIf;+ zIS^1|TK!{6J(VwGF5NFVLvC6EdqmWz_K5)_=vePmmQpTmRW`+C+MJRyQsl)rP&`e; zmDE;QDa+!ejn;9LD7vj1?UOMDFT2BTTBW*C_Ov)`IUcm)sfAg=W8kAGcARdM{s`lG zbv(x_Z>?-9I-PQ?Z{$Z-25&oY)CQ}eg{j0949_#g-2XZWHh3`><7g)0-eMzk>zd3J zN1h%+X*8h(yxX$PCWpd_IX=2W+f~hE$yXk_iZNfV>_G&Z5{-~Q5$zO~AvAk<4jytY z^`<}lv~DQ^D+#c9UR&wYsj>G(u*0M$Q0v74+nbB~QF6{V7W-gT@khnIC@NehYPIy^ z=wT|GrtU;-`8_zE^JqN<)PJ*_ieW(%+%RCp8?svJrOG*6V~io1U+S8Q$13~X3Delh zfcalBl@Apu!;O}ha~sR6~ILE2J^TY=!xqJ`q_ z5}X8gFSJDirMMS&cZUL@xVsgCySvH;Bc&iX^}gpp_Az>o<=Qk_Ht^+^%zk2hl>n>I;TD3?O%k6sO5GajRB ze0|*nDyq+gW5X`}hv2igU3xDuqzM2+(gg*Yf6~pP4M@B)(~NrCkydqxUiE~tf(#%^ zb?ApF{p2J(>QzEb$=Rn98l&%*bl*E-ci0OMQAqV79%q>E*CY_d^AB74akwxk9(q|( zTYb;v31N5&GYl#7&K=+RHZE$l%6K-?#n$n*H!K?G63?UW{S?w<;IiVwg8ss)-`Ul- zyy{c=@E-iUgX?c@p59PXVOsM7n1w; z=^M?Y+M35oZiUZ<%h|CNlY{s!c!4D$oy!Bb&@b&64SR=dl&R6M29(FBWL)P#+X%mW z5(A~=TPc`$s2PLR=(wEFcv81m#4f8ocfAPsbWQP8aPd{1lD>S>#=#3fJ$}2xU)wA= zysbh(Ua}14c)xWD~=UlRfO@*i=y4t^AG4#);Q3aMMgV} zUUe_%91SUn(C`MYK((jOlBfap?&CYZ96ntZH)sf#P>-gna#rHFg z8uoeR)U^5+H%@|4K!`g zXZfD9P-2Ace4hNNR25B7(@*428K?ITO+-&rG#lVIB@tQAOGwkZIAz|2hvoYj*O3e| zI1S&%J-%GGwN-6NY386itLgD~f;dVRAOCjF#%sRcghar`w1z97ksx9mMQp=yIH!7` z1p9!YrU47*Zd<%+(HpcYbOydA_jDGfkBs1`*;F)u{EbhBi^CJXG_qI7u}a@55`eX0rFF#>p$l5!;#5iU7KO{21?dQPj zud&Y9DV~o)1S&CYvkO0t+!+MO8=Q*ihC;{aOHXq?1Mj6M`9{Yno+Lg6`cEt~q~nH2 zi;`ugl)+-)FY#?E)=rNXs}&P_cldDg*iwDmj@ORo#@+z)u*Iy{8#siqUrqq(p99SV zeUCF?qDyXiimCM*=qEJ3cCvbZwu0(iIdX)swA<5>)yko`PM9JR+-bx!$LPLMS~EOH zZ>+JJ)~yg(Z??S9x$cHFdnHWPRtNko``QJ&4i^&inYtw`=gn~k$-L*=D|Y3TTXXVs zYD?|jDK&VHNKB(glD3BC*ehuxsY2+QO86DT#27Hxq6OO@sW- zx!O_4;i-og_M3jTrzx}@c_6+j81fr}$#mJAj2)Ha(M6t`0SaihmW^=bF-LSZOR*H5 zM*k}S!2@c4wg0w|faMG+TK;2&esiE2-{BGDSRem)S8x97@L~nR)Gw=PmNf;Rr?+g` zV)B@F(S}}11Ub-JHh@l(nZpnl8yeymaf^pBkW6nR zFwhO(j(J+kHjKiL8tOKC{|41p?|&gU-cPtPxEqIf2FktE9xw{N8O9wiJ0)JHT4coy ztkGXP=6<;+wFz6bTz!%P^Du2?J^c4ZF--?2Q6X?W{ZaZNEfcCUz4tfA`@T znC841{KKjyGCE|(cX;<#x68sO;W>EIs95L-2D7=ngkpvF59S+FpT2`4aScB7Bx|qo z@HiSl-pC$MLOy!AF4{F+ZsyQ6Rx{hNtsQ12e-UT*Y~5YRXWuP_eIIe73{Ub~YmFgW zB$F5Za^Ycj4Yc})wBpFh2qaEofPo7Z8I|BJ@;%;c$IfQ8Wn>7(aUS)07zy^HWGfPdEycqJ)nI)RqPHlmAAj>)S%=u zHa|ZDg$Hb|Ms%hw;B~6kz1M!CpgTvxTkHwv)`^Wr6~+jc-a*+LJ)pzk@ci`pCD!nj zW3L2%L-9LECDkq4hg1G_i*+F&t5DN9d3l5u|JCg6b?x7lUO1lpv6k3r6qNjj7S0Zx zA}l;52^LlzxwT6*{lwhcAh!XE81nRFG|bTTxZLQN2ZK)$4PYd%6R^Dy!%$U*Xak+R z#>P$>kFV7eS@NevLfvu~NO9&!esMR-W~ z{t*r`dZCz??@zx`GigkN8os7B`PxU?MFv6xaaXvC3Dm7 z48aFif8;CzO7wBEdT0KIhfT5CfJ{NG|Kx|@%s$pi>vAgj89fpL6_m_iV2&wyqT))1 z2N;>DR8zOnZc}k+`kNIyC(2n)c-CQ;Nl;j;Si9x=2mDgj2I*)!d0wA7I$dhgFB-BQNQV* zY-OhP;^O|jYG9aQUz4;pclI5~v6yVF36!N0J#=QlP0AgfJGu1#YG2EGn-Q*8@C`;A8a-?xXn{Lh zaC0U1Vk+A+iv|m+GPCfOrndZ8=aFOao*8o>>t3px{%rEB)&yLf%448>mwN)90N!d$ zoD~WJH+-nbO>`BDhc$Cs(*>`MeXS}R?C|Z>1Y-GoHigWM%1D}wPUVt-KrP6$AJz&c z2y(2Wqc>)~#V3)K!)w)7NiMANBsR{Y+CQgfIULsfcZ*Jnn=lXT$GGPf6;m~id>&$U$al&b2no$VBEJjtgwscrYzz$4 zT!10>3VXdFc6V_2p<~HwL{;1ytK1vPuC7wMMO=M#2G)3fYc+n$FR0)zFuiH925MXd zh;}7IX4rzti^X__>dOv0)ISQB1q3kiKBH`hlOr>bgjMMzCI1`6nmMg|E0Ig>nG9gy8N5%*>dF;Y!1j< zez{l7R7ugvKg08+YA2qZf7DXsKQdh#K}-Y-NM;Qwn>QJJJ!IMiqq$h4 zyXp_9fuqlX^6~|3C$!KPe9J=;}CF7Iy}EpE<#Kr=VIEfa+?l;2~}P?-?? zCOe7V62ZlzMQ$`+S-Azd#hsy5vp-LgcbXi?YcDS8d?TV}Fck5!>Ze@blUijb?0kri z$$!E^L%XlvVE_Z+>8DPvm;kr5@r$(#vf{A|!!KbuYsx82LwrbP@2?ik7Fs}-)Z&9n zWfaT2Vp%l8yXjc6>K9D?-2&zcZ1Z_-?8^i1+lJXIW)gb7>iss|5)z z2}$7k*iT8;j0TTZ0+0k1^ERPCuD`9@N0*$h7RX)1oD^YE=cC@LxF6DJeHY9?1aB2h zk?kz9Y{$!r+0L!us!qRfrD+z6sS)Ex{&PZpYJg0h?!HQ?>bo4HRbdU ziBJ}Gy3UtSMI(bQi~}4In@0*HwvzOCF~OZ+Uo}J$809E=*y0{7GM}tko*q)B*g(I8 zS2cdf%&Pr>pa9JX3d|pbH7$C)2@p;5TRn$kr2RR|hXoFIGt=jQDfgFxgcH`J0|Ws+ zl^QK|YPOQBLu(k0gpXBGTXW0gzwlGOQThvOuaD=-_i9K%2nDU)F80OvJ)P4(4R5cv zyw^iE8dHmd9$#J8)S z_QAbEvhsZwKg}2>b3w-c>#=y!So4BsvLst31IfnI$*K}Nd-=^1=|_xEa%mMrhAS!t zN)1oHHhSA%X|Bd+_|;39-{5?$+#`SMaC=Kk-P<^$7o=9B3T31WN7})~v7)1}Q)Y}o zb_VqspU8Cedz`4PGPJjHyGicC^{m;grWg*y?ht{L&E{m~-iMWVr=#mPZS13gxX%|6 zuo9Knyyx&&AIgUbr2CH`c4*bZkG%!%bb)#I*Ig?Lz>t*o_E3lhSh4t3%a&n$mEDRO z?E54dcmm$s=z6O@A_3W_5(o9D??L{=y(~#!C}(fhAaH=gV@0>NN> z)rS*F?yuHjKp+wjj$e6V7lFrDS(hw?T?J}1D|Tl7SYiPb(abMr=Lg^LV3xRG0UP?4 z=^1A_UbROfOt<89eFKULUtP|40mE3h8j^mHxkTKT)ZBVl-AO+-3fz1cxC%L(PRHO7NIDYz($Wb(0%uGyHwd>;bSXQt@HW zNqN0YID=1eAoAZE2grK_uRE(6b*k(-+VrGgZ<_TuHWTz0#`UE0h1GrU>X=!ae{pEEO4d$ABVe!8Pc0qLR`Oq4~dEzYUO|6MR3 z)5Z)`UMkes_~hC29%s~~@8i@U@eDvGN`U=`Z1l0@&vpS3AV*>;QlaH#egS1LqClo^ z)c_&1DVZq^rFf#y%2RBESx=tE$GP+6Wz82No=w@(Xcy|gdkx&bVgcN+6Z1lNWHA07 zo*DY`mPe#dghFm+@?k6@xX?F&EP!wN&@Y$4tg^BW-_30i_Z(!#4TJuuTZ5l)-+F#Q9Cx2faV}*hmb97H;d7+Tr{RTOX4R z%%?BycL%IL1-3sHxm@6_TF@;UuJm7czJ2)KiXjjm9c1+18MSoAl{W@65N3_4kp%bn zqp?7ej@py$CwmWRJl|Gr(?WJ0H_X1RW~WQ|&|5`X0@P=%X6IlqE5VM{nK6$F|?~HfnB%m14B=B=zGwdTX2=w|5smx1@O$N2z7m6F3PiG_ z8bsqI=Mt{1CV@W-&P=YZf;`DQCya^{zNr84&6mKSr*gLIDcES=Ds4$$#Gl{sPqMu> z&pU}s=e}}hVi;J$4-YXb4yiM}*t!;;l-ONDEETO4aQBMd*+LHr@C9K|PwPfgHZv~S zQAk{W49!S>G^;vWVSXSX@(rM6TK#8(#qDJ_RXgfdT0}3g!=awu5X5>#5>2(lYW1E# z=?LjS{#4=1$H%GJ1?hy!Shh@Er$40L)ICq9MU^keG!SW%w`#R@&y&0`LFS=l|IiN( z>Q88IisIyYi5%M)sISpHD)DX0sMmnULZ+~TEwcBqJGnHGm^>Ib4Ucsmg;Lua^@62_ zFZfbQnX38RcPfx6N98c^FnrDn$l4jxo?7v)`jz|6XG}3B+N z#PF7gN~hUt{%=R@(CHEr|1umQG74=J|TPc{bCZ;`@@8_1E*gWi9^J9e2N%?q0AP&;Rl9Zn(Se4yN)RdN#-RVd#86}%?kMN?E=`KG&jW^bODy%+H*Xgb%$ehZd4zB z;Y-twU9p9R=2A);9Ggv~LB#fJ@R;juyw&PiRh%lAetlOWi4Z_Cw%&R?CP&UV(_Tw~ zHbtV{9$1ow$e)D=kIHwZ-d@zgaL>H?+n)10Urk&Q7CPZ4o^50>s)5DteQ2P2Ye84D z7eY`5qwWH|W$0ni(K_i(&i$%RC_DQNt1y~<)z~sD7EYb#=#d}CJ=^5rJc3z< zIp+q>;J4wdujsUV;}gjmhpHAD`~m$&52BEM9bps5St!TEF)|!_USp>V@$jEDx2PqF z)u!`^sV!vWdAn&Ollcb3Wl)f~nIBm9EQ>~0t?1_?yx9w;DR}Tyc`3!X*sJM5EoCty z1tllDct$Vi+)HhHTc8Qvxg-6bGTn$UQ9!~1VP3Ydr{etf0!BuCzJ%kxMVfoUy@B>q z3zT6#N4|MQ`;|x^eqL^N9>}_VX|{=}M(p!RmEAPShmR^I6Z7*s{mI4 zN=O$Xj%T5|^|s2Zl1nV}2{OSpz6>T?=H)Qxl;j+i%lUm7k5+@s>GkNOge+04N3R3*SJfry2yIw%$W*M&C4R zfq3JaOPg0SA9Tav-3;A$v>*osKH-4`q`cC@=28B;O}e;K7QuOphuSVr@) z10+Pd&@!AOZQ99~lfvP<_;kH2vY&&;5ijU$-$sB~+Y4Jbf{=#llXf}{w{7KIN$PB# z;7jcnfpfvor`5GIr+_Q5&WRiJ0DTNp7Gv0#VJKqmqiPoWf|pr|$;wvtYBO3L?fB^c z<=;=|I-jwF2cK$DS3QA>o~OmC5q9?Jr*t}HFeqvNSSC3JNULR1+7GUCmb+EFsg|8; zF0iYqiMA}#V_fXm<6o%P`EDayvhRn&7|GS&G}Wd>Z={_H_TO#?j~4bU;fINT@p6Hd z&?)JnS8C{Bmnt z%I4AD0t`UJr7x%^^Viv%G<}oEhBtIt#_TIDKQR9VcCf*M zVvS!*RhWC76QaUyBTe3!{hm%ARFZqyI;9C=hN<$74GbW;VEH8t~SpUUuGq!YP9-Q=` z;5;TH8ZU)2%eQ1mBQpkCWHG$u5|t;bc?;utNMMG1?I_|Yl(wWq!M{}T>Y!v$#uWMg z%59cFtup_U$Nc~OGI#vn8PNYP7aIBNu>nw@a+Wm7%@_^*Fs>x2#Nho+sF`V7NXYzW2sY4$@L8w`{hW^4c1 zmFN87kviBPcr?Osq4_QY3pF?E37plv8(#HkqjD5jpeSSeu}3I94f0s1n2>)O8rAhc zz5=Ha$?)MNEi47|#rFIo`CjA_OFerrGrK|IJu=lY8IWW0xTUnO#+nM7pWk95KQle#Ba|c9?O4P zVzoZG?V$5i-1TTwdnqn3U< zVp9>l=*g@~I#Vzu~lnPeyjMJyci~vpfVT-ZZ?7 z@Av-uUoH+?;hAvuOO06d?>?!-c&rF{q14b zPvDXlch}&vKE!B)80*yC+;g|=+FM@vzJ-|oYy)i1YM>I{p{AYCo$}VH=U;Cuqe7Y8 zx8LVvEInrfUkVVnu?8($JUzxGc?T+sE|JA|7)$i$c@V@Cq}d^Q7yEMVW&4}y5xpG| zlgcPRYd(;(S8WV1Ir+k`3?~Uim4{@6Ks}ct7u%f4Xie{&D|q~nS#=N5RvWY4Ifv;S z(b<#b{}juHX_M<(lS#gme5fO_gCI8I4{?rFh=zv24;3Z)aV~H?^7;%8Qnde2^vN%L zab-t;sJKOt9?OOP6a4SBbN!(Ps{IdXARx@IDvRP$M};E{^^L5WWeJZ*8^%CV|3yj=j`Bu()!PceFce7q z6%50*{ws>2Jh`AY3_^jxOlme8JHaDGDrAo6@YYa6m1^DAGiE5s)O>dlzThb zFD=Ipu+)v`c)Y<$5IreDp^ zfDosLX**n1iENFb;i}Z_{7G;bidHRVZ{9!@ga~J!g(iiI82-mPG-NRpV)*J`L}0(L zrM3^Pj*`L?dFLHCrMmW<@LCbHhw&S_8MrkqNEgy2C&oR(*h^2nkr(Vz0`lXICMYvUZy^Qd!W*O<*G1D@F{?U&nT}w1FsHXdctkWF< zyku7e-quU48Z^Ac$HX5w04rzaV%0+{pIv^Ue%cr9F&h^dD(ymamz{?e%ZIAVaxers zeKyPmU9Eb{k-aSQ^p$?|J7gnJ=K1c=wx4QGYVi*-a`QmTQpUJEj(5ybWR~W{6xp1S zK`ZB(J%;i?b*9T_I>AidgrAv>pvfp@#FxU@ds}Ux-!?P*%ifP{Jl^w{BL2bY@Iz5O zprqr`Pkha->O%!%g1}(%25nNWn0LMbR$F%<%8(Uogqkt6aj?et4nB&rV*{Z2*5e;g zu;#ms_1^CDg$ejd&i--M;(!Tcx{a6q-2Y-5(vu)O3^$KU( z=$aB$Z{~>uLG+w6{jkpPu%GdoQLKR#7!|#y#{Yg~478j3DItEI)&i6E0fOJs^HkF8 zhUgJo!XNNJNaoe^#p?5L1iNQlzlD62UG@73%BXSEhF`LE_6hM$Td~(Bz2W>{v`ynIEud?6==(sNL%TX-y^iLx!o5?nN&9DvLS5FR&-&>WawUvoM4V z>jn#(p0!?4Mhr(*6r)l*B5@a15w(@L>M&D_(;9{D`|WS_D4fGUUW>af@dnl$Sp75b z+mM>MSvkEMKr>=C<5U!5d(G_idy|_o5Kaeh@_1b=w{2( zgns5)^&cVBMpRPF_)S@JD?)-)&Q*a{hc-lb1p+=M!DCM25*#6{%oYW$5k(iD_O5o8%J@~p~{8g1a_aFVE3PbM{j%0 z(~ds$s|PfPg=Q?rA0qQtkk@4foChbx9o`K$1brpD2BTb%vlZ~X~n`H@slhwy(ohTTujWMfW4z=ZM01?mQ|?o z;KxIQ*z-|b^@%pJs+J>Y%|o3h@fCNN3-OGOas{$4I}1Tqs>@mfBtIh{uFC%XD}(1n z!n_?6W$YovOA`@%lAA3vUGrM3s2>W1xJ`fw~Xx7fV%`vJ4k zh3XpisaauQJtW7qZ|YBl7NZm(4ENIVokJi(i&8MgI%bIWCwsAVa6MHB@3aUj*U{6x zxUM_CIyLF_$gB~S+7la#qsc!cSxTFH0=!Wzw)?3c`$S>V;t~C!>me~x7^*mRVRfdMrTDfROGMH>r)=#i|ELUYJMTL z5KiB0ii>ay*VPs7C`<8^Qe5lFT>p}Xl}OI2$`P@dN(iubK3Q= z7yRb)D?V2`$vgTNAj*s5s?E(wl?TdN#M-tNV)E7@AlAVGOx080@$c_s(!k~E#Wk2> z>Py#{)On4g{rv-PXDg-UK-x80OJ6yBVB_Z3!;Q~HrN+wR-Fsd`#Nd_@%Yd+vPEe`sRqn$7w< z4<5AM?Ck1QILUiV6cy`%9@eH{u9rEZwlb&I_%o-I?gg*1Ti% zk?)*j9ch8yy@y2Mw6;a!ooy$bPRb|tQ<<5ScZ_k06oa{LyQDBGX$ySbPRB`Qcup=B zKa*^E40M6al^u2}l~)%5R64mF^;Mxj&_uVDKOuSGxOOGIwhw70k<&Z z-*t@d-U(?KnSZ{ozUIH>ZEx)~XzMqg@F8Wk2bgr#)T5MVD=5%V-T^k>dGeTBJuJCY zQJTXun^B^l0;#+knkmy0rnUxo@z3vfQ@$ zE6k@Qc8?F=MNY=%s6DG=nA5g^0rpQ#UW9$>u5b$x#V}OhTv;1v1QkO zc(`3Q{_g1EjD|4l`+#M^(U&FhO=Y<%f4ul_o+rNH0BSeGr9LY9e-$0a&?@j_fAp9o zBuqMJnu9d5a`CmYxZ)$LCt;YOkm_p>hG$ktr8LAZoyxS|5lXjVOL3S49iA_UG9@+cH%ICI zAq^orer0cL&>l*BZaaFaTEMu~7H_viBv1Y5!uRT2nw^!l-q8q1BR+%Un&gp~YLQkO zZv`>uB*fEkrHQ|&*a-wF#JVnPC9j=@!|4IqQ@Q=LK`Y@oY^qMQSVKuRDL|8GB?i@G zt2=TQi?vRKPdR&}DME5>5xigZs}T7xo|W&#2K>n+*MxsmN%aj39|@+vfzT2UohpnnZ^DW_wpb)ZmNdCkJ$Ji;u|X#0?=KQ zb)DDow-(_CP$;9fHx|UeX(Cu2nx|~74B-;~%9MnO;rjdyq2wZsl_X@08f5wNn4&K5 z!`Erv;_qv&!&0xda+3-#tpk9`HF(|0Dmt4Y)#R0}_`HBUuhw1s$_-DWG8DB{Nd^?s5$;_l5ebj4*2 z`5et?NbYMA*)it6b^e>=%j0=fT(3=>LK%ZPQca5QRdW5O^{*N)tJThT?|y%A*_`4U z7Dnq4O(UsKbMH^)j&2raEAsk1L^1)6>oII_0n7~~>2+DY&r=#W9Kcym8BOAyRFu~= zVamD~Ox*ev5`2|JE6ZYL?c+)od+ZTdTXx|Ib3LbDIA0K#s_Y54xG;y@$|du9-;=k5 zBOs!IhdkDvj}hV024s9X^$2d3FkAD4 zt%_vkzF?>hR#`1(-rPCuZ8rs}ZD-+50(%`U|x1r=;* z?rVS>CXX1rjXpoWla?+aTjcnoX{9}v(01;(eA8iyq9?88T7BqBwD>UGkXOd{_b&|Y z-vWu#0r}a+(FY>E5~8*m%z&4-Q7|R*;BTCrmUhWX-FyD-DWb~bwK;_!kpF^2m$hviEEh)*18L+cvK; zBcJ`jPg7tMbQFkQ#F0Ip2HE^^W|0bV3k|$3drDahWps{Xc|Fo`RPG=^z zRQ*&5?Mi&lO%4A2t_y%J@_KC`b7JhB7!F`E-tCM%1$4A9K3BMXqZvZJo^<@eC*+i0 z!TNeZySnUp%DQsC_L|Ooa(|oOAr||u4*Lrg=$??3`96O-V zyJFtFVb~dbX;o8E45VJstS;>(N1yWMy|Z%Q_O|AFd*ULjAF=+jRaK+>ff6B`e_*$l z(Shm9dgnRUx=-os>do%+-SA@4G+>=zR6adm(YiV1mFof;gnP#N=6+iOO<{cdo*I@v z$EVX365W}1#OJw=oyQ6KXMUk=Gw*49>#D8a33txeg;RV(W01qqJiVr}R2gr37v=|q z46yY(^Q08*hf2S6BHtI)+xd_r`lF=XWg%%_v7Ay;xyA~lFZ}* z{qA~&T>6tN_qyCdLDqz>llA@F;h#tJh7CMWA|cMe4T`ql7YanLi)vFHRCs*IxGI`+ zulo!693MrJ2(ob1-*RNJl&iK8obBJ(%(pUQB*F7FQ^@hVI)mfCcImM4LsmKac-^@1 zbsitpYdMHUmMwQmAxjAl2Ox37pYjR>X|7Z36@J!{?td^>H;rSzh_>;*PA|6Ia$_kL zERnD!rJ~>9%x+3Y>yM-~D)wB-*XGIZRgPuQSUhI2bA!q?aAy3}$K(`j|4Wfp5s+OM z0o#?Bg=q)=gOmPd5Ye&|UeA5(KPqQ_wajGM-ZA=7@3DJz$w|0HE{VQf?7~I83(=-) z(iY1z#j^9iGf$yn1Ln2rll9!XG*)qN>se4FE zQuy%F{nZI|A^XM5(MNjI1KK|y_+dfhKTh)69G@I6Da{A7C<$Ea#?8Crb3I$P9MW_Y zL9#v7miRmr<2Qew1WU^^`F$;J1-X>3|Ik3yKq$90wI2}dn-8$)dS1$42Ur$5CzYlCZ<8Ko}30Z%b zfAJ#P53SaqbF9j_6k>B{Mll-i@~c$hU+nZ;Urss1z-RCGE8l-?LP|pxUpR*ZLU8l8 z8C8fW*;ECb^8Dg+0*<|MMGY?6)R#6pS(4};!Ar}KzGKITH%E%0f+-bJe`xZ>)G_~O zPEJPSi<3uOf@qXg+LIQfKPa!Rp5|z!#qj_fbPD5CPcd8Pc^;UPsEb>?%yT7bD04OY z`~4GAg#ez}3EQAs23tRW6mS^v3oG4v#f=y_=Si1h4FB?E zF4vqDPq#~&wqB0GmJ1F}8eeX?IyujNeVFgrz?J{bH{NrOd+Q|S)#MUlC%_X&?tKYK zeeYpm1EcywF-LG_D>(_HX}0ETl)fbDYCWV5jWT;HWex}I)5gY=9*Ow;`9Olub>l|q zN?lDi0xMJYc!~h?C2~fKHziVN1;rex<#nCG^iC3_9fKreup=ZZuX>$vN7M9w{4Z9} zMYRGQn0Dl9Ht(x+vh!a=rlmyru6=l9$;T4=g}2WUE4swC%AbG&aO>dv;rRns63;M1 zUd1FBo8jre=}1P6GhNw7Op28oD|G0bs@5xmrCqg9Zt`j8mtl;*e&yvBUQr=qdnwjS zay0>^5sU0Yx0LSz@j&WhA&OQn-a;5?lk`xhPx9TD7Ful#b|M} zI>b|io5Yv>cv#f>ELr(#`@PScY%dQI1kB7;z_An2v5+RnJK5#%jt z%k*@vGK*0S^-@DCVN#V@6=drY57sm_VdpR%VD}+qp^hr(h|g4=JjNq*xvnHQ6sMRIzOhV||Ev%KvdjRX zBb$AZX~@4}Gf&L_b2yDwsR%@aj!B3BtMG;-ppTG;6&U|L`M+pQvHpAVf6?~6`d=OW z53RA}|Lf?#v}NY>H=m1;W6zKtkf6Sv{C^+v7Szb`ED@RDg@^C&$@~Wp-FqOrE-!czQ z(GH^ZGrr45ZFjT{5kUs{*)`xNu8mH1DOLi1z%&&}n=BJ=+Jii5q%W6`L6XuzbuI;^mpE(6GQ~M-hyXOZLNil1 z*My)2cZj1%OX9VO1!7$mNfrev-XopK=z~u=wXY-?{w)r8S}}Hxk@m?jBg>A0J{~s3 z_@_4h>XUhWx?=#;q|gzOLnKN>ty}oowzu{J zJ}mFfnBA;b4WLw4a_ofg8?qx-4iUD_I+pYrb&aWO)xbaLu6K5IndQ@*4|L&T_H~64 z{DAkGPP9$JguniaBGHxj6nNlwu8#9vkqF0ueLWhK?vNYHo+0IGlL{Qa@qZ)Bj1=aO zu}Qh)>pd>8;mu%v)V&LoN!3k#?S>Uf-e?Wx|6G+81D9RUmDISWi#2PhDD%-2ykQCz zE*(zFP`NXZ(jP`?z;2V5nrFckj_b@78nK(F(0p77Jb6PqA@2@!=8|31*dB9QZ1(-N zHp8vMoMth^X03ajvo=i;$2*{8SgE3Grc$LG!le4W|3xQ+wFC#E<9=3KyI5@GWec9v+F~2^$*d6T?-6tMD>~}5;>Qb4U>?JMOah@id zH_78!=}Rv^dj`CI&g7@vI~nc23;cvh{Hg2NIGaKmm^SS(?f^ru3MHeE&SjoU5QR#9 z+TghYmU;bKEmcvDin3bQm8=Lo(^$&t>on{4cf6Xa^50}CZGlW87ZN+k{;x8>y0Z;! zt^IKxpRZ%(jGIc)6HL;XJn4@#GA9&eNcrV?ghB!JQucAJZ7jn3;+oL#Zp-(HXOLNV z>DA*`L33ff^l)c__P5R;;r&ji~{Kw&HT}x|VF<hYngaTSmoLIbsE0xsQ(;R6gWa#b zo0Oh9YhmfqzH0TtC6A4tb|v6Bju#T)XI{w5%UK+gRT>77&ycFOHummIs+Be8 zd}LKUT7BUUvC|E(_uOInx6=*3(QC+8A0mq8miOn);R1{^gFa4hLWUtm8^(l>V{H+_ z)47>VX8U8xY?ZgWk?)MN@WSHk>HC5-CbhK#-W3}KE0+i3o*OBp29Il)YyFgi?Xqj? z8vdM()7M%2Q8CePFes6z6erN6e7;UAsIBu_EV4?0_D{T{jocZQ7Ky0F6iNk&T%Iz( z>&V0gUzbSSB2uNpsFlcAB-XTigMl~+DyPnGHK+^X(eM5_ZeM$w-$#-MBxlBOex;Bt zo#+x`tFc_B@KIPW}^Qm*mXpl-z^Uj~aIqy;%ktlkh z+DtO~MS((G@s57qYUFc4uu`5uiRWB&S8)*5##OjEZO|`oe?3+(*wz5dqZVZ!y$-UJ zIDj^Vg{Mqk0Ol4+&U@FM=gq^CXFam2%{etG_S7_r941~^5w<@yE+s)O=}uFhwl!GBMX0YTID`wC zBegYaDJ>(p)`8;;LI_F714ue=%Y#n^bNYH1V|t-U*IX>iJxxWn=k>7XSlJJ9srK=+ z%^49G7m;h!euu^2z<=EQhwZ)*DhpHT_>r?O>dPuI)M3AhR?Jr1qjWZL|A%dJU}-$ z#Qt8z?Iz&s$hjfRj7zesq)=y!jQi(9#|anPEBgtyV&B7+b?J`Q^Ri%6uaT?iux+nr zl4bFK!;GFq#WUfZd3JMhNkaHxvyI=2YSoM7wJ{QXeP~rbv9|H&a6@fT0rB(~@7dnF zx_4lH2+9yqdS@k{;Qv?NLg~E+tV7&Yyf#5MZ_^ANmUpHX)lB|Ia@U#c4^FI-MWm>31DIe5z#56)&+B{AGKaHbif}sSoQ9A|DxfVw=s>x)y01)^*@|v%6tGvh_Ig;AHc}23 zKJSE3*OoGh;{9e?;=xzsIzLNTUqvju<_L54qxconYttEIvLwoa5IgJXuSc9eI~}7v>ILNEuf}88g)P;kkNszca_O{ zeh2C6#AhHjA5Z4*fBcrV2lhI~Kr73=+={6zGCCuD=LdYUs*m`=7WQFBP2T~(rd1qR9{YkM5SAS8um0CvrFa*H@lJEn<=nbV9?fY(GLIl@VMhd7 zJ8Hlkmpps(^Ua_gdny4uQ+aBewiAxm)cC_{8M(pn)L-3&wSr5U3$EN2wM(!oqxVn3 z|4fBY-5OJWX}LFPIZ%V2!Tw{DmJOA;k*??*#R%99%cl=~VsK zOQPR{=HMN4mBPFFJNmxQzyLqPLa?l{!dB?JC-vv0zFS;?XUik%@fr7~%P@mMWR9|` zHeF858UE6^ABSwr(usTi6G?vpGR=?z9C>s8?TeC0*D(`P^$IHZd)W7rQWHt_CGEBA z#qI$XITbd+I8Tc|M-c5ps;)qnb$qoy{JjQ68teUv9I*e&qY2wX9FOqe0W^d0IV9_U{ z1S9vPiv(;7K^kzWM#J8R%D`TL+NNu2nng>{#Or|IKAEn)bO$&@43`&gir@sXqs1B^T4!>hV$!ZKN zUG>c%10Uqm{&ct1f#0{q9|3d$5D4S*x9$QEw%HDO29HM*y1sl2ACdaKA5040ndQm* zh=)N8qxHD+5|SQ54wmx!)o!Y#HLLkMH)s7`ikiCk=S?E+>6>iH$4ve6I6!m$k-%N! zcaVJFIK&Iz%q&dANJIz%UK&hRgkV}g8*3;tsx44B!d0l49Q z&5B`!Ct)r|-dh(F(f@JPtUO^(kb)>=MCVo5!{%!^`8^RG!_o7BXP-+rc$E&Scg4i% zviG|L74JQe?|qXqU+E3MNjdnz*RW+W0&daaH@V?I%7NU~Pcf69*Xsu_b=6^E0VzOr z8auqOIzZ4!{oWfdwCvtx3gX@~*OOBvLYMvVo!};w3glsqcaJc~=9z$|B!+Swex4%B z!!A6PgnJkt{*)ea8~i*_=`101`OcJ3WY=?GJYudo4KT50HT$(&s+e%)9SLFu;U_O$ z{r#$_>fo*&hqB2DrGYLdgf6V(xAWCGA~s_Z$!zOfzW9+cT_Rm&IxfZM8-g>@C!^xP%6h3lGnX=tb6ucGFglZ9ukM6wuY1dp_6`j7kcK# zb>XyiOe9Q00dBvcuvgxAtV}Dcgz(O3dHuGweM!nunQ=hV!qYqa8f6bZUM^yf{*{$E z|Dn5~9WwFh)6t#mCts%PN@eKL>3++{9^44n1LCi=IRlIoP7*wfhrZ zY}51gIX!8i4@(^7{O$zX_%<>)2R@K3ADQ2iKKIID49GU!I4Y_v>uI=SdCT|vX?Wqg zj5TsEgO=y`UxzDlt>X-OW_gd{?d}jZm-WP=_FEjuqOrpb`;hKS`emtwOv`5@+?__;bDEDvuzcJW2V^!q0`0h6_IDRJ#tLpu_Jdhyr8x0 zUqr;bsKSQZIbb;cY+I9cP0v#O6&>ksBO%$LcO((bVvNulT3q@KK3+cIfb<*qMxxXUxRcyL+N2*h)`^Ta6}bfQ~1P6YB>#s_MGHpxqK>NWZavDo_=@P#p>yu+p6 zOq>rDe=KJRmWw&OLuJ4rf>k=$$!%LrD{kUM2viKtJdJ(t4%Yt3$vzfB1$PY{Sz(_rb zsD?RY&D;Pa$BB;r;rgKzhC-VNX)^dD#x)aAL5v3WZTrDsSNWr#@Kyv(K6l`-`&t0q zrCJ$^#aRkz#Nvy4{-hCn`~RBV{XjOW&lx^N)64+)UEd6nnx%!fHf!hm()QPFmh|&s z#G@c+E!dVj6x|Or ziuI<=&5)4|C#e|6jA)=$6>{+^mWppoum$qsLw1teZ0Cu+d}!EI-RnAR*Ayb#WzaT1 zO7a3T#?kHjcP2yHOvctLR+wc}e<9zKd^Xo^kS&L|C(_QgDiJk&?MwtZUm=YlQYmtF zz$0hD^dGD%vlEA{1E9$@#_^~Ni*<*Y>q{pfkmeiI(XR(;>F7U8YgtHoWRiCums|n|U?hJ8_8DFQOCtn-A>Mj61aI(Vsf_y}2dFezGZw z;nATSC}64Y8x+dq*p}&ayA&}D|2R!u!#y4^0y?M?eD3W(#|xEeL7`JPD(gQ`+eX%^ z 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 literal 0 HcmV?d00001 diff --git a/doc/bookmark-management.png b/doc/bookmark-management.png new file mode 100644 index 0000000000000000000000000000000000000000..d2848d3b7509d7019f13c73ecc46006618fe4d43 GIT binary patch literal 45777 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 QK>sMpsmgwPVe0Qox7ApigX literal 0 HcmV?d00001 diff --git a/doc/bookmarks.png b/doc/bookmarks.png new file mode 100644 index 0000000000000000000000000000000000000000..4919e970384c2cfbb852d28003b40b79e18f09b4 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4foCO|{#S9F5M?jcysy3fAP;iQ; zi(`mI@7q2_p+g1&uK&|#bUre8Dkm+@JS)ujPFs~vOc75T^8wQXSKcIP8Srjlo2*{` zf8Sq+)Rtgw!Hw}Omd`zpClzXLp7k}CEi~q6=pX)%zoHLR?+?6cd-AY_)#N=(rp#Nq zJ1JT4<=Homn*y(fg+?<(8}IJ+*uTQ?q;$jT;&&3sHMMJY2^`9lXp?PNrm~)a;okik WT`j>!FP(tyWAJqKb6Mw<&;$T+;#AQ9 literal 0 HcmV?d00001 diff --git a/doc/configure-annotations.png b/doc/configure-annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..4cffd1e452e9bf8dac3cd1c4feb9828c9b481ccf GIT binary patch literal 23450 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 E11tznmjD0& literal 0 HcmV?d00001 diff --git a/doc/configure-backends.png b/doc/configure-backends.png new file mode 100644 index 0000000000000000000000000000000000000000..ce775d08e335f50eb3e2d91e0b2df6a84baba998 GIT binary patch literal 14312 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 E57?G=w*UYD literal 0 HcmV?d00001 diff --git a/doc/configure-editor.png b/doc/configure-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..213fa049332e466c165e7bb55cc8cb02b9949fab GIT binary patch literal 23685 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 literal 0 HcmV?d00001 diff --git a/doc/configure.png b/doc/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..bd0f96111bc76b5ddfb84dc7478ca9d7993f3f1e GIT binary patch literal 32098 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%0DBB;YIU&av0)B^@C)hu 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 R|HTia-`CJnuTr%O`(KoAaR>ka literal 0 HcmV?d00001 diff --git a/doc/embedded-files-bar.png b/doc/embedded-files-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..32a98daf6d6fd359545ab97d61943c1ddd3d2682 GIT binary patch literal 3186 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 literal 0 HcmV?d00001 diff --git a/doc/enhance-lowcontrast.png b/doc/enhance-lowcontrast.png new file mode 100644 index 0000000000000000000000000000000000000000..da7d9e0c6f8bfd8d29c92cbdb4f268aba8a4d5c5 GIT binary patch literal 3753 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 literal 0 HcmV?d00001 diff --git a/doc/enhance-solid.png b/doc/enhance-solid.png new file mode 100644 index 0000000000000000000000000000000000000000..a5dcf8597d24fbfd26485cc29419d9f56c7872fe GIT binary patch literal 6491 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 +KPDF"> + + +]> + + + + The &okular; Handbook + + + Albert + Astals Cid + +

&Albert.Astals.Cid.mail;
+ + + + Pino + Toscano + +
pino@kde.org
+
+
+ + + &FDLNotice; + 2020-06-05 + 1.11 (Applications 20.08) + + + &okular; is a &kde; universal document viewer based on &kpdf; code. + + + KDE + okular + pdf + ps + postscript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + markdown + mobipocket + plucker + annotation + + + + Introduction + &okular; is a &kde; universal document viewer based on the code of the &kpdf; application. + Although being based on &kpdf; code, &okular; has some unique features such as overview mode, + improved presentation support and annotation support. + + + &okular; supports a lot of different formats like &PDF;, &PostScript;, Tiff, CHM, DjVU, Images (png, jpg, &etc;) + XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub, Fax and Markdown. + For all supported formats and their features see + &okular; Document Format Handlers. + + + &okular;s Main Window + + + + + + &okular;s Main Window + + + + + + Basic Usage + + Opening Files + + To view any supported file in &okular;, select FileOpen... + , choose a supported file in the dialog and click Open. + Your file should now be displayed in the main window. + + + + The new document will be opened in a new tab should the Open new files in tabs option on the General configuration page is checked. + + + You can close the tab by clicking with &MMB; on it. + + + The previously closed document in a tab can be reopened using the &Ctrl;&Shift;TFile Undo close tab menu item. + + + + If you have already opened files in &okular; before, you can quickly access them by selecting them in + the FileOpen Recent menu. + + &okular; is the default &kde; application for &PDF; and &PostScript; files, launched when you click with the + &LMB; on such a file type in the filemanager. If you want to open any file whose format is supported by &okular; + use Open with...&okular; from context + menu in the filemanager. + + + After having a file opened you probably want to read it and therefore navigate through it. Go to the + next section to learn more about this. + + + + Navigating + This section describes how you can navigate through a document in &okular;. + + There are multiple ways of scrolling the viewing area. One is to use the &Up; and &Down; arrow keys. You may also use the scrollbar, your mousewheel or the &PgUp; and &PgDn; keys. + + + You can also use vim-like navigation keys, namely H to move to the top of the previous page, L to move to the top of the next page, J to move one line down, and K to move one line up. + + + Another way is to hold the &LMB; down at any place on the document while dragging the mouse in the + opposite direction of where you want to move. This procedure only works if the Browse tool is + enabled, which you can select by choosing Tools + Browse. + + + + When viewing a document in the Presentation mode use &Up; and &Down; arrow keys to switch between pages or slides. The number and the position of the current slide will be shown in the overlay at the right upper corner of screen. + + + If you want to read a document with several pages use the automatic scrolling feature of &okular;. + Start automatic scrolling with &Shift;&Down; or + &Shift;&Up;. Then use these keys to increase and + decrease the scrolling speed. You can start or stop automatic scrolling temporarily by pressing the &Shift; key; + pressing any other key deactivates this feature. + + Another way to navigate through a document with several pages is to use the mouse pointer. Drag the page up or down, continue to drag even while reaching the bottom or top of the screen and behold. + Once you cross the border of a page, the mouse cursor appears on top or bottom of the screen again and you can just continue to drag. + + + The sidebar on the left side of the screen enables two more ways of navigating + through a document: + + + + + If you click on a page thumbnail the viewing area will be brought to + that page. + + + + + If the document has a table of contents, clicking on a table + of contents item will bring the document to the page linked to that + item. + + + + + If the document has layers, you can control the layers shown by checking or unchecking + the items in the Layers list. + + + + + If the document has bookmarks, enable the Bookmarks view + and click them to go to the associated page. + If bookmarks are not only shown for the current document, you can quickly + switch to bookmarks in all recently opened files. + + + + + If the document has annotations, enable the Annotations view + and click the annotations or select them with the &Up; and &Down; arrow keys and press &Enter; to go to the associated page. + + + + + Some documents have links. In this case you can click on them and the view will + change to the page it links to. If the link is to a web page or some + other document the default &kde; handler for that format will be invoked. + For example, clicking on a link pointing to https://www.kde.org + will open the web page in the default &kde;'s web browser. + + + + The document internal links work only when Browse Tool is used. + + + + Additionally, you may use the following functionality to quickly move to specific places + in the document: + + + + + You can go to the beginning of the document using + &Ctrl;Home or + using + + Go + Beginning of the document + . + + + + + You can go to the end of the document using + &Ctrl;End or + using + + Go + End of the document + . + + + + + You can go forward in the document using &Space; or &PgDn;. + To go to the next page of the document use the Next Page Toolbar + button or + + Go + Next Page + in the menubar. + + + + + You can go back in the document using &Backspace; or &PgUp;. + To go to the previous page of the document use Previous Page Toolbar + button or + + Go + Previous Page + in the menubar. + + + + + You can go back to the positions in the document where you came from in a chronological order. + Consider ⪚ reading the phrase As shown in [15], …, and you want + to know quickly lookup reference [15]. So you click on it, and &okular; will jump to the list + of references. Using &Alt;&Shift;&Left; or + + Go + Back + in the menubar will bring you back to exactly the position where you came from. + + + + + You can go forward in the document after the jumping back as described above using + &Alt;&Shift;&Right; or + + Go + Forward + in the menubar. + + + + + You can go to the next match when searching using + F3 or &Enter; (when the focus is on Find text field) keys or + + Edit + Find Next + + menu item or move back to the previous match using + &Shift;F3 or &Shift;&Enter; (when the focus is on Find text field) keys or + + Edit + Find Previous + + menu item. + + + + + + Presentation Mode + + The Presentation mode represents another way to view documents in &okular;. It can be + enabled in + ViewPresentation. + It shows the document on a page per page basis. The pages are shown with + zoom to page, that means all the page is visible. + + + + &PDF; documents can even specify that they are always opened in presentation mode. + + + + When in presentation mode, you have an helper bar located on the top of the screen. Just move + the mouse cursor to the top of the screen to make it appear. + + + &okular; in Presentation Mode + + + + + + &okular; in Presentation Mode + + + + + To navigate between + pages you may use the &LMB; (next page) and the &RMB; (previous page), the mouse + wheel, the arrow icons or the line edit in the top bar, + or the keys specified in the Navigating + section. + + + Use Play/Pause button in the top bar to start playing presentation or pause it, correspondingly. + + + You can exit presentation mode at any time by pressing the &Esc; key or clicking + the Quit icon in the top bar. + + + You can also draw on the current page with a pencil. Click on the + Toggle Drawing Mode icon in the top bar to enable or disable the possibility + to draw in the presentation mode. The drawings are cleared automatically when leaving the presentation + mode. You can also click on the Erase Drawings icon to remove the + drawings in the current page. + + + The presentation mode has support for more than one screen in a multi-monitor configuration. + With more than one screen a new button will appear in the top bar, with the icon of a screen: + this is a drop down box that allows you to move the presentation to any of the other available screens. + + + Presentation mode has some configuration options, you can find their + description in the chapter Configuring &okular;. + + + + + Inverse Search between &latex; Editors and &okular; + + Inverse search is a very useful feature when you are writing a &latex; document yourself. If everything is set up properly, you can + click into &okular;'s window with the left mouse button while pressing &Shift;. After that editor loads the &latex; source file and jumps to + the proper paragraph. + + Inverse search cannot work unless: + + + The source file has been compiled successfully. + &okular; knows which editor you would like to use. + The Browse tool has to be enabled, which you can select by choosing + ToolsBrowse + . + + + With this feature of &okular;, a left mouse click while pressing &Shift; in the &DVI; or &PDF; document will + result in editor opening the corresponding &latex; document and attempt to go to the + corresponding line. Remember to tell &okular; to use proper editor, in &okular;'s + menu item SettingsConfigure Okular... + (on the page Editor). + + For more details on editor configuration please refer to the corresponding section of this manual. + + + Configuring &okular; + + + + + + Configuring editor in &okular; + + Configuring editor in &okular; + + + + + + + &okular; Advanced Features + + Embedded Files + + If the current document has some files embedded in it, when you open it a bar + will appear above the page view to notify you about the embedded files. + + + The embedded files bar + + + + + + The embedded files bar + + + + + In this case, you can either click on the link in the text of the bar or choose + FileEmbedded Files + to open the embedded files dialog. The dialog allows you to view the embedded files and + to extract them. + + + + Forms + + If the current document has forms, when you open it a bar + will appear above the page view where you can enable the forms. + + + The forms bar + + + + + + The forms bar + + + + + In this case, you can either click on Show Forms in the bar or choose + ViewShow Forms + to enter data into the form fields. + + + + Signatures + + If the current document has signatures a bar + will appear above the page view after the document opening. It allows you to open the Signatures panel. + + + The signatures bar + + + + + + The signatures bar + + + + + Using the Signatures panel you can inspect the document signature and its certificate. + + + The signatures panel + + + + + + The signatures panel + + + + + + This feature is available for &PDF; documents only. You need to install at least version 0.51 of Poppler to get most signature information, version 0.68 to get signature location/reason information, and version 0.73 to get signature certificate information. + + + + + Annotations + + &okular; allows you to review and annotate your documents. + + + &okular;'s Annotations + + + + + + &okular;'s Annotations + + + + &okular; has two different kind of annotations: + Text annotations like Yellow Highlighter and Black Underlining + for files with text like ⪚ &PDF;. + Graphic annotations like Pop-up Note, Inline Note, Freehand Line, Highlighter, Straight Line, Polygon, Stamp, Underline, Ellipse, and Typewriter for all formats supported by &okular;. + Using the context menu either in the Annotations view of the sidebar or in the main window you can open a Pop up Note for any kind of annotation and add or edit comments. + Annotations are not only limited to &PDF; files, they can be used for any format &okular; supports. + + &okular; has the "document archiving" feature. This is an &okular;-specific format for carrying the document plus various metadata related to it (currently only annotations). You can save a "document archive" from the open document by choosing FileSave As and selecting Okular document archive in the Filter selector. Documents saved this way will get .okular as their filename extension. To open an &okular; document archive, just open it with &okular; as it would be ⪚ a &PDF; document. + + + You can also save annotations directly into &PDF; files. You can use File Save to save it over the current file or File Save As... to save it to a new file. + + + + Due to DRM limitations (typically with &PDF; documents), adding, editing some properties + or removing annotations could not be possible. + + + + + Any action on annotations (creation and removal of annotations, editing arbitrary annotation properties, relocating annotations with &Ctrl;+drag, and editing the text contents of an annotation) can be undone or redone using the corresponding item from the Edit menu. It is also possible to undo the action by pressing &Ctrl;Z and redo the undone action by pressing &Ctrl;&Shift;Z. + + + + You can configure the default properties and appearance of each annotating tool. Please refer to the corresponding section in this documentation. + + + Adding annotations + + To add some annotations to the document, you have to use Quick Annotations button on the main &okular; toolbar or activate the annotating toolbar. + This is done by either selecting + ToolsAnnotations or + pressing F6. Once the annotating toolbar is shown, just press one of + its buttons or use keyboard shortcuts (keys from 1 to 9) to start constructing that annotation. + + + The annotating toolbar helps you to make annotations with drawings, shapes, and text messages. You can use the annotating toolbar to mark up a document (⪚ add lines, ellipses, polygons, stamps, highlights, underlines &etc;). The table below describes exactly what the default set of annotating toolbar buttons does. + + + + + + + Button + + + Tool Name + + + Description + + + + + + + + + + + + + + + + + Highlighter + + + + + To highlight text in the document with some given background color. + + + Click on the tool button, then click with the &LMB; and hold to place the beginning of the highlighted text snippet, then drag to highlight it. + + + It is possible to define the Type (Highlight, Squiggle, Underline or Strike out), Color, and Opacity for the highlighter. Just right-click on the highlighted text and select the Properties menu item. + + + + + + + + + + + + + + + + Underline + + + + + To underline some text. + + + Click on the tool button, then click with the &LMB; and hold to place the beginning of the underlined text snippet, then drag to underline it. + + + It is possible to define the Type (Highlight, Squiggle, Underline or Strike out), Color, and Opacity for the underline. Just right-click on the underlined text and select the Properties menu item. + + + + + + + + + + + + + + + + Squiggle + + + + + To underline some text by a squiggle line. + + + Click on the tool button, then click with the &LMB; and hold to place the beginning of the underlined text snippet, then drag to underline it. + + + It is possible to define the Type (Highlight, Squiggle, Underline or Strike out), Color, and Opacity for the underline. Just right-click on the underlined text and select the Properties menu item. + + + + + + + + + + + + + + + + Strike Out + + + + + To strike out some text. + + + Click on the tool button, then click with the &LMB; and hold to place the beginning of the underlined text snippet, then drag to underline it. + + + It is possible to define the Type (Highlight, Squiggle, Underline or Strike out), Color, and Opacity for the underline. Just right-click on the underlined text and select the Properties menu item. + + + + + + + + + + + + + + + + Typewriter + + + + + Typewriter features opaque letters on transparent background, so that it is useful to fill noninteractive forms. + + + Click on the tool button, then click with the &LMB; and hold to place the top-left corner of the note, then drag to place the bottom-right one. Enter the text of the note then click on the OK to save the note, Cancel to cancel note entering or Clear to clear the note. + + + It is possible to define the Font and Text color for the text. Just right-click on the typewriter text created and select the Properties menu item. + + + + + + + + + + + + + + + + Inline Note + + + + + To draw inline note. The note will be shown inline as is. + + + Click on the tool button, then click with the &LMB; and hold to place the top-left corner of the note, then drag to place the bottom-right one. Enter the text of the note then click on the OK to save the note, Cancel to cancel note entering or Clear to clear the note. + + + It is possible to define the Color, Opacity, Font, Align, and Border width for the note. Just right-click on the note icon created and select the Properties menu item. + + + + + + + + + + + + + + + + Pop-up Note + + + + + To draw multiline note. The note will can be viewed by double clicking on an icon in the document. + + + Click on the tool button, then click on the place in the document where the pop-up note should be added. Enter the text of pop-up note then click on the Close this note button in the top right corner of the pop-up window. + + + It is possible to define the Color, Opacity, and Icon for the note. Just right-click on the note icon created and select the Properties menu item. + + + + + + + + + + + + + + + + Freehand Line + + + + + To draw free-form lines. + + + Click on the tool button, then click with the &LMB; and hold to place the start of the line, then drag to draw the line. + + + It is possible to define the Color, Opacity, and Width for the line. Just right-click on the line created and select the Properties menu item. + + + + + + + + + + + + + + + + Arrow (drop-down list) + + + + + To mark with an arrow. + + + Click on the tool button, then click with the &LMB; to place the starting point of the line, then drag to place of the ending point of the line should be and click once more. + + + It is possible to define the Color, Opacity, Width, Line start, Line end, Leader line length, and Leader line extension length for the line. Just right-click on the line created and select the Properties menu item. + + + + + + + + + + + + + + + + Straight line (drop-down list) + + + + + To mark with a line. + + + Click on the tool button, then click with the &LMB; to place the starting point of the line, then drag to place of the ending point of the line should be and click once more. + + + It is possible to define the Color, Opacity, Width, Line start, Line end, Leader line length, and Leader line extension length for the line. Just right-click on the line created and select the Properties menu item. + + + + + + + + + + + + + + + + Rectangle (drop-down list) + + + + + To draw a rectangle around some chosen area. + + + Click on the tool button, then click with the &LMB; and hold to place the top-left corner of the rectangle, then drag to place the bottom-right one. + + + It is possible to define the Type (Rectangle or Ellipse), Color, Opacity, Shape fill (and its color), and Width for the border. Just right-click on the border created and select the Properties menu item. + + + + + + + + + + + + + + + + Ellipse (drop-down list) + + + + + To draw an ellipse or rectangle around some chosen area. + + + Click on the tool button, then click with the &LMB; and hold to place the top-left corner of the circumscribed rectangular for the ellipse, then drag to place the bottom-right one. + + + It is possible to define the Type (Rectangle or Ellipse), Color, Opacity, Shape fill (and its color), and Width for the border. Just right-click on the border created and select the Properties menu item. + + + + + + + + + + + + + + + + Polygon (drop-down list) + + + + + To draw a closed plane figure from three or more segments. The corresponding note can be viewed by double clicking inside the polygon. + + + Click on the tool button, then click with the &LMB; to place the first vertex of the polygon, then drag to place of the second vertex. Proceed until you draw the whole polygon up to the first vertex. Click twice if you want to add some note to the polygon. Enter the text of the note then click on the OK to save the note, Cancel to cancel note entering or Clear to clear the note. + + + It is possible to define the Color, Opacity, Shape fill (and its color), and Width for the polygon. Just right-click on the polygon created and select the Properties menu item. + + + + + + + + + + + + + + + + Stamp + + + + + To mark the text or image with some predefined shape. + + + Click on the tool button to choose the stamp from the drop-down list then click with the &LMB; to place the stamp. + + + A single click just places a square stamp (useful for icons). + To add a rectangular stamp you can click with the &LMB; and hold to place the top-left point, then drag to place the bottom-right one. + + + It is possible to define the Opacity and Stamp symbol for the stamp. Just right-click on the stamp icon created and select the Properties menu item. + + + + This feature is experimental. Custom stamps inserted in &PDF; documents are not visible in &PDF; readers other than &okular;. + + + + + + + + These are the default annotations provided by &okular;. Using the Annotations page of the configuration dialog + you can add your own annotations like custom stamps, text markup or a geometrical shape with inner color to highlight regions &etc; + + + + It is possible to add &latex; code into the text of annotations. Please add $$code$$ to the text of annotation, where code is any valid &latex; equation, and follow instructions on the screen to make it render by a &latex; distribution installed in your system. + + + + It is possible to configure the current tool options using the annotating toolbar itself. The table below describes exactly what the default set of annotating toolbar configuring buttons does. + + + + + + + Button + + + Option Name + + + Description + + + + + + + + + + + + + + + + + Line width + + + + + Click on the tool button to choose the width from the drop-down list. + + + + + + + + + + + + / + + + + + + + + + + Annotation color + + + + + Click on the tool button to choose color of text or border of your annotation. You can chose one of the predefined colors or click on the Custom Color... item to open the color selection dialog. + + + + + + + + + + + + + + + + Annotation fill color + + + + + Click on the tool button to choose a fill color of your annotation. You can chose one of the predefined colors or click on the Custom Color... item to open the color selection dialog. + + + + + + + + + + + + + + + + Annotation opacity + + + + + Click on the tool button to choose annotation level of opacity from the drop-down list (100% is for the opaque annotations). + + + + + + + + + + + + + + + + Annotation font + + + + + Click on the tool button to open the font selection dialog. + + + + + + + + + + + + + + + + Advanced settings for the current annotation tool + + + + + Click on the tool button to open the general configuration dialog for your annotation. + + + + + + + + There are three additional utility buttons on the default annotating toolbar. + + + + + + + Button + + + Description + + + + + + + + + + + + + + + + + Add the current annotation to the Quick Annotations menu on the main toolbar. + + + + You can use the default shortcuts from &Alt;9 to &Alt;0 to select the quick annotation actions any time you like even with the annotating toolbar hidden. + + + + + + + + + + + + + + + + + When checked keep the current annotation tool active after use. + + + + + + + + + + + + + + + + Hide the annotating toolbar. + + + + + + + + By pressing &Shift; you can constrain the angle of line and polygon annotations to 15° steps, and the ratio of shape annotations (⪚ Rectangle, Ellipse) to 1:1. You can also get a toolbar button from Configure Toolbars.... + + + The contents of the Quick Annotations menu can be configured using the Annotations page of &okular; configuration dialog. This page can be opened by clicking Quick Annotations button, then choosing Configure Annotations... from the pop-up menu. + + + + Activating the annotating toolbar will make you switch to the Browse Mode. + + + + You can stop the construction any time by pressing again on the button of the + annotation you are constructing, or by pressing the &Esc; key. + + + The newly constructed annotation will have as author the author you set in the + Annotations page in &okular;s + configuration dialog. The Annotations page can also be used to configure the content of the annotating toolbar. + + + + Removing annotations + + To remove an annotation, just click on it with the &RMB;, and select + Delete or select an annotation using the &LMB; and press the ∇ key. + + + When removing the annotation, its window will be closed if open. + + + + This option could not be enabled because the document does not allow removing + annotations. + + + + + Editing annotations + + To edit an annotation, click on it with the &RMB; and select + Properties. A dialog will appear with the general + annotation settings (like color and opacity, author, &etc;) and the settings specific + to that annotation type. + + + Annotation Property Dialog + + + + + + Annotation Property Dialog + + + + + To move an annotation, hold down the &Ctrl; key, move the mouse pointer on it and + then start dragging with the &LMB;. + + If you click with the &LMB; on an annotation, it gets selected. Resize handles appear on the + selection rectangle. When the cursor is moved over one of the 8 resize handles on + the corners or edges, the cursor shape changes to indicate the resize mode. Click anywhere + else on the annotation to move it. + Pressing &Esc; or clicking an area outside the annotation cancels a selection. + + Resizing is only applicable for annotation types Inline Note, Typewriter, Stamp and Ellipse. + + + + Depending on the document permissions (typically with &PDF; documents), some options + can be disabled. + + + + + + Bookmark Management + + &okular; has a very flexible bookmark system. &okular; saves the position on the page in bookmark and allows you to define more than one bookmark per page. + + + To manage bookmarks in &okular; you can use Bookmarks view from Sidebar, Bookmarks menu or context menu of document view (click with &RMB; to open it). + + + Bookmarks view + + To open Bookmarks view, click on the Bookmarks tab at the top of the Sidebar. If the Sidebar is not shown, click the Show Sidebar button on the toolbar or the menu item, or the F7 SettingsShow Sidebar menu item to make it visible. + + + Bookmark view context menu + + + + + + Bookmark view context menu + + + + + The filter bar at the top of Bookmarks view can be used to filter the content of bookmark list pane according to the text in the box. + + + The list pane permits to view the bookmark list in a tree-like fashion: each document in the list can be expanded or collapsed by clicking on the < or v icon next to it. + + + Click on icon below the list to show only the bookmarks from the current document. + + + Right-click menu of document item can be used to open document, rename its item or remove it from the list. Remember that the removal of a document item leads to the removal of all bookmarks in the corresponding document. + + + Right-click menus of individual bookmark items allow you to go to the bookmark, rename or remove it. + + + The Right-click menu of items in the table of contents can be used to create bookmarks or go to the next or previous bookmark. + + + + + + Command Line Options + + Though &okular; may most often be started from the &kde; program menu, or a desktop icon, it can also be opened at the command line prompt of a terminal window. There are a few useful options that are available when doing this. + + + Specify a File + + By specifying the path and name of a particular file the user can have &okular; open that file immediately upon startup. This option might look something like the following: + + % okular + + + + For &PDF; documents, the name can be given as document_name#named_destination where named_destination is a particular named destination embedded in the document. + + + + + Other Command Line Options + + The following command line help options are available + + + + okular + + Open a page with a given number in the document. Also available through okular + + + okular + + Start the document in presentation mode. + + + okular + + Start with print dialog. + + + okular + + Start with print dialog and exit after printing. + + + okular + + Unique instance control. + + + okular + + Allows to prevent &okular; window raising after the start. + + + okular + + Tries to find and highlight a given string in the document. Only works if just one document is given as an argument of the okular command. + + + + + + Fit window to page + + The Fit window to page feature resizes the window so that it is exactly the same size as the page at the current zoom factor. + If the page doesn't completely fit on the screen, the window is enlarged so that the largest possible part of the page is shown. + + + This feature can be accessed by using the keyboard shortcut &Ctrl;J. + + + + + + The Menubar + + + The File Menu + + + + + + &Ctrl;O + + File + Open... + + + + + Open a supported file or &okular; document archive. If there is already an opened file it will be closed. For more information, see the section about Opening Files. + + + + + + + + File + Open Recent + + + + + Open a file which was used previously from a + submenu. If a file is currently being displayed it + will be closed. For more information, see the section about + Opening Files. + + + + + + + + File + Import PostScript as &PDF;... + + + + + Open a &PostScript; file and convert it to &PDF;. + + + + + + + + + &Ctrl;&Shift;T + + File + Undo close tab + + + + + Reopen the last closed document. This action is active only if you have closed some document in tab during the current session. + + + + + + + + File + Open Containing Folder + + + + + Open folder that contains the current document in your favorite file manager. This action is especially useful for the case when you have downloaded a &PDF; file from the internet that opens itself in &okular;. The location of this file may not be clear or easy to find without this feature. + + + + + + + + + &Ctrl;S + + File + Save + + + + Saves the document including all the changes (annotations, form contents, &etc;), provided the document backend supports saving those changes. If the backend does not support saving the changes, the user will be given the option to either discard or to save them together with the document in an &okular; document archive. + + + + + + + + &Ctrl;&Shift;S + + File + Save As... + + + + Saves the document under a new name including all the changes (annotations, form contents, &etc;), provided the document backend supports saving changes. If the backend does not support saving the changes, the user will be given the option to either discard or to save them together with the document in an &okular; document archive. + + + Note that, due to the way this is implemented, even if there are no changes to the file, the new file need not to be an exact bit-for-bit copy of the original file (⪚ can have a different SHA-1 hash, &etc;). + + + + + + + + + F5 + File + Reload + + + + Reload the currently open file. + + + + + + + &Ctrl;P + File + Print... + + + + + Print the currently displayed document. Please take into account that &okular; has some specific options for printing &PDF; which are available via pressing the Options >> button then choosing the &PDF; Options. Use these options to print your annotations or configure rasterization mode if you have problems with printing some symbols or need to change the scale mode. + + + + The scale mode options are only available when you check the Force rasterization option. + + + + + + + + + File + Print Preview... + + + + + Show a preview of how the currently displayed + document would be printed with the default options. + + + + + + + + &Alt;Return + File + Properties + + + + Display some basic information about the document, such as + title, author, creation date, and details about the fonts used. The available information + depends on the type of document. + + Please pay attention on the information about substituting font in the Fonts tab of the Properties dialog. Many problems with font rendering can be solved by installing of the substituted fonts. + + + + + + + File + Embedded Files... + + + + Show the files embedded in the document, if the document has any. + For more information, see the section about the + Embedded Files. + + + + + + + File + Export As + + + + This item contains the export formats the current document can be exported to. + The first entry for all kind of documents is always Plain Text.... + The second entry is Document Archive, which allows you to save the document with your annotations into an &okular;-specific archive format. Thus it is easily possible to share the original document and your annotations with other &okular; users or work with them collaboratively. + + + + + + + File + Share + + + + This item contains the services which can be used to share the current document with other people or send it to your devices. + The entries in this sub-menu are controlled by the system. They depend on the current document format and the installed KPurpose plugins. + + + + + + + &Ctrl;Q + File + Quit + + + + Close &okular;. + + + + + + + The Edit Menu + + + + + + &Ctrl;Z + Edit + Undo + + + + Undo the last annotation editing command (creation and removal of annotations, editing arbitrary annotation properties, relocating annotations with &Ctrl;+drag, and editing the text contents of an annotation). + + + + + + + &Ctrl;&Shift;Z + Edit + Redo + + + + Redo the last undo step when editing annotations. + + + + + + + + + &Ctrl;C + Edit + Copy + + + + Copy the currently selected text in + Text Selection mode to the clipboard. + + + + + + + + + &Ctrl;A + Edit + Select All + + + + Selects all the text (if the document provides it). This works only in + Text Selection mode. + + + + + + + + + Edit + Select All Text on Current Page + + + + Selects all the text (if the document provides it) of the current page. + + + + + + + + + + &Ctrl;F + Edit + Find... + + + + + Show the find bar on the bottom of the viewing area that allows you to + search for a string in the document. + + + + + + + + F3 + Edit + Find Next + + + + Try to find the previous searched string again in the document. + + + + + + + &Shift;F3 + Edit + Find Previous + + + + Goes to the previous occurrence of the search string in the document. + + + + + + + The View Menu + + + + + &Ctrl;&Shift;P + View + Presentation + + + + Activates the Presentation Mode. For more information, see the + section about Presentation Mode. + + + + + + &Ctrl;&Shift;F + View + Full Screen Mode + + + + Enables the full screen mode. Note that + full screen mode is different from presentation mode insofar as the + only peculiarity of full screen mode is that it hides the window + decorations, the menubar and the toolbar. + + + + + + &Ctrl;+ + View + Zoom In + + + + Increase the magnification of the document view. + + + + + + + &Ctrl;- + View + Zoom Out + + + + Decrease the magnification of the document view. + + + + + + View + Zoom to 100% + + + + Zoom the document image to the actual size as prescribed by the document parameters. + + + + + + View + Fit Width + + + + Change the magnification of the document + view to a value that makes the pages' width equal to the document + view's width. + + + + + + View + Fit Page + + + + Change the magnification of the document view + to a value that makes at least one whole page visible. + + + + + + View + Auto Fit + + + + Change the magnification of the document view + to a value that, depending on the size relation between the page and the view area, automatically either makes the pages' width equal to the document view's width (like fit-width), the pages' height equal to the document view's height (like fit-height), or the whole page visible (like fit-page). + + + + + + View + View Mode + + + + This submenu makes you choose the view mode for the pages. The possible + options are: Single Page (only one page per row), + Facing Pages (two pages per row, in a book style), + Facing Pages (Center First Page) and + Overview (the number of columns is the one + specified in the &okular; settings). + Additionally, you can enable the Continuous mode. + In continuous mode, all pages of the document are shown, and you can smoothly + scroll through them. Otherwise, only one page (or one row of pages) is shown + at a time. + + + + + + View + Orientation + + + + + This submenu allows you to changes the orientation + of the pages of the document. + + + + The rotation is applied to the orientation of every page. + + + + You can select Original Orientation to restore + the orientation of the document, discarding all the rotations applied + manually. + + + + + + + View + Trim View + + + + + This submenu allows you to remove the white border of pages when viewing pages (Trim Margins item) or trim viewport to selection (Trim To Selection item). + + + The trim to selection mode allows you to draw a selection over the rendered page in order to define a visible bounding box to be applied to all pages in the document. Selecting a small trim bounding box enforces minimum dimensions size (20% as a percentage of total page size). + + + The trim margins mode is persistent across &okular; restarts. The trim to selection mode is forgotten across &okular; restarts. + + + When you switch &okular; from trim margins mode to trim to selection mode, the view jumps out of trim margins mode for the bounding box selection interaction. + + + The trim mode can be deactivated by selecting the same menu item that activates it once again. + + + + + + + View + Show/Hide Forms + + + + + Show or hides the display of the form fields of the + document. + + + + This menu item is active only if the current document has form + fields. + + + + + + + + + + The Go Menu + + + + + Go + Previous Page + + + + View the previous page of the document. + + + + + + Go + Next Page + + + + View the next page of the document. + + + + + + &Ctrl;&Home; + Go + Beginning of the document + + + + Go to the beginning of the document. + + + + + + &Ctrl;&End; + Go + End of the document + + + + Go to the end of the document. + + + + + + &Alt;&Shift;&Left; + Go + Back + + + + Go back to the previous view of the document. + + + + + + &Alt;&Shift;&Right; + Go + Forward + + + + Move forward to the next view of the document. This only works if you have already moved back before. + + + + + + &Ctrl;G + Go + Go to Page... + + + + Open a dialog which allows you to go to any page of the document. + + + + + + + The Bookmarks Menu + + + + + &Ctrl;B + Bookmarks + Add/Remove Bookmark + + + + + Add or remove a bookmark for the current position. + + + + + + + Bookmarks + Rename Bookmark + + + + + Rename a bookmark for the current position. + + + + + + + Bookmarks + Previous Bookmark + + + + Go to the previous bookmark, or do nothing if there + are no bookmarks prior to the current one. + + + + + + Bookmarks + Next Bookmark + + + + Go to the next bookmark, or do nothing if there + are no bookmarks after the current one. + + + + + + Bookmarks + No Bookmarks + + + + This is an always disabled action that appears in this menu only if the current document has + no bookmarks. Otherwise a list of all bookmarks is displayed here. Clicking on these bookmarks + allows you to go directly to the associated position. + + + + + + + The Tools Menu + + + + + &Ctrl;1 + Tools + Browse + + + + The mouse will have its normal behavior, &LMB; for dragging the document and following links and &RMB; for adding bookmarks and fit to width. + + + + + + &Ctrl;2 + Tools + Zoom + + + + The mouse will work as a zoom tool. Clicking &LMB; and dragging will zoom the view to the selected area, clicking &RMB; will bring the document back to the previous zoom. + + + + + + &Ctrl;3 + Tools + Area Selection + + + + The mouse will work as a rectangular region selection tool. In that mode clicking &LMB; and dragging will draw a selection box and provide the option of copying the selected content to the clipboard, speaking the selected text, or transforming the selection region into an image and saving it to a file. + + + + + + &Ctrl;4 + Tools + Text Selection + + + + The mouse will work as a text selection tool. In that mode clicking &LMB; and + dragging will give the option of selecting the text of the document. Then, just + click with the &RMB; to copy to the clipboard or speak the current selection. + + + + + + &Ctrl;5 + Tools + Table Selection + + + + Draw a rectangle around the text for the table, then use the click with the &LMB; + to divide the text block into rows and columns. A &LMB; click on a existing line removes it and merges the adjacent rows or columns. + + + + + + &Ctrl;6 + Tools + Magnifier + + + + Activates the magnifier mode for the mouse pointer. Press and hold the &LMB; to activate magnifier widget, move the pointer for panning through the document. The magnifier scales each pixel in the document into 10 pixels in the magnifier widget. + + + + + + F6 + Tools + Annotations + + + + Open the annotating toolbar. The annotating toolbar allows you to add + annotations on the document you are reading. For more information, please see the + section about Annotations. + + + + + + Tools + Speak Whole Document + + + + + Tools + Speak Current Page + + + + + Tools + Stop Speaking + + + + + Tools + Pause/Resume Speaking + + + + These items allow you to speak the whole document or just the current page and stop speaking using the system speech service. + This service is provided by a &Qt; library which wraps speech-dispatcher on &Linux;, and native speech systems on other platforms. + It is possible to choose the current voice via &okular; Accessibility configuration page. + The Speak ... actions are enabled only if a speech service is available in the system. + + + + + + + The Settings and Help Menu + Apart from the common &kde; Settings and Help menus described + in the Menu chapter of the &kde; Fundamentals documentation + &okular; has these application specific menu entries: + + + + + F7 + Settings + Show Sidebar + + + + Shows or hides the Sidebar. + + + + + + Settings + Show Page Bar + + + + Toggle the page bar at the bottom of document area on and off to save vertical place in &okular; window. Note that the page numbers will be shown on the default toolbar anyway. + + + + + + Settings + Configure Backends... + + + + Opens the Backend Configuration + window. + + + + + + + + Configuring &okular; Backends + + You can configure &okular; backends by choosing + Settings + Configure Backends... + . + Currently, configuration options are provided for EPub, &PostScript;, FictionBook, Txt, OpenDocument Text, and &PDF; backends only. + + + The backends configuration dialog + + + + + + The backends configuration dialog + + + + + Using backend configuration pages for EPub, FictionBook, Mobipocket, Markdown, TXT, and OpenDocument Text you can define the font to render documents in the corresponding formats. The Choose... button in these pages opens standard &kde; font configuration window. Please refer to the &kde; Fundamentals documentation for the details. + + + The description of Markdown, &PostScript; and &PDF; backends configuration pages can be found below. + + + Markdown backend configuration + + You can configure &okular; Markdown rendering backend based on Discount by choosing Markdown from the list on the left part of the configuration dialog. An additional configurable option is as follows. + + + + + + Enable SmartyPants formatting + + + When checked this option allows &okular; to process SmartyPants formatting. Such formatting can be troublesome in the technical texts because of unwanted substitutions (⪚, it replaces (C) with a copyright symbol). This option is checked by default. + + + + + + + + &PostScript; backend configuration + + You can configure &okular; &PostScript; rendering backend based on Ghostscript by choosing Ghostscript from the list on the left part of the configuration dialog. The only configurable option is as follows. + + + + + + Use platform fonts + + + This option determines whether Ghostscript should be allowed to use platform fonts, if unchecked only usage of fonts embedded in the document will be allowed. This option is checked by default. + + + + + + + + &PDF; backend configuration + + You can configure &okular; &PDF; rendering backend based on Poppler by choosing &PDF; from the list on the left part of the configuration dialog. The only configurable option is as follows. + + + + + + Enhance thin lines + + + + Drawing lines in &okular; is implemented in two steps: generation of the clipping path and filling this clipping path. When the line in the original document is less than one pixel this two step implementation could cause problems. For those lines, the clipping path is filled with the filling color that depends on the thickness of the line part inside the clipping area. If the part of the line inside the clipping area gets very small the contrast between the shape and the background color can become too low for the line to be recognizable. The grids of such lines then looks very unpretty. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Thin line (red), its clipping path (dashed line) and pixel boundaries (black solid lines) + Thin line shown at a low contrast + + + + + + To enhance the look of the thin lines &okular; implements two options. + + + The first option is Solid. With this option &okular; adjusts clipping path and line position so that clipping path and line are on the same pixel boundary, &ie; &okular; enlarges the thin lines to one pixel on the output device. This mode is similar to the Enhance thin lines in Adobe + Reader. If this option is chosen, the thin lines are always enlarged. + + + + + + + + + Thin line with Solid enhancement + + + Thin line with Solid enhancement + + + + + + The second option is Shape. With this option the clipping path and line are adjusted to pixel boundary as well, but the line intensity is corrected according to its width. + + + + + + + + + Thin line with Shape enhancement + + + Thin line with Shape enhancement + + + + + + The thin lines are not enhanced by default (option No). + + + + + + + + + Configuring &okular; + + General configuration + + You can configure &okular; by choosing Settings + Configure &okular;.... + The configuration dialog is split into six sections. This chapter describes the available + options in detail. + + + + General + + + Accessibility + + + Performance + + + Presentation + + + Annotations + + + Editor + + + + The configuration dialog + + + + + + The configuration dialog + + + + + Depending on the currently installed backends, the Settings + Configure Backends... menu item could be enabled. + This particular configuration dialog holds the configurations of the backends that can + actually be configured. + + + + General + + + Use smooth scrolling + + Whether to display animated transitions when scrolling using the mouse wheel and keyboard. + + + + Show scrollbars + + Whether to show scrollbars for the document view. + + + + Link the thumbnails with the page + + Whether the thumbnails view should always display the current + page or not. + + + + Show hints and info messages + + Whether to show some informative messages on startup, file + load, &etc; + + + + Display document title in titlebar if available + + Whether to show the current document title in the titlebar of &okular; window. If no metadata for title + found in the document or this item is unchecked &okular; shows filename of the document. + + + + + When not displaying document title + + You can choose any of two options, Display file name only or Display full file path. + + + + + Use custom background color + + Enables choosing the document background color (the color around the displayed page). By default, the &Qt; toolkit color is used when this option is unchecked. + + + + + Open new files in tabs + + Whether to open new documents in tabs. The tabs are disabled by default. + + The default shortcuts to switch between tabs are &Ctrl;. (Next tab) and &Ctrl;, (Previous tab). + + + + + Switch to existing tab if file is already open + + Whether &okular; should switch to a tab if the file is already open instead of opening a new tab. This option is disabled by default. Can be toggled only if Open new files in tabs is enabled. + + + + Obey DRM limitations + + Whether &okular; should obey DRM + (Digital Rights Management) restrictions. DRM limitations are used + to make it impossible to perform certain actions with &PDF; documents, + such as copying content to the clipboard. Note that in some configurations + of &okular;, this option is not available. + + + + Reload document on file change + + Whether opened files should be automatically checked for + changes and updated, if necessary. + + + + Show backend selection dialog + + Whether &okular; should ask the user which backend to use in case of more + than one backend able to open the current file. If unchecked, &okular; will + 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 + + + This option represents the number of columns to use in the overview mode. + + + + + Page Up/Down overlap + + + Here you can define the percentage of the current viewing area that should be visible after pressing &PgUp;/&PgDn; keys. + + + + + Default Zoom + + + This options specifies the default zoom mode for file which were never + opened before. For those files which were opened before the previous zoom mode + is applied. + + + + + + + Accessibility + + + Draw border around links + + Whether to draw a border around links. + + + + Change colors + + Enables the color changing options. + + + + Invert Colors + + Inverts colors on the view, &ie; black objects will be shown white. + + + + Change Paper Color + + Changes the paper's color, &ie; the document's background. + + + + Change Dark & Light Colors + + Changes the dark and light color to your preference, that means + black will not be rendered as black but as the selected dark color and white + will not be rendered as white but as the selected light color. + + + + Convert to Black & White + + Converts the document to black and white. You can set the + threshold and the contrast. Setting the threshold to a higher value + by moving it to the right will result in lighter grays used. + + + + Invert Lightness + + Inverts lightness of all colors. + Light and dark colors will be swapped, but hue and saturation will not be affected. + The Contrast in images will usually be worse than in Invert Luma (sRGB Linear). + + + + Invert Luma (sRGB Linear) + + Inverts luma of all colors. + Light and dark will be swapped, but hue and saturation will not be affected. + The Contrast in images is preserved better than in Invert Lightness, + but graphics and colorful text markup usually look worse. + Uses sRGB luma coefficients, but no gamma correction. + + + + Invert Luma (Symmetric) + + Inverts luma of all colors, using symmetric luma coefficients. + Light and dark will be swapped, but hue and saturation will not be affected. + Very similar to Invert Lightness, + but the contrast is in some cases better. + + + + Shift Hue Positive + + Shifts hue of all colors by 120 degrees. + Can mitigate some contrast problems in colorful graphics. + + + + Shift Hue Negative + + Shifts hue of all colors by 240 degrees. + Can mitigate some contrast problems in colorful graphics. + + + + Engine + + Allows you to choose the text-to-speech (TTS) engine to be used by &okular;. + The default is speechd TTS, but you can use all + languages and voices depending on the available synthesizers on your platform. On &Linux;, + speech-dispatcher is used by default to determine available voices. + + + + + + Performance + + + Enable transparency effects + + Draw selections and other special graphics using + transparency effects. Disable the option to draw them using + outline or opaque fill styles and increase speed on selections. + + + + Memory Usage + + &okular; can achieve best performance by tuning the memory usage, based on your system and your tastes. + The more memory you let it to use, the faster the program will behave. The Default profile is good + for every system, but you can prevent &okular; from using more memory than necessary by selecting the Low + profile, or let it get the most out of your system using Aggressive. Use Greedy profile to preload all + pages without risk of system memory overfull (only 50% of total memory or free memory will be used). + + + + Rendering + + Using this group of options you can improve text and image rendering in &okular;. The result depends on the device to display the document. + Enable Text Antialias and Enable Graphics Antialias items can be used to switch on and off spatial anti-aliasing of text and images in document, correspondingly. + Enable Text Hinting item is meant to be a switcher for font hinting. + Antialiasing and hinting change how the documents are displayed, you may want to tweak them to your preference. + + + + + + Presentation + + + Advance every + + Enables automatic advancing of pages given a time period. + + + + Loop after last page + + When navigating on presentation mode and going past the last page the first page will appear. + + + + Touch navigation + + Allows you to fine-tune touchscreen navigation with tapping in the presentation using the following three possible values: + + + Tap left/right side to go back/forward: Tapping on the left (right) half of the screen makes the presentation go to the previous (next) slide. + + + Tap anywhere to go forward (default): Tapping on the screen makes the presentation go to the next slide, no matter where the screen is being tapped. + + + Disabled: Screen tapping does not do anything. + + + + + + Background color + + The color that will fill the part of the screen not covered by the page when on presentation mode. + + + + Mouse cursor + + Whether the mouse should be always hidden, always shown or hidden after a small time of inactivity. + + + + Show progress indicator + + Whether to show a progress circle that shows the current page and the total number of pages on the upper + right corner of the presentation screen every time you change the page. + + + + Show summary page + + Whether to show a summary page at the beginning of the presentation with the title, author and number of pages of the document. + + + + Enable transitions + + Use this check box to enable or disable transition effects between pages. + + + + Default transition + + The transition effect between page and page if the document does not specify one. Set this to Random + Transition to make &okular; randomly choose one of the available effects. + + + + Placement + + In this section you can select the Screen used to display the presentation. + Current Screen is same screen of the &okular; window that starts the presentation mode. + Default Screen is the screen marked as default in the xinerama configuration. + Screen 0, Screen 1 &etc; are the available screens. + + + + Drawing Tool Configuration + + Manage the colors of the pencil used when drawing on the pages during the presentation mode. + + + + + + Annotations + + The Annotations page of the configuration dialog + + + + + + The Annotations page of the configuration dialog + + + + + + Author + + The author of the contents added on a document. + Default is the name from the Password & User Account page of the &systemsettings; module Account Details. + + + + Annotation tools + + + This pane is used to configure your annotating toolbar. + + + There are five buttons (Add, Edit, Remove, Move Up, Move Down) and a list box (which lists the contents of the current annotating toolbar) which are used to configure the toolbar. + + + If you need to add some tool button on the toolbar click on the Add button. You can choose the Name, the Type and the Appearance of the created tool. + + + + Please remember that annotation tools in &okular; are highly configurable. For example, you can have two buttons of the same tool but with different color. Do not hesitate to experiment in choosing the button set that is exactly tailored to your workflow. + + + + Click on some item in the list box then click on the corresponding button at the right part of the page to edit, remove, move up or move down the item. The keyboard shortcut of the tool (keys from 1 to 9) depends on its position in the list of annotating toolbar. + + + + + 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 + + + + + + + Editor + + + Editor + + Choose the editor you want to launch when &okular; wants to open a source file. + This is the case when the document has references to the various points (usually row and column number) of sources it was generated from. The &DVI; format supports natively the addition of the information about the sources the &latex; document was generated from. A similar system exists for &PDF; documents, called pdfsync, which stores these extra information in an external file named after the &PDF; file itself (for example mydocument.pdfsync for mydocument.pdf). + + + &okular; ships with preconfigured settings for the following editors: &kate;, Kile, SciTE, &Emacs; client, LyX client, TeXstudio, and TeXiFy IDEA. + + + + To use inverse search in &kile;, you have to compile your &latex; file with the Modern configuration. + + + + + + Command + + This is the command and its parameters to invoke the selected editor with the source file of the actual document. + This field will be filled automatically if you use one of the preconfigured editors. Otherwise, please choose Custom Text Editor in Editor drop down box and refer to the documentation on your favorite editor to find the proper command. + + You can use the following placeholders: + + + %f - the file name + + + %l - the line of the file to be reached + + + %c - the column of the file to be reached + + + If %f is not specified, then the document name is appended to the specified command. + + + + + + + Credits and License + + + Program Copyright: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Current maintainer + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it &kpdf; developer + + + + Documentation Copyright: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Author + Titus Laska titus.laska@gmx.de Some updates and additions + Pino Toscano pino@kde.org + + + &underFDL; + &underGPL; + + + &documentation.index; + + + + diff --git a/doc/mainwindow.png b/doc/mainwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..f091bbdbff16725fcad196c825fb0d0d7c130202 GIT binary patch literal 28233 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 literal 0 HcmV?d00001 diff --git a/doc/man-okular.1.docbook b/doc/man-okular.1.docbook new file mode 100644 index 0000000..06445b9 --- /dev/null +++ b/doc/man-okular.1.docbook @@ -0,0 +1,136 @@ + + +]> + + + + +Okular User's Manual +YuriChornoivan +Okular man page. +yurchor@ukr.net +2019-02-14 +Okular 1.7 +KDE Applications + + + +okular +1 + + + +okular +a universal document viewer + + + + +okular +Okular options +URL + + + + +Description +okular +is aimed to show documents in different formats. + + + +Okular options + + + + + +Open a given page in the document. + + + + + + +Start the document in presentation mode. + + + + + + +Start with print dialog. + + + + + + +Start with print dialog and exit after printing. + + + + + + +Unique instance control. + + + + + + +Allows to prevent Okular window raising after the start. + + + + + + +Find a string on the text. + + + + + +Arguments + + + + +An address of the document to be opened. For PDF, can be given as document_name#named_destination where named_destination is a particular named destination embedded in the document. + + + + + +Feedback +On IRC, irc.freenode.net #okular or via email, okular-devel@kde.org or on the web, <https://okular.kde.org/>. + + + +See Also + +More detailed user documentation is available from help:/okular +(either enter this URL into &konqueror;, or run +khelpcenter +help:/okular). +kf5options(7) +qt5options(7) +There is also further information available at +https://okular.kde.org/ + + + +Copyright +Copyright © 2002 Wilco Greven, Christophe Devriese +Copyright © 2004-2005 Enrico Ros +Copyright © 2005 Piotr Szymanski +Copyright © 2004-2012 Albert Astals Cid +Copyright © 2006-2009 Pino Toscano +License: GNU General Public Version 2 <https://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/doc/presentation.png b/doc/presentation.png new file mode 100644 index 0000000000000000000000000000000000000000..3cfc1026a890d249b93769bae345ffa8ddb931d8 GIT binary patch literal 53804 zcmeFZWmHsc8#atBpdun7QW8T9B?!_WNDa*}bcuj;cPoNQNDM6vLkub1Aku??fJlRM zgLK1tjo$bDJm2&E`_}vCTkD>^Tnyu8?<>wYj^jM{1Sly;-NbuiGy<=t#ti_0cVy6=T$gfFaoFD1_vh? z!Fc(M2xp57=d<(`NhtO|aU`L4FaG)K=P1li*IEUq(adKrt)2QaH;#{PGG3Os_3Gp* zIA675e8;^mtA3-zLr{O|Snv_vYviSe4Hs}8!A~jJj_cW54b-TW?7=m^t|nelAs_wm zcH2d`YTb_X&d;CrGwYPkZSS|*#{J}cTT}BDM|7qN?mX_@?xCrYHGfy)EuB|N|G@72 z_cu=aBOd#R{E~f@8g(KuY3b|Kk%&ly&TU@uGVP-NFwb>PnlvI?8Wzr9LS`#2haOSs z(Lo79IM;5i3V0;_L>$7Hay0#bNRn>ECFRpH*_W(42Rr^y znm*$7(C@a`bvKu@TW7aD+$O^gK1LwQoaD0$3bIf~f$gU;J)-PLj5)KYD}wwM#p9oS z1KRBvjz&F=z(9=oAzMS|WJSokE8Qi-vQ7}RxjETo?vXUqpQBH=Kn2-An`SuWwj{YA zK*B%4+q;)ZI-xG_THhP6Q(+oi6T z7z=7?eQCNPvfguG>(loxp~!5EarN`Auk%>B(~P$=6=lp#>J0n4O9K(@1@WSK+X`~q6B(t?2*KX=qXCpcpow9tWM0OiNVMCGaHC~^Ka_3rkXJ&BIzrTr* z-1IZ8l*mQj9LL)iM0Y(eYSLssSTL|ZL{TWj;$nvZ%kaJ1n~O@zhKnw?-^%{<-gM0C z*X(g~_=*GqCTInNUI}^TKTf-n&VTYIPH^9m8X5T7`|e+EENS8eY>a%S4N;8 zI?gKBZO0UBNa!0$McvgJOhUmwnW~5)l;MAlCALAPj>)%=!++IVj?rh=7DAQkmL#6S zy@uG(!Dq%A^J>peqrY^Bh9k7O(p;P0oOEwm`C{hv?!h2ywqN9~gIUVtoJKy3MBG(< z?U7w8UCkm_E;5}(9zeT^imfiEi}IC-$4d)D{yAh6s}!nG{1g{r3NNpB9i^n$+e9}N zEe%tni@iEODcEG$*80Swpbyr3Gkh*yDR`BFCj&K;>N-~VbE9E$=2ojYj}OhN57CG) zD(p=s7bxFKwZJyFh1Npv>Jo$os{6=cNUZ+e%;Q5vW?z{S zvlGZNvb9{UK~$GlRA;-`oA|3r-+U=bMCRB!;`lf9e=55Qi7HKBu4BM1C`46Xex|-T zx^h_-%8hz=5w=^=a8A*&z)m}9nU3mfH_4o>hDx#CqQD>BW%X9`!2S49SO2d1G)(7R zx>`PmnZD9L%dMxx)HBI&Bdb?f{r#;5(j*Dy2hq8`#cIJh+&sZPW3M*X9>_fo`V@RD z66jUBF@rR>^jsMtw_KC`RO$6!`z!C9{Sf`~J`=?%Mnsx8%9Bu;6 z$%00~sW--s)O35{N#Bs>p7+W(A+sJP|K$T8XO%?ZbsD-&4dzi#i z2pcCAlg=aqeJwV7MY^P+!^SV!Sx$9e#Ny2c0}PaN5nqai0ohsmx$VteKN)zjt|l6BJOYTV{AN&du~bTKCKjVjl2^nCUV}TjCxRFw=8!z zgp9^^ZC+^D3DVYZb&JoN*|pn35+1;no1J&|0tPvm{>gDS2H{t$Fr6ewfd-36k(|f< zpWRK@$pX78?0hF(?WaPSupLP_z?jAo~XoCza zUY0r5ORe2clm@OjT#5BevC4=*0kn|`!obe0eMT{fR3iE^{pbRl-ZPaFfnWP+(|9L4 z>hJ6p&J1}I^|)+Kg`iJxU8n?y-*_}9BH-tpsr`uvC_Yr?uY+Qaf9~-3Tlh?DESG^h z8;Rj|)%}k>;>jBVFz)s8ltE2D^TKQM69E)M#{$kWIa7p@`*rt3i6aqzdB}UU6x0Le zyjSewck%eTKO(fk5l=hEjTNe{DdhN)&B{#Ec>?NCgo^ zcPq!%w7wbg7_ETid}$QD>ujBdTH(gHPh6!_wHtibO;XI7ig6-a9Js2(wO{r=j5==^pV-9`FSj+BNqc5X1Ptq{HvDsgE z^YuG zoyjh=xi#D)7(smVW_L;oQtI#)1;LwR?Qoh<)al*{G5Q(td!l=!Z?c${Mo17)JPJ3X zjc*)H1vbK^BeLJVuO6jU-cg+9PZ~t?W_}AQIVMQ<=RYgE@=xjuu}|DOIbC`4u821_ zpsa|CMG@7=W8A#z$S*00FAPOvEFL^ZJ5x^%6F7`MS{={705e`+e5Te&-%|_ z0sR-^oE9rD1ema=7U$5r>MW}y*4Yv_2z%1lPOR008Zm_JU5UboF$hB0c4&R@!lh2X zq)!h}sw|FQN+q!=u35Lh`yazqZ{YKbdVQnz0j%Xni~)dWoGXoGicC z?MK&(76|WoTxg?>_^&`-e>oM^_aOy7)eGWxjNRGRuFz8Fq3mGB^XdnNeXq0siNnd+ za47n0|JN_nVoWyTSF)@M^tDh7cWgJGvx1LwKz#{=NG@ zaQ;r)&{_U9*_^yp&-)*SYmiYoHQ7k%o{P`eWu13vOqW zzmV5yy)=2@*vTz0+n67Dp(#6)Endu|Xv+kJf;QWkOe?e2Jhu-nu-#PwMyJ)05^zWB_7Vo7L+Gz5HnA5BLaWrVtj0~jYv5{iohNGXIAd`OG~D6R}A9QOCgq<~HXu8Rzp z`TOJ!=_@!m&r!%=#GSuS2J{yP2YW%}-zRgz|GvxRzfMMiwfO5Uf1eDP^uI&;vlsua z(!aL!moNP5asS4pe?#TpIpW`h@>h=jH|_olPX5J9|DwwO>)2c9^3VBs`giZ%xjkr_ zdeqt3dDu~1(An51dMI~JprEMe;O(8XAV(jOm!EI^=>BY>#pn|xkqc=O0Iv$BuSa#`_gT)(RTV+|{!bC^qgh$i@D&zf!;*?y2KE$|(|fso``lezepqf=tN0 zv}P$Ye$3z<#r*j8J1XxX&HBT6vI_G7=mwwZcy(E>UR^cMUV5moeGBd^S%bx6lWxb; zqg{uEWS{y`ul@1yVUy%FAQmEJs9_mO(r{uNYVlmP{H>(Xap%#lC`RQkQBYM(6sz_R zA_#bAubQjo#BKilVeNT=PF3+fsi8~^Ti26`@|xA+po(OR!nz-#Ya?ZAHqR7fp|efX zEkWZ0>iS(y0fH4j%fvB4o6SV)p(1CtOS~Jk+kq!GObdiw!Br4+r4RWwrN`{aZX?oaM>wjS*)H6707q0+cEI~bDbN(hD@R8L&b(yMc?%1Uy_SWVUoMXK(smh`yq zAE&&zg=YnJ8|Jdz#Zx0i<@MbQSOnYP;ZDC|-8Kc6>1`VRe3bjy;et>&P(emtu%g@3 z9*B4g4!<~|l!oI{)1mDlcaaD@|JyV?_jzqo_P;){nHVD?)GoJ7wQM7p4e+WbRAe$N zw;o>>KAa^QEHaeZ*sfWx?!00)Tx<+>;&NoN?z1p6=kwG3wwKc3uT?6nbv?$zsEiCV zhz+WKX;*L5AJ3yu#XF0=w2pP}Zc!{FADQ)`zLm>=uCFv0- zWO>eEwWy80-uZK5e}BwDC8S0z zUu(Uv;mkhHcGRlEzd*m_WfvVf5a;WRW&CHAKC_BBJy|#m?A|}7ct>pYAyO79Yb~3@ zh-=~2)1BzPjJDpW z+jnM2bVOPV79@Hc&c*1$+bv&Ek?7dI9`!jt9mj@(2Tv>)xjzGgN>0ppNUF3w-{mlD z`<0`uxjk$ZLM&9MVO(I+ljJR4@bF;L=iKe)CY9^Y3wmjWJ+JNZq!&Wtg*=>7WpY5M z8jJ8;NN@-lbUkgS4RzdI8Qfo|m`uDi-w~tly_C=8(n75MZTsuF0P|AsaZuC`(~(3X zWZ;BV-Yd7Q4u*v;k9#D~{cBGSfX|GlNd)QauaA#&59&k|S5Fwn=+5tr+K6muaaoTI z$tUs;)JVb%SdJy7i`)$o`JHOdGd=ge;Ip%QLQM;YQVNae+IK)EO59sXOtcN}| zLSC=&344oFzPv_m`zjZ>?Zjd65#1mIZt#qTR;lS!i13l=hA>!QVZAp8-H8G<{`e&J zLU{6UuY;*~Og+%eRx%r2YH`A+zvBe_kE3}XEio9uXE(0JNnyj}VUgu9r+T4Y-Owbp z-gA?#k8{PZNz`i^z`l4e+C~J4QO!Z%hL{Lbv)m?cY=}ryLqP^W z9G&mxUtwu&y}I9o2@fD*a32h_>WpNH;Mx1tM6h4b^t17eVIli;;31MKuiI_HZ6QOb z+*dk>z5c-0jp(?R*2=V+@|xH}c6tbA^kt~f-cy9KuZ66AQ_$1OG^GV*YsR zrTq%{LYEklT+@z0Fv4d+-!8rW$VVqbCTff+E8#_`%Jm}J@IQ7KcpvM8M#lH6?oyEP zSO<4yFM{h#@N(KS=00%JQsgE_<3b;w7%9*u5Y2 z>{ij%yF4b&&MmKycEO;g9!X~1YA(aNRg`kNWK~NLNkp7@xwqhUWz z3HO~vLd^SiKbwZrCyp#ennw5;4ljKoabB{ZUE}r&iMG}nuThn1@~D}TDigCt0!OB5 zC9XytO}(S4?Wu8EiMCIOtkD#GqcO{y_Gwru^5v#Yv($LC(`kdsm#BPHG4mt)213gx z2Q`|Tz0x^54zE~}QXWq8)2eO}$3D$WI8`uW7sK6bJeeB))F!2=OD;Mr6)*`*Q_LaT zY30WiBtpDDQ+~YEtY1UoF5&xErG~eapEv|;%XEm*XmI!2pY9I6n?**67S8`s79dX{y{%%h0J?sEK&q}WUW5Jq6V@(!|iSoR&Idv=%o`@4LR zM+b(B2F9sbQ9>{MVDQB*ql&DrP$t}B>o8_g81(Wjh`zU5-||3i#9osOUF3cBA>{I) zzE4IlwAk*+amB(>x4=dvD z;cP6c)krC9m|%-FkVz%eFC>DKA0PgRH$*OpalSh-UR;p6zx@QG1>arjZ^Iy(i<1fO z-w@ZS{>o6C{i3jNe2_>{aLSj<^xMM&zB!Z`#P#9rB``uGs=B_DNdfm9TLpSd0j+w0#S06JrV!dMU09XMAHwM)tl;Op7T@4%v(hyg^-X zlGGHJ8lNd#>4nZ~i0VblXw^rzZ^GQ&smWe27SDOd8I53pn1pEmub;d!IO!Ty z_Qn`qBkj987x6=AgUn0{*4y@ni}JO~0+VATbw*j50EEg6uG<^2NF*SQH=?>Kk~OHV zbI$Bwb2tuTK{E>NJw937-vh~wk6OG};y*F)JFieU*C%5c<>A}cZ(tJJS<*IokPund zC4ya{kAiN+vUsFVEe#DjqgmO=+II{*Xn)=TD{)JcrMy8&%+*eTCh~qoKOM2y>#vda zbC`_PclLRVvFzn`?t&5?P9m4K{O)`fhX=S(l1uGr+|8Re4gFwY?E#77An#O&LVUi6 zW49H(DvEhZG~t19e`BaA`l#|KRYjz*7fJnb#i7|Y0tClu}qe93gdZy>%N1NQC7tEL}No1>?R@9(<*}SobFt7y*=dxWl-$Jaav;*aTgDz<}wWZ}GDaHYhOfRfMqj;g- zZbmW&7p%6mDb=NGx8ztzUd4<$^au@lzdd*!cRY)P)@Ko4EKq_F7gO_Q8Z^D_egPR6 zwQ100fe>dTs{Ig6K;@|AkKBquj8@nXd?4jA4GWs-lVz8$zVq<(=N(z7d&!jyxUJnq zKl)sztNR1l%IV^5rn1*~EQfCMPh#DHxoL-F*}dV2Yft_zWn->~`* zZ@D8DOeG?`<0-N?WO#0aTuyyQ33V;Z_EXX_YFI(avUMy0B>( z>jLPEpRmd9BenCOH#0XwYz7N-jgsl~F!(Ciz{X%K2XNF@6awU64DhwDh8{w38!!#P z1x!bQ*>m?|0-Wm~!2HR_r;vDY;%}TsRhZ1#dZiPDH6`H?J;#R%@Y9p+o&<}LmYZyq zKYf4Jx7$t+ZR_WMyRJDKlQ?6f2NAsXAcX5Lf-i74aTkRnDZxWGfgHTxEw*B&&ceENnx`!;vnh%F8IGtBD zOqPa<3^B1-R{A8OLcYnc@a8szH)KM=zwr%$aQhjugYVLuyYpzgb#;e?a+X43q@8DB z4?x5e{31p&cXu{9g~Gsgu9sxk&9tUs5qlB?tCwp*+EIz}EsOWM++hQ(v=0TC7!T5t zROas`FEBq2uWUR-WXh2iZo1>BEtVKp=$xMvJl1?05Ykm3S?#z4uUILlc^l&MJzJSg z1q-NtCk-r(dc=kB?19`!JEZ&@hPn za0en&d5J*qQO5VTas|Gx9L)iMTCCw^e*mR@!n+4B-(;Ej07exJheQ(YfnZw03kbFh zt%Z2R=`HcAUY{1jqslKwn0`xnt-Bj47j8>yLYv3f_Tmbs$5)FVd3L}p(d_t@1Y-p2 zvW#zx09tKyn2l9w9YRWB<}9m7Gr|GCs@>Q9eDXZ$k-nwogAbp=S$5Pgm*<(cqYo|A zN$6rXzIx1y^t|rMi|4UPVh9T1n~!Z*B?+f|{POFs%V>h_rjVODCVQk+NIHn2_ge~~ zPjXB2qM5XD5?^~uk$7e@nIEI{PmlK(wuhdlUMxo6u4`;?I0NcV@izaOS60JaP1u>2 z2#{pPJvQnVw%%}jC8fO_$LuL0R38RwB)%9fUu4h0D7BRAujB=6zt$wnV}HGI5-A@E(rVI_^u}MOT_E{!w8o)*b-6jrrYVw`xO9luxvRkb$I}}L zWf)D9r<_Sz?w=BTx;{3x9a2si&&#W-x)sQ4M(s_UUR)Ay=#X7{txNj?dw@u)>JX;Ea`y@)|J9Gz`T`Z}2S}l~Ia04XzcLm3 zwm*~=>|oFiuD$Kmd;v_Vo0clYp;^8@57+&j+!;sHJ4%N*%X=n+Eq&az;U|G7Q$6ie zTT2G4lXcHl@$17!S09Sl$5Z?WE89y=a7yml;`V0y^`Uk?%c*v8qMUUW8K;G(f?ujV zG##6NLc?%d`!MF~`%vzwYg>!_gAUz2LDmPohu4LMxjtOj-_o>LK3RCDYqZ%bDDs3O zYo_+Oq|G9Yz_sGh9(v8>J}!Ap#r%&Ws;9MNuae>J7SAq~Gtr3}6jd<>l9Tyw8Qf>< zbzPm--+bso5$b|xOW?fv6g*?`${@C3_a@t?CvnX<5i*=;x(ICP5{1Nz_}wo8eg_|d z8lD`q<9Bn&@1Jtmc9Gv_|NZl?zmogiiGo66&%(BwVE_E@pZ{J4+okh=VQrQ!-S;rL zU}%gioBFvvvmO${5nN>Wv?=80qxJQ5VFQmg3YY!X#PA#7H@0!!g&u8~YJGi`S54JU zL*15O2ieh&d_`CoLzcp+&jp}t7Sl?FXs}3yQkK2BMlfP`!TsI2$No(m9BHU8ismv5 z^a^<$?Gz;md1%qJhEmy}(P-yMuYFB_JYvg6-z)U99a^HC&2vbLQM0R_1f=9S`UlqzS0sQ|pHT3`w8H zUi79(l$-U_3*3ul(=`X`LpfIAA6JZ^m$z3{s5{x}R0A?~XR=6xuGj7WK%Sw)0Bo3G zl~Q6Bjc*?SG&-HH0`nU4S`?s2z8+A}$yW2Vi(Mr%7y?%AA^JKp@HQQ2$~pmR(o~OX z08%`doR3ot&d15gxg`$w+H4_lo(^Ep0t$SDR&h3lYTN-N1pb9T6%K%(cGDj)l(@kJb;L#Aq;Mz1-LK4H@L*mQQ%B8C|#xQ5*ce8X%cqg4)BIc|5E&27#1BnDgd|^_Z#H zX}qI6tFC|=f^P@IT&R&M=0C;R0gm49j8D{0Ko70vXWk3a<@}BV8*OhJlj#gRQpY#dU4v2bcYi^c4fr~X5 ztlb2L&0NC4q4fME>H)MQh~7zZevSh26)zhsBa&I2Em-K}SCaylM0lZz(DhCtw%?NgVVUJ~W*4QSXyhR}n_6qXfktZ6XCIpm7iYKu7E0W`4b*$tu|@vW1;kA2 zhk@gc9%V!Ox(IR@l)GGAlOfcLU?6ZWz0f)d6r21-^vSr*BTG?RU4wPs zf2HLBqfl7Ct}1ONS97to<_s+4vnvr)HD^aFEv9;So@Iq%5Fix*Ig#rbcJxre8|vc7Ar+#8;ZfUd|62B)lWPkmOMiuMYge5;8y_ za+1QamUkao=vlHQE}jtwtqSo6;Y+Xp1?SeNoqI#&wL|!i^*sc;^K&SirTV8YK30z} zA!b%%Ty{X6A-r*8a%}7~?5h3Vo-1^&q^SynX_v9-R%hRV*)xB|);CFH4DtZ9yhm*Y zgBYMFEIi)9}=M~`otJ>S5?hzGcq3q-;ENnLBlh2 z*z-HydrBAYbrEWHq-Q`e&!`S8mQGM_yLME#v z$1B;>vYmv6E*HO7CeNf}XoOUpk><1Q;Yitn^B;*W6J}uQJ6>pD4er;LJBdB4a8Vr* z4BBehlj^AIwMqzxTe)8j-S<`lP=R2tu_;MH+8$(5AkjhbqT4!2Xc%+4H?tt~{WT-CnWt{5l8p|-E zPbx1*O%#SjZbumn!=UHh0|c@+I|qm``cg00nSuB;=fgfwBYSfx6x6TCk5;gl`yPaw zn;3+KwC@GxY!3_xrfez-x-*o3HCJT@5~*c6&8ctY0}No-&iz@>G}(NKQbF| z`JA21L?b{EB6iLXlp4NpKMZ|$BztIqHi@)>uNM+Y-0V#kgQ~&vb!&bI-cfjft!RHu z&s-7hgG3`nij?|TtZDZ_!D;wTN+KC|kG{VBdS&#nSsbdh2h>PF?ue&Sce?*S*5-P& zl$B`N9tgs?@p6OX&(9aOvn#^StpSssSLP0%9ir)Mx^8O@j*SaTez99x}udBjN0nNY<=m zZ}-ZiXbMTPtWeU&t%ChoiY^YNeu~ZOcd~O>cE2HGYk<~t(kH_$5c3=_N@GyR;e$kP z!K(*@3h#Pbmt4l|-eqKEnIOgPd;r-l3o;E{G!ELlb39ROEE_N2QgE!WfN+Y7cCO#T zFweVz@*kIel*Wh~M|rCIZ8zkb7#(}qB1h(=N+JmkPB9iIu)o53+|%MEP~i$z`(av9 zJw(4y4|9G0AWt!Yw-;2o1q8OgK5jYy1wtxlK0*~jI_JUa)|eVd9gyjo-4n4PpK%~V z&T2;V?Cp)s1^mej6l$nIwD!V(XeUgfH^e*V;r0R? zkA!U%TG$NY_7n0(y)hf* z!vKQ>hzJFBFZFs-thn%euX1A5mD*3+UO76WJoOkn-Z@R7t2x?R%YC`Deqf}e&#LNa zW|roc6zzFrva?t+5i?P>u9)nkPdOgpZULilzkog-;5ZXn=EcD|NJjq7cA&oqyq;n+ z!yoVpe)}`?>%ad8=Qkdsmc}v|@S-CIZ^iz+|C267v5oKG^(O*?JOf^TT>$G)*w=3W zar@8vKNrBRD)#jo1^I#dPxKb*i^$5#mH@GIxILT}3wGBXChNVdK)1jXmvtQh_nmBs zrIE5+tR+?2&9JZ!m6(LqG@P9tujn}?Pn{8;=5css@qMiEI(C-Dj{VQT!S1jah&|N7=1}H^fE>dL` z;Lr+ChVVaT1sIh~VE4NUD+ou{mS-o2(bzfty&?~7%s}Wpczg(ommI0fXprC@1y2H9 zWZn%lE#y6K^o{=b(cG=E-s?CI^y-vb463p#qz5`oYf$qIygm~>l6 zoZp-@!+kDzQhDyy5=dFL7p6tDW+U^E49GV=PlZcEukV5 z?1fNl)r&Md6_OtwJOLt@P832mhRvyKB8ZszCD^Yr&=92EfrP995@h?Ot;AtL!D6De zD#8KOw)z~ZC)8QB%S#z^z8-;qo9}tJHC2u6K1gEHDZ~n}4AE(N`apu>wp;v0eY~7o zxC(%|i`QrC`oovUpaky}^5`6tLVD{UyC9SQ$BKW7=)tiK27u3P(7kU>a$jarp90~? z+hVjlABAjv41=y^yL7Tv_-!u^f#Pk)@?arV>w3+GaL^X0!&cg{jtjW{N(lh!Avc%E zWTl;9fi!eCeTx%TbB?R(a#&O`={+ilZ7MPZWm9|_`Qk;;UiBn2ryg6B87!?+Ocq{G za3{GVN6DS;vtG53r;?@c15|@;Z9s>McbLxFXhlp)U!{el4}jlTDLzBL>Ewyk2;KjC z9%vdFuY@GGc~UIwYq39GtGEUuo&%-k8w0|=tUjC#)#f%F$09!?nj;E3X`zUO8OD(Qc%C}%Y+A&>!0 zXLaJ1R(m)fZ@n7)xciZ!mX=oRF&M4J<*xopXoUUq{a@xi6DsWNt5a%pJq$#NkUNt-D_E9uPVIL_ln| zwZ}n1p;6y^pkj!{*+5kF!F14gWllsIko0-T(}i_<=a+=scWgTsLBrhIf@zl6+QEXz ziW^bAB5n@oR`MX7o7C(>LbH0p>He`@9GqEJppN4C&}U_4p2^Y;j8!=_>8!~uD3|pC zKEK#10=m6Anaq{ed-efo(T)Uecf|}fzfmMq3JNC1*nC8|7EfGLYtt4&v3>v)@5K^l zPRG;C7rpE6>Zxm`x(2zOLH81b6>Wb+4g=x;KOy~&mFwAvMWLp%sfj=rRzqjS01QUj zT>=Z(5Ll7;r2c67sOBX6VDZgqIkA3k2N{?=Kij8EqGbZ%^6!+?E`V60b(=kxV*@BdwNP(-<0Xm2G%V_= zXyl?g$nCRgRrYgS>n>Z{0<%|O8H;1v3q3qVR-;dF$v@PLZva2vFzTK>+v8Dhj3lBn zGyk4Vm=hlf6yjm0LEVMuHMgrb?mx$}KdkzJrHBvWa%q+Toa^V~8N8*)~y=RZ6G%)y`|sjyd6#*lU!opKp=#rX-#@ig@ev z6S zm{|`9g9C1kw#q?;o-2%z^6$^Izi% z_>O`}A9Jy-cc!JSsRKWzM~H4w}V3rtM*G}$Anf;p?ppwB&561*g!V!GUkFl z-rwFmYzIx&JbE#mfC8338D9oW- zl7m(c89L<3pT|vKH5|j79FLC6%{~fa=5|g!w_F;=|NISjmh}XQDg1bXG#}N7T7JZR zqiJOSbi_#)bEp&J9jxOGQ~l?}V8m5g+JPVXas#5~*kxSi1`u8^WjQUV`72E!ytB%*i7$tb}^)K^$We8vL zuPd<)p_M&ao7{5!ac}fv+t=T(jjmv;aN{1%#}1xB&!R=6SstgeptZY@TBaUbxjHtj zV_n(x^=uWjj~2vFrq!G(f+-xQV>CCW9Y=8IMwQ)eGFiZu>geynQ@{5O?g*W(VlaVR z@$zW3+~V3=mNG4QANk|Q8bkl63Es+YfUK2bARYmAdKW1}OQez-i8reJqIACH|Q zA(qnU_cCTuabLkK^aRa(2Uq#k#mq`DFZRKgCdeuEg4r_u!*6OXAOj~KM>Bj_^@n4O zBG)Z^ z3eGBuroK0lJ&i>KsXSU-Ujm6A4JCsUJb7a5WuZ!GY4yGXd;w3-h$=L1r^Br}R>waQ zlL<$oveuEsv-ml#Dmk_um>_5n-jm}J3+%3byZMh2`-+~pAu9qN9$pu+#z+ibSs@#a ztE-RlddVE2N>DyGwU=q+Qhd6Y3S&LBtb8V897!LkR3+Obkn!eKu?2e~p2T_HJqjL# z?-OGA94wRni}OB(Q={Q+J9nI={oNLrJZwbHsw$}JSVw7wO?Wcu_oOFuOgqq{+t3er zq#1DNU8U3%JZ+T@I8^RYF-eqy^U+GX$H-P+ISDd{@jr;?e(*6Ndm2|Lr4h}tD1GYA z7^b_6sxv#ERd#QreAUv#t&)j=a@~k?`SqE5aonj^kcEK#w1R{%PX!%&gR|nK9z{Uk1|vXL7h3)l8`7&&hs(l9+&+}s=qld*wPf3 zLIE?=kaSxVI|TsrqFU8@lwd{bJ^uJc{htx zR@xHCVViz6z0cxeX)UiCP(gKK>S@)Dezsp3=5doeVwj)hAs1q3aD&2!lDM;3+zah7ve5r{5EjJ3b_?(uWjq`V7aziX{H}tU}}D4sXfrU*W5Q zBi)kw<+E$6XKP&*b22lpJ=gk*$vqAA&ZbQYF<{c+UhjI^Z4xROy@+CrCwn_NBgYA- zlES9~hF9w}mjpbYcvvauc^fKY_HAVI@5I1A(%fY7NoGqrsSAowx#uB&zV>Bq>BuGo zxX6D*4e1=04AhnY>PyyIRmS|iy21U`?G3I1ajAVun8nI#@*3S3#YD~M^IwT>heFAf z51S$uj2JsV&uWqix{K<0?jmoPWQA;X`))~iE%Y|Dx{g7JvY3z~=_8z)eWWAEJcudzQfhrOM2QE-8E z{Os*4)+d8YaS}Ss*3zrPHEU5LS@sr|GDpRk1CvKz`80J3r1MK3mdU^{QLYhCT}h`b zij1@l1)oHhjr8+q`m9ydKcO01UGb)T3U?Z#n$w1-26Ix+#lw%PI|!*xhs(;iiJu(J z3To=;L>?ZxRr#FPOWwP8&&V#7Zohb?;cQcdbI1Hinv0Q|_v!4C99LJz&+s5UxEqJ@ zph#R%e_upL!K5$;q`!h0UZ}deueO9*Lz}oi(9en7dI8lHY)OYh-`8itZ~s3AbASJM zm~vpd@Er|?2gQ;a#wkinHr&7O$b*z2iV}vR5Rz53wAu3;m@lUu_AcHWH4V(?Gow7S zLWO$a`aa?=^16NZqHb6OnR5omD1YP&y73`7{FG>TH?&)Gi9&#ZDo!s_@-T^Ii89Ar zKAL%{^IH%DTdrpy2KoU8C4Rf-lX}h*e0%|i?vL0Yy^jN2Ib+b^#DZ^)Q79e1%S!+n zNm+ioZrnOII6NZ*VjXZj~`IE+B!d*v7v*^Fqg;dW`56^%OX_K)wHz^;6}@F4KEcs zO-3f3@z)NX6EL7n;cMV~O#Ufpzd~)%AkgWaTIub;(Zt0C#2&wn3Cw&5&J5v-3NMU9X%M}W8 zon3I+l(C>UKkp zs-YK>D#QdyIh}v!BNg^c{RF;Jk2|662`@kG`Hn?}QPl|2yb3zt{w!x;?h{|sr(d-K z9+|a~GS;$JwmKAC);8A8iC|Gc)chkY+Tq{~!RBIOkKZB~2s3cW;8VBIN;->W^##c) zngDFbfh^t^8`&3|Q0(^t)BVW%Yfm%6Hqm$~NvBRVeDX9LKThN0_Ev{6Tck2YzlgWw z+qSHd9^J5|czpk)A0%cP#N&^R#d4IAz9-=ku_-DJ$+sx{6Gd=vOyO0Mk*xuYLZ|TU zUoa1P6xWkt6XX{u{lScRsG3X$k~`f~PFhn=+TR}2$tcituor2e#A;r=Pco0#Z50PSFm zd0(~~KKrx5<_yG968dCbg@bUeP*w14mN(DE4p7~?^j`|y{e9VCstgm};)S+~orN7Q z;=52dX0BK!)mDf7t}+FYg|feV&aE^k8~RJ+J(PU|oeMLhil^bB&k+$wcJD)ujN^7{ zGUvBuTD~_YgdB9#2WXPE(?zk#`Aja=^yz^zcQ4`)!KkN3d|R!f7|KVVwPjcgHJ##E zzxH3FAm>7_eveJyWFi(eQ`~5xKm>lUSvrO)AtZ;_8Htp5tjE6fw;sp|SFM~J53Qp$ zB4qku3d3e=Om%vCwYfok#zl_W!d_d}^l|fC(2UjZ;;qM9qblHQwZdQbnk|vVM>U)+ znVFT2z|A8a#|jrY9g|Un^?u?R5e@27Mz|Y>95CWQrF&VI{!)Xn#a;p=CUkeMTo?4g z-Gi!F>hu^zw)(*z=B%D(MI-1l`{GqLGZyJHc5bNjHb}W?M&FB>E%e$$t_s-eU42ZQ zL0UYn(jkz|QWBTVe|m7bX?EDX3o%pADIUs}$)$AjP40|nM#u<2h5KT@`^iKpL%CU< zZ3d6(#NZh~h4@`T!G`=Wgr1DQ;;_nL`c}IiqPsn*j%4_86g~Qd;(CdnJ!T^X&p5K- z*1qD>?z9;F7=~wVY&Y-*Ra|&uhnxZh-~PeZ7ry4EUtmmw2}c3PEFQNKf2epb@G!6+}8nmo6Y3DS^v2%9WUldlf8^)e%%}hYnr7HxYRWH(?i^WMhIa6p^hsshmcE;goOhX~3I4(1AmNah zV3dE_b~PtL21XW?fE1yi{4M6bjeABBnM@f5v!{!KEi$=i-%*Ynb*5o2qJS9uou^!^ zU*oA944d`6I8YSZk?_kI%x8 zah;zMJI*$Zsb4rL&slKFWY0Ao2b5q)`7qD4?~go=P(VWK{uRz{bfS64llQ?Ya*V6? z;rQPX31ux^b<0n4UKtE1$j$O&BV_}5bd8(6H64C8Yz}?rL>1DG$znb7Vm5S+@;go{ zxOAh6j`DluB_xqA+UHf2q>NK$T$11B_vkiFw1jZV4XD&j+y33W0n!*xsexUbekMVP!d%CxRgXk1B!-laR~^Ds5zf4eo{{tl{#1g{050aAwTp_ft44 z_E`lBz=)2JK4Y|EM{ma7?0PZ}1QA)(;Jj5*^HJKTNzqmtcDi{hzT*o_Jk+oZl} z@5EJ46Q5IumSJzBU_n%y1;~Pr0c?~a?i2@Y2gv(g5)^c~_(jv!-_eDReI_!i7rSI<4_`ywnN#0s+O2kg|&tHl#S zsLph!1Ww#^MVgD8LRupM%B^YTxaoqAi2q{4_2-v9v!bRGHZr=LL8980Fh@ZH7*tVy z$=X)FP!e>FeIi9eM<;TrTjX$kqKxyHtphqSWs{r)=E!s^81R)&pY?8TvEFrS_#I9G zYlh)A?(7sc%#%2$YlVXuh9mNA%lQSo2^lMDe-@&fiA#f#;t>v3%jEu830MwrrNwNiHh%Xg|p&T3IPSY zTpI@^V`v~Orx&fEfvgj&WN^NjiN@D=*OwLcM|5E33MGA{6(AEodAAOSgu2bL?%rQi zVFy7>yl@K(2?1#BkN}(#?B6_M1oMB_{gTBKdegKTBe(QA9N&yJ3deP>VNci&2+eW$ zd=5iw#J$;mJ%rnQ82h4#i~8Qzga{9&MR~AnO*1ykp_`YRt;WFxx|W;OqESE&1#_h_ zT7!qLaIm<1P&fLo!*BmNAH<9zy^6ZV`V6jteFO$$IUM!y zIf+iM$|+TH1Pz+0Hy<~5TT7bEN*)fjR^Ff$;kr6wlP?yod{sRG0o#2L8(Br1G5fjiXGNrTJw1#7 zw%9r{-5CPXp`_mBh4d-ELF9Av;d$(`<47`MqCaotW`^c}fq^R$!xF?Z(3bBtj`ELd zb{k~#hm9cFeaOCk==)YKtURhS4r-xnXC4JF(L+Kzl;C+6hkgHQH~{|GiSEXr^VzDg zFFUu5zrk72dd?U*xtP!ZJUds~Ge9&ezG5Nkv5Up^7b)SY+7)fjwf_jZ4H+S^~#oK#KMnC(8k= zX(EWO4)2s8=A(U zWbvY#5(U5NtMDPW13%uSen_UT0<+9%K7wj$tfprb_t*AEJXl|5POFT|=T($wAV8Ez z9i#x&B4>6`pj&^n!++<#mwuG$W`v2MSe{23IAb{!Y1g+s!CH}Pk|;`eywr&t%uXY6 zjSyuCeAIictDp{-QiscUlQf-5DL~JE^5*jkoo`ZdwJco}2OsC> zr|X%t#lpRZRRlS4Y#&OR4&)?Qn1PLt(;L0@ul3&=C}w)3mGGp`gwIS)vLQmJsqy$3 zkfrYEf%l$?$+r6?vffq6kw+kJRXK_~-O`OXO>MH7jWGDQV+B|8R^|rjtka3GUnTzV zeqjwho6wMc%E$anVa>*L2+~&9(-*oVl=fs~pV#t3DzO93O|IU6JtiPeHQW zg%Pr#8dj5`8le_?V5~?Q4B8NzU_WN`Y_`K~x^gF|qd72@P2V{K$7gbP26hgye&4PQAy!*Lr4*y)P&fb}HkVU|Dp*YSe?@v5zSJitBH z5_eHjd%vqISrMIafJ=#}0DD_ThWq8Gs}qicS;}Cm8Ef_zB1pleGK6Gc6#OSWK;xB3 z-90(Z(jU<4Y5cR_qVV};!&@+XAbX+~If#0_KnfnUCkL{8DJe=5(Ejv{R|h&IA`dX% z)jx|6>TrQ%F>=aqf+2wk3t2G#bQCkTG6~mb0@HjVi|r5P<)=(L--v^NMZ#GSR9x6S zy6Er;>)(9F*%r`>)yUKeiF+v-PsG(2BEZ;6;qHOTq+xkTn*TTxP*D57lNB>=5Pf%6 zi9$MbZr}2*63qA{Il*!Hi-6$6TRDZGgpOT_MMx#_c zyd3kglUGeiT~1-qSPy^aiR?ghTzAix2uc+lrNx*M2fSEUM~Xb|Ln!>9_PK)9F@R@4)Y`G%ej)W1+iyCTxOf16}tJA1$}AnoO>dIZuQg^qnDX z*g-?kMcv`=SpCYShcaN(;=x~u39$-fIPGvaE9Nz1HZ39{R!PCQ@DP!0Xqd|2zLXmE z{_TnF085{x;6ZvstZ9DU;miJhjcPuF*Z3UHt}2zW2)JauiWNCR3q~k=90oWG(O=Ja z>5>m1IPVv&)HMKC8v2#!kJS!?yWK)X!IPu6ticg*)B^}EcI81Lsyc5?7FTmxW}07= zqqx%|0k`)7N}o7|Huj06rAYLa=Yk;u2AC5w0yuc|_nX%$;66H*L+(|n`A6_CQI1Kb zZCZnmp4A+5?jq-ZfJhQhUO6AN{l!QTREB}IXr2t zoDc^E;EY}iq7tT^G4}2qa9Cw2;KT=_LjPFD<)f9kTRNv{)$SnCi;WF#FL-&H+Ro|v-E@BpvZ?b;bT#YU~ zS#3PRIeRraF5r2_>&1wJdQn**@gS6d4FF`7G>Rpe$oQv#=6As=cfyIlaCkN5cPHDa zaUj@CUXle-DFTXuR|^8^eq%{SB^uYO`umovQqz$_^Y~@~u*%LifoR3c^4Gfid7N3H z+R06v7DHNYgQoH#3@3}keb$1yajCuZ-iLlns#%>m7U2g zRv3cnP3itJkRu5KAq>|d(j3fGiJH>W4C@IHKdr=Ce$I5;e1x7Ys^#E6RG>yuc(_61 zVi1^jZo?hwHs>{c7jOh=ePHHBtd-c`?hKsi5~tcPU^`K#kP%BoHm@gk_n_gWk3=k6 z6&1PCE8|F0U*ic7w(8|Y8PDubf6nly8LnjQoEs^Zn<}JnN_UirF}UjUS|79tl?MW_ z8(70tdP78vFkx^Y-h1Av`K~J$_nvd-KXHh}MONUin~(!o;Y|@m2&(Ym7&@Y1?fh^c z=hx%`P(_SKC5KS}i*`z^h#!y2_^nBK&%maRKfRc-B7;;0H_hZac7LiRTm^!}vu#%R z1MmFwFVrBpSUJL$9(fqwx3>8w02t#<6&Dj*WO2Yrh!{DAHvBk;xbOH9aQN6}UAF1> z$!qcAV){?Ow)OD>#1fQHfX1T~r6gdWQwv7G+HU;KF@q3PP1FV4Zn3_Td%I6ug^I$MpurWe7_p-8xVYV0C{vZM!mr6+g@ybB28LDHNPH6k z!n!gE96MiWh+A*~@0mt3>$3rOKmPV0pH4LC2ps5m(I2oKdatsJh_k2VVxvj*t)Yq& z7gd%hl^lqHA(N2iV@@o;$(Dck{#L?dR6g^VwxQroFve+WGU6m&u?^q27i?xxczP43 zq{PCXF|D`~IN@;a@48u~;y;nR5DY$cKA2F;+jnIOWc~Z&|0){5Qx-fwg03IM2C#xu zhA}YqqHjp>aKhG%>*L*()4AAZYD-%aHNdR~=Du7SL5AFFd-ZL{mFM)y4m!@!W^MZd(kA66)psnWz1!Hx8jZdAURSyoH`k!rVJVia7o z!yRquAbn8j2mN|pM74kQKhARzg8?N8>Ck4XssWbS3v3WHFx0UDm-_-lC!0Y8P{?8; zw%_EJldB{y8*#X+Z~2>3x@7sldM61;yd>9sZ=EScmP|xuw{Z>)4XX+oY%;k{*<}f$ zDsPPC(=fS+UbatUOh>Mt7BzAy8d{bA9VA?|g+k%Q!rHmJh4)ZUEF%&+8xgNq;e|^@ zt6`m&mLz0-H-Ulcz^E-AWwk}9@;{@&SC`gzI7JFg`GSYtxLg@)iQ8>`K`=M@L0 zU(aZP1oy{Zm{1SYx@3Sl?>*y^5ikY3b#U4i1j8cnUk@5sP&Dhj?4WS?ke%jICP>h= zh{IVb!$A^u>cyptB3_L(vk(s5T?J9V#VC<@nQ-`7!66Kv0Z8aO17Z4Sk3YpLKjKR- z2O$P6Jw>n5Y9$RkNx?ON(C~^t{4@&?!Y*Yj7JA`RJfS@%2!o=oNUj8((1flYz^*Ka zQ4q|Vy=rSYQTwIH6|=(kvWaUY1)BvWUbusCEShCLkNK=@*OhCPqYU{q9v~&4m^zLE zEdOGg4xRnrtX}}6ds3z>CJR?s#J&cK5jt|fPXlpV)&Ts-s(!OG&M7ol@#P0H5mqzB zhHomw+aoGx8Z3SOG%fj6U6I5w=;2SHdjw)t3hsJ|X$KT1m7@^a#lW+2d!NnqG|`yO zlIB|HW1HpqmDqooJ(UcYX1nJ(YCMy9m=7`=nZ_oID{@l7ts)L@O_V-7C3cX874bW~ zw|Ptfj>*z=Kltv4-s1ShwG+6Lf?TbLWUro0D>1sw9@>NEcok7s za7KQ|t?HBVN&)-V_QiI}POREI>_uf&6m*+`Uu%YzpHzr+8$uo|2euT|f8qv(xK2C^ zItCE%513qdGXN&Jt0eA#lwUtBjNJf<=Yrl!T$p!IiizvyrCo0U!QGUds6Z-_C=^KD zST(JvoW*^nXWn3;(_cy9aCyPnwxWNoHz8^q-#(Ln{)1*qTJ%#Re@5+bEzs0?j-9^3 zc2?N9L%6c(J)gs^Dgirm?-*rSefG!t|GrlQNgLd<9lNk6gur5{?f^65VFn-+)~AYC zG9B4!8h3{h-J)9$Ko2`VIzD-937wF&{55gjT?C-N4k~QuppeXpY++YVnv17 zu4*IU>w*!dt+Ep>5`7UTfn2(0jwtxqd;p+v=C?JVBit}8nkg3Y4^J@z?PhyeOsmqX zG$wZd5E*I$fq?TXCH#KPqp=dKOD!FI%I*>NdHyk~2tbdS41k2!lbocX4Jmry*4#EX z`^hwZgO10R&Gj^DsX`dN84Cp+kn9mAktCfFLfgZ8*n1j{&ab)pe{l`q=0Hiwy*3d_ zpq-F&<&`D^oL0+rw20LM+o_lPV@I{&_D7P7_rg`2a&mI;{Y$aEsw3U*A74-HuPVQhw27dth0!rxOmd%a}#$9 zrY1ZxfPUOx_2P?*h=83as(HLsJm|qhFZrMW==Wys(@16i+D7Nt@i@c4$QCDr1S)Cb zLx;8J&a%~Z?>5VTbqQC5v~;=Zxf7l5U)%19fZzY~UKjnV3tN1;Hm{#A-gLTCSOxD- z2g=FIMB#llzHI2}v- zB8Q#!$_KZ0lH?`-$<_WMgQ+cBy2GAzogn}tlDmbxwr!^0L<(`}u@NCr7unk12x&ia6DBwU^5IN6@wJ#npSb{;$me@i9 zg@+|zvwwG$Ewh2$TovSz;d#Ov{;F8g=Q1~Sq(gL!JXu5E(VBrXZ_bfZat-X?#R_A>s^W)O+3cOh5F5l&f4RK-LfyHOVZKM2ivj}(gw0%=Uzn?l*-OV+q}-t;8e9vM31dZt zd)7N<@c<6)jn7sTomH6z?-*B)&>X{M3}~l%vK;&8AMQ-fF>;8U2^a6gNrqnohc|j~ zpNvc2yY2hL#j(Wd4ST>K02TlJ)mTuZLqAW+Pk9&+mNicBMI9eB+h2?#+LGDnR+9cf4{p7 z=n+-|hA|2)2*9>Qz;$wz?itqXB%6|9w@FkyVNQTJZzhEx_&?qZsd6HFr}dhaAOcRx@C7KR-(UfWUwq&w1W_ie zy-(V#PN0HPz&(3qz=lvVw!MXF)QQ!Jgy(qCSbVM!-Q-)L(vb_m1lTT&v&+g18H+u& zto~LPd|v*gIGJ7e44)mL4KErIH)vrKDyAx^SK&-$%%5W~7rjC;aQ&l*?vDpuE728+dUNDSIqn^;n;UM#_pR_M-*8)LfJJ4Ch()Bq(Kh&Fi;_wyEg zX;Avr{pmb4(!Lj19y{S7M!efTb>lI!>G))nYX{sZs_#Wb8qe6=e7QxLRKumV2f8pL)?#6u1v#%e%)~f4)Fm~|G+)~MEvD6Q0X&?mwul* zXBQbU&k-=t*cIB`&)OLeezvFbA>raZgVpXN*}fk(egu}B$Dns z9aH0$!WpkIA7)%5lgjn8ycd?~_bD7Bkg>sg*f?nV$2yg$iM7EaVa@X<>-KH# zAyr-`t28J5eUPFY?|CGc2i!B{kUK-M9WqH=q4;)rjIy&=%%`!sYXrfB#G~Ezsh)^! zl0vQCZ0ZdC+k=1shSrYdq}LDS%HyA_!5nXr>iD79bQ^Al!HPoR;w^*km=Pmq>Mqu^ ziy8ott^rNfv|a}$EE0xOMdI%$53!(@i4RarDn>)Rp5+PtfF}hfIDDJ0wmF#YW6QhW zbYZTqAq`Ifv|<43>xQ;v-d5`%fGO?*Nay9KeDxDb@vR29(bFUZW*8 ztlmP8aeMoW7a$7E-`30EASa84bL0`i&LkrL&l7TO9gL)q$nU;cDxjuIut8 zC-b%VC9-7ZPfSKtg@dz&Oz4T@&4m?JK_ zvRhWP3+q}96$Wg;p8OZmMZm!@2`Rs8VI2~}{y}%ti>8qHZN^U)mpvRs58EhB8L`8A z^2x3f1}Br_fd~HkIa!)8<36#9E+qb*G7UR+>+nikif_%~Gz(Kas~J1$3D!xTj_Os< z4=To}i+BNGP#|tdzCelKj%1sI$5IMyDXyOy?x?6Yo-*?qjTzSWjURW~zrEKnx}ij>En#K0 zMJJTj-FUhaXV9Aa0VsEO6^6~Y-kGpc`Y0kmc`{l`XMAKex7jky zt9a~$%iM0jgi!GD{{pRMIi@qT;1~0lqyZPSBq~j|h%!wrTqPD~4F&Gk`~O}PJ@*TP zsdZX?yeCAgwj#NBXEmfB@dF$d?vA-*T56_2Ph0Gp&>N{~+e_?x5lenE`%J$C4QP8I) zLCz~+l~{-PA41MtDP6yCiDDl;{>OOM&>A*esPPRpYl-)PeptC<40GR}avBNPpHumn zJteAsTf}7=uVO@_!E?ogyXPht0)w*jGv{jnl z2-OB`1d0Z{y6K%lJkXpxe{g5XiLI+w2;6N}sB#%O2*0P13;h+x{>73P-}}xXL+$H!#;EZ-NIaQ~gh$}S;R=73{9Q>qo#NZUDeN7YGc!2M=Tm-W)w>(?BNA>m=AS1f zqKU-i7~X9=ce=N}BIK15F8iyDK~pvq zF&v%vz704BRGNI1Yh!b$rGo}i^qJ1f#)wYi_55TZO9osHrNWRtjN}Hw!u1>X_Z9Sy zk|}RDWU4owR2w#(Zb?$=ba^cMz1f*8z3IbN4XX~z&2gY56UoRcvdq__ISTr+BUtY%814<(!a9Vx9auBEb&=qo-?1Fu0(}B{yjxWSD$t%>{`v>ml?Nz zx!m_~{2CQlmSLbT=OGBFF0Y8d_nzPi6>tD7q~!QA& z{XE?K`u@hEH?i`7{_pM_3Zu0b#st0BitQ7B7Hb>k?M_I%jIX;F zZhqSR&Y(UbOlemnLutTn)Q^MdyWIG=kk8RrYI?x$qdTG{8_X{IWLho6TNB0hpYy{1 zjm%IS0kA0zVR4e8&1CN1*s&=Bo^02v>aIPAb-%HCoRQb#hv`3US&oEro|`9}A2Yfg zE!-Kk47`)9LD_dM4KWDB6fyV7ms}cXX0qNsz^ib*GhBz5QJ4A=F=590_&ppP;`xyH zUzlp%ZjizIUXorK^1fa>BC@gB_15`}u2FuycDBx5XHxU4hDs&NHb$#wcSLJWr~(cz z@dpxqDamPG_o}=KN(Fjr7ZaF)82uu=xY(XFpxPPa7f0SzI1~>@KH9(|mx^4-YitL9 zWt_iT=crs7%+Efz6n3|&I07a`>b4Y>j(nx#co|xHTaETk+$8e)mrJk2{VFQhXft2T zhaRq$Nw0V9#*=??G_IJ+7IX@($_z$;Dk|1bzZT8u^fX3RJNUpU)Yz|u4}OMh_B~p1 zekwuOx8V!72=rLASh1||P)vnx$mW3Mv=Y2^->3$JwcMI=&?DV2+!Q>hD7AITVdy*Q0bUi5km9)9`l zqiWcl9pT(;}-_4tz*u{C;nf5b^+JjWta(@Ea3t^QnNb>Ty{Q?4N^V4MWz!oh1 z7#rX=Z$rBLx9@;}YL-S3slUJfV704|wY9a9lG0~j4oYudUvhHt<*KSGEtRRuyGRJj z9e;^)X@-l(e!~$8WxnIj9FB*>Vzj_lvu`BbzpKziq(F8VbK|31*Te9K;@MDV`v`hv7jZd1^l zlP?Z!{el)whJfrU2<=gCTfR#WJg2|)K(u}{Sm7?^y@&fhL?dQFlRw(+e#v#bghEMG zB_;L8inV1%!!8fZ*`7G>D4aN-Ts}!Nz2(Nw2uhTgf7=>h78LZW$qyviNVRQuPgEx% zP%-MmlqF+NS6`p^+L}c~WTeSc6bj{CS}GtH{{r+R>N*Jt$(tHC5j-BRq^z9$PSxK2 z`Pz7uX+J|^860-1d$Ij8Ecbxdbu_RzjK=#+Ul`z4Uo85dQo+Dxg?1oBFdHC?@o8oiX%J-si1KNrfVKw-YR+F?yUZ29g@ zszuFbazCg^65X%h7Bnhzn#j6(wkl}-_2cP+>C*DDxT~uO4=*pbtv*rlmuJ*;7yHNy@pnZ(?Q^f+Z8>BOrt(L}B#m7mCaWeJe44z2tE!0Mqtg z8J;<)!e|9)#Rlryp}+_5tVW)oH_ADlowA#cbMBnvXUfE@>F8jzK6hosYG_6cr^u3Y4fVA6xM#%V3I>d^ZYHK zCGU z=4qk+Cy}JdICG%xP9SvqX((Q+DfBzoW$hB2_IzM!;e$o1Ve`5bJrGdM&9}$*aN3yV zKIY))6;uW;my5f(i5?x5PwfqUn%hhI{Tt-6g0JH$!-FEgfK|kJDoGwZE2gcX&GI4c)+IvCbV&QX7A#@Zsp?O@c7Kw26Xm8mg!6+?Iz(WWpeI3 zXyEmald(3Z&bc_#*{)RSQipZ=kh1Ze(+x+RY8Prif~7H8-1j>mg7QJFiX0}`p&UHW zng_oCMGv^%=2PIWyqDmx3p+BnbghGe@ivTH;k1q@dmq9EFOIF9#iK$E$-`CyeZKcIW; z`TO_#G0~>)TfxCMw^u-MF!$W3+}rL4Xq+eb$KWrX6RFprGm`@R%^ec zv|C=@vf+2H{(<$mvYay0DJs^zxa9K0$bjGa`aq)ttm3IyHhI*Vh}W#zCA{g+nd=X4 z@0HBQK3(=S^|n!ki#Tpc)L2+|%9*l1#sR8ux5>#p0Hr73`aDgk<2Gx8s4H&WdwG3t zb)?+8Q08hyLA&LK>B>{{)l1fJMrT#-uQ=&NwicaF!+)bBzS#Pf~ z><$kJ?Q56CAsoa0s_LlSE0gH}{e+U6`bX2(@q+gE_$QA;kt4Igufs+Lv_Ca>QVX&p=P zA^!u1fHC}I4}eta73wRX+DjC)7MBojMsx+xDP&ZR0~}x{B^i)~5GIFz;Z2RW6bg$b?6KKa1cDvC6X`V**J}oRvJ=Z_9CQwq9JlT>1~}zC%p}{+ zALi!DpeX2*>A(vIQ{#Jhho2%YKOTlF%8Paeb=-V5we2cTs$gZ-xWD&Y-`waxXA$fCwhZ(tbxxDTa;rK6w1SwWY-^bjdf(@;^|#P|%8hdlR~ zZEU}7BeKPtwYQ}%;J8jL3QscLDc3j2qRB_%)9s_Zj`!5j1z!dSdRdF;g(TJrmb4Dl9f9z-=1vbGp_1LT0i(mZwkV$nlu-&A8fk z7y8PrA)~UB+scmS(azs#uG<9bcfBIaxEmT9KKAYsDEo3>;g0H6?2V-EGoAa7bK$eS z9;zn;2}I0M_ESG?_^;@UXmPD~wJw(UAc(51M94+0!VNT&y=LpNUC!|^ z6In*&Z##B@v`c--7OgF-u(vq6ZJQTQ6&-^uwtGI3@`B=G!^Q*H7wMuCa1Z<32r=Cn zpg5B{HD}Gu+3M8j%3Nya`yH4i_6L>p4>(j`EY@Ta>9<$ro#&b0;c|JT0SpVYW$B-S z%V0p@Rc>tpC{GT4f9EwGA8PIn!~{pQ4yQ~QKwqp5FqiKi+U^rI*f3Y}m^wuN|Ewgy z#$X@0C!l#E7&VQ60T}CZ1y0l-efTY@H%T4dzJ%QnO#Z?veVsw4DosCJ~L~> zfT!7LfGXS1LET(-%6+HjY`$|tM_!A#-gL#iI^y2H($MO6MBW?UK;%s4RxW_ z%?WTfPmYSl)m-#62eX! zx9@FZD|PI|mR!f(c1E5*5&7g%oAcO@eXSnpd6T1ky*6dk!X>M~Y(;p3x}^T5fAnp)v2>XhcJ9StOE`3^?hd?n)1@ z^fn15-<784RSc}yCWmtGi16~NOw3Hx`6{cbrq5Se*0Nt=C;DmAu38PqLETZ(Uw>hx6~m!10*GOz87x^C~{H_1bV#7^k_Jc_t25 zn{Uu^&2Gn3XAC^wg;FVbAR=k7&YAUC%-?TXhoeO-IqL^}oP?uewP7G`-a#+yiqSUR zXD}_S?dTN<1fVkz-k2ob?-|Z}disdeIcGAh>3ZPz=B>J!wSfv6CzsQWPh;)z#BB;8 zAIPG2lO4upEL`N}QC=a;!m-HG_ zdXxu3T`!bEBUTu zZ_D!u$K!=Ym?u^|{!Q!Wok|Oi7wB!w_lG4aB?r_``FJxy1-ubGBTuC-Ac56Qd z1_qkSh!9zxI1FZT&9yw63s6<1rl$U-+VOe5Omm{n_ts$rf$GVP$Jn^HV3+Lbp8J%4 zh13`E!hz;rRtUxh$$67{-0`3YA&IH2?XJ7pL!6DaR;3j5h@ftBc|-+rYc=J$DfT=R ze7ErF?R@f2=09%^FO+TEaZi8+DnmG_=yXFivl2*eDHsx>tm1MKy8DyxizpO=*(v!tby2 zTJ5iC&&gW(ioFJ(J-K}EGSxQrfWBZRl|pHAP{74p=1<%K0AI~~D3k+8;{T+5a=l&=Kv5-DTymfg`(kM--_g?O@RCX4;6MLm5?2WgWmS$jw>U>gZJ`qiS zZry09`N1PFu~<$1&D0bc?$?)b6WWM?G+(FN+M^yI7P>dqrNq~v&a|I#6tdgy*Dyv` zF*ndWpP@okS9y7d^G+s}-xnn`t*YJgZ0)fY^O!A|+#Pwbji1?H#_hNs| z^qQ@BHgDQL$=}@HY>Fw##MrotHB_(RE(0hN^G06sNBufur`{f1O^x#1-FH#+55(N$ zE=fH!n7mt%eo!GSz0p8-P8Hq0e%+FgOjo?I-CpTWS`4H%C-mZf3Sj_;0C5a&R6u8Q zp*qCN5f>jSV=*N}iF+Bse|O_*J+2N?&!c4^`#T@;z0$P*j=1;Br!?J^@x} zd(r|2BDj&JlWZM6{hMp-@cw=V+JGhskiUg&xDui$-$CLQ!=UawGR(ksO{L#7WJz+VuSwLB8yNUEs0NAyzn?;sNDaWBb(BJ=E-`#@LYth#- zqPZj&>Wf8HmC4~br|lER!fCue=fddQRAJX*>M{&?5it_X?jGMA@x*PB$?n4Q}xHv#(AQA+7uj>M+9%wzZ=(WLzvho9W@m`2tFAaCUS`{Bs)B087$!f zxmW2?N-@*@B%sX9HhJ2O@TnPp4ET<&m&(4+~(e?3s_BmX?NC0Ns8D6 z=7kml12?_VXy&!rrq4EH-!HtH^!jyUq67+^O49F*SAih%$2VtkpYt;vZK&5r z>@lX75-YQi!a(s)KSM_d(zx*EO)iAkIWX5-dV~c{KPtXHtcTxffARW(qgW(mM9ojX^ZLxd6G(;dLJ2~98V?nsM2-~j?8$3h}d52^>47Uah zm)WpoW=0D(?1^0c2H*uypdx}U>Sx5Sx|di^JpUe$yJ!W-LLOAmHL^C@f`W3I77Y5R z=#+zM6pdfn4hhzS1!lp5*)P=}Fa|i2V2r}W8^GY#V3C|m0dHjclsN(2~8jcp*w4=lj_j!^`b@WGf*d zv0yKzsx&)4uMdc?w5Bp9={kRjJXZ?188EqO5AkSFa%^t92XNShq_+jhWYvfwWW zTI1@F2}uFThmB$89w(weHJ_k@<`b~SB<@jvf@Xj++$Mlp_&OjC!Cay$xbkO>7+XT0L0vus>;- zW0ebdaU)(jEjhwdJnz;#iPyK;q^=I%Z`(R>NK+VTh4>!dxPGbm9F?9z5 zWdlQU&0()cb4n;%rt(sXvg*p7RXzb;I;kz!yRYcpo z8oka>7-xSGMkJJa?8!PpbSh)WQ$--N)enFEIuHALH)D=$6mZgu0Sql><)-m15&VD8$*VP zR?NMO9E>+oNPKR@O^?zFWv1QmOA&O?(9Pr(zL@G!YP)#niB6@_Ly*O2X|l8%TisB2 zc(~((8%Fb%0+&%9DnxOycE9HD+{B=fK;H#$(ZC6{e^NH%{nYr-fX>F>Fmh6=H@o3J zaD~r1JwEW_YK!Zt4+%;@o&z^)NpW44nPo2wYkcTvKM%~j`my!1-`w8qldH~P|8?R0 zGV+RdSMArvJ-)J!d_3Q?tK2x4%DcMp=J`a17$uDU+MD|lyS^?PmBkx8lOAGk>*k6G zyqx$&OJa{XG<_5I;}?27rimmZrKL@6=s}<~4^TmR+{b|A1qA^Eq-z1mb)s=_KXB)Z-`%`g$CP(;Dhf#P!eeb(?afv>IT4DA4vG$K*XA;d)PPB@w#S?$a`Wc{d?BJo zn8nVzn(AQ zmTJ07C`audxKuWuz?8ViM+uSv0XMcX+Cu7D>}Jr`?zHgB@VPwV1g63)`x+b$=Lt`P zy~4q;4-p7NA6pe30xBWDc1e_Q=SC>r+2#e->GRVoIC_pjdeB>m;_XAh3xU zwCr1PjMOTPm%zD{PqYM1foVPjpWh38&35sCZI`9bnXl5stGxfFf*%z*UMY}&2@)WL zR~;>7lE5uLua4Su5RN0wQIob$z%^pq5$n7Yu8lD@o4|8lJa{+TT^I^Vh`soc6sG(T z@$%(l@3A-h)VYd?4Ix@WtUMzqg7Nd2k0!%5?uqYnxtv(KACK4qL!p`DDj@dVfF$+E z+g@NE(-5tU?)lL`1~9_Ibr=v9&H(0sIBEd1W-@^Jz;?sHK!l=xW5m^{D=9pRyon<& z(JG1VLk3ZNw}HW}(nZ_AfQ8OQV5l|s6;%(FoQX?)9d7@xtS^s;y6xhg#aN3lW6M?u zV^6khlWzNN2H90gNDNsEGg2hUp6oH1#hR=M(;|^AOUj;o9kNXky+7Ue{XEb6zVqo1 zzdn6T*Y!KsIp6a==Q`gVxiP?ZQit=6+moo}IFtOQry`(`jJtFUQ zgccwg)eo$3=yVG8nB0}Bq?JZMQ<4ZwXU{L9fW@t(%7RCA0Le&ir@J=*J*}fh%Bnh$ z{amK9N^*@WRXLX01sf~ce1RgO#}wyoU;HMB9_T&_bS&j726mUK6LDm!bhj7|=^qav zgDL>7g8w#a&PGC74iP6U1~a>oqwMF6S<7S1F`0ui4fk8>nmc1a>Arj1S>xT?qr5IR zllK^5{T7+GWs{H&UeGjIBfzk2lPDOZku4HI*u~fZk5_D3Yv4)KL3;fxq2Mwq@7^AD zE9SCKY~voS(aGnDow~+(z2|tLL~&8bqy}JC4>yvBZ%w`fM%#}(w|B<2-keRhhy1nr z%T&IB(2#X-KyR@O84DWP0)*SuCQlGQXulk4wyk7BM`WLndZRQu-uIG;XACfcNqA-d zc>hkwa#>x#4|Vw-E%Y42BqUjjH%($&E2q>m!~{nz_lEA3u~`8Tn~26ku-E zIe)w>d5^BW*Ig|c;0QC|be~mea%7XV3E8S8Ms1GSTYVM399bIKN! z0V2?#{%1QVn7@ta&jV5}%8LkPQNM~}rDZGkXmR7FLLpZZoGnGU_!zoz2)s5w_XP{E zySCNo_uFZ!ITNEMsMsD2;MIT?y2WWCa-pMk!*AY~$`srw`4G_%aU>pmO|gSb4jg~pZP8;z^QfHsv#DA*lBR43NoOK^D3AsZkpaeJ&;`0O@_ zjRZ;lP#ZD+!W{3cy|Q$|-gRCp->~6POtsJ3z@DnA&h&`x>4hp_R!c)Q@VivIRpqj( zh&U38VvPdA!!iB#?;E-PAHF_Tr3%|TnUDTs05Gyn*WZWc&~;FPTa>P8JssaDtiM{_ z0@kyu>W9p$Oa=n-1h+&od%H6_$r^9_i*V#?M^r`VuTaJ=lRo%6Zfm2dYrzzH9k5uy*a%!g(Di$R& zbxmN*{3{J`>w??(#mjqcA_W%8ffR-oHnf`Kb`RgI`uxkhY%-r-9H zoWmKCs4W?I&xfBJ3>f{Dma+MGA3A<*j9Wn7iB)UTrq7j#U@Hx4?A_7;4>A)AzX#Fo z@A~F13PaEjb|!^R$U4P$EC^am?e z?Ekh1z&8G49!veqynTV z`IGs%vT{#s9ceKUf#zkk!`>*ag$xA95T&9(F!6s`5Uj|O#G2y>L=dOB0YHyI+qe3Y zL0PLGpa`E2h;Ty`k!|53F_2;iF-2d3i8ZrOM-xdSgDAol4{=EM_^E=dA#H>aj1Pvw z8{xR{W}}w30708-AeO1E0>;;0-bfqXNv4A}+!M8k8tcEDu0LO(y9E#r+U%+mYm!H84qrZkfJ|q#0sb65*q*X2u&9-e z+Sva#L^n-^9NT7fO?Km#{*LN%gapcHE+JTQLg%0Sc4;3?qOmi4(DLdh z*tKiz(1?0GBoD-olW^}~ZZ2)!T{`;Cs`g<4e6q+qMaJZ~Xx#bo$Aeo`N;Ms3gS7(N zL}ZIFA?D%gFtgbplVqkbra)Rmd6_?7-{CLOsKou~WzOck^b z;n&x0b-9`Wn=n7e8x6CN%1)NJR_o%yPs*9RN%7Mrjqbw?V?fu6I~ryhF5zl|TWYZ>!TeE8+XAqDYfu)8B^x5O=V!|V6=o=DMS+wx>oo`r}ep|Et9 z4#<;zAb0Fn*S2t5YCS)vF7p#>+K|{OhBA>6eVp>ST0LSajWrHpONH;fD#nr0?HtMW zcN7^qa2j(%lps-#3(#Sl8X#Yi>%PTU7|x3*fSFlC+Ft~Spk~#NnIAv#_%rZEPw1A` zc!vwW1T@&P#1a|C*(B%FUifam)_=fb4j@A7<7KE1p9n{jxn<-c4d{ZrKro>;{6IyF+%`Rx$dDMu`tx}El%tJ0{zq2y)GE$R3H!m~FOMqODhG0g#?X?$gKKY(GU zr6s@$u!w&Sgo#MS;oeZjD(cdv}a( z%|nF+Az2}&VIh7qCuhX;qaaIr&q5v5*Z}va2c~p)?hXnhV8~rR_wyE$EyIPckCoP0 z6L#P5HuvVZ44>+%i`ZB4;y%+8@t~j<*a~(Td4)s@m8@QtQU>#Q)S` z2QPzq#B)|&uz=+@>`$b3NcGrIIw{Y{NKj&4~$D;!w6iy4UHC*b-N?pT8*ITP9 zGAk;I?}H?zgcqi}!`ELkWov$1x}Ov3d_nNS@VXY!lj9};iNWeH(J(s{?M43n^;;E8 zP5`d=IDU)C&Jh;D@l%-FsK-mfJ@=!@p2#(rmDjB;ev~8i>4c_H_Qap$;$PpOggRV5 zkXWis+zx~)J1YTVIvQ4pg;Z5)2rC&r$HjBe;I7_^3*CHf(MUy7&zm#t8inTnt1+&mzr$T4w zml?gXSq}$!-gV^WTcYl8Z8R918PelCf6d#%VVGsT!m%zeN_uRdFBLd=Pczzb?hz%`{=^;m0 zEPsCxP2a@B!E25^3^(p@?IVNia-d46V)epTpI>?oFftB%@tc~CXG$Podit)0(?0Sd z7J28{H3+kohnYNj_^4adevn+OoaPds2$pA|xq8Mo0>`N?uE4eeCfBE4Ki-guB7meX zS8!T%-L%w*!W3XeZKB&EJ_ACeGN=hpI*7t#qg^^hDb#^}RIX>V&s=MxPd(Adp0TXC zUV@WaCo|a;r6Nc8r%MYvTh==1Ss5ty65rad_f`T0v1MN1?FfI2t2RdePO^zEI8Gx(J>SE9w(cc$ndG9E_cP4f09MPoUz_4^7BU^`!UIl z_Um_WWM+66fD6tcyQTb%*b3L)Mfe9j>q-n{5d>Cuo#_HtH}Ts|NM??5wB%4c zHXwu)?7By*#>L^}3Sc|`sV1uMOeIMI>kp&7{J|X%kElro?uh!~w zMAR_vuhaL6#w8H5nWJn>8NsH#$I?t_X*&jq$b3t8SDIW>=N{+!>{$p6|6aWuRDzQc zI6wTbNl>$y<4bf{GjziIf7z79w^n~1z3FVB5RPtby0grib`*qjs#L(~*SHKJ;34&y zuwxe+*+B7`xp`vRtyz;Qz2o!dRJak$3~SDbf?0skcyuG}rHrV)T%2?E1iR*nXm*?o zQ)WC!5~45z$Lc;2E5q&dbUr@WmKWHqF+AUSg0J;1)C_D>yJ~uz|3~s?og0c5=fRlr zWIL_0_#A!ENz&UBh&pb(23F0QYJ;*p)2utc%xS=1q#-)+%D=;tDH41G(i!3Q*d_Su zR+nF7KV6D0!|&vt<_RgLl4`rUV5Ik7(<4AU7np8?!{)pJX;;3B7>}q5oNSoAhZAE) zj%?tH=6VEz0C>E=vqWV2**{N|@E*Ak4^6qqjr-NgUJn~*QcTqys-w2sG3!GlSXw*&LlX6{_qP2KIa?Y6{@NcmGE`#v42 zZE1V`220}&xm>Ijxt2VSbL86Y*iXVI;Y09+clvV;Gwxv)nG+(5|Rd4uTSp8a7`dB{KkAK=32dHlJ96`xe@Q}P_l zgv$K6M%rG0O)IB93h_AE*PZblhzrHGeiyyeII(}j=l4k*I4M3b9zsNsXUrrnBd3{3 z21Yew!6W8)%yLDGju8US1GW{knY8jzxS6+)JCxK0CnSJ6RKHqiig?XtbDK%@YIT#9 z>a{d5&W@9CMFuJ^@Q`AmH{3_1Gh_#fKD(meFP+8m%wWMIXIXoK|L3X)!?UWF6Wa7q zWueF)-+XU0d>K{a%>m@pS`Jh^1r!lP%#2D%+8$kV+bmB`<|yO1e*5Rs#JN7fte(!2 z{hiqhLz~(3TYWE|2+C9m@uu(CS9Ui2=tinH0p=n)$V50Kod3zRMG+|25xhjk=f^&9 zI!9dEWgWQDU>yywr1xQ#dH?&PsO$Wu1@JmJ9?f8ewE#B2J)S$3`b38zcPg*2n!eqD zhBMiM(vyAeiLvGgq#xS`y#7c;quaNYNu~vYIY5r5D5%tahgm$dLJ9ztBh1_Y0QZP) z`%CsHt3YF+@P((V{E@r;`O(H8%Zix1J9?|31?>%Bi?E}r{Ov)zN^OQLUX~<{A0l?wEy?KY>?tN*iJpPU3=BuyG5PLocG zhmat|zHvjWwSM4LAcykOhX$c2I*&S3JsF!}w|mEneJYx2ee-Yj83Q!nuQ|15&56g?$qCJdG8=f!9IUg;uxO1z zv=bH1X8=ZntRTJn@>-^jy8w+4cwBT=O$9B8Mx{)+fow(Ii|~qA4Sv)}G%qP${&5f< zm+1p8J9H@kQwKV%W0*Yq!`#ghAf)p8srW^OsGn?n-z`p)240<8aj5CZkBHjBD^g+W zlUraUD5+(C)sJdefT3bGiq(nL+YfOjH>^Yvbj*lqG#X_aK*CW_GD~m!p_HmZ5jv1) zZ;(E_gp5fidB5mV%?2?0l!qvu2gf@9#PidV8syovQ*i?6n+e)UEb9WVkNE3-osWcA zp(qToBdTkTG*D5e(g$%tx9t23Z5&tcE>OrB9p~`h5W>a0XBfES)UCU})en|)uyA%9 z56oNZ_rzx6t-YonoG)QQ)5@68qwY@%kdCYGOc_)REz z=|98CpdJL6@d%Orgrx0*zjKm5j0J)KfqKBa>iW6fFT&~lBd%@O{rv6glG7&H2qTci zX!vp&cA?tJ&uV@y+fTJavoDV)G^LYFO-2D}kCbmD2*C%_(GX69l)lovM{09O&(Ng- zg$f99s*npeewrv40;m_`wXxd_r`mlX-c-H<1@O2SZpmr$TCpjz%;ys`VTv7cu|E1_ zMY|HpBHtxlRYTOsRD{UIH={ygtlS5vs+kx_UTNmFfvh$!*k53a+IITonWPRS1Dfna zNe^=Z!2c9|@UiMpD!SaE9bkUtz(9Ravv`~{v#=9wH?f($aw0t|>{Ju};u@eiGx%6^Vv~cKpVXD$y9Bs5Wb=L?Q}@Fj-Gq^EK9 z6am5qVtxI!0A_T;IlDRqkFnE-KJyUb^i2PrVk!^Lf{^QjaHnt-UlHs(PWQBB-0?{$ z?&8e|-z!+B2F4_q6&?_lu-qBQ)CEwAUY|w`PDPYrU%(31Er|E!w@74~oY8Id(ih7V zc-w3kn>NpX4qmxY8z2a_?G7rd{w-00EO>aCMSQAq>8Y*gAamv}D(JGaRS~2xoNrbc zLinKV;R;#mjNLnuxil}{>%|zCHDs)E1E7MfpNO>#3D-C0rz-(n#D~kZ{Ga6x(wG#J zWuG4Rdu3g)V>VZzArxXDSQ5R-{z46nz=r$6?nC73j zH)#fm1aTyR>p=p$z5%j|Fpt)A&uSFDVy3+#ClC1~cH~HOE10k6-B&0{ym}-vxLR0G zqq`$g@S3B9MjMVKYy*4O*@0nAgIIK)qXKoR;r@iCS8C10Fp8i+lAjVg^e2WmUjYGs@GwCUCWuQ9$6xPHNBvJ@Eh|R8s%gAmvTHbU7g5( zKqgEPhPr}Kqe_Z)WUf*lQGx4V;JEr{Al4-?W5LC3)o#g3V>`~Fw87cxckM)oDMSJX z9bzw7cK};s`S_tB&Q6UYL+Q96|M+@hiYClryW~gLVj-j+b!v#wv`?6KKAH3O)9PKY z4&Dk7ggp)D27Pbd#~#tRag!NVz+myv9SQPwHA>&N-q}tWIizr$RBq3KqDMLuL_*-bmH9$Q8MP=w_u2MCQ`VfR z!oCzHcRVLvnUlnYXVIzfb1K3ek-NgiD}Vjsm|YT-q)uWW(s4+33W!p@%U`n{<_DBx z?VkAbii2Pt-%G_Z@As2pt!@Hh%-D$bO~|BRJ{>HIWBkE-?c)n3lPl$hlV>W%jYr&2 zwlgo3AN_7=deNIKW?Z-KB)b-#8J2PMW9O^4ot;{97q3>n?>wU2tXQpe`zODA^Lf{Z z6A?C2X}Oe)#^KA$f{RjBRTP&eUu(sq&i-b(C`f;J*FJRx^<{);8)0y4kgbT4SjJ<< zLU`}JmOZ!yZ-M41M-2(N zVY?{^mBGc(B&lis9W-+AybcJ%MiN|`R#tem4(T;Uz3qrdWuCgNT|4IkLR2)cr`i#S zUpOD7pUEiljh1z1?=>*Gbcq!OQRFmw?%h+j7N(_6n?K7?HvAV?Pvbq@8v>(;S9i?~ z5GJbq=K>39@#pmkrJhGoY=WEDN1rPIa_;ekC3Hhm1}II!iy03zq)#{Gssk$p4|p)QH_@zwy)Lt=G20aDS8WU9@7^(>N(iMmH4yG48`%|m%eAh6f$gl>0w@f)yJQa< z9JF^ccO(-?AdF`Y_TKCQfvDIPY{f#t*}=1*sVkQ+)tCuZGG3_qHDY^V*84YC66-Za z*=c_3gKm<@+TfLM;)6K%Q6~CT;*e+>rF%L;fL`K~>-WulZLJ7)A#12C!jisk#+Gum zZ?$H9?ai(3dN;WKrz60E*a`8|hwC|c0)cv;to44+2<;GQF&sO#^(ANxX#Ifdq+@yk zD$?RCg+S(;7=@9lW2tc# z2TX`HwqzmWY>G*I-y8RLM(`#e>5#O`+k8n3F_5W?AY0#Y=*oA`FX+}Dt0Y&hYs-L; zHLZS{oo(>B#MCxPgx{tiFR!vw&jOvkJ8kXL*-LDv#ej-9I zaob#r_IzEluIUd2cS{;0^sUbr7$Ms57_6WX@F0pV?qrz5D+q6q)^12T`* z#Rq*3cr=_;;aJn5=TFTkDPYZHsOGl9%I0i*5k{Us=%VwwfZH!Gfh#xxzJ$_I@S{Oj zWb>Wp`n0Y~H@^+w8OU3&L1e{t={&J{S8pN}p7?QY5!W7<+fB$&& zyBCMFe+07xNt#z6dRXcWvsgu8nOq*gzn4eS9?YLi*l_R$57cXt*F`f07$3ZC>Di^9 zjSf4t*RSPf@Jl_IfjjeK3%6Fe#Xqj;U&}vDYl~k@E7ZNe@f}EKgeUcs&i+0p>GCFO zlz+QOTqqQl<{x_&eO7MaTB=%5U$NS`qLE8JyA?obDTDTMxm-ppl0Y<)QyP~nfLMGB zm(;bRA{x0^pMfyWFZ|lwr*6QzJ{a|@>;K#z-VXNq(C#|JuVPO|ih7ffX$0?So} zFuxL{rFUQcaLr=@Jxcx%{)(fq$St?vQmGjVc7Y2*i!wqOwKlEO^DooFPM!FF{%`#B z68lHXo5f_1Yytyqtg)_fxx5jF#_<`<0MS4M1^wONcMc{jxcVloFi_D zlNc=LnGuk;6rF1=&GRS@@j_n z1B!$8oYs{ofZx6m^7g12;3|S&J=%ifmVhP)ifP{iV+$}jG(Y*>StXbh#0>i|?Hx1^ zWK(`YRHAg_!n#L1E2@qD>EkxQO=tN0n2$P`uZ`-!qMGwv7{LB-k_4=_^^jwa^Ss^a zjFDqZrAyOK%xoSe75YqM)5H;N!(5S1)1rF9RwvHsphIkI3#9)Ey8Jtnp*h&k{bopgu zWu3&HbMjm(pNKz6&QyV1a+pOI69wm?C&9!H*4qJPE_bBu`_ZEu1xufu{AR;(?$7F$ z0k2=@M;U+3p{^fJVFa!Ld-uYPRFsn_jD%6Kp0A(m^28?E*X~zmwy2 z)fHIx{)(sWGH@M`u>j)nvx$nF%$Z#neVo*dJq=Fv_x_cHOzL=-R@pwb2eJuH$F58m zmcOpf)_wf1-#COc-ws12gm~}zZ+Ox>p}m+RZzMo)Q7@qTS;BUEcew&eG2-~1Cl-`- zGkvm+Q=N(sWm2?4eFoyFd_iGUybB{9EphG&Q@Z;SQFq^q-n14`k*((EN?-Mh%KrX# zLz^mv>thnR-J3yvO}d0gI(r~_ z(}!&phS^*C1J*c&{u41%FnSaLD;Az5PHh06)CB{Lo|3q@ZW1K+0Fc0CGlISX&oIYS zDl%{8HO?!I+ZXgdirgxq#p?b#AwRje?DjicErd2Yg|^hL(Oe{?z7%_;Rh6ycV;2IH zfq9~qohFumJ0247X@P40j?4X+@|jKNzDKydtV$8~+Ko+F|hZjSzZ^g@H(PuzNxo1sbjRs}igyZYT_q(#+abl|Q5M15ZF)x=j2LR&gh&k* zr2CwH#+1foaPcC1$Ki=Tx5Y&?##>kXFu?v#uw^Ao>2ACMok+hN{^}~R<*>apS+{^4 z7aIc~(}9hv2YVJ$7;V>@=&sTtzxy6HV?YDn+e9XW0y~w)p0^2)2muX7Fg>Aw4<{}t z+IEWoJaUcW(e zQ;>&=f>e_CssEfEemb`ei>h~})p@4ZgFtO-u^2h+KjaePLI(`2Jx_$oAb}1J#Tn^Q zsvxARJ$Ylf{%=_LP%xY~*!Czzi&0QxxXl7r|Le)N4{8wTiACGB)Cp^P%x2kDxQ@v= zRK+AWSB*!|$HstWM>iXcU(2U4xh4KjBa1%upX3{;aT(KyXOz#teTZwxr zVo`6KFl9_nF-^zwt>X789{em>^FiDA+ITaYuoM>$TEq46m?BL8@*E_{V5F?XYDLqIKt8Y8w{U<`$o8kua=0S5AW1x!FfE6a4qH+chcTr+zTf40 z^(pewG>_Hx`O--LK|Ser9h;=^zE?VH?VhU4MK_NYE?q8D|AVisMF)>){);joWHa>O zv1bbRPl|)#peQNzD4-PHXr8T_YybfzUxHXz%d(dudzS#`;rWWgXf{*C1&xxzVJh(U zIN9(@Gqa0{LbFhVPYSTiOR&?}#PmP{h0l@@BV=Uo_;X;7wteu?S4)(VmulmocY69& zX3HZJwz2zEa(HRaI}4}EF})X-IuES zEyNJ80;E`^p->RU0dE~_IXI^sJPZ{E7sx6|exLawycU+&GwC~03-0{FpA=)yZ|q!m zLx?P0{!j=u*4~3Kx_cK*RSCWmSXyxpt;cyTPFTnWX7g2UkXG2{Q!%mZ6JjK|l)`23 zkb#g?@dqPA$U7}S;&Pb36iVe{e1|=H^?0cGD}y+s!6ILKk=kKLz~Uhqm>gKGn;7qU zqRce;?wZJ=bmwzXO6l-W%a2wCzBU=LkR3f1!n)hR#$!lpUicDuqlrUn9duvX-N9io z1Clp}Z4(+h&!Iga=Tw_ueeNkdDo=A;sZTQVl5_F^95yOW1j+c$r}-0LC(b9aS~jGb zST?1a98+20F;lVf_E1Y=9nxQbDD-=(m`yc=_CUzrgvpFYR8dP}i-%4Z`Cp%V=3zUh zJF1CW6a}$rH4;44&H%rZLj!t?7{rtBoos)10|yh{2fDD=nt#nIJQh08*?iJ-Q{?xL zwnod_Q`}>cx*zM$xpnQFa8E%~#co(Nio(kruGQMoW^5xQd+47I)0w}| zHVQcw4M5S^DU=APcP)~x$=YXHH(=kgI|wNTfHV)6C5Qld984P}e_RHH#W!8?7QiJN zq%qR`xrW3lRfdXix$tZ~2iqJg5}8>pZE&zsT;$Z*#2X|;>xk^6&N)lzD`H!Wr{z-S$6AKqWHj@L@!`5Cesi5Fk61JYgGNw0`*!5EWgUvIuZ5 zS$7`IJ&oEnx)K+2%v23onhGxunTMKOH0>2KRNfXll2v^y!v9riw31wA*3y@JMG6ev zue~#*cgp3p)T-yH)miV?DOSLcRNabL!yR_vKWxzAf3osIC2>O#s~qXlkhZ}O3ys+{ z+Dxh?kJX?M22OyMsJ|E73`;==*~2H>)0MQjti+#Ig5v2v`1c5c-=@DP={$vt-48Of zIU2C^4l|;r!c4Sk+8CEIMxGn=Pw}oVqUZ=4+0__R$SBzs;$7=h2>El@riT!}!NaW( z<$oER|2nYYzYw?u8MmLTWGN6r^T+dBBL1xCxI~z3R*%vgQyk@E=Ur=%6gVB!kxu_{ z1Ql-~ee1b;Z~}0mi}Buy5>|_`(oAXuZ#1R}McH?;RDF42Y}sSXy0o7I5BdM1GUZz* zfF~z%BX<`eNW))dR_3f^zS%%6OLf?7$Y04Zm&|&swZCy6wEW)Fb=?$}Id+&0dWWRH zeRKTvBX`!i=?Gzwm8AH5y1=cAHn~Xx;jZUdqShr29&sSL#OV8 zC@*786kC@vMf~H(_P=abSXerEvnO%=H8^HnGiIDf$D{T5x?j}xzE87aBRQ(A>pvPb zpY^;qIe?NJRLm534I%C3^!oG#Z0tIgEKh|p8$J9YjrcFe_vq`PqkWbdzp?T4g{ShA zp>a4E(yJ9Od>wm)ZnjT@VGJWFqj5hTAKKT%*{pqA(|yTobjq6R9xD$z@o%<+`;@ zER2nerY7Ywv)ndjo6T5CiJ#x&_c;B2kKZ}x_j^2^kN4yKet-V@{PB7`-ghq8LF8n1 z%K!i%XJc*U2mn7IH+t(Wk{k7rxiA<2B!LUI&Zk97OaHdGBoh5Kp-A-qErW*i%G&I^aaNC|XSUu$?<9eI1xJE1vi^XBE zPc5)qB(|M|d4|C}#bB^t4EH}3);E10YwIx8wHWK#@uC_WsPE3V2c zev*l*$Sf>H7NC)N#aRyvGalsK%gMc+otu_*Kjj`WAw4rL^)5W+c2vTx$k@aPczj4S zA|&!gVEFaGu!yLTh%3S2sGtb?ZxNloAy99auQ$y7vagG$w-fZz1y?A;+1J*|waCef z;pl^P@U*sbusVBw#Kzt7jJ1W;8L;I^Gm8@@;N!-oW`@U1^o@)U8yM;x(LZqTkdCh2 zFFN}}T$4Wmz!no5D@*5_qx=C0=?*|vl4O!ky_;TkQmt!@V~g)Vr^S3QOT4O1f;2YB zhV#~|ihzLQ(RI+xJ##CZsv(KHvoJ>~Kzidn5jmmJ0g2@gOZfA~)H_6ODB(};djT`$ z8}Ig?N;G8tB>l6y8`SFtDq7bvs(#;F!;t&CK z>}Yva6ldF=8RW;?-__M=Pna{hX|KifgPev9HIRWP|K5Q!^S z$BxDGaAOWJbwr5QFbp!R`buNf2Knq9(mzh<;1Y*ygt!Dtmb93EK4?RxUlApiqTny! zaxxDJ!jc4nU)M2;5=oh}82Q>3kLUW2P3)sJI0xI#f9|;m5+bBmvHb3qWHy{gE ziQRVws)aiar^GfHypAgDyUup7*K0O2w#;hJC)y2aF$Qbq>A_V=yL z#-8sljN1ZJT?h{sTk3^>lY0GPKUi=Om-XU{p9F6%O7}X4y{D+ERsARH&Qy$tY2q&8 zB|2p8?J;xXGX$}Y5VGXZ{t5C*Bg{!zPr~RdjvpCW7MY)`-OQ`Zw}+3a_-_2Wlp;Nn zq?scQvwY~Wuzg`s;+A~1U-S!gAI_;5B)mD92nmzRTwQiUN{$a?d(7?BE2rfB7|`2W z=Gk%rj`x*Ym%dQ8gIZTEv19{3IUo^9^WEe+kGl)H?Fh9jZRi`?mDm$TlFo0Hq$c&C z{6V+-FDB+ps&yX8*tKY%Reu@G4c*Zq2lz|cR#19Xw-uQiw*{a->mY-JH53zfvm-qS z9>qT|hA4+B9t@v=%;QEumI=%Yxdr_#t?G;z?;A6?;sBt6!eJ>KDLs_9Q?f*S%#?}T z3h6*em)LHL=7rvGWF)QYABX!9^32}rT=QVi9+q4zd4w#}Q+rH64IWX-h^=v) z7qwUC)GOCf%-XBwlIZq6TRbIMCTZhfc z|BQlk0$EEE$K(MW04oKw{s=sh&3C0FZS{u5f^DT#eWW^{ddgsG0O%Ef7;*TinETwd zzO<6ww0q#WO`+!HNFgfvobU=guFQ$PboAcMk`U72dvX!2A~afGobJOBb>0T)%YuD5 z3Z1U1h^~H(w8s$su;Xu;x_jmqbu-Xq6it@{@zCkJ32GwUjAHFq8m=q&A(yO`o!xH~ z*$TC58-x86Hk!4d<|T;}%!lksbv2Wx)im$S^e(1@Y~Ejw__a;#D>N-T zZEjhnoS_+$bXF6+y<|wsr}E^)D9$5W`(35}B=3nNjX>8d_72j2$+&bj~X3Uc%zlK&D8bNzNl?O0DW_ZS^TgM=Le*MZtzL=;5h!kVPV;Bw}wWNa|~< zzJ}8CqIcKHUsz<>t)=H6zt4?n7*u%L-{kxMx;3MR-A5!H^pM$W4|;NY6EwvaGrSj} zXq>B!{C&c(bCDj3j=?Wmx15tXRQAh_bpqs>wfidjVZs8;5Q4n(G5_lBhKM^cb=$8o z_r}SWDf6w5&wJYWkT#7R9d|f|M5Ju5&4GXH5Sjm; zE*~cl6=pAHSKXL;=zTawEpwCgo1ELA2V8}b-f0lWwXkM>m^e!5dh?UgQ8aFub$Ou@RO7&9Ij;kWTHkZC=Yu6y!UkzrED&4nV z?qB{~$Yd?-l>x^GBh~U(x75*mcBJg-hic)W@mkQ`HRQ54dwO#q^IBW`0DTGiX8A~g zf~U&N+r?lDaX?bKN=*1RKXq`8X?jV_t0INn{xBQgX@xPkxfQt{yy?6T1tpXBrG^ z&}`#JtO!-a`OZi~ZqR3Di3;nxuGK@2azif_td-lCIfap{IAf)y^J@!sa@QvB`#OI4+BW;a z2G1yWpn?L$>!7=!2Yk_due?_vStE{5{ed-~$2Qr>iH~YyUsn857AO$0)@tV@&UZ)7 z9nCW`f8u71#rMN(ISOE+KN+?fdm6NnQV}BPy|PD9xD$*ycax$v{q^;c*!6!V zd?WB-LUi<8;wC^jE$PuMLQ(p$16`JVnN^%b3pok|qU8RhSzUX`YjaOQyfYD~Qb%@s hY`%H@i%7LY^2Dv&8Ix0f1{-%ZU~}5e3Ukss`5%-cjX3}S literal 0 HcmV?d00001 diff --git a/doc/signatures-panel.png b/doc/signatures-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac40bb5c9d1d065ee482209bbfd5c5afde612e0 GIT binary patch literal 22494 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 xMHRr+P@g~=Oj1D^CNQPWNps5n213k%j?6e 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 literal 0 HcmV?d00001 diff --git a/doc/tool-draw-ellipse.png b/doc/tool-draw-ellipse.png new file mode 100644 index 0000000000000000000000000000000000000000..d4aa579bae6e01ee8e09b410a23ea4df327b7fb7 GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>#FVt^+WMZp{_5JgxWpu5bIYq&ubG%z)-^Uwm^9hg%;MU$ z>&dCnOR9GX?lhxo!z}1-937S#=0POkFKF{a#}`4c1}uqriqzlbzOaBb*-U^ z`L*je_8&NCVqqB_mrzwxTUk>Z5glu6ZgJq?p;xb8_x4Y4_w?1$(|7msdHwp0@3jpp zflg&i@^*J&=wOxg0CG4BJR*x382Da-Fe9I_lMGOhy~NYkmHja{2cNux(5ahxK%p#8 z7sn8Z%gG4}{02sbn>QF3Z#?uP=Z(yqn3y{@dvXNqxgCp9 zOZmmkz!k~yWzxS5RX|%+OI#yLQW8s2t&)pUffR$0fuW_Yp`osUMTnt^m9e3fv5~fc zft7)QI@3yT6b-rgDVb@NxHW{u3w{S`kObKfoS#-wo>-L1P+nfHmzkGcoSayYs+V7s UKKq@G6i^X^r>mdKI;Vst0JL?#i~s-t literal 0 HcmV?d00001 diff --git a/doc/tool-draw-freehand.png b/doc/tool-draw-freehand.png new file mode 100644 index 0000000000000000000000000000000000000000..00b8c15139b967977d4261998c08b53434c6362d GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>rkR^xxPHS%3oF~D%U0;<8#%0+IumoNJ9qEixpQ~*nsurg+RK)&T(WGri<_sNgY&g(*I&JUos(A(8=rXQ z?Af@4r1u{_Oqe)%!NSFV|NadPkNWoQ`{T!tckkI-QCV$nWz*8u@%HW8&0DrcM8*93 z_fJdLz{cJ&IW>LB(q%gOMv*abw{PD$#A9a#bUb5{x4R2N2dk_Hki%Kv5n0T@!1oe_ z8TpKzWPpO~C7!;n?2oxQ_~aE+&%WFN6sq@haSV~ToSdK_Wng5u_)}!W%?YkIEG>3M z>=dk#i?d_%6RWd`cL?ZkjA)TPCoU>1GF`ysgtwRH=Z+4AA3Q;8VvLd;>~^o2V-wLZ zb*gB_yrxByc5LDbX=sfP^$mz^ZgdpZS+I2N;?>LZ8B!#q8h;#9TbA~0mBO^vrJ{!O zSQuXSaQH}U`F#lJ6x9;fh?11Vl2ohYqEsNoU}RuuscUGcYhV##Xkuk-Xk~1yZD3$! zV9;2)=s${v-29Zxv`X9>K4?fe12ss3YzWRzD=AMbN@XZ7FW1Y=%Pvk%EJ)SMFG`>N S&PEETh{4m<&t;ucLK6UW+2@l0 literal 0 HcmV?d00001 diff --git a/doc/tool-draw-highlight.png b/doc/tool-draw-highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee1b32212888e272658329ecd5d80365173031d GIT binary patch literal 466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>#0boTas0ZC%6i6)QEg^?v^RIb+sr3oF|fFJ7o?>7F`$X2QhD6DLnu zv2xYKNmDwzdQ{Z4{{8#sacLsZNCw6vZ+91l4pvzYAcwQSBeIx*f$t>>t*I;7bhncr0V4trO$q6BL!5%;OXk; Jvd$@?2>^>El+geH literal 0 HcmV?d00001 diff --git a/doc/tool-draw-line.png b/doc/tool-draw-line.png new file mode 100644 index 0000000000000000000000000000000000000000..1b9b8e8dadb006039deffe9fc7e838e4d8c35a24 GIT binary patch literal 376 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF3p^r=85sCpf-obWv6Bo?kiEpy*OmP- zHwT}*(w`$cn1Di>o-U3d9M_W*4)95^Ci1vxI16eWdc!4Zz^M@C5Wu0OpumvI!DW!Z z&T!d+nSWjRWp1D*)e_f;l9a@fRIB8oR3OD*WMF8iYiOuzU=d2D?NY%?PN}v7C RMhd8i!PC{xWt~$(695*UWibE% literal 0 HcmV?d00001 diff --git a/doc/tool-draw-polyline.png b/doc/tool-draw-polyline.png new file mode 100644 index 0000000000000000000000000000000000000000..1125eaca56dd1f341fce5900e922564bc2aa1072 GIT binary patch literal 475 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>e~8$|NfbnTfKk(e&M1ew{G3` z@b+D{d}U2teNl1ghE1C{Hm|t?G?OvO+uensgH_f8$l)yTh%9Dc;Cl(ejC{sUGC)E0 z5>H=O_Q%{DeDccOhdZVKg~B{t977~7CnqRy85kKY;xsTwT9J_CCYF$xn*2P$UFgA+ zq=X005+6N%+WO(=57q{i*$T?mS2Pq8R|M_}U=$4GID3xI)ZIs>d-H_5$2cA-?&fu7 zWn^GDzmc(J)itBdKpRv`Tq8lpinR(g8$%zH2dih1^ Uv)|cB0TnTLy85}Sb4q9e0F%6*-~a#s literal 0 HcmV?d00001 diff --git a/doc/tool-draw-rectangle.png b/doc/tool-draw-rectangle.png new file mode 100644 index 0000000000000000000000000000000000000000..3d05f65b88069ce7d03ca163e2d215d874b026f7 GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XN>+|9@pQ%?Xnx z@7_@63>0Kc@^*J&=wOxg0I4YOh%9Dc;Cl(ejC{sUGC)E05>H=O_Q%{DeDW%y%Vo`h zLQ4|711kfA%f7u4C>nC}Q!>*kacfv4VEP28K@wy` saDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0uvp00i_>zopr03%IZ3IG5A literal 0 HcmV?d00001 diff --git a/doc/tool-edit-comment.png b/doc/tool-edit-comment.png new file mode 100644 index 0000000000000000000000000000000000000000..d720a153c458f8412c3adb6240f580b7d7087547 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8Uop6XN>+|9@pQ%^9<1 zPnH=O_Q%{DeDbPE z3v?F(g_J#A978y+Cnq?tu35N{kw=GzhiM1r1|dK81xacG2MZV??HQW(Gar(EG8tro zYKdz^NlIc#s#S7PDv)9@GBC8%H8j*Uum~|Uu`)KaGB(#XFt9Q(D79*PgQ6ifKP5A* z61N7Hbh`kc21$?&!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NC6cwc)I$ztaD0e F0sw*IUy%R+ literal 0 HcmV?d00001 diff --git a/doc/tool-edit-line-width.png b/doc/tool-edit-line-width.png new file mode 100644 index 0000000000000000000000000000000000000000..63e0ee59ff35f3eb40bddeae264939b08a78f04f GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XN>+|9=&AEoC*$ zr>Pqc0R?(8r2flh?11Vl2ohYqEsNo zU}RuuscUGcYhV##Xkuk-Xk~1nZD3$!V9;Fj4dfMshTQy=%(P0}8b0a!?F4F&1lbUr rpH@mmtT}V`<;yxP!WTttDnm{r-UW|v|(Gs literal 0 HcmV?d00001 diff --git a/doc/tool-edit-opacity.png b/doc/tool-edit-opacity.png new file mode 100644 index 0000000000000000000000000000000000000000..a91957a1e527b72b2944a09ebef90225aec6d1b9 GIT binary patch literal 558 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>j`i+H^ZBcRQj9Ig%&zx0UT7LA{aVJ;zpFe*dJAT5&&2#VGea)@yfx)5M zckB!Z3TOJdxdVxYIo-U3d5|@(`6vPaS7IGSF zUhpaM=8cFzmK&B9J16|SW3y+EO$~>g{(c7LW(Irx7>5842@V&RhfGP26c{-@cQi~f z@o;bx(^F7i&%n~dJ(XGXO^`&3I@BT7;d zOH!?pi&B9UgOP!urLLi&u7O2}p^25Tp_Q?vwt<0_fq^RP-;F35a`RI%(<*Um2#Ijz y1!|B4*$|wcR#Ki=l*&+EUaps!mtCBkSdglhUz9%kosASw5re0zpUXO@geCyQBDOyO literal 0 HcmV?d00001 diff --git a/doc/tool-favorite.png b/doc/tool-favorite.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c2b61f174ad1aa1f607aeabc06ef09c1d6c14f GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>GHgefsoSOKZEbnr2H|$AN=~>KmKm6O-*6oK@7dUcY|h=Hcz+>i*)z z3kPR6TL-7dPo8M%=zsqF`O~LQ7cN{}y=Gl%dgjB2kDfhyUR+wfX6?Fd+jj(HCK>^4 zWK8mQcVXyYmGuB}I14-?iy0XBUV<{XE)7O>#F*gUFyk@poVi!;-+0(@_ zMB;L9zo$@x0uM`}dD9Wuqf`Ia2f6r8oi`);yUI$g%tcxP!Q1S{EovzJQOIKAg>BoMXC2`=z3Xko1cP;#kG(%F{NxeK z14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>{&lz9_UL1=iCrjCAE zMpkBa?(g5f_w3!Lp{;lN%-QtJ?Cjk90|yUXxN!03&!5Su={b1?-@bkO`}c1`Qffw4 zj;V#Ue_)8JhIV6f%kmW~W8)J;!XrO_{ycB~0&P7*Wi`#Pi0EtAuHU?M>+q4I;gQi_ zzI=&@j{W-etDd2WzLDv%<0twjOqw`p%26xtuR!-RCV9KNFm$lWdH^|`1s;*b3=DiP zL70)x*hvN`$X?><>&pI^n^RCjfcw&^c|f5WPZ!4!iOb0e3PJ`(hMN~~Y}mB1xIl@! zpz!mDPl_LZva-xvScVvyTbUSG8JcMu7+4t? zxEOODN70a*pOTqYiCcqd-o|R621$?&!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2 RNC6cwc)I$ztaD0e0sunS literal 0 HcmV?d00001 diff --git a/doc/tool-font-face.png b/doc/tool-font-face.png new file mode 100644 index 0000000000000000000000000000000000000000..620c37e6f285cf1b898bc645014ecf354ba98035 GIT binary patch literal 578 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>@IE?&B89NN;_?&afu z``2nSpgS3pyxm;OkH}&M2ELad%*bc#Bm)#=FY)wsWq-`g!6&cvN!|eH zS%yqc7sn8Z%gG4}oCZb*XP(hn<1nd{_gMP#2Tz;=PoF(}x_wP+yhDIT1dC_)iWwHo zEh>}vG&9-QBqIxVh*?&$vaz|UrtT0E4K)a8&U_Glogr{m)U5zUS+Q7wrOWdfL=8-u zF1Q^#QYpaDAjB5qc}rddXsK$6YeY#(Vo9o1a#1RfVlXl=wA3{;)HSdOF*LCDzbg+`DhThqteff1sJAwYineuHAdAY#ny**}G-mdtIPL#w2fd7lsa2 zSq~tGv%n*=n1O-sB?vR}89T`U1=&kHeO=ifb8`wx2~J$Pt`cOMr;B3<$Mxid1I#Rq z4h)Ax8afk`4I~{Tbr=KO7FkTWsKJ@4Go{Vw+`Yr;stjK)vOF>1aODSTR4s9hC`m~y zNwrEYN(E93Mh1qKx`u|j29_a)=2k{#R)*%<1_o9J2JG*5l%r_K%}>cptHiCLY!kz2 ypaw~h4Z-BuF?hQAxvX14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>aU+1bgh zFjG^JlO^bq!8!pUhagpDZFT%e z7;76CSQ!{}Z&>{dMMG|WN@iLmZVkWQ3P%AoNP=t#&QB{TPb^AhC@(M9%goCzPEIUH Y)ypqRpZ(583aE&|)78&qol`;+03jpEfB*mh literal 0 HcmV?d00001 diff --git a/doc/tool-format-text-underline-squiggle.png b/doc/tool-format-text-underline-squiggle.png new file mode 100644 index 0000000000000000000000000000000000000000..23061d0a464bafe88d3137e251cc51b463a73999 GIT binary patch literal 538 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>t~qn({rvf}rLDuz z#B9}?wP_hy7cX6Y{`|Rzx9^Nuv;6{tFJHN0Ze_D~-~QbE!n}f_J$v_ASlRjp1WlhY z)7v-T#fujgE?&yW%2~I5gPEmucW=LL%~e03V;GaX-CYqzi*NBpo#FA92ErERK(!v>gTe~DWM4f@`AH( literal 0 HcmV?d00001 diff --git a/doc/tool-format-text-underline.png b/doc/tool-format-text-underline.png new file mode 100644 index 0000000000000000000000000000000000000000..26f9dc4063f23fa5b19d8b8ead45bf99c315d199 GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFytOG-&gOirCMciz8$|5mJA<>lkAqi^W#8?bWK>MADtl|a3WN#5=* z3>~bp9zYIffk$L90|Vbn5N6~vc9H=KvX^-Jy0Sm!=HQdp&8c2G87QRT>Eal|aXmTV z027O(1dB$3hSUa@2FcE&a>56CuBPADci76vvmt_)A#fVoGUhX1bAWnOOI#yLQW8s2 zt&)pUffR$0fuW_Yp`osUMTnt^m9e3fiK(`Mft7*5i-dW1P&DM`r(~v8;?^+JRxJUj wK@wy`aDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb0uvp00i_>zopr02)SjJ^%m! literal 0 HcmV?d00001 diff --git a/doc/tool-note.png b/doc/tool-note.png new file mode 100644 index 0000000000000000000000000000000000000000..d7d5849b47712fb33a654a103e4940e12ba58a62 GIT binary patch literal 359 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;OS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>?NMQuI!JwIr!xDz7~Da1PZBm zx;Tb#Tu)A5U>4+M`)$v|rNi?p{(uVi3>zjTQ6C4D05Kkh{t0X>N{x4R0M)COxJHzu zB$lLFB^RXvDF!10LrYylLtO)l5JM9yV?!$wGi?I{D+7a@9W6k=A!*3XPsvQH#I0e) zRhz#+4U!-mg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kpe1W@O1TaS?83{1OS{) BTx0+M literal 0 HcmV?d00001 diff --git a/doc/tool-pin.png b/doc/tool-pin.png new file mode 100644 index 0000000000000000000000000000000000000000..8156e2161e67752f4c1833048ff5a13c6e092e61 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF5=_FA#YC?#}JO|$q5JeS{9fr-pJIV zn3Kb@NJgT!m$%Wxd&Y*18yP%QWR(saIAD0Qf^o*dZR|=1Cd>_E6TES3!YhWP9cl&} z8eAg^B2F_fWUb}&Q+o8;1!$~liEBhjN@7W>RdP`(kYX@0FtpS)G}JY)2r)FVGB&g_ zG1oRQure^H|KI-=MMG|WN@iLmZVh~k%sqh`BtbR==ckpFCl;kLl$V$5W#(lUCnpx9 Y>g5-u&wghk1ysb~>FVdQ&MBb@0Lxo~rvLx| literal 0 HcmV?d00001 diff --git a/doc/tool-settings-configure.png b/doc/tool-settings-configure.png new file mode 100644 index 0000000000000000000000000000000000000000..c19a5a591383699a487423cab4b33a3508045647 GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFO>_%)r3+5`-D~jGbhFg6t)pzOL+#xjFdc4ftzMdI5#ZJY5_^IIbrr9N=o< zS;%wUKtPg}cf)!I-l*{(^oMIASJH3X5L%D=M#QOGLrWLdJ7~jldY%1s6HcQU+ z7|;aO64!{5l*E!$tK_0oAjM#0U}&jpXsByo5n^a!Wo&3=VxetdU}a#?x&1%L6$lNv z`6-!cmAEzhc;&tTs6i5BLvVgtNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E44$rj JF6*2UngBZWe|`V} literal 0 HcmV?d00001 diff --git a/doc/tool-tag.png b/doc/tool-tag.png new file mode 100644 index 0000000000000000000000000000000000000000..61df27df1abc07f143f9b6112cc6acf079127edc GIT binary patch literal 513 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>~bp9zYIffk$L90|Vbn5N6~vc9H=KvX^-Jy0Sm!=HQbztf=~V2Pl;2>Eak7 zak;nuxKM)v59@qKosPZb|Nm=?x=xXBuF?hQA KxvX14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>?NMQuI!JwIr!v_9u}`i0}9D_ zx;Tb#Tu)A5V76vso=IEp-hIbqy>+3{9+z4XsQKv<(cb3=GOXZG4KNAvZrIGp!Q02KM!wkw6WSARB`7 r(@M${i&7cN%ggmL^RkPR6AM!H@{7`Ezq647Dq`?-^>bP0l+XkKBjj6u literal 0 HcmV?d00001 diff --git a/doc/tool-window-pin.png b/doc/tool-window-pin.png new file mode 100644 index 0000000000000000000000000000000000000000..a26376e9b1bba4e8026e0fbdff539e09cc69bca4 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFYgu5jcq3Db zVonarA{mL^UfxC%?-?65Ze;LKkyScy;DF)H3dR`+x3Mc7m@qetP4LFC39lHEcBmO_ zXmE`vh&au_khPZ6PwCNX7of4KC9V-ADTyViR>?)FK#IZ0z|d0H&`{UFGQ`lr%FxKl z&_dh5z{nC}Q!>*kaceMdPR;>pkObKfoS#-wo>-L1P+nfHmzkGcoSayY Ys+V7sKKq@G6i^X^r>mdKI;Vst0RDf0^#A|> literal 0 HcmV?d00001 diff --git a/generators/CMakeLists.txt b/generators/CMakeLists.txt new file mode 100644 index 0000000..0667b85 --- /dev/null +++ b/generators/CMakeLists.txt @@ -0,0 +1,154 @@ + +function(okular_add_generator _target) + kcoreaddons_add_plugin(${_target} + JSON "lib${_target}.json" + INSTALL_NAMESPACE "okular/generators" + SOURCES ${ARGN} + ) + set_target_properties(${_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/plugins/okular") +endfunction() + +set(LIBSPECTRE_MINIMUM_VERSION "0.2") +find_package(LibSpectre "${LIBSPECTRE_MINIMUM_VERSION}") +set_package_properties(LibSpectre PROPERTIES + DESCRIPTION "A PostScript rendering library" + URL "https://libspectre.freedesktop.org" + TYPE RECOMMENDED + PURPOSE "Support for PS files in okular.") + +find_package(KF5KExiv2 CONFIG) +set_package_properties("LibKExiv2" PROPERTIES + DESCRIPTION "Wrapper around Exiv2 library" + URL "https://commits.kde.org/libkexiv2" + TYPE RECOMMENDED + PURPOSE "Support for image files") + +find_package(CHM) +set_package_properties("CHM" PROPERTIES + DESCRIPTION "A library for dealing with Microsoft ITSS/CHM format files" + URL "http://www.jedrea.com/chmlib" + TYPE RECOMMENDED + PURPOSE "Support CHM files in okular.") + +find_package(KF5KHtml CONFIG) +set_package_properties("KF5KHtml" PROPERTIES + DESCRIPTION "HTML rendering library" + TYPE RECOMMENDED + PURPOSE "Support CHM files in okular.") + +find_package(LibZip) +set_package_properties("LibZip" PROPERTIES + DESCRIPTION "A library for reading, creating, and modifying zip archives" + URL "https://libzip.org/" + TYPE RECOMMENDED + PURPOSE "Support CHM files in okular.") + +find_package(DjVuLibre "3.5.17") +set_package_properties("DjVuLibre" PROPERTIES + DESCRIPTION "A library for dealing with DjVu formatted files" + URL "https://djvulibre.djvuzone.org" + TYPE RECOMMENDED + PURPOSE "Support for DjVu files in okular.") + +find_package(TIFF) +set_package_properties("libTIFF" PROPERTIES + DESCRIPTION "A library for reading and writing TIFF formatted files," + URL "http://www.libtiff.org" + TYPE RECOMMENDED + PURPOSE "Support for TIFF files in okular.") + +find_package(Freetype) +set_package_properties("FreeType" PROPERTIES + DESCRIPTION "A font rendering engine" + URL "https://www.freetype.org" + TYPE RECOMMENDED + PURPOSE "Provides freetype font support in the okular DVI generator.") + +find_package(JPEG) +set_package_properties("JPEG" PROPERTIES + DESCRIPTION "A library for reading and writing JPEG image files." + URL "https://www.ijg.org" + TYPE RECOMMENDED + PURPOSE "Support for PalmDB documents in okular.") + +find_package(ZLIB) +set_package_properties("ZLib" PROPERTIES + DESCRIPTION "The Zlib compression library" + URL "https://www.zlib.net" + TYPE RECOMMENDED + PURPOSE "Support for Plucker files in Okular.") + +find_package(EPub) +set_package_properties("libepub" PROPERTIES + DESCRIPTION "A library for reading EPub documents" + URL "http://sourceforge.net/projects/ebook-tools" + TYPE RECOMMENDED + PURPOSE "Support for EPub documents in Okular.") + +find_package(QMobipocket "2" CONFIG) +set_package_properties("libqmobipocket" PROPERTIES + DESCRIPTION "A library for reading Mobipocket documents" + URL "https://commits.kde.org/kdegraphics-mobipocket" + TYPE RECOMMENDED + PURPOSE "Support for Mobipocket documents in Okular.") + +find_package(Discount "2") +set_package_properties("discount" PROPERTIES + DESCRIPTION "A library that gives you formatting functions suitable for marking down entire documents or lines of text" + URL "https://www.pell.portland.or.us/~orc/Code/discount/" + TYPE RECOMMENDED + PURPOSE "Support for Markdown documents in Okular.") + +# let's enable the generators properly configured + +if(Poppler_Qt5_FOUND) + add_subdirectory(poppler) +endif(Poppler_Qt5_FOUND) + +if(LIBSPECTRE_FOUND) + add_subdirectory(spectre) +endif(LIBSPECTRE_FOUND) + +if(KF5KExiv2_FOUND) + add_subdirectory( kimgio ) +endif() + +if(CHM_FOUND AND KF5KHtml_FOUND AND LIBZIP_FOUND) + add_subdirectory( chm ) +endif() + +if(DJVULIBRE_FOUND) + add_subdirectory(djvu) +endif(DJVULIBRE_FOUND) + +add_subdirectory(dvi) + +if(TIFF_FOUND) + add_subdirectory(tiff) +endif(TIFF_FOUND) + +add_subdirectory(xps) + +add_subdirectory(fictionbook) + +add_subdirectory(comicbook) + +add_subdirectory(fax) + +if(JPEG_FOUND AND ZLIB_FOUND) + add_subdirectory(plucker) +endif(JPEG_FOUND AND ZLIB_FOUND) + +if(EPUB_FOUND) + add_subdirectory(epub) +endif(EPUB_FOUND) + +add_subdirectory(txt) + +if(QMobipocket_FOUND) + add_subdirectory(mobipocket) +endif() + +if(discount_FOUND) + add_subdirectory(markdown) +endif() diff --git a/generators/chm/CMakeLists.txt b/generators/chm/CMakeLists.txt new file mode 100644 index 0000000..9d82b93 --- /dev/null +++ b/generators/chm/CMakeLists.txt @@ -0,0 +1,46 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_chm") + +add_subdirectory( kio-msits ) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CHM_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/lib + ${LIBZIP_INCLUDE_DIR} +) + + +########### next target ############### + +set(okularGenerator_chmlib_SRCS + lib/ebook_chm.cpp + lib/ebook_epub.cpp + lib/ebook.cpp + lib/ebook_chm_encoding.cpp + lib/ebook_search.cpp + lib/helper_entitydecoder.cpp + lib/helper_search_index.cpp + lib/helperxmlhandler_epubcontainer.cpp + lib/helperxmlhandler_epubcontent.cpp + lib/helperxmlhandler_epubtoc.cpp + generator_chm.cpp +) + +okular_add_generator(okularGenerator_chmlib ${okularGenerator_chmlib_SRCS}) +target_link_libraries(okularGenerator_chmlib okularcore ${CHM_LIBRARY} ${LIBZIP_LIBRARY} KF5::KHtml) + +########### autotests ############### + +add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) +ecm_add_test(autotests/chmgeneratortest.cpp + TEST_NAME "chmgeneratortest" + LINK_LIBRARIES Qt5::Test KF5::CoreAddons okularcore +) + +target_compile_definitions(chmgeneratortest PRIVATE -DGENERATOR_PATH="$") + +########### install files ############### +install( FILES okularChm.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_chm.desktop org.kde.mobile.okular_chm.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-chm.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/chm/Messages.sh b/generators/chm/Messages.sh new file mode 100644 index 0000000..f5dfd80 --- /dev/null +++ b/generators/chm/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_chm.pot diff --git a/generators/chm/autotests/chmgeneratortest.cpp b/generators/chm/autotests/chmgeneratortest.cpp new file mode 100644 index 0000000..1830591 --- /dev/null +++ b/generators/chm/autotests/chmgeneratortest.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (C) 2017 by Gilbert Assaf * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "core/document.h" +#include "core/page.h" +#include "core/textpage.h" +#include "settings_core.h" + +class ChmGeneratorTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testDocumentStructure(); + void testDocumentContent(); + void cleanupTestCase(); + +private: + Okular::Document *m_document; +}; + +void ChmGeneratorTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("ChmGeneratorTest")); + m_document = new Okular::Document(nullptr); + const QString testFile = QStringLiteral(KDESRCDIR "autotests/data/test.chm"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); +} + +void ChmGeneratorTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +void ChmGeneratorTest::testDocumentStructure() +{ + unsigned int expectedPageNr = 6; + QCOMPARE(m_document->pages(), expectedPageNr); + QCOMPARE(m_document->metaData(QStringLiteral("DocumentTitle")).toString(), QStringLiteral("okular test chm")); + + const Okular::DocumentSynopsis *docSyn = m_document->documentSynopsis(); + QDomElement heading1 = docSyn->documentElement(); + QCOMPARE(heading1.tagName(), QStringLiteral("Heading 1")); + + QDomElement topic1 = heading1.firstChildElement(); + QCOMPARE(topic1.tagName(), QStringLiteral("Topic 1")); + + QDomElement heading1_1 = topic1.nextSiblingElement(); + QCOMPARE(heading1_1.tagName(), QStringLiteral("Heading 1.1")); + + QDomElement topic1_1 = heading1_1.firstChildElement(); + QCOMPARE(topic1_1.tagName(), QStringLiteral("Topic 1.1")); + + QDomElement heading2 = heading1.nextSiblingElement(); + QCOMPARE(heading2.tagName(), QStringLiteral("Heading 2")); +} + +void ChmGeneratorTest::testDocumentContent() +{ + const Okular::Page *page0 = m_document->page(0); + QCOMPARE(page0->number(), 0); + m_document->requestTextPage(page0->number()); + QVERIFY(page0->hasTextPage()); + QCOMPARE(page0->text(), QStringLiteral("Heading 1This is an example Text.")); + + const Okular::Page *page1 = m_document->page(1); + QCOMPARE(page1->number(), 1); + m_document->requestTextPage(page1->number()); + QVERIFY(page1->hasTextPage()); + QCOMPARE(page1->text(), QStringLiteral("Topic 1This is an example Text.")); + + const Okular::Page *page2 = m_document->page(2); + QCOMPARE(page2->number(), 2); + m_document->requestTextPage(page2->number()); + QVERIFY(page2->hasTextPage()); + QCOMPARE(page2->text(), QStringLiteral("Heading 1.1With html title.")); + + // Test page, who doesn't have an TOC entry, but one in chm index + const Okular::Page *indexPage1 = m_document->page(5); + QCOMPARE(indexPage1->number(), 5); + m_document->requestTextPage(indexPage1->number()); + QVERIFY(indexPage1->hasTextPage()); + QCOMPARE(indexPage1->text(), QStringLiteral("Index 1This is an example Text.")); +} + +QTEST_MAIN(ChmGeneratorTest) +#include "chmgeneratortest.moc" + +/* kate: replace-tabs on; tab-width 4; */ diff --git a/generators/chm/autotests/data/test.chm b/generators/chm/autotests/data/test.chm new file mode 100644 index 0000000000000000000000000000000000000000..fb566369dba8fc6a84638a048c928cebb9588320 GIT binary patch literal 17472 zcmeHvbx>U0wr6)BIKkcBH4xn0t#N`k(73w?C%6Z9_h116f#49_f+x5W+z0M=zjx=! z)SIcPshU4nr*^NsY_D~G=Tx2At53HKNKFz7000<14dBzTz)@9(g$4jn?}6TBUSnuk zNPwIH^38p;{~$m6KNId>4B-Ax4nqBFGW<{e@Vw{~35);5|NfK#sVP63Ku-hVS^4Du z>WMw;9-ru0^-Rz6XC3@gO_uSm-ZPVpp=DnGRnv3qv;A*UR*;gnM0$?;mmbLSB*3vy z$cSr6i>m?ysx5N5(~=)K%r5ynzAZs6Ky5AW?Z>z?if&A`7LYjF~e;!3bgtyy0lzfM=mp5|x!v zR09FmU6O>bSSU3$MVy@MOdv+i5Ld7~#Ma8`xiq5x(xB{UXAgFC_5iLsK%+f-$bmiF z>>N%1Ee!iVDMdk!U@&mfHdg*0x&B>%xRJ9FaGe(!^FKu?7}*2Yr4aD`li^<#sF0$t zSb&X8A-3jh%xugS&NjdZ$p9SWe<`0;k?$@3O~d{Vr;idA2rM$TreJqw3kxe?s7Igz zA`9eM{%es*1XFAlkdd)9nAFaURLsuS8Eot9^yF&-1cZ7ZvpCz?Lrnh87{&D64e@W) zbG`{mGfZCI=Mz)2H!=aUC>q&3f$HQ80PxfP&w4dyJ4YjPFpGkkn4OKiBiP9aY|8S_ zWPm*BZg0l_EpJCV>*rhmOG3K;*8iy>TNzt3JAg49%YW+(ax}7aGP85EVfjb({L}{j z2O(Zul49)KJRGb{JmPQJnAq6FpJt-$TuiL2BCKLOY!W?7s1Kd$kqh>dL`GJzx#elfC{j)a{A5< zvyZq)PyCsXpE@ug3N?kJAZy@r^5-*rrsv+uGk@0o-Dmk<@xT3^`3t=u@Pfb#0xt-> zAn<~~3j!|)yddy`zzYH|2)rQhg24Zu2%!A47XbHnuxIF*;|ji1(|oYHu`lo-a<_``nkD@)6n8{-)cf?Md1n&F2LZI?AsJQ*Ls77hB3xbqv7HzOqyv~%4WPoI{>SpF51Jaj} z)B1!ir)8XKl*f)0D%a%akYepnkCV--3ae@u0{E ztxQbBR1E^&YYzmdIg6B}<(LJ& z00}ZEai)%VjC5>j{4_bAkzjngG~a`>{CPr#$?>*jfz(t}Z=w@#40Mah>6$Bi^JrgT%yS!TA&7@c{0xn6`yS4ts! z_SGUVcT?JCev(&q)^f2JbeU~$`$trQ+yC7(q1ok%P-u4@9432_z><;#B{3BZRB~Sf z^rpq^EK13WR9wHRHGLM@>K`c;i!mk%its`T$gU}b4%V?2$>~wil|G-CX1l?9R({j# z<96wH;!=g0Da?Mg*AH#trE?hJN`3{!%CYJuNU!885}DjmFLvZ9x*i*@ELlIWdH<2` z)YBV!%}VnjKxS?eQL^8@U31oep!n-m2td9oiLFiY9Y z3x&ktImMWUL1~C!J>OxO??)Bo>`;rX#JR> zyVTUyoLY=rJIP}58Hv6veJZN!Mm@N^QXLxBy_1tVXS=_3FyRaC= zLbFqee%q|$q6|W7@aV=DxXO>X@zS??L%-9sSvMVwqCXY3X^`>QBzt3yG;j1LJyw9s zXJ#xYMbg@g`p${VFsdRs!Rktrulo(vdo9gy-|E(e24uq|d5tkn)%MM^b-Skd>LCvo zw+z>3uI*=)%%F285iMBP!*%jxxIu_E3#TLg4g&atK*r}iLF?NslS!R~fN`cxsTjS!Z;r1%N{rzLun!v|p2*LHE%e4Hy zB{lok%(baD70=0UpyiEd^h{-^QGp|Waj71W7Mppbpam22S|2}gjAliHrr&(l?iUF; zpJJPqQX#1YVn_SMpB2yay&0^LXon^b6{OOu5^hvxNIBEazY&Fq{+!kjlI08YH5KzC zVNnj@`rLp!zk~d1;@}%@));}n^<>!ayIu2^IJTR1MO_jS^Ilm=hauMuQpxozVSax> zAaM<&s4fFXNbOxJ)QOdyvdh&~w1)-3qGP9zhPAo5(dj4t^ZA3Vkh<(k8oX-$3u7hZ zKwrMrPOpT$whS!BGd2=4#j7{Kn#&29x>YutF1MP!t8Vpz(;8cs@y1a;wg^+4$OEbl zO%T$%jlA{W6D)~8+BOFihdhG_*fWOa);rdr;y6CnP#}K5CZZ>Xd*7~a*BZdrAYdTX zpp?NoBm2Xc)=7zYyZV4cesVmk_V<y-V`XA!*&bwfha* z2#Xk!cz6htwesi{#WkR2(D8QlF4US!2_w~GoH`fP5$P3@2TOC z|0wx(9yD^rBvCCLw3%LJfOVbXoKSVY{%-0Ur*~sKT3b3Z;>?T*k^a#+uNmNBp!Cy@ zIUhFur|`QOdZ>UDTiBl%O8Y2Emo?NqguOj``>FDcd0;Cm9XD?FqvhC>6wU+=(zf_~ z3mT8s`>;ooDo9P_8{mDxrm;;mQPpCs+5nW`p(e-h0kXDyKxlgg-LB_m`(TPO3qhmK zo?g0KI+$_yZ=}jT28sGyS#ygziP#%Zt&sR<{(;9qi6ZitGY}>CJUI|^e%{T7> z_wD&oG)MJ_(SEda+!0@go~@ND9gA^_USyhQO{*8wX`b;BqH(Px>xg|!to~`!fC|78 z$y}@~&Q^={TQLE<%(h_2S0f<;`odt`E34nfMLMOb$Zzv4&BbaxzKt=w1u#MyEZj-j zB^h!a$mxlks;uTb^-bRvdY-Epf7;}ScJ`7i{xO65c*c4el(nu%mXqZu@|G3utj36I z=P1X~8ybIc;)uiQVCIyj9Y=qEGjev<-Ylk7rK{oI3XM7hnKa60m+d6-UFqm%fwJ5fot-8Xv!K0nxPRq2k>EbT6|}|Z^6Ak>E>5xHxUXN#CXlsN z+p~_uk^Pqyh;4I`eu;5;E_*X3L8tLY+i%78J8siFnOEfsyQzx^R~_AP%}{AGQeQj5 zcLcW-mIC62`zn;am}>Cf)9bEtd68{a@Q4>FT;e&9TK2hJ%*eXIOkO8pwZp)&O6>An zyF7YW-wki{{nVN^zOTDVa_YHt3=^4{Tw6K4$4z-PVp0?uD z@%5D+ye0IP;k=!b1j;T}K}dI?CF$q#^b?fFiKeBi>Vg9Q;k1kSO$FGB94~Ex;}%Zd znX7zcH1T}LB`KWp*1*;=3E|bG$3Q=*78>X=lCONuAx(Sy<_BC{K2rCe@%ISOutOJd z9-B%DSUlCf07onEN7B)$;fs2+JMFwDJ5JM9m56C!(-U8lUWV4K$Q;@1Z66~S` z@>w$=c5NIu>2bL~CO%u;{IEB%oN;igp>dw3b>ebdr9DiS-mQ_C-rj(L|4zV6gs*mG+5a#fUpjWf;n?uQFU zmTvm?=lnNpE8BNbhc@cliY_WyUe!)y6N5|su6rmgKR^rFG6`;Hs;!4g?Zoq>`dJOD z>-G@A3J*`wYZM`v%;eeoSD@3?0}{*DMU71>!pElMP&(O@9};czh!q8L;+J`Q*DIqD z-QG|sz4Lz@C_J++E`RGXE$2xtkS=MkC#1IaQ46l@Qk++YWM?*=RwZM^OMQH#LX7M% z|9S1SSMoiV2GsN=)JpyfP4VZ2qxDFoPb9>JZ0#O~B2!jgcI#hPv4JK^RZ2OVtNwQP zk6!PgJSm!(zMRaQjJHhsq&+6RB`83d%N)Bq5Q3=-+<^WraWid6(4zgY?(SnU>~vAD z(MWIt47$4+7nISp7FlRSVcGl<3Qc|8cLzE27ua-aRj(IGAi`~BdGs*GSpMVp>7klm zX4`26eVXwNsg@#XEd~D=@x!*UuMo+Z;m;t6hz}|QG*xMDg&c^D?#%rsfC{fjl}MvH zZ8p8zxADA};c4uLYA#hsgN#EDwmEBRODf3i>ks6 z8=JJ&CtS!Ts!UFMg>D4K1iDY+g(zx8@r2RSpmzd0;FY0OrNLLnZtxKXh!sfWtZxEi zfW891LncyJYv3cQJ2gVkh{;9P5Lc6E17T?JzM|>}l52`Hbi<)%`AhI#YVuG6SYPjwwvRK zgu-6^aj?Wzcp?_f;}0CI=a^cFMecg;w#-~JopCfG4Gaq}(no38?Ph1=E79*`h~*!C zmtzp)$Raf#8(&Fiubmif!G6LcMOA-IIg0RYm?5h3Ty{Mdi#*_vPP%j#iV6mv(G%C| zvMxs$ow`m3kjTMLW?^LbM>Hr77mg-Yn!PK?A1Qh;6J3;Db-;rLnvEVr9gd2gZ&WA- zFMyYOqXIvI_e!o2otX_)Cm=aKJZQCde~22Riw)Y4Hx)HJ0QFQnXoMhem=;}>6V=Q< z18-V1N5x02EJ!&jBVCOgdftEWjF!yfxBL%!GV>4qr+YzTy}~>VK@U-&sxE3cq8dU= zup=qLhVV4PraIO>%b4x7(J{WPa>cwr@H}HN9Kk9kSqTy}7>{;PSs5;u9W@c0Ln|gs z7BVQRoD`6Q1Qm=&k01hq31mmY1eef4E91cpvMVR%=Aep!$!N<&eL4e;g|$L*`pNZ3 znAn^E;ki%{q^ueVEUaT9;mQ(aGXwKEVp#xGClwXK0(y^)@P&oSYO!<-S=kwt1cCz@j?*hYnS@jhRQX530HH6P&X^fU!0tj>JA;De@9$a@#|m+kzzEE5 zxru*bUfJ2>PSKg~zmClkWNCv%9TRK6*e+uojeK*E2X4(9FZsp?8WFsACWg+B;X4?U z0IKlrlqUx)GC zlhy){4?6tYo_5_Oi_RTGGcKZHh9OfDmO=Jvh4s8#d8-z+Rx>@cUSJbgXR|8{`C)YN zwFCiPK8!nLQdig8bCF5Es@&zMO$Yw#ZPNZ$9hDQvh6(|?q+ebyJjxHBsBh6|86KR1nW;&fw=Ho8- z4x^t1_6DurU>B&~yE4S#_Z&ufZ#2OU9h~G3SdHeFt47W~{JKQHTB|mt$&w9|y1mZt zTbii$QE?naQHK~*`lf3zhe1>wg`^+R3!FNy?{=AGlLDxCx8J{FURp|qMl7~i&ZJYT z3EFjLc1XXVQczo2-+5@w4Gp3KmAJ#>5Xp&;BbuHOw-qGN^oAP+&z7hh$Ghz6v&&M+ z73}n=dKw$3m;a`sS8quro{JG`bMHpC`PoL<9+9k9NlvA4w$8Ssz*u8EC@0r@Eursw z!oY6lajM&c7H0BoqX{3&L8lSFf+6W(7P57ix`rW51N1DUg<8_qP;N3rvwnR~gpU}k zw@EvHE+#zw7@-wC<;%>VpOs{tuEp|zhp8QL_@2?7Kyy1$VICWz;dOP2wA1{6q4*e7 zG67Z}gCZw2nnB&BFH3%HcYjuDF(I0y>_@-ds*acgqZdn|(zVwb^opgoDJW0kj<&(^ zrim@D?g7iLP1D|9@^GNL#@{VnDrbY&#*=9I#`H}b&ww9$tf>Uk@oQqt%=*3zj-p@X z>&8mEq1Xk38}9a)+;Y2cZ1$o zpYQ`}^~<_@^Dy8)f8qG>J=Qu;d>u;yyqIpO;5z+9@Ork#)&)D&Bu~}PJ%JkWceO5K zSH>QgO3bJzmsX5NldJ2s;e>B+wq7curab>6yZ9ug?LFM7V|TbLBSD+*N102Wb#<*K zKjWQ)_p0v|8(Lnqv7bms@3-_v(!5E-*a4~w=xck}N4+BME8Clj_UZLuFOJwy_{t@9txd^ve;dxIM- zN*YAvSsP~K2(ICq+7)Y~E7XsOG+5+g=8+oV4t_=_uHe(J%g<`fmMbu8;A!k>*^vOJ zswPjUrzgvOl~J@BAl`lW9b(;QmNfO)wY#$gd}I6l<$-lly?NmP<#AbwI+KdR2f;b; zV4#k|w5IJsWZAANT#w~sT06ec>NJ~senY&dI*r^p#o=xM!?gU_8_Cc#`J_PyEEb0C z=CB@46z>g9^}KVkjUgQlv_72_7s z=8`JIEJ~t$5NRCl!(Q-RPHHK*xoVc#QKk@VXkKydqF*pX8vQvEq!RsL)E%hyi#~Z; z%Egz@tjS%olK(&ewm?$5jG3oTv@$pmG;@f|xXThFqfx0ixr_dj<5T4jQ?hc<0UXcw z8*SN6d6gAkzLF1hpxl+=#gFm99575i?uSwuNzEPtM=SlMA)Tn9ag%euP`-JiKSXK> zYv*a(FYI%6h&QH&N7TFA-w=H*M*I0*Av&{)rZFjTdWiq95SQ7Y^j*CUBYlgJI$hbD z^s)^-*P_qTKL;&p4fC;6uE=b3lwmMK6(hZpiG$+Gn#huR(^`WKv_7nZ#Dk2@hcCc-d{)kF$5~ZnStL^CIc{81@IJOkT%;&h#QiD&EgVOQU5c39? z_b!D}odv!6IiYf?`}a%wVR#2p%+Ekh+@Te|aNA;%`~|M?hVx%#c@<6M4fbdb^opTf znaFAm@wEsB`lW|D6d_bSh_jX)<)Vjd7r)*&Cuu}ExK_cq;Z$VuB+;0h6iZuO><)`M z90#*XYp=(c@2I675W$NC7EryfqH_|#e@B`wz#S(HC2tQ-4+dH!X)}} zsZ~=f4n(Qyu2aEwQ|f@2gUpZY_k}D(f=@l^p$sb!_Jm#)$K?}lW>&-Yrk&`YpdQ}? zja|nsISwiN;2l=Y*ZU!32^?4VH$8qTSviIHj0-4NM(DO3(;zDKY4_a&OO^@61E$`6B)4&7lG)`LLS0$R-LsI$5q8`FE>5j z6G`yytGqI$AQ(+(OAq%%IGv=7UTruT?nXT*^$kT*>9JgiwECwFuh!@r7ai+&^e4Z5^6Ig`dkpYNyeeX;puDD|V_ zEmW${NUc7Dhf0K1J#Cf7TVBh&nwD}zc-0IV65e`cj(u9&G2nEZHZ}eqII_qIvejC} zSQ|$;fgif^>H?X1eVvDPd%E4rqQ%4cge5gH4do&jTV`MB``+e8T5uX9ef92l9gdo) z+@JZP5!|sO$IXmSH{1R_!%l(|ge7MzxLkj&@#?49=b%T%V93z-#F?~ObQvW;;Z%eD z=#IUiLj0p-a6gS;BIxXGQMuMkpC(JAzWepDUR(LC|9cdrWv<-{7PFS~a8wEqLuU9! zhz?pY2QN@X+js+C(!Mt03LdPj{+1`ERbi&XeS?zd$O9tY-i&t1b(qhD=a*og;3tpG?ybxo=>KbUo*AbMrSYgY4v|$%<#!WcFYrpat@~#&uujck0u-B4=!x|px zta@!oSfG)4$bXx~rhG#wUN$$Mbree_Do)gr$VvSS9!DboJ z61^`z7JO6-)=>XsBJais3J}MEYxjPubfV6Aj^SW(2(D$p4GO=~5x#dX(2lg?w|d9`KeqSVYqBNPPwu+ z_&-fam_W4=VAT0Z*x1i;$ zehuJsB0IbO3iBDwUWHxkL5Q8KpyKNY^Ov1_PJ6@h5WV&0fLE?-flAp%pXFnhYgMF) zz)Sdac(I%j8R&ob;1sq!m@HYu9)mOS-@0$&L%(*peV1TwM_`{|P3dEF=J&Cd&&1@G zNdyy_eBkMeHyG-GnTKoOe!mcv@R*DrqPT4aBHW|yW@T!wPs|&)1$1j&5q8sJs}f2a zD>UtI7N&i=u3Doph84&S=O6uD*gtyyN)G!1MEFw0SXWQ1%W4<;jo6j-6LDK`zQw#? zq_v=@Q=(1#AjvNmZs|KKoLa^`x4?ew+J3~sQM=GEnnG$+f^-!Ic3g9yiLlrk7`YTo z#ff_h#9x23>e%ut>$I`~_4`3Q6H@2PF@_Q%)SZJAs-BmSEkkS{S#Q=kmbS(1dl;15 z;TZW(%k=cIf~Om-x5>Zqf^KOFnUOdZ)9x;|7*2lC(5`G!pP@{cou{DhIk$V^k~=tD1mA?_H5EauO=o90v^%`Z6aAs*6tp?U+cra`*gkq}Fm-)bSP7OrvnH8D zvN^)Wd?#eEoZQcWkBvhZjAI`e&m7PpuD@d$SaWuaAY#du^vGC*b!%HCEYjT*l1X*J zpce|njad8vNU$MRK0K_z?tTTa`;s;>bqOm40Skbo>bgF zn|u>xBcWF}U;K{>N_~q`SS#6`(Xhw@v$OT>I+>tMUI$IUs0UEu4p464?*aPdBtA5z z^vw$!<9ia@Q2~$(=Jek3t|7=235K5}93YV9We>vMy;p|G^Q$`f;md@B8WL&n<^ey^ zV#S`J*43tE%I~!4*TvulUV_iLj0(UNHCuI9CNxQel{Ae1aX=G!c>#9*0X=12#7F*^ z5gjL_bM$xp{SWMKlBp8gk2S;A`Die(aBMeT`h@XTtrJNsgkRT{F&8VcTX6M!jaSCT z1$-qjAVg#5V&fWu2S%r><{XcVvkW`OeFgyo{V+7yf?kM5RLWD%`U~di`T^1L*RazWIJv3U zsCuJYWny4L8^1LE>EQr*jTSBt+wTOyegnS4lY`(lAWq(iQpLnjrPon}&{6m_(3wNL zr|`jIF#4*2m_7`OL#W6SjS_yX@VU(2guVvOCl??}8TM=#pLOBvkh4}2Tfb&znYKiR zmB>{Qn)UC&+0vZA+Yh+y+RCtpr%||vxVIMMeLE^d#ay(5IweHCi~@M8J%l^_)sY%? zS_@L-4#MDG!%$4PZts$UX1G}@kw3TbOSx)=dk;q?_MUh4myAjkxn?)3DYOm=bN(jB zGVuTkF?}PYWC;=vz?}(#?L@Erh$Zp>Z^ws z!|R6inBOZ$K^u<`wJYr`389Z$Ywdn~NM{cKDZiUPcIkA*)lzlv*?-mbT>F2V9sB+3 cKRDo?UQwZa8h`)d<&Ny1@2vR$lmC * + * Copyright (C) 2008 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "generator_chm.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(CHMGenerator, "libokularGenerator_chmlib.json") + +static QString absolutePath(const QString &baseUrl, const QString &path) +{ + QString absPath; + if (path.startsWith(QLatin1Char('/'))) { + // already absolute + absPath = path; + } else { + QUrl url = QUrl::fromLocalFile(baseUrl).adjusted(QUrl::RemoveFilename); + url.setPath(url.path() + path); + absPath = url.toLocalFile(); + } + return absPath; +} + +CHMGenerator::CHMGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) +{ + setFeature(TextExtraction); + + m_syncGen = nullptr; + m_file = nullptr; + m_request = nullptr; +} + +CHMGenerator::~CHMGenerator() +{ + delete m_syncGen; +} + +bool CHMGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + m_file = EBook::loadFile(fileName); + if (!m_file) { + return false; + } + m_fileName = fileName; + QList topics; + m_file->getTableOfContents(topics); + + // fill m_docSyn + QMap lastIndentElement; + QMap tmpPageList; + int pageNum = 0; + + for (const EBookTocEntry &e : qAsConst(topics)) { + QDomElement item = m_docSyn.createElement(e.name); + if (!e.url.isEmpty()) { + QString url = e.url.toString(); + item.setAttribute(QStringLiteral("ViewportName"), url); + if (!tmpPageList.contains(url)) { // add a page only once + tmpPageList.insert(url, pageNum); + pageNum++; + } + } + item.setAttribute(QStringLiteral("Icon"), e.iconid); + if (e.indent == 0) + m_docSyn.appendChild(item); + else + lastIndentElement[e.indent - 1].appendChild(item); + lastIndentElement[e.indent] = item; + } + + // fill m_urlPage and m_pageUrl + QList pageList; + m_file->enumerateFiles(pageList); + const QUrl home = m_file->homeUrl(); + if (home.path() != QLatin1String("/")) + pageList.prepend(home); + m_pageUrl.resize(pageNum); + + for (const QUrl &qurl : qAsConst(pageList)) { + QString url = qurl.toString(); + const QString urlLower = url.toLower(); + if (!urlLower.endsWith(QLatin1String(".html")) && !urlLower.endsWith(QLatin1String(".htm"))) + continue; + + int pos = url.indexOf(QLatin1Char(('#'))); + // insert the url into the maps, but insert always the variant without the #ref part + QString tmpUrl = pos == -1 ? url : url.left(pos); + + // url already there, abort insertion + if (m_urlPage.contains(tmpUrl)) + continue; + + int foundPage = tmpPageList.value(tmpUrl, -1); + if (foundPage != -1) { + m_urlPage.insert(tmpUrl, foundPage); + m_pageUrl[foundPage] = tmpUrl; + } else { + // add pages not present in toc + m_urlPage.insert(tmpUrl, pageNum); + m_pageUrl.append(tmpUrl); + pageNum++; + } + } + + pagesVector.resize(m_pageUrl.count()); + m_textpageAddedList.fill(false, pagesVector.count()); + m_rectsGenerated.fill(false, pagesVector.count()); + + if (!m_syncGen) { + m_syncGen = new KHTMLPart(); + } + disconnect(m_syncGen, nullptr, this, nullptr); + + for (int i = 0; i < m_pageUrl.count(); ++i) { + preparePageForSyncOperation(m_pageUrl.at(i)); + pagesVector[i] = new Okular::Page(i, m_syncGen->view()->contentsWidth(), m_syncGen->view()->contentsHeight(), Okular::Rotation0); + } + + connect(m_syncGen, QOverload<>::of(&KHTMLPart::completed), this, &CHMGenerator::slotCompleted); + connect(m_syncGen, &KParts::ReadOnlyPart::canceled, this, &CHMGenerator::slotCompleted); + + return true; +} + +bool CHMGenerator::doCloseDocument() +{ + // delete the document information of the old document + delete m_file; + m_file = nullptr; + m_textpageAddedList.clear(); + m_rectsGenerated.clear(); + m_urlPage.clear(); + m_pageUrl.clear(); + m_docSyn.clear(); + if (m_syncGen) { + m_syncGen->closeUrl(); + } + + return true; +} + +void CHMGenerator::preparePageForSyncOperation(const QString &url) +{ + QString pAddress = QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + m_file->urlToPath(QUrl(url)); + m_chmUrl = url; + + m_syncGen->openUrl(QUrl(pAddress)); + m_syncGen->view()->layout(); + + QEventLoop loop; + connect(m_syncGen, QOverload<>::of(&KHTMLPart::completed), &loop, &QEventLoop::quit); + connect(m_syncGen, &KParts::ReadOnlyPart::canceled, &loop, &QEventLoop::quit); + // discard any user input, otherwise it breaks the "synchronicity" of this + // function + loop.exec(QEventLoop::ExcludeUserInputEvents); +} + +void CHMGenerator::slotCompleted() +{ + if (!m_request) + return; + + QImage image(m_request->width(), m_request->height(), QImage::Format_ARGB32); + image.fill(Qt::white); + + QPainter p(&image); + QRect r(0, 0, m_request->width(), m_request->height()); + + bool moreToPaint; + m_syncGen->paint(&p, r, 0, &moreToPaint); + + p.end(); + + if (!m_textpageAddedList.at(m_request->pageNumber())) { + additionalRequestData(); + m_textpageAddedList[m_request->pageNumber()] = true; + } + + m_syncGen->closeUrl(); + m_chmUrl = QString(); + + userMutex()->unlock(); + + Okular::PixmapRequest *req = m_request; + m_request = nullptr; + + if (!req->page()->isBoundingBoxKnown()) + updatePageBoundingBox(req->page()->number(), Okular::Utils::imageBoundingBox(&image)); + req->page()->setPixmap(req->observer(), new QPixmap(QPixmap::fromImage(image))); + signalPixmapRequestDone(req); +} + +Okular::DocumentInfo CHMGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + if (keys.contains(Okular::DocumentInfo::MimeType)) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("application/x-chm")); + if (keys.contains(Okular::DocumentInfo::Title)) + docInfo.set(Okular::DocumentInfo::Title, m_file->title()); + return docInfo; +} + +const Okular::DocumentSynopsis *CHMGenerator::generateDocumentSynopsis() +{ + return &m_docSyn; +} + +bool CHMGenerator::canGeneratePixmap() const +{ + bool isLocked = true; + if (userMutex()->tryLock()) { + userMutex()->unlock(); + isLocked = false; + } + + return !isLocked; +} + +void CHMGenerator::generatePixmap(Okular::PixmapRequest *request) +{ + int requestWidth = request->width(); + int requestHeight = request->height(); + + userMutex()->lock(); + QString url = m_pageUrl[request->pageNumber()]; + + QString pAddress = QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + m_file->urlToPath(QUrl(url)); + m_chmUrl = url; + m_syncGen->view()->resizeContents(requestWidth, requestHeight); + m_request = request; + // will emit openURL without problems + m_syncGen->openUrl(QUrl(pAddress)); +} + +void CHMGenerator::recursiveExploreNodes(DOM::Node node, Okular::TextPage *tp) +{ + if (node.nodeType() == DOM::Node::TEXT_NODE && !node.getRect().isNull()) { + QString nodeText = node.nodeValue().string(); + QRect r = node.getRect(); + int vWidth = m_syncGen->view()->width(); + int vHeight = m_syncGen->view()->height(); + Okular::NormalizedRect *nodeNormRect; +#define NOEXP +#ifndef NOEXP + int x, y, height; + int x_next, y_next, height_next; + int nodeTextLength = nodeText.length(); + if (nodeTextLength == 1) { + nodeNormRect = new Okular::NormalizedRect(r, vWidth, vHeight); + tp->append(nodeText, nodeNormRect, nodeNormRect->bottom, 0, (nodeText == "\n")); + } else { + for (int i = 0; i < nodeTextLength; i++) { + node.getCursor(i, x, y, height); + if (i == 0) + // i is 0, use left rect boundary + { + // if (nodeType[i+1] + node.getCursor(i + 1, x_next, y_next, height_next); + nodeNormRect = new Okular::NormalizedRect(QRect(x, y, x_next - x - 1, height), vWidth, vHeight); + } else if (i < nodeTextLength - 1) + // i is between zero and the last element + { + node.getCursor(i + 1, x_next, y_next, height_next); + nodeNormRect = new Okular::NormalizedRect(QRect(x, y, x_next - x - 1, height), vWidth, vHeight); + } else + // the last element use right rect boundary + { + node.getCursor(i - 1, x_next, y_next, height_next); + } + } +#else + nodeNormRect = new Okular::NormalizedRect(r, vWidth, vHeight); + tp->append(nodeText, nodeNormRect /*,0*/); +#endif + } + DOM::Node child = node.firstChild(); + while (!child.isNull()) { + recursiveExploreNodes(child, tp); + child = child.nextSibling(); + } + } + + void CHMGenerator::additionalRequestData() + { + Okular::Page *page = m_request->page(); + const bool genObjectRects = !m_rectsGenerated.at(m_request->page()->number()); + const bool genTextPage = !m_request->page()->hasTextPage() && genObjectRects; + + if (genObjectRects || genTextPage) { + DOM::HTMLDocument domDoc = m_syncGen->htmlDocument(); + // only generate object info when generating a full page not a thumbnail + if (genObjectRects) { + QLinkedList objRects; + int xScale = m_syncGen->view()->width(); + int yScale = m_syncGen->view()->height(); + // getting links + DOM::HTMLCollection coll = domDoc.links(); + DOM::Node n; + QRect r; + if (!coll.isNull()) { + int size = coll.length(); + for (int i = 0; i < size; i++) { + n = coll.item(i); + if (!n.isNull()) { + QString url = n.attributes().getNamedItem("href").nodeValue().string(); + r = n.getRect(); + // there is no way for us to support javascript properly + if (url.startsWith(QLatin1String("JavaScript:")), Qt::CaseInsensitive) + continue; + else if (url.contains(QStringLiteral(":"))) { + objRects.push_back(new Okular::ObjectRect(Okular::NormalizedRect(r, xScale, yScale), false, Okular::ObjectRect::Action, new Okular::BrowseAction(QUrl(url)))); + } else { + Okular::DocumentViewport viewport(metaData(QStringLiteral("NamedViewport"), absolutePath(m_chmUrl, url)).toString()); + objRects.push_back(new Okular::ObjectRect(Okular::NormalizedRect(r, xScale, yScale), false, Okular::ObjectRect::Action, new Okular::GotoAction(QString(), viewport))); + } + } + } + } + + // getting images + coll = domDoc.images(); + if (!coll.isNull()) { + int size = coll.length(); + for (int i = 0; i < size; i++) { + n = coll.item(i); + if (!n.isNull()) { + objRects.push_back(new Okular::ObjectRect(Okular::NormalizedRect(n.getRect(), xScale, yScale), false, Okular::ObjectRect::Image, nullptr)); + } + } + } + m_request->page()->setObjectRects(objRects); + m_rectsGenerated[m_request->page()->number()] = true; + } + + if (genTextPage) { + Okular::TextPage *tp = new Okular::TextPage(); + recursiveExploreNodes(domDoc, tp); + page->setTextPage(tp); + } + } + } + + Okular::TextPage *CHMGenerator::textPage(Okular::TextRequest * request) + { + userMutex()->lock(); + + const Okular::Page *page = request->page(); + m_syncGen->view()->resize(page->width(), page->height()); + + preparePageForSyncOperation(m_pageUrl[page->number()]); + Okular::TextPage *tp = new Okular::TextPage(); + recursiveExploreNodes(m_syncGen->htmlDocument(), tp); + userMutex()->unlock(); + return tp; + } + + QVariant CHMGenerator::metaData(const QString &key, const QVariant &option) const + { + if (key == QLatin1String("NamedViewport") && !option.toString().isEmpty()) { + const int pos = option.toString().indexOf(QLatin1Char('#')); + QString tmpUrl = pos == -1 ? option.toString() : option.toString().left(pos); + Okular::DocumentViewport viewport; + QMap::const_iterator it = m_urlPage.find(tmpUrl); + if (it != m_urlPage.end()) { + viewport.pageNumber = it.value(); + return viewport.toString(); + } + + } else if (key == QLatin1String("DocumentTitle")) { + return m_file->title(); + } + return QVariant(); + } + + /* kate: replace-tabs on; tab-width 4; */ + +#include "generator_chm.moc" diff --git a/generators/chm/generator_chm.h b/generators/chm/generator_chm.h new file mode 100644 index 0000000..c62508d --- /dev/null +++ b/generators/chm/generator_chm.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005 by Piotr Szymański * + * Copyright (C) 2008 by Albert Astals Cid * + * * + * 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_GENERATOR_CHM_H_ +#define _OKULAR_GENERATOR_CHM_H_ + +#include +#include + +#include "lib/ebook_chm.h" + +#include + +class KHTMLPart; + +namespace Okular +{ +class TextPage; +} + +namespace DOM +{ +class Node; +} + +class CHMGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + CHMGenerator(QObject *parent, const QVariantList &args); + ~CHMGenerator() override; + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + + bool canGeneratePixmap() const override; + void generatePixmap(Okular::PixmapRequest *request) override; + + QVariant metaData(const QString &key, const QVariant &option) const override; + +public Q_SLOTS: + void slotCompleted(); + +protected: + bool doCloseDocument() override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + +private: + void additionalRequestData(); + void recursiveExploreNodes(DOM::Node node, Okular::TextPage *tp); + void preparePageForSyncOperation(const QString &url); + QMap m_urlPage; + QVector m_pageUrl; + Okular::DocumentSynopsis m_docSyn; + EBook *m_file; + KHTMLPart *m_syncGen; + QString m_fileName; + QString m_chmUrl; + Okular::PixmapRequest *m_request; + QBitArray m_textpageAddedList; + QBitArray m_rectsGenerated; +}; + +#endif diff --git a/generators/chm/kio-msits/CMakeLists.txt b/generators/chm/kio-msits/CMakeLists.txt new file mode 100644 index 0000000..36e6706 --- /dev/null +++ b/generators/chm/kio-msits/CMakeLists.txt @@ -0,0 +1,23 @@ +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../lib + ${CHM_INCLUDE_DIR} +) + + +########### next target ############### + +set(kio_msits_PART_SRCS msits.cpp kio_mits_debug.cpp) + + +add_library(kio_msits MODULE ${kio_msits_PART_SRCS}) + +target_link_libraries(kio_msits KF5::KIOCore Qt5::Core ${CHM_LIBRARY} Qt5::Network) + +install(TARGETS kio_msits DESTINATION ${KDE_INSTALL_PLUGINDIR} ) + + +########### install files ############### + +install( FILES ms-its.protocol DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) + diff --git a/generators/chm/kio-msits/kio_mits_debug.cpp b/generators/chm/kio-msits/kio_mits_debug.cpp new file mode 100644 index 0000000..826073d --- /dev/null +++ b/generators/chm/kio-msits/kio_mits_debug.cpp @@ -0,0 +1,21 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kio_mits_debug.h" +Q_LOGGING_CATEGORY(KIO_MITS_LOG, "org.kde.kio.msits", QtWarningMsg) diff --git a/generators/chm/kio-msits/kio_mits_debug.h b/generators/chm/kio-msits/kio_mits_debug.h new file mode 100644 index 0000000..54e261d --- /dev/null +++ b/generators/chm/kio-msits/kio_mits_debug.h @@ -0,0 +1,26 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIO_MITS_DEBUG_H +#define KIO_MITS_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(KIO_MITS_LOG) + +#endif diff --git a/generators/chm/kio-msits/ms-its.protocol b/generators/chm/kio-msits/ms-its.protocol new file mode 100644 index 0000000..8d87306 --- /dev/null +++ b/generators/chm/kio-msits/ms-its.protocol @@ -0,0 +1,70 @@ +[Protocol] +exec=kio_msits +protocol=ms-its +input=none +output=filesystem +reading=true +listing=Name,Type,Size +defaultMimetype=text/html +Description=A kioslave for displaying WinHelp files +Description[ar]=خاصية كِييُوسليْف لعرض ملفات WinHelp +Description[az]=WinHelp fayllarının göstərilməsi üçün kioslave +Description[bg]=kioslave за показване на помощни файлове за Windows +Description[bs]=U/I alat za prikaz WinHelp datoteke +Description[ca]=Un kioslave per a visualitzar els fitxers de WinHelp +Description[ca@valencia]=Un kioslave per a visualitzar els fitxers de WinHelp +Description[cs]=Kioslave pro zobrazení souborů WinHelp +Description[da]=En kioslave til visning af WinHelp-filer +Description[de]=Ein-/Ausgabemodul zur Anzeige von Windows-Hilfe-Dateien +Description[el]=Ένα kioslave για την εμφάνιση αρχείων WinHelp +Description[en_GB]=A kioslave for displaying WinHelp files +Description[eo]=Kio-sklavo por montri la WinHelp dosierojn +Description[es]=Un «kioslave» para mostrar archivos WinHelp +Description[et]=KIO-moodul WinHelp-failide näitamiseks +Description[eu]=WinHelp fitxategiak bistaratzeko kioslave bat +Description[fi]=WinHelp-tiedostoja näyttävä kioslave +Description[fr]=Module d'entrées / sorties pour l'affichage des fichiers d'aide « Win Help » +Description[ga]=Sclábhaí KIO a thaispeánann comhaid WinHelp +Description[gl]=Un kioslave para mostrar ficheiros WinHelp +Description[hi]=विन-हेल्प फ़ाइलों को प्रदर्शित करने के लिए एक केआईओस्लेव +Description[hne]=विन-हेल्प फाइल मन ल प्रदर्सित करे बर एक केआईओस्लेव +Description[hr]=kioslave za prikaz datoteka oblika WinHelp +Description[hu]=KDE-protokoll Windows súgófájlok megtekintéséhez +Description[ia]=Un kioslave pro monstrar files de WinHelp +Description[is]=Kioslave tilað sýna WinHelp skrár +Description[it]=Un kioslave per visualizzare i file della guida di windows +Description[ja]=WinHelp ファイルを表示するための kioslave +Description[kk]=WinHelp файлдарын оқитын kioslave +Description[km]=kioslave សម្រាប់​បង្ហាញ​ឯកសារ WinHelp +Description[ko]=WinHelp 파일을 표시하는 KIO 슬레이브 +Description[ku]=Kioslave ji bo nîşandana pelên WinHelp +Description[lt]=Pagalbinė programa WinHelp failų atvaizdavimui +Description[lv]=KIO apstrādātājs WinHelp failu attēloÅ¡anai +Description[mr]=WinHelp फाईल्स दर्शविण्याकरिता किओस्लेव्ह +Description[nb]=En kioslave som viser WinHelp-filer +Description[nds]=En In-/Utgaavmoduul för't Wiesen vun "WinHelp"-Dateien +Description[ne]=विनहेल्प फाइल प्रदर्शन गर्नका लागि कियोस्लाभ +Description[nl]=Een kioslave voor het weergeven van WinHelp-bestanden +Description[nn]=Ein kioslave for vising av WinHelp-filer +Description[pa]=WinHelp ਫਾਇਲਾਂ ਵੇਖਾਉਣ ਲਈ kioslave +Description[pl]=Moduł wyświetlający pliki WinHelp +Description[pt]=Um 'kioslave' para mostrar ficheiros do WinHelp +Description[pt_BR]=Um kioslave para mostrar arquivos WinHelp +Description[ro]=Sclav KIO pentru afișarea fișierelor WinHelp +Description[ru]=Библиотека просмотра файлов WinHelp +Description[sk]=Kioslave pre zobrazenie WinHelp súborov +Description[sl]=KIOSlave za prikaz datotek s pomočjo za Windows +Description[sq]=Një kioslave për të shfaqur skedarët WinHelp +Description[sr]=У/И захват за приказ винхелп фајлова +Description[sr@ijekavian]=У/И захват за приказ винхелп фајлова +Description[sr@ijekavianlatin]=U/I zahvat za prikaz WinHelp fajlova +Description[sr@latin]=U/I zahvat za prikaz WinHelp fajlova +Description[sv]=En I/O-slav för att visa WinHelp-filer +Description[th]=ส่วนเสริม kioslave สำหรับแสดงแฟ้ม WinHelp +Description[tr]=WinHelp dosyalarını göstermek için bir kioslave +Description[uk]=Підлеглий засіб введення-виведення для перегляду файлів WinHelp +Description[vi]=Dịch vụ trợ giúp đọc tệp CHM cá»§a Windows +Description[x-test]=xxA kioslave for displaying WinHelp filesxx +Description[zh_CN]=用以显示 WinHelp 文件的 kioslave +Description[zh_TW]=顯示 WinHelp 檔的 kioslave +Icon=help diff --git a/generators/chm/kio-msits/msits.cpp b/generators/chm/kio-msits/msits.cpp new file mode 100644 index 0000000..dde8ff4 --- /dev/null +++ b/generators/chm/kio-msits/msits.cpp @@ -0,0 +1,287 @@ +/* This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include "kio_mits_debug.h" +#include +#include +#include + +#include +#include +#include +#include + +#include "libchmurlfactory.h" +#include "msits.h" + +using namespace KIO; + +extern "C" { +int Q_DECL_EXPORT kdemain(int argc, char **argv) +{ + qCDebug(KIO_MITS_LOG) << "*** kio_msits Init"; + + QCoreApplication app(argc, argv); + app.setApplicationName(QStringLiteral("kio_msits")); + + if (argc != 4) { + qCDebug(KIO_MITS_LOG) << "Usage: kio_msits protocol domain-socket1 domain-socket2"; + exit(-1); + } + + ProtocolMSITS slave(argv[2], argv[3]); + slave.dispatchLoop(); + + qCDebug(KIO_MITS_LOG) << "*** kio_msits Done"; + return 0; +} +} + +ProtocolMSITS::ProtocolMSITS(const QByteArray &pool_socket, const QByteArray &app_socket) + : SlaveBase("kio_msits", pool_socket, app_socket) +{ + m_chmFile = nullptr; +} + +ProtocolMSITS::~ProtocolMSITS() +{ + if (!m_chmFile) + return; + + chm_close(m_chmFile); + m_chmFile = nullptr; +} + +// A simple stat() wrapper +static bool isDirectory(const QString &filename) +{ + return filename.endsWith(QLatin1Char('/')); +} + +void ProtocolMSITS::get(const QUrl &url) +{ + QString htmdata, fileName; + chmUnitInfo ui; + QByteArray buf; + + qCDebug(KIO_MITS_LOG) << "kio_msits::get() " << url.path(); + + if (!parseLoadAndLookup(url, fileName)) + return; // error() has been called by parseLoadAndLookup + + qCDebug(KIO_MITS_LOG) << "kio_msits::get: parseLoadAndLookup returned " << fileName; + + if (LCHMUrlFactory::handleFileType(url.path(), htmdata)) { + buf = htmdata.toUtf8(); + qCDebug(KIO_MITS_LOG) << "Using special handling for image pages: " << htmdata; + } else { + if (isDirectory(fileName)) { + error(KIO::ERR_IS_DIRECTORY, url.toString()); + return; + } + + if (!ResolveObject(fileName, &ui)) { + qCDebug(KIO_MITS_LOG) << "kio_msits::get: could not resolve filename " << fileName; + error(KIO::ERR_DOES_NOT_EXIST, url.toString()); + return; + } + + buf.resize(ui.length); + + if (RetrieveObject(&ui, (unsigned char *)buf.data(), 0, ui.length) == 0) { + qCDebug(KIO_MITS_LOG) << "kio_msits::get: could not retrieve filename " << fileName; + error(KIO::ERR_NO_CONTENT, url.toString()); + return; + } + } + + totalSize(buf.size()); + + QMimeDatabase db; + QMimeType result = db.mimeTypeForFileNameAndData(fileName, buf); + qCDebug(KIO_MITS_LOG) << "Emitting mimetype " << result.name(); + + mimeType(result.name()); + + data(buf); + processedSize(buf.size()); + + finished(); +} + +bool ProtocolMSITS::parseLoadAndLookup(const QUrl &url, QString &abspath) +{ + qCDebug(KIO_MITS_LOG) << "ProtocolMSITS::parseLoadAndLookup (const KUrl&) " << url.path(); + + int pos = url.path().indexOf(QStringLiteral("::")); + + if (pos == -1) { + error(KIO::ERR_MALFORMED_URL, url.toString()); + return false; + } + + QString filename = url.path().left(pos); + abspath = url.path().mid(pos + 2); // skip :: + + // Some buggy apps add ms-its:/ to the path as well + if (abspath.startsWith(QLatin1String("ms-its:"))) + abspath = abspath.mid(7); + + qCDebug(KIO_MITS_LOG) << "ProtocolMSITS::parseLoadAndLookup: filename " << filename << ", path " << abspath; + + if (filename.isEmpty()) { + error(KIO::ERR_MALFORMED_URL, url.toString()); + return false; + } + + // If the file has been already loaded, nothing to do. + if (m_chmFile && filename == m_openedFile) + return true; + + qCDebug(KIO_MITS_LOG) << "Opening a new CHM file " << QFile::encodeName(QDir::toNativeSeparators(filename)); + + // First try to open a temporary file + chmFile *tmpchm; + + if ((tmpchm = chm_open(QFile::encodeName(QDir::toNativeSeparators(filename)).constData())) == nullptr) { + error(KIO::ERR_COULD_NOT_READ, url.toString()); + return false; + } + + // Replace an existing file by a new one + if (m_chmFile) + chm_close(m_chmFile); + + m_chmFile = tmpchm; + m_openedFile = filename; + + qCDebug(KIO_MITS_LOG) << "A CHM file " << filename << " has beed opened successfully"; + return true; +} + +/* + * Shamelessly stolen from a KDE KIO tutorial + */ +static void app_entry(UDSEntry &e, unsigned int uds, const QString &str) +{ + e.fastInsert(uds, str); +} + +// appends an int with the UDS-ID uds +static void app_entry(UDSEntry &e, unsigned int uds, long l) +{ + e.fastInsert(uds, l); +} + +// internal function +// fills a directory item with its name and size +static void app_dir(UDSEntry &e, const QString &name) +{ + e.clear(); + app_entry(e, KIO::UDSEntry::UDS_NAME, name); + app_entry(e, KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); + app_entry(e, KIO::UDSEntry::UDS_SIZE, 1); +} + +// internal function +// fills a file item with its name and size +static void app_file(UDSEntry &e, const QString &name, size_t size) +{ + e.clear(); + app_entry(e, KIO::UDSEntry::UDS_NAME, name); + app_entry(e, KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); + app_entry(e, KIO::UDSEntry::UDS_SIZE, size); +} + +void ProtocolMSITS::stat(const QUrl &url) +{ + QString fileName; + chmUnitInfo ui; + + qCDebug(KIO_MITS_LOG) << "kio_msits::stat (const KUrl& url) " << url.path(); + + if (!parseLoadAndLookup(url, fileName)) + return; // error() has been called by parseLoadAndLookup + + if (!ResolveObject(fileName, &ui)) { + error(KIO::ERR_DOES_NOT_EXIST, url.toString()); + return; + } + + qCDebug(KIO_MITS_LOG) << "kio_msits::stat: adding an entry for " << fileName; + UDSEntry entry; + + if (isDirectory(fileName)) + app_dir(entry, fileName); + else + app_file(entry, fileName, ui.length); + + statEntry(entry); + + finished(); +} + +// A local CHMLIB enumerator +static int chmlib_enumerator(struct chmFile *, struct chmUnitInfo *ui, void *context) +{ + ((QVector *)context)->push_back(QString::fromLocal8Bit(ui->path)); + return CHM_ENUMERATOR_CONTINUE; +} + +void ProtocolMSITS::listDir(const QUrl &url) +{ + QString filepath; + + qCDebug(KIO_MITS_LOG) << "kio_msits::listDir (const KUrl& url) " << url.path(); + + if (!parseLoadAndLookup(url, filepath)) + return; // error() has been called by parseLoadAndLookup + + filepath += QLatin1Char('/'); + + if (!isDirectory(filepath)) { + error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path()); + return; + } + + qCDebug(KIO_MITS_LOG) << "kio_msits::listDir: enumerating directory " << filepath; + + QVector listing; + + if (chm_enumerate_dir(m_chmFile, filepath.toLocal8Bit().constData(), CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES | CHM_ENUMERATE_DIRS, chmlib_enumerator, &listing) != 1) { + error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path()); + return; + } + + UDSEntry entry; + int striplength = filepath.length(); + + for (const QString &iListing : qAsConst(listing)) { + // Strip the directory name + const QString ename = iListing.mid(striplength); + + if (isDirectory(ename)) + app_dir(entry, ename); + else + app_file(entry, ename, 0); + } + + finished(); +} diff --git a/generators/chm/kio-msits/msits.h b/generators/chm/kio-msits/msits.h new file mode 100644 index 0000000..277530f --- /dev/null +++ b/generators/chm/kio-msits/msits.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005 by Georgy Yunaev * + * tim@krasnogorsk.ru * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef MSITS_H +#define MSITS_H + +#include +#include + +#include +#include + +#include "chm_lib.h" + +class ProtocolMSITS : public KIO::SlaveBase +{ +public: + ProtocolMSITS(const QByteArray &, const QByteArray &); + ~ProtocolMSITS() override; + + ProtocolMSITS(const ProtocolMSITS &) = delete; + ProtocolMSITS &operator=(const ProtocolMSITS &) = delete; + + void get(const QUrl &) override; + void listDir(const QUrl &url) override; + void stat(const QUrl &url) override; + +private: + // This function does next thing: + // - parses the URL to get a file name and URL inside the file; + // - loads a new CHM file, if needed; + // - returns the parsed URL inside the file; + bool parseLoadAndLookup(const QUrl &, QString &abspath); + + // Resolve an object inside a CHM file + inline bool ResolveObject(const QString &fileName, chmUnitInfo *ui) + { + return m_chmFile != nullptr && ::chm_resolve_object(m_chmFile, fileName.toUtf8().constData(), ui) == CHM_RESOLVE_SUCCESS; + } + + // Retrieve an object from the CHM file + inline size_t RetrieveObject(chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) + { + return ::chm_retrieve_object(m_chmFile, ui, buffer, fileOffset, bufferSize); + } + + // An opened file name, if presend + QString m_openedFile; + + // a CHM structure file pointer (from chmlib) + chmFile *m_chmFile; +}; + +#endif /* MSITS_H */ diff --git a/generators/chm/lib/bitfiddle.h b/generators/chm/lib/bitfiddle.h new file mode 100644 index 0000000..44e18e3 --- /dev/null +++ b/generators/chm/lib/bitfiddle.h @@ -0,0 +1,164 @@ +/* + + Copyright (C) 2003 Razvan Cojocaru + Most of the code in this file is a modified version of code from + Pabs' GPL chmdeco project, credits and thanks go to him. + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +inline unsigned short UINT16ARRAY(const void *x) +{ + unsigned char *p = (unsigned char *)x; + return p[0] | (p[1] << 8); +} + +inline unsigned int UINT32ARRAY(const void *x) +{ + unsigned char *p = (unsigned char *)x; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +inline int INT32ARRAY(const void *x) +{ + char *p = (char *)x; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +inline unsigned int get_int32_le(void *addr) +{ + unsigned char *p = (unsigned char *)addr; + return (unsigned int)(p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); +} + +inline quint64 be_encint(unsigned char *buffer, size_t &length) +{ + quint64 result = 0; + int shift = 0; + length = 0; + + do { + result |= ((*buffer) & 0x7f) << shift; + shift += 7; + ++length; + + } while (*(buffer++) & 0x80); + + return result; +} + +/* + Finds the first unset bit in memory. Returns the number of set bits found. + Returns -1 if the buffer runs out before we find an unset bit. +*/ +inline int ffus(unsigned char *byte, int *bit, size_t &length) +{ + int bits = 0; + length = 0; + + while (*byte & (1 << *bit)) { + if (*bit) + --(*bit); + else { + ++byte; + ++length; + *bit = 7; + } + ++bits; + } + + if (*bit) + --(*bit); + else { + ++length; + *bit = 7; + } + + return bits; +} + +inline quint64 sr_int(unsigned char *byte, int *bit, unsigned char s, unsigned char r, size_t &length) +{ + quint64 ret; + unsigned char mask; + int n, n_bits, num_bits, base, count; + length = 0; + size_t fflen; + + if (!bit || *bit > 7 || s != 2) + return ~(quint64)0; + ret = 0; + + count = ffus(byte, bit, fflen); + length += fflen; + byte += length; + + n_bits = n = r + (count ? count - 1 : 0); + + while (n > 0) { + num_bits = n > *bit ? *bit : n - 1; + base = n > *bit ? 0 : *bit - (n - 1); + + switch (num_bits) { + case 0: + mask = 1; + break; + case 1: + mask = 3; + break; + case 2: + mask = 7; + break; + case 3: + mask = 0xf; + break; + case 4: + mask = 0x1f; + break; + case 5: + mask = 0x3f; + break; + case 6: + mask = 0x7f; + break; + case 7: + mask = 0xff; + break; + default: + mask = 0xff; + break; + } + + mask <<= base; + ret = (ret << (num_bits + 1)) | (quint64)((*byte & mask) >> base); + + if (n > *bit) { + ++byte; + ++length; + n -= *bit + 1; + *bit = 7; + } else { + *bit -= n; + n = 0; + } + } + + if (count) + ret |= (quint64)1 << n_bits; + + return ret; +} diff --git a/generators/chm/lib/ebook.cpp b/generators/chm/lib/ebook.cpp new file mode 100644 index 0000000..69aa775 --- /dev/null +++ b/generators/chm/lib/ebook.cpp @@ -0,0 +1,47 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ebook.h" +#include "ebook_chm.h" +#include "ebook_epub.h" + +EBook::EBook() +{ +} + +EBook::~EBook() +{ +} + +EBook *EBook::loadFile(const QString &archiveName) +{ + EBook_CHM *cbook = new EBook_CHM(); + + if (cbook->load(archiveName)) + return cbook; + + delete cbook; + + EBook_EPUB *ebook = new EBook_EPUB(); + + if (ebook->load(archiveName)) + return ebook; + + delete ebook; + return nullptr; +} diff --git a/generators/chm/lib/ebook.h b/generators/chm/lib/ebook.h new file mode 100644 index 0000000..1d984f7 --- /dev/null +++ b/generators/chm/lib/ebook.h @@ -0,0 +1,230 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDE_EBOOK_H +#define INCLUDE_EBOOK_H + +#include +#include +#include + +//! Stores a single table of content entry +class EBookTocEntry +{ +public: + //! Content TOC icon indexes for CHM books (epub books contain no icons) + enum Icon { + IMAGE_NONE = -1, + IMAGE_AUTO = -2, + + MAX_BUILTIN_ICONS = 42 + }; + + //! Entry name + QString name; + + //! Entry URL. + QUrl url; + + //! Associated image number. Used for TOC only; indexes does not have the image. + //! If IMAGE_NONE, no icon is associated. Otherwise use getBookIconPixmap() to get associated pixmap icon. + Icon iconid; + + //! Indentation level for this entry. + int indent; +}; + +//! Stores a single index entry +class EBookIndexEntry +{ +public: + //! Entry name + QString name; + + //! Entry URLs. The index entry could have several URLs + QList urls; + + //! Whether this is a 'see also' index type, and its value + QString seealso; + + //! Indentation level for this entry. + int indent; +}; + +//! Universal ebook files processor supporting both CHM and EPUB. Abstract. +class EBook +{ +public: + enum Feature { + FEATURE_TOC, // has table of contents + FEATURE_INDEX, // has index + FEATURE_ENCODING // Could be encoded with different encodings + }; + + //! Default constructor and destructor. + EBook(); + virtual ~EBook(); + + EBook(const EBook &) = delete; + EBook &operator=(const EBook &) = delete; + + /*! + * \brief Attempts to load chm or epub file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a CHM or epub file. For CHM files it could internally load more than one file, + * if files linked to this one are present locally (like MSDN). + * \ingroup init + */ + static EBook *loadFile(const QString &archiveName); + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + virtual void close() = 0; + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + virtual QString title() const = 0; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + virtual QUrl homeUrl() const = 0; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + virtual bool hasFeature(Feature code) const = 0; + + /*! + * \brief Parses and fills up the Table of Contents (TOC) + * \param topics A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + virtual bool getTableOfContents(QList &toc) const = 0; + + /*! + * \brief Parses the index table + * \param indexes A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy chm file; so far it never happened on indexes. + * \ingroup fileparsing + */ + virtual bool getIndex(QList &index) const = 0; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as QString. + * \param str A string where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + virtual bool getFileContentAsString(QString &str, const QUrl &url) const = 0; + + /*! + * \brief Retrieves the content from url in current chm file to QByteArray. + * \param data A data array where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. + * + * This function retreives the file content from the chm archive opened by load() + * function. The content is not encoded. + * + * \sa getFileContentAsString() + * \ingroup dataretrieve + */ + virtual bool getFileContentAsBinary(QByteArray &data, const QUrl &url) const = 0; + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \param files An array to store list of URLs present in chm archive. + * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason). + * + * \ingroup dataretrieve + */ + virtual bool enumerateFiles(QList &files) = 0; + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook file to get title from. Must be absolute. + * \return The title, or QString() if the URL cannot be found or not a HTML page. + * + * \ingroup dataretrieve + */ + virtual QString getTopicByUrl(const QUrl &url) = 0; + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec name. Must be implemented, + * even if the book doesn't support change of encoding (then it should return a default encoding) + * \return The current encoding. + * + * \ingroup encoding + */ + virtual QString currentEncoding() const = 0; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + virtual bool setCurrentEncoding(const char *encoding) = 0; + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + virtual bool isSupportedUrl(const QUrl &url) = 0; + + // Converts the string to the ebook-specific URL format + virtual QUrl pathToUrl(const QString &link) const = 0; + + // Extracts the path component from the URL + virtual QString urlToPath(const QUrl &link) const = 0; + +protected: + // Loads the file; returns true if loaded, false otherwise + virtual bool load(const QString &archiveName) = 0; +}; + +#endif // INCLUDE_LIBCHMFILE_H diff --git a/generators/chm/lib/ebook_chm.cpp b/generators/chm/lib/ebook_chm.cpp new file mode 100644 index 0000000..b04461b --- /dev/null +++ b/generators/chm/lib/ebook_chm.cpp @@ -0,0 +1,1006 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "ebook_chm.h" +#include "ebook_chm_encoding.h" + +#include "bitfiddle.h" + +// Big-enough buffer size for use with various routines. +#define BUF_SIZE 4096 +#define COMMON_BUF_LEN 1025 + +#define TOPICS_ENTRY_LEN 16 +#define URLTBL_ENTRY_LEN 12 + +//#define DEBUGPARSER(A) qDebug A +#define DEBUGPARSER(A) + +static const char *URL_SCHEME_CHM = "ms-its"; + +EBook_CHM::EBook_CHM() + : EBook() +{ + m_envOptions = qgetenv("KCHMVIEWEROPTS"); + m_chmFile = nullptr; + m_filename = m_font = QString(); + + m_textCodec = nullptr; + m_textCodecForSpecialFiles = nullptr; + m_detectedLCID = 0; + m_currentEncoding = QStringLiteral("UTF-8"); + m_htmlEntityDecoder = nullptr; +} + +EBook_CHM::~EBook_CHM() +{ + close(); +} + +void EBook_CHM::close() +{ + if (m_chmFile == nullptr) + return; + + chm_close(m_chmFile); + + m_chmFile = nullptr; + m_filename = m_font = QString(); + + m_home.clear(); + m_topicsFile.clear(); + m_indexFile.clear(); + + m_textCodec = nullptr; + m_textCodecForSpecialFiles = nullptr; + m_detectedLCID = 0; + m_currentEncoding = QStringLiteral("UTF-8"); +} + +QString EBook_CHM::title() const +{ + return encodeWithCurrentCodec(m_title); +} + +QUrl EBook_CHM::homeUrl() const +{ + return pathToUrl(m_home); +} + +bool EBook_CHM::hasFeature(EBook::Feature code) const +{ + switch (code) { + case FEATURE_TOC: + return m_tocAvailable; + + case FEATURE_INDEX: + return m_indexAvailable; + + case FEATURE_ENCODING: + return true; + } + + return false; +} + +bool EBook_CHM::getTableOfContents(QList &toc) const +{ + if (parseBinaryTOC(toc)) + return true; + + // Parse the plain text TOC + QList parsed; + + if (!parseFileAndFillArray(m_topicsFile, parsed, false)) + return false; + + // Find out the root offset, and reduce the indent level to it + // so the toc starts from zero offset. + int root_offset = -1; + + // Fill up the real toc + toc.reserve(parsed.size()); + for (const ParsedEntry &e : qAsConst(parsed)) { + if (root_offset == -1) + root_offset = e.indent; + + EBookTocEntry entry; + entry.iconid = (EBookTocEntry::Icon)e.iconid; + entry.indent = e.indent - root_offset; + entry.name = e.name; + + if (!e.urls.empty()) + entry.url = e.urls[0]; + + toc.append(entry); + } + + return true; +} + +bool EBook_CHM::getIndex(QList &index) const +{ + // Parse the plain text index + QList parsed; + + if (!parseFileAndFillArray(m_indexFile, parsed, true)) + return false; + + // Find out the root offset, and reduce the indent level to it + // so the index starts from zero offset. + int root_offset = 0; + + // Fill up the real index + index.reserve(parsed.size()); + + // Find the index root offset + const QList &parsedList = parsed; + for (const ParsedEntry &e : parsedList) { + if (e.urls.empty()) + continue; + + root_offset = qMin(root_offset, e.indent); + } + + // And apply the index + for (const ParsedEntry &e : parsedList) { + if (e.urls.empty()) + continue; + + EBookIndexEntry entry; + entry.name = e.name; + entry.urls = e.urls; + entry.seealso = e.seealso; + + // If the index array is empty, make sure the first entry is on root offset + if (index.isEmpty()) + entry.indent = root_offset; + else + entry.indent = e.indent - root_offset; + + index.append(entry); + printf("%d: %s\n", entry.indent, qPrintable(entry.name)); + } + + return true; +} + +bool EBook_CHM::getFileContentAsString(QString &str, const QUrl &url) const +{ + return getTextContent(str, urlToPath(url)); +} + +bool EBook_CHM::getFileContentAsBinary(QByteArray &data, const QUrl &url) const +{ + return getBinaryContent(data, urlToPath(url)); +} + +bool EBook_CHM::getBinaryContent(QByteArray &data, const QString &url) const +{ + chmUnitInfo ui; + + if (!ResolveObject(url, &ui)) + return false; + + data.resize(ui.length); + + if (RetrieveObject(&ui, (unsigned char *)data.data(), 0, ui.length)) + return true; + + return false; +} + +bool EBook_CHM::getTextContent(QString &str, const QString &url, bool internal_encoding) const +{ + QByteArray buf; + + if (getBinaryContent(buf, url)) { + unsigned int length = buf.size(); + + if (length > 0) { + buf.resize(length + 1); + buf[length] = '\0'; + + str = internal_encoding ? (QString)(buf.constData()) : encodeWithCurrentCodec(buf.constData()); + return true; + } + } + + return false; +} + +int EBook_CHM::getContentSize(const QString &url) +{ + chmUnitInfo ui; + + if (!ResolveObject(url, &ui)) + return -1; + + return ui.length; +} + +bool EBook_CHM::load(const QString &archiveName) +{ + QString filename; + + // If the file has a file:// prefix, remove it + if (archiveName.startsWith(QLatin1String("file://"))) + filename = archiveName.mid(7); // strip it + else + filename = archiveName; + + if (m_chmFile) + close(); + +#if defined(WIN32) + // chm_open on Windows OS uses the following prototype: + // struct chmFile* chm_open(BSTR filename); + // + // however internally it simply passes the filename + // directly to CreateFileW function without any conversion. + // Thus we need to pass it as WCHAR * and not BSTR. + m_chmFile = chm_open((BSTR)filename.toStdWString().c_str()); +#else + m_chmFile = chm_open(QFile::encodeName(filename)); +#endif + + if (m_chmFile == nullptr) + return false; + + m_filename = filename; + + // Reset encoding + m_textCodec = nullptr; + m_textCodecForSpecialFiles = nullptr; + m_currentEncoding = QStringLiteral("UTF-8"); + + // Get information from /#WINDOWS and /#SYSTEM files (encoding, title, context file and so) + // and guess the encoding + getInfoFromWindows(); + getInfoFromSystem(); + guessTextEncoding(); + + // Check whether the search tables are present + if (ResolveObject(QStringLiteral("/#TOPICS"), &m_chmTOPICS) && ResolveObject(QStringLiteral("/#STRINGS"), &m_chmSTRINGS) && ResolveObject(QStringLiteral("/#URLTBL"), &m_chmURLTBL) && + ResolveObject(QStringLiteral("/#URLSTR"), &m_chmURLSTR)) { + m_lookupTablesValid = true; + fillTopicsUrlMap(); + } else + m_lookupTablesValid = false; + + // Some CHM files have toc and index files, but do not set the name properly. + // Some heuristics here. + if (m_topicsFile.isEmpty() && hasFile(QStringLiteral("/toc.hhc"))) + m_topicsFile = "/toc.hhc"; + + if (m_indexFile.isEmpty() && hasFile(QStringLiteral("/index.hhk"))) + m_indexFile = "/index.hhk"; + + if (!m_topicsFile.isEmpty() || (m_lookupTablesValid && hasFile(QStringLiteral("/#TOCIDX")))) + m_tocAvailable = true; + else + m_tocAvailable = false; + + if (!m_indexFile.isEmpty() || (m_lookupTablesValid && hasFile(QStringLiteral("/$WWKeywordLinks/BTree")))) + m_indexAvailable = true; + else + m_indexAvailable = false; + + return true; +} + +int EBook_CHM::findStringInQuotes(const QString &tag, int offset, QString &value, bool firstquote, bool decodeentities) const +{ + int qbegin = tag.indexOf('"', offset); + + if (qbegin == -1) + qFatal("EBook_CHMImpl::findStringInQuotes: cannot find first quote in tag: '%s'", qPrintable(tag)); + + int qend = firstquote ? tag.indexOf('"', qbegin + 1) : tag.lastIndexOf('"'); + + if (qend == -1 || qend <= qbegin) + qFatal("EBook_CHMImpl::findStringInQuotes: cannot find last quote in tag: '%s'", qPrintable(tag)); + + // If we do not need to decode HTML entities, just return. + if (decodeentities) { + QString htmlentity = QString(); + bool fill_entity = false; + + value.reserve(qend - qbegin); // to avoid multiple memory allocations + + for (int i = qbegin + 1; i < qend; i++) { + if (!fill_entity) { + if (tag[i] == '&') // HTML entity starts + fill_entity = true; + else + value.append(tag[i]); + } else { + if (tag[i] == ';') // HTML entity ends + { + // If entity is an ASCII code, just decode it + QString decode = m_htmlEntityDecoder.decode(htmlentity); + + if (decode.isNull()) + break; + + value.append(decode); + htmlentity = QString(); + fill_entity = false; + } else + htmlentity.append(tag[i]); + } + } + } else + value = tag.mid(qbegin + 1, qend - qbegin - 1); + + return qend + 1; +} + +bool EBook_CHM::parseFileAndFillArray(const QString &file, QList &data, bool asIndex) const +{ + QString src; + const int MAX_NEST_DEPTH = 256; + + if (!getTextContent(src, file) || src.isEmpty()) + return false; + + /* + // Save the index for debugging purposes + QFile outfile( "parsed.htm" ); + + if ( outfile.open( QIODevice::WriteOnly ) ) + { + QTextStream textstream( &outfile ); + textstream << src; + outfile.close(); + } + */ + + EBookTocEntry::Icon defaultimagenum = EBookTocEntry::IMAGE_AUTO; + int pos = 0, indent = 0, root_indent_offset = 0; + bool in_object = false, root_indent_offset_set = false; + + ParsedEntry entry; + entry.iconid = defaultimagenum; + + // Split the HHC file by HTML tags + int stringlen = src.length(); + + while (pos < stringlen && (pos = src.indexOf('<', pos)) != -1) { + int i, word_end = 0; + + for (i = ++pos; i < stringlen; i++) { + // If a " or ' is found, skip to the next one. + if ((src[i] == '"' || src[i] == '\'')) { + // find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML) + int nextpos = src.indexOf(src[i], i + 1); + if (nextpos == -1 && (nextpos = src.indexOf('>', i + 1)) == -1) { + qWarning("EBook_CHMImpl::ParseHhcAndFillTree: corrupted TOC: %s", qPrintable(src.mid(i))); + return false; + } + + i = nextpos; + } else if (src[i] == '>') + break; + else if (!src[i].isLetterOrNumber() && src[i] != '/' && !word_end) + word_end = i; + } + + QString tagword, tag = src.mid(pos, i - pos); + + if (word_end) + tagword = src.mid(pos, word_end - pos).toLower(); + else + tagword = tag.toLower(); + + // DEBUGPARSER(("tag: '%s', tagword: '%s'\n", qPrintable( tag ), qPrintable( tagword ) )); + + // - a topic entry + if (tagword == QLatin1String("object") && tag.indexOf(QLatin1String("text/sitemap"), 0, Qt::CaseInsensitive) != -1) + in_object = true; + else if (tagword == QLatin1String("/object") && in_object) { + // a topic entry closed. Add a tree item + if (entry.name.isEmpty() && entry.urls.isEmpty()) { + qWarning("EBook_CHMImpl::ParseAndFillTopicsTree: tag is parsed, but both name and url are empty."); + } else { + // If the name is empty, use the URL as name + if (entry.name.isEmpty()) + entry.name = entry.urls[0].toString(); + + if (!root_indent_offset_set) { + root_indent_offset_set = true; + root_indent_offset = indent; + + if (root_indent_offset > 1) + qWarning("CHM has improper index; root indent offset is %d", root_indent_offset); + } + + // Trim the entry name + entry.name = entry.name.trimmed(); + + int real_indent = indent - root_indent_offset; + + entry.indent = real_indent; + data.push_back(entry); + } + + entry.name = QString(); + entry.urls.clear(); + entry.iconid = defaultimagenum; + entry.seealso.clear(); + in_object = false; + } else if (tagword == QLatin1String("param") && in_object) { + // + int offset; // strlen("param ") + const QString name_pattern = QStringLiteral("name="), value_pattern = QStringLiteral("value="); + QString pname, pvalue; + + if ((offset = tag.indexOf(name_pattern, 0, Qt::CaseInsensitive)) == -1) + qFatal("EBook_CHMImpl::ParseAndFillTopicsTree: bad tag '%s': no name=\n", qPrintable(tag)); + + // offset+5 skips 'name=' + offset = findStringInQuotes(tag, offset + name_pattern.length(), pname, true, false); + pname = pname.toLower(); + + if ((offset = tag.indexOf(value_pattern, offset, Qt::CaseInsensitive)) == -1) + qFatal("EBook_CHMImpl::ParseAndFillTopicsTree: bad tag '%s': no value=\n", qPrintable(tag)); + + // offset+6 skips 'value=' + findStringInQuotes(tag, offset + value_pattern.length(), pvalue, false, true); + + // DEBUGPARSER((": name '%s', value '%s'", qPrintable( pname ), qPrintable( pvalue ))); + + if (pname == QLatin1String("name") || pname == QLatin1String("keyword")) { + // Some help files contain duplicate names, where the second name is empty. Work it around by keeping the first one + if (!pvalue.isEmpty()) + entry.name = pvalue; + } else if (pname == QLatin1String("merge")) { + // MERGE implementation is experimental + QUrl mergeurl = pathToUrl(pvalue); + QString mergecontent; + + if (getFileContentAsString(mergecontent, mergeurl) && !mergecontent.isEmpty()) { + qWarning("MERGE is used in index; the implementation is experimental. Please let me know if it works"); + + // Merge the read value into the current parsed file. + // To save memory it is done in a kinda hacky way: + src = mergecontent + src.mid(i); + pos = 0; + stringlen = src.length(); + } else + qWarning("MERGE is used in index but file %s was not found in CHM archive", qPrintable(pvalue)); + } else if (pname == QLatin1String("local")) { + // Check for URL duplication + QUrl url = pathToUrl(pvalue); + + if (!entry.urls.contains(url)) + entry.urls.push_back(url); + } else if (pname == QLatin1String("see also") && asIndex && entry.name != pvalue) { + entry.urls.push_back(QUrl(QStringLiteral("seealso"))); + entry.seealso = pvalue; + } else if (pname == QLatin1String("imagenumber")) { + bool bok; + int imgnum = pvalue.toInt(&bok); + + if (bok && imgnum >= 0 && imgnum < EBookTocEntry::MAX_BUILTIN_ICONS) + entry.iconid = (EBookTocEntry::Icon)imgnum; + } + } else if (tagword == QLatin1String("ul")) // increase indent level + { + // Fix for buggy help files + if (++indent >= MAX_NEST_DEPTH) + qFatal("EBook_CHMImpl::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH); + + DEBUGPARSER(("
    : new intent is %d\n", indent - root_indent_offset)); + } else if (tagword == QLatin1String("/ul")) // decrease indent level + { + if (--indent < root_indent_offset) + indent = root_indent_offset; + + DEBUGPARSER(("
: new intent is %d\n", indent - root_indent_offset)); + } + + pos = i; + } + + // Dump our array + // for ( int i = 0; i < data.size(); i++ ) + // qDebug() << data[i].indent << data[i].name << data[i].urls; + + return true; +} + +bool EBook_CHM::ResolveObject(const QString &fileName, chmUnitInfo *ui) const +{ + return m_chmFile != nullptr && ::chm_resolve_object(m_chmFile, qPrintable(fileName), ui) == CHM_RESOLVE_SUCCESS; +} + +bool EBook_CHM::hasFile(const QString &fileName) const +{ + chmUnitInfo ui; + + return m_chmFile != nullptr && ::chm_resolve_object(m_chmFile, qPrintable(fileName), &ui) == CHM_RESOLVE_SUCCESS; +} + +size_t EBook_CHM::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) const +{ + return ::chm_retrieve_object(m_chmFile, const_cast(ui), buffer, fileOffset, bufferSize); +} + +bool EBook_CHM::getInfoFromWindows() +{ +#define WIN_HEADER_LEN 0x08 + unsigned char buffer[BUF_SIZE]; + unsigned int factor; + chmUnitInfo ui; + long size = 0; + + if (ResolveObject(QStringLiteral("/#WINDOWS"), &ui)) { + if (!RetrieveObject(&ui, buffer, 0, WIN_HEADER_LEN)) + return false; + + unsigned int entries = get_int32_le(reinterpret_cast(buffer)); + unsigned int entry_size = get_int32_le(reinterpret_cast(buffer + 0x04)); + + QVector uptr(entries * entry_size); + unsigned char *raw = (unsigned char *)uptr.data(); + + if (!RetrieveObject(&ui, raw, 8, entries * entry_size)) + return false; + + if (!ResolveObject(QStringLiteral("/#STRINGS"), &ui)) + return false; + + for (unsigned int i = 0; i < entries; ++i) { + unsigned int offset = i * entry_size; + + unsigned int off_title = get_int32_le(reinterpret_cast(raw + offset + 0x14)); + unsigned int off_home = get_int32_le(reinterpret_cast(raw + offset + 0x68)); + unsigned int off_hhc = get_int32_le(reinterpret_cast(raw + offset + 0x60)); + unsigned int off_hhk = get_int32_le(reinterpret_cast(raw + offset + 0x64)); + + factor = off_title / 4096; + + if (size == 0) + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + + if (size && off_title) + m_title = QByteArray((const char *)(buffer + off_title % 4096)); + + if (factor != off_home / 4096) { + factor = off_home / 4096; + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + } + + if (size && off_home) + m_home = QByteArray("/") + QByteArray((const char *)buffer + off_home % 4096); + + if (factor != off_hhc / 4096) { + factor = off_hhc / 4096; + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + } + + if (size && off_hhc) + m_topicsFile = QByteArray("/") + QByteArray((const char *)buffer + off_hhc % 4096); + + if (factor != off_hhk / 4096) { + factor = off_hhk / 4096; + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + } + + if (size && off_hhk) + m_indexFile = QByteArray("/") + QByteArray((const char *)buffer + off_hhk % 4096); + } + } + return true; +} + +bool EBook_CHM::getInfoFromSystem() +{ + unsigned char buffer[BUF_SIZE]; + chmUnitInfo ui; + + int index = 0; + unsigned char *cursor = nullptr, *p; + unsigned short value = 0; + long size = 0; + + // Run the first loop to detect the encoding. We need this, because title could be + // already encoded in user encoding. Same for file names + if (!ResolveObject(QStringLiteral("/#SYSTEM"), &ui)) + return false; + + // Can we pull BUFF_SIZE bytes of the #SYSTEM file? + if ((size = RetrieveObject(&ui, buffer, 4, BUF_SIZE)) == 0) + return false; + + buffer[size - 1] = 0; + + // First loop to detect the encoding + for (index = 0; index < (size - 1 - (long)sizeof(unsigned short));) { + cursor = buffer + index; + value = UINT16ARRAY(cursor); + + switch (value) { + case 0: + index += 2; + cursor = buffer + index; + + if (m_topicsFile.isEmpty()) + m_topicsFile = QByteArray("/") + QByteArray((const char *)buffer + index + 2); + + break; + + case 1: + index += 2; + cursor = buffer + index; + + if (m_indexFile.isEmpty()) + m_indexFile = QByteArray("/") + QByteArray((const char *)buffer + index + 2); + break; + + case 2: + index += 2; + cursor = buffer + index; + + if (m_home.isEmpty() || m_home == "/") + m_home = QByteArray("/") + QByteArray((const char *)buffer + index + 2); + break; + + case 3: + index += 2; + cursor = buffer + index; + m_title = QByteArray((const char *)(buffer + index + 2)); + break; + + case 4: + index += 2; + cursor = buffer + index; + + p = buffer + index + 2; + m_detectedLCID = (short)(p[0] | (p[1] << 8)); + + break; + + case 6: + index += 2; + cursor = buffer + index; + + if (m_topicsFile.isEmpty()) { + QString topicAttempt = QStringLiteral("/"); + topicAttempt += QString((const char *)buffer + index + 2); + + QString tmp = topicAttempt + ".hhc"; + + if (ResolveObject(tmp, &ui)) + m_topicsFile = qPrintable(tmp); + + tmp = topicAttempt + ".hhk"; + + if (ResolveObject(tmp, &ui)) + m_indexFile = qPrintable(tmp); + } + break; + + case 16: + index += 2; + cursor = buffer + index; + + m_font = QString((const char *)buffer + index + 2); + break; + + default: + index += 2; + cursor = buffer + index; + } + + value = UINT16ARRAY(cursor); + index += value + 2; + } + + return true; +} + +QString EBook_CHM::getTopicByUrl(const QUrl &url) +{ + QMap::const_iterator it = m_url2topics.constFind(url); + + if (it == m_url2topics.constEnd()) + return QString(); + + return it.value(); +} + +static int chm_enumerator_callback(struct chmFile *, struct chmUnitInfo *ui, void *context) +{ + EBook_CHM tmp; + ((QList *)context)->push_back(tmp.pathToUrl(ui->path)); + return CHM_ENUMERATOR_CONTINUE; +} + +bool EBook_CHM::enumerateFiles(QList &files) +{ + files.clear(); + return chm_enumerate(m_chmFile, CHM_ENUMERATE_ALL, chm_enumerator_callback, &files); +} + +QString EBook_CHM::currentEncoding() const +{ + return m_currentEncoding; +} + +bool EBook_CHM::setCurrentEncoding(const char *encoding) +{ + m_currentEncoding = encoding; + return changeFileEncoding(encoding); +} + +bool EBook_CHM::isSupportedUrl(const QUrl &url) +{ + return url.scheme() == URL_SCHEME_CHM; +} + +bool EBook_CHM::guessTextEncoding() +{ + if (!m_detectedLCID) { + qWarning("Could not detect LCID"); + return false; + } + + QString enc = Ebook_CHM_Encoding::guessByLCID(m_detectedLCID); + + if (changeFileEncoding(enc)) { + m_currentEncoding = enc; + return true; + } + + return false; +} + +bool EBook_CHM::changeFileEncoding(const QString &qtencoding) +{ + // Encoding could be either simple Qt codepage, or set like CP1251/KOI8, which allows to + // set up encodings separately for text (first) and internal files (second) + int p = qtencoding.indexOf('/'); + + if (p != -1) { + QString global = qtencoding.left(p); + QString special = qtencoding.mid(p + 1); + + m_textCodec = QTextCodec::codecForName(global.toUtf8()); + + if (!m_textCodec) { + qWarning("Could not set up Text Codec for encoding '%s'", qPrintable(global)); + return false; + } + + m_textCodecForSpecialFiles = QTextCodec::codecForName(special.toUtf8()); + + if (!m_textCodecForSpecialFiles) { + qWarning("Could not set up Text Codec for encoding '%s'", qPrintable(special)); + return false; + } + } else { + m_textCodecForSpecialFiles = m_textCodec = QTextCodec::codecForName(qtencoding.toUtf8()); + + if (!m_textCodec) { + qWarning("Could not set up Text Codec for encoding '%s'", qPrintable(qtencoding)); + return false; + } + } + + m_htmlEntityDecoder.changeEncoding(m_textCodec); + return true; +} + +void EBook_CHM::fillTopicsUrlMap() +{ + if (!m_lookupTablesValid) + return; + + // Read those tables + QVector topics(m_chmTOPICS.length), urltbl(m_chmURLTBL.length), urlstr(m_chmURLSTR.length), strings(m_chmSTRINGS.length); + + if (!RetrieveObject(&m_chmTOPICS, (unsigned char *)topics.data(), 0, m_chmTOPICS.length) || !RetrieveObject(&m_chmURLTBL, (unsigned char *)urltbl.data(), 0, m_chmURLTBL.length) || + !RetrieveObject(&m_chmURLSTR, (unsigned char *)urlstr.data(), 0, m_chmURLSTR.length) || !RetrieveObject(&m_chmSTRINGS, (unsigned char *)strings.data(), 0, m_chmSTRINGS.length)) + return; + + for (LONGUINT64 i = 0; i < m_chmTOPICS.length; i += TOPICS_ENTRY_LEN) { + unsigned int off_title = get_int32_le(reinterpret_cast(topics.data() + i + 4)); + unsigned int off_url = get_int32_le(reinterpret_cast(topics.data() + i + 8)); + off_url = get_int32_le(reinterpret_cast(urltbl.data() + off_url + 8)) + 8; + + QUrl url = pathToUrl((const char *)urlstr.data() + off_url); + + if (off_title < (unsigned int)strings.size()) + m_url2topics[url] = encodeWithCurrentCodec((const char *)strings.data() + off_title); + else + m_url2topics[url] = QStringLiteral("Untitled"); + } +} + +bool EBook_CHM::parseBinaryTOC(QList &toc) const +{ + if (!m_lookupTablesValid) + return false; + + QByteArray tocidx, topics, urltbl, urlstr, strings; + + // Read the index tables + if (!getBinaryContent(tocidx, QStringLiteral("/#TOCIDX")) || !getBinaryContent(topics, QStringLiteral("/#TOPICS")) || !getBinaryContent(urltbl, QStringLiteral("/#URLTBL")) || !getBinaryContent(urlstr, QStringLiteral("/#URLSTR")) || + !getBinaryContent(strings, QStringLiteral("/#STRINGS"))) + return false; + + // Shamelessly stolen from xchm + if (!RecurseLoadBTOC(tocidx, topics, urltbl, urlstr, strings, UINT32ARRAY(tocidx.data()), toc, 0)) { + qWarning("Failed to parse binary TOC, fallback to text-based TOC"); + toc.clear(); + return false; + } + + return true; +} + +// +// This piece of code was based on the one in xchm written by Razvan Cojocaru +// +bool EBook_CHM::RecurseLoadBTOC(const QByteArray &tocidx, const QByteArray &topics, const QByteArray &urltbl, const QByteArray &urlstr, const QByteArray &strings, int offset, QList &entries, int level) const +{ + while (offset) { + // If this is end of TOCIDX, return. + if (tocidx.size() < offset + 20) + return true; + + unsigned int flags = UINT32ARRAY(tocidx.data() + offset + 4); + int index = UINT32ARRAY(tocidx.data() + offset + 8); + + if ((flags & 0x04) || (flags & 0x08)) { + QString name, value; + + if ((flags & 0x08) == 0) { + if (strings.size() < index + 1) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name index (%d) for book TOC entry!", index); + return false; + } + + name = encodeWithCurrentCodec(strings.data() + index); + } else { + if (topics.size() < (index * 16) + 12) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name index (%d) for local TOC entry!", index); + return false; + } + + int tocoffset = (int)UINT32ARRAY(topics.data() + (index * 16) + 4); + + if (strings.size() < tocoffset + 1) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name tocoffset (%d) for TOC entry!", tocoffset); + return false; + } + + if (tocoffset < 0) + name.clear(); + else + name = encodeWithCurrentCodec(strings.data() + tocoffset); + + // #URLTBL index + tocoffset = (int)UINT32ARRAY(topics.data() + (index * 16) + 8); + + if (tocoffset < 0 || urltbl.size() < tocoffset + 12) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid url index (%d) for TOC entry!", tocoffset); + return false; + } + + tocoffset = (int)UINT32ARRAY(urltbl.data() + tocoffset + 8); + + if (tocoffset < 0 || urlstr.size() < tocoffset) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid url offset (%d) for TOC entry!", tocoffset); + return false; + } + + value = encodeWithCurrentCodec(urlstr.data() + tocoffset + 8); + } + + EBookTocEntry entry; + entry.name = name.trimmed(); + + if (!entry.name.isEmpty()) { + if (!value.isEmpty()) + entry.url = pathToUrl(value); + + entry.iconid = EBookTocEntry::IMAGE_AUTO; + entry.indent = level; + entries.push_back(entry); + } + } + + if (flags & 0x04) { + // book + if (tocidx.size() < offset + 24) { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid child entry offset (%d)", offset); + return false; + } + + unsigned int childoffset = UINT32ARRAY(tocidx.data() + offset + 20); + + if (childoffset) { + if (!RecurseLoadBTOC(tocidx, topics, urltbl, urlstr, strings, childoffset, entries, level + 1)) + return false; + } + } + + offset = UINT32ARRAY(tocidx.data() + offset + 0x10); + } + + return true; +} + +bool EBook_CHM::hasOption(const QString &name) const +{ + if (!m_envOptions.isEmpty() && m_envOptions.contains(name)) + return true; + + return false; +} + +QUrl EBook_CHM::pathToUrl(const QString &link) const +{ + if (link.startsWith(QLatin1String("http://")) || link.startsWith(QLatin1String("https://"))) + return QUrl(link); + + QUrl url; + url.setScheme(URL_SCHEME_CHM); + url.setHost(URL_SCHEME_CHM); + + // Does the link contain the fragment as well? + int off = link.indexOf('#'); + QString path; + + if (off != -1) { + path = link.left(off); + url.setFragment(link.mid(off + 1)); + } else + path = link; + + if (!path.startsWith('/')) + path.prepend('/'); + + url.setPath(QUrl::fromPercentEncoding(path.toUtf8())); + return url; +} + +QString EBook_CHM::urlToPath(const QUrl &link) const +{ + if (link.scheme() == URL_SCHEME_CHM) { + if (link.path() == QLatin1String("/") || link.path().isEmpty()) + return m_home; + + return link.path(); + } + + return QLatin1String(""); +} + +EBook_CHM::ParsedEntry::ParsedEntry() +{ + iconid = 0; + indent = 0; +} diff --git a/generators/chm/lib/ebook_chm.h b/generators/chm/lib/ebook_chm.h new file mode 100644 index 0000000..fcfad96 --- /dev/null +++ b/generators/chm/lib/ebook_chm.h @@ -0,0 +1,335 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_CHM_H +#define EBOOK_CHM_H + +#include +#include + +// Enable Unicode use in libchm +#if defined(WIN32) +#define PPC_BSTR +#endif +#include + +#include "ebook.h" +#include "helper_entitydecoder.h" + +class EBook_CHM : public EBook +{ +public: + EBook_CHM(); + ~EBook_CHM() override; + + /*! + * \brief Attempts to load chm file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a CHM file. For CHM files it could internally load more than one file, + * if files linked to this one are present locally (like MSDN). + * \ingroup init + */ + bool load(const QString &archiveName) override; + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + void close() override; + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + QString title() const override; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + QUrl homeUrl() const override; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + bool hasFeature(Feature code) const override; + + /*! + * \brief Parses and fills up the Table of Contents (TOC) + * \param topics A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + bool getTableOfContents(QList &toc) const override; + + /*! + * \brief Parses the index table + * \param indexes A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy chm file; so far it never happened on indexes. + * \ingroup fileparsing + */ + bool getIndex(QList &index) const override; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as QString. + * \param str A string where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + bool getFileContentAsString(QString &str, const QUrl &url) const override; + + /*! + * \brief Retrieves the content from url in current chm file to QByteArray. + * \param data A data array where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. + * + * This function retreives the file content from the chm archive opened by load() + * function. The content is not encoded. + * + * \sa getFileContentAsString() + * \ingroup dataretrieve + */ + bool getFileContentAsBinary(QByteArray &data, const QUrl &url) const override; + + /*! + * \brief Retrieves the content size. + * \param url An URL in ebook file to retreive content from. Must be absolute. + * \return the size; -1 in case of error. + * + * \ingroup dataretrieve + */ + virtual int getContentSize(const QString &url); + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \param files An array to store list of URLs (file names) present in chm archive. + * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason). + * + * \ingroup dataretrieve + */ + bool enumerateFiles(QList &files) override; + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook file to get title from. Must be absolute. + * \return The title, or QString() if the URL cannot be found or not a HTML page. + * + * \ingroup dataretrieve + */ + QString getTopicByUrl(const QUrl &url) override; + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec + * \return The current encoding. + * + * \ingroup encoding + */ + QString currentEncoding() const override; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + bool setCurrentEncoding(const char *encoding) override; + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + bool isSupportedUrl(const QUrl &url) override; + + // Converts the string to the ebook-specific URL format + QUrl pathToUrl(const QString &link) const override; + + // Extracts the path component from the URL + QString urlToPath(const QUrl &link) const override; + +private: + // Used in local parser + class ParsedEntry + { + public: + ParsedEntry(); + + QString name; + QList urls; + int iconid; + int indent; + QString seealso; + }; + + //! Looks up fileName in the archive. + bool hasFile(const QString &fileName) const; + + //! Looks up fileName in the archive. + bool ResolveObject(const QString &fileName, chmUnitInfo *ui) const; + + //! Retrieves an uncompressed chunk of a file in the .chm. + size_t RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) const; + + //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not. + inline QString encodeWithCurrentCodec(const QByteArray &str) const + { + return (m_textCodec ? m_textCodec->toUnicode(str.constData()) : str); + } + + //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not. + inline QString encodeWithCurrentCodec(const char *str) const + { + return (m_textCodec ? m_textCodec->toUnicode(str) : (QString)str); + } + + //! Encode the string from internal files with the currently selected text codec, if possible. + //! Or return as-is, if not. + inline QString encodeInternalWithCurrentCodec(const QString &str) const + { + return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode(qPrintable(str)) : str); + } + + //! Encode the string from internal files with the currently selected text codec, if possible. + //! Or return as-is, if not. + inline QString encodeInternalWithCurrentCodec(const char *str) const + { + return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode(str) : (QString)str); + } + + //! Helper. Translates from Win32 encodings to generic wxWidgets ones. + const char *GetFontEncFromCharSet(const QString &font) const; + + //! Parse the HHC or HHS file, and fill the context (asIndex is false) or index (asIndex is true) array. + bool parseFileAndFillArray(const QString &file, QList &data, bool asIndex) const; + + bool getBinaryContent(QByteArray &data, const QString &url) const; + bool getTextContent(QString &str, const QString &url, bool internal_encoding = false) const; + + /*! + * Parse binary TOC + */ + bool parseBinaryTOC(QList &toc) const; + + //! btree string parser + QString getBtreeString(const QByteArray &btidx, unsigned long *offset, unsigned short *spaceLeft) const; + + /*! + * Recursively parse and fill binary TOC + */ + bool RecurseLoadBTOC(const QByteArray &tocidx, const QByteArray &topics, const QByteArray &urltbl, const QByteArray &urlstr, const QByteArray &strings, int offset, QList &entries, int level) const; + + /*! + * Helper procedure in TOC parsing, decodes the string between the quotes (first or last) with decoding HTML + * entities like í + */ + int findStringInQuotes(const QString &tag, int offset, QString &value, bool firstquote, bool decodeentities) const; + bool getInfoFromWindows(); + bool getInfoFromSystem(); + bool changeFileEncoding(const QString &qtencoding); + bool guessTextEncoding(); + void fillTopicsUrlMap(); + bool hasOption(const QString &name) const; + + // Members + + //! Pointer to the chmlib structure + chmFile *m_chmFile; + + //! Opened file name + QString m_filename; + + //! Home url, got from CHM file + QByteArray m_home; + + //! Context tree filename. Got from CHM file + QByteArray m_topicsFile; + + //! Index filename. Got from CHM file + QByteArray m_indexFile; + + //! Chm Title. Got from CHM file + QByteArray m_title; + + // Localization stuff + //! LCID from CHM file, used in encoding detection + short m_detectedLCID; + + //! font charset from CHM file, used in encoding detection + QString m_font; + + //! Chosen text codec + QTextCodec *m_textCodec; + QTextCodec *m_textCodecForSpecialFiles; + + //! Current encoding + QString m_currentEncoding; + + //! TRUE if /#TOPICS, /#STRINGS, /#URLTBL and /#URLSTR are resolved, and the members below are valid + bool m_lookupTablesValid; + + //! pointer to /#TOPICS + chmUnitInfo m_chmTOPICS; + + //! pointer to /#STRINGS + chmUnitInfo m_chmSTRINGS; + + //! pointer to /#URLTBL + chmUnitInfo m_chmURLTBL; + + //! pointer to /#URLSTR + chmUnitInfo m_chmURLSTR; + + //! Indicates whether TOC, either binary or text, is available. + bool m_tocAvailable; + + //! Indicates whether index, either binary or text, is available. + bool m_indexAvailable; + + //! Map url->topic + QMap m_url2topics; + + //! KCHMViewer debug options from environment + QString m_envOptions; + + //! HTML entity decoder + HelperEntityDecoder m_htmlEntityDecoder; +}; + +#endif // EBOOK_CHM_H diff --git a/generators/chm/lib/ebook_chm_encoding.cpp b/generators/chm/lib/ebook_chm_encoding.cpp new file mode 100644 index 0000000..f3a30a3 --- /dev/null +++ b/generators/chm/lib/ebook_chm_encoding.cpp @@ -0,0 +1,141 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ebook_chm_encoding.h" + +typedef struct { + const char *qtcodec; + const short *lcids; +} EbookChmTextEncodingEntry; + +// Do not try to embed those in the text_encoding_table, it does not work - at least with gcc. +static short lcid_arabic[] = { + 0x1401, 0x3C01, 0x0C01, 0x0801, 0x2C01, 0x3401, 0x3001, 0x1001, 0x1801, 0x2001, 0x4001, 0x0401, 0x2801, 0x1C01, 0x3801, 0x2401, 0x0429, 0x0420, 0, +}; + +static short lcid_baltic[] = {0x0425, 0x0426, 0x0427, 0}; + +static short lcid_centralEuropean[] = {0x041C, 0x041A, 0x0405, 0x040E, 0x0415, 0x0418, 0x081A, 0x041B, 0x0424, 0}; + +static short lcid_ChineseSimplifiedGB18030[] = {0x0804, 0}; + +static short lcid_ChineseSimplifiedGBK[] = {0x0804, 0}; + +static short lcid_ChineseSimplifiedGB2313[] = {0x1004, 0}; + +static short lcid_ChineseTraditionalBig5[] = {0x0404, 0x1404, 0}; + +static short lcid_ChineseTraditionalBigHKSCS[] = {0x0C04, 0}; + +static short lcid_CyrillicCP1251[] = {0x082C, 0x0423, 0x0402, 0x042F, 0x0419, 0x0C1A, 0x0444, 0x0422, 0x0843, 0}; + +static short lcid_CyrillicKOI8R[] = {0x7001, // artifical LCID + 0}; + +static short lcid_Greek[] = {0x0408, 0}; + +static short lcid_Hebrew[] = {0x040D, 0}; + +static short lcid_Japanese_eucJP[] = {0x0411, 0}; + +static short lcid_Japanese_JIS7[] = {0x0411, 0}; + +static short lcid_Japanese_ShiftJIS[] = {0x0411, 0}; + +static short lcid_Korean_eucKR[] = {0x0412, 0}; + +static short lcid_TamilTSCII[] = {0x0449, 0}; + +static short lcid_ThaiTIS[] = {0x041E, 0}; + +static short lcid_UkrainianKOI[] = {0x7006, 0}; + +static short lcid_Turkish[] = {0x042C, 0x041F, 0x0443, 0}; + +static short lcid_Vietnamese[] = {0x042A, 0}; + +static short lcid_UnicodeUTF8[] = {0x7004, // artifical LCID + 0}; + +static short lcid_UnicodeUTF16[] = {0x7005, // artifical LCID + 0}; + +static short lcid_Western[] = {0x0436, 0x042D, 0x0403, 0x0406, 0x0813, 0x0413, 0x0C09, 0x2809, 0x1009, 0x2409, 0x1809, 0x2009, 0x1409, 0x3409, 0x1C09, 0x2C09, 0x0809, 0x0409, 0x0438, 0x040B, 0x080C, 0x0C0C, 0x040C, 0x140C, 0x100C, + 0x0C07, 0x0407, 0x1407, 0x1007, 0x0807, 0x040F, 0x0421, 0x0410, 0x0810, 0x083E, 0x043E, 0x0414, 0x0814, 0x0416, 0x0816, 0x0432, 0x2C0A, 0x400A, 0x340A, 0x240A, 0x140A, 0x1C0A, 0x300A, 0x440A, 0x100A, + 0x480A, 0x080A, 0x4C0A, 0x180A, 0x3C0A, 0x280A, 0x500A, 0x0C0A, 0x380A, 0x200A, 0x0441, 0x081D, 0x041D, 0x0434, 0x0435, 0x042B, 0x042C, 0x0439, 0x043A, 0x044E, 0x044F, 0x081A, 0x0443, 0}; + +static const EbookChmTextEncodingEntry text_encoding_table[] = {{"CP1256", lcid_arabic}, + + {"CP1257", lcid_baltic}, + + {"CP1250", lcid_centralEuropean}, + + {"GB18030", lcid_ChineseSimplifiedGB18030}, + + {"GBK", lcid_ChineseSimplifiedGBK}, + + {"GB2313", lcid_ChineseSimplifiedGB2313}, + + {"Big5", lcid_ChineseTraditionalBig5}, + + {"Big5-HKSCS", lcid_ChineseTraditionalBigHKSCS}, + + {"CP1251", lcid_CyrillicCP1251}, + + {"KOI8-R", lcid_CyrillicKOI8R}, + + {"CP1253", lcid_Greek}, + + {"CP1255", lcid_Hebrew}, + + {"Shift-JIS", lcid_Japanese_ShiftJIS}, + + {"eucJP", lcid_Japanese_eucJP}, + + {"JIS7", lcid_Japanese_JIS7}, + + {"eucKR", lcid_Korean_eucKR}, + + {"TSCII", lcid_TamilTSCII}, + + {"TIS-620", lcid_ThaiTIS}, + + {"KOI8-U", lcid_UkrainianKOI}, + + {"CP1254", lcid_Turkish}, + + {"CP1258", lcid_Vietnamese}, + + {"UTF-8", lcid_UnicodeUTF8}, + + {"UTF-16", lcid_UnicodeUTF16}, + + {"CP1252", lcid_Western}, + + {nullptr, nullptr}}; + +QString Ebook_CHM_Encoding::guessByLCID(unsigned short lcid) +{ + for (const EbookChmTextEncodingEntry *t = text_encoding_table; t->qtcodec; ++t) { + for (const short *lcids = t->lcids; *lcids; lcids++) + if (*lcids == lcid) + return t->qtcodec; + } + + return QStringLiteral("UTF-8"); +} diff --git a/generators/chm/lib/ebook_chm_encoding.h b/generators/chm/lib/ebook_chm_encoding.h new file mode 100644 index 0000000..701ed45 --- /dev/null +++ b/generators/chm/lib/ebook_chm_encoding.h @@ -0,0 +1,30 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_CHM_ENCODING_H +#define EBOOK_CHM_ENCODING_H + +#include + +class Ebook_CHM_Encoding +{ +public: + static QString guessByLCID(unsigned short lcid); +}; + +#endif // EBOOK_CHM_ENCODING_H diff --git a/generators/chm/lib/ebook_epub.cpp b/generators/chm/lib/ebook_epub.cpp new file mode 100644 index 0000000..06d52ba --- /dev/null +++ b/generators/chm/lib/ebook_epub.cpp @@ -0,0 +1,358 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if defined(WIN32) +#include // dup +#else +#include +#endif + +#include +#include +#include + +#include "ebook_epub.h" +#include "helperxmlhandler_epubcontainer.h" +#include "helperxmlhandler_epubcontent.h" +#include "helperxmlhandler_epubtoc.h" + +static const char *URL_SCHEME_EPUB = "epub"; + +EBook_EPUB::EBook_EPUB() + : EBook() +{ + m_zipFile = nullptr; +} + +EBook_EPUB::~EBook_EPUB() +{ + close(); +} + +bool EBook_EPUB::load(const QString &archiveName) +{ + close(); + + // We use QFile and zip_fdopen instead of zip_open because latter does not support Unicode file names + m_epubFile.setFileName(archiveName); + + if (!m_epubFile.open(QIODevice::ReadOnly)) { + qWarning("Could not open file %s: %s", qPrintable(archiveName), qPrintable(m_epubFile.errorString())); + return false; + } + + // Open the ZIP archive: http://www.nih.at/libzip/zip_fdopen.html + // Note that zip_fdopen takes control over the passed descriptor, + // so we need to pass a duplicate of it for this to work correctly + int fdcopy = dup(m_epubFile.handle()); + + if (fdcopy < 0) { + qWarning("Could not duplicate descriptor"); + return false; + } + + int errcode; + m_zipFile = zip_fdopen(fdcopy, 0, &errcode); + + if (!m_zipFile) { + qWarning("Could not open file %s: error %d", qPrintable(archiveName), errcode); + return false; + } + + // Parse the book descriptor file + if (!parseBookinfo()) + return false; + + return true; +} + +void EBook_EPUB::close() +{ + if (m_zipFile) { + zip_close(m_zipFile); + m_zipFile = nullptr; + } + + // if ( m_epubFile.isOpen() ) + // m_epubFile.close(); +} + +bool EBook_EPUB::getFileContentAsString(QString &str, const QUrl &url) const +{ + return getFileAsString(str, urlToPath(url)); +} + +bool EBook_EPUB::getFileContentAsBinary(QByteArray &data, const QUrl &url) const +{ + return getFileAsBinary(data, urlToPath(url)); +} + +bool EBook_EPUB::enumerateFiles(QList &files) +{ + files = m_ebookManifest; + return true; +} + +QString EBook_EPUB::title() const +{ + return m_title; +} + +QUrl EBook_EPUB::homeUrl() const +{ + return m_tocEntries[0].url; +} + +bool EBook_EPUB::hasFeature(EBook::Feature code) const +{ + switch (code) { + case FEATURE_TOC: + return true; + + case FEATURE_INDEX: + return false; + + case FEATURE_ENCODING: + return false; + } + + return false; +} + +bool EBook_EPUB::getTableOfContents(QList &toc) const +{ + toc = m_tocEntries; + return true; +} + +bool EBook_EPUB::getIndex(QList &) const +{ + return false; +} + +QString EBook_EPUB::getTopicByUrl(const QUrl &url) +{ + if (m_urlTitleMap.contains(url)) + return m_urlTitleMap[url]; + + return QLatin1String(""); +} + +QString EBook_EPUB::currentEncoding() const +{ + return QStringLiteral("UTF-8"); +} + +bool EBook_EPUB::setCurrentEncoding(const char *) +{ + abort(); +} + +bool EBook_EPUB::isSupportedUrl(const QUrl &url) +{ + return url.scheme() == URL_SCHEME_EPUB; +} + +bool EBook_EPUB::parseXML(const QString &uri, QXmlDefaultHandler *parser) +{ + QByteArray container; + + if (!getFileAsBinary(container, uri)) { + qDebug("Failed to retrieve XML file %s", qPrintable(uri)); + return false; + } + + // Use it as XML source + QXmlInputSource source; + source.setData(container); + + // Init the reader + QXmlSimpleReader reader; + reader.setContentHandler(parser); + reader.setErrorHandler(parser); + + return reader.parse(source); +} + +bool EBook_EPUB::parseBookinfo() +{ + // Parse the container.xml to find the content descriptor + HelperXmlHandler_EpubContainer container_parser; + + if (!parseXML(QStringLiteral("META-INF/container.xml"), &container_parser) || container_parser.contentPath.isEmpty()) + return false; + + // Parse the content.opf + HelperXmlHandler_EpubContent content_parser; + + if (!parseXML(container_parser.contentPath, &content_parser)) + return false; + + // At least title and the TOC must be present + if (!content_parser.metadata.contains(QStringLiteral("title")) || content_parser.tocname.isEmpty()) + return false; + + // All the files, including TOC, are relative to the container_parser.contentPath + m_documentRoot.clear(); + int sep = container_parser.contentPath.lastIndexOf('/'); + + if (sep != -1) + m_documentRoot = container_parser.contentPath.left(sep + 1); // Keep the trailing slash + + // Parse the TOC + HelperXmlHandler_EpubTOC toc_parser(this); + + if (!parseXML(content_parser.tocname, &toc_parser)) + return false; + + // Get the data + m_title = content_parser.metadata[QStringLiteral("title")]; + + // Move the manifest entries into the list + for (const QString &f : qAsConst(content_parser.manifest)) + m_ebookManifest.push_back(pathToUrl(f)); + + // Copy the manifest information and fill up the other maps if we have it + if (!toc_parser.entries.isEmpty()) { + for (const EBookTocEntry &e : qAsConst(toc_parser.entries)) { + // Add into url-title map + m_urlTitleMap[e.url] = e.name; + m_tocEntries.push_back(e); + } + } else { + // Copy them from spine + for (QString url : qAsConst(content_parser.spine)) { + EBookTocEntry e; + + if (content_parser.manifest.contains(url)) + url = content_parser.manifest[url]; + + e.name = url; + e.url = pathToUrl(url); + e.iconid = EBookTocEntry::IMAGE_NONE; + e.indent = 0; + + // Add into url-title map + m_urlTitleMap[pathToUrl(url)] = url; + m_tocEntries.push_back(e); + } + } + + // EPub with an empty TOC is not valid + if (m_tocEntries.isEmpty()) + return false; + + return true; +} + +QUrl EBook_EPUB::pathToUrl(const QString &link) const +{ + QUrl url; + url.setScheme(URL_SCHEME_EPUB); + url.setHost(URL_SCHEME_EPUB); + + // Does the link contain the fragment as well? + int off = link.indexOf('#'); + QString path; + + if (off != -1) { + path = link.left(off); + url.setFragment(link.mid(off + 1)); + } else + path = link; + + if (!path.startsWith('/')) + path.prepend('/'); + + url.setPath(QUrl::fromPercentEncoding(path.toUtf8())); + + return url; +} + +QString EBook_EPUB::urlToPath(const QUrl &link) const +{ + if (link.scheme() == URL_SCHEME_EPUB) + return link.path(); + + return QLatin1String(""); +} + +bool EBook_EPUB::getFileAsString(QString &str, const QString &path) const +{ + QByteArray data; + + if (!getFileAsBinary(data, path)) + return false; + + // I have never seen yet an UTF16 epub + if (data.startsWith(""); + int utf16 = data.indexOf("UTF-16"); + + if (utf16 > 0 && utf16 < endxmltag) { + QMessageBox::critical(nullptr, i18n("Unsupported encoding"), i18n("The encoding of this ebook is not supported yet. Please open a bug in https://bugs.kde.org for support to be added")); + return false; + } + } + + str = QString::fromUtf8(data); + return true; +} + +bool EBook_EPUB::getFileAsBinary(QByteArray &data, const QString &path) const +{ + // Retrieve the file size + struct zip_stat fileinfo; + QString completeUrl; + + if (!path.isEmpty() && path[0] == '/') + completeUrl = m_documentRoot + path.mid(1); + else + completeUrl = m_documentRoot + path; + + // qDebug("URL requested: %s (%s)", qPrintable(path), qPrintable(completeUrl)); + + // http://www.nih.at/libzip/zip_stat.html + if (zip_stat(m_zipFile, completeUrl.toUtf8().constData(), 0, &fileinfo) != 0) { + qDebug("File %s is not found in the archive", qPrintable(completeUrl)); + return false; + } + + // Make sure the size field is valid + if ((fileinfo.valid & ZIP_STAT_SIZE) == 0 || (fileinfo.valid & ZIP_STAT_INDEX) == 0) + return false; + + // Open the file + struct zip_file *file = zip_fopen_index(m_zipFile, fileinfo.index, 0); + + if (!file) + return false; + + // Allocate the memory and read the file + data.resize(fileinfo.size); + + // Could it return a positive number but not fileinfo.size??? + int ret = zip_fread(file, data.data(), fileinfo.size); + if (ret != (int)fileinfo.size) { + zip_fclose(file); + return false; + } + + zip_fclose(file); + return true; +} diff --git a/generators/chm/lib/ebook_epub.h b/generators/chm/lib/ebook_epub.h new file mode 100644 index 0000000..c883455 --- /dev/null +++ b/generators/chm/lib/ebook_epub.h @@ -0,0 +1,205 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_EPUB_H +#define EBOOK_EPUB_H + +#include +#include +#include +#include +#include + +#include "ebook.h" +#include "zip.h" + +class QXmlDefaultHandler; + +class EBook_EPUB : public EBook +{ +public: + EBook_EPUB(); + ~EBook_EPUB() override; + + /*! + * \brief Attempts to load epub file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a epub file. + * \ingroup init + */ + bool load(const QString &archiveName) override; + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + void close() override; + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + QString title() const override; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + QUrl homeUrl() const override; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + bool hasFeature(Feature code) const override; + + /*! + * \brief Parses and fills up the Table of Contents (TOC) + * \param topics A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + bool getTableOfContents(QList &toc) const override; + + /*! + * \brief Parses the index table + * \param indexes A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy chm file; so far it never happened on indexes. + * \ingroup fileparsing + */ + bool getIndex(QList &index) const override; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as QString. + * \param str A string where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + bool getFileContentAsString(QString &str, const QUrl &url) const override; + + /*! + * \brief Retrieves the content from url in current chm file to QByteArray. + * \param data A data array where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. + * + * This function retreives the file content from the chm archive opened by load() + * function. The content is not encoded. + * + * \sa getFileContentAsString() + * \ingroup dataretrieve + */ + bool getFileContentAsBinary(QByteArray &data, const QUrl &url) const override; + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \param files An array to store list of URLs (file names) present in chm archive. + * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason). + * + * \ingroup dataretrieve + */ + bool enumerateFiles(QList &files) override; + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook file to get title from. Must be absolute. + * \return The title, or QString() if the URL cannot be found or not a HTML page. + * + * \ingroup dataretrieve + */ + QString getTopicByUrl(const QUrl &url) override; + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec + * \return The current encoding. + * + * \ingroup encoding + */ + QString currentEncoding() const override; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + bool setCurrentEncoding(const char *encoding) override; + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + bool isSupportedUrl(const QUrl &url) override; + + // Converts the string to the ebook-specific URL format + QUrl pathToUrl(const QString &link) const override; + + // Extracts the path component from the URL + QString urlToPath(const QUrl &link) const override; + +private: + // Parses the XML file using a specified parser + bool parseXML(const QString &uri, QXmlDefaultHandler *parser); + + // Parses the book description file. Fills up the ebook info + bool parseBookinfo(); + + // Get file content from path + bool getFileAsString(QString &str, const QString &path) const; + bool getFileAsBinary(QByteArray &data, const QString &path) const; + + // ZIP archive fd and structs + QFile m_epubFile; + struct zip *m_zipFile; + + // Ebook info + QString m_title; + QString m_documentRoot; + + // List of files in the ebook + QList m_ebookManifest; + + // Table of contents + QList m_tocEntries; + + // Map of URL-Title + QMap m_urlTitleMap; +}; + +#endif // EBOOK_EPUB_H diff --git a/generators/chm/lib/ebook_search.cpp b/generators/chm/lib/ebook_search.cpp new file mode 100644 index 0000000..2b81965 --- /dev/null +++ b/generators/chm/lib/ebook_search.cpp @@ -0,0 +1,215 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "ebook.h" +#include "ebook_search.h" + +// Helper class to simplicity state management and data keeping +class SearchDataKeeper +{ +public: + SearchDataKeeper() + { + m_inPhrase = false; + } + + void beginPhrase() + { + phrase_terms.clear(); + m_inPhrase = true; + } + + void endPhrase() + { + m_inPhrase = false; + phrasewords += phrase_terms; + phrases.push_back(phrase_terms.join(QStringLiteral(" "))); + } + + bool isInPhrase() const + { + return m_inPhrase; + } + + void addTerm(const QString &term) + { + if (!term.isEmpty()) { + terms.push_back(term); + + if (m_inPhrase) + phrase_terms.push_back(term); + } + } + + // Should contain all the search terms present in query, includind those from phrases. One element - one term . + QStringList terms; + + // Should contain phrases present in query without quotes. One element - one phrase. + QStringList phrases; + + // Should contain all the terms present in all the phrases (but not outside). + QStringList phrasewords; + +private: + bool m_inPhrase; + QStringList phrase_terms; +}; + +EBookSearch::EBookSearch() +{ + m_Index = nullptr; +} + +EBookSearch::~EBookSearch() +{ + delete m_Index; +} + +bool EBookSearch::loadIndex(QDataStream &stream) +{ + delete m_Index; + + m_Index = new QtAs::Index(); + return m_Index->readDict(stream); +} + +bool EBookSearch::generateIndex(EBook *ebookFile, QDataStream &stream) +{ + QList documents; + QList alldocuments; + + emit progressStep(0, QStringLiteral("Generating the list of documents")); + processEvents(); + + // Enumerate the documents + if (!ebookFile->enumerateFiles(alldocuments)) + return false; + + if (m_Index) + delete m_Index; + + m_Index = new QtAs::Index(); + connect(m_Index, &QtAs::Index::indexingProgress, this, &EBookSearch::updateProgress); + + // Process the list of files in CHM archive and keep only HTML document files from there + for (const QUrl &allDocumentsI : qAsConst(alldocuments)) { + const QString docpath = allDocumentsI.path(); + + if (docpath.endsWith(QLatin1String(".html"), Qt::CaseInsensitive) || docpath.endsWith(QLatin1String(".htm"), Qt::CaseInsensitive) || docpath.endsWith(QLatin1String(".xhtml"), Qt::CaseInsensitive)) + documents.push_back(allDocumentsI); + } + + if (!m_Index->makeIndex(documents, ebookFile)) { + delete m_Index; + m_Index = nullptr; + return false; + } + + m_Index->writeDict(stream); + m_keywordDocuments.clear(); + + return true; +} + +void EBookSearch::cancelIndexGeneration() +{ + m_Index->setLastWinClosed(); +} + +void EBookSearch::updateProgress(int value, const QString &stepName) +{ + emit progressStep(value, stepName); +} + +void EBookSearch::processEvents() +{ + // Do it up to ten times; some events generate other events + for (int i = 0; i < 10; i++) + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +bool EBookSearch::searchQuery(const QString &query, QList *results, EBook *ebookFile, unsigned int limit) +{ + // We should have index + if (!m_Index) + return false; + + // Characters which split the words. We need to make them separate tokens + QString splitChars = m_Index->getCharsSplit(); + + // Characters which are part of the word. We should keep them apart. + QString partOfWordChars = m_Index->getCharsPartOfWord(); + + // Variables to store current state + SearchDataKeeper keeper; + QString term; + + for (const QChar &iChar : query) { + const QChar ch = iChar.toLower(); + + // a quote either begins or ends the phrase + if (ch == '"') { + keeper.addTerm(term); + + if (keeper.isInPhrase()) + keeper.endPhrase(); + else + keeper.beginPhrase(); + + continue; + } + + // If new char does not stop the word, add ot and continue + if (ch.isLetterOrNumber() || partOfWordChars.indexOf(ch) != -1) { + term.append(ch); + continue; + } + + // If it is a split char, add this term and split char as separate term + if (splitChars.indexOf(ch) != -1) { + // Add existing term if present + keeper.addTerm(term); + + // Change the term variable, so it will be added when we exit this block + term = ch; + } + + // Just add the word; it is most likely a space or terminated by tokenizer. + keeper.addTerm(term); + term = QString(); + } + + keeper.addTerm(term); + + if (keeper.isInPhrase()) + return false; + + QList foundDocs = m_Index->query(keeper.terms, keeper.phrases, keeper.phrasewords, ebookFile); + + for (QList::iterator it = foundDocs.begin(); it != foundDocs.end() && limit > 0; ++it, limit--) + results->push_back(*it); + + return true; +} + +bool EBookSearch::hasIndex() const +{ + return m_Index != nullptr; +} diff --git a/generators/chm/lib/ebook_search.h b/generators/chm/lib/ebook_search.h new file mode 100644 index 0000000..819fbba --- /dev/null +++ b/generators/chm/lib/ebook_search.h @@ -0,0 +1,83 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBookSearch_H +#define EBookSearch_H + +#include "helper_search_index.h" +#include + +class EBook; + +class EBookSearch : public QObject +{ + Q_OBJECT + +public: + EBookSearch(); + ~EBookSearch() override; + + //! Loads the search index from the data stream \param stream. + //! The index should be previously saved with generateIndex(). + bool loadIndex(QDataStream &stream); + + //! Generates the search index from the opened CHM file \param chmFile, + //! and saves it to the data stream \param stream which should be writeable. + //! + //! To show the progress, this procedure emits a progressStep() signal periodically + //! with the value showing current progress in percentage (i.e. from 0 to 100) + //! After signal emission, the following event processing function will be called: + //! qApp->processEvents( QEventLoop::ExcludeUserInputEvents ) + //! to make sure the dialogs (if any) are properly updated. + //! + //! If \param progressDls is not null, it will be used to display progress. + //! Returns true if the index has been generated and saved, or false if internal + //! error occurs, or (most likely) the cancelIndexGeneration() slot has been called. + bool generateIndex(EBook *ebook, QDataStream &stream); + + //! Executes the search query. The \param query is a string like "C++ language" class, + //! \param results is a pointer to QStringList, and \param limit limits the number of + //! results in case the query is too generic (like \a "a" ). + //! The \param ebookFile is used to get the current encoding information. + //! The return value is false only if the index is not generated, or if a closing quote character + //! is missing. Call hasIndex() to clarify. If search returns no results, the return value is + //! true, but the \param results list will be empty. + //! + //! Note that the function does not clear \param results before adding search results, so if you are + //! not merging search results, make sure it's empty. + bool searchQuery(const QString &query, QList *results, EBook *ebookFile, unsigned int limit = 100); + + //! Returns true if a valid search index is present, and therefore search could be executed + bool hasIndex() const; + +signals: + void progressStep(int value, const QString &stepName); + +public slots: + void cancelIndexGeneration(); + +private slots: + void updateProgress(int value, const QString &stepName); + void processEvents(); + +private: + QStringList m_keywordDocuments; + QtAs::Index *m_Index; +}; + +#endif diff --git a/generators/chm/lib/ebook_url.h b/generators/chm/lib/ebook_url.h new file mode 100644 index 0000000..1ed1b78 --- /dev/null +++ b/generators/chm/lib/ebook_url.h @@ -0,0 +1,13 @@ +#ifndef EBOOK_URL_H +#define EBOOK_URL_H + +#include + +class EbookURL : public QUrl +{ +public: + EbookURL(); + EbookURL(const QString &url); +}; + +#endif // EBOOK_URL_H diff --git a/generators/chm/lib/helper_entitydecoder.cpp b/generators/chm/lib/helper_entitydecoder.cpp new file mode 100644 index 0000000..a81384f --- /dev/null +++ b/generators/chm/lib/helper_entitydecoder.cpp @@ -0,0 +1,222 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "helper_entitydecoder.h" + +HelperEntityDecoder::HelperEntityDecoder(QTextCodec *encoder) +{ + changeEncoding(encoder); +} + +static inline QString encodeWithCodec(QTextCodec *encoder, const QByteArray &str) +{ + return (encoder ? encoder->toUnicode(str.constData()) : str); +} + +void HelperEntityDecoder::changeEncoding(QTextCodec *encoder) +{ + // Set up m_entityDecodeMap characters according to current textCodec + m_entityDecodeMap.clear(); + + m_entityDecodeMap[QStringLiteral("AElig")] = encodeWithCodec(encoder, "\306"); // capital AE diphthong (ligature) + m_entityDecodeMap[QStringLiteral("Aacute")] = encodeWithCodec(encoder, "\301"); // capital A, acute accent + m_entityDecodeMap[QStringLiteral("Acirc")] = encodeWithCodec(encoder, "\302"); // capital A, circumflex accent + m_entityDecodeMap[QStringLiteral("Agrave")] = encodeWithCodec(encoder, "\300"); // capital A, grave accent + m_entityDecodeMap[QStringLiteral("Aring")] = encodeWithCodec(encoder, "\305"); // capital A, ring + m_entityDecodeMap[QStringLiteral("Atilde")] = encodeWithCodec(encoder, "\303"); // capital A, tilde + m_entityDecodeMap[QStringLiteral("Auml")] = encodeWithCodec(encoder, "\304"); // capital A, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("Ccedil")] = encodeWithCodec(encoder, "\307"); // capital C, cedilla + m_entityDecodeMap[QStringLiteral("Dstrok")] = encodeWithCodec(encoder, "\320"); // whatever + m_entityDecodeMap[QStringLiteral("ETH")] = encodeWithCodec(encoder, "\320"); // capital Eth, Icelandic + m_entityDecodeMap[QStringLiteral("Eacute")] = encodeWithCodec(encoder, "\311"); // capital E, acute accent + m_entityDecodeMap[QStringLiteral("Ecirc")] = encodeWithCodec(encoder, "\312"); // capital E, circumflex accent + m_entityDecodeMap[QStringLiteral("Egrave")] = encodeWithCodec(encoder, "\310"); // capital E, grave accent + m_entityDecodeMap[QStringLiteral("Euml")] = encodeWithCodec(encoder, "\313"); // capital E, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("Iacute")] = encodeWithCodec(encoder, "\315"); // capital I, acute accent + m_entityDecodeMap[QStringLiteral("Icirc")] = encodeWithCodec(encoder, "\316"); // capital I, circumflex accent + m_entityDecodeMap[QStringLiteral("Igrave")] = encodeWithCodec(encoder, "\314"); // capital I, grave accent + m_entityDecodeMap[QStringLiteral("Iuml")] = encodeWithCodec(encoder, "\317"); // capital I, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("Ntilde")] = encodeWithCodec(encoder, "\321"); // capital N, tilde + m_entityDecodeMap[QStringLiteral("Oacute")] = encodeWithCodec(encoder, "\323"); // capital O, acute accent + m_entityDecodeMap[QStringLiteral("Ocirc")] = encodeWithCodec(encoder, "\324"); // capital O, circumflex accent + m_entityDecodeMap[QStringLiteral("Ograve")] = encodeWithCodec(encoder, "\322"); // capital O, grave accent + m_entityDecodeMap[QStringLiteral("Oslash")] = encodeWithCodec(encoder, "\330"); // capital O, slash + m_entityDecodeMap[QStringLiteral("Otilde")] = encodeWithCodec(encoder, "\325"); // capital O, tilde + m_entityDecodeMap[QStringLiteral("Ouml")] = encodeWithCodec(encoder, "\326"); // capital O, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("THORN")] = encodeWithCodec(encoder, "\336"); // capital THORN, Icelandic + m_entityDecodeMap[QStringLiteral("Uacute")] = encodeWithCodec(encoder, "\332"); // capital U, acute accent + m_entityDecodeMap[QStringLiteral("Ucirc")] = encodeWithCodec(encoder, "\333"); // capital U, circumflex accent + m_entityDecodeMap[QStringLiteral("Ugrave")] = encodeWithCodec(encoder, "\331"); // capital U, grave accent + m_entityDecodeMap[QStringLiteral("Uuml")] = encodeWithCodec(encoder, "\334"); // capital U, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("Yacute")] = encodeWithCodec(encoder, "\335"); // capital Y, acute accent + m_entityDecodeMap[QStringLiteral("OElig")] = encodeWithCodec(encoder, "\338"); // capital Y, acute accent + m_entityDecodeMap[QStringLiteral("oelig")] = encodeWithCodec(encoder, "\339"); // capital Y, acute accent + + m_entityDecodeMap[QStringLiteral("aacute")] = encodeWithCodec(encoder, "\341"); // small a, acute accent + m_entityDecodeMap[QStringLiteral("acirc")] = encodeWithCodec(encoder, "\342"); // small a, circumflex accent + m_entityDecodeMap[QStringLiteral("aelig")] = encodeWithCodec(encoder, "\346"); // small ae diphthong (ligature) + m_entityDecodeMap[QStringLiteral("agrave")] = encodeWithCodec(encoder, "\340"); // small a, grave accent + m_entityDecodeMap[QStringLiteral("aring")] = encodeWithCodec(encoder, "\345"); // small a, ring + m_entityDecodeMap[QStringLiteral("atilde")] = encodeWithCodec(encoder, "\343"); // small a, tilde + m_entityDecodeMap[QStringLiteral("auml")] = encodeWithCodec(encoder, "\344"); // small a, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("ccedil")] = encodeWithCodec(encoder, "\347"); // small c, cedilla + m_entityDecodeMap[QStringLiteral("eacute")] = encodeWithCodec(encoder, "\351"); // small e, acute accent + m_entityDecodeMap[QStringLiteral("ecirc")] = encodeWithCodec(encoder, "\352"); // small e, circumflex accent + m_entityDecodeMap[QStringLiteral("Scaron")] = encodeWithCodec(encoder, "\352"); // small e, circumflex accent + m_entityDecodeMap[QStringLiteral("egrave")] = encodeWithCodec(encoder, "\350"); // small e, grave accent + m_entityDecodeMap[QStringLiteral("eth")] = encodeWithCodec(encoder, "\360"); // small eth, Icelandic + m_entityDecodeMap[QStringLiteral("euml")] = encodeWithCodec(encoder, "\353"); // small e, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("iacute")] = encodeWithCodec(encoder, "\355"); // small i, acute accent + m_entityDecodeMap[QStringLiteral("icirc")] = encodeWithCodec(encoder, "\356"); // small i, circumflex accent + m_entityDecodeMap[QStringLiteral("igrave")] = encodeWithCodec(encoder, "\354"); // small i, grave accent + m_entityDecodeMap[QStringLiteral("iuml")] = encodeWithCodec(encoder, "\357"); // small i, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("ntilde")] = encodeWithCodec(encoder, "\361"); // small n, tilde + m_entityDecodeMap[QStringLiteral("oacute")] = encodeWithCodec(encoder, "\363"); // small o, acute accent + m_entityDecodeMap[QStringLiteral("ocirc")] = encodeWithCodec(encoder, "\364"); // small o, circumflex accent + m_entityDecodeMap[QStringLiteral("ograve")] = encodeWithCodec(encoder, "\362"); // small o, grave accent + m_entityDecodeMap[QStringLiteral("oslash")] = encodeWithCodec(encoder, "\370"); // small o, slash + m_entityDecodeMap[QStringLiteral("otilde")] = encodeWithCodec(encoder, "\365"); // small o, tilde + m_entityDecodeMap[QStringLiteral("ouml")] = encodeWithCodec(encoder, "\366"); // small o, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("szlig")] = encodeWithCodec(encoder, "\337"); // small sharp s, German (sz ligature) + m_entityDecodeMap[QStringLiteral("thorn")] = encodeWithCodec(encoder, "\376"); // small thorn, Icelandic + m_entityDecodeMap[QStringLiteral("uacute")] = encodeWithCodec(encoder, "\372"); // small u, acute accent + m_entityDecodeMap[QStringLiteral("ucirc")] = encodeWithCodec(encoder, "\373"); // small u, circumflex accent + m_entityDecodeMap[QStringLiteral("ugrave")] = encodeWithCodec(encoder, "\371"); // small u, grave accent + m_entityDecodeMap[QStringLiteral("uuml")] = encodeWithCodec(encoder, "\374"); // small u, dieresis or umlaut mark + m_entityDecodeMap[QStringLiteral("yacute")] = encodeWithCodec(encoder, "\375"); // small y, acute accent + m_entityDecodeMap[QStringLiteral("yuml")] = encodeWithCodec(encoder, "\377"); // small y, dieresis or umlaut mark + + m_entityDecodeMap[QStringLiteral("iexcl")] = encodeWithCodec(encoder, "\241"); + m_entityDecodeMap[QStringLiteral("cent")] = encodeWithCodec(encoder, "\242"); + m_entityDecodeMap[QStringLiteral("pound")] = encodeWithCodec(encoder, "\243"); + m_entityDecodeMap[QStringLiteral("curren")] = encodeWithCodec(encoder, "\244"); + m_entityDecodeMap[QStringLiteral("yen")] = encodeWithCodec(encoder, "\245"); + m_entityDecodeMap[QStringLiteral("brvbar")] = encodeWithCodec(encoder, "\246"); + m_entityDecodeMap[QStringLiteral("sect")] = encodeWithCodec(encoder, "\247"); + m_entityDecodeMap[QStringLiteral("uml")] = encodeWithCodec(encoder, "\250"); + m_entityDecodeMap[QStringLiteral("ordf")] = encodeWithCodec(encoder, "\252"); + m_entityDecodeMap[QStringLiteral("laquo")] = encodeWithCodec(encoder, "\253"); + m_entityDecodeMap[QStringLiteral("not")] = encodeWithCodec(encoder, "\254"); + m_entityDecodeMap[QStringLiteral("shy")] = encodeWithCodec(encoder, "\255"); + m_entityDecodeMap[QStringLiteral("macr")] = encodeWithCodec(encoder, "\257"); + m_entityDecodeMap[QStringLiteral("deg")] = encodeWithCodec(encoder, "\260"); + m_entityDecodeMap[QStringLiteral("plusmn")] = encodeWithCodec(encoder, "\261"); + m_entityDecodeMap[QStringLiteral("sup1")] = encodeWithCodec(encoder, "\271"); + m_entityDecodeMap[QStringLiteral("sup2")] = encodeWithCodec(encoder, "\262"); + m_entityDecodeMap[QStringLiteral("sup3")] = encodeWithCodec(encoder, "\263"); + m_entityDecodeMap[QStringLiteral("acute")] = encodeWithCodec(encoder, "\264"); + m_entityDecodeMap[QStringLiteral("micro")] = encodeWithCodec(encoder, "\265"); + m_entityDecodeMap[QStringLiteral("para")] = encodeWithCodec(encoder, "\266"); + m_entityDecodeMap[QStringLiteral("middot")] = encodeWithCodec(encoder, "\267"); + m_entityDecodeMap[QStringLiteral("cedil")] = encodeWithCodec(encoder, "\270"); + m_entityDecodeMap[QStringLiteral("ordm")] = encodeWithCodec(encoder, "\272"); + m_entityDecodeMap[QStringLiteral("raquo")] = encodeWithCodec(encoder, "\273"); + m_entityDecodeMap[QStringLiteral("frac14")] = encodeWithCodec(encoder, "\274"); + m_entityDecodeMap[QStringLiteral("frac12")] = encodeWithCodec(encoder, "\275"); + m_entityDecodeMap[QStringLiteral("frac34")] = encodeWithCodec(encoder, "\276"); + m_entityDecodeMap[QStringLiteral("iquest")] = encodeWithCodec(encoder, "\277"); + m_entityDecodeMap[QStringLiteral("times")] = encodeWithCodec(encoder, "\327"); + m_entityDecodeMap[QStringLiteral("divide")] = encodeWithCodec(encoder, "\367"); + + m_entityDecodeMap[QStringLiteral("copy")] = encodeWithCodec(encoder, "\251"); // copyright sign + m_entityDecodeMap[QStringLiteral("reg")] = encodeWithCodec(encoder, "\256"); // registered sign + m_entityDecodeMap[QStringLiteral("nbsp")] = encodeWithCodec(encoder, "\240"); // non breaking space + + m_entityDecodeMap[QStringLiteral("fnof")] = QChar((unsigned short)402); + + m_entityDecodeMap[QStringLiteral("Delta")] = QChar((unsigned short)916); + m_entityDecodeMap[QStringLiteral("Pi")] = QChar((unsigned short)928); + m_entityDecodeMap[QStringLiteral("Sigma")] = QChar((unsigned short)931); + + m_entityDecodeMap[QStringLiteral("beta")] = QChar((unsigned short)946); + m_entityDecodeMap[QStringLiteral("gamma")] = QChar((unsigned short)947); + m_entityDecodeMap[QStringLiteral("delta")] = QChar((unsigned short)948); + m_entityDecodeMap[QStringLiteral("eta")] = QChar((unsigned short)951); + m_entityDecodeMap[QStringLiteral("theta")] = QChar((unsigned short)952); + m_entityDecodeMap[QStringLiteral("lambda")] = QChar((unsigned short)955); + m_entityDecodeMap[QStringLiteral("mu")] = QChar((unsigned short)956); + m_entityDecodeMap[QStringLiteral("nu")] = QChar((unsigned short)957); + m_entityDecodeMap[QStringLiteral("pi")] = QChar((unsigned short)960); + m_entityDecodeMap[QStringLiteral("rho")] = QChar((unsigned short)961); + + m_entityDecodeMap[QStringLiteral("lsquo")] = QChar((unsigned short)8216); + m_entityDecodeMap[QStringLiteral("rsquo")] = QChar((unsigned short)8217); + m_entityDecodeMap[QStringLiteral("rdquo")] = QChar((unsigned short)8221); + m_entityDecodeMap[QStringLiteral("bdquo")] = QChar((unsigned short)8222); + m_entityDecodeMap[QStringLiteral("trade")] = QChar((unsigned short)8482); + m_entityDecodeMap[QStringLiteral("ldquo")] = QChar((unsigned short)8220); + m_entityDecodeMap[QStringLiteral("ndash")] = QChar((unsigned short)8211); + m_entityDecodeMap[QStringLiteral("mdash")] = QChar((unsigned short)8212); + m_entityDecodeMap[QStringLiteral("bull")] = QChar((unsigned short)8226); + m_entityDecodeMap[QStringLiteral("hellip")] = QChar((unsigned short)8230); + m_entityDecodeMap[QStringLiteral("emsp")] = QChar((unsigned short)8195); + m_entityDecodeMap[QStringLiteral("rarr")] = QChar((unsigned short)8594); + m_entityDecodeMap[QStringLiteral("rArr")] = QChar((unsigned short)8658); + m_entityDecodeMap[QStringLiteral("crarr")] = QChar((unsigned short)8629); + m_entityDecodeMap[QStringLiteral("le")] = QChar((unsigned short)8804); + m_entityDecodeMap[QStringLiteral("ge")] = QChar((unsigned short)8805); + m_entityDecodeMap[QStringLiteral("lte")] = QChar((unsigned short)8804); // wrong, but used somewhere + m_entityDecodeMap[QStringLiteral("gte")] = QChar((unsigned short)8805); // wrong, but used somewhere + m_entityDecodeMap[QStringLiteral("dagger")] = QChar((unsigned short)8224); + m_entityDecodeMap[QStringLiteral("Dagger")] = QChar((unsigned short)8225); + m_entityDecodeMap[QStringLiteral("euro")] = QChar((unsigned short)8364); + m_entityDecodeMap[QStringLiteral("asymp")] = QChar((unsigned short)8776); + m_entityDecodeMap[QStringLiteral("isin")] = QChar((unsigned short)8712); + m_entityDecodeMap[QStringLiteral("notin")] = QChar((unsigned short)8713); + m_entityDecodeMap[QStringLiteral("prod")] = QChar((unsigned short)8719); + m_entityDecodeMap[QStringLiteral("ne")] = QChar((unsigned short)8800); + + m_entityDecodeMap[QStringLiteral("amp")] = QStringLiteral("&"); // ampersand + m_entityDecodeMap[QStringLiteral("gt")] = QStringLiteral(">"); // greater than + m_entityDecodeMap[QStringLiteral("lt")] = QStringLiteral("<"); // less than + m_entityDecodeMap[QStringLiteral("quot")] = QStringLiteral("\""); // double quote + m_entityDecodeMap[QStringLiteral("apos")] = QStringLiteral("'"); // single quote + m_entityDecodeMap[QStringLiteral("frasl")] = QStringLiteral("/"); + m_entityDecodeMap[QStringLiteral("minus")] = QStringLiteral("-"); + m_entityDecodeMap[QStringLiteral("oplus")] = QStringLiteral("+"); + m_entityDecodeMap[QStringLiteral("Prime")] = QStringLiteral("\""); +} + +QString HelperEntityDecoder::decode(const QString &entity) const +{ + // If entity is an ASCII code like 〽 - just decode it + if (entity.isEmpty()) { + return QLatin1String(""); + } else if (entity[0] == '#') { + bool valid; + unsigned int ascode = entity.midRef(1).toUInt(&valid); + + if (!valid) { + qWarning("HelperEntityDecoder::decode: could not decode HTML entity '%s'", qPrintable(entity)); + return QString(); + } + + return (QString)(QChar(ascode)); + } else { + QMap::const_iterator it = m_entityDecodeMap.find(entity); + + if (it == m_entityDecodeMap.end()) { + qWarning("HelperEntityDecoder::decode: could not decode HTML entity '%s'", qPrintable(entity)); + return QLatin1String(""); + } + + return *it; + } +} diff --git a/generators/chm/lib/helper_entitydecoder.h b/generators/chm/lib/helper_entitydecoder.h new file mode 100644 index 0000000..6a4c3ed --- /dev/null +++ b/generators/chm/lib/helper_entitydecoder.h @@ -0,0 +1,45 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPER_ENTITYDECODER_H +#define HELPER_ENTITYDECODER_H + +#include +#include + +// +// This helper class decodes the Unicode HTML entities into the Unicode characters +// +class HelperEntityDecoder +{ +public: + // Initialization with the specific decoder + HelperEntityDecoder(QTextCodec *encoder = nullptr); + + // Used when the encoding changes + void changeEncoding(QTextCodec *encoder = nullptr); + + // The decoder function + QString decode(const QString &entity) const; + +private: + // Map to decode HTML entitles like ´ based on current encoding, initialized upon the first use + QMap m_entityDecodeMap; +}; + +#endif // HELPER_ENTITYDECODER_H diff --git a/generators/chm/lib/helper_search_index.cpp b/generators/chm/lib/helper_search_index.cpp new file mode 100644 index 0000000..cac832c --- /dev/null +++ b/generators/chm/lib/helper_search_index.cpp @@ -0,0 +1,448 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "ebook.h" +#include "ebook_search.h" +#include "helper_search_index.h" + +static const int DICT_VERSION = 4; + +namespace QtAs +{ +// Those characters are splitters (i.e. split the word), but added themselves into dictionary too. +// This makes the dictionary MUCH larger, but ensure that for the piece of "window->print" both +// search for "print" and "->print" will find it. +static const char SPLIT_CHARACTERS[] = "!()*&^%#@[]{}':;,.?/|/?<>\\-+=~`"; + +// Those characters are parts of word - for example, '_' is here, and search for _debug will find only _debug. +static const char WORD_CHARACTERS[] = "$_"; + +struct Term { + Term() + : frequency(-1) + { + } + Term(const QString &t, int f, const QVector &l) + : term(t) + , frequency(f) + , documents(l) + { + } + QString term; + int frequency; + QVector documents; + bool operator<(const Term &i2) const + { + return frequency < i2.frequency; + } +}; + +QDataStream &operator>>(QDataStream &s, Document &l) +{ + s >> l.docNumber; + s >> l.frequency; + return s; +} + +QDataStream &operator<<(QDataStream &s, const Document l) +{ + s << (short)l.docNumber; + s << (short)l.frequency; + return s; +} + +Index::Index() + : QObject(nullptr) +{ + lastWindowClosed = false; + connect(qApp, &QGuiApplication::lastWindowClosed, this, &Index::setLastWinClosed); +} + +void Index::setLastWinClosed() +{ + lastWindowClosed = true; +} + +bool Index::makeIndex(const QList &docs, EBook *chmFile) +{ + if (docs.isEmpty()) + return false; + + docList = docs; + + if (chmFile->hasFeature(EBook::FEATURE_ENCODING)) + entityDecoder.changeEncoding(QTextCodec::codecForName(chmFile->currentEncoding().toUtf8())); + + QList::ConstIterator it = docList.constBegin(); + int steps = docList.count() / 100; + + if (!steps) + steps++; + + int prog = 0; + + for (int i = 0; it != docList.constEnd(); ++it, ++i) { + if (lastWindowClosed) + return false; + + QUrl filename = *it; + QStringList terms; + + if (parseDocumentToStringlist(chmFile, filename, terms)) { + for (QStringList::ConstIterator tit = terms.constBegin(); tit != terms.constEnd(); ++tit) + insertInDict(*tit, i); + } + + if (i % steps == 0) { + prog++; + prog = qMin(prog, 99); + emit indexingProgress(prog, tr("Processing document %1").arg((*it).path())); + } + } + + emit indexingProgress(100, tr("Processing completed")); + return true; +} + +void Index::insertInDict(const QString &str, int docNum) +{ + Entry *e = nullptr; + if (!dict.isEmpty()) + e = dict[str]; + + if (e) { + if (e->documents.last().docNumber != docNum) + e->documents.append(Document(docNum, 1)); + else + e->documents.last().frequency++; + } else { + dict.insert(str, new Entry(docNum)); + } +} + +bool Index::parseDocumentToStringlist(EBook *chmFile, const QUrl &filename, QStringList &tokenlist) +{ + QString parsedbuf, parseentity, text; + + if (!chmFile->getFileContentAsString(text, filename) || text.isEmpty()) { + qWarning("Search index generator: could not retrieve the document content for %s", qPrintable(filename.toString())); + return false; + } + + m_charssplit = SPLIT_CHARACTERS; + m_charsword = WORD_CHARACTERS; + + tokenlist.clear(); + + // State machine states + enum state_t { + STATE_OUTSIDE_TAGS, // outside HTML tags; parse text + STATE_IN_HTML_TAG, // inside HTML tags; wait for end tag + STATE_IN_QUOTES, // inside HTML tags and inside quotes; wait for end quote (in var QuoteChar) + STATE_IN_HTML_ENTITY // inside HTML entity; parse the entity + }; + + state_t state = STATE_OUTSIDE_TAGS; + QChar QuoteChar; // used in STATE_IN_QUOTES + + for (int j = 0; j < text.length(); j++) { + QChar ch = text[j]; + + if ((j % 20000) == 0) + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + + if (state == STATE_IN_HTML_TAG) { + // We are inside HTML tag. + // Ignore everything until we see '>' (end of HTML tag) or quote char (quote start) + if (ch == '"' || ch == '\'') { + state = STATE_IN_QUOTES; + QuoteChar = ch; + } else if (ch == '>') + state = STATE_OUTSIDE_TAGS; + + continue; + } else if (state == STATE_IN_QUOTES) { + // We are inside quoted text inside HTML tag. + // Ignore everything until we see the quote character again + if (ch == QuoteChar) + state = STATE_IN_HTML_TAG; + + continue; + } else if (state == STATE_IN_HTML_ENTITY) { + // We are inside encoded HTML entity (like  ). + // Collect to parsedbuf everything until we see ; + if (ch.isLetterOrNumber()) { + // get next character of this entity + parseentity.append(ch); + continue; + } + + // The entity ended + state = STATE_OUTSIDE_TAGS; + + // Some shitty HTML does not terminate entities correctly. Screw it. + if (ch != ';' && ch != '<') { + if (parseentity.isEmpty()) { + // straight '&' symbol. Add and continue. + parsedbuf += QLatin1String("&"); + } else + qWarning("Index::parseDocument: incorrectly terminated HTML entity '&%s%c', ignoring", qPrintable(parseentity), ch.toLatin1()); + + j--; // parse this character again, but in different state + continue; + } + + // Don't we have a space? + if (parseentity.toLower() != QLatin1String("nbsp")) { + QString entity = entityDecoder.decode(parseentity); + + if (entity.isNull()) { + // decodeEntity() already printed error message + // qWarning( "Index::parseDocument: failed to decode entity &%s;", parsedbuf.ascii() ); + continue; + } + + parsedbuf += entity; + continue; + } else + ch = ' '; // We got a space, so treat it like it, and not add it to parsebuf + } + + // + // Now process STATE_OUTSIDE_TAGS + // + + // Check for start of HTML tag, and switch to STATE_IN_HTML_TAG if it is + if (ch == '<') { + state = STATE_IN_HTML_TAG; + goto tokenize_buf; + } + + // Check for start of HTML entity + if (ch == '&') { + state = STATE_IN_HTML_ENTITY; + parseentity = QString(); + continue; + } + + // Replace quote by ' - quotes are used in search window to set the phrase + if (ch == '"') + ch = '\''; + + // Ok, we have a valid character outside HTML tags, and probably some in buffer already. + // If it is char or letter, add it and continue + if (ch.isLetterOrNumber() || m_charsword.indexOf(ch) != -1) { + parsedbuf.append(ch); + continue; + } + + // If it is a split char, add the word to the dictionary, and then add the char itself. + if (m_charssplit.indexOf(ch) != -1) { + if (!parsedbuf.isEmpty()) + tokenlist.push_back(parsedbuf.toLower()); + + tokenlist.push_back(ch.toLower()); + parsedbuf = QString(); + continue; + } + + tokenize_buf: + // Just add the word; it is most likely a space or terminated by tokenizer. + if (!parsedbuf.isEmpty()) { + tokenlist.push_back(parsedbuf.toLower()); + parsedbuf = QString(); + } + } + + // Add the last word if still here - for broken htmls. + if (!parsedbuf.isEmpty()) + tokenlist.push_back(parsedbuf.toLower()); + + return true; +} + +void Index::writeDict(QDataStream &stream) +{ + stream << DICT_VERSION; + stream << m_charssplit; + stream << m_charsword; + + // Document list + stream << docList; + + // Dictionary + for (QHash::ConstIterator it = dict.constBegin(); it != dict.constEnd(); ++it) { + stream << it.key(); + stream << (int)it.value()->documents.count(); + stream << it.value()->documents; + } +} + +bool Index::readDict(QDataStream &stream) +{ + dict.clear(); + docList.clear(); + + QString key; + int version, numOfDocs; + + stream >> version; + + if (version < 2) + return false; + + stream >> m_charssplit; + stream >> m_charsword; + + // Read the document list + stream >> docList; + + while (!stream.atEnd()) { + stream >> key; + stream >> numOfDocs; + + QVector docs(numOfDocs); + + stream >> docs; + dict.insert(key, new Entry(docs)); + } + + return dict.size() > 0; +} + +QList Index::query(const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords, EBook *chmFile) +{ + QList termList; + + QStringList::ConstIterator it = terms.begin(); + for (it = terms.begin(); it != terms.end(); ++it) { + Entry *e = nullptr; + + if (dict[*it]) { + e = dict[*it]; + termList.append(Term(*it, e->documents.count(), e->documents)); + } else { + return QList(); + } + } + + if (termList.isEmpty()) + return QList(); + + std::sort(termList.begin(), termList.end()); + + QVector minDocs = termList.takeFirst().documents; + for (const Term &t : qAsConst(termList)) { + const QVector docs = t.documents; + for (QVector::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end();) { + bool found = false; + for (QVector::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it) { + if ((*minDoc_it).docNumber == (*doc_it).docNumber) { + (*minDoc_it).frequency += (*doc_it).frequency; + found = true; + break; + } + } + if (!found) + minDoc_it = minDocs.erase(minDoc_it); + else + ++minDoc_it; + } + } + + QList results; + std::sort(minDocs.begin(), minDocs.end()); + if (termSeq.isEmpty()) { + for (const Document &doc : qAsConst(minDocs)) + results << docList.at((int)doc.docNumber); + return results; + } + + QUrl fileName; + for (const Document &doc : qAsConst(minDocs)) { + fileName = docList[(int)doc.docNumber]; + if (searchForPhrases(termSeq, seqWords, fileName, chmFile)) + results << fileName; + } + + return results; +} + +bool Index::searchForPhrases(const QStringList &phrases, const QStringList &words, const QUrl &filename, EBook *chmFile) +{ + QStringList parsed_document; + + if (!parseDocumentToStringlist(chmFile, filename, parsed_document)) + return false; + + miniDict.clear(); + + // Initialize the dictionary with the words in phrase(s) + for (const QString &word : words) + miniDict.insert(word, new PosEntry(0)); + + // Fill the dictionary with the words from the document + unsigned int word_offset = 3; + for (QStringList::ConstIterator it = parsed_document.constBegin(); it != parsed_document.constEnd(); it++, word_offset++) { + PosEntry *entry = miniDict[*it]; + + if (entry) + entry->positions.append(word_offset); + } + + // Dump it + /* + QDictIterator it( miniDict ); + for( ; it.current(); ++it ) + { + QString text( it.currentKey() ); + QValueList pos = miniDict[text]->positions; + for ( unsigned int i = 1; i < pos.size(); i++ ) + text += " " + QString::number( pos[i] ); + + qDebug( "%s", text.ascii()); + } + */ + + QList first_word_positions; + + for (QStringList::ConstIterator phrase_it = phrases.constBegin(); phrase_it != phrases.constEnd(); phrase_it++) { + QStringList phrasewords = phrase_it->split(' '); + first_word_positions = miniDict[phrasewords[0]]->positions; + + for (int j = 1; j < phrasewords.count(); ++j) { + QList next_word_it = miniDict[phrasewords[j]]->positions; + QList::iterator dict_it = first_word_positions.begin(); + + while (dict_it != first_word_positions.end()) { + if (next_word_it.indexOf(*dict_it + 1) != -1) { + (*dict_it)++; + ++dict_it; + } else + dict_it = first_word_positions.erase(dict_it); + } + } + } + + return !first_word_positions.isEmpty(); +} + +}; diff --git a/generators/chm/lib/helper_search_index.h b/generators/chm/lib/helper_search_index.h new file mode 100644 index 0000000..460fc54 --- /dev/null +++ b/generators/chm/lib/helper_search_index.h @@ -0,0 +1,146 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_SEARCH_INDEX_H +#define EBOOK_SEARCH_INDEX_H + +#include +#include +#include +#include +#include + +#include "helper_entitydecoder.h" + +class EBook; + +// This code is based on some pretty old version of Qt Assistant +namespace QtAs +{ +struct Document { + Document(int d, int f) + : docNumber(d) + , frequency(f) + { + } + Document() + : docNumber(-1) + , frequency(0) + { + } + bool operator==(const Document doc) const + { + return docNumber == doc.docNumber; + } + + bool operator<(const Document doc) const + { + return frequency > doc.frequency; + } + + bool operator<=(const Document doc) const + { + return frequency >= doc.frequency; + } + + bool operator>(const Document doc) const + { + return frequency < doc.frequency; + } + + qint16 docNumber; + qint16 frequency; +}; + +QDataStream &operator>>(QDataStream &s, Document &l); +QDataStream &operator<<(QDataStream &s, const Document l); + +class Index : public QObject +{ + Q_OBJECT +public: + Index(); + + void writeDict(QDataStream &stream); + bool readDict(QDataStream &stream); + bool makeIndex(const QList &docs, EBook *chmFile); + QList query(const QStringList &, const QStringList &, const QStringList &, EBook *chmFile); + QString getCharsSplit() const + { + return m_charssplit; + } + QString getCharsPartOfWord() const + { + return m_charsword; + } + +signals: + void indexingProgress(int, const QString &); + +public slots: + void setLastWinClosed(); + +private: + struct Entry { + Entry(int d) + { + documents.append(Document(d, 1)); + } + Entry(const QVector &l) + : documents(l) + { + } + QVector documents; + }; + + struct PosEntry { + PosEntry(int p) + { + positions.append(p); + } + QList positions; + }; + + bool parseDocumentToStringlist(EBook *chmFile, const QUrl &filename, QStringList &tokenlist); + void insertInDict(const QString &, int); + + QStringList getWildcardTerms(const QString &); + QStringList split(const QString &); + QList setupDummyTerm(const QStringList &); + bool searchForPhrases(const QStringList &phrases, const QStringList &words, const QUrl &filename, EBook *chmFile); + + QList docList; + QHash dict; + QHash miniDict; + bool lastWindowClosed; + HelperEntityDecoder entityDecoder; + + // Those characters are splitters (i.e. split the word), but added themselves into dictionary too. + // This makes the dictionary MUCH larger, but ensure that for the piece of "window->print" both + // search for "print" and "->print" will find it. + QString m_charssplit; + + // Those characters are parts of word - for example, '_' is here, and search for _debug will find only _debug. + QString m_charsword; +}; + +}; + +Q_DECLARE_TYPEINFO(QtAs::Document, Q_MOVABLE_TYPE); + +#endif // EBOOK_SEARCH_INDEX_H diff --git a/generators/chm/lib/helperxmlhandler_epubcontainer.cpp b/generators/chm/lib/helperxmlhandler_epubcontainer.cpp new file mode 100644 index 0000000..354a967 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontainer.cpp @@ -0,0 +1,33 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "helperxmlhandler_epubcontainer.h" + +bool HelperXmlHandler_EpubContainer::startElement(const QString &, const QString &, const QString &qName, const QXmlAttributes &atts) +{ + if (qName == QLatin1String("rootfile")) { + int idx = atts.index(QLatin1String("full-path")); + + if (idx == -1) + return false; + + contentPath = atts.value(idx); + } + + return true; +} diff --git a/generators/chm/lib/helperxmlhandler_epubcontainer.h b/generators/chm/lib/helperxmlhandler_epubcontainer.h new file mode 100644 index 0000000..6f23266 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontainer.h @@ -0,0 +1,34 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBCONTAINER_H +#define HELPERXMLHANDLER_EPUBCONTAINER_H + +#include + +class HelperXmlHandler_EpubContainer : public QXmlDefaultHandler +{ +public: + // Overridden members + bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts) override; + + // The content path + QString contentPath; +}; + +#endif // HELPERXMLHANDLER_EPUBCONTAINER_H diff --git a/generators/chm/lib/helperxmlhandler_epubcontent.cpp b/generators/chm/lib/helperxmlhandler_epubcontent.cpp new file mode 100644 index 0000000..b06b635 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontent.cpp @@ -0,0 +1,87 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "helperxmlhandler_epubcontent.h" + +HelperXmlHandler_EpubContent::HelperXmlHandler_EpubContent() +{ + m_state = STATE_NONE; +} + +bool HelperXmlHandler_EpubContent::startElement(const QString &, const QString &localName, const QString &, const QXmlAttributes &atts) +{ + // tag contains the medatada which goes into m_metadata + if (localName == QLatin1String("metadata")) + m_state = STATE_IN_METADATA; + else if (localName == QLatin1String("manifest")) + m_state = STATE_IN_MANIFEST; + else if (localName == QLatin1String("spine")) + m_state = STATE_IN_SPINE; + // Now handle the states + else if (m_state == STATE_IN_METADATA) // we don't need to store the first 'metadata' here + m_tagname = localName; + else if (m_state == STATE_IN_MANIFEST && localName == QLatin1String("item")) { + int idx_id = atts.index(QLatin1String("id")); + int idx_href = atts.index(QLatin1String("href")); + int idx_mtype = atts.index(QLatin1String("media-type")); + + if (idx_id == -1 || idx_href == -1 || idx_mtype == -1) + return false; + + manifest[atts.value(idx_id)] = atts.value(idx_href); + + if (atts.value(idx_mtype) == QLatin1String("application/x-dtbncx+xml")) + tocname = atts.value(idx_href); + + // qDebug() << "MANIFEST: " << atts.value( idx_id ) << "->" << atts.value( idx_href ); + } else if (m_state == STATE_IN_SPINE && localName == QLatin1String("itemref")) { + int idx = atts.index(QLatin1String("idref")); + + if (idx == -1) + return false; + + spine.push_back(atts.value(idx)); + // qDebug() << "SPINE: " << atts.value( idx ); + } + + return true; +} + +bool HelperXmlHandler_EpubContent::characters(const QString &ch) +{ + if (m_state == STATE_IN_METADATA && !m_tagname.isEmpty() && !ch.trimmed().isEmpty()) { + // Some metadata may be duplicated; we concantenate them with | + if (metadata.contains(m_tagname)) { + metadata[m_tagname].append("|"); + metadata[m_tagname].append(ch.trimmed()); + } else + metadata[m_tagname] = ch.trimmed(); + + // qDebug() << "METATAG: " << m_tagname << " " << metadata[ m_tagname ]; + } + + return true; +} + +bool HelperXmlHandler_EpubContent::endElement(const QString &, const QString &, const QString &qName) +{ + if (qName == QLatin1String("manifest") || qName == QLatin1String("metadata") || qName == QLatin1String("spine")) + m_state = STATE_NONE; + + return true; +} diff --git a/generators/chm/lib/helperxmlhandler_epubcontent.h b/generators/chm/lib/helperxmlhandler_epubcontent.h new file mode 100644 index 0000000..a223b84 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontent.h @@ -0,0 +1,55 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBCONTENT_H +#define HELPERXMLHANDLER_EPUBCONTENT_H + +#include +#include +#include + +class HelperXmlHandler_EpubContent : public QXmlDefaultHandler +{ +public: + HelperXmlHandler_EpubContent(); + + // Keep the tag-associated metadata + QMap metadata; + + // Manifest storage, id -> href + QMap manifest; + + // Spline storage + QList spine; + + // TOC (NCX) filename + QString tocname; + +private: + enum State { STATE_NONE, STATE_IN_METADATA, STATE_IN_MANIFEST, STATE_IN_SPINE }; + + bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts) override; + bool characters(const QString &ch) override; + bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName) override; + + // Tracking + State m_state; + QString m_tagname; +}; + +#endif // HELPERXMLHANDLER_EPUBCONTENT_H diff --git a/generators/chm/lib/helperxmlhandler_epubtoc.cpp b/generators/chm/lib/helperxmlhandler_epubtoc.cpp new file mode 100644 index 0000000..15e9dfb --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubtoc.cpp @@ -0,0 +1,108 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "helperxmlhandler_epubtoc.h" +#include + +HelperXmlHandler_EpubTOC::HelperXmlHandler_EpubTOC(EBook_EPUB *epub) +{ + m_epub = epub; + m_inNavMap = false; + m_inText = false; + m_indent = 0; +} + +bool HelperXmlHandler_EpubTOC::startElement(const QString &, const QString &localName, const QString &, const QXmlAttributes &atts) +{ + // qDebug() << "startElement " << " " << localName; + + // for ( int i = 0; i < atts.count(); i++ ) + // qDebug() << " " << atts.localName(i) << " " << atts.value(i); + + if (localName == QLatin1String("navMap")) { + m_inNavMap = true; + return true; + } + + if (!m_inNavMap) + return true; + + if (localName == QLatin1String("navPoint")) + m_indent++; + + if (localName == QLatin1String("text")) + m_inText = true; + + if (localName == QLatin1String("content")) { + int idx = atts.index(QLatin1String("src")); + + if (idx == -1) + return false; + + m_lastId = atts.value(idx); + checkNewTocEntry(); + } + + return true; +} + +bool HelperXmlHandler_EpubTOC::characters(const QString &ch) +{ + // qDebug() << "characters" << " " << ch; + if (m_inText) + m_lastTitle = ch; + + checkNewTocEntry(); + return true; +} + +bool HelperXmlHandler_EpubTOC::endElement(const QString &, const QString &localName, const QString &) +{ + // qDebug() << "endElement" << " " << qName; + + if (localName == QLatin1String("navMap")) { + m_inNavMap = false; + return true; + } + + if (localName == QLatin1String("navPoint")) + m_indent--; + + if (localName == QLatin1String("text")) + m_inText = false; + + return true; +} + +void HelperXmlHandler_EpubTOC::checkNewTocEntry() +{ + if (!m_lastId.isEmpty() && !m_lastTitle.isEmpty()) { + EBookTocEntry entry; + entry.name = m_lastTitle; + entry.url = m_epub->pathToUrl(m_lastId); + entry.iconid = EBookTocEntry::IMAGE_AUTO; + entry.indent = m_indent - 1; + + entries.push_back(entry); + + // qDebug() << "TOC entry: " << m_lastId << " :" << m_lastTitle << " :" << m_indent - 1; + + m_lastId.clear(); + m_lastTitle.clear(); + } +} diff --git a/generators/chm/lib/helperxmlhandler_epubtoc.h b/generators/chm/lib/helperxmlhandler_epubtoc.h new file mode 100644 index 0000000..3673e2d --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubtoc.h @@ -0,0 +1,47 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBTOC_H +#define HELPERXMLHANDLER_EPUBTOC_H + +#include "ebook_epub.h" +#include + +class HelperXmlHandler_EpubTOC : public QXmlDefaultHandler +{ +public: + HelperXmlHandler_EpubTOC(EBook_EPUB *epub); + + QList entries; + +private: + // Overridden members + bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts) override; + bool characters(const QString &ch) override; + bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName) override; + void checkNewTocEntry(); + + bool m_inNavMap; + bool m_inText; + unsigned int m_indent; + QString m_lastId; + QString m_lastTitle; + EBook_EPUB *m_epub; +}; + +#endif // HELPERXMLHANDLER_EPUBTOC_H diff --git a/generators/chm/lib/libchmurlfactory.h b/generators/chm/lib/libchmurlfactory.h new file mode 100644 index 0000000..8d92f6e --- /dev/null +++ b/generators/chm/lib/libchmurlfactory.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include + +namespace LCHMUrlFactory +{ +static inline bool isRemoteURL(const QString &url, QString &protocol) +{ + // Check whether the URL is external + QRegularExpression uriregex(QStringLiteral("^(\\w+):\\/\\/")); + QRegularExpressionMatch match; + + // mailto: can also have different format, so handle it + if (url.startsWith(QLatin1String("mailto:"))) { + protocol = QStringLiteral("mailto"); + return true; + } else if ((match = uriregex.match(url)).hasMatch()) { + const QString proto = match.captured(1).toLower(); + + // Filter the URLs which need to be opened by a browser + if (proto == QLatin1String("http") || proto == QLatin1String("ftp") || proto == QLatin1String("mailto") || proto == QLatin1String("news")) { + protocol = proto; + return true; + } + } + + return false; +} + +// Some JS urls start with javascript:// +static inline bool isJavascriptURL(const QString &url) +{ + return url.startsWith(QLatin1String("javascript://")); +} + +// Parse urls like "ms-its:file name.chm::/topic.htm" +static inline bool isNewChmURL(const QString &url, QString &chmfile, QString &page) +{ + QRegularExpression uriregex(QStringLiteral("^ms-its:(.*)::(.*)$")); + uriregex.setPatternOptions(QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch match = uriregex.match(url); + if (match.hasMatch()) { + chmfile = match.captured(1); + page = match.captured(2); + + return true; + } + + return false; +} + +static inline QString makeURLabsoluteIfNeeded(const QString &url) +{ + QString p1, p2, newurl = url; + + if (!isRemoteURL(url, p1) && !isJavascriptURL(url) && !isNewChmURL(url, p1, p2)) { + newurl = QDir::cleanPath(url); + + // Normalize url, so it becomes absolute + if (newurl[0] != QLatin1Char('/')) + newurl = QLatin1Char('/') + newurl; + } + + // qDebug ("makeURLabsolute (%s) -> (%s)", url.ascii(), newurl.ascii()); + return newurl; +} + +// Returns a special string, which allows the kio-slave, or viewwindow-browser interaction +// to recognize our own internal urls, which is necessary to show image-only pages. +static inline QString getInternalUriExtension() +{ + return QStringLiteral(".KCHMVIEWER_SPECIAL_HANDLER"); +} + +static inline bool handleFileType(const QString &link, QString &generated) +{ + QString intext = getInternalUriExtension(); + + if (!link.endsWith(intext)) + return false; + + QString filelink = link.left(link.length() - intext.length()); + generated = QStringLiteral(""); + return true; +} + +} diff --git a/generators/chm/libokularGenerator_chmlib.json b/generators/chm/libokularGenerator_chmlib.json new file mode 100644 index 0000000..2f4e48c --- /dev/null +++ b/generators/chm/libokularGenerator_chmlib.json @@ -0,0 +1,209 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "niedakh@gmail.com", + "Name": "Piotr Szymański", + "Name[az]": "Piotr Szymański", + "Name[ca@valencia]": "Piotr Szymański", + "Name[ca]": "Piotr Szymański", + "Name[cs]": "Piotr Szymański", + "Name[da]": "Piotr Szymański", + "Name[de]": "Piotr Szymański", + "Name[el]": "Piotr Szymański", + "Name[en_GB]": "Piotr Szymański", + "Name[es]": "Piotr Szymański", + "Name[et]": "Piotr Szymański", + "Name[eu]": "Piotr Szymański", + "Name[fi]": "Piotr Szymański", + "Name[fr]": "Piotr Szymański", + "Name[gl]": "Piotr Szymański", + "Name[ia]": "Piotr Szymański", + "Name[it]": "Piotr Szymański", + "Name[ko]": "Piotr Szymański", + "Name[lt]": "Piotr Szymański", + "Name[nl]": "Piotr Szymański", + "Name[nn]": "Piotr Szymański", + "Name[pl]": "Piotr Szymański", + "Name[pt]": "Piotr Szymański", + "Name[pt_BR]": "Piotr Szymański", + "Name[ru]": "Piotr Szymański", + "Name[sk]": "Piotr Szymański", + "Name[sl]": "Piotr Szymański", + "Name[sr@ijekavian]": "Пјотр Шимањски", + "Name[sr@ijekavianlatin]": "Pjotr Å imanjski", + "Name[sr@latin]": "Pjotr Å imanjski", + "Name[sr]": "Пјотр Шимањски", + "Name[sv]": "Piotr Szymański", + "Name[tr]": "Piotr Szymański", + "Name[uk]": "Piotr Szymański", + "Name[x-test]": "xxPiotr Szymańskixx", + "Name[zh_CN]": "Piotr Szymański", + "Name[zh_TW]": "Piotr Szymański" + }, + { + "Email": "aacid@kde.org", + "Name": "Albert Astals Cid", + "Name[az]": "Albert Astals Cid", + "Name[ca@valencia]": "Albert Astals Cid", + "Name[ca]": "Albert Astals Cid", + "Name[cs]": "Albert Astals Cid", + "Name[da]": "Albert Astals Cid", + "Name[de]": "Albert Astals Cid", + "Name[el]": "Albert Astals Cid", + "Name[en_GB]": "Albert Astals Cid", + "Name[es]": "Albert Astals Cid", + "Name[et]": "Albert Astals Cid", + "Name[eu]": "Albert Astals Cid", + "Name[fi]": "Albert Astals Cid", + "Name[fr]": "Albert Astals Cid", + "Name[gl]": "Albert Astals Cid", + "Name[ia]": "Albert Astals Cid", + "Name[it]": "Albert Astals Cid", + "Name[ko]": "Albert Astals Cid", + "Name[lt]": "Albert Astals Cid", + "Name[nl]": "Albert Astals Cid", + "Name[nn]": "Albert Astals Cid", + "Name[pl]": "Albert Astals Cid", + "Name[pt]": "Albert Astals Cid", + "Name[pt_BR]": "Albert Astals Cid", + "Name[ru]": "Albert Astals Cid", + "Name[sk]": "Albert Astals Cid", + "Name[sl]": "Albert Astals Cid", + "Name[sr@ijekavian]": "Алберт Асталс Сид", + "Name[sr@ijekavianlatin]": "Albert Astals Sid", + "Name[sr@latin]": "Albert Astals Sid", + "Name[sr]": "Алберт Асталс Сид", + "Name[sv]": "Albert Astals Cid", + "Name[tr]": "Albert Astals Cid", + "Name[uk]": "Albert Astals Cid", + "Name[x-test]": "xxAlbert Astals Cidxx", + "Name[zh_CN]": "Albert Astals Cid", + "Name[zh_TW]": "Albert Astals Cid" + } + ], + "Copyright": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[az]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[ca@valencia]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[ca]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[cs]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[da]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[de]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[el]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[en_GB]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[es]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[et]": "© 2005-2007: Piotr Szymański\n© 2008: Albert Astals Cid", + "Copyright[eu]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[fi]": "© 2005–2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[fr]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[gl]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[ia]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[it]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[ko]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[lt]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[nl]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[nn]": "© 2005–2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[pl]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[pt]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[pt_BR]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[ru]": "© Piotr Szymański, 2005-2007\n© Albert Astals Cid, 2008", + "Copyright[sk]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[sl]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[sr@ijekavian]": "© 2005—2007, Пјотр Шимањски\n© 2008, Алберт Асталс Сид", + "Copyright[sr@ijekavianlatin]": "© 2005—2007, Pjotr Å imanjski\n© 2008, Albert Astals Sid", + "Copyright[sr@latin]": "© 2005—2007, Pjotr Å imanjski\n© 2008, Albert Astals Sid", + "Copyright[sr]": "© 2005—2007, Пјотр Шимањски\n© 2008, Алберт Асталс Сид", + "Copyright[sv]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[tr]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[uk]": "© Piotr Szymański, 2005–2007\n© Albert Astals Cid, 2008", + "Copyright[x-test]": "xx© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cidxx", + "Copyright[zh_CN]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Copyright[zh_TW]": "© 2005-2007 Piotr Szymański\n© 2008 Albert Astals Cid", + "Description": "A Microsoft Windows help file renderer", + "Description[az]": "Microsoft Windows köməkçi fayl tərtibatçısı", + "Description[ca@valencia]": "Un renderitzador per als fitxers d'ajuda de Microsoft Windows", + "Description[ca]": "Un renderitzador per als fitxers d'ajuda de Microsoft Windows", + "Description[cs]": "Nástroj pro zobrazování nápovědy Microsoft Windows", + "Description[da]": "En gengiver til Microsoft Windows-hjælpfiler", + "Description[de]": "Darstellungsprogramm für Hilfedateien aus Microsoft Windows", + "Description[el]": "Πρόγραμμα αποτύπωσης για αρχεία βοήθειας Microsoft Windows", + "Description[en_GB]": "A Microsoft Windows help file renderer", + "Description[es]": "Un visor de archivos de ayuda de Microsoft Windows", + "Description[et]": "Microsoft Windowsi abifailide renderdaja", + "Description[eu]": "Microsoft Windows laguntza fitxategien errendatzaile bat", + "Description[fi]": "Microsoft Windows -ohjetiedostohahmonnin", + "Description[fr]": "Un système de rendu pour les fichiers d'aide Windows", + "Description[gl]": "Un visor de ficheiros de axuda de Microsoft Windows", + "Description[ia]": "Un rendition de file de adjuta de Microsoft Windows", + "Description[it]": "Un visualizzatore per file di aiuto di Microsoft Windows", + "Description[ko]": "Microsoft Windows 도움말 파일 표시기", + "Description[lt]": "Microsoft Windows pagalbos failų atvaizdavimas", + "Description[nl]": "Een viewer voor Microsoft Windows-helpbestanden", + "Description[nn]": "Ein framvisar for Microsoft Windows-hjelpefiler", + "Description[pl]": "Wyświetlanie plików pomocy Microsoft Windows", + "Description[pt]": "Um visualizador de ficheiros de ajuda do Microsoft Windows", + "Description[pt_BR]": "Um interpretador de arquivos de ajuda do Microsoft Windows", + "Description[ru]": "Модуль поддержки формата CHM (справка Microsoft Windows)", + "Description[sk]": "Vykresľovanie súborov pomocníka Microsoft Windows", + "Description[sl]": "Izrisovalnik datotek za pomoč za Microsoft Windows", + "Description[sr@ijekavian]": "Рендерер за фајлове Виндоузове помоћи", + "Description[sr@ijekavianlatin]": "Renderer za fajlove Windowsove pomoći", + "Description[sr@latin]": "Renderer za fajlove Windowsove pomoći", + "Description[sr]": "Рендерер за фајлове Виндоузове помоћи", + "Description[sv]": "Ett Ã¥tergivningsprogram av Microsoft Windows hjälpfiler", + "Description[tr]": "Microsoft Windows yardım dosyası oluşturucusu", + "Description[uk]": "Відображення файлів довідки Microsoft Windows", + "Description[x-test]": "xxA Microsoft Windows help file rendererxx", + "Description[zh_CN]": "Microsoft Windows 帮助文件渲染器", + "Description[zh_TW]": "Microsoft Windows 說明檔成像器", + "Id": "okular_chm", + "License": "GPL", + "MimeTypes": [ + "application/x-chm" + ], + "Name": "CHM Backend", + "Name[az]": "CHM modulu", + "Name[ca@valencia]": "Dorsal CHM", + "Name[ca]": "Dorsal CHM", + "Name[cs]": "Podpora CHM", + "Name[da]": "CHM-backend", + "Name[de]": "Anzeigemodul für CHM", + "Name[el]": "Σύστημα υποστήριξης CHM", + "Name[en_GB]": "CHM Backend", + "Name[es]": "Motor para CHM", + "Name[et]": "CHM-i taustaprogramm", + "Name[eu]": "CHM-ren bizkarraldekoa", + "Name[fi]": "CHM-taustaosa", + "Name[fr]": "Moteur CHM", + "Name[gl]": "Infraestrutura para CHM", + "Name[ia]": "Retro-Administration de CHM", + "Name[it]": "Backend CHM", + "Name[ko]": "CHM 백엔드", + "Name[lt]": "CHM programinė sąsaja", + "Name[nl]": "CHM-backend", + "Name[nn]": "CHM-motor", + "Name[pl]": "Obsługa CHM", + "Name[pt]": "Infra-Estrutura de CHM", + "Name[pt_BR]": "Infraestrutura CHM", + "Name[ru]": "Модуль поддержки формата CHM", + "Name[sk]": "CHM Backend", + "Name[sl]": "Zaledje za CHM", + "Name[sr@ijekavian]": "Позадина за ЦХМ", + "Name[sr@ijekavianlatin]": "Pozadina za CHM", + "Name[sr@latin]": "Pozadina za CHM", + "Name[sr]": "Позадина за ЦХМ", + "Name[sv]": "CHM-gränssnitt", + "Name[tr]": "CHM Arka Ucu", + "Name[uk]": "Модуль CHM", + "Name[x-test]": "xxCHM Backendxx", + "Name[zh_CN]": "CHM 后端", + "Name[zh_TW]": "CHM 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.4" + }, + "X-KDE-Priority": 2, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/chm/okularApplication_chm.desktop b/generators/chm/okularApplication_chm.desktop new file mode 100755 index 0000000..5282c93 --- /dev/null +++ b/generators/chm/okularApplication_chm.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/x-chm; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=3 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=chm +X-KDE-Keywords[ar]=chm +X-KDE-Keywords[az]=chm +X-KDE-Keywords[bg]=chm +X-KDE-Keywords[bs]=chm +X-KDE-Keywords[ca]=chm +X-KDE-Keywords[ca@valencia]=chm +X-KDE-Keywords[cs]=chm +X-KDE-Keywords[da]=chm +X-KDE-Keywords[de]=chm +X-KDE-Keywords[el]=chm +X-KDE-Keywords[en_GB]=chm +X-KDE-Keywords[es]=chm +X-KDE-Keywords[et]=chm +X-KDE-Keywords[eu]=chm +X-KDE-Keywords[fi]=chm +X-KDE-Keywords[fr]=chm +X-KDE-Keywords[ga]=chm +X-KDE-Keywords[gl]=chm +X-KDE-Keywords[hu]=chm +X-KDE-Keywords[ia]=chm +X-KDE-Keywords[is]=chm +X-KDE-Keywords[it]=chm +X-KDE-Keywords[ja]=chm +X-KDE-Keywords[kk]=chm +X-KDE-Keywords[km]=chm +X-KDE-Keywords[ko]=chm +X-KDE-Keywords[lt]=chm +X-KDE-Keywords[lv]=chm +X-KDE-Keywords[mr]=chm +X-KDE-Keywords[nb]=chm +X-KDE-Keywords[nds]=CHM +X-KDE-Keywords[nl]=chm +X-KDE-Keywords[nn]=chm +X-KDE-Keywords[pa]=chm +X-KDE-Keywords[pl]=chm +X-KDE-Keywords[pt]=chm +X-KDE-Keywords[pt_BR]=chm +X-KDE-Keywords[ro]=chm +X-KDE-Keywords[ru]=chm +X-KDE-Keywords[sk]=chm +X-KDE-Keywords[sl]=chm +X-KDE-Keywords[sr]=chm,ЦХМ +X-KDE-Keywords[sr@ijekavian]=chm,ЦХМ +X-KDE-Keywords[sr@ijekavianlatin]=chm,CHM +X-KDE-Keywords[sr@latin]=chm,CHM +X-KDE-Keywords[sv]=chm +X-KDE-Keywords[tr]=chm +X-KDE-Keywords[uk]=chm +X-KDE-Keywords[x-test]=xxchmxx +X-KDE-Keywords[zh_CN]=chm +X-KDE-Keywords[zh_TW]=chm diff --git a/generators/chm/okularChm.desktop b/generators/chm/okularChm.desktop new file mode 100644 index 0000000..23ac5d1 --- /dev/null +++ b/generators/chm/okularChm.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-chm; diff --git a/generators/chm/org.kde.mobile.okular_chm.desktop b/generators/chm/org.kde.mobile.okular_chm.desktop new file mode 100644 index 0000000..61c5f4f --- /dev/null +++ b/generators/chm/org.kde.mobile.okular_chm.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +MimeType=application/x-chm; +X-KDE-Keywords=chm +X-KDE-Keywords[ar]=chm +X-KDE-Keywords[az]=chm +X-KDE-Keywords[bg]=chm +X-KDE-Keywords[bs]=chm +X-KDE-Keywords[ca]=chm +X-KDE-Keywords[ca@valencia]=chm +X-KDE-Keywords[cs]=chm +X-KDE-Keywords[da]=chm +X-KDE-Keywords[de]=chm +X-KDE-Keywords[el]=chm +X-KDE-Keywords[en_GB]=chm +X-KDE-Keywords[es]=chm +X-KDE-Keywords[et]=chm +X-KDE-Keywords[eu]=chm +X-KDE-Keywords[fi]=chm +X-KDE-Keywords[fr]=chm +X-KDE-Keywords[ga]=chm +X-KDE-Keywords[gl]=chm +X-KDE-Keywords[hu]=chm +X-KDE-Keywords[ia]=chm +X-KDE-Keywords[is]=chm +X-KDE-Keywords[it]=chm +X-KDE-Keywords[ja]=chm +X-KDE-Keywords[kk]=chm +X-KDE-Keywords[km]=chm +X-KDE-Keywords[ko]=chm +X-KDE-Keywords[lt]=chm +X-KDE-Keywords[lv]=chm +X-KDE-Keywords[mr]=chm +X-KDE-Keywords[nb]=chm +X-KDE-Keywords[nds]=CHM +X-KDE-Keywords[nl]=chm +X-KDE-Keywords[nn]=chm +X-KDE-Keywords[pa]=chm +X-KDE-Keywords[pl]=chm +X-KDE-Keywords[pt]=chm +X-KDE-Keywords[pt_BR]=chm +X-KDE-Keywords[ro]=chm +X-KDE-Keywords[ru]=chm +X-KDE-Keywords[sk]=chm +X-KDE-Keywords[sl]=chm +X-KDE-Keywords[sr]=chm,ЦХМ +X-KDE-Keywords[sr@ijekavian]=chm,ЦХМ +X-KDE-Keywords[sr@ijekavianlatin]=chm,CHM +X-KDE-Keywords[sr@latin]=chm,CHM +X-KDE-Keywords[sv]=chm +X-KDE-Keywords[tr]=chm +X-KDE-Keywords[uk]=chm +X-KDE-Keywords[x-test]=xxchmxx +X-KDE-Keywords[zh_CN]=chm +X-KDE-Keywords[zh_TW]=chm diff --git a/generators/chm/org.kde.okular-chm.metainfo.xml b/generators/chm/org.kde.okular-chm.metainfo.xml new file mode 100644 index 0000000..5917c27 --- /dev/null +++ b/generators/chm/org.kde.okular-chm.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-chm + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + CHM Documents + CHM sənədləri + Documents CHM + Documents CHM + Dokumenty CHM + CHM-Dokumente + Έγγραφα CHM + CHM Documents + Documentos CHM + CHM-dokumendid + CHM dokumentuak + CHM-tiedostot + Documents « CHM » + Documentos CHM + Documentos CHM + Documenti CHM + CHM 문서 + CHM dokumentai + സി എച് എം പ്രമാണങ്ങൾ + CHM-documenten + CHM-dokument + Dokumenty CHM + Documentos CHM + Documentos CHM + Документы CHM + CHM dokumenty + Dokumenti CHM + ЦХМ документи + CHM dokumenti + ЦХМ документи + CHM dokumenti + CHM-dokument + CHM Belgeleri + документи CHM + xxCHM Documentsxx + CHM 文档 + CHM 文件 + Adds support for reading CHM documents + CHM sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents CHM + Afig la implementació per a llegir documents CHM + Přidává podporu pro čtení dokumentů CHM + Bietet Unterstützung zum Lesen von CHM-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων CHM + Adds support for reading CHM documents + Permite la lectura de documentos CHM + CHM-dokumentide lugemise toetus + CHM dokumentuak irakurtzeko euskarria gehitzen du + Lisää CHM-tiedostojen lukutuen + Permet la lecture des documents « CHM » + Engade a posibilidade de ler documentos CHM + Adde supporto per leger documentos CHM + Aggiunge il supporto per la lettura di documenti CHM + CHM 문서 읽기 지원 추가 + Prideda palaikymą CHM dokumentų skaitymui + സി എം എച് പ്രമാണങ്ങൾ വായിക്കുവാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van CHM-documenten toe + Legg til støtte for Ã¥ lesa CHM-dokument + Dodaje obsługę dokumentów CHM + Adiciona o suporte para a leitura de documentos CHM + Adiciona o suporte para leitura de documentos CHM + Поддержка чтения документов CHM + Pridá podporu pre čítanie CHM dokumentov + Doda podporo za branje dokumentov CHM + Подршка за читање ЦХМ докумената + PodrÅ¡ka za čitanje CHM dokumenata + Подршка за читање ЦХМ докумената + PodrÅ¡ka za čitanje CHM dokumenata + Lägger till stöd för att läsa CHM-dokument + CHM belgelerini okuma desteği ekler + Додає підтримку читання документів CHM + xxAdds support for reading CHM documentsxx + 增加对 CHM 文档的阅读支持 + 加入對讀取 CHM 文件的支援 + + application/x-chm + + https://okular.kde.org + + + + + + + diff --git a/generators/comicbook/CMakeLists.txt b/generators/comicbook/CMakeLists.txt new file mode 100644 index 0000000..9a07c71 --- /dev/null +++ b/generators/comicbook/CMakeLists.txt @@ -0,0 +1,43 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_comicbook") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + +########### next target ############### + +set( okularGenerator_comicbook_PART_SRCS + document.cpp + directory.cpp + unrar.cpp qnatsort.cpp + unrarflavours.cpp + ) + +add_library(okular_comicbook STATIC ${okularGenerator_comicbook_PART_SRCS}) +target_link_libraries(okular_comicbook okularcore KF5::KIOCore KF5::I18n KF5::Archive) + +okular_add_generator(okularGenerator_comicbook generator_comicbook.cpp) +target_link_libraries(okularGenerator_comicbook okular_comicbook) +if (UNIX AND NOT ANDROID) + find_package(KF5Pty REQUIRED) + target_compile_definitions(okular_comicbook PRIVATE -DWITH_KPTY=1) + target_link_libraries(okular_comicbook KF5::Pty) +endif () + +if (KArchive_HAVE_LZMA) + target_compile_definitions(okular_comicbook PRIVATE -DWITH_K7ZIP=1) +endif() + +########### autotests ############### + +add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) +ecm_add_test(autotests/comicbooktest.cpp + TEST_NAME "comicbooktest" + LINK_LIBRARIES Qt5::Test KF5::CoreAddons okularcore okular_comicbook +) + +########### install files ############### +install( FILES okularComicbook.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_comicbook.desktop org.kde.mobile.okular_comicbook.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-comicbook.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/comicbook/Messages.sh b/generators/comicbook/Messages.sh new file mode 100755 index 0000000..f2418e7 --- /dev/null +++ b/generators/comicbook/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp") -o $podir/okular_comicbook.pot diff --git a/generators/comicbook/autotests/comicbooktest.cpp b/generators/comicbook/autotests/comicbooktest.cpp new file mode 100644 index 0000000..79cdc62 --- /dev/null +++ b/generators/comicbook/autotests/comicbooktest.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2020 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "core/document.h" +#include "core/generator.h" +#include "core/observer.h" +#include "core/page.h" + +#include "../document.h" + +#include "settings_core.h" + +class ComicBookGeneratorTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testRotatedImage(); + void cleanupTestCase(); +}; + +void ComicBookGeneratorTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("ComicBookGeneratorTest")); +} + +void ComicBookGeneratorTest::cleanupTestCase() +{ +} + +void ComicBookGeneratorTest::testRotatedImage() +{ + ComicBook::Document document; + const QString testFile = QStringLiteral(KDESRCDIR "autotests/data/rotated_cb.cbz"); + QVERIFY(document.open(testFile)); + + QVector pagesVector; + document.pages(&pagesVector); + + const Okular::Page *p = pagesVector[0]; + QVERIFY(p->height() > p->width()); + + const QImage image = document.pageImage(0); + QVERIFY(image.height() > image.width()); +} + +QTEST_MAIN(ComicBookGeneratorTest) +#include "comicbooktest.moc" + +/* kate: replace-tabs on; tab-width 4; */ diff --git a/generators/comicbook/autotests/data/rotated_cb.cbz b/generators/comicbook/autotests/data/rotated_cb.cbz new file mode 100644 index 0000000000000000000000000000000000000000..469f795c819b96210052d10288d903cf3beb112f GIT binary patch literal 22493 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 literal 0 HcmV?d00001 diff --git a/generators/comicbook/debug_comicbook.h b/generators/comicbook/debug_comicbook.h new file mode 100644 index 0000000..69005c7 --- /dev/null +++ b/generators/comicbook/debug_comicbook.h @@ -0,0 +1,17 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_COMICBOOK_H +#define OKULAR_DEBUG_COMICBOOK_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularComicbookDebug) + +#endif diff --git a/generators/comicbook/directory.cpp b/generators/comicbook/directory.cpp new file mode 100644 index 0000000..3b84507 --- /dev/null +++ b/generators/comicbook/directory.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * Copyright (C) 2011 by David Palacio * + * * + * 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. * + ***************************************************************************/ + +#include "directory.h" + +#include +#include +#include +#include + +#include + +Directory::Directory() +{ +} + +Directory::~Directory() +{ +} + +bool Directory::open(const QString &dirName) +{ + mDir = dirName; + QFileInfo dirTest(dirName); + return dirTest.isDir() && dirTest.isReadable(); +} + +QStringList Directory::recurseDir(const QString &dirPath, int curDepth) const +{ + QDir dir(dirPath); + dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); + QStringList fileList; + QDirIterator it(dir); + QFileInfo info; + while (it.hasNext()) { + it.next(); + info = it.fileInfo(); + if (info.isDir() && curDepth < staticMaxDepth) { + fileList.append(recurseDir(info.filePath(), curDepth + 1)); + } else if (info.isFile()) { + fileList.append(info.filePath()); + } + } + return fileList; +} + +QStringList Directory::list() const +{ + return recurseDir(mDir, 0); +} + +QIODevice *Directory::createDevice(const QString &path) const +{ + std::unique_ptr file(new QFile(path)); + if (!file->open(QIODevice::ReadOnly)) + return nullptr; + + return file.release(); +} diff --git a/generators/comicbook/directory.h b/generators/comicbook/directory.h new file mode 100644 index 0000000..c042918 --- /dev/null +++ b/generators/comicbook/directory.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * Copyright (C) 2011 by David Palacio * + * * + * 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 DIRECTORY_H +#define DIRECTORY_H + +#include + +class QIODevice; + +class Directory +{ +public: + /** + * Creates a new directory object. + */ + Directory(); + + /** + * Destroys the directory object. + */ + ~Directory(); + + /** + * Opens given directory. + */ + bool open(const QString &dirName); + + /** + * Returns the list of files from the directory. + */ + QStringList list() const; + + /** + * Returns a new device for reading the file with the given path. + */ + QIODevice *createDevice(const QString &path) const; + +private: + /** + * Iterates over a directory and returns a file list. + */ + QStringList recurseDir(const QString &dir, int curDepth) const; + + static const int staticMaxDepth = 1; + QString mDir; +}; + +#endif diff --git a/generators/comicbook/document.cpp b/generators/comicbook/document.cpp new file mode 100644 index 0000000..6f4010f --- /dev/null +++ b/generators/comicbook/document.cpp @@ -0,0 +1,256 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "document.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#if WITH_K7ZIP +#include +#endif + +#include + +#include + +#include "debug_comicbook.h" +#include "directory.h" +#include "qnatsort.h" +#include "unrar.h" + +using namespace ComicBook; + +static void imagesInArchive(const QString &prefix, const KArchiveDirectory *dir, QStringList *entries) +{ + const QStringList entryList = dir->entries(); + for (const QString &file : entryList) { + const KArchiveEntry *e = dir->entry(file); + if (e->isDirectory()) { + imagesInArchive(prefix + file + QLatin1Char('/'), static_cast(e), entries); + } else if (e->isFile()) { + entries->append(prefix + file); + } + } +} + +Document::Document() + : mDirectory(nullptr) + , mUnrar(nullptr) + , mArchive(nullptr) +{ +} + +Document::~Document() +{ +} + +bool Document::open(const QString &fileName) +{ + close(); + + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); + + /** + * We have a zip archive + */ + if (mime.inherits(QStringLiteral("application/x-cbz")) || mime.inherits(QStringLiteral("application/zip"))) { + mArchive = new KZip(fileName); + + if (!processArchive()) { + return false; + } + /** + * We have a TAR archive + */ + } else if (mime.inherits(QStringLiteral("application/x-cbt")) || mime.inherits(QStringLiteral("application/x-gzip")) || mime.inherits(QStringLiteral("application/x-tar")) || mime.inherits(QStringLiteral("application/x-bzip"))) { + mArchive = new KTar(fileName); + + if (!processArchive()) { + return false; + } +#ifdef WITH_K7ZIP + /** + * We have a 7z archive + */ + } else if (mime.inherits(QStringLiteral("application/x-cb7")) || mime.inherits(QStringLiteral("application/x-7z-compressed"))) { + mArchive = new K7Zip(fileName); + + if (!processArchive()) { + return false; + } +#endif + } 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, neither unrar nor unarchiver were found."); + return false; + } + + if (!Unrar::isSuitableVersionAvailable()) { + mLastErrorString = i18n("The version of unrar on your system is not suitable for opening comicbooks."); + return false; + } + + /** + * We have a rar archive + */ + mUnrar = new Unrar(); + + if (!mUnrar->open(fileName)) { + delete mUnrar; + mUnrar = nullptr; + + return false; + } + + mEntries = mUnrar->list(); + } else if (mime.inherits(QStringLiteral("inode/directory"))) { + mDirectory = new Directory(); + + if (!mDirectory->open(fileName)) { + delete mDirectory; + mDirectory = nullptr; + + return false; + } + + mEntries = mDirectory->list(); + } else { + mLastErrorString = i18n("Unknown ComicBook format."); + return false; + } + + return true; +} + +void Document::close() +{ + mLastErrorString.clear(); + + if (!(mArchive || mUnrar || mDirectory)) + return; + + delete mArchive; + mArchive = nullptr; + delete mDirectory; + mDirectory = nullptr; + delete mUnrar; + mUnrar = nullptr; + mPageMap.clear(); + mEntries.clear(); +} + +bool Document::processArchive() +{ + if (!mArchive->open(QIODevice::ReadOnly)) { + delete mArchive; + mArchive = nullptr; + + return false; + } + + const KArchiveDirectory *directory = mArchive->directory(); + if (!directory) { + delete mArchive; + mArchive = nullptr; + + return false; + } + + mArchiveDir = directory; + + imagesInArchive(QString(), mArchiveDir, &mEntries); + + return true; +} + +void Document::pages(QVector *pagesVector) +{ + std::sort(mEntries.begin(), mEntries.end(), caseSensitiveNaturalOrderLessThen); + QScopedPointer dev; + + int count = 0; + pagesVector->clear(); + pagesVector->resize(mEntries.size()); + QImageReader reader; + reader.setAutoTransform(true); + for (const QString &file : qAsConst(mEntries)) { + if (mArchive) { + const KArchiveFile *entry = static_cast(mArchiveDir->entry(file)); + if (entry) { + dev.reset(entry->createDevice()); + } + } else if (mDirectory) { + dev.reset(mDirectory->createDevice(file)); + } else { + dev.reset(mUnrar->createDevice(file)); + } + + if (!dev.isNull()) { + reader.setDevice(dev.data()); + if (reader.canRead()) { + QSize pageSize = reader.size(); + if (reader.transformation() & QImageIOHandler::TransformationRotate90) { + pageSize.transpose(); + } + if (!pageSize.isValid()) { + const QImage i = reader.read(); + if (!i.isNull()) + pageSize = i.size(); + } + if (pageSize.isValid()) { + pagesVector->replace(count, new Okular::Page(count, pageSize.width(), pageSize.height(), Okular::Rotation0)); + mPageMap.append(file); + count++; + } else { + qCDebug(OkularComicbookDebug) << "Ignoring" << file << "doesn't seem to be an image even if QImageReader::canRead returned true"; + } + } + } + } + pagesVector->resize(count); +} + +QStringList Document::pageTitles() const +{ + return QStringList(); +} + +QImage Document::pageImage(int page) const +{ + if (mArchive) { + const KArchiveFile *entry = static_cast(mArchiveDir->entry(mPageMap[page])); + if (entry) { + std::unique_ptr dev(entry->createDevice()); + QImageReader reader(dev.get()); + reader.setAutoTransform(true); + return reader.read(); + } + } else if (mDirectory) { + return QImage(mPageMap[page]); + } else { + return QImage::fromData(mUnrar->contentOf(mPageMap[page])); + } + + return QImage(); +} + +QString Document::lastErrorString() const +{ + return mLastErrorString; +} + +Q_LOGGING_CATEGORY(OkularComicbookDebug, "org.kde.okular.generators.comicbook", QtWarningMsg) diff --git a/generators/comicbook/document.h b/generators/comicbook/document.h new file mode 100644 index 0000000..f59298a --- /dev/null +++ b/generators/comicbook/document.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 COMICBOOK_DOCUMENT_H +#define COMICBOOK_DOCUMENT_H + +#include + +class KArchiveDirectory; +class KArchive; +class QImage; +class Unrar; +class Directory; + +namespace Okular +{ +class Page; +} + +namespace ComicBook +{ +class Document +{ +public: + Document(); + ~Document(); + + bool open(const QString &fileName); + void close(); + + void pages(QVector *pagesVector); + QStringList pageTitles() const; + + QImage pageImage(int page) const; + + QString lastErrorString() const; + +private: + bool processArchive(); + + QStringList mPageMap; + Directory *mDirectory; + Unrar *mUnrar; + KArchive *mArchive; + const KArchiveDirectory *mArchiveDir; + QString mLastErrorString; + QStringList mEntries; +}; + +} + +#endif diff --git a/generators/comicbook/generator_comicbook.cpp b/generators/comicbook/generator_comicbook.cpp new file mode 100644 index 0000000..9323f28 --- /dev/null +++ b/generators/comicbook/generator_comicbook.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "generator_comicbook.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include "debug_comicbook.h" + +OKULAR_EXPORT_PLUGIN(ComicBookGenerator, "libokularGenerator_comicbook.json") + +ComicBookGenerator::ComicBookGenerator(QObject *parent, const QVariantList &args) + : Generator(parent, args) +{ + setFeature(Threaded); + setFeature(PrintNative); + setFeature(PrintToFile); +} + +ComicBookGenerator::~ComicBookGenerator() +{ +} + +bool ComicBookGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + if (!mDocument.open(fileName)) { + const QString errString = mDocument.lastErrorString(); + if (!errString.isEmpty()) + emit error(errString, -1); + return false; + } + + mDocument.pages(&pagesVector); + return true; +} + +bool ComicBookGenerator::doCloseDocument() +{ + mDocument.close(); + + return true; +} + +QImage ComicBookGenerator::image(Okular::PixmapRequest *request) +{ + int width = request->width(); + int height = request->height(); + + QImage image = mDocument.pageImage(request->pageNumber()); + + return image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); +} + +bool ComicBookGenerator::print(QPrinter &printer) +{ + QPainter p(&printer); + + QList pageList = Okular::FilePrinter::pageList(printer, document()->pages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + + for (int i = 0; i < pageList.count(); ++i) { + QImage image = mDocument.pageImage(pageList[i] - 1); + + if ((image.width() > printer.width()) || (image.height() > printer.height())) + + image = image.scaled(printer.width(), printer.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + + if (i != 0) + printer.newPage(); + + p.drawImage(0, 0, image); + } + + return true; +} + +#include "generator_comicbook.moc" diff --git a/generators/comicbook/generator_comicbook.h b/generators/comicbook/generator_comicbook.h new file mode 100644 index 0000000..c9d301e --- /dev/null +++ b/generators/comicbook/generator_comicbook.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 GENERATOR_COMICBOOK_H +#define GENERATOR_COMICBOOK_H + +#include + +#include "document.h" + +class ComicBookGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + ComicBookGenerator(QObject *parent, const QVariantList &args); + ~ComicBookGenerator() override; + + // [INHERITED] load a document and fill up the pagesVector + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + // [INHERITED] print document using already configured kprinter + bool print(QPrinter &printer) override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + +private: + ComicBook::Document mDocument; +}; + +#endif diff --git a/generators/comicbook/libokularGenerator_comicbook.json b/generators/comicbook/libokularGenerator_comicbook.json new file mode 100644 index 0000000..7943ed7 --- /dev/null +++ b/generators/comicbook/libokularGenerator_comicbook.json @@ -0,0 +1,173 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "tokoe@kde.org", + "Name": "Tobias Koenig", + "Name[az]": "Tobias Koenig", + "Name[ca@valencia]": "Tobias Koenig", + "Name[ca]": "Tobias Koenig", + "Name[cs]": "Tobias Koenig", + "Name[da]": "Tobias Koenig", + "Name[de]": "Tobias Koenig", + "Name[el]": "Tobias Koenig", + "Name[en_GB]": "Tobias Koenig", + "Name[es]": "Tobias Koenig", + "Name[et]": "Tobias Koenig", + "Name[eu]": "Tobias Koenig", + "Name[fi]": "Tobias Koenig", + "Name[fr]": "Tobias Koenig", + "Name[gl]": "Tobias Koenig", + "Name[ia]": "Tobias Koenig", + "Name[it]": "Tobias Koenig", + "Name[ko]": "Tobias Koenig", + "Name[lt]": "Tobias Koenig", + "Name[nl]": "Tobias Koenig", + "Name[nn]": "Tobias König", + "Name[pl]": "Tobias Koenig", + "Name[pt]": "Tobias Koenig", + "Name[pt_BR]": "Tobias Koenig", + "Name[ru]": "Tobias König", + "Name[sk]": "Tobias Koenig", + "Name[sl]": "Tobias Koenig", + "Name[sr@ijekavian]": "Тобијас Кениг", + "Name[sr@ijekavianlatin]": "Tobijas Kenig", + "Name[sr@latin]": "Tobijas Kenig", + "Name[sr]": "Тобијас Кениг", + "Name[sv]": "Tobias Koenig", + "Name[tr]": "Tobias Koenig", + "Name[uk]": "Tobias Koenig", + "Name[x-test]": "xxTobias Koenigxx", + "Name[zh_CN]": "Tobias Koenig", + "Name[zh_TW]": "Tobias Koenig" + } + ], + "Copyright": "© 2007-2008 Tobias Koenig", + "Copyright[az]": "© 2007-2008 Tobias Koenig", + "Copyright[ca@valencia]": "© 2007-2008 Tobias Koenig", + "Copyright[ca]": "© 2007-2008 Tobias Koenig", + "Copyright[cs]": "© 2007-2008 Tobias Koenig", + "Copyright[da]": "© 2007-2008 Tobias Koenig", + "Copyright[de]": "© 2007-2008 Tobias Koenig", + "Copyright[el]": "© 2007-2008 Tobias Koenig", + "Copyright[en_GB]": "© 2007-2008 Tobias Koenig", + "Copyright[es]": "© 2007-2008 Tobias Koenig", + "Copyright[et]": "© 2007-2008: Tobias Koenig", + "Copyright[eu]": "© 2007-2008 Tobias Koenig", + "Copyright[fi]": "© 2007–2008 Tobias Koenig", + "Copyright[fr]": "© 2007-2008 Tobias Koenig", + "Copyright[gl]": "© 2007-2008 Tobias Koenig", + "Copyright[ia]": "© 2007-2008 Tobias Koenig", + "Copyright[it]": "© 2007-2008 Tobias Koenig", + "Copyright[ko]": "© 2007-2008 Tobias Koenig", + "Copyright[lt]": "© 2007-2008 Tobias Koenig", + "Copyright[nl]": "© 2007-2008 Tobias Koenig", + "Copyright[nn]": "© 2007–2008 Tobias König", + "Copyright[pl]": "© 2007-2008 Tobias Koenig", + "Copyright[pt]": "© 2007-2008 Tobias Koenig", + "Copyright[pt_BR]": "© 2007-2008 Tobias Koenig", + "Copyright[ru]": "© Tobias König, 2007-2008", + "Copyright[sk]": "© 2007-2008 Tobias Koenig", + "Copyright[sl]": "© 2007-2008 Tobias Koenig", + "Copyright[sr@ijekavian]": "© 2007–2008, Тобијас Кениг", + "Copyright[sr@ijekavianlatin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr@latin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr]": "© 2007–2008, Тобијас Кениг", + "Copyright[sv]": "© 2007-2008 Tobias Koenig", + "Copyright[tr]": "© 2007-2008 Tobias Koenig", + "Copyright[uk]": "© Tobias Koenig, 2007–2008", + "Copyright[x-test]": "xx© 2007-2008 Tobias Koenigxx", + "Copyright[zh_CN]": "© 2007-2008 Tobias Koenig", + "Copyright[zh_TW]": "© 2007-2008 Tobias Koenig", + "Description": "A renderer for various comic book formats", + "Description[az]": "Dəyişkən komiks formatları tərtibatçısı", + "Description[ca@valencia]": "Un renderitzador per a diversos formats de ComicBook", + "Description[ca]": "Un renderitzador per a diversos formats de ComicBook", + "Description[cs]": "Vykreslovač různých formátů knih komiksů", + "Description[da]": "En gengiver til diverse tegneserierformater", + "Description[de]": "Ein Renderer für verschiedene Comic-Book-Formate", + "Description[el]": "Πρόγραμμα αποτύπωσης για διάφορους τύπους comic book", + "Description[en_GB]": "A renderer for various comic book formats", + "Description[es]": "Un visor para diversos formatos de libros de cómics", + "Description[et]": "Mitmesuguste koomiksivormingute renderdaja", + "Description[eu]": "Hainbat Komiki-liburu formatuentzako errendatzaile bat", + "Description[fi]": "Eri sarjakuvakirjamuotojen hahmonnin", + "Description[fr]": "Un système de rendu pour divers formats de livres de BD", + "Description[gl]": "Un visor de varios formatos de banda deseñada", + "Description[ia]": "Un rendition pro varie formatos de libros comic", + "Description[it]": "Un visualizzatore per vari formati di strisce a fumetti", + "Description[ko]": "다양한 만화책 형식 렌더러", + "Description[lt]": "Ä®vairių komiksų knygų formatų atvaizdavimas", + "Description[nl]": "Een viewer voor diverse ComicBook-formaten", + "Description[nn]": "Ein gjengjevar for ulike teikneserieformat", + "Description[pl]": "Wyświetlanie różnych formatów komiksów", + "Description[pt]": "Um visualizador de diversos formatos de banda desenhada", + "Description[pt_BR]": "Um interpretador de vários formatos de histórias em quadrinhos", + "Description[ru]": "Модуль поддержки различных форматов комиксов", + "Description[sk]": "Vykresľovanie rôznych formátov kníh komiksov", + "Description[sl]": "Izrisovalnik za različne vrste stripov", + "Description[sr@ijekavian]": "Рендерер различитих формата стрипова", + "Description[sr@ijekavianlatin]": "Renderer različitih formata stripova", + "Description[sr@latin]": "Renderer različitih formata stripova", + "Description[sr]": "Рендерер различитих формата стрипова", + "Description[sv]": "Ett Ã¥tergivningsprogram för diverse format för serieböcker", + "Description[tr]": "Çeşitli çizgi roman biçimleri için bir oluşturucu", + "Description[uk]": "Програма для відображення коміксів у різних форматах", + "Description[x-test]": "xxA renderer for various comic book formatsxx", + "Description[zh_CN]": "多种漫画书格式的渲染器", + "Description[zh_TW]": "多種漫畫書的成像器", + "Id": "okular_comicbook", + "License": "GPL", + "MimeTypes": [ + "application/x-cbz", + "application/x-cbr", + "application/x-cbt", + "application/x-cb7", + "inode/directory" + ], + "Name": "ComicBook Backend", + "Name[az]": "ComicBook modulu", + "Name[ca@valencia]": "Dorsal ComicBook", + "Name[ca]": "Dorsal ComicBook", + "Name[cs]": "Podpůrná vrstva ComicBook", + "Name[da]": "ComicBook-backend", + "Name[de]": "Anzeigemodul für Comic-Book", + "Name[el]": "Σύστημα υποστήριξης ComicBook", + "Name[en_GB]": "ComicBook Backend", + "Name[es]": "Motor para ComicBook", + "Name[et]": "ComicBooki taustaprogramm", + "Name[eu]": "ComicBook-en bizkarraldekoa", + "Name[fi]": "ComicBook-taustaosa", + "Name[fr]": "Moteur pour les livres de BD", + "Name[gl]": "Infraestrutura para ComicBook", + "Name[ia]": "Retro-Administration de libros de comic", + "Name[it]": "Backend ComicBook", + "Name[ko]": "만화책 백엔드", + "Name[lt]": "ComicBook programinė sąsaja", + "Name[nl]": "ComicBook-backend", + "Name[nn]": "ComicBook-motor", + "Name[pl]": "Obsługa ComicBook", + "Name[pt]": "Infra-Estrutura de ComicBook (BD)", + "Name[pt_BR]": "Infraestrutura ComicBook", + "Name[ru]": "Модуль поддержки формата ComicBook", + "Name[sk]": "Backend pre knihy komiksov", + "Name[sl]": "Zaledje za stripe", + "Name[sr@ijekavian]": "Позадина за комикбук", + "Name[sr@ijekavianlatin]": "Pozadina za ComicBook", + "Name[sr@latin]": "Pozadina za ComicBook", + "Name[sr]": "Позадина за комикбук", + "Name[sv]": "Comic Book-gränssnitt", + "Name[tr]": "ComicBook Arka Ucu", + "Name[uk]": "Модуль коміксів", + "Name[x-test]": "xxComicBook Backendxx", + "Name[zh_CN]": "漫画书后端", + "Name[zh_TW]": "ComicBook 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.4" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/comicbook/okularApplication_comicbook.desktop b/generators/comicbook/okularApplication_comicbook.desktop new file mode 100755 index 0000000..f65048a --- /dev/null +++ b/generators/comicbook/okularApplication_comicbook.desktop @@ -0,0 +1,205 @@ +[Desktop Entry] +MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[az]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[ca]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[ca@valencia]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[cs]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[da]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[de]=cbr, cbz, cbt, cb7, Comic-Book +X-KDE-Keywords[el]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[en_GB]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[es]=cbr, cbz, cbt, cb7, libro de cómic +X-KDE-Keywords[et]=cbr, cbz, cbt, cb7, Comic Book, koomiks +X-KDE-Keywords[eu]=cbr, cbz, cbt, cb7, komiki-liburua +X-KDE-Keywords[fi]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[fr]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[gl]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[hu]=cbr, cbz, cbt, cb7, Képregény +X-KDE-Keywords[ia]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[it]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[ko]=cbr, cbz, cbt, cb7, Comic Book, 만화책, 만화 +X-KDE-Keywords[lt]=cbr, cbz, cbt, cb7, Comic Book, komiksų knygos, komiksu knygos +X-KDE-Keywords[nl]=cbr, cbz, cbt, cbz, Stripverhaal +X-KDE-Keywords[nn]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[pl]=cbr, cbz, cbt, cb7, Komiks +X-KDE-Keywords[pt]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[pt_BR]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[ru]=cbr, cbz, cbt, cb7, Comic Book, комикс +X-KDE-Keywords[sk]=cbr, cbz, cbt, cb7, Kniha komiksov +X-KDE-Keywords[sl]=cbr, cbz, cbt, cbt7, strip +X-KDE-Keywords[sv]=cbr, cbz, cbt, cb7, Comic Book +X-KDE-Keywords[uk]=cbr,cbz,cbt,cb7,комікс +X-KDE-Keywords[x-test]=xxcbrxx,xx cbzxx,xx cbtxx,xx cb7xx,xx Comic Bookxx +X-KDE-Keywords[zh_CN]=cbr, cbz, cbt, cb7, Comic Book, 漫画书, 漫画, 连环画 +X-KDE-Keywords[zh_TW]=cbr, cbz, cbt, cb7, Comic Book, 漫畫, 漫畫書 diff --git a/generators/comicbook/okularComicbook.desktop b/generators/comicbook/okularComicbook.desktop new file mode 100644 index 0000000..009d351 --- /dev/null +++ b/generators/comicbook/okularComicbook.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7; diff --git a/generators/comicbook/org.kde.mobile.okular_comicbook.desktop b/generators/comicbook/org.kde.mobile.okular_comicbook.desktop new file mode 100644 index 0000000..f875dc3 --- /dev/null +++ b/generators/comicbook/org.kde.mobile.okular_comicbook.desktop @@ -0,0 +1,202 @@ +[Desktop Entry] +MimeType=application/x-cbz;application/x-cbr;application/x-cbt;application/x-cb7; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[az]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[ca]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[ca@valencia]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[cs]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[da]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[de]=cbr, cbz, cbt, Comic-Book +X-KDE-Keywords[el]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[en_GB]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[es]=cbr, cbz, cbt, libro de cómic +X-KDE-Keywords[et]=cbr, cbz, cbt, Comic Book, koomiks +X-KDE-Keywords[eu]=cbr, cbz, cbt, komiki-liburua +X-KDE-Keywords[fi]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[fr]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[gl]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[hu]=cbr, cbz, cbt, Képregény +X-KDE-Keywords[ia]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[it]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[ja]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[ko]=cbr, cbz, cbt, Comic Book,만화책 +X-KDE-Keywords[lt]=cbr, cbz, cbt, Comic Book, komiksų knygos, komiksu knygos +X-KDE-Keywords[nb]=cbr, cbz, cbt, tegneserie +X-KDE-Keywords[nl]=cbr, cbz, cbt, Stripverhaal +X-KDE-Keywords[nn]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[pl]=cbr, cbz, cbt, Komiks +X-KDE-Keywords[pt]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[pt_BR]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[ru]=cbr, cbz, cbt, Comic Book, комикс +X-KDE-Keywords[sk]=cbr, cbz, cbt, Kniha komiksov +X-KDE-Keywords[sl]=cbr, cbz, cbt, strip +X-KDE-Keywords[sr]=cbr, cbz, cbt, Comic Book,комикбук +X-KDE-Keywords[sr@ijekavian]=cbr, cbz, cbt, Comic Book,комикбук +X-KDE-Keywords[sr@ijekavianlatin]=cbr, cbz, cbt, Comic Book,ComicBook +X-KDE-Keywords[sr@latin]=cbr, cbz, cbt, Comic Book,ComicBook +X-KDE-Keywords[sv]=cbr, cbz, cbt, Comic Book +X-KDE-Keywords[uk]=cbr,cbz,cbt,комікс +X-KDE-Keywords[x-test]=xxcbrxx,xx cbzxx,xx cbtxx,xx Comic Bookxx +X-KDE-Keywords[zh_CN]=cbr, cbz, cbt, Comic Book,漫画书,漫画,连环画 +X-KDE-Keywords[zh_TW]=cbr, cbz, cbt, Comic Book, 漫畫, 漫畫書 diff --git a/generators/comicbook/org.kde.okular-comicbook.metainfo.xml b/generators/comicbook/org.kde.okular-comicbook.metainfo.xml new file mode 100644 index 0000000..7debefc --- /dev/null +++ b/generators/comicbook/org.kde.okular-comicbook.metainfo.xml @@ -0,0 +1,94 @@ + + + org.kde.okular-comicbook + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Comic Books + Comic Books + Llibres de còmic + Llibres de còmic + Komiksy + Comic-Buch + Comic Books + Comic Books + Libros de cómics + Koomiksid + Komiki-liburuak + Sarjakuvakirjat + Bandes dessinées + Libros de banda deseñada + Libros de Comic + Fumetti + 만화책 + Komiksų knygos + കോമിക് പുസ്തകങ്ങള്‍ + Stripboeken + Teikneseriar + Komiksy + Banda Desenhada + Comic Books + Комиксы + Knihy komiksov + Stripi + Стрипови + Stripovi + Стрипови + Stripovi + Comic Book + Çizgiromanlar + Комікси + xxComic Booksxx + 漫画书 + 漫畫書 + Adds support for reading comic books + Komiks sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir llibres de còmic + Afig la implementació per a llegir llibres de còmic + Přidává podporu pro čtení komiksů + Bietet Unterstützung zum Lesen von Comic-Büchern + Προσθέτει υποστήριξη για την ανάγνωση comic books + Adds support for reading comic books + Permite la lectura de libros de cómics + Koomiksite lugemise toetus + Komiki-liburuak irakurtzeko euskarria gehitzen du + Lisää sarjakuvakirjojen lukutuen + Permet la lecture des bandes dessinées + Engade a posibilidade de ler libros de banda deseñada + Adde supporto per leger libros de comic + Aggiunge il supporto per la lettura di fumetti + 만화책 읽기 지원 추가 + Prideda palaikymą komiksų knygų skaitymui + കോമിക്ക് പുസ്തകങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van stripboeken toe + Legg til støtte for Ã¥ lesa teikneseriefiler + Dodaje obsługę komiksów + Adiciona o suporte para ler livros de banda desenhada + Adiciona o suporte para leitura de comic books + Поддержка чтения комиксов + Pridá podporu pre čítanie komiksov + Doda podporo za branje stripov + Подршка за читање стрипова + PodrÅ¡ka za čitanje stripova + Подршка за читање стрипова + PodrÅ¡ka za čitanje stripova + Lägger till stöd för att läsa Comic Book + Çizgi roman okuma desteği ekler + Додає підтримку читання коміксів + xxAdds support for reading comic booksxx + 增加对漫画书的阅读支持 + 加入讀取漫畫書的支援 + + application/x-cbr + application/x-cbz + application/x-cbt + application/x-cb7 + + https://okular.kde.org + + + + + + + diff --git a/generators/comicbook/qnatsort.cpp b/generators/comicbook/qnatsort.cpp new file mode 100644 index 0000000..d2d1fcd --- /dev/null +++ b/generators/comicbook/qnatsort.cpp @@ -0,0 +1,160 @@ +/** + Natural order sorting of strings which contains numbers. + + Copyright 2007 Tobias Koenig + based on the natural order code by Martin Pool + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 or at your option version 3 as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "qnatsort.h" + +static int compare_right(const QString &leftStr, int left, const QString &rightStr, int right) +{ + int bias = 0; + + /** + * The longest run of digits wins. That aside, the greatest + * value wins, but we can't know that it will until we've scanned + * both numbers to know that they have the same magnitude, so we + * remember it in BIAS. + */ + for (;; left++, right++) { + if (left >= leftStr.length() && right < rightStr.length()) + return -1; + else if (right >= rightStr.length() && left < leftStr.length()) + return +1; + else if (right >= rightStr.length() && left >= leftStr.length()) + return bias; + else if (!leftStr[left].isDigit() && !rightStr[right].isDigit()) + return bias; + else if (!leftStr[left].isDigit()) + return -1; + else if (!rightStr[right].isDigit()) + return +1; + else if (leftStr[left] < rightStr[right]) { + if (!bias) + bias = -1; + } else if (leftStr[left] > rightStr[right]) { + if (!bias) + bias = +1; + } else if (leftStr[left].isNull() && rightStr[right].isNull()) + return bias; + } + + return 0; +} + +static int compare_left(const QString &leftStr, int left, const QString &rightStr, int right) +{ + /** + * Compare two left-aligned numbers: the first to have a + * different value wins. + */ + for (;; left++, right++) { + if (left >= leftStr.length() && right < rightStr.length()) + return -1; + else if (right >= rightStr.length() && left < leftStr.length()) + return +1; + else if (right >= rightStr.length() && left >= leftStr.length()) + return 0; + else if (!leftStr[left].isDigit() && !rightStr[right].isDigit()) + return 0; + else if (!leftStr[left].isDigit()) + return -1; + else if (!rightStr[right].isDigit()) + return +1; + else if (leftStr[left] < rightStr[right]) + return -1; + else if (leftStr[left] > rightStr[right]) + return +1; + } + + return 0; +} + +static int natural_order_compare(const QString &leftStr, const QString &rightStr, bool fold_case) +{ + if (leftStr.isEmpty() && rightStr.isEmpty()) + return 0; + + int ai, bi; + QChar ca, cb; + int fractional, result; + + ai = bi = 0; + const int aSize = leftStr.size(); + const int bSize = rightStr.size(); + + while (true) { + ca = leftStr[ai]; + cb = rightStr[bi]; + + /* skip over leading spaces or zeros */ + while (ca.isSpace() && ++ai < aSize) + ca = leftStr[ai]; + + while (cb.isSpace() && ++bi < bSize) + cb = rightStr[bi]; + + /* process run of digits */ + if (ca.isDigit() && cb.isDigit()) { + fractional = (ca == QLatin1Char('0') || cb == QLatin1Char('0')); + + if (fractional) { + if ((result = compare_left(leftStr, ai, rightStr, bi)) != 0) + return result; + } else { + if ((result = compare_right(leftStr, ai, rightStr, bi)) != 0) + return result; + } + } + + if (ca.isNull() && cb.isNull()) { + /* The strings compare the same. Perhaps the caller + will want to call strcmp to break the tie. */ + return 0; + } + + if (fold_case) { + ca = ca.toUpper(); + cb = cb.toUpper(); + } + + if (ca < cb) + return -1; + else if (ca > cb) + return +1; + + ++ai; + ++bi; + if (aSize == ai) { + return aSize <= bSize ? -1 : 1; + } + if (bSize == bi) { + return bSize <= aSize ? 1 : -1; + } + } +} + +bool caseSensitiveNaturalOrderLessThen(const QString &left, const QString &right) +{ + return (natural_order_compare(left, right, false) < 0); +} + +bool caseInsensitiveNaturalOrderLessThen(const QString &left, const QString &right) +{ + return (natural_order_compare(left, right, true) < 0); +} diff --git a/generators/comicbook/qnatsort.h b/generators/comicbook/qnatsort.h new file mode 100644 index 0000000..13a2532 --- /dev/null +++ b/generators/comicbook/qnatsort.h @@ -0,0 +1,54 @@ +/** + Natural order sorting of strings which contains numbers. + + Copyright 2007 Tobias Koenig + based on the natural order code by Martin Pool + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License version 2 or at your option version 3 as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef QNATSORT_H +#define QNATSORT_H + +#include + +/** + * The two methods can be used in qSort to sort strings which contain + * numbers in natural order. + * + * Normally strings are ordered like this: fam10g fam1g fam2g fam3g + * natural ordered it would look like this: fam1g fam2g fam3g fam10g + * + * Code: + * + * QStringList list; + * list << "fam10g" << "fam1g" << "fam2g" << "fam5g"; + * + * qSort( list.begin(), list.end(), caseSensitiveNaturalOderLessThen ); + */ + +/** + * Returns whether the @p left string is lesser than the @p right string + * in natural order. + */ +bool caseSensitiveNaturalOrderLessThen(const QString &left, const QString &right); + +/** + * Returns whether the @p left string is lesser than the @p right string + * in natural order and case insensitive. + */ +bool caseInsensitiveNaturalOrderLessThen(const QString &left, const QString &right); + +#endif diff --git a/generators/comicbook/unrar.cpp b/generators/comicbook/unrar.cpp new file mode 100644 index 0000000..cdc442a --- /dev/null +++ b/generators/comicbook/unrar.cpp @@ -0,0 +1,294 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "unrar.h" + +#include +#include +#include +#include +#include + +#include +#if defined(WITH_KPTY) +#include +#include +#endif + +#include "debug_comicbook.h" + +#include +#include + +struct UnrarHelper { + UnrarHelper(); + ~UnrarHelper(); + + UnrarHelper(const UnrarHelper &) = delete; + UnrarHelper &operator=(const UnrarHelper &) = delete; + + UnrarFlavour *kind; + QString unrarPath; + QString lsarPath; +}; + +Q_GLOBAL_STATIC(UnrarHelper, helper) + +static UnrarFlavour *detectUnrar(const QString &unrarPath, const QString &versionCommand) +{ + UnrarFlavour *kind = nullptr; + QProcess proc; + proc.start(unrarPath, QStringList() << versionCommand); + bool ok = proc.waitForFinished(-1); + Q_UNUSED(ok) + const QStringList lines = QString::fromLocal8Bit(proc.readAllStandardOutput()).split(QLatin1Char('\n'), QString::SkipEmptyParts); + if (!lines.isEmpty()) { + if (lines.first().startsWith(QLatin1String("UNRAR "))) + kind = new NonFreeUnrarFlavour(); + else if (lines.first().startsWith(QLatin1String("RAR "))) + kind = new NonFreeUnrarFlavour(); + else if (lines.first().startsWith(QLatin1String("unrar "))) + kind = new FreeUnrarFlavour(); + else if (lines.first().startsWith(QLatin1String("v"))) + kind = new UnarFlavour(); + } + return kind; +} + +UnrarHelper::UnrarHelper() + : kind(nullptr) +{ + QString path = QStandardPaths::findExecutable(QStringLiteral("lsar")); + + if (!path.isEmpty()) { + lsarPath = path; + } + + path = QStandardPaths::findExecutable(QStringLiteral("unrar-nonfree")); + + if (path.isEmpty()) + path = QStandardPaths::findExecutable(QStringLiteral("unrar")); + if (path.isEmpty()) + path = QStandardPaths::findExecutable(QStringLiteral("rar")); + if (path.isEmpty()) + path = QStandardPaths::findExecutable(QStringLiteral("unar")); + + if (!path.isEmpty()) + kind = detectUnrar(path, QStringLiteral("--version")); + + if (!kind) + kind = detectUnrar(path, QStringLiteral("-v")); + + if (!kind) { + // no luck, print that + qWarning() << "Neither unrar nor unarchiver were found."; + } else { + unrarPath = path; + qCDebug(OkularComicbookDebug) << "detected:" << path << "(" << kind->name() << ")"; + } +} + +UnrarHelper::~UnrarHelper() +{ + delete kind; +} + +Unrar::Unrar() + : QObject(nullptr) + , mLoop(nullptr) + , mTempDir(nullptr) +{ +} + +Unrar::~Unrar() +{ + delete mTempDir; +} + +bool Unrar::open(const QString &fileName) +{ + if (!isSuitableVersionAvailable()) + return false; + + delete mTempDir; + mTempDir = new QTemporaryDir(); + + mFileName = fileName; + + /** + * Extract the archive to a temporary directory + */ + mStdOutData.clear(); + mStdErrData.clear(); + + const int ret = startSyncProcess(helper->kind->processOpenArchiveArgs(mFileName, mTempDir->path())); + bool ok = ret == 0; + + return ok; +} + +QStringList Unrar::list() +{ + mStdOutData.clear(); + mStdErrData.clear(); + + if (!isSuitableVersionAvailable()) + return QStringList(); + + startSyncProcess(helper->kind->processListArgs(mFileName)); + + QStringList listFiles = helper->kind->processListing(QString::fromLocal8Bit(mStdOutData).split(QLatin1Char('\n'), QString::SkipEmptyParts)); + + QString subDir; + + if (listFiles.last().endsWith(QLatin1Char('/')) && helper->kind->name() == QLatin1String("unar")) { + // Subfolder detected. The unarchiver is unable to extract all files into a single folder + subDir = listFiles.last(); + listFiles.removeLast(); + } + + QStringList newList; + for (const QString &f : qAsConst(listFiles)) { + // Extract all the files to mTempDir regardless of their path inside the archive + // This will break if ever an arvhice with two files with the same name in different subfolders + QFileInfo fi(f); + if (QFile::exists(mTempDir->path() + QLatin1Char('/') + subDir + fi.fileName())) { + newList.append(subDir + fi.fileName()); + } + } + return newList; +} + +QByteArray Unrar::contentOf(const QString &fileName) const +{ + if (!isSuitableVersionAvailable()) + return QByteArray(); + + QFile file(mTempDir->path() + QLatin1Char('/') + fileName); + if (!file.open(QIODevice::ReadOnly)) + return QByteArray(); + + return file.readAll(); +} + +QIODevice *Unrar::createDevice(const QString &fileName) const +{ + if (!isSuitableVersionAvailable()) + return nullptr; + + std::unique_ptr file(new QFile(mTempDir->path() + QLatin1Char('/') + fileName)); + if (!file->open(QIODevice::ReadOnly)) + return nullptr; + + return file.release(); +} + +bool Unrar::isAvailable() +{ + return helper->kind; +} + +bool Unrar::isSuitableVersionAvailable() +{ + if (!isAvailable()) + return false; + + if (dynamic_cast(helper->kind) || dynamic_cast(helper->kind)) + return true; + else + return false; +} + +void Unrar::readFromStdout() +{ + if (!mProcess) + return; + + mStdOutData += mProcess->readAllStandardOutput(); +} + +void Unrar::readFromStderr() +{ + if (!mProcess) + return; + + mStdErrData += mProcess->readAllStandardError(); + if (!mStdErrData.isEmpty()) { + mProcess->kill(); + return; + } +} + +void Unrar::finished(int exitCode, QProcess::ExitStatus exitStatus) +{ + Q_UNUSED(exitCode) + if (mLoop) { + mLoop->exit(exitStatus == QProcess::CrashExit ? 1 : 0); + } +} + +int Unrar::startSyncProcess(const ProcessArgs &args) +{ + int ret = 0; + +#if !defined(WITH_KPTY) + mProcess = new QProcess(this); + connect(mProcess, &QProcess::readyReadStandardOutput, this, &Unrar::readFromStdout); + connect(mProcess, &QProcess::readyReadStandardError, this, &Unrar::readFromStderr); + connect(mProcess, static_cast(&QProcess::finished), this, &Unrar::finished); + +#else + mProcess = new KPtyProcess(this); + mProcess->setOutputChannelMode(KProcess::SeparateChannels); + connect(mProcess, &KPtyProcess::readyReadStandardOutput, this, &Unrar::readFromStdout); + connect(mProcess, &KPtyProcess::readyReadStandardError, this, &Unrar::readFromStderr); + connect(mProcess, static_cast(&KPtyProcess::finished), this, &Unrar::finished); + +#endif + +#if !defined(WITH_KPTY) + if (helper->kind->name() == QLatin1String("unar") && args.useLsar) { + mProcess->start(helper->lsarPath, args.appArgs, QIODevice::ReadWrite | QIODevice::Unbuffered); + } else { + mProcess->start(helper->unrarPath, args.appArgs, QIODevice::ReadWrite | QIODevice::Unbuffered); + } + + ret = mProcess->waitForFinished(-1) ? 0 : 1; +#else + if (helper->kind->name() == QLatin1String("unar") && args.useLsar) { + mProcess->setProgram(helper->lsarPath, args.appArgs); + } else { + mProcess->setProgram(helper->unrarPath, args.appArgs); + } + + mProcess->setNextOpenMode(QIODevice::ReadWrite | QIODevice::Unbuffered); + mProcess->start(); + QEventLoop loop; + mLoop = &loop; + ret = loop.exec(QEventLoop::WaitForMoreEvents | QEventLoop::ExcludeUserInputEvents); + mLoop = nullptr; +#endif + + delete mProcess; + mProcess = nullptr; + + return ret; +} + +void Unrar::writeToProcess(const QByteArray &data) +{ + if (!mProcess || data.isNull()) + return; + +#if !defined(WITH_KPTY) + mProcess->write(data); +#else + mProcess->pty()->write(data); +#endif +} diff --git a/generators/comicbook/unrar.h b/generators/comicbook/unrar.h new file mode 100644 index 0000000..3881c06 --- /dev/null +++ b/generators/comicbook/unrar.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 UNRAR_H +#define UNRAR_H + +#include +#include +#include + +#include + +class QEventLoop; +class QTemporaryDir; + +#if defined(WITH_KPTY) +class KPtyProcess; +#endif + +class Unrar : public QObject +{ + Q_OBJECT + +public: + /** + * Creates a new unrar object. + */ + Unrar(); + + /** + * Destroys the unrar object. + */ + ~Unrar() override; + + /** + * Opens given rar archive. + */ + bool open(const QString &fileName); + + /** + * Returns the list of files from the archive. + */ + QStringList list(); + + /** + * Returns the content of the file with the given name. + */ + QByteArray contentOf(const QString &fileName) const; + + /** + * Returns a new device for reading the file with the given name. + */ + QIODevice *createDevice(const QString &fileName) const; + + static bool isAvailable(); + static bool isSuitableVersionAvailable(); + +private Q_SLOTS: + void readFromStdout(); + void readFromStderr(); + void finished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + int startSyncProcess(const ProcessArgs &args); + void writeToProcess(const QByteArray &data); + +#if defined(WITH_KPTY) + KPtyProcess *mProcess; +#else + QProcess *mProcess; +#endif + QEventLoop *mLoop; + QString mFileName; + QByteArray mStdOutData; + QByteArray mStdErrData; + QTemporaryDir *mTempDir; +}; + +#endif diff --git a/generators/comicbook/unrarflavours.cpp b/generators/comicbook/unrarflavours.cpp new file mode 100644 index 0000000..c3bd5f6 --- /dev/null +++ b/generators/comicbook/unrarflavours.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "unrarflavours.h" + +#include + +ProcessArgs::ProcessArgs() +{ +} + +ProcessArgs::ProcessArgs(const QStringList &args, bool lsar) + : appArgs {args} + , useLsar {lsar} +{ +} + +UnrarFlavour::UnrarFlavour() +{ +} + +UnrarFlavour::~UnrarFlavour() +{ +} + +void UnrarFlavour::setFileName(const QString &fileName) +{ + mFileName = fileName; +} + +QString UnrarFlavour::fileName() const +{ + return mFileName; +} + +NonFreeUnrarFlavour::NonFreeUnrarFlavour() + : UnrarFlavour() +{ +} + +QStringList NonFreeUnrarFlavour::processListing(const QStringList &data) +{ + // unrar-nonfree just lists the files + return data; +} + +QString NonFreeUnrarFlavour::name() const +{ + return QStringLiteral("unrar-nonfree"); +} + +ProcessArgs NonFreeUnrarFlavour::processListArgs(const QString &fileName) const +{ + return ProcessArgs(QStringList() << QStringLiteral("lb") << fileName, false); +} + +ProcessArgs NonFreeUnrarFlavour::processOpenArchiveArgs(const QString &fileName, const QString &path) const +{ + return ProcessArgs(QStringList() << QStringLiteral("e") << fileName << path + QLatin1Char('/'), false); +} + +FreeUnrarFlavour::FreeUnrarFlavour() + : UnrarFlavour() +{ +} + +QStringList FreeUnrarFlavour::processListing(const QStringList &data) +{ + QRegularExpression re(QStringLiteral("^ ([^/]+/([^\\s]+))$")); + + QStringList newdata; + for (const QString &line : data) { + QRegularExpressionMatch match = re.match(line); + if (match.hasMatch()) { + newdata.append(match.captured(1)); + } + } + return newdata; +} + +QString FreeUnrarFlavour::name() const +{ + return QStringLiteral("unrar-free"); +} + +ProcessArgs FreeUnrarFlavour::processListArgs(const QString &) const +{ + return ProcessArgs(); +} + +ProcessArgs FreeUnrarFlavour::processOpenArchiveArgs(const QString &, const QString &) const +{ + return ProcessArgs(); +} + +UnarFlavour::UnarFlavour() + : UnrarFlavour() +{ +} + +QStringList UnarFlavour::processListing(const QStringList &data) +{ + QStringList newdata = data; + + newdata.removeFirst(); + + return newdata; +} + +QString UnarFlavour::name() const +{ + return QStringLiteral("unar"); +} + +ProcessArgs UnarFlavour::processListArgs(const QString &fileName) const +{ + return ProcessArgs(QStringList() << fileName, true); +} + +ProcessArgs UnarFlavour::processOpenArchiveArgs(const QString &fileName, const QString &path) const +{ + return ProcessArgs(QStringList() << fileName << QStringLiteral("-o") << path + QLatin1Char('/'), false); +} diff --git a/generators/comicbook/unrarflavours.h b/generators/comicbook/unrarflavours.h new file mode 100644 index 0000000..4b2f445 --- /dev/null +++ b/generators/comicbook/unrarflavours.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2007 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 UNRARFLAVOURS_H +#define UNRARFLAVOURS_H + +#include +#include + +struct ProcessArgs { + ProcessArgs(); + ProcessArgs(const QStringList &appArgs, bool useLsar); + + QStringList appArgs; + bool useLsar; +}; + +class QStringList; + +class UnrarFlavour +{ +public: + virtual ~UnrarFlavour(); + + UnrarFlavour(const UnrarFlavour &) = delete; + UnrarFlavour &operator=(const UnrarFlavour &) = delete; + + virtual QStringList processListing(const QStringList &data) = 0; + virtual QString name() const = 0; + + virtual ProcessArgs processListArgs(const QString &fileName) const = 0; + virtual ProcessArgs processOpenArchiveArgs(const QString &fileName, const QString &path) const = 0; + + void setFileName(const QString &fileName); + +protected: + UnrarFlavour(); + + QString fileName() const; + +private: + QString mFileName; +}; + +class NonFreeUnrarFlavour : public UnrarFlavour +{ +public: + NonFreeUnrarFlavour(); + + QStringList processListing(const QStringList &data) override; + QString name() const override; + + ProcessArgs processListArgs(const QString &fileName) const override; + ProcessArgs processOpenArchiveArgs(const QString &fileName, const QString &path) const override; +}; + +class FreeUnrarFlavour : public UnrarFlavour +{ +public: + FreeUnrarFlavour(); + + QStringList processListing(const QStringList &data) override; + QString name() const override; + + ProcessArgs processListArgs(const QString &fileName) const override; + ProcessArgs processOpenArchiveArgs(const QString &fileName, const QString &path) const override; +}; + +class UnarFlavour : public UnrarFlavour +{ +public: + UnarFlavour(); + + QStringList processListing(const QStringList &data) override; + QString name() const override; + + ProcessArgs processListArgs(const QString &fileName) const override; + ProcessArgs processOpenArchiveArgs(const QString &fileName, const QString &path) const override; +}; + +#endif diff --git a/generators/djvu/CMakeLists.txt b/generators/djvu/CMakeLists.txt new file mode 100644 index 0000000..e44f64a --- /dev/null +++ b/generators/djvu/CMakeLists.txt @@ -0,0 +1,26 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_djvu") + +include_directories( + ${DJVULIBRE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + + +########### next target ############### + +set(okularGenerator_djvu_SRCS + generator_djvu.cpp + kdjvu.cpp +) + + +okular_add_generator(okularGenerator_djvu ${okularGenerator_djvu_SRCS}) + +target_link_libraries(okularGenerator_djvu okularcore ${DJVULIBRE_LIBRARY} KF5::I18n) + +########### install files ############### +install( FILES okularDjvu.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_djvu.desktop org.kde.mobile.okular_djvu.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-djvu.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) + diff --git a/generators/djvu/Messages.sh b/generators/djvu/Messages.sh new file mode 100644 index 0000000..195b109 --- /dev/null +++ b/generators/djvu/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_djvu.pot diff --git a/generators/djvu/TODO b/generators/djvu/TODO new file mode 100644 index 0000000..e2d396b --- /dev/null +++ b/generators/djvu/TODO @@ -0,0 +1,10 @@ +KDjVu: +* Fix the cache handling to behave sanely in 90 and 170 degrees rotation +* Implement the threaded generation (the API is already ok) +* Annotations: + - Read the missing properties, if possible + - The default font size is quite small compared to the usual DjVu page sizes, + what to do for this? +* Read the metadata in the document (like year, booktitle, editor, author, etc) + stored as annotations + diff --git a/generators/djvu/generator_djvu.cpp b/generators/djvu/generator_djvu.cpp new file mode 100644 index 0000000..b7aed4e --- /dev/null +++ b/generators/djvu/generator_djvu.cpp @@ -0,0 +1,396 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "generator_djvu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static void recurseCreateTOC(QDomDocument &maindoc, const QDomNode &parent, QDomNode &parentDestination, KDjVu *djvu) +{ + QDomNode n = parent.firstChild(); + while (!n.isNull()) { + QDomElement el = n.toElement(); + + QDomElement newel = maindoc.createElement(el.attribute(QStringLiteral("title"))); + parentDestination.appendChild(newel); + + QString dest; + if (!(dest = el.attribute(QStringLiteral("PageNumber"))).isEmpty()) { + Okular::DocumentViewport vp; + vp.pageNumber = dest.toInt() - 1; + newel.setAttribute(QStringLiteral("Viewport"), vp.toString()); + } else if (!(dest = el.attribute(QStringLiteral("PageName"))).isEmpty()) { + Okular::DocumentViewport vp; + vp.pageNumber = djvu->pageNumber(dest); + newel.setAttribute(QStringLiteral("Viewport"), vp.toString()); + } else if (!(dest = el.attribute(QStringLiteral("URL"))).isEmpty()) { + newel.setAttribute(QStringLiteral("URL"), dest); + } + + if (el.hasChildNodes()) { + recurseCreateTOC(maindoc, n, newel, djvu); + } + n = n.nextSibling(); + } +} + +OKULAR_EXPORT_PLUGIN(DjVuGenerator, "libokularGenerator_djvu.json") + +DjVuGenerator::DjVuGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) + , m_docSyn(nullptr) +{ + setFeature(TextExtraction); + setFeature(Threaded); + setFeature(PrintPostscript); + if (Okular::FilePrinter::ps2pdfAvailable()) + setFeature(PrintToFile); + + m_djvu = new KDjVu(); + m_djvu->setCacheEnabled(false); +} + +DjVuGenerator::~DjVuGenerator() +{ + delete m_djvu; +} + +bool DjVuGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + QMutexLocker locker(userMutex()); + if (!m_djvu->openFile(fileName)) + return false; + + locker.unlock(); + + loadPages(pagesVector, 0); + + return true; +} + +bool DjVuGenerator::doCloseDocument() +{ + userMutex()->lock(); + m_djvu->closeFile(); + userMutex()->unlock(); + + delete m_docSyn; + m_docSyn = nullptr; + + return true; +} + +QImage DjVuGenerator::image(Okular::PixmapRequest *request) +{ + userMutex()->lock(); + QImage img = m_djvu->image(request->pageNumber(), request->width(), request->height(), request->page()->rotation()); + userMutex()->unlock(); + return img; +} + +Okular::DocumentInfo DjVuGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + + if (keys.contains(Okular::DocumentInfo::MimeType)) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("image/vnd.djvu")); + + if (m_djvu) { + // compile internal structure reading properties from KDjVu + if (keys.contains(Okular::DocumentInfo::Author)) + docInfo.set(Okular::DocumentInfo::Title, m_djvu->metaData(QStringLiteral("title")).toString()); + if (keys.contains(Okular::DocumentInfo::Author)) + docInfo.set(Okular::DocumentInfo::Author, m_djvu->metaData(QStringLiteral("author")).toString()); + if (keys.contains(Okular::DocumentInfo::CreationDate)) + docInfo.set(Okular::DocumentInfo::CreationDate, m_djvu->metaData(QStringLiteral("year")).toString()); + if (keys.contains(Okular::DocumentInfo::CustomKeys)) { + docInfo.set(QStringLiteral("editor"), m_djvu->metaData(QStringLiteral("editor")).toString(), i18n("Editor")); + docInfo.set(QStringLiteral("publisher"), m_djvu->metaData(QStringLiteral("publisher")).toString(), i18n("Publisher")); + docInfo.set(QStringLiteral("volume"), m_djvu->metaData(QStringLiteral("volume")).toString(), i18n("Volume")); + docInfo.set(QStringLiteral("documentType"), m_djvu->metaData(QStringLiteral("documentType")).toString(), i18n("Type of document")); + QVariant numcomponents = m_djvu->metaData(QStringLiteral("componentFile")); + docInfo.set(QStringLiteral("componentFile"), numcomponents.type() != QVariant::Int ? i18nc("Unknown number of component files", "Unknown") : numcomponents.toString(), i18n("Component Files")); + } + } + + return docInfo; +} + +const Okular::DocumentSynopsis *DjVuGenerator::generateDocumentSynopsis() +{ + QMutexLocker locker(userMutex()); + if (m_docSyn) + return m_docSyn; + + const QDomDocument *doc = m_djvu->documentBookmarks(); + if (doc) { + m_docSyn = new Okular::DocumentSynopsis(); + recurseCreateTOC(*m_docSyn, *doc, *m_docSyn, m_djvu); + } + locker.unlock(); + + return m_docSyn; +} + +bool DjVuGenerator::print(QPrinter &printer) +{ + bool result = false; + + // Create tempfile to write to + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + if (!tf.open()) + return false; + const QString fileName = tf.fileName(); + + QMutexLocker locker(userMutex()); + QList pageList = Okular::FilePrinter::pageList(printer, m_djvu->pages().count(), document()->currentPage() + 1, document()->bookmarkedPageList()); + + if (m_djvu->exportAsPostScript(&tf, pageList)) { + tf.setAutoRemove(false); + tf.close(); + int ret = Okular::FilePrinter::printFile(printer, fileName, document()->orientation(), Okular::FilePrinter::SystemDeletesFiles, Okular::FilePrinter::ApplicationSelectsPages, document()->bookmarkedPageRange()); + result = (ret >= 0); + } + + return result; +} + +QVariant DjVuGenerator::metaData(const QString &key, const QVariant &option) const +{ + Q_UNUSED(option) + if (key == QLatin1String("DocumentTitle")) { + return m_djvu->metaData(QStringLiteral("title")); + } + return QVariant(); +} + +Okular::TextPage *DjVuGenerator::textPage(Okular::TextRequest *request) +{ + userMutex()->lock(); + const Okular::Page *page = request->page(); + QList te; +#if 0 + m_djvu->textEntities( page->number(), "char" ); +#endif + if (te.isEmpty()) + te = m_djvu->textEntities(page->number(), QStringLiteral("word")); + if (te.isEmpty()) + te = m_djvu->textEntities(page->number(), QStringLiteral("line")); + userMutex()->unlock(); + QList::ConstIterator it = te.constBegin(); + QList::ConstIterator itEnd = te.constEnd(); + QList words; + const KDjVu::Page *djvupage = m_djvu->pages().at(page->number()); + for (; it != itEnd; ++it) { + const KDjVu::TextEntity &cur = *it; + words.append(new Okular::TextEntity(cur.text(), new Okular::NormalizedRect(cur.rect(), djvupage->width(), djvupage->height()))); + } + Okular::TextPage *textpage = new Okular::TextPage(words); + return textpage; +} + +void DjVuGenerator::loadPages(QVector &pagesVector, int rotation) +{ + const QVector &djvu_pages = m_djvu->pages(); + int numofpages = djvu_pages.count(); + pagesVector.resize(numofpages); + + for (int i = 0; i < numofpages; ++i) { + const KDjVu::Page *p = djvu_pages.at(i); + if (pagesVector[i]) + delete pagesVector[i]; + int w = p->width(); + int h = p->height(); + if (rotation % 2 == 1) + qSwap(w, h); + Okular::Page *page = new Okular::Page(i, w, h, (Okular::Rotation)(p->orientation() + rotation)); + pagesVector[i] = page; + + QList annots; + QList links; + userMutex()->lock(); + m_djvu->linksAndAnnotationsForPage(i, &links, &annots); + userMutex()->unlock(); + if (!links.isEmpty()) { + QLinkedList rects; + QList::ConstIterator it = links.constBegin(); + QList::ConstIterator itEnd = links.constEnd(); + for (; it != itEnd; ++it) { + KDjVu::Link *curlink = (*it); + Okular::ObjectRect *newrect = convertKDjVuLink(i, curlink); + if (newrect) + rects.append(newrect); + // delete the links as soon as we process them + delete curlink; + } + if (rects.count() > 0) + page->setObjectRects(rects); + } + if (!annots.isEmpty()) { + QList::ConstIterator it = annots.constBegin(); + QList::ConstIterator itEnd = annots.constEnd(); + for (; it != itEnd; ++it) { + KDjVu::Annotation *ann = (*it); + Okular::Annotation *newann = convertKDjVuAnnotation(w, h, ann); + if (newann) + page->addAnnotation(newann); + // delete the annotations as soon as we process them + delete ann; + } + } + } +} + +Okular::ObjectRect *DjVuGenerator::convertKDjVuLink(int page, KDjVu::Link *link) const +{ + Okular::Action *newlink = nullptr; + Okular::ObjectRect *newrect = nullptr; + switch (link->type()) { + case KDjVu::Link::PageLink: { + KDjVu::PageLink *l = static_cast(link); + bool ok = true; + QString target = l->page(); + if ((target.length() > 0) && target.at(0) == QLatin1Char('#')) + target.remove(0, 1); + int tmppage = target.toInt(&ok); + if (ok || target.isEmpty()) { + Okular::DocumentViewport vp; + if (!target.isEmpty()) + vp.pageNumber = (target.at(0) == QLatin1Char('+') || target.at(0) == QLatin1Char('-')) ? page + tmppage : tmppage - 1; + newlink = new Okular::GotoAction(QString(), vp); + } + break; + } + case KDjVu::Link::UrlLink: { + KDjVu::UrlLink *l = static_cast(link); + QString url = l->url(); + newlink = new Okular::BrowseAction(QUrl(url)); + break; + } + } + if (newlink) { + const KDjVu::Page *p = m_djvu->pages().at(page); + int width = p->width(); + int height = p->height(); + bool scape_orientation = false; // hack by tokoe, should always create default page + if (scape_orientation) + qSwap(width, height); + switch (link->areaType()) { + case KDjVu::Link::RectArea: + case KDjVu::Link::EllipseArea: { + QRect r(QPoint(link->point().x(), p->height() - link->point().y() - link->size().height()), link->size()); + bool ellipse = (link->areaType() == KDjVu::Link::EllipseArea); + newrect = new Okular::ObjectRect(Okular::NormalizedRect(Okular::Utils::rotateRect(r, width, height, 0), width, height), ellipse, Okular::ObjectRect::Action, newlink); + break; + } + case KDjVu::Link::PolygonArea: { + QPolygon poly = link->polygon(); + QPolygonF newpoly; + for (int i = 0; i < poly.count(); ++i) { + int x = poly.at(i).x(); + int y = poly.at(i).y(); + if (scape_orientation) + qSwap(x, y); + else { + y = height - y; + } + newpoly << QPointF((double)(x) / width, (double)(y) / height); + } + if (!newpoly.isEmpty()) { + newpoly << newpoly.first(); + newrect = new Okular::ObjectRect(newpoly, Okular::ObjectRect::Action, newlink); + } + break; + } + default:; + } + if (!newrect) { + delete newlink; + } + } + return newrect; +} + +Okular::Annotation *DjVuGenerator::convertKDjVuAnnotation(int w, int h, KDjVu::Annotation *ann) const +{ + Okular::Annotation *newann = nullptr; + switch (ann->type()) { + case KDjVu::Annotation::TextAnnotation: { + KDjVu::TextAnnotation *txtann = static_cast(ann); + Okular::TextAnnotation *newtxtann = new Okular::TextAnnotation(); + // boundary + QRect rect(QPoint(txtann->point().x(), h - txtann->point().y() - txtann->size().height()), txtann->size()); + newtxtann->setBoundingRectangle(Okular::NormalizedRect(Okular::Utils::rotateRect(rect, w, h, 0), w, h)); + // type + newtxtann->setTextType(txtann->inlineText() ? Okular::TextAnnotation::InPlace : Okular::TextAnnotation::Linked); + newtxtann->style().setOpacity(txtann->color().alphaF()); + // FIXME remove once the annotation text handling is fixed + newtxtann->setContents(ann->comment()); + newann = newtxtann; + break; + } + case KDjVu::Annotation::LineAnnotation: { + KDjVu::LineAnnotation *lineann = static_cast(ann); + Okular::LineAnnotation *newlineann = new Okular::LineAnnotation(); + // boundary + QPoint a(lineann->point().x(), h - lineann->point().y()); + QPoint b(lineann->point2().x(), h - lineann->point2().y()); + QRect rect = QRect(a, b).normalized(); + newlineann->setBoundingRectangle(Okular::NormalizedRect(Okular::Utils::rotateRect(rect, w, h, 0), w, h)); + // line points + QLinkedList points; + points.append(Okular::NormalizedPoint(a.x(), a.y(), w, h)); + points.append(Okular::NormalizedPoint(b.x(), b.y(), w, h)); + newlineann->setLinePoints(points); + // arrow? + if (lineann->isArrow()) + newlineann->setLineEndStyle(Okular::LineAnnotation::OpenArrow); + // width + newlineann->style().setWidth(lineann->width()); + newann = newlineann; + break; + } + } + if (newann) { + // setting the common parameters + newann->style().setColor(ann->color()); + newann->setContents(ann->comment()); + // creating an id as name for the annotation + QString uid = QUuid::createUuid().toString(); + uid.remove(0, 1); + uid.chop(1); + uid.remove(QLatin1Char('-')); + newann->setUniqueName(uid); + // is external + newann->setFlags(newann->flags() | Okular::Annotation::External); + } + return newann; +} + +#include "generator_djvu.moc" diff --git a/generators/djvu/generator_djvu.h b/generators/djvu/generator_djvu.h new file mode 100644 index 0000000..59bbc0c --- /dev/null +++ b/generators/djvu/generator_djvu.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _GENERATOR_DJVU_H_ +#define _GENERATOR_DJVU_H_ + +#include + +#include + +#include "kdjvu.h" + +namespace Okular +{ +class Annotation; +class ObjectRect; +} + +class DjVuGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + DjVuGenerator(QObject *parent, const QVariantList &args); + ~DjVuGenerator() override; + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + // document information + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + + // printing + bool print(QPrinter &printer) override; + + QVariant metaData(const QString &key, const QVariant &option) const override; + +protected: + bool doCloseDocument() override; + // pixmap generation + QImage image(Okular::PixmapRequest *request) override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + +private: + void loadPages(QVector &pagesVector, int rotation); + Okular::ObjectRect *convertKDjVuLink(int page, KDjVu::Link *link) const; + Okular::Annotation *convertKDjVuAnnotation(int w, int h, KDjVu::Annotation *ann) const; + + KDjVu *m_djvu; + + Okular::DocumentSynopsis *m_docSyn; +}; + +#endif diff --git a/generators/djvu/kdjvu.cpp b/generators/djvu/kdjvu.cpp new file mode 100644 index 0000000..78d182e --- /dev/null +++ b/generators/djvu/kdjvu.cpp @@ -0,0 +1,1061 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "kdjvu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +QDebug &operator<<(QDebug &s, const ddjvu_rect_t r) +{ + s.nospace() << "[" << r.x << "," << r.y << " - " << r.w << "x" << r.h << "]"; + return s.space(); +} + +static void which_ddjvu_message(const ddjvu_message_t *msg) +{ +#ifdef KDJVU_DEBUG + qDebug() << "which_djvu_message(...):" << msg->m_any.tag; + switch (msg->m_any.tag) { + case DDJVU_ERROR: + qDebug().nospace() << "ERROR: file " << msg->m_error.filename << ", line " << msg->m_error.lineno; + qDebug().nospace() << "ERROR: function '" << msg->m_error.function << "'"; + qDebug().nospace() << "ERROR: '" << msg->m_error.message << "'"; + break; + case DDJVU_INFO: + qDebug().nospace() << "INFO: '" << msg->m_info.message << "'"; + break; + case DDJVU_CHUNK: + qDebug().nospace() << "CHUNK: '" << QByteArray(msg->m_chunk.chunkid) << "'"; + break; + case DDJVU_PROGRESS: + qDebug().nospace() << "PROGRESS: '" << msg->m_progress.percent << "'"; + break; + default:; + } +#else + Q_UNUSED(msg); +#endif +} + +/** + * Explore the message queue until there are message left in it. + */ +static void handle_ddjvu_messages(ddjvu_context_t *ctx, int wait) +{ + const ddjvu_message_t *msg; + if (wait) + ddjvu_message_wait(ctx); + while ((msg = ddjvu_message_peek(ctx))) { + which_ddjvu_message(msg); + ddjvu_message_pop(ctx); + } +} + +/** + * Explore the message queue until the message \p mid is found. + */ +static void wait_for_ddjvu_message(ddjvu_context_t *ctx, ddjvu_message_tag_t mid) +{ + ddjvu_message_wait(ctx); + const ddjvu_message_t *msg; + while ((msg = ddjvu_message_peek(ctx)) && msg && (msg->m_any.tag != mid)) { + which_ddjvu_message(msg); + ddjvu_message_pop(ctx); + } +} + +/** + * Convert a clockwise coefficient \p r for a rotation to a counter-clockwise + * and vice versa. + */ +static int flipRotation(int r) +{ + return (4 - r) % 4; +} + +static miniexp_t find_second_in_pair(miniexp_t theexp, const char *which) +{ + miniexp_t exp = theexp; + while (exp) { + miniexp_t cur = miniexp_car(exp); + if (!miniexp_consp(cur) || !miniexp_symbolp(miniexp_car(cur))) { + exp = miniexp_cdr(exp); + continue; + } + + const QString id = QString::fromUtf8(miniexp_to_name(miniexp_car(cur))); + if (id == QLatin1String(which)) + return miniexp_cadr(cur); + exp = miniexp_cdr(exp); + } + return miniexp_nil; +} + +static bool find_replace_or_add_second_in_pair(miniexp_t theexp, const char *which, miniexp_t replacement) +{ + miniexp_t exp = miniexp_cdddr(theexp); + while (exp) { + miniexp_t cur = miniexp_car(exp); + if (!miniexp_consp(cur) || !miniexp_symbolp(miniexp_car(cur))) { + exp = miniexp_cdr(exp); + continue; + } + + const QString id = QString::fromUtf8(miniexp_to_name(miniexp_car(cur))); + if (id == QLatin1String(which)) { + miniexp_t reversed = miniexp_reverse(cur); + miniexp_rplaca(reversed, replacement); + cur = miniexp_reverse(reversed); + return true; + } + exp = miniexp_cdr(exp); + } + // TODO add the new replacement ad the end of the list + return false; +} + +// ImageCacheItem + +class ImageCacheItem +{ +public: + ImageCacheItem(int p, int w, int h, const QImage &i) + : page(p) + , width(w) + , height(h) + , img(i) + { + } + + int page; + int width; + int height; + QImage img; +}; + +// KdjVu::Page + +KDjVu::Page::Page() +{ +} + +KDjVu::Page::~Page() +{ +} + +int KDjVu::Page::width() const +{ + return m_width; +} + +int KDjVu::Page::height() const +{ + return m_height; +} + +int KDjVu::Page::dpi() const +{ + return m_dpi; +} + +int KDjVu::Page::orientation() const +{ + return m_orientation; +} + +// KDjVu::Link + +KDjVu::Link::~Link() +{ +} + +KDjVu::Link::LinkArea KDjVu::Link::areaType() const +{ + return m_area; +} + +QPoint KDjVu::Link::point() const +{ + return m_point; +} + +QSize KDjVu::Link::size() const +{ + return m_size; +} + +QPolygon KDjVu::Link::polygon() const +{ + return m_poly; +} + +// KDjVu::PageLink + +KDjVu::PageLink::PageLink() +{ +} + +int KDjVu::PageLink::type() const +{ + return KDjVu::Link::PageLink; +} + +QString KDjVu::PageLink::page() const +{ + return m_page; +} + +// KDjVu::UrlLink + +KDjVu::UrlLink::UrlLink() +{ +} + +int KDjVu::UrlLink::type() const +{ + return KDjVu::Link::UrlLink; +} + +QString KDjVu::UrlLink::url() const +{ + return m_url; +} + +// KDjVu::Annotation + +KDjVu::Annotation::Annotation(miniexp_t anno) + : m_anno(anno) +{ +} + +KDjVu::Annotation::~Annotation() +{ +} + +QPoint KDjVu::Annotation::point() const +{ + miniexp_t area = miniexp_nth(3, m_anno); + int a = miniexp_to_int(miniexp_nth(1, area)); + int b = miniexp_to_int(miniexp_nth(2, area)); + return QPoint(a, b); +} + +QString KDjVu::Annotation::comment() const +{ + return QString::fromUtf8(miniexp_to_str(miniexp_nth(2, m_anno))); +} + +void KDjVu::Annotation::setComment(const QString &comment) +{ + miniexp_t exp = m_anno; + exp = miniexp_cdr(exp); + exp = miniexp_cdr(exp); + miniexp_rplaca(exp, miniexp_string(comment.toUtf8().constData())); +} + +QColor KDjVu::Annotation::color() const +{ + return QColor(); +} + +void KDjVu::Annotation::setColor(const QColor &) +{ +} + +// KDjVu::TextAnnotation + +KDjVu::TextAnnotation::TextAnnotation(miniexp_t anno) + : Annotation(anno) + , m_inlineText(true) +{ + const int num = miniexp_length(m_anno); + for (int j = 4; j < num; ++j) { + miniexp_t curelem = miniexp_nth(j, m_anno); + if (!miniexp_listp(curelem)) + continue; + + QString id = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, curelem))); + if (id == QLatin1String("pushpin")) + m_inlineText = false; + } +} + +QSize KDjVu::TextAnnotation::size() const +{ + miniexp_t area = miniexp_nth(3, m_anno); + int c = miniexp_to_int(miniexp_nth(3, area)); + int d = miniexp_to_int(miniexp_nth(4, area)); + return QSize(c, d); +} + +int KDjVu::TextAnnotation::type() const +{ + return KDjVu::Annotation::TextAnnotation; +} + +QColor KDjVu::TextAnnotation::color() const +{ + miniexp_t col = find_second_in_pair(m_anno, "backclr"); + if (!miniexp_symbolp(col)) + return Qt::transparent; + + return QColor(QString::fromUtf8(miniexp_to_name(col))); +} + +void KDjVu::TextAnnotation::setColor(const QColor &color) +{ + const QByteArray col = color.name().toLatin1(); + find_replace_or_add_second_in_pair(m_anno, "backclr", miniexp_symbol(col.constData())); +} + +bool KDjVu::TextAnnotation::inlineText() const +{ + return m_inlineText; +} + +// KDjVu::LineAnnotation + +KDjVu::LineAnnotation::LineAnnotation(miniexp_t anno) + : Annotation(anno) + , m_isArrow(false) + , m_width(miniexp_nil) +{ + const int num = miniexp_length(m_anno); + for (int j = 4; j < num; ++j) { + miniexp_t curelem = miniexp_nth(j, m_anno); + if (!miniexp_listp(curelem)) + continue; + + QString id = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, curelem))); + if (id == QLatin1String("arrow")) + m_isArrow = true; + else if (id == QLatin1String("width")) + m_width = curelem; + } +} + +int KDjVu::LineAnnotation::type() const +{ + return KDjVu::Annotation::LineAnnotation; +} + +QColor KDjVu::LineAnnotation::color() const +{ + miniexp_t col = find_second_in_pair(m_anno, "lineclr"); + if (!miniexp_symbolp(col)) + return Qt::black; + + return QColor(QString::fromUtf8(miniexp_to_name(col))); +} + +void KDjVu::LineAnnotation::setColor(const QColor &color) +{ + const QByteArray col = color.name().toLatin1(); + find_replace_or_add_second_in_pair(m_anno, "lineclr", miniexp_symbol(col.constData())); +} + +QPoint KDjVu::LineAnnotation::point2() const +{ + miniexp_t area = miniexp_nth(3, m_anno); + int c = miniexp_to_int(miniexp_nth(3, area)); + int d = miniexp_to_int(miniexp_nth(4, area)); + return QPoint(c, d); +} + +bool KDjVu::LineAnnotation::isArrow() const +{ + return m_isArrow; +} + +int KDjVu::LineAnnotation::width() const +{ + if (m_width == miniexp_nil) + return 1; + + return miniexp_to_int(miniexp_cadr(m_width)); +} + +void KDjVu::LineAnnotation::setWidth(int width) +{ + find_replace_or_add_second_in_pair(m_anno, "width", miniexp_number(width)); +} + +// KDjVu::TextEntity + +KDjVu::TextEntity::TextEntity() +{ +} + +KDjVu::TextEntity::~TextEntity() +{ +} + +QString KDjVu::TextEntity::text() const +{ + return m_text; +} + +QRect KDjVu::TextEntity::rect() const +{ + return m_rect; +} + +class KDjVu::Private +{ +public: + Private() + : m_djvu_cxt(nullptr) + , m_djvu_document(nullptr) + , m_format(nullptr) + , m_docBookmarks(nullptr) + , m_cacheEnabled(true) + { + } + + QImage generateImageTile(ddjvu_page_t *djvupage, int &res, int width, int row, int xdelta, int height, int col, int ydelta); + + void readBookmarks(); + void fillBookmarksRecurse(QDomDocument &maindoc, QDomNode &curnode, miniexp_t exp, int offset = -1); + + void readMetaData(int page); + + int pageWithName(const QString &name); + + ddjvu_context_t *m_djvu_cxt; + ddjvu_document_t *m_djvu_document; + ddjvu_format_t *m_format; + + QVector m_pages; + QVector m_pages_cache; + + QList mImgCache; + + QHash m_metaData; + QDomDocument *m_docBookmarks; + + QHash m_pageNamesCache; + + bool m_cacheEnabled; + + static unsigned int s_formatmask[4]; +}; + +unsigned int KDjVu::Private::s_formatmask[4] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}; + +QImage KDjVu::Private::generateImageTile(ddjvu_page_t *djvupage, int &res, int width, int row, int xdelta, int height, int col, int ydelta) +{ + ddjvu_rect_t renderrect; + renderrect.x = row * xdelta; + renderrect.y = col * ydelta; + int realwidth = qMin(width - renderrect.x, xdelta); + int realheight = qMin(height - renderrect.y, ydelta); + renderrect.w = realwidth; + renderrect.h = realheight; +#ifdef KDJVU_DEBUG + qDebug() << "renderrect:" << renderrect; +#endif + ddjvu_rect_t pagerect; + pagerect.x = 0; + pagerect.y = 0; + pagerect.w = width; + pagerect.h = height; +#ifdef KDJVU_DEBUG + qDebug() << "pagerect:" << pagerect; +#endif + handle_ddjvu_messages(m_djvu_cxt, false); + QImage res_img(realwidth, realheight, QImage::Format_RGB32); + // the following line workarounds a rare crash in djvulibre; + // it should be fixed with >= 3.5.21 + ddjvu_page_get_width(djvupage); + res = ddjvu_page_render(djvupage, DDJVU_RENDER_COLOR, &pagerect, &renderrect, m_format, res_img.bytesPerLine(), (char *)res_img.bits()); + if (!res) { + res_img.fill(Qt::white); + } +#ifdef KDJVU_DEBUG + qDebug() << "rendering result:" << res; +#endif + handle_ddjvu_messages(m_djvu_cxt, false); + + return res_img; +} + +void KDjVu::Private::readBookmarks() +{ + if (!m_djvu_document) + return; + + miniexp_t outline; + while ((outline = ddjvu_document_get_outline(m_djvu_document)) == miniexp_dummy) + handle_ddjvu_messages(m_djvu_cxt, true); + + if (miniexp_listp(outline) && (miniexp_length(outline) > 0) && miniexp_symbolp(miniexp_nth(0, outline)) && (QString::fromUtf8(miniexp_to_name(miniexp_nth(0, outline))) == QLatin1String("bookmarks"))) { + m_docBookmarks = new QDomDocument(QStringLiteral("KDjVuBookmarks")); + fillBookmarksRecurse(*m_docBookmarks, *m_docBookmarks, outline, 1); + ddjvu_miniexp_release(m_djvu_document, outline); + } +} + +void KDjVu::Private::fillBookmarksRecurse(QDomDocument &maindoc, QDomNode &curnode, miniexp_t exp, int offset) +{ + if (!miniexp_listp(exp)) + return; + + int l = miniexp_length(exp); + for (int i = qMax(offset, 0); i < l; ++i) { + miniexp_t cur = miniexp_nth(i, exp); + + if (miniexp_consp(cur) && (miniexp_length(cur) > 0) && miniexp_stringp(miniexp_nth(0, cur)) && miniexp_stringp(miniexp_nth(1, cur))) { + QString title = QString::fromUtf8(miniexp_to_str(miniexp_nth(0, cur))); + QString dest = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, cur))); + QDomElement el = maindoc.createElement(QStringLiteral("item")); + el.setAttribute(QStringLiteral("title"), title); + if (!dest.isEmpty()) { + if (dest.at(0) == QLatin1Char('#')) { + dest.remove(0, 1); + bool isNumber = false; + dest.toInt(&isNumber); + if (isNumber) { + // it might be an actual page number, but could also be a page label + // so resolve the number, and get the real page number + int pageNo = pageWithName(dest); + if (pageNo != -1) { + el.setAttribute(QStringLiteral("PageNumber"), QString::number(pageNo + 1)); + } else { + el.setAttribute(QStringLiteral("PageNumber"), dest); + } + } else { + el.setAttribute(QStringLiteral("PageName"), dest); + } + } else { + el.setAttribute(QStringLiteral("URL"), dest); + } + } + curnode.appendChild(el); + if (!el.isNull() && (miniexp_length(cur) > 2)) { + fillBookmarksRecurse(maindoc, el, cur, 2); + } + } + } +} + +void KDjVu::Private::readMetaData(int page) +{ + if (!m_djvu_document) + return; + + miniexp_t annots; + while ((annots = ddjvu_document_get_pageanno(m_djvu_document, page)) == miniexp_dummy) + handle_ddjvu_messages(m_djvu_cxt, true); + + if (!miniexp_listp(annots) || miniexp_length(annots) == 0) + return; + + miniexp_t exp = miniexp_nth(0, annots); + int size = miniexp_length(exp); + if (size <= 1 || qstrncmp(miniexp_to_name(miniexp_nth(0, exp)), "metadata", 8)) + return; + + for (int i = 1; i < size; ++i) { + miniexp_t cur = miniexp_nth(i, exp); + if (miniexp_length(cur) != 2) + continue; + + QString id = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, cur))); + QString value = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, cur))); + m_metaData[id.toLower()] = value; + } +} + +int KDjVu::Private::pageWithName(const QString &name) +{ + const int pageNo = m_pageNamesCache.value(name, -1); + if (pageNo != -1) + return pageNo; + + const QByteArray utfName = name.toUtf8(); + const int fileNum = ddjvu_document_get_filenum(m_djvu_document); + ddjvu_fileinfo_t info; + for (int i = 0; i < fileNum; ++i) { + if (DDJVU_JOB_OK != ddjvu_document_get_fileinfo(m_djvu_document, i, &info)) + continue; + if (info.type != 'P') + continue; + if ((utfName == info.id) || (utfName == info.name) || (utfName == info.title)) { + m_pageNamesCache.insert(name, info.pageno); + return info.pageno; + } + } + return -1; +} + +KDjVu::KDjVu() + : d(new Private) +{ + // creating the djvu context + d->m_djvu_cxt = ddjvu_context_create("KDjVu"); + // creating the rendering format +#if DDJVUAPI_VERSION >= 18 + d->m_format = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 4, Private::s_formatmask); +#else + d->m_format = ddjvu_format_create(DDJVU_FORMAT_RGBMASK32, 3, Private::s_formatmask); +#endif + ddjvu_format_set_row_order(d->m_format, 1); + ddjvu_format_set_y_direction(d->m_format, 1); +} + +KDjVu::~KDjVu() +{ + closeFile(); + + ddjvu_format_release(d->m_format); + ddjvu_context_release(d->m_djvu_cxt); + + delete d; +} + +bool KDjVu::openFile(const QString &fileName) +{ + // first, close the old file + if (d->m_djvu_document) + closeFile(); + + // load the document..., use UTF-8 variant to work on Windows, too, see bug 422500 + d->m_djvu_document = ddjvu_document_create_by_filename_utf8(d->m_djvu_cxt, fileName.toUtf8().constData(), true); + if (!d->m_djvu_document) + return false; + // ...and wait for its loading + wait_for_ddjvu_message(d->m_djvu_cxt, DDJVU_DOCINFO); + if (ddjvu_document_decoding_error(d->m_djvu_document)) { + ddjvu_document_release(d->m_djvu_document); + d->m_djvu_document = nullptr; + return false; + } + + qDebug() << "# of pages:" << ddjvu_document_get_pagenum(d->m_djvu_document); + int numofpages = ddjvu_document_get_pagenum(d->m_djvu_document); + d->m_pages.clear(); + d->m_pages.resize(numofpages); + d->m_pages_cache.clear(); + d->m_pages_cache.resize(numofpages); + + // get the document type + QString doctype; + switch (ddjvu_document_get_type(d->m_djvu_document)) { + case DDJVU_DOCTYPE_UNKNOWN: + doctype = i18nc("Type of DjVu document", "Unknown"); + break; + case DDJVU_DOCTYPE_SINGLEPAGE: + doctype = i18nc("Type of DjVu document", "Single Page"); + break; + case DDJVU_DOCTYPE_BUNDLED: + doctype = i18nc("Type of DjVu document", "Bundled"); + break; + case DDJVU_DOCTYPE_INDIRECT: + doctype = i18nc("Type of DjVu document", "Indirect"); + break; + case DDJVU_DOCTYPE_OLD_BUNDLED: + doctype = i18nc("Type of DjVu document", "Bundled (old)"); + break; + case DDJVU_DOCTYPE_OLD_INDEXED: + doctype = i18nc("Type of DjVu document", "Indexed (old)"); + break; + } + if (!doctype.isEmpty()) + d->m_metaData[QStringLiteral("documentType")] = doctype; + // get the number of components + d->m_metaData[QStringLiteral("componentFile")] = ddjvu_document_get_filenum(d->m_djvu_document); + + // read the pages + for (int i = 0; i < numofpages; ++i) { + ddjvu_status_t sts; + ddjvu_pageinfo_t info; + while ((sts = ddjvu_document_get_pageinfo(d->m_djvu_document, i, &info)) < DDJVU_JOB_OK) + handle_ddjvu_messages(d->m_djvu_cxt, true); + if (sts >= DDJVU_JOB_FAILED) { + qDebug().nospace() << "\t>>> page " << i << " failed: " << sts; + return false; + } + + KDjVu::Page *p = new KDjVu::Page(); + p->m_width = info.width; + p->m_height = info.height; + p->m_dpi = info.dpi; +#if DDJVUAPI_VERSION >= 18 + p->m_orientation = flipRotation(info.rotation); +#else + p->m_orientation = 0; +#endif + d->m_pages[i] = p; + } + + // reading the metadata from the first page only should be enough + if (numofpages > 0) + d->readMetaData(0); + + return true; +} + +void KDjVu::closeFile() +{ + // deleting the old TOC + delete d->m_docBookmarks; + d->m_docBookmarks = nullptr; + // deleting the pages + qDeleteAll(d->m_pages); + d->m_pages.clear(); + // releasing the djvu pages + QVector::Iterator it = d->m_pages_cache.begin(), itEnd = d->m_pages_cache.end(); + for (; it != itEnd; ++it) + ddjvu_page_release(*it); + d->m_pages_cache.clear(); + // clearing the image cache + qDeleteAll(d->mImgCache); + d->mImgCache.clear(); + // clearing the old metadata + d->m_metaData.clear(); + // cleaning the page names mapping + d->m_pageNamesCache.clear(); + // releasing the old document + if (d->m_djvu_document) + ddjvu_document_release(d->m_djvu_document); + d->m_djvu_document = nullptr; +} + +QVariant KDjVu::metaData(const QString &key) const +{ + QHash::ConstIterator it = d->m_metaData.constFind(key); + return it != d->m_metaData.constEnd() ? it.value() : QVariant(); +} + +const QDomDocument *KDjVu::documentBookmarks() const +{ + if (!d->m_docBookmarks) + d->readBookmarks(); + return d->m_docBookmarks; +} + +void KDjVu::linksAndAnnotationsForPage(int pageNum, QList *links, QList *annotations) const +{ + if ((pageNum < 0) || (pageNum >= d->m_pages.count()) || (!links && !annotations)) + return; + + miniexp_t annots; + while ((annots = ddjvu_document_get_pageanno(d->m_djvu_document, pageNum)) == miniexp_dummy) + handle_ddjvu_messages(d->m_djvu_cxt, true); + + if (!miniexp_listp(annots)) + return; + + if (links) + links->clear(); + if (annotations) + annotations->clear(); + + int l = miniexp_length(annots); + for (int i = 0; i < l; ++i) { + miniexp_t cur = miniexp_nth(i, annots); + int num = miniexp_length(cur); + if ((num < 4) || !miniexp_symbolp(miniexp_nth(0, cur)) || (qstrncmp(miniexp_to_name(miniexp_nth(0, cur)), "maparea", 7) != 0)) + continue; + + QString target; + QString type; + if (miniexp_symbolp(miniexp_nth(0, miniexp_nth(3, cur)))) + type = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, miniexp_nth(3, cur)))); + KDjVu::Link *link = nullptr; + KDjVu::Annotation *ann = nullptr; + miniexp_t urlexp = miniexp_nth(1, cur); + if (links && (type == QLatin1String("rect") || type == QLatin1String("oval") || type == QLatin1String("poly"))) { + if (miniexp_stringp(urlexp)) { + target = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, cur))); + } else if (miniexp_listp(urlexp) && (miniexp_length(urlexp) == 3) && miniexp_symbolp(miniexp_nth(0, urlexp)) && (qstrncmp(miniexp_to_name(miniexp_nth(0, urlexp)), "url", 3) == 0)) { + target = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, urlexp))); + } + if (target.isEmpty() || ((target.length() > 0) && target.at(0) == QLatin1Char('#'))) { + KDjVu::PageLink *plink = new KDjVu::PageLink(); + plink->m_page = target; + link = plink; + } else { + KDjVu::UrlLink *ulink = new KDjVu::UrlLink(); + ulink->m_url = target; + link = ulink; + } + } else if (annotations && (type == QLatin1String("text") || type == QLatin1String("line"))) { + if (type == QLatin1String("text")) { + KDjVu::TextAnnotation *textann = new KDjVu::TextAnnotation(cur); + ann = textann; + } else if (type == QLatin1String("line")) { + KDjVu::LineAnnotation *lineann = new KDjVu::LineAnnotation(cur); + ann = lineann; + } + } + if (link /* safety check */ && links) { + link->m_area = KDjVu::Link::UnknownArea; + miniexp_t area = miniexp_nth(3, cur); + int arealength = miniexp_length(area); + if ((arealength == 5) && (type == QLatin1String("rect") || type == QLatin1String("oval"))) { + link->m_point = QPoint(miniexp_to_int(miniexp_nth(1, area)), miniexp_to_int(miniexp_nth(2, area))); + link->m_size = QSize(miniexp_to_int(miniexp_nth(3, area)), miniexp_to_int(miniexp_nth(4, area))); + if (type == QLatin1String("rect")) { + link->m_area = KDjVu::Link::RectArea; + } else { + link->m_area = KDjVu::Link::EllipseArea; + } + } else if ((arealength > 0) && (arealength % 2 == 1) && type == QLatin1String("poly")) { + link->m_area = KDjVu::Link::PolygonArea; + QPolygon poly; + for (int j = 1; j < arealength; j += 2) { + poly << QPoint(miniexp_to_int(miniexp_nth(j, area)), miniexp_to_int(miniexp_nth(j + 1, area))); + } + link->m_poly = poly; + } + + if (link->m_area != KDjVu::Link::UnknownArea) + links->append(link); + } else if (ann /* safety check */ && annotations) { + annotations->append(ann); + } + } +} + +const QVector &KDjVu::pages() const +{ + return d->m_pages; +} + +QImage KDjVu::image(int page, int width, int height, int rotation) +{ + if (d->m_cacheEnabled) { + bool found = false; + QList::Iterator it = d->mImgCache.begin(), itEnd = d->mImgCache.end(); + for (; (it != itEnd) && !found; ++it) { + ImageCacheItem *cur = *it; + if ((cur->page == page) && (rotation % 2 == 0 ? cur->width == width && cur->height == height : cur->width == height && cur->height == width)) + found = true; + } + if (found) { + // taking the element and pushing to the top of the list + --it; + ImageCacheItem *cur2 = *it; + d->mImgCache.erase(it); + d->mImgCache.push_front(cur2); + + return cur2->img; + } + } + + if (!d->m_pages_cache.at(page)) { + ddjvu_page_t *newpage = ddjvu_page_create_by_pageno(d->m_djvu_document, page); + // wait for the new page to be loaded + ddjvu_status_t sts; + while ((sts = ddjvu_page_decoding_status(newpage)) < DDJVU_JOB_OK) + handle_ddjvu_messages(d->m_djvu_cxt, true); + d->m_pages_cache[page] = newpage; + } + ddjvu_page_t *djvupage = d->m_pages_cache[page]; + + /* + if ( ddjvu_page_get_rotation( djvupage ) != flipRotation( rotation ) ) + { + // TODO: test documents with initial rotation != 0 + // ddjvu_page_set_rotation( djvupage, m_pages.at( page )->orientation() ); + ddjvu_page_set_rotation( djvupage, (ddjvu_page_rotation_t)flipRotation( rotation ) ); + } + */ + + static const int xdelta = 1500; + static const int ydelta = 1500; + + int xparts = width / xdelta + 1; + int yparts = height / ydelta + 1; + + QImage newimg; + + int res = 10000; + if ((xparts == 1) && (yparts == 1)) { + // only one part -- render at once with no need to auxiliary image + newimg = d->generateImageTile(djvupage, res, width, 0, xdelta, height, 0, ydelta); + } else { + // more than one part -- need to render piece-by-piece and to compose + // the results + newimg = QImage(width, height, QImage::Format_RGB32); + QPainter p; + p.begin(&newimg); + int parts = xparts * yparts; + for (int i = 0; i < parts; ++i) { + const int row = i % xparts; + const int col = i / xparts; + int tmpres = 0; + const QImage tempp = d->generateImageTile(djvupage, tmpres, width, row, xdelta, height, col, ydelta); + p.drawImage(row * xdelta, col * ydelta, tempp); + res = qMin(tmpres, res); + } + p.end(); + } + + if (res && d->m_cacheEnabled) { + // delete all the cached pixmaps for the current page with a size that + // differs no more than 35% of the new pixmap size + int imgsize = newimg.width() * newimg.height(); + if (imgsize > 0) { + for (int i = 0; i < d->mImgCache.count();) { + ImageCacheItem *cur = d->mImgCache.at(i); + if ((cur->page == page) && (abs(cur->img.width() * cur->img.height() - imgsize) < imgsize * 0.35)) { + d->mImgCache.removeAt(i); + delete cur; + } else + ++i; + } + } + + // the image cache has too many elements, remove the last + if (d->mImgCache.size() >= 10) { + delete d->mImgCache.last(); + d->mImgCache.removeLast(); + } + ImageCacheItem *ich = new ImageCacheItem(page, width, height, newimg); + d->mImgCache.push_front(ich); + } + + return newimg; +} + +bool KDjVu::exportAsPostScript(const QString &fileName, const QList &pageList) const +{ + if (!d->m_djvu_document || fileName.trimmed().isEmpty() || pageList.isEmpty()) + return false; + + QFile f(fileName); + f.open(QIODevice::ReadWrite); + bool ret = exportAsPostScript(&f, pageList); + if (ret) { + f.close(); + } + return ret; +} + +bool KDjVu::exportAsPostScript(QFile *file, const QList &pageList) const +{ + if (!d->m_djvu_document || !file || pageList.isEmpty()) + return false; + + FILE *f = fdopen(file->handle(), "w+"); + if (!f) { + qDebug() << "error while getting the FILE*"; + return false; + } + + QString pl; + for (const int p : pageList) { + if (!pl.isEmpty()) + pl += QLatin1String(","); + pl += QString::number(p); + } + pl.prepend(QStringLiteral("-page=")); + + // setting the options + static const int optc = 1; + const char **optv = (const char **)malloc(1 * sizeof(char *)); + QByteArray plb = pl.toLatin1(); + optv[0] = plb.constData(); + + ddjvu_job_t *printjob = ddjvu_document_print(d->m_djvu_document, f, optc, optv); + while (!ddjvu_job_done(printjob)) + handle_ddjvu_messages(d->m_djvu_cxt, true); + + free(optv); + + return fclose(f) == 0; +} + +QList KDjVu::textEntities(int page, const QString &granularity) const +{ + if ((page < 0) || (page >= d->m_pages.count())) + return QList(); + + miniexp_t r; + while ((r = ddjvu_document_get_pagetext(d->m_djvu_document, page, nullptr)) == miniexp_dummy) + handle_ddjvu_messages(d->m_djvu_cxt, true); + + if (r == miniexp_nil) + return QList(); + + QList ret; + + int height = d->m_pages.at(page)->height(); + + QQueue queue; + queue.enqueue(r); + + while (!queue.isEmpty()) { + miniexp_t cur = queue.dequeue(); + + if (miniexp_listp(cur) && (miniexp_length(cur) > 0) && miniexp_symbolp(miniexp_nth(0, cur))) { + int size = miniexp_length(cur); + QString sym = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, cur))); + if (sym == granularity) { + if (size >= 6) { + int xmin = miniexp_to_int(miniexp_nth(1, cur)); + int ymin = miniexp_to_int(miniexp_nth(2, cur)); + int xmax = miniexp_to_int(miniexp_nth(3, cur)); + int ymax = miniexp_to_int(miniexp_nth(4, cur)); + QRect rect(xmin, height - ymax, xmax - xmin, ymax - ymin); + KDjVu::TextEntity entity; + entity.m_rect = rect; + entity.m_text = QString::fromUtf8(miniexp_to_str(miniexp_nth(5, cur))); + ret.append(entity); + } + } else { + for (int i = 5; i < size; ++i) + queue.enqueue(miniexp_nth(i, cur)); + } + } + } + + return ret; +} + +void KDjVu::setCacheEnabled(bool enable) +{ + if (enable == d->m_cacheEnabled) + return; + + d->m_cacheEnabled = enable; + if (!d->m_cacheEnabled) { + qDeleteAll(d->mImgCache); + d->mImgCache.clear(); + } +} + +bool KDjVu::isCacheEnabled() const +{ + return d->m_cacheEnabled; +} + +int KDjVu::pageNumber(const QString &name) const +{ + if (!d->m_djvu_document) + return -1; + + return d->pageWithName(name); +} diff --git a/generators/djvu/kdjvu.h b/generators/djvu/kdjvu.h new file mode 100644 index 0000000..85f5d52 --- /dev/null +++ b/generators/djvu/kdjvu.h @@ -0,0 +1,304 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _KDJVU_ +#define _KDJVU_ + +#include +#include +#include +#include +#include +#include +#include + +class QDomDocument; +class QFile; + +#ifndef MINIEXP_H +typedef struct miniexp_s *miniexp_t; +#endif + +/** + * @brief Qt (KDE) encapsulation of the DjVuLibre + */ +class KDjVu +{ +public: + KDjVu(); + ~KDjVu(); + + KDjVu(const KDjVu &) = delete; + KDjVu &operator=(const KDjVu &) = delete; + + /** + * A DjVu page. + */ + class Page + { + friend class KDjVu; + + public: + ~Page(); + + int width() const; + int height() const; + int dpi() const; + int orientation() const; + + private: + Page(); + + int m_width; + int m_height; + int m_dpi; + int m_orientation; + }; + + /** + * The base implementation for a DjVu link. + */ + class Link + { + friend class KDjVu; + + public: + Link() = default; + virtual ~Link(); + + Link(const Link &) = delete; + Link &operator=(const Link &) = delete; + + enum LinkType { PageLink, UrlLink }; + enum LinkArea { UnknownArea, RectArea, EllipseArea, PolygonArea }; + virtual int type() const = 0; + LinkArea areaType() const; + QPoint point() const; + QSize size() const; + QPolygon polygon() const; + + private: + LinkArea m_area; + QPoint m_point; + QSize m_size; + QPolygon m_poly; + }; + + /** + * A link to reach a page of a DjVu document. + */ + class PageLink : public Link + { + friend class KDjVu; + + public: + int type() const override; + QString page() const; + + private: + PageLink(); + QString m_page; + }; + + /** + * A DjVu link to open an external Url. + */ + class UrlLink : public Link + { + friend class KDjVu; + + public: + int type() const override; + QString url() const; + + private: + UrlLink(); + QString m_url; + }; + + /** + * The base implementation for a DjVu annotation. + */ + class Annotation + { + friend class KDjVu; + + public: + virtual ~Annotation(); + + Annotation(const Annotation &) = delete; + Annotation &operator=(const Annotation &) = delete; + + enum AnnotationType { TextAnnotation, LineAnnotation }; + virtual int type() const = 0; + QPoint point() const; + QString comment() const; + void setComment(const QString &comment); + virtual QColor color() const; + virtual void setColor(const QColor &color); + + protected: + Annotation(miniexp_t anno); + + miniexp_t m_anno; + QPoint m_point; + }; + + /** + * A DjVu text annotation. + */ + class TextAnnotation : public Annotation + { + friend class KDjVu; + + public: + int type() const override; + QColor color() const override; + void setColor(const QColor &color) override; + QSize size() const; + bool inlineText() const; + + private: + explicit TextAnnotation(miniexp_t anno); + QSize m_size; + bool m_inlineText; + }; + + /** + * A DjVu line annotation. + */ + class LineAnnotation : public Annotation + { + friend class KDjVu; + + public: + int type() const override; + QColor color() const override; + void setColor(const QColor &color) override; + QPoint point2() const; + bool isArrow() const; + int width() const; + void setWidth(int width); + + private: + explicit LineAnnotation(miniexp_t anno); + QPoint m_point2; + bool m_isArrow; + miniexp_t m_width; + }; + + /** + * A DjVu text entity. + */ + class TextEntity + { + friend class KDjVu; + + public: + ~TextEntity(); + + QString text() const; + QRect rect() const; + + private: + TextEntity(); + + QString m_text; + QRect m_rect; + }; + + /** + * Opens the file \p fileName, closing the old one if necessary. + */ + bool openFile(const QString &fileName); + /** + * Close the file currently opened, if any. + */ + void closeFile(); + + /** + * The pages of the current document, or an empty vector otherwise. + * \note KDjVu handles the pages, so you don't need to delete them manually + * \return a vector with the pages of the current document + */ + const QVector &pages() const; + + /** + * Get the metadata for the specified \p key, or a null variant otherwise. + */ + QVariant metaData(const QString &key) const; + + /** + * Get an XML document with the bookmarks of the current document (if any). + * The XML will look like this: + * \verbatim + * + * + * + * ... + * + * + * \endverbatim + */ + const QDomDocument *documentBookmarks() const; + + /** + * Reads the links and the annotations for the page \p pageNum + * + * For both \p links and \p annotations , you can pass either a valid pointer + * (in case you want to extract that kind of information), or a null pointer + * (if you don't want that information). + */ + void linksAndAnnotationsForPage(int pageNum, QList *links, QList *annotations) const; + + /** + * Check if the image for the specified \p page with the specified + * \p width, \p height and \p rotation is already in cache, and returns + * it. If not, a null image is returned. + */ + QImage image(int page, int width, int height, int rotation); + + /** + * Export the currently open document as PostScript file \p fileName. + * \returns whether the exporting was successful + */ + bool exportAsPostScript(const QString &fileName, const QList &pageList) const; + + /** + * Export the currently open document as PostScript file. + * \returns whether the exporting was successful + */ + bool exportAsPostScript(QFile *file, const QList &pageList) const; + + /** + * Return the list of the text entities for the specified \p page, that matches the + * specified \p granularity. + */ + QList textEntities(int page, const QString &granularity) const; + + /** + * Enable or disable the internal rendered pages cache. + */ + void setCacheEnabled(bool enable); + /** + * \returns whether the internal rendered pages cache is enabled + */ + bool isCacheEnabled() const; + + /** + * Return the page number of the page whose title is \p name. + */ + int pageNumber(const QString &name) const; + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/generators/djvu/libokularGenerator_djvu.json b/generators/djvu/libokularGenerator_djvu.json new file mode 100644 index 0000000..41503f7 --- /dev/null +++ b/generators/djvu/libokularGenerator_djvu.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "pino@kde.org", + "Name": "Pino Toscano", + "Name[az]": "Pino Toscano", + "Name[ca@valencia]": "Pino Toscano", + "Name[ca]": "Pino Toscano", + "Name[cs]": "Pino Toscano", + "Name[da]": "Pino Toscano", + "Name[de]": "Pino Toscano", + "Name[el]": "Pino Toscano", + "Name[en_GB]": "Pino Toscano", + "Name[es]": "Pino Toscano", + "Name[et]": "Pino Toscano", + "Name[eu]": "Pino Toscano", + "Name[fi]": "Pino Toscano", + "Name[fr]": "Pino Toscano", + "Name[gl]": "Pino Toscano", + "Name[ia]": "Pino Toscano", + "Name[it]": "Pino Toscano", + "Name[ko]": "Pino Toscano", + "Name[lt]": "Pino Toscano", + "Name[nl]": "Pino Toscano", + "Name[nn]": "Pino Toscano", + "Name[pl]": "Pino Toscano", + "Name[pt]": "Pino Toscano", + "Name[pt_BR]": "Pino Toscano", + "Name[ru]": "Pino Toscano", + "Name[sk]": "Pino Toscano", + "Name[sl]": "Pino Toscano", + "Name[sr@ijekavian]": "Пино Тоскано", + "Name[sr@ijekavianlatin]": "Pino Toskano", + "Name[sr@latin]": "Pino Toskano", + "Name[sr]": "Пино Тоскано", + "Name[sv]": "Pino Toscano", + "Name[tr]": "Pino Toscano", + "Name[uk]": "Pino Toscano", + "Name[x-test]": "xxPino Toscanoxx", + "Name[zh_CN]": "Pino Toscano", + "Name[zh_TW]": "Pino Toscano" + } + ], + "Copyright": "© 2006-2008 Pino Toscano", + "Copyright[az]": "© 2006-2008 Pino Toscano", + "Copyright[ca@valencia]": "© 2006-2008 Pino Toscano", + "Copyright[ca]": "© 2006-2008 Pino Toscano", + "Copyright[cs]": "© 2006-2008 Pino Toscano", + "Copyright[da]": "© 2006-2008 Pino Toscano", + "Copyright[de]": "© 2006-2008 Pino Toscano", + "Copyright[el]": "© 2006-2008 Pino Toscano", + "Copyright[en_GB]": "© 2006-2008 Pino Toscano", + "Copyright[es]": "© 2006-2008 Pino Toscano", + "Copyright[et]": "© 2006-2008: Pino Toscano", + "Copyright[eu]": "© 2006-2008 Pino Toscano", + "Copyright[fi]": "© 2006–2008 Pino Toscano", + "Copyright[fr]": "© 2006-2008 Pino Toscano", + "Copyright[gl]": "© 2006-2008 Pino Toscano", + "Copyright[ia]": "© 2006-2008 Pino Toscano", + "Copyright[it]": "© 2006-2008 Pino Toscano", + "Copyright[ko]": "© 2006-2008 Pino Toscano", + "Copyright[lt]": "© 2006-2008 Pino Toscano", + "Copyright[nl]": "© 2006-2008 Pino Toscano", + "Copyright[nn]": "© 2006–2008 Pino Toscano", + "Copyright[pl]": "© 2006-2008 Pino Toscano", + "Copyright[pt]": "© 2006-2008 Pino Toscano", + "Copyright[pt_BR]": "© 2006-2008 Pino Toscano", + "Copyright[ru]": "© Pino Toscano, 2006-2008", + "Copyright[sk]": "© 2006-2008 Pino Toscano", + "Copyright[sl]": "© 2006-2008 Pino Toscano", + "Copyright[sr@ijekavian]": "© 2006–2008, Пино Тоскано", + "Copyright[sr@ijekavianlatin]": "© 2006–2008, Pino Toskano", + "Copyright[sr@latin]": "© 2006–2008, Pino Toskano", + "Copyright[sr]": "© 2006–2008, Пино Тоскано", + "Copyright[sv]": "© 2006-2008 Pino Toscano", + "Copyright[tr]": "© 2006-2008 Pino Toscano", + "Copyright[uk]": "© Pino Toscano, 2006–2008", + "Copyright[x-test]": "xx© 2006-2008 Pino Toscanoxx", + "Copyright[zh_CN]": "© 2006-2008 Pino Toscano", + "Copyright[zh_TW]": "© 2006-2008 Pino Toscano", + "Description": "DjVu backend based on DjVuLibre", + "Description[az]": "DjVuLibre'yə əsaslanan DjVu modulu", + "Description[ca@valencia]": "Dorsal DjVu basat en el DjVuLibre", + "Description[ca]": "Dorsal DjVu basat en el DjVuLibre", + "Description[cs]": "Implementace DjVu založena na DjVuLibre", + "Description[da]": "DjVu-backend baseret pÃ¥ DjVuLibre", + "Description[de]": "Anzeigemodul für DjVu auf der Basis von DjVuLibre", + "Description[el]": "Σύστημα υποστήριξης DjVu με βάση το DjVuLibre", + "Description[en_GB]": "DjVu backend based on DjVuLibre", + "Description[es]": "Motor DjVu basado en DjVuLibre", + "Description[et]": "DjVu taustaprogramm DjVuLibre alusel", + "Description[eu]": "DjVu-ren bizkarraldekoa DjVuLibre-n oinarritua", + "Description[fi]": "DjVuLibreen perustuva DjVu-taustaosa", + "Description[fr]": "Moteur DjVu utilisant DjVuLibre", + "Description[gl]": "Infraestrutura de DjVu baseada en DjVuLibre.", + "Description[ia]": "Retro-Administration de DjVu basate sur DjVuLibre.", + "Description[it]": "Backend DjVu basato su DjVuLibre", + "Description[ko]": "DjVuLibre 기반 DjVu 백엔드", + "Description[lt]": "DjVu programinė sąsaja pagrįsta DjVuLibre", + "Description[nl]": "DjVu-backend gebaseerd op DjVuLibre", + "Description[nn]": "DjVu-motor basert pÃ¥ DjVuLibre", + "Description[pl]": "Obsługa formatu DjVu oparta na DjVuLibre", + "Description[pt]": "Infra-estrutura do DjVu com base no DjVuLibre", + "Description[pt_BR]": "Infraestrutura DjVu, baseado no DjVuLibre", + "Description[ru]": "Модуль поддержки формата DjVu на основе библиотеки DjVuLibre", + "Description[sk]": "DjVu backend postavený na DjVuLibre", + "Description[sl]": "Zaledje za DjVu, ki temelji na DjVuLibre", + "Description[sr@ijekavian]": "Позадина за ДјВу заснована на ДјВу‑либреу", + "Description[sr@ijekavianlatin]": "Pozadina za DjVu zasnovana na DjVuLibreu", + "Description[sr@latin]": "Pozadina za DjVu zasnovana na DjVuLibreu", + "Description[sr]": "Позадина за ДјВу заснована на ДјВу‑либреу", + "Description[sv]": "DjVu-gränssnitt baserat pÃ¥ DjVuLibre", + "Description[tr]": "DjVuLibre tabanlı DjVu arka ucu", + "Description[uk]": "Засіб обробки DjVu, заснований на DjVuLibre", + "Description[x-test]": "xxDjVu backend based on DjVuLibrexx", + "Description[zh_CN]": "基于 DjVuLibre 的 DjVu 后端", + "Description[zh_TW]": "基於 DjVuLibre 的 DjVu 後端介面", + "Id": "okular_djvu", + "License": "GPL", + "MimeTypes": [ + "image/vnd.djvu" + ], + "Name": "DjVu Backend", + "Name[az]": "DjVu modulu", + "Name[ca@valencia]": "Dorsal DjVu", + "Name[ca]": "Dorsal DjVu", + "Name[cs]": "Podpůrná vrstva DjVu", + "Name[da]": "DjVu-backend", + "Name[de]": "Anzeigemodul für DjVu", + "Name[el]": "Σύστημα υποστήριξης djvu", + "Name[en_GB]": "DjVu Backend", + "Name[es]": "Motor para DjVu", + "Name[et]": "DjVu taustaprogramm", + "Name[eu]": "DjVu-ren bizkarraldekoa", + "Name[fi]": "DjVu-taustaosa", + "Name[fr]": "Moteur DjVu", + "Name[gl]": "Infraestrutura para DjVu", + "Name[ia]": "Retro-Administration de DjVu", + "Name[it]": "Backend DjVu", + "Name[ko]": "DjVu 백엔드", + "Name[lt]": "DjVu programinė sąsaja", + "Name[nl]": "DjVu-backend", + "Name[nn]": "DjVu-motor", + "Name[pl]": "Obsługa DjVu", + "Name[pt]": "Infra-Estrutura do DjVu", + "Name[pt_BR]": "Infraestrutura DjVu", + "Name[ru]": "Модуль поддержки формата DjVu", + "Name[sk]": "DjVu Backend", + "Name[sl]": "Zaledje za DjVu", + "Name[sr@ijekavian]": "Позадина за ДјВу", + "Name[sr@ijekavianlatin]": "Pozadina za DjVu", + "Name[sr@latin]": "Pozadina za DjVu", + "Name[sr]": "Позадина за ДјВу", + "Name[sv]": "DjVu-gränssnitt", + "Name[tr]": "DjVu Arka Ucu", + "Name[uk]": "Модуль DjVu", + "Name[x-test]": "xxDjVu Backendxx", + "Name[zh_CN]": "DjVu 后端", + "Name[zh_TW]": "DjVu 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.2.3" + }, + "X-KDE-Priority": 2, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/djvu/okularApplication_djvu.desktop b/generators/djvu/okularApplication_djvu.desktop new file mode 100755 index 0000000..2a6e913 --- /dev/null +++ b/generators/djvu/okularApplication_djvu.desktop @@ -0,0 +1,226 @@ +[Desktop Entry] +MimeType=image/vnd.djvu; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=djvu +X-KDE-Keywords[ar]=djvu +X-KDE-Keywords[az]=djvu +X-KDE-Keywords[bg]=djvu +X-KDE-Keywords[bs]=djvu +X-KDE-Keywords[ca]=djvu +X-KDE-Keywords[ca@valencia]=djvu +X-KDE-Keywords[cs]=djvu +X-KDE-Keywords[da]=djvu +X-KDE-Keywords[de]=djvu +X-KDE-Keywords[el]=djvu +X-KDE-Keywords[en_GB]=djvu +X-KDE-Keywords[eo]=djvu +X-KDE-Keywords[es]=djvu +X-KDE-Keywords[et]=djvu +X-KDE-Keywords[eu]=djvu +X-KDE-Keywords[fi]=djvu +X-KDE-Keywords[fr]=djvu +X-KDE-Keywords[ga]=djvu +X-KDE-Keywords[gl]=djvu +X-KDE-Keywords[hu]=djvu +X-KDE-Keywords[ia]=djvu +X-KDE-Keywords[is]=djvu +X-KDE-Keywords[it]=djvu +X-KDE-Keywords[ja]=djvu +X-KDE-Keywords[kk]=djvu +X-KDE-Keywords[km]=djvu +X-KDE-Keywords[ko]=djvu +X-KDE-Keywords[lt]=djvu +X-KDE-Keywords[lv]=djvu +X-KDE-Keywords[mr]=djvu +X-KDE-Keywords[nb]=djvu +X-KDE-Keywords[nds]=DjVu +X-KDE-Keywords[nl]=djvu +X-KDE-Keywords[nn]=djvu +X-KDE-Keywords[pa]=djvu +X-KDE-Keywords[pl]=djvu +X-KDE-Keywords[pt]=djvu +X-KDE-Keywords[pt_BR]=djvu +X-KDE-Keywords[ro]=djvu +X-KDE-Keywords[ru]=djvu +X-KDE-Keywords[sk]=djvu +X-KDE-Keywords[sl]=djvu +X-KDE-Keywords[sr]=djvu,ДјВу +X-KDE-Keywords[sr@ijekavian]=djvu,ДјВу +X-KDE-Keywords[sr@ijekavianlatin]=djvu,DjVu +X-KDE-Keywords[sr@latin]=djvu,DjVu +X-KDE-Keywords[sv]=djvu +X-KDE-Keywords[tr]=djvu +X-KDE-Keywords[ug]=djvu +X-KDE-Keywords[uk]=djvu +X-KDE-Keywords[x-test]=xxdjvuxx +X-KDE-Keywords[zh_CN]=djvu +X-KDE-Keywords[zh_TW]=djvu diff --git a/generators/djvu/okularDjvu.desktop b/generators/djvu/okularDjvu.desktop new file mode 100644 index 0000000..4a47cb9 --- /dev/null +++ b/generators/djvu/okularDjvu.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=image/vnd.djvu; diff --git a/generators/djvu/org.kde.mobile.okular_djvu.desktop b/generators/djvu/org.kde.mobile.okular_djvu.desktop new file mode 100644 index 0000000..3e470ae --- /dev/null +++ b/generators/djvu/org.kde.mobile.okular_djvu.desktop @@ -0,0 +1,217 @@ +[Desktop Entry] +MimeType=image/vnd.djvu; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=djvu +X-KDE-Keywords[ar]=djvu +X-KDE-Keywords[az]=djvu +X-KDE-Keywords[bg]=djvu +X-KDE-Keywords[bs]=djvu +X-KDE-Keywords[ca]=djvu +X-KDE-Keywords[ca@valencia]=djvu +X-KDE-Keywords[cs]=djvu +X-KDE-Keywords[da]=djvu +X-KDE-Keywords[de]=djvu +X-KDE-Keywords[el]=djvu +X-KDE-Keywords[en_GB]=djvu +X-KDE-Keywords[eo]=djvu +X-KDE-Keywords[es]=djvu +X-KDE-Keywords[et]=djvu +X-KDE-Keywords[eu]=djvu +X-KDE-Keywords[fi]=djvu +X-KDE-Keywords[fr]=djvu +X-KDE-Keywords[ga]=djvu +X-KDE-Keywords[gl]=djvu +X-KDE-Keywords[hu]=djvu +X-KDE-Keywords[ia]=djvu +X-KDE-Keywords[is]=djvu +X-KDE-Keywords[it]=djvu +X-KDE-Keywords[ja]=djvu +X-KDE-Keywords[kk]=djvu +X-KDE-Keywords[km]=djvu +X-KDE-Keywords[ko]=djvu +X-KDE-Keywords[lt]=djvu +X-KDE-Keywords[lv]=djvu +X-KDE-Keywords[mr]=djvu +X-KDE-Keywords[nb]=djvu +X-KDE-Keywords[nds]=DjVu +X-KDE-Keywords[nl]=djvu +X-KDE-Keywords[nn]=djvu +X-KDE-Keywords[pa]=djvu +X-KDE-Keywords[pl]=djvu +X-KDE-Keywords[pt]=djvu +X-KDE-Keywords[pt_BR]=djvu +X-KDE-Keywords[ro]=djvu +X-KDE-Keywords[ru]=djvu +X-KDE-Keywords[sk]=djvu +X-KDE-Keywords[sl]=djvu +X-KDE-Keywords[sr]=djvu,ДјВу +X-KDE-Keywords[sr@ijekavian]=djvu,ДјВу +X-KDE-Keywords[sr@ijekavianlatin]=djvu,DjVu +X-KDE-Keywords[sr@latin]=djvu,DjVu +X-KDE-Keywords[sv]=djvu +X-KDE-Keywords[tr]=djvu +X-KDE-Keywords[ug]=djvu +X-KDE-Keywords[uk]=djvu +X-KDE-Keywords[x-test]=xxdjvuxx +X-KDE-Keywords[zh_CN]=djvu +X-KDE-Keywords[zh_TW]=djvu diff --git a/generators/djvu/org.kde.okular-djvu.metainfo.xml b/generators/djvu/org.kde.okular-djvu.metainfo.xml new file mode 100644 index 0000000..6883b4f --- /dev/null +++ b/generators/djvu/org.kde.okular-djvu.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-djvu + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + DjVu Documents + DjVu sənədləri + Documents DjVu + Documents DjVu + Dokumenty DjVu + DjVu-Dokumente + Έγγραφα DjVu + DjVu Documents + Documentos DjVu + DjVu dokumendid + DjVu dokumentuak + DjVu-tiedostot + Documents DjVu + Documentos DjVu + Documentos DjVu + Documenti DjVu + DjVu 문서 + DjVu dokumentai + ഡിജെവിയു പ്രമാണങ്ങൾ + DjVu-documenten + DjVu-dokument + Dokumenty DjVu + Documentos DjVu + Documentos DjVu + Документы DjVu + DjVu dokumenty + Dokumenti DjVu + ДјВу документи + DjVu dokumenti + ДјВу документи + DjVu dokumenti + DjVu-dokument + DvVu Belgeleri + документи DjVu + xxDjVu Documentsxx + DjVu 文档 + DjVu 文件 + Adds support for reading DjVu documents + DjVu sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents DjVu + Afig la implementació per a llegir documents DjVu + Přidává podporu pro čtení dokumentů DjVu + Bietet Unterstützung zum Lesen von DjVu-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων DjVu + Adds support for reading DjVu documents + Permite la lectura de documentos DjVu + DjVu dokumentide lugemise toetus + DjVu dokumentuak irakurtzeko euskarria gehitzen du + Lisää DjVu-tiedostojen lukutuen + Permet la lecture des documents DjVu + Engade a posibilidade de ler documentos de DjVu + Adde supporto per leger documentos DjVu + Aggiunge il supporto per la lettura di documenti DjVu + DjVu 문서 읽기 지원 추가 + Prideda palaikymą DjVu dokumentų skaitymui + ഡിജെവിയു പ്രമാണങ്ങൾ വായിക്കുവാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van DjVu-documenten toe + Legg til støtte for Ã¥ lesa DjVu-dokument + Dodaje obsługę dokumentów DjVu + Adiciona o suporte para a leitura de documentos DjVu + Adiciona o suporte para leitura de documentos DjVu + Поддержка чтения документов DjVu + Pridá podporu pre čítanie DjVu dokumentov + Doda podporo za branje dokumentov DjVu + Подршка за читање ДјВу докумената + PodrÅ¡ka za čitanje DjVu dokumenata + Подршка за читање ДјВу докумената + PodrÅ¡ka za čitanje DjVu dokumenata + Lägger till stöd för att läsa DjVu-dokument + DjVu belgelerini okuma desteği ekler + Додає підтримку читання документів DjVu + xxAdds support for reading DjVu documentsxx + 增加对 DjVu 文档的阅读支持 + 加入讀取 DjVu 文件的支援 + + image/vnd.djvu + + https://okular.kde.org + + + + + + + diff --git a/generators/dvi/CMakeLists.txt b/generators/dvi/CMakeLists.txt new file mode 100644 index 0000000..79a1e35 --- /dev/null +++ b/generators/dvi/CMakeLists.txt @@ -0,0 +1,62 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_dvi") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + +#add_definitions(-DDEBUG_DVIRENDERER -DDEBUG_RENDER -DDEBUG_PRESCAN -DDEBUG_PSGS -DDEBUG_FONTPOOL) + +if (FREETYPE_FOUND) + add_definitions(-DHAVE_FREETYPE) + include_directories(${FREETYPE_INCLUDE_DIRS}) +else (FREETYPE_FOUND) + remove_definitions(-DHAVE_FREETYPE) +endif (FREETYPE_FOUND) + +########### next target ############### + +set(okularGenerator_dvi_SRCS + generator_dvi.cpp + bigEndianByteReader.cpp + dviRenderer.cpp + dviRenderer_draw.cpp + dviRenderer_prescan.cpp + dviRenderer_dr.cpp + special.cpp + dviFile.cpp + dviPageInfo.cpp + psgs.cpp +# psheader.cpp # already included in psgs.cpp + glyph.cpp + TeXFont.cpp + TeXFontDefinition.cpp + vf.cpp + TeXFont_PFB.cpp + TeXFont_PK.cpp + TeXFont_TFM.cpp + util.cpp + pageSize.cpp + simplePageSize.cpp + length.cpp + fontEncoding.cpp + fontEncodingPool.cpp + fontMap.cpp + fontpool.cpp + dvisourcesplitter.cpp + dviexport.cpp +) + + +okular_add_generator(okularGenerator_dvi ${okularGenerator_dvi_SRCS}) + +target_link_libraries(okularGenerator_dvi okularcore KF5::I18n) +if (FREETYPE_FOUND) + target_link_libraries(okularGenerator_dvi ${FREETYPE_LIBRARIES}) +endif (FREETYPE_FOUND) + + +########### install files ############### +install( FILES okularDvi.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_dvi.desktop org.kde.mobile.okular_dvi.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-dvi.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/dvi/Messages.sh b/generators/dvi/Messages.sh new file mode 100644 index 0000000..deeeb65 --- /dev/null +++ b/generators/dvi/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_dvi.pot diff --git a/generators/dvi/TeXFont.cpp b/generators/dvi/TeXFont.cpp new file mode 100644 index 0000000..fa831bb --- /dev/null +++ b/generators/dvi/TeXFont.cpp @@ -0,0 +1,8 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +#include + +#include "TeXFont.h" + +TeXFont::~TeXFont() +{ +} diff --git a/generators/dvi/TeXFont.h b/generators/dvi/TeXFont.h new file mode 100644 index 0000000..ec9356d --- /dev/null +++ b/generators/dvi/TeXFont.h @@ -0,0 +1,51 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// TeXFont.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#ifndef _TEXFONT_H +#define _TEXFONT_H + +#include "TeXFontDefinition.h" +#include "glyph.h" + +class TeXFont +{ +public: + TeXFont(TeXFontDefinition *_parent) + { + parent = _parent; + errorMessage.clear(); + } + + virtual ~TeXFont(); + + TeXFont(const TeXFont &) = delete; + TeXFont &operator=(const TeXFont &) = delete; + + void setDisplayResolution() + { + for (glyph &g : glyphtable) + g.shrunkenCharacter = QImage(); + } + + virtual glyph *getGlyph(quint16 character, bool generateCharacterPixmap = false, const QColor &color = Qt::black) = 0; + + // Checksum of the font. Used e.g. by PK fonts. This field is filled + // in by the constructor, or set to 0.0, if the font format does not + // contain checksums. + quint32 checksum; + + // If the font or if some glyphs could not be loaded, error messages + // will be put here. + QString errorMessage; + +protected: + glyph glyphtable[TeXFontDefinition::max_num_of_chars_in_font]; + TeXFontDefinition *parent; +}; + +#endif diff --git a/generators/dvi/TeXFontDefinition.cpp b/generators/dvi/TeXFontDefinition.cpp new file mode 100644 index 0000000..4d95b69 --- /dev/null +++ b/generators/dvi/TeXFontDefinition.cpp @@ -0,0 +1,242 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +#include + +#include "TeXFontDefinition.h" +#include "debug_dvi.h" +#include "dviRenderer.h" +#ifdef HAVE_FREETYPE +#include "TeXFont_PFB.h" +#endif +#include "TeXFont_PK.h" +#include "TeXFont_TFM.h" +#include "debug_dvi.h" +#include "xdvi.h" + +#include + +#include +#include + +extern const int MFResolutions[]; + +#define PK_PRE 247 +#define PK_ID 89 +#define PK_MAGIC (PK_PRE << 8) + PK_ID +#define GF_PRE 247 +#define GF_ID 131 +#define GF_MAGIC (GF_PRE << 8) + GF_ID +#define VF_PRE 247 +#define VF_ID_BYTE 202 +#define VF_MAGIC (VF_PRE << 8) + VF_ID_BYTE + +// #define DEBUG_FONT + +TeXFontDefinition::TeXFontDefinition(const QString &nfontname, double _displayResolution_in_dpi, quint32 chk, qint32 _scaled_size_in_DVI_units, class fontPool *pool, double _enlargement) +{ +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "TeXFontDefinition::TeXFontDefinition(...); fontname=" << nfontname << ", enlargement=" << _enlargement; +#endif + + enlargement = _enlargement; + font_pool = pool; + fontname = nfontname; + font = nullptr; + displayResolution_in_dpi = _displayResolution_in_dpi; + checksum = chk; + flags = TeXFontDefinition::FONT_IN_USE; + file = nullptr; + filename.clear(); + scaled_size_in_DVI_units = _scaled_size_in_DVI_units; + + macrotable = nullptr; + + // By default, this font contains only empty characters. After the + // font has been loaded, this function pointer will be replaced by + // another one. + set_char_p = &dviRenderer::set_empty_char; +} + +TeXFontDefinition::~TeXFontDefinition() +{ +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "discarding font " << fontname << " at " << (int)(enlargement * MFResolutions[font_pool->getMetafontMode()] + 0.5) << " dpi"; +#endif + + if (font != nullptr) { + delete font; + font = nullptr; + } + if (macrotable != nullptr) { + delete[] macrotable; + macrotable = nullptr; + } + + if (flags & FONT_LOADED) { + if (file != nullptr) { + fclose(file); + file = nullptr; + } + if (flags & FONT_VIRTUAL) + vf_table.clear(); + } +} + +void TeXFontDefinition::fontNameReceiver(const QString &fname) +{ +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "void TeXFontDefinition::fontNameReceiver( " << fname << " )"; +#endif + + flags |= TeXFontDefinition::FONT_LOADED; + filename = fname; +#ifdef HAVE_FREETYPE + fullFontName.clear(); + fullEncodingName.clear(); +#endif + + file = fopen(QFile::encodeName(filename).constData(), "r"); + // Check if the file could be opened. If not, try to find the file + // in the DVI file's directory. If that works, modify the filename + // accordingly and go on. + if (file == nullptr) { + QString filename_test(font_pool->getExtraSearchPath() + QLatin1Char('/') + filename); + file = fopen(QFile::encodeName(filename_test).constData(), "r"); + if (file == nullptr) { + qCCritical(OkularDviDebug) << i18n("Cannot find font %1, file %2.", fontname, filename) << endl; + return; + } else + filename = filename_test; + } + + set_char_p = &dviRenderer::set_char; + int magic = two(file); + + if (fname.endsWith(QLatin1String("pk"))) + if (magic == PK_MAGIC) { + fclose(file); + file = nullptr; + font = new TeXFont_PK(this); + set_char_p = &dviRenderer::set_char; + if ((checksum != 0) && (checksum != font->checksum)) + qCWarning(OkularDviDebug) << i18n("Checksum mismatch for font file %1", filename); + fontType = TEX_PK; + return; + } + + if (fname.endsWith(QLatin1String(".vf"))) + if (magic == VF_MAGIC) { + read_VF_index(); + set_char_p = &dviRenderer::set_vf_char; + fontType = TEX_VIRTUAL; + return; + } + + if (fname.endsWith(QLatin1String(".tfm"))) { + fclose(file); + file = nullptr; + font = new TeXFont_TFM(this); + set_char_p = &dviRenderer::set_char; + fontType = TEX_FONTMETRIC; + return; + } + + // None of these known types? Then it should be one of the font + // formats that are handled by the FreeType library + fclose(file); + file = nullptr; +#ifdef HAVE_FREETYPE + // Find the encoding for that font + const QString &enc = font_pool->fontsByTeXName.findEncoding(fontname); + + if (enc.isEmpty() == false) { +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "Font " << fontname << " uses encoding " << enc; +#endif + font = new TeXFont_PFB(this, font_pool->encodingPool.findByName(enc), font_pool->fontsByTeXName.findSlant(fontname)); + } else { +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "Font " << fontname << " does not have an encoding."; +#endif + font = new TeXFont_PFB(this); + } + + set_char_p = &dviRenderer::set_char; + fontType = FREETYPE; + return; +#else + // If we don't have the FreeType library, we should never have + // reached this point. Complain, and leave this font blank + qCCritical(OkularDviDebug) << i18n("Cannot recognize format for font file %1", filename) << endl; +#endif +} + +void TeXFontDefinition::reset() +{ + if (font != nullptr) { + delete font; + font = nullptr; + } + + if (macrotable != nullptr) { + delete[] macrotable; + macrotable = nullptr; + } + + if (flags & FONT_LOADED) { + if (file != nullptr) { + fclose(file); + file = nullptr; + } + if (flags & FONT_VIRTUAL) + vf_table.clear(); + } + + filename.clear(); + flags = TeXFontDefinition::FONT_IN_USE; + set_char_p = &dviRenderer::set_empty_char; +} + +void TeXFontDefinition::setDisplayResolution(double _displayResolution_in_dpi) +{ + displayResolution_in_dpi = _displayResolution_in_dpi; + if (font != nullptr) + font->setDisplayResolution(); +} + +/** mark_as_used marks the font, and all the fonts it refers to, as + used, i.e. their FONT_IN_USE-flag is set. */ + +void TeXFontDefinition::mark_as_used() +{ +#ifdef DEBUG_FONT + qCDebug(OkularDviDebug) << "TeXFontDefinition::mark_as_used()"; +#endif + + if (flags & TeXFontDefinition::FONT_IN_USE) + return; + + flags |= TeXFontDefinition::FONT_IN_USE; + + // For virtual fonts, also go through the list of referred fonts + if (flags & TeXFontDefinition::FONT_VIRTUAL) { + QHashIterator it(vf_table); + while (it.hasNext()) { + it.next(); + it.value()->flags |= TeXFontDefinition::FONT_IN_USE; + } + } +} + +macro::macro() +{ + pos = nullptr; /* address of first byte of macro */ + end = nullptr; /* address of last+1 byte */ + dvi_advance_in_units_of_design_size_by_2e20 = 0; /* DVI units to move reference point */ + free_me = false; +} + +macro::~macro() +{ + if ((pos != nullptr) && (free_me == true)) + delete[] pos; +} diff --git a/generators/dvi/TeXFontDefinition.h b/generators/dvi/TeXFontDefinition.h new file mode 100644 index 0000000..38d3dc7 --- /dev/null +++ b/generators/dvi/TeXFontDefinition.h @@ -0,0 +1,162 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * The layout of a font information block. + * There is one of these for every loaded font or magnification thereof. + * Duplicates are eliminated: this is necessary because of possible recursion + * in virtual fonts. + * + * Also note the strange units. The design size is in 1/2^20 point + * units (also called micro-points), and the individual character widths + * are in the TFM file in 1/2^20 ems units, i.e., relative to the design size. + * + * We then change the sizes to SPELL units (unshrunk pixel / 2^16). + */ + +#ifndef _FONT_H +#define _FONT_H + +#include +#include + +class dviRenderer; +class TeXFont; + +typedef void (dviRenderer::*set_char_proc)(unsigned int, unsigned int); + +// Per character information for virtual fonts + +class macro +{ +public: + macro(); + ~macro(); + + macro(const macro &) = delete; + macro &operator=(const macro &) = delete; + + // address of first byte of macro + unsigned char *pos; + // address of last+1 byte + unsigned char *end; + // DVI units to move reference point + qint32 dvi_advance_in_units_of_design_size_by_2e20; + // if memory at pos should be returned on destruction + bool free_me; +}; + +class TeXFontDefinition +{ +public: + // Currently, kdvi supports fonts with at most 256 characters to + // comply with "The DVI Driver Standard, Level 0". If you change + // this value here, make sure to go through all the source and + // ensure that character numbers are stored in ints rather than + // unsigned chars. + static const unsigned int max_num_of_chars_in_font = 256; + enum font_flags { + // used for housekeeping + FONT_IN_USE = 1, + // if font file has been read + FONT_LOADED = 2, + // if font is virtual + FONT_VIRTUAL = 4, + // if kpathsea has already tried to find the font name + FONT_KPSE_NAME = 8 + }; + + enum font_type { TEX_PK, TEX_VIRTUAL, TEX_FONTMETRIC, FREETYPE }; + + TeXFontDefinition(const QString &nfontname, double _displayResolution_in_dpi, quint32 chk, qint32 _scaled_size_in_DVI_units, class fontPool *pool, double _enlargement); + ~TeXFontDefinition(); + + TeXFontDefinition(const TeXFontDefinition &) = delete; + TeXFontDefinition &operator=(const TeXFontDefinition &) = delete; + + void reset(); + void fontNameReceiver(const QString &); + + // Members for character fonts + void setDisplayResolution(double _displayResolution_in_dpi); + + bool isLocated() const + { + return ((flags & FONT_KPSE_NAME) != 0); + } + void markAsLocated() + { + flags |= FONT_KPSE_NAME; + } + + void mark_as_used(); + // Pointer to the pool that contains this font. + class fontPool *font_pool; + // name of font, such as "cmr10" + QString fontname; + // flags byte (see values below) + unsigned char flags; + double enlargement; + // Scaled size from the font definition command; in DVI units + qint32 scaled_size_in_DVI_units; + // proc used to set char + set_char_proc set_char_p; + + // Resolution of the display device (resolution will usually be + // scaled, according to the zoom) + double displayResolution_in_dpi; + + // open font file or NULL + FILE *file; + // name of font file + QString filename; + + TeXFont *font; + // used by (loaded) virtual fonts + macro *macrotable; + // used by (loaded) virtual fonts, list of fonts used by this vf, + QHash vf_table; + // accessible by number + // used by (loaded) virtual fonts, list of fonts used by this vf + TeXFontDefinition *first_font; + +#ifdef HAVE_FREETYPE + const QString &getFullFontName() const + { + return fullFontName; + } + const QString &getFullEncodingName() const + { + return fullEncodingName; + } +#endif + + const font_type &getFontType() const + { + return fontType; + }; + +#ifdef HAVE_FREETYPE + /** For FREETYPE fonts, which use a map file, this field will + contain the full name of the font (e.g. 'Computer Modern'). If + the name does not exist, or cannot be found, this field will be + QString(). Only subclasses of TeXFont should write into this + field. */ + QString fullFontName; + + /** For FREETYPE fonts, which use a map file, this field will + contain the full name of the font encoding (e.g. 'TexBase1'). If + the encoding name does not exist, or cannot be found, this field + will be QString(). Only subclasses of TeXFont should write + into this field. */ + QString fullEncodingName; +#endif + +private: + quint32 checksum; + + font_type fontType; + + // Functions related to virtual fonts + void read_VF_index(); +}; + +#endif diff --git a/generators/dvi/TeXFont_PFB.cpp b/generators/dvi/TeXFont_PFB.cpp new file mode 100644 index 0000000..1c38ab6 --- /dev/null +++ b/generators/dvi/TeXFont_PFB.cpp @@ -0,0 +1,284 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// TeXFont_PFB.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +// This file is compiled only if the FreeType library is present on +// the system + +#include + +#ifdef HAVE_FREETYPE + +#include "TeXFont_PFB.h" +#include "debug_dvi.h" +#include "fontpool.h" + +#include + +#include +#include + +//#define DEBUG_PFB 1 + +TeXFont_PFB::TeXFont_PFB(TeXFontDefinition *parent, fontEncoding *enc, double slant) + : TeXFont(parent) + , face(nullptr) +{ +#ifdef DEBUG_PFB + if (enc != 0) + qCDebug(OkularDviDebug) << "TeXFont_PFB::TeXFont_PFB( parent=" << parent << ", encoding=" << enc->encodingFullName << " )"; + else + qCDebug(OkularDviDebug) << "TeXFont_PFB::TeXFont_PFB( parent=" << parent << ", encoding=0 )"; +#endif + + fatalErrorInFontLoading = false; + + int error = FT_New_Face(parent->font_pool->FreeType_library, parent->filename.toLocal8Bit().constData(), 0, &face); + + if (error == FT_Err_Unknown_File_Format) { + errorMessage = i18n("The font file %1 could be opened and read, but its font format is unsupported.", parent->filename); + qCCritical(OkularDviDebug) << errorMessage << endl; + fatalErrorInFontLoading = true; + return; + } else if (error) { + errorMessage = i18n("The font file %1 is broken, or it could not be opened or read.", parent->filename); + qCCritical(OkularDviDebug) << errorMessage << endl; + fatalErrorInFontLoading = true; + return; + } + + // Take care of slanting, and transform all characters in the font, if necessary. + if (slant != 0.0) { + // Construct a transformation matrix for vertical shear which will + // be used to transform the characters. + transformationMatrix.xx = 0x10000; + transformationMatrix.xy = (FT_Fixed)(slant * 0x10000); + transformationMatrix.yx = 0; + transformationMatrix.yy = 0x10000; + + FT_Set_Transform(face, &transformationMatrix, nullptr); + } + + if (face->family_name != nullptr) + parent->fullFontName = QString::fromLocal8Bit(face->family_name); + + // Finally, we need to set up the charMap array, which maps TeX + // character codes to glyph indices in the font. (Remark: the + // charMap, and the font encoding procedure is necessary, because + // TeX is only able to address character codes 0-255 while + // e.g. Type1 fonts may contain several thousands of characters) + if (enc != nullptr) { + parent->fullEncodingName = enc->encodingFullName.remove(QStringLiteral("Encoding")); + parent->fullEncodingName = enc->encodingFullName.remove(QStringLiteral("encoding")); + + // An encoding vector is given for this font, i.e. an array of + // character names (such as: 'parenleft' or 'dotlessj'). We use + // the FreeType library function 'FT_Get_Name_Index()' to + // associate glyph indices to those names. +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << "Trying to associate glyph indices to names from the encoding vector."; +#endif + for (int i = 0; i < 256; i++) { + charMap[i] = FT_Get_Name_Index(face, (FT_String *)(enc->glyphNameVector[i].toLatin1().data())); +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << i << ": " << enc->glyphNameVector[i] << ", GlyphIndex=" << charMap[i]; +#endif + } + } else { + // If there is no encoding vector available, we check if the font + // itself contains a charmap that could be used. An admissible + // charMap will be stored under platform_id=7 and encoding_id=2. + FT_CharMap found = nullptr; + for (int n = 0; n < face->num_charmaps; n++) { + FT_CharMap charmap = face->charmaps[n]; + if (charmap->platform_id == 7 && charmap->encoding_id == 2) { + found = charmap; + break; + } + } + + if ((found != nullptr) && (FT_Set_Charmap(face, found) == 0)) { + // Feed the charMap array with the charmap data found in the + // previous step. +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << "No encoding given: using charmap platform=7, encoding=2 that is contained in the font."; +#endif + for (int i = 0; i < 256; i++) + charMap[i] = FT_Get_Char_Index(face, i); + } else { + if ((found == nullptr) && (face->charmap != nullptr)) { +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << "No encoding given: using charmap platform=" << face->charmap->platform_id << ", encoding=" << face->charmap->encoding_id << " that is contained in the font." << endl; +#endif + for (int i = 0; i < 256; i++) + charMap[i] = FT_Get_Char_Index(face, i); + } else { + // As a last resort, we use the identity map. +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << "No encoding given, no suitable charmaps found in the font: using identity charmap."; +#endif + for (int i = 0; i < 256; i++) + charMap[i] = i; + } + } + } +} + +TeXFont_PFB::~TeXFont_PFB() +{ + FT_Done_Face(face); +} + +glyph *TeXFont_PFB::getGlyph(quint16 ch, bool generateCharacterPixmap, const QColor &color) +{ +#ifdef DEBUG_PFB + qCDebug(OkularDviDebug) << "TeXFont_PFB::getGlyph( ch=" << ch << ", '" << (char)(ch) << "', generateCharacterPixmap=" << generateCharacterPixmap << " )"; +#endif + + // Paranoia checks + if (ch >= TeXFontDefinition::max_num_of_chars_in_font) { + qCCritical(OkularDviDebug) << "TeXFont_PFB::getGlyph(): Argument is too big." << endl; + return glyphtable; + } + + // This is the address of the glyph that will be returned. + glyph *g = glyphtable + ch; + + if (fatalErrorInFontLoading == true) + return g; + + if ((generateCharacterPixmap == true) && ((g->shrunkenCharacter.isNull()) || (color != g->color))) { + int error; + unsigned int res = (unsigned int)(parent->displayResolution_in_dpi / parent->enlargement + 0.5); + g->color = color; + + // Character height in 1/64th of points (reminder: 1 pt = 1/72 inch) + // Only approximate, may vary from file to file!!!! @@@@@ + + long int characterSize_in_printers_points_by_64 = (long int)((64.0 * 72.0 * parent->scaled_size_in_DVI_units * parent->font_pool->getCMperDVIunit()) / 2.54 + 0.5); + error = FT_Set_Char_Size(face, 0, characterSize_in_printers_points_by_64, res, res); + if (error) { + QString msg = i18n("FreeType reported an error when setting the character size for font file %1.", parent->filename); + if (errorMessage.isEmpty()) + errorMessage = msg; + qCCritical(OkularDviDebug) << msg << endl; + g->shrunkenCharacter = QImage(1, 1, QImage::Format_RGB32); + g->shrunkenCharacter.fill(qRgb(255, 255, 255)); + return g; + } + + // load glyph image into the slot and erase the previous one + if (parent->font_pool->getUseFontHints() == true) + error = FT_Load_Glyph(face, charMap[ch], FT_LOAD_DEFAULT); + else + error = FT_Load_Glyph(face, charMap[ch], FT_LOAD_NO_HINTING); + + if (error) { + QString msg = i18n("FreeType is unable to load glyph #%1 from font file %2.", ch, parent->filename); + if (errorMessage.isEmpty()) + errorMessage = msg; + qCCritical(OkularDviDebug) << msg << endl; + g->shrunkenCharacter = QImage(1, 1, QImage::Format_RGB32); + g->shrunkenCharacter.fill(qRgb(255, 255, 255)); + return g; + } + + // convert to an anti-aliased bitmap + error = FT_Render_Glyph(face->glyph, ft_render_mode_normal); + if (error) { + QString msg = i18n("FreeType is unable to render glyph #%1 from font file %2.", ch, parent->filename); + if (errorMessage.isEmpty()) + errorMessage = msg; + qCCritical(OkularDviDebug) << msg << endl; + g->shrunkenCharacter = QImage(1, 1, QImage::Format_RGB32); + g->shrunkenCharacter.fill(qRgb(255, 255, 255)); + return g; + } + + FT_GlyphSlot slot = face->glyph; + + if ((slot->bitmap.width == 0) || (slot->bitmap.rows == 0)) { + if (errorMessage.isEmpty()) + errorMessage = i18n("Glyph #%1 is empty.", ch); + qCCritical(OkularDviDebug) << i18n("Glyph #%1 from font file %2 is empty.", ch, parent->filename) << endl; + g->shrunkenCharacter = QImage(15, 15, QImage::Format_RGB32); + g->shrunkenCharacter.fill(qRgb(255, 0, 0)); + g->x2 = 0; + g->y2 = 15; + } else { + QImage imgi(slot->bitmap.width, slot->bitmap.rows, QImage::Format_ARGB32); + + // Do QPixmaps fully support the alpha channel? If yes, we use + // that. Otherwise, use other routines as a fallback + if (parent->font_pool->QPixmapSupportsAlpha) { + // If the alpha channel is properly supported, we set the + // character glyph to a colored rectangle, and define the + // character outline only using the alpha channel. That + // ensures good quality rendering for overlapping characters. + uchar *srcScanLine = slot->bitmap.buffer; + for (unsigned int row = 0; row < slot->bitmap.rows; row++) { + uchar *destScanLine = imgi.scanLine(row); + for (unsigned int col = 0; col < slot->bitmap.width; col++) { + destScanLine[4 * col + 0] = color.blue(); + destScanLine[4 * col + 1] = color.green(); + destScanLine[4 * col + 2] = color.red(); + destScanLine[4 * col + 3] = srcScanLine[col]; + } + srcScanLine += slot->bitmap.pitch; + } + } else { + // If the alpha channel is not supported... QT seems to turn + // the alpha channel into a crude bitmap which is used to mask + // the resulting QPixmap. In this case, we define the + // character outline using the image data, and use the alpha + // channel only to store "maximally opaque" or "completely + // transparent" values. When characters are rendered, + // overlapping characters are no longer correctly drawn, but + // quality is still sufficient for most purposes. One notable + // exception is output from the gftodvi program, which will be + // partially unreadable. + quint16 rInv = 0xFF - color.red(); + quint16 gInv = 0xFF - color.green(); + quint16 bInv = 0xFF - color.blue(); + + for (unsigned int y = 0; y < slot->bitmap.rows; y++) { + quint8 *srcScanLine = slot->bitmap.buffer + y * slot->bitmap.pitch; + unsigned int *destScanLine = reinterpret_cast(imgi.scanLine(y)); + for (unsigned int col = 0; col < slot->bitmap.width; col++) { + quint16 data = *srcScanLine; + // The value stored in "data" now has the following meaning: + // data = 0 -> white; data = 0xff -> use "color" + *destScanLine = qRgba(0xFF - (rInv * data + 0x7F) / 0xFF, 0xFF - (gInv * data + 0x7F) / 0xFF, 0xFF - (bInv * data + 0x7F) / 0xFF, (data > 0x03) ? 0xff : 0x00); + destScanLine++; + srcScanLine++; + } + } + } + + g->shrunkenCharacter = imgi; + g->x2 = -slot->bitmap_left; + g->y2 = slot->bitmap_top; + } + } + + // Load glyph width, if that hasn't been done yet. + if (g->dvi_advance_in_units_of_design_size_by_2e20 == 0) { + int error = FT_Load_Glyph(face, charMap[ch], FT_LOAD_NO_SCALE); + if (error) { + QString msg = i18n("FreeType is unable to load metric for glyph #%1 from font file %2.", ch, parent->filename); + if (errorMessage.isEmpty()) + errorMessage = msg; + qCCritical(OkularDviDebug) << msg << endl; + g->dvi_advance_in_units_of_design_size_by_2e20 = 1; + } + g->dvi_advance_in_units_of_design_size_by_2e20 = (qint32)(((qint64)(1 << 20) * (qint64)face->glyph->metrics.horiAdvance) / (qint64)face->units_per_EM); + } + + return g; +} + +#endif // HAVE_FREETYPE diff --git a/generators/dvi/TeXFont_PFB.h b/generators/dvi/TeXFont_PFB.h new file mode 100644 index 0000000..63dc790 --- /dev/null +++ b/generators/dvi/TeXFont_PFB.h @@ -0,0 +1,41 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// TeXFont_PFB.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +// This file is compiled only if the FreeType library is present on +// the system + +#ifndef _TEXFONT_PFB_H +#define _TEXFONT_PFB_H + +#include "TeXFont.h" + +#include +#include FT_FREETYPE_H + +class fontEncoding; +class glyph; + +class TeXFont_PFB : public TeXFont +{ +public: + TeXFont_PFB(TeXFontDefinition *parent, fontEncoding *enc = nullptr, double slant = 0.0); + ~TeXFont_PFB() override; + + glyph *getGlyph(quint16 character, bool generateCharacterPixmap = false, const QColor &color = Qt::black) override; + +private: + FT_Face face; + bool fatalErrorInFontLoading; + quint16 charMap[256]; + + // This matrix is used internally to describes the slant, if + // nonzero. Otherwise, this is undefined. + FT_Matrix transformationMatrix; +}; + +#endif diff --git a/generators/dvi/TeXFont_PK.cpp b/generators/dvi/TeXFont_PK.cpp new file mode 100644 index 0000000..5c7a80a --- /dev/null +++ b/generators/dvi/TeXFont_PK.cpp @@ -0,0 +1,729 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * NOTE: + * xdvi is based on prior work as noted in the modification history, below. + */ + +/* + * DVI previewer for X. + * + * Eric Cooper, CMU, September 1985. + * + * Code derived from dvi-imagen.c. + * + * Modification history: + * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS. + * 7/1988 Modified for X.11 --Mark Eichin, MIT + * 12/1988 Added 'R' option, toolkit, magnifying glass + * --Paul Vojta, UC Berkeley. + * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto + * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ. + * 3/1990 Added VMS support --Scott Allendorf, U of Iowa + * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem + * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen + * and Lee Hetherington, MIT + * 4/1994 Added DPS support, bounding box + * --Ricardo Telichevesky + * and Luis Miguel Silveira, MIT RLE. + */ + +#include + +#include "TeXFont_PK.h" +#include "debug_dvi.h" +#include "fontpool.h" +#include "xdvi.h" + +#include + +#include +#include + +#include +#include + +//#define DEBUG_PK + +#define PK_PRE 247 +#define PK_ID 89 +#define PK_MAGIC (PK_PRE << 8) + PK_ID + +extern void oops(const QString &message); + +TeXFont_PK::TeXFont_PK(TeXFontDefinition *parent) + : TeXFont(parent) +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::TeXFont_PK( parent=" << parent << ")"; +#endif + + for (auto &characterBitmap : characterBitmaps) + characterBitmap = nullptr; + file = fopen(QFile::encodeName(parent->filename).constData(), "r"); + if (file == nullptr) + qCCritical(OkularDviDebug) << i18n("Cannot open font file %1.", parent->filename) << endl; +#ifdef DEBUG_PK + else + qCDebug(OkularDviDebug) << "TeXFont_PK::TeXFont_PK(): file opened successfully"; +#endif + + read_PK_index(); + +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::TeXFont_PK() ended"; +#endif +} + +TeXFont_PK::~TeXFont_PK() +{ + //@@@ Release bitmaps + for (bitmap *characterBitmap : characterBitmaps) { + delete characterBitmap; + } + + if (file != nullptr) { + fclose(file); + file = nullptr; + } +} + +glyph *TeXFont_PK::getGlyph(quint16 ch, bool generateCharacterPixmap, const QColor &color) +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::getGlyph( ch=" << ch << ", generateCharacterPixmap=" << generateCharacterPixmap << " )"; +#endif + + // Paranoia checks + if (ch >= TeXFontDefinition::max_num_of_chars_in_font) { + qCCritical(OkularDviDebug) << "TeXFont_PK::getGlyph(): Argument is too big." << endl; + return glyphtable; + } + + // This is the address of the glyph that will be returned. + class glyph *g = glyphtable + ch; + + // Check if the glyph is loaded. If not, load it now. + if (characterBitmaps[ch] == nullptr) { + // If the character is not defined in the PK file, mark the + // character as missing, and print an error message + if (g->addr == 0) { + qCCritical(OkularDviDebug) << i18n("TexFont_PK::operator[]: Character %1 not defined in font %2", ch, parent->filename) << endl; + g->addr = -1; + return g; + } + + // If the character has already been marked as missing, just + // return a pointer to the glyph (which will then be empty) + if (g->addr == -1) + return g; + + // Otherwise, try to load the character + fseek(file, g->addr, 0); + read_PK_char(ch); + // Check if the character could be loaded. If not, mark the + // character as 'missing', and return a pointer. + if (characterBitmaps[ch]->bits == nullptr) { + g->addr = -1; + return g; + } + } + + // At this point, g points to a properly loaded character. Generate + // a smoothly scaled QPixmap if the user asks for it. + if ((generateCharacterPixmap == true) && ((g->shrunkenCharacter.isNull()) || (color != g->color)) && (characterBitmaps[ch]->w != 0)) { + g->color = color; + double shrinkFactor = 1200 / parent->displayResolution_in_dpi; + + // All is fine? Then we rescale the bitmap in order to produce the + // required pixmap. Rescaling a character, however, is an art + // that requires some explanation... + // + // If we would just divide the size of the character and the + // coordinates by the shrink factor, then the result would look + // quite ugly: due to the inevitable rounding errors in the + // integer arithmetic, the characters would be displaced by up to + // a pixel. That doesn't sound much, but on low-resolution + // devices, such as a notebook screen, the effect would be a + // "dancing line" of characters, which looks really bad. + + // Calculate the coordinates of the hot point in the shrunken + // bitmap. For simplicity, let us consider the x-coordinate + // first. In principle, the hot point should have an x-coordinate + // of (g->x/shrinkFactor). That, however, will generally NOT be an + // integral number. The cure is to translate the source image + // somewhat, so that the x-coordinate of the hot point falls onto + // the round-up of this number, i.e. + g->x2 = (int)ceil(g->x / shrinkFactor); + + // Translating and scaling then means that the pixel in the scaled + // image which covers the range [x,x+1) corresponds to the range + // [x*shrinkFactor+srcXTrans, (x+1)*shrinkFactor+srcXTrans), where + // srcXTrans is the following NEGATIVE number + double srcXTrans = shrinkFactor * (g->x / shrinkFactor - ceil(g->x / shrinkFactor)); + + // How big will the shrunken bitmap then become? If shrunk_width + // denotes that width of the scaled image, and + // characterBitmaps[ch]->w the width of the original image, we + // need to make sure that the following inequality holds: + // + // shrunk_width*shrinkFactor+srcXTrans >= characterBitmaps[ch]->w + // + // in other words, + int shrunk_width = (int)ceil((characterBitmaps[ch]->w - srcXTrans) / shrinkFactor); + + // Now do the same for the y-coordinate + g->y2 = (int)ceil(g->y / shrinkFactor); + double srcYTrans = shrinkFactor * (g->y / shrinkFactor - ceil(g->y / shrinkFactor)); + int shrunk_height = (int)ceil((characterBitmaps[ch]->h - srcYTrans) / shrinkFactor); + + // Turn the image into 8 bit + QByteArray translated(characterBitmaps[ch]->w * characterBitmaps[ch]->h, '\0'); + quint8 *data = (quint8 *)translated.data(); + for (int x = 0; x < characterBitmaps[ch]->w; x++) + for (int y = 0; y < characterBitmaps[ch]->h; y++) { + quint8 bit = *(characterBitmaps[ch]->bits + characterBitmaps[ch]->bytes_wide * y + (x >> 3)); + bit = bit >> (x & 7); + bit = bit & 1; + data[characterBitmaps[ch]->w * y + x] = bit; + } + + // Now shrink the image. We shrink the X-direction first + QByteArray xshrunk(shrunk_width * characterBitmaps[ch]->h, '\0'); + quint8 *xdata = (quint8 *)xshrunk.data(); + + // Do the shrinking. The pixel (x,y) that we want to calculate + // corresponds to the line segment from + // + // [shrinkFactor*x+srcXTrans, shrinkFactor*(x+1)+srcXTrans) + // + // The trouble is, these numbers are in general no integers. + + for (int y = 0; y < characterBitmaps[ch]->h; y++) + for (int x = 0; x < shrunk_width; x++) { + quint32 value = 0; + double destStartX = shrinkFactor * x + srcXTrans; + double destEndX = shrinkFactor * (x + 1) + srcXTrans; + for (int srcX = (int)ceil(destStartX); srcX < floor(destEndX); srcX++) + if ((srcX >= 0) && (srcX < characterBitmaps[ch]->w)) + value += data[characterBitmaps[ch]->w * y + srcX] * 255; + + if (destStartX >= 0.0) + value += (quint32)(255.0 * (ceil(destStartX) - destStartX) * data[characterBitmaps[ch]->w * y + (int)floor(destStartX)]); + if (floor(destEndX) < characterBitmaps[ch]->w) + value += (quint32)(255.0 * (destEndX - floor(destEndX)) * data[characterBitmaps[ch]->w * y + (int)floor(destEndX)]); + + xdata[shrunk_width * y + x] = (int)(value / shrinkFactor + 0.5); + } + + // Now shrink the Y-direction + QByteArray xyshrunk(shrunk_width * shrunk_height, '\0'); + quint8 *xydata = (quint8 *)xyshrunk.data(); + for (int x = 0; x < shrunk_width; x++) + for (int y = 0; y < shrunk_height; y++) { + quint32 value = 0; + double destStartY = shrinkFactor * y + srcYTrans; + double destEndY = shrinkFactor * (y + 1) + srcYTrans; + for (int srcY = (int)ceil(destStartY); srcY < floor(destEndY); srcY++) + if ((srcY >= 0) && (srcY < characterBitmaps[ch]->h)) + value += xdata[shrunk_width * srcY + x]; + + if (destStartY >= 0.0) + value += (quint32)((ceil(destStartY) - destStartY) * xdata[shrunk_width * (int)floor(destStartY) + x]); + if (floor(destEndY) < characterBitmaps[ch]->h) + value += (quint32)((destEndY - floor(destEndY)) * xdata[shrunk_width * (int)floor(destEndY) + x]); + + xydata[shrunk_width * y + x] = (int)(value / shrinkFactor); + } + + QImage im32(shrunk_width, shrunk_height, QImage::Format_ARGB32); + // Do QPixmaps fully support the alpha channel? If yes, we use + // that. Otherwise, use other routines as a fallback + if (parent->font_pool->QPixmapSupportsAlpha) { + // If the alpha channel is properly supported, we set the + // character glyph to a colored rectangle, and define the + // character outline only using the alpha channel. That ensures + // good quality rendering for overlapping characters. + im32.fill(qRgb(color.red(), color.green(), color.blue())); + for (int y = 0; y < shrunk_height; y++) { + quint8 *destScanLine = (quint8 *)im32.scanLine(y); + for (int col = 0; col < shrunk_width; col++) + destScanLine[4 * col + 3] = xydata[shrunk_width * y + col]; + } + } else { + // If the alpha channel is not supported... QT seems to turn the + // alpha channel into a crude bitmap which is used to mask the + // resulting QPixmap. In this case, we define the character + // outline using the image data, and use the alpha channel only + // to store "maximally opaque" or "completely transparent" + // values. When characters are rendered, overlapping characters + // are no longer correctly drawn, but quality is still + // sufficient for most purposes. One notable exception is output + // from the gftodvi program, which will be partially unreadable. + quint16 rInv = 0xFF - color.red(); + quint16 gInv = 0xFF - color.green(); + quint16 bInv = 0xFF - color.blue(); + + quint8 *srcScanLine = xydata; + for (int y = 0; y < shrunk_height; y++) { + unsigned int *destScanLine = reinterpret_cast(im32.scanLine(y)); + for (int col = 0; col < shrunk_width; col++) { + quint16 data = *srcScanLine; + // The value stored in "data" now has the following meaning: + // data = 0 -> white; data = 0xff -> use "color" + *destScanLine = qRgba(0xFF - (rInv * data + 0x7F) / 0xFF, 0xFF - (gInv * data + 0x7F) / 0xFF, 0xFF - (bInv * data + 0x7F) / 0xFF, (data > 0x03) ? 0xff : 0x00); + destScanLine++; + srcScanLine++; + } + } + } + + g->shrunkenCharacter = im32; + } + return g; +} + +#define ADD(a, b) (reinterpret_cast(((char *)a) + b)) +#define SUB(a, b) (reinterpret_cast(((char *)a) - b)) + +// This table is used for changing the bit order in a byte. The +// expression bitflp[byte] takes a byte in big endian and gives the +// little endian equivalent of that. +static const uchar bitflip[256] = {0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, + 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, + 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, + 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, + 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, + 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, + 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255}; + +static const quint32 bit_masks[33] = {0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, + 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; + +#define PK_ID 89 +#define PK_CMD_START 240 +#define PK_X1 240 +#define PK_X2 241 +#define PK_X3 242 +#define PK_X4 243 +#define PK_Y 244 +#define PK_POST 245 +#define PK_NOOP 246 +#define PK_PRE 247 + +int TeXFont_PK::PK_get_nyb(FILE *fp) +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "PK_get_nyb"; +#endif + + unsigned temp; + if (PK_bitpos < 0) { + PK_input_byte = one(fp); + PK_bitpos = 4; + } + temp = PK_input_byte >> PK_bitpos; + PK_bitpos -= 4; + return (temp & 0xf); +} + +int TeXFont_PK::PK_packed_num(FILE *fp) +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "PK_packed_num"; +#endif + + int i, j; + + if ((i = PK_get_nyb(fp)) == 0) { + do { + j = PK_get_nyb(fp); + ++i; + } while (j == 0); + while (i > 0) { + j = (j << 4) | PK_get_nyb(fp); + --i; + } + return (j - 15 + ((13 - PK_dyn_f) << 4) + PK_dyn_f); + } else { + if (i <= PK_dyn_f) + return i; + if (i < 14) + return (((i - PK_dyn_f - 1) << 4) + PK_get_nyb(fp) + PK_dyn_f + 1); + if (i == 14) + PK_repeat_count = PK_packed_num(fp); + else + PK_repeat_count = 1; + return PK_packed_num(fp); + } +} + +void TeXFont_PK::PK_skip_specials() +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::PK_skip_specials() called"; +#endif + + int i, j; + FILE *fp = file; + +#ifdef DEBUG_PK + if (fp == 0) + qCDebug(OkularDviDebug) << "TeXFont_PK::PK_skip_specials(): file == 0"; +#endif + + do { + PK_flag_byte = one(fp); + if (PK_flag_byte >= PK_CMD_START) { + switch (PK_flag_byte) { + case PK_X1: + case PK_X2: + case PK_X3: + case PK_X4: + i = 0; + for (j = PK_CMD_START; j <= PK_flag_byte; ++j) + i = (i << 8) | one(fp); + while (i--) + (void)one(fp); + break; + case PK_Y: + (void)four(fp); + case PK_POST: + case PK_NOOP: + break; + default: + oops(i18n("Unexpected %1 in PK file %2", PK_flag_byte, parent->filename)); + break; + } + } + } while (PK_flag_byte != PK_POST && PK_flag_byte >= PK_CMD_START); + +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::PK_skip_specials() ended"; +#endif +} + +void TeXFont_PK::read_PK_char(unsigned int ch) +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "read_PK_char"; +#endif + + int i, j; + int n; + int row_bit_pos; + bool paint_switch; + quint32 *cp; + class glyph *g; + FILE *fp = file; + long fpwidth; + quint32 word = 0; + int word_weight, bytes_wide; + int rows_left, h_bit, count; + + g = glyphtable + ch; + PK_flag_byte = g->x2; + PK_dyn_f = PK_flag_byte >> 4; + paint_switch = ((PK_flag_byte & 8) != 0); + PK_flag_byte &= 0x7; + if (PK_flag_byte == 7) + n = 4; + else if (PK_flag_byte > 3) + n = 2; + else + n = 1; + +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "loading pk char " << ch << ", char type " << n; +#endif + + if (characterBitmaps[ch] == nullptr) + characterBitmaps[ch] = new bitmap(); + + /* + * now read rest of character preamble + */ + if (n != 4) + fpwidth = num(fp, 3); + else { + fpwidth = sfour(fp); + (void)four(fp); /* horizontal escapement */ + } + (void)num(fp, n); /* vertical escapement */ + { + unsigned long w, h; + + w = num(fp, n); + h = num(fp, n); + if (w > 0x7fff || h > 0x7fff) + oops(i18n("The character %1 is too large in file %2", ch, parent->filename)); + characterBitmaps[ch]->w = w; + characterBitmaps[ch]->h = h; + } + g->x = snum(fp, n); + g->y = snum(fp, n); + + g->dvi_advance_in_units_of_design_size_by_2e20 = fpwidth; + + { + /* width must be multiple of 16 bits for raster_op */ + characterBitmaps[ch]->bytes_wide = ROUNDUP((int)characterBitmaps[ch]->w, 32) * 4; + unsigned int size = characterBitmaps[ch]->bytes_wide * characterBitmaps[ch]->h; + characterBitmaps[ch]->bits = new char[size != 0 ? size : 1]; + } + + cp = reinterpret_cast(characterBitmaps[ch]->bits); + + /* + * read character data into *cp + */ + bytes_wide = ROUNDUP((int)characterBitmaps[ch]->w, 32) * 4; + PK_bitpos = -1; + + // The routines which read the character depend on the bit + // ordering. In principle, the bit order should be detected at + // compile time and the proper routing chosen. For the moment, as + // autoconf is somewhat complicated for the author, we prefer a + // simpler -even if somewhat slower approach and detect the ordering + // at runtime. That should of course be changed in the future. + + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + // Routine for big Endian machines. Applies e.g. to Motorola and + // (Ultra-)Sparc processors. + +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "big Endian byte ordering"; +#endif + + if (PK_dyn_f == 14) { /* get raster by bits */ + memset(characterBitmaps[ch]->bits, 0, (int)characterBitmaps[ch]->h * bytes_wide); + for (i = 0; i < (int)characterBitmaps[ch]->h; i++) { /* get all rows */ + cp = ADD(characterBitmaps[ch]->bits, i * bytes_wide); + row_bit_pos = 32; + for (j = 0; j < (int)characterBitmaps[ch]->w; j++) { /* get one row */ + if (--PK_bitpos < 0) { + word = one(fp); + PK_bitpos = 7; + } + if (--row_bit_pos < 0) { + cp++; + row_bit_pos = 32 - 1; + } + if (word & (1 << PK_bitpos)) + *cp |= 1 << row_bit_pos; + } + } + } else { /* get packed raster */ + rows_left = characterBitmaps[ch]->h; + h_bit = characterBitmaps[ch]->w; + PK_repeat_count = 0; + word_weight = 32; + word = 0; + while (rows_left > 0) { + count = PK_packed_num(fp); + while (count > 0) { + if (count < word_weight && count < h_bit) { + h_bit -= count; + word_weight -= count; + if (paint_switch) + word |= bit_masks[count] << word_weight; + count = 0; + } else if (count >= h_bit && h_bit <= word_weight) { + if (paint_switch) + word |= bit_masks[h_bit] << (word_weight - h_bit); + *cp++ = word; + /* "output" row(s) */ + for (i = PK_repeat_count * bytes_wide / 4; i > 0; --i) { + *cp = *SUB(cp, bytes_wide); + ++cp; + } + rows_left -= PK_repeat_count + 1; + PK_repeat_count = 0; + word = 0; + word_weight = 32; + count -= h_bit; + h_bit = characterBitmaps[ch]->w; + } else { + if (paint_switch) + word |= bit_masks[word_weight]; + *cp++ = word; + word = 0; + count -= word_weight; + h_bit -= word_weight; + word_weight = 32; + } + } + paint_switch = 1 - paint_switch; + } + if (cp != (reinterpret_cast(characterBitmaps[ch]->bits + bytes_wide * characterBitmaps[ch]->h))) + oops(i18n("Wrong number of bits stored: char. %1, font %2", ch, parent->filename)); + if (rows_left != 0 || h_bit != characterBitmaps[ch]->w) + oops(i18n("Bad pk file (%1), too many bits", parent->filename)); + } + + // The data in the bitmap is now in the processor's bit order, + // that is, big endian. Since XWindows needs little endian, we + // need to change the bit order now. + unsigned char *bitmapData = (unsigned char *)characterBitmaps[ch]->bits; + unsigned char *endOfData = bitmapData + characterBitmaps[ch]->bytes_wide * characterBitmaps[ch]->h; + while (bitmapData < endOfData) { + *bitmapData = bitflip[*bitmapData]; + bitmapData++; + } + + } else { + // Routines for small Endian start here. This applies e.g. to + // Intel and Alpha processors. + +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "small Endian byte ordering"; +#endif + + if (PK_dyn_f == 14) { /* get raster by bits */ + memset(characterBitmaps[ch]->bits, 0, (int)characterBitmaps[ch]->h * bytes_wide); + for (i = 0; i < (int)characterBitmaps[ch]->h; i++) { /* get all rows */ + cp = ADD(characterBitmaps[ch]->bits, i * bytes_wide); + row_bit_pos = -1; + for (j = 0; j < (int)characterBitmaps[ch]->w; j++) { /* get one row */ + if (--PK_bitpos < 0) { + word = one(fp); + PK_bitpos = 7; + } + if (++row_bit_pos >= 32) { + cp++; + row_bit_pos = 0; + } + if (word & (1 << PK_bitpos)) + *cp |= 1 << row_bit_pos; + } + } + } else { /* get packed raster */ + rows_left = characterBitmaps[ch]->h; + h_bit = characterBitmaps[ch]->w; + PK_repeat_count = 0; + word_weight = 32; + word = 0; + while (rows_left > 0) { + count = PK_packed_num(fp); + while (count > 0) { + if (count < word_weight && count < h_bit) { + if (paint_switch) + word |= bit_masks[count] << (32 - word_weight); + h_bit -= count; + word_weight -= count; + count = 0; + } else if (count >= h_bit && h_bit <= word_weight) { + if (paint_switch) + word |= bit_masks[h_bit] << (32 - word_weight); + *cp++ = word; + /* "output" row(s) */ + for (i = PK_repeat_count * bytes_wide / 4; i > 0; --i) { + *cp = *SUB(cp, bytes_wide); + ++cp; + } + rows_left -= PK_repeat_count + 1; + PK_repeat_count = 0; + word = 0; + word_weight = 32; + count -= h_bit; + h_bit = characterBitmaps[ch]->w; + } else { + if (paint_switch) + word |= bit_masks[word_weight] << (32 - word_weight); + *cp++ = word; + word = 0; + count -= word_weight; + h_bit -= word_weight; + word_weight = 32; + } + } + paint_switch = 1 - paint_switch; + } + if (cp != (reinterpret_cast(characterBitmaps[ch]->bits + bytes_wide * characterBitmaps[ch]->h))) + oops(i18n("Wrong number of bits stored: char. %1, font %2", ch, parent->filename)); + if (rows_left != 0 || h_bit != characterBitmaps[ch]->w) + oops(i18n("Bad pk file (%1), too many bits", parent->filename)); + } + } // endif: big or small Endian? +} + +void TeXFont_PK::read_PK_index() +{ +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::read_PK_index() called"; +#endif + + if (file == nullptr) { + qCCritical(OkularDviDebug) << "TeXFont_PK::read_PK_index(): file == 0" << endl; + return; + } + + int magic = two(file); + if (magic != PK_MAGIC) { + qCCritical(OkularDviDebug) << "TeXFont_PK::read_PK_index(): file is not a PK file" << endl; + return; + } + + fseek(file, (long)one(file), SEEK_CUR); /* skip comment */ + (void)four(file); /* skip design size */ + + checksum = four(file); + + int hppp = sfour(file); + int vppp = sfour(file); + if (hppp != vppp) + qCWarning(OkularDviDebug) << i18n("Font has non-square aspect ratio ") << vppp << ":" << hppp; + + // Read glyph directory (really a whole pass over the file). + for (;;) { + int bytes_left, flag_low_bits; + unsigned int ch; + + PK_skip_specials(); + if (PK_flag_byte == PK_POST) + break; + flag_low_bits = PK_flag_byte & 0x7; + if (flag_low_bits == 7) { + bytes_left = four(file); + ch = four(file); + } else if (flag_low_bits > 3) { + bytes_left = ((flag_low_bits - 4) << 16) + two(file); + ch = one(file); + } else { + bytes_left = (flag_low_bits << 8) + one(file); + ch = one(file); + } + + glyphtable[ch].addr = ftell(file); + glyphtable[ch].x2 = PK_flag_byte; + fseek(file, (long)bytes_left, SEEK_CUR); +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "Scanning pk char " << ch << "at " << glyphtable[ch].addr; +#endif + } +#ifdef DEBUG_PK + qCDebug(OkularDviDebug) << "TeXFont_PK::read_PK_index() called"; +#endif +} diff --git a/generators/dvi/TeXFont_PK.h b/generators/dvi/TeXFont_PK.h new file mode 100644 index 0000000..4ef0a45 --- /dev/null +++ b/generators/dvi/TeXFont_PK.h @@ -0,0 +1,41 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- + +#ifndef _TEXFONT_PK_H +#define _TEXFONT_PK_H + +#include "TeXFont.h" + +class glyph; + +class TeXFont_PK : public TeXFont +{ +public: + TeXFont_PK(TeXFontDefinition *parent); + ~TeXFont_PK() override; + + glyph *getGlyph(quint16 character, bool generateCharacterPixmap = false, const QColor &color = Qt::black) override; + +private: + // open font file or NULL + FILE *file; + + struct bitmap *characterBitmaps[TeXFontDefinition::max_num_of_chars_in_font]; + + // For use by PK-decryption routines. I don't understand what these + // are good for -- Stefan Kebekus + int PK_flag_byte; + unsigned int PK_input_byte; + int PK_bitpos; + int PK_dyn_f; + int PK_repeat_count; + + // PK-internal routines which were taken from xdvi. Again, I do not + // really know what they are good for -- Stefan Kebekus + inline void read_PK_char(unsigned int ch); + inline int PK_get_nyb(FILE *fp); + inline int PK_packed_num(FILE *fp); + inline void read_PK_index(); + inline void PK_skip_specials(); +}; + +#endif diff --git a/generators/dvi/TeXFont_TFM.cpp b/generators/dvi/TeXFont_TFM.cpp new file mode 100644 index 0000000..8f0442f --- /dev/null +++ b/generators/dvi/TeXFont_TFM.cpp @@ -0,0 +1,144 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// TeXFont_TFM.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "TeXFont_TFM.h" +#include "debug_dvi.h" + +#include +#include +#include + +//#define DEBUG_TFM + +TeXFont_TFM::TeXFont_TFM(TeXFontDefinition *parent) + : TeXFont(parent) +{ +#ifdef DEBUG_TFM + qCDebug(OkularDviDebug) << "TeXFont_TFM::TeXFont_TFM( parent=" << parent << " )"; +#endif + + QFile file(parent->filename); + if (!file.open(QIODevice::ReadOnly)) { + qCCritical(OkularDviDebug) << "TeXFont_TFM::TeXFont_TFM(): Could not read TFM file" << endl; + return; + } + QDataStream stream(&file); + + // Data from the very beginning of the TFM file, as specified in + // "The DVI Driver Standard, Level 0", section D.2.1 + quint16 lf, lh, bc, ec, nw, nh, nd; + stream >> lf >> lh >> bc >> ec >> nw >> nh >> nd; +#ifdef DEBUG_TFM + qCDebug(OkularDviDebug) << "lf= " << lf << "lh= " << lh << endl << "bc= " << bc << endl << "ec= " << ec << endl << "nw= " << nw << endl << "nh= " << nh << endl << "nd= " << nd << endl; +#endif + if ((bc > ec) || (ec >= TeXFontDefinition::max_num_of_chars_in_font)) { + qCCritical(OkularDviDebug) << "TeXFont_TFM::TeXFont_TFM( filename=" << parent->filename << " ): The font has an invalid bc and ec entries." << endl; + file.close(); + return; + } + + // Data from the HEADER section of the TFM data. + file.seek(24); + stream >> checksum >> design_size_in_TeX_points.value; +#ifdef DEBUG_TFM + qCDebug(OkularDviDebug) << "checksum = " << checksum << "design_size = " << design_size_in_TeX_points.toDouble() << " TeX Points" << endl << " = " << design_size_in_TeX_points.toDouble() * 254.0 / 7227.0 << " cm" << endl; +#endif + + // Width table + fix_word widthTable_in_units_of_design_size[TeXFontDefinition::max_num_of_chars_in_font]; + for (fix_word &fw : widthTable_in_units_of_design_size) + fw.value = 0; + + file.seek(24 + 4 * lh + 4 * (ec - bc)); + for (unsigned int i = 0; i < nw; i++) { + stream >> widthTable_in_units_of_design_size[i].value; + // Some characters, which are used as parts of glyphs, have width + // 0 --the real width is calculated in a lig_kern program and + // depends on the preceding character. We cannot calculate the + // real width here and take 0.4 times the design size as an + // approximation. + if (widthTable_in_units_of_design_size[i].value == 0) + widthTable_in_units_of_design_size[i].fromDouble(0.4); + } + + // Height table + fix_word heightTable_in_units_of_design_size[16]; + for (fix_word &fw : heightTable_in_units_of_design_size) + fw.value = 0; + for (unsigned int i = 0; i < nh; i++) { + stream >> heightTable_in_units_of_design_size[i].value; + } + + // Char-Info table + file.seek(24 + 4 * lh); + for (unsigned int characterCode = bc; characterCode < ec; characterCode++) { + glyph *g = glyphtable + characterCode; + + quint8 byte; + stream >> byte; + if (byte >= nw) + qCCritical(OkularDviDebug) << "TeXFont_TFM::TeXFont_TFM( filename=" << parent->filename << " ): The font has an invalid Char-Info table." << endl; + else { + characterWidth_in_units_of_design_size[characterCode] = widthTable_in_units_of_design_size[byte]; + g->dvi_advance_in_units_of_design_size_by_2e20 = widthTable_in_units_of_design_size[byte].value; + } + + stream >> byte; + byte = byte >> 4; + if (byte >= nh) + qCCritical(OkularDviDebug) << "TeXFont_TFM::TeXFont_TFM( filename=" << parent->filename << " ): The font has an invalid Char-Info table." << endl; + else + characterHeight_in_units_of_design_size[characterCode] = heightTable_in_units_of_design_size[byte]; + + stream >> byte; + stream >> byte; + } + file.close(); +} + +TeXFont_TFM::~TeXFont_TFM() +{ +} + +glyph *TeXFont_TFM::getGlyph(quint16 characterCode, bool generateCharacterPixmap, const QColor &color) +{ +#ifdef DEBUG_TFM + qCDebug(OkularDviDebug) << "TeXFont_TFM::getGlyph( ch=" << ch << ", generateCharacterPixmap=" << generateCharacterPixmap << " )"; +#endif + + // Paranoia checks + if (characterCode >= TeXFontDefinition::max_num_of_chars_in_font) { + qCCritical(OkularDviDebug) << "TeXFont_TFM::getGlyph(): Argument is too big." << endl; + return glyphtable; + } + + // This is the address of the glyph that will be returned. + class glyph *g = glyphtable + characterCode; + + if ((generateCharacterPixmap == true) && ((g->shrunkenCharacter.isNull()) || (color != g->color))) { + g->color = color; + quint16 pixelWidth = (quint16)(parent->displayResolution_in_dpi * design_size_in_TeX_points.toDouble() * characterWidth_in_units_of_design_size[characterCode].toDouble() * 100.0 / 7227.0 + 0.5); + quint16 pixelHeight = (quint16)(parent->displayResolution_in_dpi * design_size_in_TeX_points.toDouble() * characterHeight_in_units_of_design_size[characterCode].toDouble() * 100.0 / 7227.0 + 0.5); + + // Just make sure that weird TFM files never lead to giant + // pixmaps that eat all system memory... + if (pixelWidth > 50) + pixelWidth = 50; + if (pixelHeight > 50) + pixelHeight = 50; + + g->shrunkenCharacter = QImage(pixelWidth, pixelHeight, QImage::Format_RGB32); + g->shrunkenCharacter.fill(color.rgba()); + g->x2 = 0; + g->y2 = pixelHeight; + } + + return g; +} diff --git a/generators/dvi/TeXFont_TFM.h b/generators/dvi/TeXFont_TFM.h new file mode 100644 index 0000000..2b39a4c --- /dev/null +++ b/generators/dvi/TeXFont_TFM.h @@ -0,0 +1,48 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// TeXFont_TFM.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#ifndef _TEXFONT_TFM_H +#define _TEXFONT_TFM_H + +#include "TeXFont.h" + +class fix_word +{ +public: + void fromINT32(qint32 val) + { + value = val; + } + void fromDouble(double val) + { + value = (qint32)(val * (1 << 20) + 0.5); + } + double toDouble() + { + return (double(value)) / (double(1 << 20)); + } + + qint32 value; +}; + +class TeXFont_TFM : public TeXFont +{ +public: + TeXFont_TFM(TeXFontDefinition *parent); + ~TeXFont_TFM() override; + + glyph *getGlyph(quint16 character, bool generateCharacterPixmap = false, const QColor &color = Qt::black) override; + +private: + fix_word characterWidth_in_units_of_design_size[256]; + fix_word characterHeight_in_units_of_design_size[256]; + + fix_word design_size_in_TeX_points; +}; + +#endif diff --git a/generators/dvi/anchor.h b/generators/dvi/anchor.h new file mode 100644 index 0000000..ca2c958 --- /dev/null +++ b/generators/dvi/anchor.h @@ -0,0 +1,69 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// anchor.h +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2004-2005 Stefan Kebekus +// Distributed under the GPL + +#ifndef ANCHOR_H +#define ANCHOR_H + +#include "length.h" +#include "pageNumber.h" + +/** \brief Page number and vertical position in physical coordinates + +This very simple class contains a page number and a vertical position +in physical coordinates. The vertical position is given by the +distance from the top of the page. Anchors are completely independent +of documents, there is no need for a document to exists that contains +the given page, nor does the page number need to be valid. + +@author Stefan Kebekus +@version 1.0 0 +*/ + +class Anchor +{ +public: + /** \brief Constructs an anchor that points to an invalid page */ + Anchor() + { + page = 0; + } + + /** \brief Constructs an anchor that points to a given position on a + given page + + The class contains no code to make sure in any way that the page + number pg exists, and that page pg, if it exists, is taller than + distance_from_top + + @param pg number of the page + @param _distance_from_top distance from the top of the page + */ + Anchor(const PageNumber pg, const Length _distance_from_top) + : page(pg) + , distance_from_top(_distance_from_top) + { + } + + /** \brief quick validity check for anchors + + @returns true if the page number is valid, and 0mm <= distance_from_top <= 2m + */ + bool isValid() const + { + return page.isValid() && (0.0 <= distance_from_top.getLength_in_mm()) && (distance_from_top.getLength_in_mm() <= 2000.0); + } + + /** \brief Page number that this anchor point to */ + PageNumber page; + + /** \brief Distance from the top of the page in inch */ + Length distance_from_top; +}; + +#endif diff --git a/generators/dvi/bigEndianByteReader.cpp b/generators/dvi/bigEndianByteReader.cpp new file mode 100644 index 0000000..90d4dea --- /dev/null +++ b/generators/dvi/bigEndianByteReader.cpp @@ -0,0 +1,111 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// bigEndianByteReader.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "bigEndianByteReader.h" +#include "debug_dvi.h" +#include "dvi.h" + +//#define DEBUG_ENDIANREADER + +quint8 bigEndianByteReader::readUINT8() +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) { +#ifdef DEBUG_ENDIANREADER + qCCritical(OkularDviDebug) << "bigEndianByteReader::readUINT8() tried to read past end of data chunk" << endl; + qCCritical(OkularDviDebug) << "end_pointer = " << end_pointer << endl; + qCCritical(OkularDviDebug) << "command_pointer = " << command_pointer << endl; +#endif + return EOP; + } + + return *(command_pointer++); +} + +quint16 bigEndianByteReader::readUINT16() +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) + return EOP; + + quint16 a; + a = *(command_pointer++); + a = (a << 8) | *(command_pointer++); + return a; +} + +quint32 bigEndianByteReader::readUINT32() +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) + return EOP; + + quint32 a; + a = *(command_pointer++); + a = (a << 8) | *(command_pointer++); + a = (a << 8) | *(command_pointer++); + a = (a << 8) | *(command_pointer++); + return a; +} + +void bigEndianByteReader::writeUINT32(quint32 a) +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) + return; + + command_pointer[3] = (quint8)(a & 0xFF); + a = a >> 8; + command_pointer[2] = (quint8)(a & 0xFF); + a = a >> 8; + command_pointer[1] = (quint8)(a & 0xFF); + a = a >> 8; + command_pointer[0] = (quint8)(a & 0xFF); + + command_pointer += 4; + return; +} + +quint32 bigEndianByteReader::readUINT(quint8 size) +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) + return EOP; + + quint32 a = 0; + while (size > 0) { + a = (a << 8) + *(command_pointer++); + size--; + } + return a; +} + +qint32 bigEndianByteReader::readINT(quint8 length) +{ + // This check saveguards us against segmentation fault. It is also + // necessary for virtual fonts, which do not end with EOP. + if (command_pointer >= end_pointer) + return EOP; + + qint32 a = *(command_pointer++); + + if (a & 0x80) + a -= 0x100; + + while ((--length) > 0) + a = (a << 8) | *(command_pointer++); + + return a; +} diff --git a/generators/dvi/bigEndianByteReader.h b/generators/dvi/bigEndianByteReader.h new file mode 100644 index 0000000..7427b59 --- /dev/null +++ b/generators/dvi/bigEndianByteReader.h @@ -0,0 +1,62 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* This file is part of KDVI (C) 2001 by Stefan Kebekus (kebekus@kde.org) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. +*/ + +/** + * Byte reading routines which read big endian numbers from memory and + * convert them to native integers. + * + * @author Stefan Kebekus (kebekus@kde.org) + * + **/ + +#ifndef _bigEndianByteReader_H +#define _bigEndianByteReader_H + +#include + +class bigEndianByteReader +{ +public: + /** Set this pointer to the location where the number resides which + you want to read. */ + quint8 *command_pointer; + + /** This pointer marks the end of the memory area where bytes can be + read. It should point to the first byte which CANNOT be + read. The idea is to have a safety net which protects us against + SEGFAULTs. This is also used in virtual fonts, where the macro + does not have an EOP command at the end of the macro. */ + quint8 *end_pointer; + + /** If command_pointer >= end_pointer, this method return EOP (=140) + and exists. Otherwise, the method returns the unsigned byte + and increases the command_pointer by one. */ + quint8 readUINT8(); + + /** Similar to the method above, only that the method reads a big + endian 2-byte word and increases the pointer by two. */ + quint16 readUINT16(); + + /** Similar to the method above, only that the method reads a big + endian 4-byte word and increases the pointer by four. */ + quint32 readUINT32(); + + void writeUINT32(quint32 a); + + /** Similar to the method above, only that the method reads a big + endian number of length size, where 1 <= size <= 4. Note that + the value 3 is allowed (and is actually used in DVI files)!!! */ + quint32 readUINT(quint8 size); + + /** Similar to the method above, only that the method reads a SIGNED + number */ + qint32 readINT(quint8); +}; + +#endif // ifndef _bigEndianByteReader_H diff --git a/generators/dvi/config.h b/generators/dvi/config.h new file mode 100644 index 0000000..06ed2b3 --- /dev/null +++ b/generators/dvi/config.h @@ -0,0 +1 @@ +/* empty, just to make dvi compile without changing the sources */ diff --git a/generators/dvi/debug_dvi.h b/generators/dvi/debug_dvi.h new file mode 100644 index 0000000..16b6507 --- /dev/null +++ b/generators/dvi/debug_dvi.h @@ -0,0 +1,19 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi Toscano * + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DVI_DEBUG_P_H +#define OKULAR_DVI_DEBUG_P_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularDviDebug) +Q_DECLARE_LOGGING_CATEGORY(OkularDviShellDebug) + +#endif diff --git a/generators/dvi/dvi.h b/generators/dvi/dvi.h new file mode 100644 index 0000000..8b18ef8 --- /dev/null +++ b/generators/dvi/dvi.h @@ -0,0 +1,68 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Mnemonics for bytes in dvi file. + */ + +#ifndef DVI_H +#define DVI_H + +#define SETCHAR0 0 +#define SET1 128 +#define SETRULE 132 +#define PUT1 133 +#define PUTRULE 137 +#define NOP 138 +#define BOP 139 +#define EOP 140 +#define PUSH 141 +#define POP 142 +#define RIGHT1 143 +#define RIGHT2 144 +#define RIGHT3 145 +#define RIGHT4 146 +#define W0 147 +#define W1 148 +#define W2 149 +#define W3 150 +#define W4 151 +#define X0 152 +#define X1 153 +#define X2 154 +#define X3 155 +#define X4 156 +#define DOWN1 157 +#define DOWN2 158 +#define DOWN3 159 +#define DOWN4 160 +#define Y0 161 +#define Y1 162 +#define Y2 163 +#define Y3 164 +#define Y4 165 +#define Z0 166 +#define Z1 167 +#define Z2 168 +#define Z3 169 +#define Z4 170 +#define FNTNUM0 171 +#define FNT1 235 +#define FNT2 236 +#define FNT3 237 +#define FNT4 238 +#define XXX1 239 +#define XXX2 240 +#define XXX3 241 +#define XXX4 242 +#define FNTDEF1 243 +#define FNTDEF2 244 +#define FNTDEF3 245 +#define FNTDEF4 246 +#define PRE 247 +#define POST 248 +#define POSTPOST 249 +#define SREFL 250 +#define EREFL 251 +// Trailing bytes at end of file +#define TRAILER 223 + +#endif diff --git a/generators/dvi/dviFile.cpp b/generators/dvi/dviFile.cpp new file mode 100644 index 0000000..1e9b34e --- /dev/null +++ b/generators/dvi/dviFile.cpp @@ -0,0 +1,438 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * NOTE: + * xdvi is based on prior work as noted in the modification history, below. + */ + +/* + * DVI previewer for X. + * + * Eric Cooper, CMU, September 1985. + * + * Code derived from dvi-imagen.c. + * + * Modification history: + * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS. + * 7/1988 Modified for X.11 --Mark Eichin, MIT + * 12/1988 Added 'R' option, toolkit, magnifying glass + * --Paul Vojta, UC Berkeley. + * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto + * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ. + * 3/1990 Added VMS support --Scott Allendorf, U of Iowa + * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem + * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen + * and Lee Hetherington, MIT + * 4/1994 Added DPS support, bounding box + * --Ricardo Telichevesky + * and Luis Miguel Silveira, MIT RLE. + */ + +#include + +#include "debug_dvi.h" +#include "dvi.h" +#include "dviFile.h" +#include "fontpool.h" +#include "pageSize.h" + +#include + +#include +#include +#include +#include + +#include + +dvifile::dvifile(const dvifile *old, fontPool *fp) +{ + errorMsg.clear(); + errorCounter = 0; + page_offset.clear(); + suggestedPageSize = nullptr; + numberOfExternalPSFiles = 0; + numberOfExternalNONPSFiles = 0; + sourceSpecialMarker = old->sourceSpecialMarker; + have_complainedAboutMissingPDF2PS = false; + + dviData = old->dviData; + + filename = old->filename; + size_of_file = old->size_of_file; + end_pointer = dvi_Data() + size_of_file; + if (dvi_Data() == nullptr) { + qCCritical(OkularDviDebug) << "Not enough memory to copy the DVI-file."; + return; + } + + font_pool = fp; + filename = old->filename; + generatorString = old->generatorString; + total_pages = old->total_pages; + + tn_table.clear(); + process_preamble(); + find_postamble(); + read_postamble(); + prepare_pages(); +} + +void dvifile::process_preamble() +{ + command_pointer = dvi_Data(); + + quint8 magic_number = readUINT8(); + if (magic_number != PRE) { + errorMsg = i18n("The DVI file does not start with the preamble."); + return; + } + magic_number = readUINT8(); + if (magic_number != 2) { + errorMsg = i18n( + "The DVI file contains the wrong version of DVI output for this program. " + "Hint: If you use the typesetting system Omega, you have to use a special " + "program, such as oxdvi."); + return; + } + + /** numerator, denominator and the magnification value that describe + how many centimeters there are in one TeX unit, as explained in + section A.3 of the DVI driver standard, Level 0, published by + the TUG DVI driver standards committee. */ + quint32 numerator = readUINT32(); + quint32 denominator = readUINT32(); + _magnification = readUINT32(); + + cmPerDVIunit = (double(numerator) / double(denominator)) * (double(_magnification) / 1000.0) * (1.0 / 1e5); + + // Read the generatorString (such as "TeX output ..." from the + // DVI-File). The variable "magic_number" holds the length of the + // string. + char job_id[300]; + magic_number = readUINT8(); + strncpy(job_id, (char *)command_pointer, magic_number); + job_id[magic_number] = '\0'; + generatorString = QString::fromLocal8Bit(job_id); +} + +/** find_postamble locates the beginning of the postamble and leaves + the file ready to start reading at that location. */ + +void dvifile::find_postamble() +{ + // Move backwards through the TRAILER bytes + command_pointer = dvi_Data() + size_of_file - 1; + while ((*command_pointer == TRAILER) && (command_pointer > dvi_Data())) + command_pointer--; + if (command_pointer == dvi_Data()) { + errorMsg = i18n("The DVI file is badly corrupted. Okular was not able to find the postamble."); + return; + } + + // And this is finally the pointer to the beginning of the postamble + command_pointer -= 4; + beginning_of_postamble = readUINT32(); + command_pointer = dvi_Data() + beginning_of_postamble; +} + +void dvifile::read_postamble() +{ + quint8 magic_byte = readUINT8(); + if (magic_byte != POST) { + errorMsg = i18n("The postamble does not begin with the POST command."); + return; + } + last_page_offset = readUINT32(); + + // Skip the numerator, denominator and magnification, the largest + // box height and width and the maximal depth of the stack. These + // are not used at the moment. + command_pointer += 4 + 4 + 4 + 4 + 4 + 2; + + // The number of pages is more interesting for us. + total_pages = readUINT16(); + + // As a next step, read the font definitions. + quint8 cmnd = readUINT8(); + while (cmnd >= FNTDEF1 && cmnd <= FNTDEF4) { + quint32 TeXnumber = readUINT(cmnd - FNTDEF1 + 1); + quint32 checksum = readUINT32(); // Checksum of the font, as found by TeX in the TFM file + + // Read scale and design factor, and the name of the font. All + // these are explained in section A.4 of the DVI driver standard, + // Level 0, published by the TUG DVI driver standards committee + quint32 scale = readUINT32(); + quint32 design = readUINT32(); + quint16 len = readUINT8() + readUINT8(); // Length of the font name, including the directory name + QByteArray fontname((char *)command_pointer, len); + command_pointer += len; + +#ifdef DEBUG_FONTS + qCDebug(OkularDviDebug) << "Postamble: define font \"" << fontname << "\" scale=" << scale << " design=" << design; +#endif + + // According to section A.4 of the DVI driver standard, this font + // shall be enlarged by the following factor before it is used. + double enlargement_factor = (double(scale) * double(_magnification)) / (double(design) * 1000.0); + + if (font_pool != nullptr) { + TeXFontDefinition *fontp = font_pool->appendx(QString::fromLocal8Bit(fontname), checksum, scale, enlargement_factor); + + // Insert font in dictionary and make sure the dictionary is big + // enough. + if (tn_table.capacity() - 2 <= tn_table.count()) + // Not quite optimal. The size of the dictionary should be a + // prime for optimal performance. I don't care. + tn_table.reserve(tn_table.capacity() * 2); + tn_table.insert(TeXnumber, fontp); + } + + // Read the next command + cmnd = readUINT8(); + } + + if (cmnd != POSTPOST) { + errorMsg = i18n("The postamble contained a command other than FNTDEF."); + return; + } + + // Now we remove all those fonts from the memory which are no longer + // in use. + if (font_pool != nullptr) + font_pool->release_fonts(); +} + +void dvifile::prepare_pages() +{ +#ifdef DEBUG_DVIFILE + qCDebug(OkularDviDebug) << "prepare_pages"; +#endif + if (total_pages == 0) + return; + + page_offset.resize(total_pages + 1); + if (page_offset.size() < (total_pages + 1)) { + qCCritical(OkularDviDebug) << "No memory for page list!"; + return; + } + for (int i = 0; i <= total_pages; i++) + page_offset[i] = 0; + + page_offset[int(total_pages)] = beginning_of_postamble; + int j = total_pages - 1; + page_offset[j] = last_page_offset; + + // Follow back pointers through pages in the DVI file, storing the + // offsets in the page_offset table. + while (j > 0) { + command_pointer = dvi_Data() + page_offset[j--]; + if (readUINT8() != BOP) { + errorMsg = i18n("The page %1 does not start with the BOP command.", j + 1); + return; + } + command_pointer += 10 * 4; + page_offset[j] = readUINT32(); + if ((dvi_Data() + page_offset[j] < dvi_Data()) || (dvi_Data() + page_offset[j] > dvi_Data() + size_of_file)) + break; + } +} + +dvifile::dvifile(const QString &fname, fontPool *pool) +{ +#ifdef DEBUG_DVIFILE + qCDebug(OkularDviDebug) << "init_dvi_file: " << fname; +#endif + + errorMsg.clear(); + errorCounter = 0; + page_offset.clear(); + suggestedPageSize = nullptr; + numberOfExternalPSFiles = 0; + numberOfExternalNONPSFiles = 0; + font_pool = pool; + sourceSpecialMarker = true; + have_complainedAboutMissingPDF2PS = false; + + QFile file(fname); + filename = file.fileName(); + file.open(QIODevice::ReadOnly); + size_of_file = file.size(); + dviData.resize(size_of_file); + // Sets the end pointer for the bigEndianByteReader so that the + // whole memory buffer is readable + end_pointer = dvi_Data() + size_of_file; + if (dvi_Data() == nullptr) { + qCCritical(OkularDviDebug) << "Not enough memory to load the DVI-file."; + return; + } + file.read((char *)dvi_Data(), size_of_file); + file.close(); + if (file.error() != QFile::NoError) { + qCCritical(OkularDviDebug) << "Could not load the DVI-file."; + return; + } + + tn_table.clear(); + + total_pages = 0; + process_preamble(); + find_postamble(); + read_postamble(); + prepare_pages(); + + return; +} + +dvifile::~dvifile() +{ +#ifdef DEBUG_DVIFILE + qCDebug(OkularDviDebug) << "destroy dvi-file"; +#endif + + // Delete converted PDF files + QMapIterator i(convertedFiles); + while (i.hasNext()) { + i.next(); + QFile::remove(i.value()); + } + + if (suggestedPageSize != nullptr) + delete suggestedPageSize; + if (font_pool != nullptr) + font_pool->mark_fonts_as_unused(); +} + +void dvifile::renumber() +{ + dviData.detach(); + + // Write the page number to the file, taking good care of byte + // orderings. + bool bigEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian); + + for (int i = 1; i <= total_pages; i++) { + quint8 *ptr = dviData.data() + page_offset[i - 1] + 1; + quint8 *num = (quint8 *)&i; + for (quint8 j = 0; j < 4; j++) + if (bigEndian) { + *(ptr++) = num[0]; + *(ptr++) = num[1]; + *(ptr++) = num[2]; + *(ptr++) = num[3]; + } else { + *(ptr++) = num[3]; + *(ptr++) = num[2]; + *(ptr++) = num[1]; + *(ptr++) = num[0]; + } + } +} + +QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms) +{ + // Check if the PDFFile is known + QMap::Iterator it = convertedFiles.find(PDFFilename); + if (it != convertedFiles.end()) { + // PDF-File is known. Good. + return it.value(); + } + + // Get the name of a temporary file. + // Must open the QTemporaryFile to access the name. + QTemporaryFile tmpfile; + tmpfile.open(); + const QString convertedFileName = tmpfile.fileName(); + tmpfile.close(); + + // Use pdf2ps to do the conversion + QProcess pdf2ps; + pdf2ps.setProcessChannelMode(QProcess::MergedChannels); + pdf2ps.start(QStringLiteral("pdf2ps"), QStringList() << PDFFilename << convertedFileName, QIODevice::ReadOnly | QIODevice::Text); + + if (!pdf2ps.waitForStarted()) { + // Indicates that conversion failed, won't try again. + convertedFiles[PDFFilename].clear(); + if (converrorms != nullptr && !have_complainedAboutMissingPDF2PS) { + *converrorms = i18n( + "

The external program pdf2ps could not be started. As a result, " + "the PDF-file %1 could not be converted to PostScript. Some graphic elements in your " + "document will therefore not be displayed.

" + "

Possible reason: The program pdf2ps may not be installed " + "on your system, or cannot be found in the current search path.

" + "

What you can do: The program pdf2ps is normally " + "contained in distributions of the ghostscript PostScript interpreter system. If " + "ghostscript is not installed on your system, you could install it now. " + "If you are sure that ghostscript is installed, try to use pdf2ps " + "from the command line to check if it really works.

PATH: %2

", + PDFFilename, + QString::fromLocal8Bit(qgetenv("PATH"))); + have_complainedAboutMissingPDF2PS = true; + } + return QString(); + } + + // We wait here while the external program runs concurrently. + pdf2ps.waitForFinished(-1); + + if (!QFile::exists(convertedFileName) || pdf2ps.exitCode() != 0) { + // Indicates that conversion failed, won't try again. + convertedFiles[PDFFilename].clear(); + if (converrorms != nullptr) { + const QString output = QString::fromLocal8Bit(pdf2ps.readAll()); + + *converrorms = i18n( + "

The PDF-file %1 could not be converted to PostScript. Some graphic elements in your " + "document will therefore not be displayed.

" + "

Possible reason: The file %1 might be broken, or might not be a PDF-file at all. " + "This is the output of the pdf2ps program that Okular used:

" + "

%2

", + PDFFilename, + output); + } + return QString(); + } + // Save name of converted file to buffer, so PDF file won't be + // converted again, and files can be deleted when *this is + // deconstructed. + convertedFiles[PDFFilename] = convertedFileName; + + tmpfile.setAutoRemove(false); + return convertedFileName; +} + +bool dvifile::saveAs(const QString &filename) +{ + if (dvi_Data() == nullptr) + return false; + + QFile out(filename); + if (out.open(QIODevice::WriteOnly) == false) + return false; + if (out.write((char *)(dvi_Data()), size_of_file) == -1) + return false; + out.close(); + return true; +} diff --git a/generators/dvi/dviFile.h b/generators/dvi/dviFile.h new file mode 100644 index 0000000..6366eb6 --- /dev/null +++ b/generators/dvi/dviFile.h @@ -0,0 +1,166 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Class: dviFile +// +// Class that represents a DVI file. Part of KDVI - A DVI previewing +// plugin for kviewshell. +// +// (C) 2004-2005 Stefan Kebekus. Distributed under the GPL. +// + +#ifndef _DVIFILE_H +#define _DVIFILE_H + +#include "bigEndianByteReader.h" + +#include +#include +#include +#include + +class fontPool; +class pageSize; +class TeXFontDefinition; + +class dvifile : public bigEndianByteReader +{ +public: + /** Makes a deep copy of the old DVI file. */ + dvifile(const dvifile *old, fontPool *fp); + dvifile(const QString &fname, class fontPool *pool); + + ~dvifile(); + + dvifile(const dvifile &) = delete; + dvifile &operator=(const dvifile &) = delete; + + fontPool *font_pool; + QString filename; + QString generatorString; + quint16 total_pages; + QVector page_offset; + + /** Saves the DVI file. Returns true on success. */ + bool saveAs(const QString &filename); + + // Returns a pointer to the DVI file's data, or 0 if no data has yet + // been allocated. + quint8 *dvi_Data() + { + return dviData.data(); + } + + qint64 size_of_file; + QString errorMsg; + + /** This field is set to zero when the DVI file is constructed, and + will be modified during the prescan phase (at this time the + prescan code still resides in the dviRenderer class) */ + quint16 numberOfExternalPSFiles; + + /** This field is set to zero when the DVI file is constructed, and + will be modified during the prescan phase (at this time the + prescan code still resides in the dviRenderer class) */ + quint16 numberOfExternalNONPSFiles; + + quint32 beginning_of_postamble; + + /** This flag is set to "true" during the construction of the + dvifile, and is never changed afterwards by the dvifile + class. It is used in kdvi in conjunction with source-specials: + the first time a page with source specials is rendered, KDVI + shows an info dialog, and the flag is set to false. That way + KDVI ensures that the user is only informed once. */ + bool sourceSpecialMarker; + + QHash tn_table; + + /** Returns the number of centimeters per DVI unit in this DVI + file. */ + double getCmPerDVIunit() const + { + return cmPerDVIunit; + } + + /** Returns the magnification of the DVI file, as described in the + DVI Standard. */ + quint32 getMagnification() const + { + return _magnification; + } + + /** This member is set to zero on construction and can be used by + other software to count error messages that were printed when + the DVI-file was processed. Suggested application: limit the + number of error messages to, say, 25. */ + quint8 errorCounter; + + /** Papersize information read from the dvi-File */ + pageSize *suggestedPageSize; + + /** Sets new DVI data; all old data is erased. EXPERIMENTAL, use + with care. */ + void setNewData(const QVector &newData) + { + dviData = newData; + } + + /** Page numbers that appear in a DVI document need not be + ordered. Worse, page numbers need not be unique. This method + renumbers the pages. */ + void renumber(); + + /** PDF to PS file conversion + + This utility method takes the name of a PDF-file, and attempts to + convert it to a PS file. The dvifile internally keeps a list of + converted files, to do two things: + + - convert files only once. + + - delete all converted files on destruction + + @warning The internal buffer can lead to difficulties if filenames + of PDF-files are not unique: if the content of a PDF file is + changed and this method is called a second time with the same file + name, the method will then NOT convert the file, but simply return + the name from the buffer + + @returns The name of the PS file, or QString() on failure. + */ + QString convertPDFtoPS(const QString &PDFFilename, QString *converrorms = nullptr); + +private: + /** process_preamble reads the information in the preamble and + stores it into global variables for later use. */ + void process_preamble(); + void find_postamble(); + /** read_postamble reads the information in the postamble, storing + it into global variables. It also takes care of reading in all + of the pixel files for the fonts used in the job. */ + void read_postamble(); + void prepare_pages(); + + /** Offset in DVI file of last page, set in read_postamble(). */ + quint32 last_page_offset; + quint32 _magnification; + + double cmPerDVIunit; + + QVector dviData; + + /** Map of filenames for converted PDF files + + This map contains names of PDF files that were converted to + PostScript. The key is the name of the PDF file, the data the name + of the associated PS file, or QString(), if the file could not + be converted. The PS files are deleted when the DVI-file is + destructed. */ + QMap convertedFiles; + + /** Flag, used so that KDVI complains only once about a missing + "PDF2PS" utility. Set to "false" in the constructor. */ + bool have_complainedAboutMissingPDF2PS; +}; + +#endif // ifndef _DVIFILE_H diff --git a/generators/dvi/dviPageInfo.cpp b/generators/dvi/dviPageInfo.cpp new file mode 100644 index 0000000..a7b9def --- /dev/null +++ b/generators/dvi/dviPageInfo.cpp @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi 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. * + ***************************************************************************/ + +#include "dviPageInfo.h" + +dviPageInfo::dviPageInfo() +{ + sourceHyperLinkList.reserve(200); +} + +dviPageInfo::~dviPageInfo() +{ +} + +void dviPageInfo::clear() +{ + sourceHyperLinkList.clear(); +} diff --git a/generators/dvi/dviPageInfo.h b/generators/dvi/dviPageInfo.h new file mode 100644 index 0000000..dd1c23b --- /dev/null +++ b/generators/dvi/dviPageInfo.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi 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 _dvipageinfo_h_ +#define _dvipageinfo_h_ + +#include "hyperlink.h" +#include "pageNumber.h" +#include "textBox.h" +#include +#include + +class dviPageInfo +{ +public: + QImage img; + int width, height; + double resolution; + PageNumber pageNumber; + + dviPageInfo(); + + virtual ~dviPageInfo(); + + dviPageInfo(const dviPageInfo &) = delete; + dviPageInfo &operator=(const dviPageInfo &) = delete; + + virtual void clear(); + + /** \brief List of source hyperlinks + */ + QVector sourceHyperLinkList; + + /** \brief Hyperlinks on the document page + */ + QVector hyperLinkList; + QVector textBoxList; +}; + +/* quick&dirty hack to cheat the dviRenderer class... */ +#define RenderedDviPagePixmap dviPageInfo +#define RenderedDocumentPagePixmap dviPageInfo +#endif diff --git a/generators/dvi/dviRenderer.cpp b/generators/dvi/dviRenderer.cpp new file mode 100644 index 0000000..8a6d432 --- /dev/null +++ b/generators/dvi/dviRenderer.cpp @@ -0,0 +1,740 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Class: dviRenderer +// +// Class for rendering TeX DVI files. +// Part of KDVI- A previewer for TeX DVI files. +// +// (C) 2001-2005 Stefan Kebekus +// Distributed under the GPL +// + +#include + +#include "debug_dvi.h" +#include "dviFile.h" +#include "dviRenderer.h" +#include "dvisourcesplitter.h" +#include "hyperlink.h" +#include "psgs.h" +//#include "renderedDviPagePixmap.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------ now comes the dviRenderer class implementation ---------- + +dviRenderer::dviRenderer(bool useFontHinting) + : dviFile(nullptr) + , font_pool(useFontHinting) + , resolutionInDPI(0) + , embedPS_progress(nullptr) + , embedPS_numOfProgressedFiles(0) + , shrinkfactor(3) + , source_href(nullptr) + , HTML_href(nullptr) + , editorCommand(QLatin1String("")) + , PostScriptOutPutString(nullptr) + , PS_interface(new ghostscript_interface) + , _postscript(true) + , line_boundary_encountered(false) + , word_boundary_encountered(false) + , current_page(0) + , penWidth_in_mInch(0) + , number_of_elements_in_path(0) + , currentlyDrawnPage(nullptr) + , m_eventLoop(nullptr) + , foreGroundPainter(nullptr) + , fontpoolLocateFontsDone(false) +{ +#ifdef DEBUG_DVIRENDERER + // qCDebug(OkularDviDebug) << "dviRenderer( parent=" << par << " )"; +#endif + + connect(&font_pool, &fontPool::error, this, &dviRenderer::error); + connect(&font_pool, &fontPool::warning, this, &dviRenderer::warning); + connect(PS_interface, &ghostscript_interface::error, this, &dviRenderer::error); +} + +dviRenderer::~dviRenderer() +{ +#ifdef DEBUG_DVIRENDERER + qCDebug(OkularDviDebug) << "~dviRenderer"; +#endif + + QMutexLocker locker(&mutex); + + delete PS_interface; + delete dviFile; +} + +#if 0 +void dviRenderer::setPrefs(bool flag_showPS, const QString &str_editorCommand, bool useFontHints ) +{ + //QMutexLocker locker(&mutex); + _postscript = flag_showPS; + editorCommand = str_editorCommand; + font_pool.setParameters( useFontHints ); +} + +#endif + +//------ this function calls the dvi interpreter ---------- + +void dviRenderer::drawPage(RenderedDocumentPagePixmap *page) +{ +#ifdef DEBUG_DVIRENDERER + // qCDebug(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called, page number " << page->pageNumber; +#endif + + // Paranoid safety checks + if (page == nullptr) { + qCCritical(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called with argument == 0"; + return; + } + // Paranoid safety checks + if (page->pageNumber == 0) { + qCCritical(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called for a documentPage with page number 0"; + return; + } + + QMutexLocker locker(&mutex); + + if (dviFile == nullptr) { + qCCritical(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called, but no dviFile class allocated."; + page->clear(); + return; + } + if (page->pageNumber > dviFile->total_pages) { + qCCritical(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called for a documentPage with page number " << page->pageNumber << " but the current dviFile has only " << dviFile->total_pages << " pages."; + return; + } + if (dviFile->dvi_Data() == nullptr) { + qCCritical(OkularDviDebug) << "dviRenderer::drawPage(documentPage *) called, but no dviFile is loaded yet."; + page->clear(); + return; + } + + /* locateFonts() is here just once (if it has not been executed + not been executed yet), so that it is possible to easily intercept + the cancel signal (because for example the user tries to open + another document); it would not have been possible (or more + complicated) in case it was still in the document loading section. + */ + if (!fontpoolLocateFontsDone) { + font_pool.locateFonts(); + fontpoolLocateFontsDone = true; + } + + double resolution = page->resolution; + + if (resolution != resolutionInDPI) + setResolution(resolution); + + currentlyDrawnPage = page; + shrinkfactor = 1200 / resolutionInDPI; + current_page = page->pageNumber - 1; + + // Reset colors + colorStack.clear(); + globalColor = Qt::black; + + int pageWidth = page->width; + int pageHeight = page->height; + + QImage img(pageWidth, pageHeight, QImage::Format_RGB32); + foreGroundPainter = new QPainter(&img); + if (foreGroundPainter != nullptr) { + errorMsg.clear(); + draw_page(); + delete foreGroundPainter; + foreGroundPainter = nullptr; + } else { + qCDebug(OkularDviDebug) << "painter creation failed."; + } + page->img = img; + // page->setImage(img); + + // Postprocess hyperlinks + // Without that, based on the way TeX draws certain characters like german "Umlaute", + // some hyperlinks would be broken into two overlapping parts, in the middle of a word. + QVector::iterator i = page->hyperLinkList.begin(); + QVector::iterator j; + while (i != page->hyperLinkList.end()) { + // Iterator j always points to the element after i. + j = i; + j++; + + if (j == page->hyperLinkList.end()) + break; + + Hyperlink &hi = *i; + Hyperlink &hj = *j; + + bool merged = false; + + // Merge all hyperlinks that point to the same target, and have the same baseline. + while (hi.linkText == hj.linkText && hi.baseline == hj.baseline) { + merged = true; + hi.box = hi.box.united(hj.box); + + j++; + if (j == page->hyperLinkList.end()) + break; + + hj = *j; + } + + if (merged) { + i = page->hyperLinkList.erase(++i, j); + } else { + i++; + } + } + + if (errorMsg.isEmpty() != true) { + emit error(i18n("File corruption. %1", errorMsg), -1); + errorMsg.clear(); + currentlyDrawnPage = nullptr; + return; + } +#if 0 + + // Tell the user (once) if the DVI file contains source specials + // ... we don't want our great feature to go unnoticed. + RenderedDviPagePixmap* currentDVIPage = dynamic_cast(currentlyDrawnPage); + if (currentDVIPage) + { + if ((dviFile->sourceSpecialMarker == true) && (currentDVIPage->sourceHyperLinkList.size() > 0)) { + dviFile->sourceSpecialMarker = false; + // Show the dialog as soon as event processing is finished, and + // the program is idle + //FIXME + //QTimer::singleShot( 0, this, SLOT(showThatSourceInformationIsPresent()) ); + } + } +#endif + currentlyDrawnPage = nullptr; +} + +void dviRenderer::getText(RenderedDocumentPagePixmap *page) +{ + bool postscriptBackup = _postscript; + // Disable postscript-specials temporarily to speed up text extraction. + _postscript = false; + + drawPage(page); + + _postscript = postscriptBackup; +} + +/* +void dviRenderer::showThatSourceInformationIsPresent() +{ + // In principle, we should use a KMessagebox here, but we want to + // add a button "Explain in more detail..." which opens the + // Helpcenter. Thus, we practically re-implement the KMessagebox + // here. Most of the code is stolen from there. + + // Check if the 'Don't show again' feature was used + KConfig *config = KSharedConfig::openConfig(); + KConfigGroup saver(config, "Notification Messages"); + bool showMsg = config->readEntry( "KDVI-info_on_source_specials", true); + + if (showMsg) { + KDialogBase dialog(i18n("KDVI: Information"), KDialogBase::Yes, KDialogBase::Yes, KDialogBase::Yes, + parentWidget, "information", true, true, KStandardGuiItem::ok()); + + QWidget *topcontents = new QWidget (&dialog); + QVBoxLayout *topcontentsVBoxLayout = new QVBoxLayout(topcontents); + topcontentsVBoxLayout->setContentsMargins(0, 0, 0, 0); + topcontentsVBoxLayout->setSpacing(KDialog::spacingHint()*2); + topcontentsVBoxLayout->setContentsMargins(KDialog::marginHint()*2, KDialog::marginHint()*2, KDialog::marginHint()*2, KDialog::marginHint()*2); + + QWidget *contents = new QWidget(topcontents); + topcontentsVBoxLayout->addWidget(contents); + QHBoxLayout * lay = new QHBoxLayout(contents); + lay->setSpacing(KDialog::spacingHint()*2); + + lay->addStretch(1); + QLabel *label1 = new QLabel( contents); + label1->setPixmap(QMessageBox::standardIcon(QMessageBox::Information)); + lay->addWidget(label1); + QLabel *label2 = new QLabel( i18n("This DVI file contains source file information. You may click into the text with the " + "middle mouse button, and an editor will open the TeX-source file immediately."), + contents); + label2->setMinimumSize(label2->sizeHint()); + lay->addWidget(label2); + lay->addStretch(1); + QSize extraSize = QSize(50,30); + QCheckBox *checkbox = new QCheckBox(i18n("Do not show this message again"), topcontents); + topcontentsVBoxLayout->addWidget(checkbox); + extraSize = QSize(50,0); + dialog.setHelpLinkText(i18n("Explain in more detail...")); + dialog.setHelp("inverse-search", "kdvi"); + dialog.enableLinkedHelp(true); + dialog.setMainWidget(topcontents); + dialog.enableButtonSeparator(false); + dialog.incInitialSize( extraSize ); + dialog.exec(); + + showMsg = !checkbox->isChecked(); + if (!showMsg) { + KConfigGroup saver(config, "Notification Messages"); + config->writeEntry( "KDVI-info_on_source_specials", showMsg); + } + config->sync(); + } +} +*/ + +void dviRenderer::embedPostScript() +{ +#ifdef DEBUG_DVIRENDERER + qCDebug(OkularDviDebug) << "dviRenderer::embedPostScript()"; +#endif + + if (!dviFile) + return; + + /* embedPS_progress = new QProgressDialog(parentWidget); + embedPS_progress->setWindowTitle(i18n("Embedding PostScript Files")); + embedPS_progress->setLabelText(QString()); + */ + if (!embedPS_progress) + return; + embedPS_progress->setCancelButton(nullptr); + embedPS_progress->setCancelButton(nullptr); + embedPS_progress->setMinimumDuration(400); + embedPS_progress->setMaximum(dviFile->numberOfExternalPSFiles); + embedPS_progress->setValue(0); + embedPS_numOfProgressedFiles = 0; + + quint16 currPageSav = current_page; + errorMsg.clear(); + for (current_page = 0; current_page < dviFile->total_pages; current_page++) { + if (current_page < dviFile->total_pages) { + command_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page)]; + end_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page + 1)]; + } else + command_pointer = end_pointer = nullptr; + + memset((char *)&currinf.data, 0, sizeof(currinf.data)); + currinf.fonttable = &(dviFile->tn_table); + currinf._virtual = nullptr; + prescan(&dviRenderer::prescan_embedPS); + } + + delete embedPS_progress; + embedPS_progress = nullptr; + + if (!errorMsg.isEmpty()) { + emit warning(i18n("Not all PostScript files could be embedded into your document. %1", errorMsg), -1); + errorMsg.clear(); + } else { + emit notice(i18n("All external PostScript files were embedded into your document."), -1); + } + + // Prescan phase starts here +#ifdef PERFORMANCE_MEASUREMENT + // qCDebug(OkularDviDebug) << "Time elapsed till prescan phase starts " << performanceTimer.elapsed() << "ms"; + // QTime preScanTimer; + // preScanTimer.start(); +#endif + dviFile->numberOfExternalPSFiles = 0; + prebookmarks.clear(); + for (current_page = 0; current_page < dviFile->total_pages; current_page++) { + PostScriptOutPutString = new QString(); + + if (current_page < dviFile->total_pages) { + command_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page)]; + end_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page + 1)]; + } else + command_pointer = end_pointer = nullptr; + + memset((char *)&currinf.data, 0, sizeof(currinf.data)); + currinf.fonttable = &(dviFile->tn_table); + currinf._virtual = nullptr; + + prescan(&dviRenderer::prescan_parseSpecials); + + if (!PostScriptOutPutString->isEmpty()) + PS_interface->setPostScript(current_page, *PostScriptOutPutString); + delete PostScriptOutPutString; + } + PostScriptOutPutString = nullptr; + +#ifdef PERFORMANCE_MEASUREMENT + // qCDebug(OkularDviDebug) << "Time required for prescan phase: " << preScanTimer.restart() << "ms"; +#endif + current_page = currPageSav; + _isModified = true; +} + +bool dviRenderer::isValidFile(const QString &filename) const +{ + QFile f(filename); + if (!f.open(QIODevice::ReadOnly)) + return false; + + unsigned char test[4]; + if (f.read((char *)test, 2) < 2 || test[0] != 247 || test[1] != 2) + return false; + + int n = f.size(); + if (n < 134) // Too short for a dvi file + return false; + f.seek(n - 4); + + unsigned char trailer[4] = {0xdf, 0xdf, 0xdf, 0xdf}; + + if (f.read((char *)test, 4) < 4 || strncmp((char *)test, (char *)trailer, 4) != 0) + return false; + // We suppose now that the dvi file is complete and OK + return true; +} + +bool dviRenderer::setFile(const QString &fname, const QUrl &base) +{ +#ifdef DEBUG_DVIRENDERER + qCDebug(OkularDviDebug) << "dviRenderer::setFile( fname='" << fname << "' )"; //, ref='" << ref << "', sourceMarker=" << sourceMarker << " )"; +#endif + + // QMutexLocker lock(&mutex); + + QFileInfo fi(fname); + QString filename = fi.absoluteFilePath(); + + // If fname is the empty string, then this means: "close". Delete + // the dvifile and the pixmap. + if (fname.isEmpty()) { + // Delete DVI file + delete dviFile; + dviFile = nullptr; + return true; + } + + // Make sure the file actually exists. + if (!fi.exists() || fi.isDir()) { + emit error(i18n("The specified file '%1' does not exist.", filename), -1); + return false; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + dvifile *dviFile_new = new dvifile(filename, &font_pool); + + if ((dviFile == nullptr) || (dviFile->filename != filename)) + dviFile_new->sourceSpecialMarker = true; + else + dviFile_new->sourceSpecialMarker = false; + + if ((dviFile_new->dvi_Data() == nullptr) || (dviFile_new->errorMsg.isEmpty() != true)) { + QApplication::restoreOverrideCursor(); + if (dviFile_new->errorMsg.isEmpty() != true) + emit error(i18n("File corruption. %1", dviFile_new->errorMsg), -1); + delete dviFile_new; + return false; + } + + delete dviFile; + dviFile = dviFile_new; + numPages = dviFile->total_pages; + _isModified = false; + baseURL = base; + + font_pool.setExtraSearchPath(fi.absolutePath()); + font_pool.setCMperDVIunit(dviFile->getCmPerDVIunit()); + + // Extract PostScript from the DVI file, and store the PostScript + // specials in PostScriptDirectory, and the headers in the + // PostScriptHeaderString. + PS_interface->clear(); + + // If the DVI file comes from a remote URL (e.g. downloaded from a + // web server), we limit the PostScript files that can be accessed + // by this file to the download directory, in order to limit the + // possibilities of a denial of service attack. + QString includePath; + if (!baseURL.isLocalFile()) { + includePath = filename; + includePath.truncate(includePath.lastIndexOf(QLatin1Char('/'))); + } + PS_interface->setIncludePath(includePath); + + // We will also generate a list of hyperlink-anchors and source-file + // anchors in the document. So declare the existing lists empty. + // anchorList.clear(); + sourceHyperLinkAnchors.clear(); + // bookmarks.clear(); + prebookmarks.clear(); + + if (dviFile->page_offset.isEmpty() == true) + return false; + + // We should pre-scan the document now (to extract embedded, + // PostScript, Hyperlinks, ets). + + // PRESCAN STARTS HERE +#ifdef PERFORMANCE_MEASUREMENT + // qCDebug(OkularDviDebug) << "Time elapsed till prescan phase starts " << performanceTimer.elapsed() << "ms"; + // QTime preScanTimer; + // preScanTimer.start(); +#endif + dviFile->numberOfExternalPSFiles = 0; + quint16 currPageSav = current_page; + prebookmarks.clear(); + + for (current_page = 0; current_page < dviFile->total_pages; current_page++) { + PostScriptOutPutString = new QString(); + + if (current_page < dviFile->total_pages) { + command_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page)]; + end_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page + 1)]; + } else + command_pointer = end_pointer = nullptr; + + memset((char *)&currinf.data, 0, sizeof(currinf.data)); + currinf.fonttable = &(dviFile->tn_table); + currinf._virtual = nullptr; + prescan(&dviRenderer::prescan_parseSpecials); + + if (!PostScriptOutPutString->isEmpty()) + PS_interface->setPostScript(current_page, *PostScriptOutPutString); + delete PostScriptOutPutString; + } + PostScriptOutPutString = nullptr; + +#if 0 + // Generate the list of bookmarks + bookmarks.clear(); + Q3PtrStack stack; + stack.setAutoDelete (false); + QVector::iterator it; + for( it = prebookmarks.begin(); it != prebookmarks.end(); ++it ) { + Bookmark *bmk = new Bookmark((*it).title, findAnchor((*it).anchorName)); + if (stack.isEmpty()) + bookmarks.append(bmk); + else { + stack.top()->subordinateBookmarks.append(bmk); + stack.remove(); + } + for(int i=0; i<(*it).noOfChildren; i++) + stack.push(bmk); + } + prebookmarks.clear(); +#endif + +#ifdef PERFORMANCE_MEASUREMENT + // qCDebug(OkularDviDebug) << "Time required for prescan phase: " << preScanTimer.restart() << "ms"; +#endif + current_page = currPageSav; + // PRESCAN ENDS HERE + + pageSizes.resize(0); + if (dviFile->suggestedPageSize != nullptr) { + // Fill the vector pageSizes with total_pages identical entries + pageSizes.fill(*(dviFile->suggestedPageSize), dviFile->total_pages); + } + QApplication::restoreOverrideCursor(); + return true; +} + +Anchor dviRenderer::parseReference(const QString &reference) +{ + QMutexLocker locker(&mutex); + +#ifdef DEBUG_DVIRENDERER + qCCritical(OkularDviDebug) << "dviRenderer::parseReference( " << reference << " ) called" << endl; +#endif + + if (dviFile == nullptr) + return Anchor(); + + // case 1: The reference is a number, which we'll interpret as a + // page number. + bool ok; + int page = reference.toInt(&ok); + if (ok == true) { + if (page < 0) + page = 0; + if (page > dviFile->total_pages) + page = dviFile->total_pages; + + return Anchor(page, Length()); + } + + // case 2: The reference is of form "src:1111Filename", where "1111" + // points to line number 1111 in the file "Filename". KDVI then + // looks for source specials of the form "src:xxxxFilename", and + // tries to find the special with the biggest xxxx + if (reference.indexOf(QStringLiteral("src:"), 0, Qt::CaseInsensitive) == 0) { + // Extract the file name and the numeral part from the reference string + DVI_SourceFileSplitter splitter(reference, dviFile->filename); + quint32 refLineNumber = splitter.line(); + QString refFileName = splitter.filePath(); + + if (sourceHyperLinkAnchors.isEmpty()) { + emit warning(i18n("You have asked Okular to locate the place in the DVI file which corresponds to " + "line %1 in the TeX-file %2. It seems, however, that the DVI file " + "does not contain the necessary source file information. ", + refLineNumber, + refFileName), + -1); + return Anchor(); + } + + // Go through the list of source file anchors, and find the anchor + // whose line number is the biggest among those that are smaller + // than the refLineNumber. That way, the position in the DVI file + // which is highlighted is always a little further up than the + // position in the editor, e.g. if the DVI file contains + // positional information at the beginning of every paragraph, + // KDVI jumps to the beginning of the paragraph that the cursor is + // in, and never to the next paragraph. If source file anchors for + // the refFileName can be found, but none of their line numbers is + // smaller than the refLineNumber, the reason is most likely, that + // the cursor in the editor stands somewhere in the preamble of + // the LaTeX file. In that case, we jump to the beginning of the + // document. + bool anchorForRefFileFound = false; // Flag that is set if source file anchors for the refFileName could be found at all + + QVector::iterator bestMatch = sourceHyperLinkAnchors.end(); + QVector::iterator it; + for (it = sourceHyperLinkAnchors.begin(); it != sourceHyperLinkAnchors.end(); ++it) + if (refFileName.trimmed() == it->fileName.trimmed() || refFileName.trimmed() == it->fileName.trimmed() + QStringLiteral(".tex")) { + anchorForRefFileFound = true; + + if ((it->line <= refLineNumber) && ((bestMatch == sourceHyperLinkAnchors.end()) || (it->line > bestMatch->line))) + bestMatch = it; + } + + if (bestMatch != sourceHyperLinkAnchors.end()) + return Anchor(bestMatch->page, bestMatch->distance_from_top); + else if (anchorForRefFileFound == false) { + emit warning(i18n("Okular was not able to locate the place in the DVI file which corresponds to " + "line %1 in the TeX-file %2.", + refLineNumber, + refFileName), + -1); + } else + return Anchor(); + return Anchor(); + } + return Anchor(); +} + +void dviRenderer::setResolution(double resolution_in_DPI) +{ + // Ignore minute changes. The difference to the current value would + // hardly be visible anyway. That saves a lot of re-painting, + // e.g. when the user resizes the window, and a flickery mouse + // changes the window size by 1 pixel all the time. + if (fabs(resolutionInDPI - resolution_in_DPI) < 1) + return; + + resolutionInDPI = resolution_in_DPI; + + // Pass the information on to the font pool. + font_pool.setDisplayResolution(resolutionInDPI); + shrinkfactor = 1200 / resolutionInDPI; + return; +} + +void dviRenderer::handleSRCLink(const QString &linkText, const QPoint point, DocumentWidget *widget) +{ + Q_UNUSED(linkText); + Q_UNUSED(point); + Q_UNUSED(widget); +#if 0 + QExplicitlySharedDataPointer editor(new DVISourceEditor(*this, parentWidget, linkText, point, win)); + if (editor->started()) + editor_ = editor; +#endif +} + +QString dviRenderer::PDFencodingToQString(const QString &_pdfstring) +{ + // This method locates special PDF characters in a string and + // replaces them by UTF8. See Section 3.2.3 of the PDF reference + // guide for information. + QString pdfstring = _pdfstring; + pdfstring = pdfstring.replace(QLatin1String("\\n"), QLatin1String("\n")); + pdfstring = pdfstring.replace(QLatin1String("\\r"), QLatin1String("\n")); + pdfstring = pdfstring.replace(QLatin1String("\\t"), QLatin1String("\t")); + pdfstring = pdfstring.replace(QLatin1String("\\f"), QLatin1String("\f")); + pdfstring = pdfstring.replace(QLatin1String("\\("), QLatin1String("(")); + pdfstring = pdfstring.replace(QLatin1String("\\)"), QLatin1String(")")); + pdfstring = pdfstring.replace(QLatin1String("\\\\"), QLatin1String("\\")); + + // Now replace octal character codes with the characters they encode + QRegularExpression regex(QStringLiteral("(\\\\)(\\d\\d\\d)")); // matches "\xyz" where x,y,z are numbers + QRegularExpressionMatch match; + while ((match = regex.match(pdfstring)).hasMatch()) { + pdfstring = pdfstring.replace(match.capturedStart(0), 4, QChar(match.captured(2).toInt(nullptr, 8))); + } + regex.setPattern(QStringLiteral("(\\\\)(\\d\\d)")); // matches "\xy" where x,y are numbers + while ((match = regex.match(pdfstring)).hasMatch()) { + pdfstring = pdfstring.replace(match.capturedStart(0), 3, QChar(match.captured(2).toInt(nullptr, 8))); + } + regex.setPattern(QStringLiteral("(\\\\)(\\d)")); // matches "\x" where x is a number + while ((match = regex.match(pdfstring)).hasMatch()) { + pdfstring = pdfstring.replace(match.capturedStart(0), 2, QChar(match.captured(2).toInt(nullptr, 8))); + } + + return pdfstring; +} + +void dviRenderer::exportPDF() +{ + /* + QExplicitlySharedDataPointer exporter(new DVIExportToPDF(*this, parentWidget)); + if (exporter->started()) + all_exports_[exporter.data()] = exporter; + */ +} + +void dviRenderer::exportPS(const QString &fname, const QStringList &options, QPrinter *printer, QPrinter::Orientation orientation) +{ + QExplicitlySharedDataPointer exporter(new DVIExportToPS(*this, fname, options, printer, font_pool.getUseFontHints(), orientation)); + if (exporter->started()) + all_exports_[exporter.data()] = exporter; +} + +/* +void dviRenderer::editor_finished(const DVISourceEditor*) +{ + editor_.attach(0); +} +*/ + +void dviRenderer::export_finished(const DVIExport *key) +{ + typedef QMap> ExportMap; + ExportMap::iterator it = all_exports_.find(key); + if (it != all_exports_.end()) + all_exports_.remove(key); +} + +void dviRenderer::setEventLoop(QEventLoop *el) +{ + if (el == nullptr) { + delete m_eventLoop; + m_eventLoop = nullptr; + } else + m_eventLoop = el; +} diff --git a/generators/dvi/dviRenderer.h b/generators/dvi/dviRenderer.h new file mode 100644 index 0000000..e566937 --- /dev/null +++ b/generators/dvi/dviRenderer.h @@ -0,0 +1,346 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Class: dviRenderer +// +// Class for rendering TeX DVI files. +// Part of KDVI- A previewer for TeX DVI files. +// +// (C) 2001-2006 Stefan Kebekus. Distributed under the GPL. + +#ifndef _dvirenderer_h_ +#define _dvirenderer_h_ + +#include "bigEndianByteReader.h" +//#include "documentRenderer.h" +#include "dviexport.h" +//#include "dvisourceeditor.h" +#include "anchor.h" +#include "dviPageInfo.h" +#include "fontpool.h" +#include "pageSize.h" +#include "prebookmark.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Anchor; +class DocumentWidget; +class dvifile; +class dviRenderer; +class ghostscript_interface; +class QEventLoop; +class QProgressDialog; +class PreBookmark; +class TeXFontDefinition; + +extern const int MFResolutions[]; + +class DVI_SourceFileAnchor +{ +public: + DVI_SourceFileAnchor() + { + } + DVI_SourceFileAnchor(const QString &name, quint32 ln, quint32 pg, const Length _distance_from_top) + : fileName(name) + , line(ln) + , page(pg) + , distance_from_top(_distance_from_top) + { + } + + QString fileName; + quint32 line; + quint32 page; + Length distance_from_top; +}; + +/** Compound of registers, as defined in section 2.6.2 of the DVI + driver standard, Level 0, published by the TUG DVI driver + standards committee. */ + +struct framedata { + long dvi_h; + long dvi_v; + long w; + long x; + long y; + long z; + int pxl_v; +}; + +/* this information is saved when using virtual fonts */ + +typedef void (dviRenderer::*set_char_proc)(unsigned int, unsigned int); +typedef void (dviRenderer::*parseSpecials)(char *, quint8 *); + +struct drawinf { + struct framedata data; + TeXFontDefinition *fontp; + set_char_proc set_char_p; + + QHash *fonttable; + TeXFontDefinition *_virtual; +}; + +class dviRenderer : public QObject /*: public DocumentRenderer*/, bigEndianByteReader +{ + Q_OBJECT + +public: + dviRenderer(bool useFontHinting); + ~dviRenderer() override; + + virtual bool setFile(const QString &fname, const QUrl &base); + + dvifile *dviFile; + +#if 0 + bool isModified() const {return _isModified;}; + + void setPrefs(bool flag_showPS, const QString &editorCommand, bool useFontHints ); +#endif + + virtual bool supportsTextSearch() const + { + return true; + } + + bool showPS() + { + return _postscript; + } + int curr_page() + { + return current_page + 1; + } + virtual bool isValidFile(const QString &fileName) const; + + /** This method will try to parse the reference part of the DVI + file's URL, (either a number, which is supposed to be a page + number, or src:\\) and see if a corresponding + section of the DVI file can be found. If so, it returns an + anchor to that section. If not, it returns an invalid anchor. */ + virtual Anchor parseReference(const QString &reference); + + Anchor findAnchor(const QString &); + + virtual PageNumber totalPages() const; + + void setEventLoop(QEventLoop *el); + + // These should not be public... only for the moment + void read_postamble(); + void draw_part(double current_dimconv, bool is_vfmacro); + void set_vf_char(unsigned int cmd, unsigned int ch); + void set_char(unsigned int cmd, unsigned int ch); + void set_empty_char(unsigned int cmd, unsigned int ch); + void set_no_char(unsigned int cmd, unsigned int ch); + void applicationDoSpecial(char *cp); + + void special(long nbytes); + void printErrorMsgForSpecials(const QString &msg); + void color_special(const QString &msg); + void html_href_special(const QString &msg); + void html_anchor_end(); + void draw_page(); + void export_finished(const DVIExport *); + // void editor_finished(const DVISourceEditor*); + + QVector getPrebookmarks() const + { + return prebookmarks; + } + +Q_SIGNALS: + /** + * The following three signals are modeleed on the corresponding signals + * of the Document class. + */ + void error(const QString &message, int duration); + void warning(const QString &message, int duration); + void notice(const QString &message, int duration); + +public Q_SLOTS: + void exportPS(const QString &fname = QString(), const QStringList &options = QStringList(), QPrinter *printer = nullptr, QPrinter::Orientation orientation = QPrinter::Portrait); + void exportPDF(); + + void handleSRCLink(const QString &linkText, const QPoint point, DocumentWidget *widget); + + void embedPostScript(); + + virtual void drawPage(RenderedDocumentPagePixmap *page); + virtual void getText(RenderedDocumentPagePixmap *page); + + SimplePageSize sizeOfPage(const PageNumber page); + + const QVector &sourceAnchors() + { + return sourceHyperLinkAnchors; + } + +private Q_SLOTS: + /** This method shows a dialog that tells the user that source + information is present, and gives the opportunity to open the + manual and learn more about forward and inverse search */ + // void showThatSourceInformationIsPresent(); + +private: + friend class DVIExportToPS; + friend class DVIExport; + // friend class DVISourceEditor; + + /** URL to the DVI file + This field is initialized by the setFile() method. See the + explanation there. */ + QUrl baseURL; + + /** This method parses a color specification of type "gray 0.5", "rgb + 0.5 0.7 1.0", "hsb ...", "cmyk .." or "PineGreen". See the source + code for details. */ + QColor parseColorSpecification(const QString &colorSpec); + + /** This map contains the colors which are known by name. This field + is initialized in the method parseColorSpecification() as soon as + it is needed. */ + QMap namedColors; + + /** This method locates special PDF characters in a string and + replaces them by UTF8. See Section 3.2.3 of the PDF reference + guide for information */ + QString PDFencodingToQString(const QString &pdfstring); + + void setResolution(double resolution_in_DPI); + + fontPool font_pool; + + double resolutionInDPI; + + // @@@ explanation + void prescan(parseSpecials specialParser); + void prescan_embedPS(char *cp, quint8 *); + void prescan_removePageSizeInfo(char *cp, quint8 *); + void prescan_parseSpecials(char *cp, quint8 *); + void prescan_ParsePapersizeSpecial(const QString &cp); + void prescan_ParseBackgroundSpecial(const QString &cp); + void prescan_ParseHTMLAnchorSpecial(const QString &cp); + void prescan_ParsePSHeaderSpecial(const QString &cp); + void prescan_ParsePSBangSpecial(const QString &cp); + void prescan_ParsePSQuoteSpecial(const QString &cp); + void prescan_ParsePSSpecial(const QString &cp); + void prescan_ParsePSFileSpecial(const QString &cp); + void prescan_ParseSourceSpecial(const QString &cp); + void prescan_setChar(unsigned int ch); + + /* */ + QVector prebookmarks; + + /** Utility fields used by the embedPostScript method*/ + QProgressDialog *embedPS_progress; + quint16 embedPS_numOfProgressedFiles; + + /** Shrink factor. Units are not quite clear */ + double shrinkfactor; + + QString errorMsg; + + /** Methods which handle certain special commands. */ + void epsf_special(const QString &cp); + void source_special(const QString &cp); + + /** TPIC specials */ + void TPIC_setPen_special(const QString &cp); + void TPIC_addPath_special(const QString &cp); + void TPIC_flushPath_special(); + + // List of source-hyperlinks on all pages. This vector is generated + // when the DVI-file is first loaded, i.e. when draw_part is called + // with PostScriptOutPutString != NULL + QVector sourceHyperLinkAnchors; + + // If not NULL, the text currently drawn represents a source + // hyperlink to the (relative) URL given in the string; + QString *source_href; + + // If not NULL, the text currently drawn represents a hyperlink to + // the (relative) URL given in the string; + QString *HTML_href; + + QString editorCommand; + + /** Stack for register compounds, used for the DVI-commands PUSH/POP + as explained in section 2.5 and 2.6.2 of the DVI driver standard, + Level 0, published by the TUG DVI driver standards committee. */ + QStack stack; + + /** A stack where color are stored, according to the documentation of + DVIPS */ + QStack colorStack; + + /** The global color is to be used when the color stack is empty */ + QColor globalColor; + + /** If PostScriptOutPutFile is non-zero, then no rendering takes + place. Instead, the PostScript code which is generated by the + \special-commands is written to the PostScriptString */ + QString *PostScriptOutPutString; + + ghostscript_interface *PS_interface; + + /** true, if gs should be used, otherwise, only bounding boxes are + drawn. */ + bool _postscript; + + /** This flag is used when rendering a dvi-page. It is set to "true" + when any dvi-command other than "set" or "put" series of commands + is encountered. This is considered to mark the end of a word. */ + bool line_boundary_encountered; + bool word_boundary_encountered; + + unsigned int current_page; + + /** Data required for handling TPIC specials */ + float penWidth_in_mInch; + QPolygon TPIC_path; + quint16 number_of_elements_in_path; + + drawinf currinf; + RenderedDocumentPagePixmap *currentlyDrawnPage; + QMap> all_exports_; + // QExplicitlySharedDataPointer editor_; + + /** Flag if document is modified + + This flag indicates if the document was modified after it was + loaded. It is set to 'false' in the constructor, in the clear() and + setFile() method. It can be set to 'true' be methods that modify the + document (e.g. the deletePages() method of the djvu implementation + of this class). + */ + bool _isModified; + + QMutex mutex; + quint16 numPages; + + // TODO: merge into dviPageInfo + QVector pageSizes; + + QMap anchorList; + + QEventLoop *m_eventLoop; + + QPainter *foreGroundPainter; + + // was the locateFonts method of font pool executed? + bool fontpoolLocateFontsDone; +}; + +#endif diff --git a/generators/dvi/dviRenderer_dr.cpp b/generators/dvi/dviRenderer_dr.cpp new file mode 100644 index 0000000..60fc61d --- /dev/null +++ b/generators/dvi/dviRenderer_dr.cpp @@ -0,0 +1,47 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Extracted from: +// Class: documentRenderer +// +// Abstract Widget for displaying document types +// Needs to be implemented from the actual parts +// using kviewshell +// Part of KViewshell - A generic interface for document viewers. +// +// (C) 2004-2005 Wilfried Huss +// (C) 2004-2006 Stefan Kebekus. +// Distributed under the GPL. + +#include "dviRenderer.h" + +SimplePageSize dviRenderer::sizeOfPage(const PageNumber page) +{ +#if !defined(QT_NO_THREAD) + // Wait for all access to this DocumentRenderer to finish + // QMutexLocker locker(&mutex); +#endif + + if (!page.isValid()) + return SimplePageSize(); + if (page > totalPages()) + return SimplePageSize(); + if (page > pageSizes.size()) + return SimplePageSize(); + + return pageSizes[page - 1]; +} + +Anchor dviRenderer::findAnchor(const QString &locallink) +{ + QMap::Iterator it = anchorList.find(locallink); + if (it != anchorList.end()) + return *it; + else + return Anchor(); +} + +PageNumber dviRenderer::totalPages() const +{ + PageNumber temp = numPages; + return temp; +} diff --git a/generators/dvi/dviRenderer_draw.cpp b/generators/dvi/dviRenderer_draw.cpp new file mode 100644 index 0000000..a2e858e --- /dev/null +++ b/generators/dvi/dviRenderer_draw.cpp @@ -0,0 +1,675 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * NOTE: + * xdvi is based on prior work as noted in the modification history, below. + */ + +/* + * DVI previewer for X. + * + * Eric Cooper, CMU, September 1985. + * + * Code derived from dvi-imagen.c. + * + * Modification history: + * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS. + * 7/1988 Modified for X.11 --Mark Eichin, MIT + * 12/1988 Added 'R' option, toolkit, magnifying glass + * --Paul Vojta, UC Berkeley. + * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto + * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ. + * 3/1990 Added VMS support --Scott Allendorf, U of Iowa + * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem + * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen + * and Lee Hetherington, MIT + * 4/1994 Added DPS support, bounding box + * --Ricardo Telichevesky + * and Luis Miguel Silveira, MIT RLE. + */ + +//#define DEBUG_RENDER 0 + +#include + +#include "debug_dvi.h" +#include "dvi.h" +#include "dviFile.h" +#include "dviRenderer.h" +#include "hyperlink.h" +#include "psgs.h" +//#include "renderedDviPagePixmap.h" +#include "TeXFont.h" +#include "textBox.h" +#include "xdvi.h" + +#include + +#include +#include + +/** Routine to print characters. */ + +void dviRenderer::set_char(unsigned int cmd, unsigned int ch) +{ +#ifdef DEBUG_RENDER + qCDebug(OkularDviDebug) << "set_char #" << ch; +#endif + + glyph *g; + if (colorStack.isEmpty()) + g = ((TeXFont *)(currinf.fontp->font))->getGlyph(ch, true, globalColor); + else + g = ((TeXFont *)(currinf.fontp->font))->getGlyph(ch, true, colorStack.top()); + if (g == nullptr) + return; + + long dvi_h_sav = currinf.data.dvi_h; + + QImage pix = g->shrunkenCharacter; + int x = ((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))) - g->x2; + int y = currinf.data.pxl_v - g->y2; + + // Draw the character. + foreGroundPainter->drawImage(x, y, pix); + + // Are we drawing text for a hyperlink? And are hyperlinks + // enabled? + if (HTML_href != nullptr) { + // Now set up a rectangle which is checked against every mouse + // event. + if (line_boundary_encountered == true) { + // Set up hyperlink + Hyperlink dhl; + dhl.baseline = currinf.data.pxl_v; + dhl.box.setRect(x, y, pix.width(), pix.height()); + dhl.linkText = *HTML_href; + currentlyDrawnPage->hyperLinkList.push_back(dhl); + } else { + QRect dshunion = currentlyDrawnPage->hyperLinkList[currentlyDrawnPage->hyperLinkList.size() - 1].box.united(QRect(x, y, pix.width(), pix.height())); + currentlyDrawnPage->hyperLinkList[currentlyDrawnPage->hyperLinkList.size() - 1].box = dshunion; + } + } + + // Are we drawing text for a source hyperlink? And are source + // hyperlinks enabled? + // If we are printing source hyperlinks are irrelevant, otherwise we + // actually got a pointer to a RenderedDviPagePixmap. + RenderedDviPagePixmap *currentDVIPage = dynamic_cast(currentlyDrawnPage); + if (source_href != nullptr && currentDVIPage) { + // Now set up a rectangle which is checked against every mouse + // event. + if (line_boundary_encountered == true) { + // Set up source hyperlinks + Hyperlink dhl; + dhl.baseline = currinf.data.pxl_v; + dhl.box.setRect(x, y, pix.width(), pix.height()); + if (source_href != nullptr) + dhl.linkText = *source_href; + else + dhl.linkText = QLatin1String(""); + currentDVIPage->sourceHyperLinkList.push_back(dhl); + } else { + QRect dshunion = currentDVIPage->sourceHyperLinkList[currentDVIPage->sourceHyperLinkList.size() - 1].box.united(QRect(x, y, pix.width(), pix.height())); + currentDVIPage->sourceHyperLinkList[currentDVIPage->sourceHyperLinkList.size() - 1].box = dshunion; + } + } + + // Code for DVI -> text functions (e.g. marking of text, full text + // search, etc.). Set up the currentlyDrawnPage->textBoxList. + TextBox link; + link.box.setRect(x, y, pix.width(), pix.height()); + link.text = QLatin1String(""); + currentlyDrawnPage->textBoxList.push_back(link); + + switch (ch) { + case 0x0b: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("ff"); + break; + case 0x0c: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("fi"); + break; + case 0x0d: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("fl"); + break; + case 0x0e: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("ffi"); + break; + case 0x0f: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("ffl"); + break; + + case 0x7b: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('-'); + break; + case 0x7c: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("---"); + break; + case 0x7d: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("\""); + break; + case 0x7e: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('~'); + break; + case 0x7f: + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1String("@@"); // @@@ check! + break; + + default: + if ((ch >= 0x21) && (ch <= 0x7a)) + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QChar(ch); + else + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('?'); + break; + } + + if (cmd == PUT1) + currinf.data.dvi_h = dvi_h_sav; + else + currinf.data.dvi_h += (int)(currinf.fontp->scaled_size_in_DVI_units * dviFile->getCmPerDVIunit() * (1200.0 / 2.54) / 16.0 * g->dvi_advance_in_units_of_design_size_by_2e20 + 0.5); + + word_boundary_encountered = false; + line_boundary_encountered = false; +} + +void dviRenderer::set_empty_char(unsigned int, unsigned int) +{ + return; +} + +void dviRenderer::set_vf_char(unsigned int cmd, unsigned int ch) +{ +#ifdef DEBUG_RENDER + qCDebug(OkularDviDebug) << "dviRenderer::set_vf_char( cmd=" << cmd << ", ch=" << ch << " )"; +#endif + + static unsigned char c; + macro *m = &currinf.fontp->macrotable[ch]; + if (m->pos == nullptr) { + qCCritical(OkularDviDebug) << "Character " << ch << " not defined in font " << currinf.fontp->fontname << endl; + m->pos = m->end = &c; + return; + } + + long dvi_h_sav = currinf.data.dvi_h; + + struct drawinf oldinfo = currinf; + currinf.data.w = 0; + currinf.data.x = 0; + currinf.data.y = 0; + currinf.data.z = 0; + + currinf.fonttable = &(currinf.fontp->vf_table); + currinf._virtual = currinf.fontp; + quint8 *command_ptr_sav = command_pointer; + quint8 *end_ptr_sav = end_pointer; + command_pointer = m->pos; + end_pointer = m->end; + draw_part(currinf.fontp->scaled_size_in_DVI_units * (dviFile->getCmPerDVIunit() * 1200.0 / 2.54) / 16.0, true); + command_pointer = command_ptr_sav; + end_pointer = end_ptr_sav; + currinf = oldinfo; + + if (cmd == PUT1) + currinf.data.dvi_h = dvi_h_sav; + else + currinf.data.dvi_h += (int)(currinf.fontp->scaled_size_in_DVI_units * dviFile->getCmPerDVIunit() * (1200.0 / 2.54) / 16.0 * m->dvi_advance_in_units_of_design_size_by_2e20 + 0.5); +} + +void dviRenderer::set_no_char(unsigned int cmd, unsigned int ch) +{ +#ifdef DEBUG_RENDER + qCDebug(OkularDviDebug) << "dviRenderer::set_no_char( cmd=" << cmd << ", ch =" << ch << " )"; +#endif + + if (currinf._virtual) { + currinf.fontp = currinf._virtual->first_font; + if (currinf.fontp != nullptr) { + currinf.set_char_p = currinf.fontp->set_char_p; + (this->*currinf.set_char_p)(cmd, ch); + return; + } + } + + errorMsg = i18n("The DVI code set a character of an unknown font."); + return; +} + +void dviRenderer::draw_part(double current_dimconv, bool is_vfmacro) +{ +#ifdef DEBUG_RENDER + qCDebug(OkularDviDebug) << "draw_part"; +#endif + + qint32 RRtmp = 0, WWtmp = 0, XXtmp = 0, YYtmp = 0, ZZtmp = 0; + quint8 ch; + + currinf.fontp = nullptr; + currinf.set_char_p = &dviRenderer::set_no_char; + + int last_space_index = 0; + bool space_encountered = false; + bool after_space = false; + for (;;) { + space_encountered = false; + ch = readUINT8(); + if (ch <= (unsigned char)(SETCHAR0 + 127)) { + (this->*currinf.set_char_p)(ch, ch); + } else if (FNTNUM0 <= ch && ch <= (unsigned char)(FNTNUM0 + 63)) { + currinf.fontp = currinf.fonttable->value(ch - FNTNUM0); + if (currinf.fontp == nullptr) { + errorMsg = i18n("The DVI code referred to font #%1, which was not previously defined.", ch - FNTNUM0); + return; + } + currinf.set_char_p = currinf.fontp->set_char_p; + } else { + qint32 a, b; + + switch (ch) { + case SET1: + case PUT1: + (this->*currinf.set_char_p)(ch, readUINT8()); + break; + + case SETRULE: + if (is_vfmacro == false) { + word_boundary_encountered = true; + line_boundary_encountered = true; + } + /* Be careful, dvicopy outputs rules with height = + 0x80000000. We don't want any SIGFPE here. */ + a = readUINT32(); + b = readUINT32(); + b = ((long)(b * current_dimconv)); + if (a > 0 && b > 0) { + int h = ((int)ROUNDUP(((long)(a * current_dimconv)), shrinkfactor * 65536)); + int w = ((int)ROUNDUP(b, shrinkfactor * 65536)); + + if (colorStack.isEmpty()) + foreGroundPainter->fillRect(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - h + 1, w ? w : 1, h ? h : 1, globalColor); + else + foreGroundPainter->fillRect(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - h + 1, w ? w : 1, h ? h : 1, colorStack.top()); + } + currinf.data.dvi_h += b; + break; + + case PUTRULE: + if (is_vfmacro == false) { + word_boundary_encountered = true; + line_boundary_encountered = true; + } + a = readUINT32(); + b = readUINT32(); + a = ((long)(a * current_dimconv)); + b = ((long)(b * current_dimconv)); + if (a > 0 && b > 0) { + int h = ((int)ROUNDUP(a, shrinkfactor * 65536)); + int w = ((int)ROUNDUP(b, shrinkfactor * 65536)); + if (colorStack.isEmpty()) + foreGroundPainter->fillRect(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - h + 1, w ? w : 1, h ? h : 1, globalColor); + else + foreGroundPainter->fillRect(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - h + 1, w ? w : 1, h ? h : 1, colorStack.top()); + } + break; + + case NOP: + break; + + case BOP: + if (is_vfmacro == false) { + word_boundary_encountered = true; + line_boundary_encountered = true; + } + command_pointer += 11 * 4; + currinf.data.dvi_h = 1200 << 16; // Reminder: DVI-coordinates start at (1",1") from top of page + currinf.data.dvi_v = 1200; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + currinf.data.w = currinf.data.x = currinf.data.y = currinf.data.z = 0; + break; + + case EOP: + // Check if we are just at the end of a virtual font macro. + if (is_vfmacro == false) { + // This is really the end of a page, and not just the end + // of a macro. Mark the end of the current word. + word_boundary_encountered = true; + line_boundary_encountered = true; + // Sanity check for the dvi-file: The DVI-standard asserts + // that at the end of a page, the stack should always be + // empty. + if (!stack.isEmpty()) { + qCDebug(OkularDviDebug) << "DRAW: The stack was not empty when the EOP command was encountered."; + errorMsg = i18n("The stack was not empty when the EOP command was encountered."); + return; + } + } + return; + + case PUSH: + stack.push(currinf.data); + break; + + case POP: + if (stack.isEmpty()) { + errorMsg = i18n("The stack was empty when a POP command was encountered."); + return; + } else + currinf.data = stack.pop(); + word_boundary_encountered = true; + line_boundary_encountered = true; + break; + + case RIGHT1: + case RIGHT2: + case RIGHT3: + case RIGHT4: + RRtmp = readINT(ch - RIGHT1 + 1); + + // A horizontal motion in the range 4 * font space [f] < h < + // font space [f] will be treated as a kern that is not + // indicated in the printouts that DVItype produces between + // brackets. We allow a larger space in the negative + // direction than in the positive one, because TEX makes + // comparatively large backspaces when it positions + // accents. (comments stolen from the source of dvitype) + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && ((RRtmp >= currinf.fontp->scaled_size_in_DVI_units / 6) || (RRtmp <= -4 * (currinf.fontp->scaled_size_in_DVI_units / 6))) && + (currentlyDrawnPage->textBoxList.size() > 0)) { + // currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += ' '; + space_encountered = true; + } + currinf.data.dvi_h += ((long)(RRtmp * current_dimconv)); + break; + + case W1: + case W2: + case W3: + case W4: + WWtmp = readINT(ch - W0); + currinf.data.w = ((long)(WWtmp * current_dimconv)); + // fallthrough + case W0: + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && ((WWtmp >= currinf.fontp->scaled_size_in_DVI_units / 6) || (WWtmp <= -4 * (currinf.fontp->scaled_size_in_DVI_units / 6))) && + (currentlyDrawnPage->textBoxList.size() > 0)) { + // currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += ' '; + space_encountered = true; + } + currinf.data.dvi_h += currinf.data.w; + break; + + case X1: + case X2: + case X3: + case X4: + XXtmp = readINT(ch - X0); + currinf.data.x = ((long)(XXtmp * current_dimconv)); + // fallthrough + case X0: + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && ((XXtmp >= currinf.fontp->scaled_size_in_DVI_units / 6) || (XXtmp <= -4 * (currinf.fontp->scaled_size_in_DVI_units / 6))) && + (currentlyDrawnPage->textBoxList.size() > 0)) { + // currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size()-1].text += ' '; + space_encountered = true; + } + currinf.data.dvi_h += currinf.data.x; + break; + + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: { + qint32 DDtmp = readINT(ch - DOWN1 + 1); + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && (abs(DDtmp) >= 5 * (currinf.fontp->scaled_size_in_DVI_units / 6)) && (currentlyDrawnPage->textBoxList.size() > 0)) { + word_boundary_encountered = true; + line_boundary_encountered = true; + space_encountered = true; + if (abs(DDtmp) >= 10 * (currinf.fontp->scaled_size_in_DVI_units / 6)) + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('\n'); + } + currinf.data.dvi_v += ((long)(DDtmp * current_dimconv)) / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + } break; + + case Y1: + case Y2: + case Y3: + case Y4: + YYtmp = readINT(ch - Y0); + currinf.data.y = ((long)(YYtmp * current_dimconv)); + // fallthrough + case Y0: + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && (abs(YYtmp) >= 5 * (currinf.fontp->scaled_size_in_DVI_units / 6)) && (currentlyDrawnPage->textBoxList.size() > 0)) { + word_boundary_encountered = true; + line_boundary_encountered = true; + space_encountered = true; + if (abs(YYtmp) >= 10 * (currinf.fontp->scaled_size_in_DVI_units / 6)) + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('\n'); + } + currinf.data.dvi_v += currinf.data.y / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + break; + + case Z1: + case Z2: + case Z3: + case Z4: + ZZtmp = readINT(ch - Z0); + currinf.data.z = ((long)(ZZtmp * current_dimconv)); + // fallthrough + case Z0: + if ((is_vfmacro == false) && (currinf.fontp != nullptr) && (abs(ZZtmp) >= 5 * (currinf.fontp->scaled_size_in_DVI_units / 6)) && (currentlyDrawnPage->textBoxList.size() > 0)) { + word_boundary_encountered = true; + line_boundary_encountered = true; + space_encountered = true; + if (abs(ZZtmp) >= 10 * (currinf.fontp->scaled_size_in_DVI_units / 6)) + currentlyDrawnPage->textBoxList[currentlyDrawnPage->textBoxList.size() - 1].text += QLatin1Char('\n'); + } + currinf.data.dvi_v += currinf.data.z / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + break; + + case FNT1: + case FNT2: + case FNT3: + currinf.fontp = currinf.fonttable->value(readUINT(ch - FNT1 + 1)); + if (currinf.fontp == nullptr) { + errorMsg = i18n("The DVI code referred to a font which was not previously defined."); + return; + } + currinf.set_char_p = currinf.fontp->set_char_p; + break; + + case FNT4: + currinf.fontp = currinf.fonttable->value(readINT(ch - FNT1 + 1)); + if (currinf.fontp == nullptr) { + errorMsg = i18n("The DVI code referred to a font which was not previously defined."); + return; + } + currinf.set_char_p = currinf.fontp->set_char_p; + break; + + case XXX1: + case XXX2: + case XXX3: + case XXX4: + if (is_vfmacro == false) { + word_boundary_encountered = true; + line_boundary_encountered = true; + space_encountered = true; + } + a = readUINT(ch - XXX1 + 1); + if (a > 0) { + char *cmd = new char[a + 1]; + strncpy(cmd, (char *)command_pointer, a); + command_pointer += a; + cmd[a] = '\0'; + applicationDoSpecial(cmd); + delete[] cmd; + } + break; + + case FNTDEF1: + case FNTDEF2: + case FNTDEF3: + case FNTDEF4: + command_pointer += 12 + ch - FNTDEF1 + 1; + { + quint8 tempa = readUINT8(); + quint8 tempb = readUINT8(); + command_pointer += tempa + tempb; + } + break; + + case PRE: + case POST: + case POSTPOST: + errorMsg = i18n("An illegal command was encountered."); + return; + break; + + default: + errorMsg = i18n("The unknown op-code %1 was encountered.", ch); + return; + } /* end switch*/ + } /* end else (ch not a SETCHAR or FNTNUM) */ + +#ifdef DEBUG_RENDER + if (currentlyDrawnPage->textBoxList.size() > 0) + qCDebug(OkularDviDebug) << "Element:" << currentlyDrawnPage->textBoxList.last().box << currentlyDrawnPage->textBoxList.last().text << " ? s:" << space_encountered << " / nl:" << line_boundary_encountered + << " / w:" << word_boundary_encountered << ", " << last_space_index << "/" << currentlyDrawnPage->textBoxList.size(); +#endif + + /* heuristic to properly detect newlines; a space is needed */ + if (after_space && line_boundary_encountered && word_boundary_encountered) { + if (currentlyDrawnPage->textBoxList.last().text.endsWith(QLatin1Char('\n'))) + currentlyDrawnPage->textBoxList.last().text.chop(1); + currentlyDrawnPage->textBoxList.last().text += QLatin1String(" \n"); + after_space = false; + } + + /* a "space" has been found and there is some (new) character + in the array */ + if (space_encountered && (currentlyDrawnPage->textBoxList.size() > last_space_index)) { + for (int lidx = last_space_index + 1; lidx < currentlyDrawnPage->textBoxList.size(); ++lidx) { + // merge two adjacent boxes which are part of the same word + currentlyDrawnPage->textBoxList[lidx - 1].box.setRight(currentlyDrawnPage->textBoxList[lidx].box.x()); + } +#ifdef DEBUG_RENDER + QString lastword(currentlyDrawnPage->textBoxList[last_space_index].text); + for (int lidx = last_space_index + 1; lidx < currentlyDrawnPage->textBoxList.size(); ++lidx) + lastword += currentlyDrawnPage->textBoxList[lidx].text; + qCDebug(OkularDviDebug) << "space encountered: '" << lastword << "'"; +#endif + last_space_index = currentlyDrawnPage->textBoxList.size(); + after_space = true; + } + } /* end for */ +} + +void dviRenderer::draw_page() +{ + // Reset a couple of variables + HTML_href = nullptr; + source_href = nullptr; + penWidth_in_mInch = 0.0; + + // Calling resize() here rather than clear() means that the memory + // taken up by the vector is not freed. This is faster than + // constantly allocating/freeing memory. + currentlyDrawnPage->textBoxList.resize(0); + + RenderedDviPagePixmap *currentDVIPage = dynamic_cast(currentlyDrawnPage); + if (currentDVIPage) { + currentDVIPage->sourceHyperLinkList.resize(0); + } + +#ifdef PERFORMANCE_MEASUREMENT + // If this is the first time a page is drawn, take the time that is + // elapsed till the kdvi_multipage was constructed, and print + // it. Set the flag so that is message will not be printed again. + if (performanceFlag == 0) { + qCDebug(OkularDviDebug) << "Time elapsed till the first page is drawn: " << performanceTimer.restart() << "ms"; + performanceFlag = 1; + } +#endif + +#ifdef DEBUG_RENDER + qCDebug(OkularDviDebug) << "draw_page"; +#endif + +#if 0 + if (!accessibilityBackground) + { +#endif + foreGroundPainter->fillRect(foreGroundPainter->viewport(), PS_interface->getBackgroundColor(current_page)); +#if 0 + } + else + { + // In accessibility mode use the custom background color + foreGroundPainter->fillRect( foreGroundPainter->viewport(), accessibilityBackgroundColor ); + } +#endif + + // Render the PostScript background, if there is one. + if (_postscript) { +#if 0 + // In accessibility mode use the custom background color + if (accessibilityBackground) + { + // Flag permanent is set to false because otherwise we would not be able to restore + // the original background color. + PS_interface->setBackgroundColor(current_page, accessibilityBackgroundColor, false); + } + else +#endif + PS_interface->restoreBackgroundColor(current_page); + + PS_interface->graphics(current_page, resolutionInDPI, dviFile->getMagnification(), foreGroundPainter); + } + + // Now really write the text + if (dviFile->page_offset.isEmpty() == true) + return; + if (current_page < dviFile->total_pages) { + command_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page)]; + end_pointer = dviFile->dvi_Data() + dviFile->page_offset[int(current_page + 1)]; + } else + command_pointer = end_pointer = nullptr; + + memset((char *)&currinf.data, 0, sizeof(currinf.data)); + currinf.fonttable = &(dviFile->tn_table); + currinf._virtual = nullptr; + + double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0 / 2.54; + + draw_part(65536.0 * fontPixelPerDVIunit, false); + if (HTML_href != nullptr) { + delete HTML_href; + HTML_href = nullptr; + } + if (source_href != nullptr) { + delete source_href; + source_href = nullptr; + } +} diff --git a/generators/dvi/dviRenderer_prescan.cpp b/generators/dvi/dviRenderer_prescan.cpp new file mode 100644 index 0000000..e8978b7 --- /dev/null +++ b/generators/dvi/dviRenderer_prescan.cpp @@ -0,0 +1,781 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// dviRenderer_prescan.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003--2004 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "TeXFont.h" +#include "debug_dvi.h" +#include "dvi.h" +#include "dviFile.h" +#include "dviRenderer.h" +#include "prebookmark.h" +#include "psgs.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern QPainter foreGroundPaint; +extern void parse_special_argument(const QString &strg, const char *argument_name, int *variable); + +//#define DEBUG_PRESCAN + +void dviRenderer::prescan_embedPS(char *cp, quint8 *beginningOfSpecialCommand) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "dviRenderer::prescan_embedPS( cp = " << cp << " ) "; +#endif + + // Encapsulated Postscript File + if (qstrnicmp(cp, "PSfile=", 7) != 0) + return; + + QString command = QString::fromLocal8Bit(cp + 7); + + QString include_command = command.simplified(); + + // The line is supposed to start with "..ile=", and then comes the + // filename. Figure out what the filename is and stow it away. Of + // course, this does not work if the filename contains spaces + // (already the simplified() above is wrong). If you have + // files like this, go away. + QString EPSfilename = include_command; + EPSfilename.truncate(EPSfilename.indexOf(QLatin1Char(' '))); + + // Strip enclosing quotation marks which are included by some LaTeX + // macro packages (but not by others). This probably means that + // graphic files are no longer found if the filename really does + // contain quotes, but we don't really care that much. + if ((EPSfilename.at(0) == QLatin1Char('"')) && (EPSfilename.at(EPSfilename.length() - 1) == QLatin1Char('"'))) + EPSfilename = EPSfilename.mid(1, EPSfilename.length() - 2); + + // Now locate the Gfx file on the hard disk... + EPSfilename = ghostscript_interface::locateEPSfile(EPSfilename, baseURL); + + // If the file is neither a PostScript not a PDF file, we exit here. + // The graphic file is later read when the page is rendered. + QMimeDatabase db; + QMimeType const mime_type = db.mimeTypeForFile(EPSfilename, QMimeDatabase::MatchContent); + QString const &mime_type_name = mime_type.isValid() ? mime_type.name() : QString(); + + bool const is_ps_file = (mime_type_name == QLatin1String("application/postscript") || mime_type_name == QLatin1String("image/x-eps")); + bool const is_pdf_file = (!is_ps_file && mime_type_name == QLatin1String("application/pdf")); + if (!(is_ps_file || is_pdf_file)) + return; + + QString originalFName = EPSfilename; + + embedPS_progress->setLabelText(i18n("Embedding %1", EPSfilename)); + qApp->processEvents(); + + // If the EPSfilename really points to a PDF file, convert that file now. + if (is_pdf_file) + EPSfilename = dviFile->convertPDFtoPS(EPSfilename); + + if (!QFile::exists(EPSfilename)) { + // Find the number of the page + quint32 currentOffset = beginningOfSpecialCommand - dviFile->dvi_Data(); + int page = 0; + for (; page < dviFile->total_pages; page++) + if ((dviFile->page_offset[page] <= currentOffset) && (currentOffset <= dviFile->page_offset[page + 1])) + break; + if (is_pdf_file) + errorMsg += i18n("Page %1: The PDF file %2 could not be converted to PostScript.
", page + 1, originalFName); + else + errorMsg += i18n("Page %1: The PostScript file %2 could not be found.
", page + 1, originalFName); + embedPS_progress->setValue(embedPS_progress->value() + 1); + qApp->processEvents(); + return; + } + + // Now parse the arguments. + int llx = 0; + int lly = 0; + int urx = 0; + int ury = 0; + int rwi = 0; + int rhi = 0; + int angle = 0; + + // just to avoid ambiguities; the filename could contain keywords + include_command = include_command.mid(include_command.indexOf(QLatin1Char(' '))); + + parse_special_argument(include_command, "llx=", &llx); + parse_special_argument(include_command, "lly=", &lly); + parse_special_argument(include_command, "urx=", &urx); + parse_special_argument(include_command, "ury=", &ury); + parse_special_argument(include_command, "rwi=", &rwi); + parse_special_argument(include_command, "rhi=", &rhi); + parse_special_argument(include_command, "angle=", &angle); + + int clip = include_command.indexOf(QStringLiteral(" clip")); // -1 if clip keyword is not present, >= 0 otherwise + + // Generate the PostScript commands to be included + QString PS = QStringLiteral("ps: @beginspecial %1 @llx %2 @lly %3 @urx %4 @ury").arg(llx).arg(lly).arg(urx).arg(ury); + if (rwi != 0) + PS.append(QStringLiteral(" %1 @rwi").arg(rwi)); + if (rhi != 0) + PS.append(QStringLiteral(" %1 @rhi").arg(rhi)); + if (angle != 0) + PS.append(QStringLiteral(" %1 @angle").arg(angle)); + if (clip != -1) + PS.append(QStringLiteral(" @clip")); + PS.append(QStringLiteral(" @setspecial\n")); + + QFile file(EPSfilename); + if (file.open(QIODevice::ReadOnly)) { + QTextStream stream(&file); + while (!stream.atEnd()) { + PS += stream.readLine().section(QLatin1Char('%'), 0, 0); + PS += QLatin1Char('\n'); + } + file.close(); + } + PS.append(QStringLiteral("@endspecial")); + PS = PS.simplified(); + + _isModified = true; + quint32 lengthOfOldSpecial = command_pointer - beginningOfSpecialCommand; + quint32 lengthOfNewSpecial = PS.length() + 5; + + QVector newDVI(dviFile->size_of_file + lengthOfNewSpecial - lengthOfOldSpecial); + + quint8 *commandPtrSav = command_pointer; + quint8 *endPtrSav = end_pointer; + end_pointer = newDVI.data() + dviFile->size_of_file + lengthOfNewSpecial - lengthOfOldSpecial; + memcpy(newDVI.data(), dviFile->dvi_Data(), beginningOfSpecialCommand - dviFile->dvi_Data()); + command_pointer = newDVI.data() + (beginningOfSpecialCommand - dviFile->dvi_Data()); + command_pointer[0] = XXX4; + command_pointer++; + writeUINT32(PS.length()); + memcpy(newDVI.data() + (beginningOfSpecialCommand - dviFile->dvi_Data()) + 5, PS.toLatin1().constData(), PS.length()); + memcpy( + newDVI.data() + (beginningOfSpecialCommand - dviFile->dvi_Data()) + lengthOfNewSpecial, beginningOfSpecialCommand + lengthOfOldSpecial, dviFile->size_of_file - (beginningOfSpecialCommand - dviFile->dvi_Data()) - lengthOfOldSpecial); + + // Adjust page pointers in the DVI file + dviFile->size_of_file = dviFile->size_of_file + lengthOfNewSpecial - lengthOfOldSpecial; + end_pointer = newDVI.data() + dviFile->size_of_file; + quint32 currentOffset = beginningOfSpecialCommand - dviFile->dvi_Data(); + for (int i = 0; i < dviFile->total_pages; i++) { + if (dviFile->page_offset[i] > currentOffset) { + dviFile->page_offset[i] = dviFile->page_offset[i] + lengthOfNewSpecial - lengthOfOldSpecial; + command_pointer = dviFile->page_offset[i] + newDVI.data() + 4 * 10 + 1; + quint32 a = readUINT32(); + if (a > currentOffset) { + a = a + lengthOfNewSpecial - lengthOfOldSpecial; + command_pointer = dviFile->page_offset[i] + newDVI.data() + 4 * 10 + 1; + writeUINT32(a); + } + } + } + + dviFile->beginning_of_postamble = dviFile->beginning_of_postamble + lengthOfNewSpecial - lengthOfOldSpecial; + dviFile->page_offset[int(dviFile->total_pages)] = dviFile->beginning_of_postamble; + + command_pointer = newDVI.data() + dviFile->beginning_of_postamble + 1; + quint32 a = readUINT32(); + if (a > currentOffset) { + a = a + lengthOfNewSpecial - lengthOfOldSpecial; + command_pointer = newDVI.data() + dviFile->beginning_of_postamble + 1; + writeUINT32(a); + } + + command_pointer = newDVI.data() + dviFile->size_of_file - 1; + while ((*command_pointer == TRAILER) && (command_pointer > newDVI.data())) + command_pointer--; + command_pointer -= 4; + writeUINT32(dviFile->beginning_of_postamble); + command_pointer -= 4; + + command_pointer = commandPtrSav; + end_pointer = endPtrSav; + + // Modify all pointers to point to the newly allocated memory + command_pointer = newDVI.data() + (command_pointer - dviFile->dvi_Data()) + lengthOfNewSpecial - lengthOfOldSpecial; + end_pointer = newDVI.data() + (end_pointer - dviFile->dvi_Data()) + lengthOfNewSpecial - lengthOfOldSpecial; + + dviFile->setNewData(newDVI); + + embedPS_progress->setValue(embedPS_progress->value() + 1); + qApp->processEvents(); + return; +} + +void dviRenderer::prescan_removePageSizeInfo(char *cp, quint8 *beginningOfSpecialCommand) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "dviRenderer::prescan_embedPS( cp = " << cp << " ) "; +#endif + + // Encapsulated Postscript File + if (qstrnicmp(cp, "papersize=", 10) != 0) + return; + + for (quint8 *ptr = beginningOfSpecialCommand; ptr < command_pointer; ptr++) + *ptr = NOP; +} + +void dviRenderer::prescan_ParsePapersizeSpecial(const QString &_cp) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "Papersize-Special : papersize" << _cp; +#endif + + QString cp = _cp.simplified(); + + if (cp[0] == QLatin1Char('=')) { + cp = cp.mid(1); + dviFile->suggestedPageSize = new pageSize; + dviFile->suggestedPageSize->setPageSize(cp); + } else + printErrorMsgForSpecials(i18n("The papersize data '%1' could not be parsed.", cp)); + + return; +} + +void dviRenderer::prescan_ParseBackgroundSpecial(const QString &cp) +{ + QColor col = parseColorSpecification(cp.trimmed()); + if (col.isValid()) + for (quint16 page = current_page; page < dviFile->total_pages; page++) + PS_interface->setBackgroundColor(page, col); + return; +} + +void dviRenderer::prescan_ParseHTMLAnchorSpecial(const QString &_cp) +{ + QString cp = _cp; + cp.truncate(cp.indexOf(QLatin1Char('"'))); + Length l; + l.setLength_in_inch(currinf.data.dvi_v / (resolutionInDPI * shrinkfactor)); + anchorList[cp] = Anchor(current_page + 1, l); +} + +void dviRenderer::prescan_ParsePSHeaderSpecial(const QString &cp) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "PostScript-special, header " << cp; +#endif + + QString _file = cp; + + // If the file is not found in the current directory, use kpsewhich + // to find it. + if (!QFile::exists(_file)) { + // Otherwise, use kpsewhich to find the eps file. + KProcess proc; + proc << QStringLiteral("kpsewhich") << cp; + proc.setOutputChannelMode(KProcess::SeparateChannels); + proc.execute(); + _file = QString::fromLocal8Bit(proc.readLine().trimmed()); + } + + if (QFile::exists(_file)) + PS_interface->PostScriptHeaderString->append(QStringLiteral(" (%1) run\n").arg(_file)); +} + +void dviRenderer::prescan_ParsePSBangSpecial(const QString &cp) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "PostScript-special, literal header " << cp; +#endif + + PS_interface->PostScriptHeaderString->append(QStringLiteral(" @defspecial \n")); + PS_interface->PostScriptHeaderString->append(cp); + PS_interface->PostScriptHeaderString->append(QStringLiteral(" @fedspecial \n")); +} + +void dviRenderer::prescan_ParsePSQuoteSpecial(const QString &cp) +{ +#ifdef DEBUG_PRESCAN + qCCritical(OkularDviDebug) << "PostScript-special, literal PostScript " << cp; +#endif + + double PS_H = (currinf.data.dvi_h * 300.0) / (65536 * 1200) - 300; + double PS_V = (currinf.data.dvi_v * 300.0) / 1200 - 300; + PostScriptOutPutString->append(QStringLiteral(" %1 %2 moveto\n").arg(PS_H).arg(PS_V)); + PostScriptOutPutString->append(QStringLiteral(" @beginspecial @setspecial \n")); + PostScriptOutPutString->append(cp); + PostScriptOutPutString->append(QStringLiteral(" @endspecial \n")); +} + +void dviRenderer::prescan_ParsePSSpecial(const QString &cp) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "PostScript-special, direct PostScript " << cp; +#endif + + // Unfortunately, in some TeX distribution the hyperref package uses + // the dvips driver by default, rather than the hypertex driver. As + // a result, the DVI files produced are full of PostScript that + // specifies links and anchors, and KDVI would call the ghostscript + // interpreter for every page which makes it really slow. This is a + // major nuisance, so that we try to filter and interpret the + // hypertex generated PostScript here. + if (cp.startsWith(QLatin1String("ps:SDict begin"))) { + // We suspect this may be hyperref generated nonsense. Let's check + // for some known code that hyperref generates. + if (cp == QLatin1String("ps:SDict begin H.S end")) + return; // start of hyperref rectangle + if (cp == QLatin1String("ps:SDict begin H.R end")) + return; // end of hyperref rectangle + if (cp.endsWith(QLatin1String("H.A end"))) + return; // end of hyperref anchor + if (cp.endsWith(QLatin1String("H.L end"))) + return; // end of hyperref link + if (cp.startsWith(QLatin1String("ps:SDict begin /product where{pop product(Distiller)"))) + return; // hyperref tries to work around Distiller bug + if (cp.startsWith(QLatin1String("ps:SDict begin [")) && cp.endsWith(QLatin1String(" pdfmark end"))) { // hyperref definition of link/anchor/bookmark/etc + if (cp.contains(QStringLiteral("/DEST"))) { // The PostScript code defines an anchor + QString anchorName = cp.section(QLatin1Char('('), 1, 1).section(QLatin1Char(')'), 0, 0); + Length l; + l.setLength_in_inch(currinf.data.dvi_v / (resolutionInDPI * shrinkfactor)); + anchorList[anchorName] = Anchor(current_page + 1, l); + } + // The PostScript code defines a bookmark + if (cp.contains(QStringLiteral("/Dest")) && cp.contains(QStringLiteral("/Title"))) { + const QString childrenNumberAndMoreStuff = cp.section(QLatin1Char('-'), 1, 1); // Contains from the - symbol to the end of cp, effectively containing the number of children and some stuff after it + int indexOfFirstNonDigit = 0; + for (const QChar &c : childrenNumberAndMoreStuff) { + if (c.isDigit()) + ++indexOfFirstNonDigit; + else + break; + } + prebookmarks.append(PreBookmark(PDFencodingToQString(cp.section(QLatin1Char('('), 2, 2).section(QLatin1Char(')'), 0, 0)), + cp.section(QLatin1Char('('), 1, 1).section(QLatin1Char(')'), 0, 0), + childrenNumberAndMoreStuff.leftRef(indexOfFirstNonDigit).toUInt())); + } + return; + } + } + + double PS_H = (currinf.data.dvi_h * 300.0) / (65536 * 1200) - 300; + double PS_V = (currinf.data.dvi_v * 300.0) / 1200 - 300; + + if (cp.indexOf(QStringLiteral("ps::[begin]"), 0, Qt::CaseInsensitive) == 0) { + PostScriptOutPutString->append(QStringLiteral(" %1 %2 moveto\n").arg(PS_H).arg(PS_V)); + PostScriptOutPutString->append(QStringLiteral(" %1\n").arg(cp.mid(11))); + } else { + if (cp.indexOf(QStringLiteral("ps::[end]"), 0, Qt::CaseInsensitive) == 0) { + PostScriptOutPutString->append(QStringLiteral(" %1\n").arg(cp.mid(9))); + } else { + if (cp.indexOf(QStringLiteral("ps::"), 0, Qt::CaseInsensitive) == 0) { + PostScriptOutPutString->append(QStringLiteral(" %1\n").arg(cp.mid(4))); + } else { + PostScriptOutPutString->append(QStringLiteral(" %1 %2 moveto\n").arg(PS_H).arg(PS_V)); + PostScriptOutPutString->append(QStringLiteral(" %1\n").arg(cp.mid(3))); + } + } + } +} + +void dviRenderer::prescan_ParsePSFileSpecial(const QString &cp) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "epsf-special: psfile=" << cp; +#endif + + QString include_command = cp.simplified(); + + // The line is supposed to start with "..ile=", and then comes the + // filename. Figure out what the filename is and stow it away. Of + // course, this does not work if the filename contains spaces + // (already the simplified() above is wrong). If you have + // files like this, go away. + QString EPSfilename = include_command; + EPSfilename.truncate(EPSfilename.indexOf(QLatin1Char(' '))); + + // Strip enclosing quotation marks which are included by some LaTeX + // macro packages (but not by others). This probably means that + // graphic files are no longer found if the filename really does + // contain quotes, but we don't really care that much. + if ((EPSfilename.at(0) == QLatin1Char('\"')) && (EPSfilename.at(EPSfilename.length() - 1) == QLatin1Char('\"'))) { + EPSfilename = EPSfilename.mid(1, EPSfilename.length() - 2); + } + + // If the file name ends in 'png', 'gif', 'jpg' or 'jpeg', we assume + // that this is NOT a PostScript file, and we exit here. + QString ending = EPSfilename.section(QLatin1Char('.'), -1).toLower(); + if ((ending == QLatin1String("png")) || (ending == QLatin1String("gif")) || (ending == QLatin1String("jpg")) || (ending == QLatin1String("jpeg"))) { + dviFile->numberOfExternalNONPSFiles++; + return; + } + + // Now assume that the graphics file *is* a PostScript file + dviFile->numberOfExternalPSFiles++; + + // Now locate the Gfx file on the hard disk... + EPSfilename = ghostscript_interface::locateEPSfile(EPSfilename, baseURL); + + // If the EPSfilename really points to a PDF file, convert that file now. + if (ending == QLatin1String("pdf")) { + QString convErrorMsg; + EPSfilename = dviFile->convertPDFtoPS(EPSfilename, &convErrorMsg); + if (convErrorMsg.isEmpty() != true) { + emit error(convErrorMsg, -1); + return; + } + } + + // Now parse the arguments. + int llx = 0; + int lly = 0; + int urx = 0; + int ury = 0; + int rwi = 0; + int rhi = 0; + int angle = 0; + + // just to avoid ambiguities; the filename could contain keywords + include_command = include_command.mid(include_command.indexOf(QLatin1Char(' '))); + + parse_special_argument(include_command, "llx=", &llx); + parse_special_argument(include_command, "lly=", &lly); + parse_special_argument(include_command, "urx=", &urx); + parse_special_argument(include_command, "ury=", &ury); + parse_special_argument(include_command, "rwi=", &rwi); + parse_special_argument(include_command, "rhi=", &rhi); + parse_special_argument(include_command, "angle=", &angle); + + int clip = include_command.indexOf(QStringLiteral(" clip")); // -1 if clip keyword is not present, >= 0 otherwise + + if (QFile::exists(EPSfilename)) { + double PS_H = (currinf.data.dvi_h * 300.0) / (65536 * 1200) - 300; + double PS_V = (currinf.data.dvi_v * 300.0) / 1200 - 300; + PostScriptOutPutString->append(QStringLiteral(" %1 %2 moveto\n").arg(PS_H).arg(PS_V)); + PostScriptOutPutString->append(QStringLiteral("@beginspecial ")); + PostScriptOutPutString->append(QStringLiteral(" %1 @llx").arg(llx)); + PostScriptOutPutString->append(QStringLiteral(" %1 @lly").arg(lly)); + PostScriptOutPutString->append(QStringLiteral(" %1 @urx").arg(urx)); + PostScriptOutPutString->append(QStringLiteral(" %1 @ury").arg(ury)); + if (rwi != 0) + PostScriptOutPutString->append(QStringLiteral(" %1 @rwi").arg(rwi)); + if (rhi != 0) + PostScriptOutPutString->append(QStringLiteral(" %1 @rhi").arg(rhi)); + if (angle != 0) + PostScriptOutPutString->append(QStringLiteral(" %1 @angle").arg(angle)); + if (clip != -1) + PostScriptOutPutString->append(QStringLiteral(" @clip")); + PostScriptOutPutString->append(QStringLiteral(" @setspecial \n")); + PostScriptOutPutString->append(QStringLiteral(" (%1) run\n").arg(EPSfilename)); + PostScriptOutPutString->append(QStringLiteral("@endspecial \n")); + } + + return; +} + +void dviRenderer::prescan_ParseSourceSpecial(const QString &cp) +{ + // if no rendering takes place, i.e. when the DVI file is first + // loaded, generate a DVI_SourceFileAnchor. These anchors are used + // in forward search, i.e. to relate references line + // "src:123file.tex" to positions in the DVI file + + // extract the file name and the numeral part from the string + qint32 j; + for (j = 0; j < cp.length(); j++) + if (!cp.at(j).isNumber()) + break; + quint32 sourceLineNumber = cp.leftRef(j).toUInt(); + QFileInfo fi1(dviFile->filename); + QString sourceFileName = QFileInfo(fi1.dir(), cp.mid(j).trimmed()).absoluteFilePath(); + Length l; + l.setLength_in_inch(currinf.data.dvi_v / (resolutionInDPI * shrinkfactor)); + DVI_SourceFileAnchor sfa(sourceFileName, sourceLineNumber, current_page + 1, l); + sourceHyperLinkAnchors.push_back(sfa); +} + +void dviRenderer::prescan_parseSpecials(char *cp, quint8 *) +{ + QString special_command = QString::fromUtf8(cp); + + // Now to those specials which are only interpreted during the + // prescan phase, and NOT during rendering. + + // PaperSize special + if (qstrnicmp(cp, "papersize", 9) == 0) { + prescan_ParsePapersizeSpecial(special_command.mid(9)); + return; + } + + // color special for background color + if (qstrnicmp(cp, "background", 10) == 0) { + prescan_ParseBackgroundSpecial(special_command.mid(10)); + return; + } + + // HTML anchor special + if (qstrnicmp(cp, "html:", 9) == 0) { + html_anchor_end(); + return; + } + + return; +} + +void dviRenderer::prescan_setChar(unsigned int ch) +{ + TeXFontDefinition *fontp = currinf.fontp; + if (fontp == nullptr) + return; + + if (currinf.set_char_p == &dviRenderer::set_char) { + glyph *g = ((TeXFont *)(currinf.fontp->font))->getGlyph(ch, true, globalColor); + if (g == nullptr) + return; + currinf.data.dvi_h += (int)(currinf.fontp->scaled_size_in_DVI_units * dviFile->getCmPerDVIunit() * (1200.0 / 2.54) / 16.0 * g->dvi_advance_in_units_of_design_size_by_2e20 + 0.5); + return; + } + + if (currinf.set_char_p == &dviRenderer::set_vf_char) { + macro *m = &currinf.fontp->macrotable[ch]; + if (m->pos == nullptr) + return; + currinf.data.dvi_h += (int)(currinf.fontp->scaled_size_in_DVI_units * dviFile->getCmPerDVIunit() * (1200.0 / 2.54) / 16.0 * m->dvi_advance_in_units_of_design_size_by_2e20 + 0.5); + return; + } +} + +void dviRenderer::prescan(parseSpecials specialParser) +{ +#ifdef DEBUG_PRESCAN + qCDebug(OkularDviDebug) << "dviRenderer::prescan( ... )"; +#endif + + if (resolutionInDPI == 0.0) + setResolution(100); + + qint32 RRtmp = 0, WWtmp = 0, XXtmp = 0, YYtmp = 0, ZZtmp = 0; + quint8 ch; + double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0 / 2.54; + + stack.clear(); + + currinf.fontp = nullptr; + currinf.set_char_p = &dviRenderer::set_no_char; + + for (;;) { + ch = readUINT8(); + + if (ch <= (unsigned char)(SETCHAR0 + 127)) { + prescan_setChar(ch); + continue; + } + + if (FNTNUM0 <= ch && ch <= (unsigned char)(FNTNUM0 + 63)) { + currinf.fontp = currinf.fonttable->value(ch - FNTNUM0); + if (currinf.fontp == nullptr) { + errorMsg = i18n("The DVI code referred to font #%1, which was not previously defined.", ch - FNTNUM0); + return; + } + currinf.set_char_p = currinf.fontp->set_char_p; + continue; + } + + qint32 a, b; + + switch (ch) { + case SET1: + prescan_setChar(readUINT8()); + break; + + case SETRULE: + /* Be careful, dvicopy outputs rules with height = + 0x80000000. We don't want any SIGFPE here. */ + a = readUINT32(); + b = readUINT32(); + b = ((long)(b * 65536.0 * fontPixelPerDVIunit)); + currinf.data.dvi_h += b; + break; + + case PUTRULE: + a = readUINT32(); + b = readUINT32(); + break; + + case PUT1: + case NOP: + break; + + case BOP: + command_pointer += 11 * 4; + currinf.data.dvi_h = 1200 << 16; // Reminder: DVI-coordinates start at (1",1") from top of page + currinf.data.dvi_v = 1200; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + currinf.data.w = currinf.data.x = currinf.data.y = currinf.data.z = 0; + break; + + case PUSH: + stack.push(currinf.data); + break; + + case POP: + if (stack.isEmpty()) + return; + else + currinf.data = stack.pop(); + break; + + case RIGHT1: + case RIGHT2: + case RIGHT3: + case RIGHT4: + RRtmp = readINT(ch - RIGHT1 + 1); + currinf.data.dvi_h += ((long)(RRtmp * 65536.0 * fontPixelPerDVIunit)); + break; + + case W1: + case W2: + case W3: + case W4: + WWtmp = readINT(ch - W0); + currinf.data.w = ((long)(WWtmp * 65536.0 * fontPixelPerDVIunit)); + // fallthrough + case W0: + currinf.data.dvi_h += currinf.data.w; + break; + + case X1: + case X2: + case X3: + case X4: + XXtmp = readINT(ch - X0); + currinf.data.x = ((long)(XXtmp * 65536.0 * fontPixelPerDVIunit)); + // fallthrough + case X0: + currinf.data.dvi_h += currinf.data.x; + break; + + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: { + qint32 DDtmp = readINT(ch - DOWN1 + 1); + currinf.data.dvi_v += ((long)(DDtmp * 65536.0 * fontPixelPerDVIunit)) / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + } break; + + case Y1: + case Y2: + case Y3: + case Y4: + YYtmp = readINT(ch - Y0); + currinf.data.y = ((long)(YYtmp * 65536.0 * fontPixelPerDVIunit)); + // fallthrough + case Y0: + currinf.data.dvi_v += currinf.data.y / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + break; + + case Z1: + case Z2: + case Z3: + case Z4: + ZZtmp = readINT(ch - Z0); + currinf.data.z = ((long)(ZZtmp * 65536.0 * fontPixelPerDVIunit)); + // fallthrough + case Z0: + currinf.data.dvi_v += currinf.data.z / 65536; + currinf.data.pxl_v = int(currinf.data.dvi_v / shrinkfactor); + break; + + case FNT1: + case FNT2: + case FNT3: + case FNT4: + currinf.fontp = currinf.fonttable->value(readUINT(ch - FNT1 + 1)); + if (currinf.fontp == nullptr) + return; + currinf.set_char_p = currinf.fontp->set_char_p; + break; + + case XXX1: + case XXX2: + case XXX3: + case XXX4: { + quint8 *beginningOfSpecialCommand = command_pointer - 1; + a = readUINT(ch - XXX1 + 1); + if (a > 0) { + char *cmd = new char[a + 1]; + strncpy(cmd, (char *)command_pointer, a); + command_pointer += a; + cmd[a] = '\0'; + (this->*specialParser)(cmd, beginningOfSpecialCommand); + delete[] cmd; + } + } break; + + case FNTDEF1: + case FNTDEF2: + case FNTDEF3: + case FNTDEF4: + command_pointer += 12 + ch - FNTDEF1 + 1; + command_pointer += readUINT8() + readUINT8(); + break; + + default: + return; + } /* end switch */ + } /* end for */ +} diff --git a/generators/dvi/dviexport.cpp b/generators/dvi/dviexport.cpp new file mode 100644 index 0000000..b038cc7 --- /dev/null +++ b/generators/dvi/dviexport.cpp @@ -0,0 +1,292 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/** + * \file dviexport.h + * Distributed under the GNU GPL version 2 or (at your option) + * any later version. See accompanying file COPYING or copy at + * http://www.gnu.org/copyleft/gpl.html + * + * \author Angus Leeming + * \author Stefan Kebekus + * + * Classes DVIExportToPDF and DVIExportToPS control the export + * of a DVI file to PDF or PostScript format, respectively. + * Common functionality is factored out into a common base class, + * DVIExport which itself derives from QSharedData allowing easy, + * polymorphic storage of multiple QExplicitlySharedDataPointer variables + * in a container of all exported processes. + */ + +#include +#include + +#include "dviexport.h" + +#include "debug_dvi.h" +#include "dviFile.h" +#include "dviRenderer.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +DVIExport::DVIExport(dviRenderer &parent) + : started_(false) + , process_(nullptr) + , parent_(&parent) +{ + connect(this, &DVIExport::error, &parent, &dviRenderer::error); +} + +DVIExport::~DVIExport() +{ + delete process_; +} + +void DVIExport::start(const QString &command, const QStringList &args, const QString &working_directory, const QString &error_message) +{ + assert(!process_); + + process_ = new KProcess; + process_->setOutputChannelMode(KProcess::MergedChannels); + process_->setNextOpenMode(QIODevice::Text); + connect(process_, &KProcess::readyReadStandardOutput, this, &DVIExport::output_receiver); + connect(process_, QOverload::of(&KProcess::finished), this, &DVIExport::finished); + + *process_ << command << args; + + if (!working_directory.isEmpty()) + process_->setWorkingDirectory(working_directory); + + error_message_ = error_message; + + process_->start(); + if (!process_->waitForStarted(-1)) + qCCritical(OkularDviDebug) << command << " failed to start" << endl; + else + started_ = true; + + if (parent_->m_eventLoop) + parent_->m_eventLoop->exec(); +} + +void DVIExport::abort_process_impl() +{ + // deleting process_ kills the external process itself + // if it's still running. + delete process_; + process_ = nullptr; +} + +void DVIExport::finished_impl(int exit_code) +{ + if (process_ && exit_code != 0) + emit error(error_message_, -1); + // Remove this from the store of all export processes. + parent_->m_eventLoop->exit(exit_code); + parent_->export_finished(this); +} + +void DVIExport::output_receiver() +{ + if (process_) { + process_->readAllStandardOutput(); + } +} + +DVIExportToPDF::DVIExportToPDF(dviRenderer &parent, const QString &output_name) + : DVIExport(parent) +{ + // Neither of these should happen. Paranoia checks. + if (!parent.dviFile) + return; + const dvifile &dvi = *(parent.dviFile); + + const QFileInfo input(dvi.filename); + if (!input.exists() || !input.isReadable()) + return; + + if (QStandardPaths::findExecutable(QStringLiteral("dvipdfm")).isEmpty()) { + emit error(i18n("

Okular could not locate the program dvipdfm on your computer. This program is " + "essential for the export function to work. You can, however, convert " + "the DVI-file to PDF using the print function of Okular, but that will often " + "produce documents which print okay, but are of inferior quality if viewed in " + "Acrobat Reader. It may be wise to upgrade to a more recent version of your " + "TeX distribution which includes the dvipdfm program.

" + "

Hint to the perplexed system administrator: Okular uses the PATH environment variable " + "when looking for programs.

"), + -1); + return; + } + + if (output_name.isEmpty()) + return; + + start(QStringLiteral("dvipdfm"), + QStringList() << QStringLiteral("-o") << output_name << dvi.filename, + QFileInfo(dvi.filename).absolutePath(), + i18n("The external program 'dvipdfm', which was used to export the file, reported an error. " + "You might wish to look at the document info dialog which you will " + "find in the File-Menu for a precise error report.")); +} + +DVIExportToPS::DVIExportToPS(dviRenderer &parent, const QString &output_name, const QStringList &options, QPrinter *printer, bool useFontHinting, QPrinter::Orientation orientation) + : DVIExport(parent) + , printer_(printer) + , orientation_(orientation) +{ + // None of these should happen. Paranoia checks. + if (!parent.dviFile) + return; + const dvifile &dvi = *(parent.dviFile); + + const QFileInfo input(dvi.filename); + if (!input.exists() || !input.isReadable()) + return; + + if (dvi.page_offset.isEmpty()) + return; + + if (dvi.numberOfExternalNONPSFiles != 0) { + emit error(i18n("This DVI file refers to external graphic files which are not in PostScript format, and cannot be handled by the " + "dvips program that Okular uses internally to print or to export to PostScript. The functionality that " + "you require is therefore unavailable in this version of Okular."), + -1); + return; + } + + if (QStandardPaths::findExecutable(QStringLiteral("dvips")).isEmpty()) { + emit error(i18n("

Okular could not locate the program dvips on your computer. " + "That program is essential for the export function to work.

" + "

Hint to the perplexed system administrator: Okular uses the PATH environment " + "variable when looking for programs.

"), + -1); + return; + } + + if (output_name.isEmpty()) + return; + + output_name_ = output_name; + + // There is a major problem with dvips, at least 5.86 and lower: the + // arguments of the option "-pp" refer to TeX-pages, not to + // sequentially numbered pages. For instance "-pp 7" may refer to 3 + // or more pages: one page "VII" in the table of contents, a page + // "7" in the text body, and any number of pages "7" in various + // appendices, indices, bibliographies, and so forth. KDVI currently + // uses the following disgusting workaround: if the "options" + // variable is used, the DVI-file is copied to a temporary file, and + // all the page numbers are changed into a sequential ordering + // (using UNIX files, and taking manually care of CPU byte + // ordering). Finally, dvips is then called with the new file, and + // the file is afterwards deleted. Isn't that great? + + // A similar problem occurs with DVI files that contain page size + // information. On these files, dvips pointblank refuses to change + // the page orientation or set another page size. Thus, if the + // DVI-file does contain page size information, we remove that + // information first. + + // input_name is the name of the DVI which is used by dvips, either + // the original file, or a temporary file with a new numbering. + QString input_name = dvi.filename; + if (!options.isEmpty() || dvi.suggestedPageSize != nullptr) { + // Get a name for a temporary file. + // Must open the QTemporaryFile to access the name. + QTemporaryFile tmpfile; + tmpfile.setAutoRemove(false); + tmpfile.open(); + tmpfile_name_ = tmpfile.fileName(); + tmpfile.close(); + + input_name = tmpfile_name_; + + fontPool fp(useFontHinting); + dvifile newFile(&dvi, &fp); + + // Renumber pages + newFile.renumber(); + + const quint16 saved_current_page = parent.current_page; + dvifile *saved_dvi = parent.dviFile; + parent.dviFile = &newFile; + parent.errorMsg = QString(); + + // Remove any page size information from the file + for (parent.current_page = 0; parent.current_page < newFile.total_pages; parent.current_page++) { + if (parent.current_page < newFile.total_pages) { + parent.command_pointer = newFile.dvi_Data() + parent.dviFile->page_offset[int(parent.current_page)]; + parent.end_pointer = newFile.dvi_Data() + parent.dviFile->page_offset[int(parent.current_page + 1)]; + } else { + parent.command_pointer = nullptr; + parent.end_pointer = nullptr; + } + + memset((char *)&parent.currinf.data, 0, sizeof(parent.currinf.data)); + parent.currinf.fonttable = &(parent.dviFile->tn_table); + parent.currinf._virtual = nullptr; + parent.prescan(&dviRenderer::prescan_removePageSizeInfo); + } + + parent.current_page = saved_current_page; + parent.dviFile = saved_dvi; + newFile.saveAs(input_name); + } + + QStringList args; + if (!printer) + // Export hyperlinks + args << QStringLiteral("-z"); + + if (!options.isEmpty()) + args += options; + + args << input_name << QStringLiteral("-o") << output_name_; + + start(QStringLiteral("dvips"), + args, + QFileInfo(dvi.filename).absolutePath(), + i18n("The external program 'dvips', which was used to export the file, reported an error. " + "You might wish to look at the document info dialog which you will " + "find in the File-Menu for a precise error report.")); +} + +void DVIExportToPS::finished_impl(int exit_code) +{ + if (printer_ && !output_name_.isEmpty()) { + const QFileInfo output(output_name_); + if (output.exists() && output.isReadable()) { + // I'm not 100% sure on this, think we still need to select pages in export to ps above + Okular::FilePrinter::printFile((*printer_), output_name_, orientation_, Okular::FilePrinter::ApplicationDeletesFiles, Okular::FilePrinter::ApplicationSelectsPages, QString()); + } + } + + if (!tmpfile_name_.isEmpty()) { + // Delete the file. + QFile(tmpfile_name_).remove(); + tmpfile_name_.clear(); + } + + DVIExport::finished_impl(exit_code); +} + +void DVIExportToPS::abort_process_impl() +{ + if (!tmpfile_name_.isEmpty()) { + // Delete the file. + QFile(tmpfile_name_).remove(); + tmpfile_name_.clear(); + } + + printer_ = nullptr; + + DVIExport::abort_process_impl(); +} diff --git a/generators/dvi/dviexport.h b/generators/dvi/dviexport.h new file mode 100644 index 0000000..e52dcfd --- /dev/null +++ b/generators/dvi/dviexport.h @@ -0,0 +1,138 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/** + * \file dviexport.h + * Distributed under the GNU GPL version 2 or (at your option) + * any later version. See accompanying file COPYING or copy at + * http://www.gnu.org/copyleft/gpl.html + * + * \author Angus Leeming + * \author Stefan Kebekus + * + * Classes DVIExportToPDF and DVIExportToPS control the export + * of a DVI file to PDF or PostScript format, respectively. + * Common functionality is factored out into a common base class, + * DVIExport which itself derives from QSharedData allowing easy, + * polymorphic storage of multiple QExplicitlySharedDataPointer variables + * in a container of all exported processes. + */ + +#ifndef DVIEXPORT_H +#define DVIEXPORT_H + +#include + +#include +#include + +class dviRenderer; +class KProcess; +class QStringList; + +class DVIExport : public QObject, public QSharedData +{ + Q_OBJECT +public: + ~DVIExport() override; + + /** @c started() Flags whether or not the external process was + * spawned successfully. + * Can be used to decide whether to discard the DVIExport variable, + * or to store it and await notification that the external process + * has finished. + */ + bool started() const + { + return started_; + } + +Q_SIGNALS: + void error(const QString &message, int duration); + +protected: + /** @param parent is stored internally in order to inform the parent + * that the external process has finished and that this variable + * can be removed from any stores. + */ + DVIExport(dviRenderer &parent); + + /** Spawns the external process having connected slots to the child + * process's stdin and stdout streams. + */ + void start(const QString &command, const QStringList &args, const QString &working_directory, const QString &error_message); + + /** The real implementation of the abort_process() slot that is + * called when the fontProcessDialog is closed by the user, + * indicating that the export should be halted. + */ + virtual void abort_process_impl(); + + /** The real implementation of the finished() slot that is called + * when the external process finishes. + * @param exit_code the exit code returned by the external process. + */ + virtual void finished_impl(int exit_code); + +private Q_SLOTS: + /// Calls an impl() inline so that derived classes don't need slots. + void abort_process() + { + abort_process_impl(); + } + void finished(int exit_code) + { + finished_impl(exit_code); + } + + /** This slot receives all output from the child process's stdin + * and stdout streams. + */ + void output_receiver(); + +private: + QString error_message_; + bool started_; + KProcess *process_; + dviRenderer *parent_; +}; + +class DVIExportToPDF : public DVIExport +{ + Q_OBJECT + +public: + /** @param parent is stored internally in order to inform the parent + * that the external process has finished. + * @param output_name is the name of the PDF file that is + * to contain the exported data. */ + DVIExportToPDF(dviRenderer &parent, const QString &output_name); +}; + +class DVIExportToPS : public DVIExport +{ + Q_OBJECT + +public: + /** @param parent is stored internally in order to inform the parent + * that the external process has finished. + * @param output_name is the name of the PostScript file that is + * to contain the exported data. + * @param options extra command line arguments that are to be + * passed to the external process's argv command line. + * @param printer having generated the PostScript file, it is passed + * to @c printer (if not null). + * @param useFontHinting boolean that defines whether to use font hinting. + * @param orientation the original orientation of the document + */ + DVIExportToPS(dviRenderer &parent, const QString &output_name, const QStringList &options, QPrinter *printer, bool useFontHinting, QPrinter::Orientation orientation = QPrinter::Portrait); + +private: + void abort_process_impl() override; + void finished_impl(int exit_code) override; + + QPrinter *printer_; + QString output_name_; + QString tmpfile_name_; + QPrinter::Orientation orientation_; +}; + +#endif diff --git a/generators/dvi/dvisourcesplitter.cpp b/generators/dvi/dvisourcesplitter.cpp new file mode 100644 index 0000000..c68433f --- /dev/null +++ b/generators/dvi/dvisourcesplitter.cpp @@ -0,0 +1,104 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// C++ Implementation: dvisourcesplitter +// +// Author: Jeroen Wijnhout , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// + +#include + +#include "debug_dvi.h" +#include "dvisourcesplitter.h" + +#include + +//#define DEBUG_SOURCESPLITTER + +DVI_SourceFileSplitter::DVI_SourceFileSplitter(const QString &srclink, const QString &dviFile) +{ + QString filepart = srclink, linepart; + // if sourcefilename starts with a number + // then there could be a mix up, i.e. src:123file.tex + // line 123 and file.tex or line 12 and 3file.tex? + bool possibleNumberMixUp = false; + +#ifdef DEBUG_SOURCESPLITTER + qCDebug(OkularDviDebug) << "DVI_SourceSplitter: srclink " << srclink; +#endif + + // remove src: if necessary + if (filepart.left(4) == QLatin1String("src:")) + filepart = srclink.mid(4); + + // split first + quint32 max = filepart.length(), i = 0; + for (i = 0; i < max; ++i) + if (!filepart[i].isDigit()) + break; + linepart = filepart.left(i); + filepart = filepart.mid(i); + + // check for number mix up + if (filepart[0] != QLatin1Char(' ') && (linepart.length() != 1)) + possibleNumberMixUp = true; + + // remove a spaces + filepart = filepart.trimmed(); + linepart = linepart.trimmed(); + +#ifdef DEBUG_SOURCESPLITTER + qCDebug(OkularDviDebug) << "DVI_SourceSplitter: filepart " << filepart << " linepart " << linepart; +#endif + + // test if the file exists + m_fileInfo.setFile(QFileInfo(dviFile).absoluteDir(), filepart); + bool fiExists = m_fileInfo.exists(); + + // if it doesn't exist, but adding ".tex" + if (!fiExists && QFileInfo::exists(m_fileInfo.absoluteFilePath() + QStringLiteral(".tex"))) + m_fileInfo.setFile(m_fileInfo.absoluteFilePath() + QStringLiteral(".tex")); + + // if that doesn't help either, perhaps the file started with a + // number: move the numbers from the sourceline to the filename + // one by one (also try to add .tex repeatedly) + if (possibleNumberMixUp && !fiExists) { + QFileInfo tempInfo(m_fileInfo); + QString tempFileName = tempInfo.fileName(); + quint32 index, maxindex = linepart.length(); + bool found = false; + for (index = 1; index < maxindex; ++index) { + tempInfo.setFile(linepart.right(index) + tempFileName); +#ifdef DEBUG_SOURCESPLITTER + qCDebug(OkularDviDebug) << "DVI_SourceSplitter: trying " << tempInfo.fileName(); +#endif + if (tempInfo.exists()) { + found = true; + break; + } + tempInfo.setFile(linepart.right(index) + tempFileName + QStringLiteral(".tex")); +#ifdef DEBUG_SOURCESPLITTER + qCDebug(OkularDviDebug) << "DVI_SourceSplitter: trying " << tempInfo.fileName(); +#endif + if (tempInfo.exists()) { + found = true; + break; + } + } + + if (found) { + m_fileInfo = tempInfo; + linepart = linepart.left(maxindex - index); + } + } + + bool ok; + m_line = linepart.toInt(&ok); + if (!ok) + m_line = 0; + +#ifdef DEBUG_SOURCESPLITTER + qCDebug(OkularDviDebug) << "DVI_SourceSplitter: result: file " << m_fileInfo.absoluteFilePath() << " line " << m_line; +#endif +} diff --git a/generators/dvi/dvisourcesplitter.h b/generators/dvi/dvisourcesplitter.h new file mode 100644 index 0000000..266dca5 --- /dev/null +++ b/generators/dvi/dvisourcesplitter.h @@ -0,0 +1,43 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// C++ Interface: dvisourcesplitter +// +// Author: Jeroen Wijnhout , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// + +#ifndef DVI_SOURCEFILESPLITTER_H +#define DVI_SOURCEFILESPLITTER_H + +#include + +class QString; + +class DVI_SourceFileSplitter +{ +public: + DVI_SourceFileSplitter(const QString &srclink, const QString &dviFile); + + QString fileName() const + { + return m_fileInfo.fileName(); + } + QString filePath() const + { + return m_fileInfo.absoluteFilePath(); + } + bool fileExists() const + { + return m_fileInfo.exists(); + } + quint32 line() const + { + return m_line; + } + +private: + QFileInfo m_fileInfo; + quint32 m_line; +}; +#endif diff --git a/generators/dvi/fontEncoding.cpp b/generators/dvi/fontEncoding.cpp new file mode 100644 index 0000000..00631b3 --- /dev/null +++ b/generators/dvi/fontEncoding.cpp @@ -0,0 +1,93 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontEncoding.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#ifdef HAVE_FREETYPE + +#include "debug_dvi.h" +#include "fontEncoding.h" + +#include +#include +#include +#include + +//#define DEBUG_FONTENC + +fontEncoding::fontEncoding(const QString &encName) +{ +#ifdef DEBUG_FONTENC + qCDebug(OkularDviDebug) << "fontEncoding( " << encName << " )"; +#endif + + _isValid = false; + // Use kpsewhich to find the encoding file. + QProcess kpsewhich; + kpsewhich.setProcessChannelMode(QProcess::MergedChannels); + + kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << encName, QIODevice::ReadOnly | QIODevice::Text); + + if (!kpsewhich.waitForStarted()) { + qCCritical(OkularDviDebug) << "fontEncoding::fontEncoding(...): kpsewhich could not be started." << endl; + return; + } + + // We wait here while the external program runs concurrently. + kpsewhich.waitForFinished(-1); + + const QString encFileName = QString::fromLocal8Bit(kpsewhich.readAll()).trimmed(); + if (encFileName.isEmpty()) { + qCCritical(OkularDviDebug) << QStringLiteral("fontEncoding::fontEncoding(...): The file '%1' could not be found by kpsewhich.").arg(encName) << endl; + return; + } + +#ifdef DEBUG_FONTENC + qCDebug(OkularDviDebug) << "FileName of the encoding: " << encFileName; +#endif + + QFile file(encFileName); + if (file.open(QIODevice::ReadOnly)) { + // Read the file (excluding comments) into the QString variable + // 'fileContent' + QTextStream stream(&file); + QString fileContent; + while (!stream.atEnd()) + fileContent += stream.readLine().section(QLatin1Char('%'), 0, 0); // line of text excluding '\n' until first '%'-sign + file.close(); + + fileContent = fileContent.trimmed(); + + // Find the name of the encoding + encodingFullName = fileContent.section(QLatin1Char('['), 0, 0).simplified().mid(1); +#ifdef DEBUG_FONTENC + qCDebug(OkularDviDebug) << "encodingFullName: " << encodingFullName; +#endif + + fileContent = fileContent.section(QLatin1Char('['), 1, 1).section(QLatin1Char(']'), 0, 0).simplified(); + const QStringList glyphNameList = fileContent.split(QLatin1Char('/'), QString::SkipEmptyParts); + + int i = 0; + for (QStringList::ConstIterator it = glyphNameList.constBegin(); (it != glyphNameList.constEnd()) && (i < 256); ++it) { + glyphNameVector[i] = (*it).simplified(); +#ifdef DEBUG_FONTENC + qCDebug(OkularDviDebug) << i << ": " << glyphNameVector[i]; +#endif + i++; + } + for (; i < 256; i++) + glyphNameVector[i] = QStringLiteral(".notdef"); + } else { + qCCritical(OkularDviDebug) << QStringLiteral("fontEncoding::fontEncoding(...): The file '%1' could not be opened.").arg(encFileName) << endl; + return; + } + + _isValid = true; +} + +#endif // HAVE_FREETYPE diff --git a/generators/dvi/fontEncoding.h b/generators/dvi/fontEncoding.h new file mode 100644 index 0000000..eee2966 --- /dev/null +++ b/generators/dvi/fontEncoding.h @@ -0,0 +1,89 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontEncoding.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#ifndef _FONTENCODING_H +#define _FONTENCODING_H + +#include + +/** + * This class represents the contents of a font encoding file, + * e.g. "8r.enc" + * + * Explanation of font encodings: TeX was designed to only use + * MetaFont fonts. A DVI file refers to a MetaFont font by giving an + * at-most-8-character name, such as 'cmr10'. The DVI previewer would + * then locate the associated PK font file (e.g. cmr10.600pk), load + * it, and retrieve the character shaped. + * + * Today TeX is also used to access Type1 and TrueType fonts, which it + * was never designed to do. As in the case of MetaFont font, the DVI + * file specifies the name of a font, e.g. 'rpbkd', and the DVI + * previewer finds the associated font file 'ubkd8a.pfb' by means of a + * map file (see fontMap.h). The font map file also specifies an + * encoding (e.g. '8r', to be found in a file '8r.enc'). Font + * encodings are necessary because TeX can only use the first 256 + * characters of a font, while modern PostScript fonts often contain + * more. + * + * In a PostScript font, glyphs can often be accessed in two ways: + * + * (a) by an integer, the 'glyph index', which need not be + * positive. Glyph indices can be found in every font. + * + * (b) by the name of the glyph, such as 'A', 'plusminus' or + * 'ogonek'. Note: Not all fonts contain glyph names, and if a font + * contains glyph names, they are not always reliable. + * + * An encoding file is essentially a list of 256 names of glyphs that + * TeX wishes to use from a certain font. If the font contains more + * than 256 glyphs, TeX is still limited to use at most 256 glyphs. If + * more glyphs are required, TeX can probably use the same font under + * a different name and with a different encoding ---the map file + * (fontMap.h) can probably see to that. + * + * Summing up: this class contains 256 glyph names read from an + * encoding file during the construction of this class. + * + * @author Stefan Kebekus + * + **/ + +class fontEncoding +{ +public: + // The constructor takes the name of an encoding file, such as + // '8r.enc', locate the file on the hard disk using the 'kpsewhich' + // command, reads it in and parses it. If the file cannot be + // located, opened or parsed, errors are printed using the kError() + // channel, and the array glyphNameVector will contain empty + // strings. + fontEncoding(const QString &encName); + + // Full name of the encoding, as read from the encoding file + QString encodingFullName; + + // List of 256 glyph names. The name can be '.notdef' to indicate + // that a certain position is left open, or empty, if the encoding + // file did not contain 256 characters or could not be properly read + QString glyphNameVector[256]; + + // Returns 'true' if the encoding file was found and could + // successfully be loaded. + bool isValid() + { + return _isValid; + } + +private: + // Set by the constructor to 'true', if the encoding file was found + // and could be loaded successfully. + bool _isValid; +}; + +#endif diff --git a/generators/dvi/fontEncodingPool.cpp b/generators/dvi/fontEncodingPool.cpp new file mode 100644 index 0000000..41c55d8 --- /dev/null +++ b/generators/dvi/fontEncodingPool.cpp @@ -0,0 +1,41 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontEncodingPool.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#ifdef HAVE_FREETYPE + +#include "fontEncodingPool.h" + +fontEncodingPool::fontEncodingPool() +{ +} + +fontEncodingPool::~fontEncodingPool() +{ + qDeleteAll(dictionary); +} + +fontEncoding *fontEncodingPool::findByName(const QString &name) +{ + fontEncoding *ptr = dictionary.value(name); + + if (ptr == nullptr) { + ptr = new fontEncoding(name); + if (ptr->isValid()) + dictionary.insert(name, ptr); + else { + delete ptr; + ptr = nullptr; + } + } + + return ptr; +} + +#endif // HAVE_FREETYPE diff --git a/generators/dvi/fontEncodingPool.h b/generators/dvi/fontEncodingPool.h new file mode 100644 index 0000000..17ecfe1 --- /dev/null +++ b/generators/dvi/fontEncodingPool.h @@ -0,0 +1,33 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontEncodingPool.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#ifndef _FONTENCODINGPOOL_H +#define _FONTENCODINGPOOL_H + +#include "fontEncoding.h" + +#include + +class QString; + +class fontEncodingPool +{ +public: + fontEncodingPool(); + ~fontEncodingPool(); + + fontEncodingPool(const fontEncodingPool &) = delete; + fontEncodingPool &operator=(const fontEncodingPool &) = delete; + + fontEncoding *findByName(const QString &name); + +private: + QHash dictionary; +}; + +#endif diff --git a/generators/dvi/fontMap.cpp b/generators/dvi/fontMap.cpp new file mode 100644 index 0000000..7b76a08 --- /dev/null +++ b/generators/dvi/fontMap.cpp @@ -0,0 +1,161 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontMap.cpp +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#ifdef HAVE_FREETYPE + +#include "debug_dvi.h" +#include "fontMap.h" +#include +#include +#include +#include + +//#define DEBUG_FONTMAP + +fontMap::fontMap() +{ + // Read the map file of ps2pk which will provide us with a + // dictionary "TeX Font names" <-> "Name of font files, Font Names + // and Encodings" (example: the font "Times-Roman" is called + // "ptmr8y" in the DVI file, but the Type1 font file name is + // "utmr8a.pfb". We use the map file of "ps2pk" because that program + // has, like kdvi (and unlike dvips), no built-in fonts. + + // Finding ps2pk.map is not easy. In teTeX < 3.0, the kpsewhich + // program REQUIRES the option "--format=dvips config". In teTeX = + // 3.0, the option "--format=map" MUST be used. Since there is no + // way to give both options at the same time, there is seemingly no + // other way than to try both options one after another. We use the + // teTeX 3.0 format first. + QProcess kpsewhich; + kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << QStringLiteral("--format=map") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); + + if (!kpsewhich.waitForStarted()) { + qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; + return; + } + + // We wait here while the external program runs concurrently. + kpsewhich.waitForFinished(-1); + + QString map_fileName = QString::fromLocal8Bit(kpsewhich.readAll()).trimmed(); + if (map_fileName.isEmpty()) { + // Map file not found? Then we try the teTeX < 3.0 way of finding + // the file. + kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << QStringLiteral("--format=dvips config") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); + if (!kpsewhich.waitForStarted()) { + qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; + return; + } + + kpsewhich.waitForFinished(-1); + + map_fileName = QString::fromLocal8Bit(kpsewhich.readAll()).trimmed(); + // If both versions fail, then there is nothing left to do. + if (map_fileName.isEmpty()) { + qCCritical(OkularDviDebug) << "fontMap::fontMap(): The file 'ps2pk.map' could not be found by kpsewhich." << endl; + return; + } + } + + QFile file(map_fileName); + if (file.open(QIODevice::ReadOnly)) { + QTextStream stream(&file); + QString line; + while (!stream.atEnd()) { + line = stream.readLine().simplified(); + if (line.isEmpty() || (line.at(0) == QLatin1Char('%'))) + continue; + + QString TeXName = line.section(QLatin1Char(' '), 0, 0); + QString FullName = line.section(QLatin1Char(' '), 1, 1); + QString fontFileName = line.section(QLatin1Char('<'), -1).trimmed().section(QLatin1Char(' '), 0, 0); + QString encodingName = line.section(QLatin1Char('<'), -2, -2).trimmed().section(QLatin1Char(' '), 0, 0); + // It seems that sometimes the encoding is prepended by the + // letter '[', which we ignore + if ((!encodingName.isEmpty()) && (encodingName[0] == QLatin1Char('['))) + encodingName = encodingName.mid(1); + + double slant = 0.0; + int i = line.indexOf(QStringLiteral("SlantFont")); + if (i >= 0) { + bool ok; + slant = line.left(i).section(QLatin1Char(' '), -1, -1, QString::SectionSkipEmpty).toDouble(&ok); + if (ok == false) + slant = 0.0; + } + + fontMapEntry &entry = fontMapEntries[TeXName]; + + entry.slant = slant; + entry.fontFileName = fontFileName; + entry.fullFontName = FullName; + if (encodingName.endsWith(QLatin1String(".enc"))) + entry.fontEncoding = encodingName; + else + entry.fontEncoding.clear(); + } + file.close(); + } else + qCCritical(OkularDviDebug) << QStringLiteral("fontMap::fontMap(): The file '%1' could not be opened.").arg(map_fileName) << endl; + +#ifdef DEBUG_FONTMAP + qCDebug(OkularDviDebug) << "FontMap file parsed. Results:"; + QMap::Iterator it; + for (it = fontMapEntries.begin(); it != fontMapEntries.end(); ++it) + qCDebug(OkularDviDebug) << "TeXName: " << it.key() << ", FontFileName=" << it.data().fontFileName << ", FullName=" << it.data().fullFontName << ", Encoding=" << it.data().fontEncoding << "." << endl; + ; +#endif +} + +const QString &fontMap::findFileName(const QString &TeXName) +{ + QMap::Iterator it = fontMapEntries.find(TeXName); + + if (it != fontMapEntries.end()) + return it.value().fontFileName; + + static const QString nullstring; + return nullstring; +} + +const QString &fontMap::findFontName(const QString &TeXName) +{ + QMap::Iterator it = fontMapEntries.find(TeXName); + + if (it != fontMapEntries.end()) + return it.value().fullFontName; + + static const QString nullstring; + return nullstring; +} + +const QString &fontMap::findEncoding(const QString &TeXName) +{ + QMap::Iterator it = fontMapEntries.find(TeXName); + + if (it != fontMapEntries.end()) + return it.value().fontEncoding; + + static const QString nullstring; + return nullstring; +} + +double fontMap::findSlant(const QString &TeXName) +{ + QMap::Iterator it = fontMapEntries.find(TeXName); + + if (it != fontMapEntries.end()) + return it.value().slant; + else + return 0.0; +} + +#endif // HAVE_FREETYPE diff --git a/generators/dvi/fontMap.h b/generators/dvi/fontMap.h new file mode 100644 index 0000000..e2b193c --- /dev/null +++ b/generators/dvi/fontMap.h @@ -0,0 +1,119 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontMap.h +// +// Part of KDVI - A DVI previewer for the KDE desktop environment +// +// (C) 2003 Stefan Kebekus +// Distributed under the GPL + +#ifndef _FONTMAP_H +#define _FONTMAP_H + +#include +#include + +/** + * This class represents one line of a font map file, and contains + * three pieces of information about a font: its file name, the full + * name of the font, and the encoding. + * + * @author Stefan Kebekus + **/ + +class fontMapEntry +{ +public: + // File name of the font WITHOUT the path. The full path name must + // be looked by using the kpathsea library, e.g. by means of the + // kpsewhich command. A valid entry would be 'ubkd8a.pfb' + QString fontFileName; + + // This string contains the full name of the font, + // e.g. 'URWBookmanL-DemiBold' + QString fullFontName; + + // If the font requires an encoding (see fontEncoding.h for an + // explanation), this string is not empty and contains the name of + // the encoding, e.g. '8r'. The path of the associated encoding file + // (on the author's machine: /usr/share/texmf/dvips/psnfss/8r.enc) + // must be looked up using the kpsewhich command. + QString fontEncoding; + + // Some fonts need to be slanted, and the font map file defines by + // how much. This field is set to 0.0 if no slanting is specified in + // the map file. + double slant; +}; + +/** + * This class represents the contents of the font map file "ps2pk.map" + * + * A font map file is part of the machinery that make it possible to + * access PostScript (and possibly also TrueType and OpenType) fonts + * from a DVI file. + * + * Long time ago, when TeX was only used with MetaFont fonts, the DVI + * file would specify a font by giving an 8-character name, such as + * 'cmr10'. The DVI previewer would then locate the associated PK font + * file, load it, and retrieve the character shaped. Happy times, they + * were. + * + * Today TeX is also used to access Type1 and TrueType fonts, which do + * not fit well into the TeX naming scheme. Like in earlier times, the + * DVI file specifies the name of a font, e.g. 'rpbkd', but nowadays + * the DVI previewer cannot just go and find a file 'rpbkd.pk'. No, + * no. Instead, the DVI previewr needs to look up the meaning of + * 'rpbkd' in a map-file. There it finds that 'rpbkd' refers to a font + * called 'URWBookmanL-DemiBold', to be found under the file name + * 'ubkd8a.pfb' whose glyphs are to be encoded using the '8a' encoding + * file (see the header file 'fontEncoding.h' for more information + * about encodings) + * + * Such map files exists for all dvi output drivers that are part of + * the TeX distribution that is installed on your + * computer. Unfortunately, KDVI is not part of a TeX distribution, + * and therefore does not have its own map file. As a workaround, KDVI + * uses the map file of the program ps2pk which is similar to KDVI in + * that the ps2pk driver does not have built-in fonts, unlike the + * PostScript printers for which dvips is used. + * + * @author Stefan Kebekus + * + **/ + +class fontMap +{ +public: + /** The default constructor will try to locate the file 'ps2pk.map', + and read its contents. If the file 'ps2pk.map' cannot be found + using the kpsewhich command, or if it cannot be read, or is + (partially) in an improper format, an error message is printed + to stderr using the kDebug() stream. */ + fontMap(); + + /** find the name of a font file (e.g. 'ubkd8a.pfb') from a TeX font + name (e.g. 'rpbkd'). This method return a reference to + QString() if the font could not be found. */ + const QString &findFileName(const QString &TeXName); + + /** find the name of a font (e.g. 'URWBookmanL-DemiBold') from a TeX + font name (e.g. 'rpbkd'). This method return a reference to + QString() if the font could not be found. */ + const QString &findFontName(const QString &TeXName); + + /** find the name of an encoding file for a font (e.g. '8r') from a + TeX font name (e.g. 'rpbkd'). This method return a reference to + QString() if the font could not be found. */ + const QString &findEncoding(const QString &TeXName); + + /** This method finds the slant of a font. Returns 0.0 if no slant + was defined. */ + double findSlant(const QString &TeXName); + +private: + /** This member maps TeX font names mapEntry classes that contain + the font's filenames, full font names and encodings. */ + QMap fontMapEntries; +}; + +#endif // ifndef _FONTMAP_H diff --git a/generators/dvi/fontpool.cpp b/generators/dvi/fontpool.cpp new file mode 100644 index 0000000..44dbc51 --- /dev/null +++ b/generators/dvi/fontpool.cpp @@ -0,0 +1,466 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// fontpool.cpp +// +// (C) 2001-2005 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "TeXFont.h" +#include "debug_dvi.h" +#include "fontpool.h" + +#include + +#include +#include + +#include +#include + +//#define DEBUG_FONTPOOL + +// List of permissible MetaFontModes which are supported by kdvi. + +// const char *MFModes[] = { "cx", "ljfour", "lexmarks" }; +// const char *MFModenames[] = { "Canon CX", "LaserJet 4", "Lexmark S" }; +// const int MFResolutions[] = { 300, 600, 1200 }; + +#ifdef PERFORMANCE_MEASUREMENT +QTime fontPoolTimer; +bool fontPoolTimerFlag; +#endif + +fontPool::fontPool(bool useFontHinting) +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::fontPool() called"; +#endif + + setObjectName(QStringLiteral("Font Pool")); + + displayResolution_in_dpi = 100.0; // A not-too-bad-default + useFontHints = useFontHinting; + CMperDVIunit = 0; + extraSearchPath.clear(); + +#ifdef HAVE_FREETYPE + // Initialize the Freetype Library + if (FT_Init_FreeType(&FreeType_library) != 0) { + qCCritical(OkularDviDebug) << "Cannot load the FreeType library. KDVI proceeds without FreeType support." << endl; + FreeType_could_be_loaded = false; + } else + FreeType_could_be_loaded = true; +#endif + + // Check if the QT library supports the alpha channel of + // QImages. Experiments show that --depending of the configuration + // of QT at compile and runtime or the availability of the XFt + // extension, alpha channels are either supported, or silently + // ignored. + QImage start(1, 1, QImage::Format_ARGB32); // Generate a 1x1 image, black with alpha=0x10 + quint32 *destScanLine = reinterpret_cast(start.scanLine(0)); + *destScanLine = 0x80000000; + QPixmap intermediate = QPixmap::fromImage(start); + QPixmap dest(1, 1); + dest.fill(Qt::white); + QPainter paint(&dest); + paint.drawPixmap(0, 0, intermediate); + paint.end(); + start = dest.toImage().convertToFormat(QImage::Format_ARGB32); + quint8 result = *(start.scanLine(0)) & 0xff; + + if ((result == 0xff) || (result == 0x00)) { +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::fontPool(): QPixmap does not support the alpha channel"; +#endif + QPixmapSupportsAlpha = false; + } else { +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::fontPool(): QPixmap supports the alpha channel"; +#endif + QPixmapSupportsAlpha = true; + } +} + +fontPool::~fontPool() +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::~fontPool() called"; +#endif + + // need to manually clear the fonts _before_ freetype gets unloaded + qDeleteAll(fontList); + fontList.clear(); + +#ifdef HAVE_FREETYPE + if (FreeType_could_be_loaded == true) + FT_Done_FreeType(FreeType_library); +#endif +} + +void fontPool::setParameters(bool _useFontHints) +{ + // Check if glyphs need to be cleared + if (_useFontHints != useFontHints) { + double displayResolution = displayResolution_in_dpi; + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + fontp->setDisplayResolution(displayResolution * fontp->enlargement); + } + } + + useFontHints = _useFontHints; +} + +TeXFontDefinition *fontPool::appendx(const QString &fontname, quint32 checksum, quint32 scale, double enlargement) +{ + // Reuse font if possible: check if a font with that name and + // natural resolution is already in the fontpool, and use that, if + // possible. + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + if ((fontname == fontp->fontname) && ((int)(enlargement * 1000.0 + 0.5)) == (int)(fontp->enlargement * 1000.0 + 0.5)) { + // if font is already in the list + fontp->mark_as_used(); + return fontp; + } + } + + // If font doesn't exist yet, we have to generate a new font. + + double displayResolution = displayResolution_in_dpi; + + TeXFontDefinition *fontp = new TeXFontDefinition(fontname, displayResolution * enlargement, checksum, scale, this, enlargement); + if (fontp == nullptr) { + qCCritical(OkularDviDebug) << "Could not allocate memory for a font structure"; + exit(0); + } + fontList.append(fontp); + +#ifdef PERFORMANCE_MEASUREMENT + fontPoolTimer.start(); + fontPoolTimerFlag = false; +#endif + + // Now start kpsewhich/MetaFont, etc. if necessary + return fontp; +} + +bool fontPool::areFontsLocated() +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::areFontsLocated() called"; +#endif + + // Is there a font whose name we did not try to find out yet? + QList::const_iterator cit_fontp = fontList.constBegin(); + for (; cit_fontp != fontList.constEnd(); ++cit_fontp) { + TeXFontDefinition *fontp = *cit_fontp; + if (!fontp->isLocated()) + return false; + } + +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "... yes, all fonts are located (but not necessarily loaded)."; +#endif + return true; // That says that all fonts are located. +} + +void fontPool::locateFonts() +{ + kpsewhichOutput.clear(); + + // First, we try and find those fonts which exist on disk + // already. If virtual fonts are found, they will add new fonts to + // the list of fonts whose font files need to be located, so that we + // repeat the lookup. + bool vffound; + do { + vffound = false; + locateFonts(false, false, &vffound); + } while (vffound); + + // If still not all fonts are found, look again, this time with + // on-demand generation of PK fonts enabled. + if (!areFontsLocated()) + locateFonts(true, false); + + // If still not all fonts are found, we look for TFM files as a last + // resort, so that we can at least draw filled rectangles for + // characters. + if (!areFontsLocated()) + locateFonts(false, true); + + // If still not all fonts are found, we give up. We mark all fonts + // as 'located', so that we won't look for them any more, and + // present an error message to the user. + if (!areFontsLocated()) { + markFontsAsLocated(); + emit error(i18n("

Okular was not able to locate all the font files " + "which are necessary to display the current DVI file. " + "Your document might be unreadable.

" + "

PATH: %1

" + "

%2

", + QString::fromLocal8Bit(qgetenv("PATH")), + kpsewhichOutput.replace(QLatin1String("\n"), QLatin1String("
"))), + -1); + } +} + +void fontPool::locateFonts(bool makePK, bool locateTFMonly, bool *virtualFontsFound) +{ + // Set up the kpsewhich process. If pass == 0, look for vf-fonts and + // disable automatic font generation as vf-fonts can't be + // generated. If pass == 0, enable font generation, if it was + // enabled globally. + + // Now generate the command line for the kpsewhich + // program. Unfortunately, this can be rather long and involved... + QStringList kpsewhich_args; + kpsewhich_args << QStringLiteral("--dpi") << QStringLiteral("1200") << QStringLiteral("--mode") << QStringLiteral("lexmarks"); + + // Disable automatic pk-font generation. + kpsewhich_args << QString::fromLocal8Bit(makePK ? "--mktex" : "--no-mktex") << QStringLiteral("pk"); + + // Names of fonts that shall be located + quint16 numFontsInJob = 0; + QList::const_iterator cit_fontp = fontList.constBegin(); + for (; cit_fontp != fontList.constEnd(); ++cit_fontp) { + TeXFontDefinition *fontp = *cit_fontp; + if (!fontp->isLocated()) { + numFontsInJob++; + + if (locateTFMonly == true) + kpsewhich_args << QStringLiteral("%1.tfm").arg(fontp->fontname); + else { +#ifdef HAVE_FREETYPE + if (FreeType_could_be_loaded == true) { + const QString &filename = fontsByTeXName.findFileName(fontp->fontname); + if (!filename.isEmpty()) + kpsewhich_args << QStringLiteral("%1").arg(filename); + } +#endif + kpsewhich_args << QStringLiteral("%1.vf").arg(fontp->fontname) << QStringLiteral("%1.1200pk").arg(fontp->fontname); + } + } + } + + if (numFontsInJob == 0) + return; + + // If PK fonts are generated, the kpsewhich command will re-route + // the output of MetaFont into its stderr. Here we make sure this + // output is intercepted and parsed. + kpsewhich_ = new QProcess(); + connect(kpsewhich_, &QProcess::readyReadStandardError, this, &fontPool::mf_output_receiver); + + // Now run... kpsewhich. In case of error, kick up a fuss. + // This string is not going to be quoted, as it might be were it + // a real command line, but who cares? + const QString kpsewhich_exe = QStringLiteral("kpsewhich"); + kpsewhichOutput += QStringLiteral("") + kpsewhich_exe + QLatin1Char(' ') + kpsewhich_args.join(QStringLiteral(" ")) + QStringLiteral(""); + + kpsewhich_->start(kpsewhich_exe, kpsewhich_args, QIODevice::ReadOnly | QIODevice::Text); + if (!kpsewhich_->waitForStarted()) { + QApplication::restoreOverrideCursor(); + emit error(i18n("

There were problems running kpsewhich. As a result, " + "some font files could not be located, and your document might be unreadable.
" + "Possible reason: the kpsewhich program is perhaps not installed on your system, " + "or it cannot be found in the current search path.

" + "

PATH: %1

" + "

%2

", + QString::fromLocal8Bit(qgetenv("PATH")), + kpsewhichOutput.replace(QLatin1String("\n"), QLatin1String("
"))), + -1); + + // This makes sure the we don't try to run kpsewhich again + markFontsAsLocated(); + delete kpsewhich_; + return; + } + // We wait here while the external program runs concurrently. + kpsewhich_->waitForFinished(); + + // Handle fatal errors. + int const kpsewhich_exit_code = kpsewhich_->exitCode(); + if (kpsewhich_exit_code < 0) { + emit warning(i18n("The font generation by kpsewhich was aborted (exit code %1, error %2). As a " + "result, some font files could not be located, and your document might be unreadable.", + kpsewhich_exit_code, + kpsewhich_->errorString()), + -1); + + // This makes sure the we don't try to run kpsewhich again + if (makePK == false) + markFontsAsLocated(); + } + + // Create a list with all filenames found by the kpsewhich program. + const QStringList fileNameList = QString::fromLocal8Bit(kpsewhich_->readAll()).split(QLatin1Char('\n'), QString::SkipEmptyParts); + + // Now associate the file names found with the fonts + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + + if (fontp->filename.isEmpty() == true) { + QStringList matchingFiles; +#ifdef HAVE_FREETYPE + const QString &fn = fontsByTeXName.findFileName(fontp->fontname); + if (!fn.isEmpty()) + matchingFiles = fileNameList.filter(fn); +#endif + if (matchingFiles.isEmpty() == true) + matchingFiles += fileNameList.filter(QLatin1Char('/') + fontp->fontname + QLatin1Char('.')); + + if (matchingFiles.isEmpty() != true) { +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "Associated " << fontp->fontname << " to " << matchingFiles.first(); +#endif + QString fname = matchingFiles.first(); + fontp->fontNameReceiver(fname); + fontp->flags |= TeXFontDefinition::FONT_KPSE_NAME; + if (fname.endsWith(QLatin1String(".vf"))) { + if (virtualFontsFound != nullptr) + *virtualFontsFound = true; + // Constructing a virtual font will most likely insert other + // fonts into the fontList. After that, fontList.next() will + // no longer work. It is therefore safer to start over. + it_fontp = fontList.begin(); + continue; + } + } + } // of if (fontp->filename.isEmpty() == true) + } + delete kpsewhich_; +} + +void fontPool::setCMperDVIunit(double _CMperDVI) +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::setCMperDVIunit( " << _CMperDVI << " )"; +#endif + + if (CMperDVIunit == _CMperDVI) + return; + + CMperDVIunit = _CMperDVI; + + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + fontp->setDisplayResolution(displayResolution_in_dpi * fontp->enlargement); + } +} + +void fontPool::setDisplayResolution(double _displayResolution_in_dpi) +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::setDisplayResolution( displayResolution_in_dpi=" << _displayResolution_in_dpi << " ) called"; +#endif + + // Ignore minute changes by less than 2 DPI. The difference would + // hardly be visible anyway. That saves a lot of re-painting, + // e.g. when the user resizes the window, and a flickery mouse + // changes the window size by 1 pixel all the time. + if (fabs(displayResolution_in_dpi - _displayResolution_in_dpi) <= 2.0) { +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::setDisplayResolution(...): resolution wasn't changed. Aborting."; +#endif + return; + } + + displayResolution_in_dpi = _displayResolution_in_dpi; + double displayResolution = displayResolution_in_dpi; + + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + fontp->setDisplayResolution(displayResolution * fontp->enlargement); + } + + // Do something that causes re-rendering of the dvi-window + /*@@@@ + emit fonts_have_been_loaded(this); + */ +} + +void fontPool::markFontsAsLocated() +{ + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + fontp->markAsLocated(); + } +} + +void fontPool::mark_fonts_as_unused() +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "fontPool::mark_fonts_as_unused() called"; +#endif + + QList::iterator it_fontp = fontList.begin(); + for (; it_fontp != fontList.end(); ++it_fontp) { + TeXFontDefinition *fontp = *it_fontp; + fontp->flags &= ~TeXFontDefinition::FONT_IN_USE; + } +} + +void fontPool::release_fonts() +{ +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "Release_fonts"; +#endif + + QMutableListIterator it_fontp(fontList); + while (it_fontp.hasNext()) { + TeXFontDefinition *fontp = it_fontp.next(); + if ((fontp->flags & TeXFontDefinition::FONT_IN_USE) != TeXFontDefinition::FONT_IN_USE) { + delete fontp; + it_fontp.remove(); + } + } +} + +void fontPool::mf_output_receiver() +{ + const QString output_data = QString::fromLocal8Bit(kpsewhich_->readAllStandardError()); + + kpsewhichOutput.append(output_data); + MetafontOutput.append(output_data); + + // We'd like to print only full lines of text. + int numleft; + while ((numleft = MetafontOutput.indexOf(QLatin1Char('\n'))) != -1) { + QString line = MetafontOutput.left(numleft + 1); +#ifdef DEBUG_FONTPOOL + qCDebug(OkularDviDebug) << "MF OUTPUT RECEIVED: " << line; +#endif + // If the Output of the kpsewhich program contains a line starting + // with "kpathsea:", this means that a new MetaFont-run has been + // started. We filter these lines out and update the display + // accordingly. + int startlineindex = line.indexOf(QStringLiteral("kpathsea:")); + if (startlineindex != -1) { + int endstartline = line.indexOf(QStringLiteral("\n"), startlineindex); + QString startLine = line.mid(startlineindex, endstartline - startlineindex); + + // The last word in the startline is the name of the font which we + // are generating. The second-to-last word is the resolution in + // dots per inch. Display this info in the text label below the + // progress bar. + int lastblank = startLine.lastIndexOf(QLatin1Char(' ')); + QString fontName = startLine.mid(lastblank + 1); + int secondblank = startLine.lastIndexOf(QLatin1Char(' '), lastblank - 1); + QString dpi = startLine.mid(secondblank + 1, lastblank - secondblank - 1); + + emit warning(i18n("Currently generating %1 at %2 dpi...", fontName, dpi), -1); + } + MetafontOutput = MetafontOutput.remove(0, numleft + 1); + } +} diff --git a/generators/dvi/fontpool.h b/generators/dvi/fontpool.h new file mode 100644 index 0000000..9cf1d86 --- /dev/null +++ b/generators/dvi/fontpool.h @@ -0,0 +1,219 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// fontpool.h +// +// (C) 2001-2004 Stefan Kebekus +// Distributed under the GPL + +#ifndef _FONTPOOL_H +#define _FONTPOOL_H + +#include "TeXFontDefinition.h" +#include "fontEncodingPool.h" +#include "fontMap.h" + +#include +#include +#include + +#ifdef HAVE_FREETYPE +#include +#include FT_FREETYPE_H +#endif + +/** + * A list of fonts and a compilation of utility functions + * + * This class holds a list of fonts and is able to perform a number of + * functions on each of the fonts. The main use of this class is that + * it is able to control a concurrently running "kpsewhich" program + * which is used to locate and load the fonts. + * + * @author Stefan Kebekus + * + **/ + +class fontPool : public QObject +{ + Q_OBJECT + +public: + // Default constructor. + fontPool(bool useFontHinting); + + // Default destructor. + ~fontPool() override; + + /** Method used to set the MetafontMode for the PK font files. This + data is used when loading fonts. Currently, a change here will be + applied only to those font which were not yet loaded ---expect + funny results when changing the data in the mid-work. */ + void setParameters(bool useFontHints); + + /** Sets the DVI file's path. This information is used to set the + current working directory for the kpsewhich command, so that + kpsewhich will find fonts that are stored in the DVI file's + directory. */ + void setExtraSearchPath(const QString &path) + { + extraSearchPath = path; + } + + /** Returns the path that is set as the current working directory + for the kpsewhich command, so that kpsewhich will find fonts + that are stored in the DVI file's directory. */ + QString getExtraSearchPath() const + { + return extraSearchPath; + } + + /** Sets the resolution of the output device. */ + void setDisplayResolution(double _displayResolution_in_dpi); + + /** Sets the number of centimeters per DVI unit. */ + void setCMperDVIunit(double CMperDVI); + double getCMperDVIunit() const + { + return CMperDVIunit; + } + + // If return value is true, font hinting should be used if possible + bool getUseFontHints() const + { + return useFontHints; + } + + // This method adds a font to the list. If the font is not currently + // loaded, it's file will be located and font::load_font will be + // called. Since this is done using a concurrently running process, + // there is no guarantee that the loading is already performed when + // the method returns. + TeXFontDefinition *appendx(const QString &fontname, quint32 checksum, quint32 scale, double enlargement); + + // This is the list which actually holds pointers to the fonts + QList fontList; + + // This method marks all fonts in the fontpool as "not in use". The + // fonts are, however, not removed from memory until the method + // release_fonts is called. The method is called when the dvi-file + // is closed. Because the next dvi-file which will be loaded is + // likely to use most of the fonts again, this method implements a + // convenient way of re-using fonts without loading them repeatedly. + void mark_fonts_as_unused(); + + /** This methods removes all fonts from the fontpool (and thus from + memory) which are labeled "not in use". For explanation, see the + mark_fonts_as_unused method. */ + void release_fonts(); + +#ifdef HAVE_FREETYPE + /** A handle to the FreeType library, which is used by TeXFont_PFM + font objects, if KDVI is compiled with FreeType support. */ + FT_Library FreeType_library; + + /** Simple marker. Set to 'true', if the FreeType library was loaded + successfully */ + bool FreeType_could_be_loaded; + + /** This maps TeX font names to font file names, full font names and + encodings. See the file 'fontMap.h' for a detailed + description. */ + fontMap fontsByTeXName; + + /** This is a list of known font encodings which can be conveniently + accessed by name. */ + fontEncodingPool encodingPool; +#endif + + /** This flag is set during the construction of the fontPool + object. It indicates if the QT library supports the alpha + channel of pixmaps. Experiments show that --depending of the + configuration of QT at compile and runtime or the availability + of the XFt extension, alpha channels are either supported, or + silently converted to 1-bit masks. The rendering routines in the + TeXFont implementation use this flag to choose the appropriated + drawing routines for the different setups. */ + bool QPixmapSupportsAlpha; + +Q_SIGNALS: + /** Passed through to the top-level kpart. */ + void error(const QString &message, int duration); + void warning(const QString &message, int duration); + void notice(const QString &message, int duration); + +public Q_SLOTS: + // Locates font files on the disk using the kpsewhich program. If + // 'locateTFMonly' is true, the method does not look for PFB- or + // PK-fonts. Instead, only TFM-files are searched. This option can be + // used as a 'last resort': if a found cannot be found, one can at + // least use the TFM file to draw filled rectangles for the + // characters. If not null, the bool pointed at by virtualFontsFound + // is set to true if one of the fonts found is a virtual font. If no + // virtual font is found, the variable remains untouched. + void locateFonts(); + +private: + // This method goes through the list of fonts, and marks each of them + // as 'located'. Used, e.g. after a fatal error in the font lookup + // process to ensure that the problematic kpsewhich is not used again + void markFontsAsLocated(); + + // Checks if all the fonts file names have been located, and returns + // true if that is so. + bool areFontsLocated(); + + // This flag is used by PFB fonts to determine if the FREETYPE engine + // should use hinted fonts or not + bool useFontHints; + + // Resolution of the output device. + double displayResolution_in_dpi; + + // Number of centimeters per DVI unit + double CMperDVIunit; + + /** Members used for font location */ + + // Locates font files on the disk using the kpsewhich program. If + // 'locateTFMonly' is true, the method does not look for PFB- or + // PK-fonts. Instead, only TFM-files are searched. This option can be + // used as a 'last resort': if a found cannot be found, one can at + // least use the TFM file to draw filled rectangles for the + // characters. If not null, the bool pointed at by virtualFontsFound + // is set to true if one of the fonts found is a virtual font. If no + // virtual font is found, the variable remains untouched. + void locateFonts(bool makePK, bool locateTFMonly, bool *virtualFontsFound = nullptr); + + // This QString is used internally by the mf_output_receiver() + // method. This string is set to QString() in locateFonts(bool, + // bool, bool *). Values are set and read by the + // mf_output_receiver(...) method + QString MetafontOutput; + + // This QString is used to collect the output of kpsewhich and + // MetaFont. The string is set to QString() in the + // locateFonts()-method, and content is gathered by the + // mf_output_receiver(). This string is used by locateFonts() and + // locateFonts(bool, bool, bool *) to display error messages. + QString kpsewhichOutput; + + // This string is set to the DVI file's path. It is used to set the + // current working directory for the kpsewhich command, so that + // kpsewhich will find fonts that are stored in the DVI file's + // directory. Used by the locateFonts() and the locateFonts(bool, + // bool, bool *) method. Values are set by the + // setExtraSearchPath(...) method + QString extraSearchPath; + + // The handle on the external process. + QProcess *kpsewhich_; + +private Q_SLOTS: + // This slot is called when MetaFont is run via the kpsewhich program. + // The MetaFont output is transmitted to the fontpool via the @c kpsewhich_ + // member variable. This method passes on progress information to the + // fontProgress Dialog and collects the output of MetaFont in the + // @c MetafontOutput member variable. + void mf_output_receiver(); +}; + +#endif // ifndef _FONTPOOL_H diff --git a/generators/dvi/generator_dvi.cpp b/generators/dvi/generator_dvi.cpp new file mode 100644 index 0000000..7144749 --- /dev/null +++ b/generators/dvi/generator_dvi.cpp @@ -0,0 +1,515 @@ +/*************************************************************************** + * Copyright (C) 2006-2009 by Luigi 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. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "TeXFont.h" +#include "debug_dvi.h" +#include "dviFile.h" +#include "dviPageInfo.h" +#include "dviRenderer.h" +#include "dviexport.h" +#include "generator_dvi.h" +#include "pageSize.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef DVI_OPEN_BUSYLOOP +#include +#endif + +OKULAR_EXPORT_PLUGIN(DviGenerator, "libokularGenerator_dvi.json") + +DviGenerator::DviGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) + , m_fontExtracted(false) + , m_docSynopsis(nullptr) + , m_dviRenderer(nullptr) +{ + setFeature(Threaded); + setFeature(TextExtraction); + setFeature(FontInfo); + setFeature(PrintPostscript); + if (Okular::FilePrinter::ps2pdfAvailable()) + setFeature(PrintToFile); +} + +bool DviGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + // qCDebug(OkularDviDebug) << "file:" << fileName; + QUrl base(QUrl::fromLocalFile(fileName)); + + (void)userMutex(); + + m_dviRenderer = new dviRenderer(documentMetaData(TextHintingMetaData, QVariant()).toBool()); + connect(m_dviRenderer, &dviRenderer::error, this, &DviGenerator::error); + connect(m_dviRenderer, &dviRenderer::warning, this, &DviGenerator::warning); + connect(m_dviRenderer, &dviRenderer::notice, this, &DviGenerator::notice); +#ifdef DVI_OPEN_BUSYLOOP + static const ushort s_waitTime = 800; // milliseconds + static const int s_maxIterations = 10; + int iter = 0; + for (; !m_dviRenderer->isValidFile(fileName) && iter < s_maxIterations; ++iter) { + qCDebug(OkularDviDebug).nospace() << "file not valid after iteration #" << iter << "/" << s_maxIterations << ", waiting for " << s_waitTime; + QThread::msleep(s_waitTime); + } + if (iter >= s_maxIterations && !m_dviRenderer->isValidFile(fileName)) { + qCDebug(OkularDviDebug) << "file still not valid after" << s_maxIterations; + delete m_dviRenderer; + m_dviRenderer = 0; + return false; + } +#else + if (!m_dviRenderer->isValidFile(fileName)) { + delete m_dviRenderer; + m_dviRenderer = nullptr; + return false; + } +#endif + if (!m_dviRenderer->setFile(fileName, base)) { + delete m_dviRenderer; + m_dviRenderer = nullptr; + return false; + } + + qCDebug(OkularDviDebug) << "# of pages:" << m_dviRenderer->dviFile->total_pages; + + m_resolution = dpi().height(); + loadPages(pagesVector); + + return true; +} + +bool DviGenerator::doCloseDocument() +{ + delete m_docSynopsis; + m_docSynopsis = nullptr; + delete m_dviRenderer; + m_dviRenderer = nullptr; + + m_linkGenerated.clear(); + m_fontExtracted = false; + + return true; +} + +void DviGenerator::fillViewportFromAnchor(Okular::DocumentViewport &vp, const Anchor anch, const Okular::Page *page) const +{ + fillViewportFromAnchor(vp, anch, page->width(), page->height()); +} + +void DviGenerator::fillViewportFromAnchor(Okular::DocumentViewport &vp, const Anchor anch, int pW, int pH) const +{ + vp.pageNumber = anch.page - 1; + + SimplePageSize ps = m_dviRenderer->sizeOfPage(vp.pageNumber); + double resolution = 0; + if (ps.isValid()) + resolution = (double)(pW) / ps.width().getLength_in_inch(); + else + resolution = m_resolution; + + double py = (double)anch.distance_from_top.getLength_in_inch() * resolution + 0.5; + + vp.rePos.normalizedX = 0.5; + vp.rePos.normalizedY = py / (double)pH; + vp.rePos.enabled = true; + vp.rePos.pos = Okular::DocumentViewport::Center; +} + +QLinkedList DviGenerator::generateDviLinks(const dviPageInfo *pageInfo) +{ + QLinkedList dviLinks; + + int pageWidth = pageInfo->width, pageHeight = pageInfo->height; + + for (const Hyperlink &dviLink : qAsConst(pageInfo->hyperLinkList)) { + QRect boxArea = dviLink.box; + double nl = (double)boxArea.left() / pageWidth, nt = (double)boxArea.top() / pageHeight, nr = (double)boxArea.right() / pageWidth, nb = (double)boxArea.bottom() / pageHeight; + + QString linkText = dviLink.linkText; + if (linkText.startsWith(QLatin1String("#"))) + linkText = linkText.mid(1); + Anchor anch = m_dviRenderer->findAnchor(linkText); + + Okular::Action *okuLink = nullptr; + + /* distinguish between local (-> anchor) and remote links */ + if (anch.isValid()) { + /* internal link */ + Okular::DocumentViewport vp; + fillViewportFromAnchor(vp, anch, pageWidth, pageHeight); + + okuLink = new Okular::GotoAction(QLatin1String(""), vp); + } else { + okuLink = new Okular::BrowseAction(QUrl::fromUserInput(dviLink.linkText)); + } + if (okuLink) { + Okular::ObjectRect *orlink = new Okular::ObjectRect(nl, nt, nr, nb, false, Okular::ObjectRect::Action, okuLink); + dviLinks.push_front(orlink); + } + } + return dviLinks; +} + +QImage DviGenerator::image(Okular::PixmapRequest *request) +{ + dviPageInfo *pageInfo = new dviPageInfo(); + pageSize ps; + QImage ret; + + pageInfo->width = request->width(); + pageInfo->height = request->height(); + + pageInfo->pageNumber = request->pageNumber() + 1; + + // pageInfo->resolution = m_resolution; + + QMutexLocker lock(userMutex()); + + if (m_dviRenderer) { + SimplePageSize s = m_dviRenderer->sizeOfPage(pageInfo->pageNumber); + + /* if ( s.width() != pageInfo->width) */ + // if (!useDocumentSpecifiedSize) + // s = userPreferredSize; + + if (s.isValid()) { + pageInfo->resolution = (double)(pageInfo->width) / s.width().getLength_in_inch(); + } else { + pageInfo->resolution = (double)(pageInfo->width) / ps.width().getLength_in_inch(); + } + + m_dviRenderer->drawPage(pageInfo); + + if (!pageInfo->img.isNull()) { + qCDebug(OkularDviDebug) << "Image OK"; + + ret = pageInfo->img; + + if (!m_linkGenerated[request->pageNumber()]) { + request->page()->setObjectRects(generateDviLinks(pageInfo)); + m_linkGenerated[request->pageNumber()] = true; + } + } + } + + lock.unlock(); + + delete pageInfo; + + return ret; +} + +Okular::TextPage *DviGenerator::textPage(Okular::TextRequest *request) +{ + const Okular::Page *page = request->page(); + + qCDebug(OkularDviDebug); + dviPageInfo *pageInfo = new dviPageInfo(); + pageSize ps; + + pageInfo->width = page->width(); + pageInfo->height = page->height(); + + pageInfo->pageNumber = page->number() + 1; + + pageInfo->resolution = m_resolution; + + QMutexLocker lock(userMutex()); + + // get page text from m_dviRenderer + Okular::TextPage *ktp = nullptr; + if (m_dviRenderer) { + SimplePageSize s = m_dviRenderer->sizeOfPage(pageInfo->pageNumber); + pageInfo->resolution = (double)(pageInfo->width) / ps.width().getLength_in_inch(); + + m_dviRenderer->getText(pageInfo); + lock.unlock(); + + ktp = extractTextFromPage(pageInfo); + } + delete pageInfo; + return ktp; +} + +Okular::TextPage *DviGenerator::extractTextFromPage(dviPageInfo *pageInfo) +{ + QList textOfThePage; + + QVector::ConstIterator it = pageInfo->textBoxList.constBegin(); + QVector::ConstIterator itEnd = pageInfo->textBoxList.constEnd(); + + int pageWidth = pageInfo->width, pageHeight = pageInfo->height; + + for (; it != itEnd; ++it) { + TextBox curTB = *it; + +#if 0 + qCDebug(OkularDviDebug) << "orientation: " << orientation + << ", curTB.box: " << curTB.box + << ", ( " << pageWidth << "," << pageHeight << " )" + < &keys) const +{ + Okular::DocumentInfo docInfo; + + if (keys.contains(Okular::DocumentInfo::MimeType)) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("application/x-dvi")); + + QMutexLocker lock(userMutex()); + + if (m_dviRenderer && m_dviRenderer->dviFile) { + dvifile *dvif = m_dviRenderer->dviFile; + + // read properties from dvif + // docInfo.set( "filename", dvif->filename, i18n("Filename") ); + if (keys.contains(Okular::DocumentInfo::CustomKeys)) + docInfo.set(QStringLiteral("generatorDate"), dvif->generatorString, i18n("Generator/Date")); + if (keys.contains(Okular::DocumentInfo::Pages)) + docInfo.set(Okular::DocumentInfo::Pages, QString::number(dvif->total_pages)); + } + return docInfo; +} + +const Okular::DocumentSynopsis *DviGenerator::generateDocumentSynopsis() +{ + if (m_docSynopsis) + return m_docSynopsis; + + m_docSynopsis = new Okular::DocumentSynopsis(); + + userMutex()->lock(); + + QVector prebookmarks = m_dviRenderer->getPrebookmarks(); + + userMutex()->unlock(); + + if (prebookmarks.isEmpty()) + return m_docSynopsis; + + QStack stack; + + QVector::ConstIterator it = prebookmarks.constBegin(); + QVector::ConstIterator itEnd = prebookmarks.constEnd(); + for (; it != itEnd; ++it) { + QDomElement domel = m_docSynopsis->createElement((*it).title); + Anchor a = m_dviRenderer->findAnchor((*it).anchorName); + if (a.isValid()) { + Okular::DocumentViewport vp; + + const Okular::Page *p = document()->page(a.page - 1); + + fillViewportFromAnchor(vp, a, (int)p->width(), (int)p->height()); + domel.setAttribute(QStringLiteral("Viewport"), vp.toString()); + } + if (stack.isEmpty()) + m_docSynopsis->appendChild(domel); + else { + stack.top().appendChild(domel); + stack.pop(); + } + for (int i = 0; i < (*it).noOfChildren; ++i) + stack.push(domel); + } + + return m_docSynopsis; +} + +Okular::FontInfo::List DviGenerator::fontsForPage(int page) +{ + Q_UNUSED(page); + + Okular::FontInfo::List list; + + // the list of the fonts is extracted once + if (m_fontExtracted) + return list; + + if (m_dviRenderer && m_dviRenderer->dviFile && m_dviRenderer->dviFile->font_pool) { + const QList fonts = m_dviRenderer->dviFile->font_pool->fontList; + for (const TeXFontDefinition *font : fonts) { + Okular::FontInfo of; + QString name; + int zoom = (int)(font->enlargement * 100 + 0.5); +#ifdef HAVE_FREETYPE + if (font->getFullFontName().isEmpty()) { + name = QStringLiteral("%1, %2%").arg(font->fontname).arg(zoom); + } else { + name = QStringLiteral("%1 (%2), %3%").arg(font->fontname, font->getFullFontName(), QString::number(zoom)); + } +#else + name = QString("%1, %2%").arg(font->fontname).arg(zoom); +#endif + of.setName(name); + + QString fontFileName; + if (!(font->flags & TeXFontDefinition::FONT_VIRTUAL)) { + if (font->font != nullptr) + fontFileName = font->font->errorMessage; + else + fontFileName = i18n("Font file not found"); + + if (fontFileName.isEmpty()) + fontFileName = font->filename; + } + + of.setFile(fontFileName); + + Okular::FontInfo::FontType ft; + switch (font->getFontType()) { + case TeXFontDefinition::TEX_PK: + ft = Okular::FontInfo::TeXPK; + break; + case TeXFontDefinition::TEX_VIRTUAL: + ft = Okular::FontInfo::TeXVirtual; + break; + case TeXFontDefinition::TEX_FONTMETRIC: + ft = Okular::FontInfo::TeXFontMetric; + break; + case TeXFontDefinition::FREETYPE: + ft = Okular::FontInfo::TeXFreeTypeHandled; + break; + } + of.setType(ft); + + // DVI has not the concept of "font embedding" + of.setEmbedType(Okular::FontInfo::NotEmbedded); + of.setCanBeExtracted(false); + + list.append(of); + } + + m_fontExtracted = true; + } + + return list; +} + +void DviGenerator::loadPages(QVector &pagesVector) +{ + QSize pageRequiredSize; + + int numofpages = m_dviRenderer->dviFile->total_pages; + pagesVector.resize(numofpages); + + m_linkGenerated.fill(false, numofpages); + + // qCDebug(OkularDviDebug) << "resolution:" << m_resolution << ", dviFile->preferred?"; + + /* get the suggested size */ + if (m_dviRenderer->dviFile->suggestedPageSize) { + pageRequiredSize = m_dviRenderer->dviFile->suggestedPageSize->sizeInPixel(m_resolution); + } else { + pageSize ps; + pageRequiredSize = ps.sizeInPixel(m_resolution); + } + + for (int i = 0; i < numofpages; ++i) { + // qCDebug(OkularDviDebug) << "getting status of page" << i << ":"; + + if (pagesVector[i]) { + delete pagesVector[i]; + } + + Okular::Page *page = new Okular::Page(i, pageRequiredSize.width(), pageRequiredSize.height(), Okular::Rotation0); + + pagesVector[i] = page; + } + qCDebug(OkularDviDebug) << "pagesVector successfully inizialized!"; + + // filling the pages with the source references rects + const QVector &sourceAnchors = m_dviRenderer->sourceAnchors(); + QVector> refRects(numofpages); + for (const DVI_SourceFileAnchor &sfa : sourceAnchors) { + if (sfa.page < 1 || (int)sfa.page > numofpages) + continue; + + Okular::NormalizedPoint p(-1.0, (double)sfa.distance_from_top.getLength_in_pixel(dpi().height()) / (double)pageRequiredSize.height()); + Okular::SourceReference *sourceRef = new Okular::SourceReference(sfa.fileName, sfa.line); + refRects[sfa.page - 1].append(new Okular::SourceRefObjectRect(p, sourceRef)); + } + for (int i = 0; i < refRects.size(); ++i) + if (!refRects.at(i).isEmpty()) + pagesVector[i]->setSourceReferences(refRects.at(i)); +} + +bool DviGenerator::print(QPrinter &printer) +{ + // Create tempfile to write to + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + if (!tf.open()) + return false; + + const QList pageList = Okular::FilePrinter::pageList(printer, m_dviRenderer->totalPages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + QString pages; + QStringList printOptions; + // List of pages to print. + for (const int p : pageList) { + pages += QStringLiteral(",%1").arg(p); + } + if (!pages.isEmpty()) + printOptions << QStringLiteral("-pp") << pages.mid(1); + + QEventLoop el; + m_dviRenderer->setEventLoop(&el); + m_dviRenderer->exportPS(tf.fileName(), printOptions, &printer, document()->orientation()); + + tf.close(); + + // Error messages are handled by the generator - ugly, but it works. + return true; +} + +QVariant DviGenerator::metaData(const QString &key, const QVariant &option) const +{ + if (key == QLatin1String("NamedViewport") && !option.toString().isEmpty()) { + const Anchor anchor = m_dviRenderer->parseReference(option.toString()); + if (anchor.isValid()) { + const Okular::Page *page = document()->page(anchor.page - 1); + Q_ASSERT_X(page, "DviGenerator::metaData()", "NULL page as result of valid Anchor"); + Okular::DocumentViewport viewport; + fillViewportFromAnchor(viewport, anchor, page); + if (viewport.isValid()) { + return viewport.toString(); + } + } + } + return QVariant(); +} + +Q_LOGGING_CATEGORY(OkularDviDebug, "org.kde.okular.generators.dvi.core", QtWarningMsg) +Q_LOGGING_CATEGORY(OkularDviShellDebug, "org.kde.okular.generators.dvi.shell", QtWarningMsg) + +#include "generator_dvi.moc" diff --git a/generators/dvi/generator_dvi.h b/generators/dvi/generator_dvi.h new file mode 100644 index 0000000..8d10e00 --- /dev/null +++ b/generators/dvi/generator_dvi.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi 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 _DVI_GENERATOR_H_ +#define _DVI_GENERATOR_H_ + +#include + +#include + +class dviRenderer; +class dviPageInfo; +class Anchor; + +namespace Okular +{ +class DocumentViewport; +class ObjectRect; +} + +class DviGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + DviGenerator(QObject *parent, const QVariantList &args); + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + // document information + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + + // table of contents + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + + // list of fonts + Okular::FontInfo::List fontsForPage(int page) override; + + bool print(QPrinter &printer) override; + + QVariant metaData(const QString &key, const QVariant &option) const override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + +private: + double m_resolution; + bool m_fontExtracted; + + Okular::DocumentSynopsis *m_docSynopsis; + + dviRenderer *m_dviRenderer; + QBitArray m_linkGenerated; + + void loadPages(QVector &pagesVector); + Okular::TextPage *extractTextFromPage(dviPageInfo *pageInfo); + void fillViewportFromAnchor(Okular::DocumentViewport &vp, const Anchor anch, int pW, int pH) const; + void fillViewportFromAnchor(Okular::DocumentViewport &vp, const Anchor anch, const Okular::Page *page) const; + QLinkedList generateDviLinks(const dviPageInfo *pageInfo); +}; + +#endif diff --git a/generators/dvi/glyph.cpp b/generators/dvi/glyph.cpp new file mode 100644 index 0000000..323cc2c --- /dev/null +++ b/generators/dvi/glyph.cpp @@ -0,0 +1,39 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- + +/* glyph.cpp + * + * part of kdvi, a dvi-previewer for the KDE desktop environment + * + * written by Stefan Kebekus, originally based on code by Paul Vojta + * and a large number of co-authors */ + +#include + +#include "debug_dvi.h" +#include "glyph.h" + +bitmap::bitmap() +{ + bits = nullptr; +} + +bitmap::~bitmap() +{ + delete[] bits; +} + +glyph::glyph() +{ +#ifdef DEBUG_GLYPH + qCDebug(OkularDviDebug) << "glyph::glyph()"; +#endif + + addr = 0; + x = 0; + y = 0; + dvi_advance_in_units_of_design_size_by_2e20 = 0; +} + +glyph::~glyph() +{ +} diff --git a/generators/dvi/glyph.h b/generators/dvi/glyph.h new file mode 100644 index 0000000..bfed981 --- /dev/null +++ b/generators/dvi/glyph.h @@ -0,0 +1,47 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- + +#ifndef _GLYPH_H +#define _GLYPH_H + +#include +#include + +struct bitmap { + bitmap(); + ~bitmap(); + + bitmap(const bitmap &) = delete; + bitmap &operator=(const bitmap &) = delete; + + // width and height in pixels + quint16 w, h; + // scan-line width in bytes + quint16 bytes_wide; + // pointer to the bits + char *bits; +}; + +class glyph +{ +public: + glyph(); + ~glyph(); + + // address of bitmap in font file + long addr; + + QColor color; + + // DVI units to move reference point + qint32 dvi_advance_in_units_of_design_size_by_2e20; + + // x and y offset in pixels + short x, y; + + QImage shrunkenCharacter; + + // x and y offset in pixels (shrunken bitmap) + short x2, y2; +}; + +#endif // ifndef _GLYPH_H diff --git a/generators/dvi/hyperlink.h b/generators/dvi/hyperlink.h new file mode 100644 index 0000000..a0e221b --- /dev/null +++ b/generators/dvi/hyperlink.h @@ -0,0 +1,82 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Class: hyperlink +// +// Part of KDVI- A previewer for TeX DVI files. +// +// (C) 2004-2005 Stefan Kebekus. Distributed under the GPL. + +#ifndef _hyperlink_h_ +#define _hyperlink_h_ + +#include +#include + +/** Represents a named, rectangular region in a rendered documentPage + + This trivial class is used in the documentPage class to represent + a hyperlink in a rendered documentPage. + + @author Stefan Kebekus + @version 1.0.0 +*/ + +class Hyperlink +{ +public: + /** \brief Default Constructor + + The default constructor leaves all fields uninitialized. + */ + Hyperlink() + { + } + + /** \brief Constructor + + Trivial constructor leaves that initialized all members. + + @param bl value for the baseline field + @param re value for the box + @param lT valus for the text field + */ + Hyperlink(quint32 bl, const QRect re, const QString &lT) + : baseline(bl) + , box(re) + , linkText(lT) + { + } + + /** \brief Base line of a hyperlink + + This field specifies the Y-coordinate of the base line of the + bounding box in the same coordinates that were used when the + associated documentPage was rendered by the + documentRenderer.drawPage() method. It is used to underline + hyperlinks in blue. Note that this field does generally differ from + the Y-coordinate of the bottom of the bounding box, e.g. if the text + in the box contains characters with underlengths, such as 'y', 'j' + or 'g'. + */ + quint32 baseline; + + /** \brief Bounding box of the text or hyperlink + + This rectangle specifies where on the page the hyperlink is + found. It uses the same coordinates that were used when the + associated documentPage was rendered by the + documentRenderer.drawPage() method. The box is used to determine if + the mouse pointer hovers over the link. + */ + QRect box; + + /** \brief Name of the region + + This field contains the name of the target, + e.g. "http://www.kde.org". If the Hyperlink class is used to + represent text, then the text is stored here. + */ + QString linkText; +}; + +#endif diff --git a/generators/dvi/length.cpp b/generators/dvi/length.cpp new file mode 100644 index 0000000..36e91f5 --- /dev/null +++ b/generators/dvi/length.cpp @@ -0,0 +1,73 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// units.cpp +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2003 Stefan Kebekus +// (C) 2006 Wilfried Huss +// Distributed under the GPL + +#include + +#include "debug_dvi.h" +#include "length.h" + +class unitOfDistance +{ +public: + float mmPerUnit; + const char *name; +}; + +static const unitOfDistance distanceUnitTable[] = { + // Metric units + {1.0f, "mm"}, + {1.0f, "millimeter"}, + {10.0f, "cm"}, + {10.0f, "centimeter"}, + {float(100.0 * 10.0), "m"}, + {float(100.0 * 10.0), "meter"}, + + // Imperial units + {25.4f, "in"}, + {25.4f, "inch"}, + + // Typographical units + {float(2540.0 / 7227.0), "pt"}, // TeX points. 7227points = 254cm + {float(25.4 / 72.0), "bp"}, // big points, 1/72 inch as used in Postscript + {float(25.4 / 6.0), "pc"}, // pica = 1/6 inch + {float(25.4 / 6.0), "pica"}, + {float(25.4 * 0.0148), "dd"}, // didot points = 0.0148 inches + {float(25.4 * 0.0148), "didot"}, + {float(25.4 * 0.178), "cc"}, // cicero points = 0.178 inches + {float(25.4 * 0.178), "cicero"}, + + {0.0f, nullptr}, +}; + +float Length::convertToMM(const QString &distance, bool *ok) +{ + float MMperUnit = 0.0; + int unitPos = 0; // position of the unit in the string + + // Check for various known units, and store the beginning position + // of the unit in 'unitPos', so that distance[0..unitPos] will hold + // the value. Store the number of mm per unit in 'MMperUnit'. + for (int i = 0; MMperUnit == 0.0 && distanceUnitTable[i].name != nullptr; i++) { + unitPos = distance.lastIndexOf(QString::fromLocal8Bit(distanceUnitTable[i].name)); + if (unitPos != -1) + MMperUnit = distanceUnitTable[i].mmPerUnit; + } + + // If no unit has been found -> error message, set *ok to false and + // return 0.0. + if (MMperUnit == 0.0) { + qCCritical(OkularDviShellDebug) << "distance::convertToMM: no known unit found in the string '" << distance << "'." << endl; + if (ok) + *ok = false; + return 0.0; + } + + QString val = distance.left(unitPos).simplified(); + return MMperUnit * val.toFloat(ok); +} diff --git a/generators/dvi/length.h b/generators/dvi/length.h new file mode 100644 index 0000000..4ba0da2 --- /dev/null +++ b/generators/dvi/length.h @@ -0,0 +1,306 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// Class: length +// +// Part of KVIEWSHELL +// +// (C) 2005 Stefan Kebekus +// (C) 2006 Wilfried Huss +// +// Distributed under the GPL. + +#ifndef _length_h_ +#define _length_h_ + +#include +#include + +class QString; + +#define mm_per_cm 10.0 +#define mm_per_m 1000.0 +#define mm_per_inch 25.4 +#define mm_per_TeXPoint (2540.0 / 7227.0) +#define mm_per_bigPoint (25.4 / 72.0) +#define mm_per_pica (25.4 / 6.0) +#define mm_per_didot (25.4 * 0.0148) +#define mm_per_cicero (25.4 * 0.178) +#define mm_per_scaledPoint (25.4 / (72.27 * 65536.0)) + +/** @short Represents a phyical length + + This class is used to represent a physical length. Its main purpose + it to help in the conversion of units, and to avoid confusion + about units. To avoid misunderstandings, there is no default + constructor so that this class needs to be explicitly initialized + with one of the functions below. + + @warning Lengths are stored internally in mm. If you convert to + or from any other unit, expect floating point round-off errors. + + @author Stefan Kebekus + @version 1.0.0 +*/ + +class Length +{ +public: + /** constructs a 'length = 0mm' object */ + Length() + { + length_in_mm = 0; + } + + /** sets the length in millimeters */ + void setLength_in_mm(double l) + { + length_in_mm = l; + } + + /** sets the length in centimeters */ + void setLength_in_cm(double l) + { + length_in_mm = l * mm_per_cm; + } + + /** sets the length in meters */ + void setLength_in_m(double l) + { + length_in_mm = l * mm_per_m; + } + + /** sets the length in inches */ + void setLength_in_inch(double l) + { + length_in_mm = l * mm_per_inch; + } + + /** sets the length in TeX points */ + void setLength_in_TeXPoints(double l) + { + length_in_mm = l * mm_per_TeXPoint; + } + + /** sets the length in big points (1/72 of an inch) */ + void setLength_in_bigPoints(double l) + { + length_in_mm = l * mm_per_bigPoint; + } + + /** sets the length in picas (1/6 of an inch) */ + void setLength_in_pica(double l) + { + length_in_mm = l * mm_per_pica; + } + + /** sets the length in didots (0.0148 inches) */ + void setLength_in_didot(double l) + { + length_in_mm = l * mm_per_didot; + } + + /** sets the length in ciceros (0.178 inches) */ + void setLength_in_cicero(double l) + { + length_in_mm = l * mm_per_cicero; + } + + /** sets the length in scaled points (1 scaled point = 65536 TeX points) */ + void setLength_in_scaledPoints(double l) + { + length_in_mm = l * mm_per_scaledPoint; + } + + /** sets the length (@param l ) in pixels. The parameter @param res is the resolution of the + used device in DPI. */ + void setLength_in_pixel(int l, double res) + { + setLength_in_inch(l / res); + } + + /** @returns the length in millimeters */ + double getLength_in_mm() const + { + return length_in_mm; + } + + /** @returns the length in centimeters */ + double getLength_in_cm() const + { + return length_in_mm / mm_per_cm; + } + + /** @returns the length in meters */ + double getLength_in_m() const + { + return length_in_mm / mm_per_m; + } + + /** @returns the length in inches */ + double getLength_in_inch() const + { + return length_in_mm / mm_per_inch; + } + + /** @returns the length in TeX points */ + double getLength_in_TeXPoints() const + { + return length_in_mm / mm_per_TeXPoint; + } + + /** @returns the length in big points (1/72 of an inch) */ + double getLength_in_bigPoints() const + { + return length_in_mm / mm_per_bigPoint; + } + + /** @returns the length in picas (1/6 of an inch) */ + double getLength_in_pica() const + { + return length_in_mm / mm_per_pica; + } + + /** @returns the length in didots (0.0148 inches) */ + double getLength_in_didot() const + { + return length_in_mm / mm_per_didot; + } + + /** @returns the length in ciceros (0.178 inches) */ + double getLength_in_cicero() const + { + return length_in_mm / mm_per_cicero; + } + + /** @returns the length in scaled points (1 scaled point = 65536 TeX points) */ + double getLength_in_scaledPoints() const + { + return length_in_mm / mm_per_scaledPoint; + } + + /** @returns the length in pixel. The parameter @param res is the resolution of the + used device in DPI. */ + int getLength_in_pixel(double res) const + { + return int(getLength_in_inch() * res); + } + + /** @returns true is lengths differ by no more than 2mm */ + bool isNearlyEqual(const Length o) const + { + return fabs(length_in_mm - o.getLength_in_mm()) <= 2.0; + } + + /** Comparison of two lengthes */ + bool operator>(const Length o) const + { + return (length_in_mm > o.getLength_in_mm()); + } + bool operator<(const Length o) const + { + return (length_in_mm < o.getLength_in_mm()); + } + + /** Comparison of two lengthes */ + bool operator>=(const Length o) const + { + return (length_in_mm >= o.getLength_in_mm()); + } + bool operator<=(const Length o) const + { + return (length_in_mm <= o.getLength_in_mm()); + } + + /** Ratio of two lengthes + + @warning There is no safeguared to prevent you from division by + zero. If the length in the denominator is near 0.0, a floating point + exception may occur. + + @returns the ratio of the two lengthes as a double + */ + double operator/(const Length o) const + { + return (length_in_mm / o.getLength_in_mm()); + } + + /** Sum of two lengthes + + @returns the sum of the lengthes as a Length + */ + Length operator+(const Length o) const + { + Length r; + r.length_in_mm = length_in_mm + o.length_in_mm; + return r; + } + + /** Difference of two lengthes + + @returns the difference of the lengthes as a Length + */ + Length operator-(const Length o) const + { + Length r; + r.length_in_mm = length_in_mm - o.length_in_mm; + return r; + } + + /** Division of a length + + @warning There is no safeguared to prevent you from division by + zero. If the number in the denominator is near 0.0, a floating point + exception may occur. + + @returns a fraction of the original length as a Length + */ + Length operator/(const double l) const + { + Length r; + r.length_in_mm = length_in_mm / l; + return r; + } + + /** Multiplication of a length + + @returns a multiplied length as a Length + */ + Length operator*(const double l) const + { + Length r; + r.length_in_mm = length_in_mm * l; + return r; + } + + /** This method converts a string that gives a distance in one of the + commonly used units, such as "12.3mm", "12 inch" or "15 didot" to + millimeters. For a complete list of supported units, see the + static lists that are hardcoded in "units.cpp". + + If the conversion is not possible *ok is set to "false" and an + undefined value is returned. If the unit could not be recognized, + an error message is printed via kdError(). Otherwise, *ok is set + to true. + + It is possible in rare circumstances that ok is set to true + although the string is malformed. + + It is fine to set ok to 0. */ + static float convertToMM(const QString &distance, bool *ok = nullptr); + +private: + /** Length in millimeters */ + double length_in_mm; +}; + +#undef mm_per_cm +#undef mm_per_m +#undef mm_per_inch +#undef mm_per_TeXPoint +#undef mm_per_bigPoint +#undef mm_per_pica +#undef mm_per_didot +#undef mm_per_cicero +#undef mm_per_scaledPoint + +#endif diff --git a/generators/dvi/libokularGenerator_dvi.json b/generators/dvi/libokularGenerator_dvi.json new file mode 100644 index 0000000..83dcd78 --- /dev/null +++ b/generators/dvi/libokularGenerator_dvi.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "luigi.toscano@tiscali.it", + "Name": "Luigi Toscano", + "Name[az]": "Luigi Toscano", + "Name[ca@valencia]": "Luigi Toscano", + "Name[ca]": "Luigi Toscano", + "Name[cs]": "Luigi Toscano", + "Name[da]": "Luigi Toscano", + "Name[de]": "Luigi Toscano", + "Name[el]": "Luigi Toscano", + "Name[en_GB]": "Luigi Toscano", + "Name[es]": "Luigi Toscano", + "Name[et]": "Luigi Toscano", + "Name[eu]": "Luigi Toscano", + "Name[fi]": "Luigi Toscano", + "Name[fr]": "Luigi Toscano", + "Name[gl]": "Luigi Toscano", + "Name[ia]": "Luigi Toscano", + "Name[it]": "Luigi Toscano", + "Name[ko]": "Luigi Toscano", + "Name[lt]": "Luigi Toscano", + "Name[nl]": "Luigi Toscano", + "Name[nn]": "Luigi Toscano", + "Name[pl]": "Luigi Toscano", + "Name[pt]": "Luigi Toscano", + "Name[pt_BR]": "Luigi Toscano", + "Name[ru]": "Luigi Toscano", + "Name[sk]": "Luigi Toscano", + "Name[sl]": "Luigi Toscano", + "Name[sr@ijekavian]": "Луиђи Тоскано", + "Name[sr@ijekavianlatin]": "Luiđi Toskano", + "Name[sr@latin]": "Luiđi Toskano", + "Name[sr]": "Луиђи Тоскано", + "Name[sv]": "Luigi Toscano", + "Name[tr]": "Luigi Toscano", + "Name[uk]": "Luigi Toscano", + "Name[x-test]": "xxLuigi Toscanoxx", + "Name[zh_CN]": "Luigi Toscano", + "Name[zh_TW]": "Luigi Toscano" + } + ], + "Copyright": "© 2006 Luigi Toscano", + "Copyright[az]": "© 2006 Luigi Toscano", + "Copyright[ca@valencia]": "© 2006 Luigi Toscano", + "Copyright[ca]": "© 2006 Luigi Toscano", + "Copyright[cs]": "© 2006 Luigi Toscano", + "Copyright[da]": "© 2006 Luigi Toscano", + "Copyright[de]": "© 2006 Luigi Toscano", + "Copyright[el]": "© 2006 Luigi Toscano", + "Copyright[en_GB]": "© 2006 Luigi Toscano", + "Copyright[es]": "© 2006 Luigi Toscano", + "Copyright[et]": "© 2006: Luigi Toscano", + "Copyright[eu]": "© 2006 Luigi Toscano", + "Copyright[fi]": "© 2006 Luigi Toscano", + "Copyright[fr]": "© 2006 Luigi Toscano", + "Copyright[gl]": "© 2006 Luigi Toscano", + "Copyright[ia]": "© 2006 Pino Toscano", + "Copyright[it]": "© 2006 Luigi Toscano", + "Copyright[ko]": "© 2006 Luigi Toscano", + "Copyright[lt]": "© 2006 Luigi Toscano", + "Copyright[nl]": "© 2006 Luigi Toscano", + "Copyright[nn]": "© 2006 Luigi Toscano", + "Copyright[pl]": "© 2006 Luigi Toscano", + "Copyright[pt]": "© 2006 Luigi Toscano", + "Copyright[pt_BR]": "© 2006 Luigi Toscano", + "Copyright[ru]": "© Luigi Toscano, 2006", + "Copyright[sk]": "© 2006 Luigi Toscano", + "Copyright[sl]": "© 2006 Luigi Toscano", + "Copyright[sr@ijekavian]": "© 2006, Луиђи Тоскано", + "Copyright[sr@ijekavianlatin]": "© 2006, Luiđi Toskano", + "Copyright[sr@latin]": "© 2006, Luiđi Toskano", + "Copyright[sr]": "© 2006, Луиђи Тоскано", + "Copyright[sv]": "© 2006 Luigi Toscano", + "Copyright[tr]": "© 2006 Luigi Toscano", + "Copyright[uk]": "© Luigi Toscano, 2006", + "Copyright[x-test]": "xx© 2006 Luigi Toscanoxx", + "Copyright[zh_CN]": "© 2006 Luigi Toscano", + "Copyright[zh_TW]": "© 2006 Luigi Toscano", + "Description": "A DVI file renderer", + "Description[az]": "DVİ faylı tərtibatçısı", + "Description[ca@valencia]": "Un renderitzador per als fitxers DVI", + "Description[ca]": "Un renderitzador per als fitxers DVI", + "Description[cs]": "Vykreslovač DVI souborů", + "Description[da]": "En gengiver til DVI-filer", + "Description[de]": "Ein Renderer für DVI-Dateien", + "Description[el]": "Πρόγραμμα αποτύπωσης για DVI αρχεία", + "Description[en_GB]": "A DVI file renderer", + "Description[es]": "Un visor de archivos DVI", + "Description[et]": "DVI-faili renderdaja", + "Description[eu]": "DVI fitxategi errendatzaile bat", + "Description[fi]": "DVI-tiedostohahmonnin", + "Description[fr]": "Système de rendu pour fichiers « DVI »", + "Description[gl]": "Un visor de ficheiros DVI", + "Description[ia]": "Un renditor de file de DVI", + "Description[it]": "Un visualizzatore di file DVI", + "Description[ko]": "DVI 파일 렌더러", + "Description[lt]": "DVI failų atvaizdavimas", + "Description[nl]": "Een DVI-bestandsweergever", + "Description[nn]": "Ein gjengjevar for DVI-filer", + "Description[pl]": "Wyświetlanie plików DVI", + "Description[pt]": "Um visualizador de ficheiros DVI", + "Description[pt_BR]": "Um renderizador de arquivo DVI", + "Description[ru]": "Модуль поддержки формата DVI", + "Description[sk]": "Vykresľovanie DVI súborov", + "Description[sl]": "Izrisovalnik datotek DVI", + "Description[sr@ijekavian]": "Рендерер ДВИ фајлова", + "Description[sr@ijekavianlatin]": "Renderer DVI fajlova", + "Description[sr@latin]": "Renderer DVI fajlova", + "Description[sr]": "Рендерер ДВИ фајлова", + "Description[sv]": "Ett återgivningsprogram för DVI-filer", + "Description[tr]": "Bir DVI dosya oluşturucu", + "Description[uk]": "Інструмент для показу файлів DVI", + "Description[x-test]": "xxA DVI file rendererxx", + "Description[zh_CN]": "DVI 文件渲染器", + "Description[zh_TW]": "DVI 檔成像器", + "Id": "okular_dvi", + "License": "GPL", + "MimeTypes": [ + "application/x-dvi" + ], + "Name": "DVI Backend", + "Name[az]": "DVİ modulu", + "Name[ca@valencia]": "Dorsal DVI", + "Name[ca]": "Dorsal DVI", + "Name[cs]": "Implementace DVI", + "Name[da]": "DVI-backend", + "Name[de]": "Anzeigemodul für DVI", + "Name[el]": "Σύστημα υποστήριξης DVI", + "Name[en_GB]": "DVI Backend", + "Name[es]": "Motor para DVI", + "Name[et]": "DVI taustaprogramm", + "Name[eu]": "DVIren bizkarraldekoa", + "Name[fi]": "DVI-taustaosa", + "Name[fr]": "Moteur DVI", + "Name[gl]": "Infraestrutura de DVI", + "Name[ia]": "Retro-administration de DVI", + "Name[it]": "Backend DVI", + "Name[ko]": "DVI 백엔드", + "Name[lt]": "DVI programinė sąsaja", + "Name[nl]": "DVI-backend", + "Name[nn]": "DVI-motor", + "Name[pl]": "Obsługa DVI", + "Name[pt]": "Infra-Estrutura de DVI", + "Name[pt_BR]": "Infraestrutura DVI", + "Name[ru]": "Модуль поддержки формата DVI", + "Name[sk]": "DVI Backend", + "Name[sl]": "Zaledje za DVI", + "Name[sr@ijekavian]": "Позадина за ДВИ", + "Name[sr@ijekavianlatin]": "Pozadina za DVI", + "Name[sr@latin]": "Pozadina za DVI", + "Name[sr]": "Позадина за ДВИ", + "Name[sv]": "DVI-gränssnitt", + "Name[tr]": "DVI Arka Ucu", + "Name[uk]": "Модуль DVI", + "Name[x-test]": "xxDVI Backendxx", + "Name[zh_CN]": "DVI 后端", + "Name[zh_TW]": "DVI 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.3.7" + }, + "X-KDE-Priority": 2, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/dvi/okularApplication_dvi.desktop b/generators/dvi/okularApplication_dvi.desktop new file mode 100755 index 0000000..021698c --- /dev/null +++ b/generators/dvi/okularApplication_dvi.desktop @@ -0,0 +1,226 @@ +[Desktop Entry] +MimeType=application/x-dvi;application/x-gzdvi;application/x-bzdvi; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=dvi +X-KDE-Keywords[ar]=dvi +X-KDE-Keywords[az]=dvi +X-KDE-Keywords[bg]=dvi +X-KDE-Keywords[bs]=dvi +X-KDE-Keywords[ca]=dvi +X-KDE-Keywords[ca@valencia]=dvi +X-KDE-Keywords[cs]=dvi +X-KDE-Keywords[da]=dvi +X-KDE-Keywords[de]=dvi +X-KDE-Keywords[el]=dvi +X-KDE-Keywords[en_GB]=dvi +X-KDE-Keywords[eo]=dvi +X-KDE-Keywords[es]=dvi +X-KDE-Keywords[et]=dvi +X-KDE-Keywords[eu]=dvi +X-KDE-Keywords[fi]=dvi +X-KDE-Keywords[fr]=dvi +X-KDE-Keywords[ga]=dvi +X-KDE-Keywords[gl]=dvi +X-KDE-Keywords[hu]=dvi +X-KDE-Keywords[ia]=dvi +X-KDE-Keywords[is]=dvi +X-KDE-Keywords[it]=dvi +X-KDE-Keywords[ja]=dvi +X-KDE-Keywords[kk]=dvi +X-KDE-Keywords[km]=dvi +X-KDE-Keywords[ko]=dvi +X-KDE-Keywords[lt]=dvi +X-KDE-Keywords[lv]=dvi +X-KDE-Keywords[mr]=dvi +X-KDE-Keywords[nb]=dvi +X-KDE-Keywords[nds]=DVI +X-KDE-Keywords[nl]=dvi +X-KDE-Keywords[nn]=dvi +X-KDE-Keywords[pa]=dvi +X-KDE-Keywords[pl]=dvi +X-KDE-Keywords[pt]=dvi +X-KDE-Keywords[pt_BR]=dvi +X-KDE-Keywords[ro]=dvi +X-KDE-Keywords[ru]=dvi +X-KDE-Keywords[sk]=dvi +X-KDE-Keywords[sl]=dvi +X-KDE-Keywords[sr]=dvi,ДВИ +X-KDE-Keywords[sr@ijekavian]=dvi,ДВИ +X-KDE-Keywords[sr@ijekavianlatin]=dvi,DVI +X-KDE-Keywords[sr@latin]=dvi,DVI +X-KDE-Keywords[sv]=dvi +X-KDE-Keywords[tr]=dvi +X-KDE-Keywords[ug]=dvi +X-KDE-Keywords[uk]=dvi +X-KDE-Keywords[x-test]=xxdvixx +X-KDE-Keywords[zh_CN]=dvi +X-KDE-Keywords[zh_TW]=dvi diff --git a/generators/dvi/okularDvi.desktop b/generators/dvi/okularDvi.desktop new file mode 100644 index 0000000..64387c9 --- /dev/null +++ b/generators/dvi/okularDvi.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-dvi;application/x-gzdvi;application/x-bzdvi; diff --git a/generators/dvi/org.kde.mobile.okular_dvi.desktop b/generators/dvi/org.kde.mobile.okular_dvi.desktop new file mode 100644 index 0000000..ea92191 --- /dev/null +++ b/generators/dvi/org.kde.mobile.okular_dvi.desktop @@ -0,0 +1,217 @@ +[Desktop Entry] +MimeType=application/x-dvi;application/x-gzdvi;application/x-bzdvi; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=dvi +X-KDE-Keywords[ar]=dvi +X-KDE-Keywords[az]=dvi +X-KDE-Keywords[bg]=dvi +X-KDE-Keywords[bs]=dvi +X-KDE-Keywords[ca]=dvi +X-KDE-Keywords[ca@valencia]=dvi +X-KDE-Keywords[cs]=dvi +X-KDE-Keywords[da]=dvi +X-KDE-Keywords[de]=dvi +X-KDE-Keywords[el]=dvi +X-KDE-Keywords[en_GB]=dvi +X-KDE-Keywords[eo]=dvi +X-KDE-Keywords[es]=dvi +X-KDE-Keywords[et]=dvi +X-KDE-Keywords[eu]=dvi +X-KDE-Keywords[fi]=dvi +X-KDE-Keywords[fr]=dvi +X-KDE-Keywords[ga]=dvi +X-KDE-Keywords[gl]=dvi +X-KDE-Keywords[hu]=dvi +X-KDE-Keywords[ia]=dvi +X-KDE-Keywords[is]=dvi +X-KDE-Keywords[it]=dvi +X-KDE-Keywords[ja]=dvi +X-KDE-Keywords[kk]=dvi +X-KDE-Keywords[km]=dvi +X-KDE-Keywords[ko]=dvi +X-KDE-Keywords[lt]=dvi +X-KDE-Keywords[lv]=dvi +X-KDE-Keywords[mr]=dvi +X-KDE-Keywords[nb]=dvi +X-KDE-Keywords[nds]=DVI +X-KDE-Keywords[nl]=dvi +X-KDE-Keywords[nn]=dvi +X-KDE-Keywords[pa]=dvi +X-KDE-Keywords[pl]=dvi +X-KDE-Keywords[pt]=dvi +X-KDE-Keywords[pt_BR]=dvi +X-KDE-Keywords[ro]=dvi +X-KDE-Keywords[ru]=dvi +X-KDE-Keywords[sk]=dvi +X-KDE-Keywords[sl]=dvi +X-KDE-Keywords[sr]=dvi,ДВИ +X-KDE-Keywords[sr@ijekavian]=dvi,ДВИ +X-KDE-Keywords[sr@ijekavianlatin]=dvi,DVI +X-KDE-Keywords[sr@latin]=dvi,DVI +X-KDE-Keywords[sv]=dvi +X-KDE-Keywords[tr]=dvi +X-KDE-Keywords[ug]=dvi +X-KDE-Keywords[uk]=dvi +X-KDE-Keywords[x-test]=xxdvixx +X-KDE-Keywords[zh_CN]=dvi +X-KDE-Keywords[zh_TW]=dvi diff --git a/generators/dvi/org.kde.okular-dvi.metainfo.xml b/generators/dvi/org.kde.okular-dvi.metainfo.xml new file mode 100644 index 0000000..ed0dfcf --- /dev/null +++ b/generators/dvi/org.kde.okular-dvi.metainfo.xml @@ -0,0 +1,93 @@ + + + org.kde.okular-dvi + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + DVI Documents + DVI sənədləri + Documents DVI + Documents DVI + Dokumenty DVI + DVI-Dokumente + Έγγραφα DVI + DVI Documents + Documentos DVI + DVI dokumendid + DVI dokumentuak + DVI-tiedostot + Documents « DVI » + Documentos DVI + Documentos DVI + Documenti DVI + DVI 문서 + DVI dokumentai + ഡിവിഐ പ്രമാണങ്ങൾ + DVI-documenten + DVI-dokument + Dokumenty DVI + Documentos DVI + Documentos DVI + Документы DVI + DVI dokumenty + Dokumenti DVI + ДВИ документи + DVI dokumenti + ДВИ документи + DVI dokumenti + DVI-dokument + DVI Belgeleri + документи DVI + xxDVI Documentsxx + DVI 文档 + DVI 文件 + Adds support for reading DVI documents + DjVu sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents DVI + Afig la implementació per a llegir documents DVI + Přidává podporu pro čtení dokumentů DVI + Bietet Unterstützung zum Lesen von DVI-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων DVI + Adds support for reading DVI documents + Permite la lectura de documentos DVI + DVI dokumentide lugemise toetus + DVI dokumentuak irakurtzeko euskarria gehitzen du + Lisää DVI-tiedostojen lukutuen + Permet la lecture des documents DVI + Engade a posibilidade de ler documentos DVI + Adde supporto per leger documentos DVI + Aggiunge il supporto per la lettura di documenti DVI + DVI 문서 읽기 지원 추가 + Prideda palaikymą DVI dokumentų skaitymui + ഡിവിഐ പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van DVI-documenten toe + Legg til støtte for å lesa DVI-dokument + Dodaje obsługę dokumentów DVI + Adiciona o suporte para a leitura de documentos DVI + Adiciona o suporte para leitura de documentos DVI + Поддержка чтения документов DVI + Pridá podporu pre čítanie DVI dokumentov + Doda podporo za branje dokumentov DVI + Подршка за читање ДВИ докумената + Podrška za čitanje DVI dokumenata + Подршка за читање ДВИ докумената + Podrška za čitanje DVI dokumenata + Lägger till stöd för att läsa DVI-dokument + DVI belgelerini okuma desteği ekler + Додає підтримку читання документів DVI + xxAdds support for reading DVI documentsxx + 增加对 DVI 文档的阅读支持 + 加入讀取 DVI 文件的支援 + + application/x-dvi + application/x-gzdvi + application/x-dzdvi + + https://okular.kde.org + + + + + + + diff --git a/generators/dvi/pageNumber.h b/generators/dvi/pageNumber.h new file mode 100644 index 0000000..008165c --- /dev/null +++ b/generators/dvi/pageNumber.h @@ -0,0 +1,78 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// pageNumber.h +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2004 Stefan Kebekus +// Distributed under the GPL + +#ifndef PAGENUMBER_H +#define PAGENUMBER_H + +#include + +/** \brief Class to represent a page number + +The class PageNumber is really nothing but an alias for quint16, and +can be casted to and from quint16. It is used in kviewshell to remind +the programmer of the convention that page numbers start at '1' (for +'first page'), and that the value '0' means 'illegal page number' or +'no page number'. Accordingly, the value '0' is also named +PageNumber::invalidPage, and there is a trivial method isInvalid() +that checks if the page number is 0. + +@author Stefan Kebekus +@version 1.0 0 +*/ + +class PageNumber +{ +public: + enum pageNums { + invalidPage = 0 /*! Invalid page number */ + }; + + /** The default constructor sets the page number to 'invalidPage' */ + PageNumber() + { + pgNum = invalidPage; + } + + /** \brief Constructor that sets the page number + + @param num page number that is set initially + */ + PageNumber(quint16 num) + { + pgNum = num; + } + + /** \brief this method implements typecasts from quint16 */ + PageNumber &operator=(const quint16 p) + { + pgNum = p; + return *this; + } + + /** \brief This method implements typecasts to quint16 */ + operator quint16() const + { + return pgNum; + } + + /** \brief Checks if the page number is invalid + + @returns true, if pgNum != invalidPage, i.e., does not equal 0 + */ + bool isValid() const + { + return (pgNum != invalidPage); + } + +private: + /** \brief Single number that represents the page number */ + quint16 pgNum; +}; + +#endif diff --git a/generators/dvi/pageSize.cpp b/generators/dvi/pageSize.cpp new file mode 100644 index 0000000..ab1da21 --- /dev/null +++ b/generators/dvi/pageSize.cpp @@ -0,0 +1,330 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// pageSize.cpp +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2002-2003 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "debug_dvi.h" +#include "length.h" +#include "pageSize.h" + +#include + +#include + +struct pageSizeItem { + const char *name; + float width; // in mm + float height; // in mm + const char *preferredUnit; +}; + +#define defaultMetricPaperSize 4 // Default paper size is "DIN A4" +#define defaultImperialPaperSize 8 // Default paper size is "US Letter" + +static const pageSizeItem staticList[] = { + {"DIN A0", 841.0f, 1189.0f, "mm"}, + {"DIN A1", 594.0f, 841.0f, "mm"}, + {"DIN A2", 420.0f, 594.0f, "mm"}, + {"DIN A3", 297.0f, 420.0f, "mm"}, + {"DIN A4", 210.0f, 297.0f, "mm"}, + {"DIN A5", 148.5f, 210.0f, "mm"}, + {"DIN B4", 250.0f, 353.0f, "mm"}, + {"DIN B5", 176.0f, 250.0f, "mm"}, + {"US Letter", 215.9f, 279.4f, "in"}, + {"US Legal", 215.9f, 355.6f, "in"}, + {nullptr, 0.0f, 0.0f, nullptr} // marks the end of the list. +}; + +pageSize::pageSize() +{ + currentSize = defaultPageSize(); + pageWidth.setLength_in_mm(staticList[currentSize].width); + pageHeight.setLength_in_mm(staticList[currentSize].height); +} + +pageSize::pageSize(const SimplePageSize &s) +{ + pageWidth = s.width(); + pageHeight = s.height(); + + rectifySizes(); + reconstructCurrentSize(); +} + +bool pageSize::setPageSize(const QString &name) +{ + // See if we can recognize the string + QString currentName; + for (int i = 0; staticList[i].name != nullptr; i++) { + currentName = QString::fromLocal8Bit(staticList[i].name); + if (currentName == name) { + currentSize = i; + // Set page width/height accordingly + pageWidth.setLength_in_mm(staticList[currentSize].width); + pageHeight.setLength_in_mm(staticList[currentSize].height); + emit sizeChanged(*this); + return true; + } + } + + // Check if the string contains 'x'. If yes, we assume it is of type + // "x". If yes, the first number is interpreted as + // the width in mm, the second as the height in mm + if (name.indexOf(QLatin1Char('x')) >= 0) { + bool wok, hok; + float pageWidth_tmp = name.section(QLatin1Char('x'), 0, 0).toFloat(&wok); + float pageHeight_tmp = name.section(QLatin1Char('x'), 1, 1).toFloat(&hok); + if (wok && hok) { + pageWidth.setLength_in_mm(pageWidth_tmp); + pageHeight.setLength_in_mm(pageHeight_tmp); + + rectifySizes(); + reconstructCurrentSize(); + emit sizeChanged(*this); + return true; + } + } + + // Check if the string contains ','. If yes, we assume it is of type + // ",". The first number is supposed to + // be the width, the second the height. + if (name.indexOf(QLatin1Char(',')) >= 0) { + bool wok, hok; + float pageWidth_tmp = Length::convertToMM(name.section(QLatin1Char(','), 0, 0), &wok); + float pageHeight_tmp = Length::convertToMM(name.section(QLatin1Char(','), 1, 1), &hok); + if (wok && hok) { + pageWidth.setLength_in_mm(pageWidth_tmp); + pageHeight.setLength_in_mm(pageHeight_tmp); + + rectifySizes(); + reconstructCurrentSize(); + emit sizeChanged(*this); + return true; + } + } + + // Last resource. Set the default, in case the string is + // unintelligible to us. + currentSize = defaultPageSize(); + pageWidth.setLength_in_mm(staticList[currentSize].width); + pageHeight.setLength_in_mm(staticList[currentSize].height); + qCCritical(OkularDviShellDebug) << "pageSize::setPageSize: could not parse '" << name << "'. Using " << staticList[currentSize].name << " as a default." << endl; + emit sizeChanged(*this); + return false; +} + +void pageSize::setPageSize(double width, double height) +{ + SimplePageSize oldPage = *this; + + pageWidth.setLength_in_mm(width); + pageHeight.setLength_in_mm(height); + + rectifySizes(); + reconstructCurrentSize(); + if (!isNearlyEqual(oldPage)) + emit sizeChanged(*this); +} + +void pageSize::setPageSize(const QString &width, const QString &_widthUnits, const QString &height, const QString &_heightUnits) +{ + SimplePageSize oldPage = *this; + + double w = width.toFloat(); + double h = height.toFloat(); + + QString widthUnits = _widthUnits; + if ((widthUnits != QLatin1String("cm")) && (widthUnits != QLatin1String("mm")) && (widthUnits != QLatin1String("in"))) { + qCCritical(OkularDviShellDebug) << "Unrecognized page width unit '" << widthUnits << "'. Assuming mm" << endl; + widthUnits = QStringLiteral("mm"); + } + pageWidth.setLength_in_mm(w); + if (widthUnits == QLatin1String("cm")) + pageWidth.setLength_in_cm(w); + if (widthUnits == QLatin1String("in")) + pageWidth.setLength_in_inch(w); + + QString heightUnits = _heightUnits; + if ((heightUnits != QLatin1String("cm")) && (heightUnits != QLatin1String("mm")) && (heightUnits != QLatin1String("in"))) { + qCCritical(OkularDviShellDebug) << "Unrecognized page height unit '" << widthUnits << "'. Assuming mm" << endl; + heightUnits = QStringLiteral("mm"); + } + pageHeight.setLength_in_mm(h); + if (heightUnits == QLatin1String("cm")) + pageHeight.setLength_in_cm(h); + if (heightUnits == QLatin1String("in")) + pageHeight.setLength_in_inch(h); + + rectifySizes(); + reconstructCurrentSize(); + if (!isNearlyEqual(oldPage)) + emit sizeChanged(*this); +} + +void pageSize::rectifySizes() +{ + // Now do some sanity checks to make sure that values are not + // outrageous. We allow values between 5cm and 50cm. + if (pageWidth.getLength_in_mm() < 50) + pageWidth.setLength_in_mm(50.0); + if (pageWidth.getLength_in_mm() > 1200) + pageWidth.setLength_in_mm(1200); + if (pageHeight.getLength_in_mm() < 50) + pageHeight.setLength_in_mm(50); + if (pageHeight.getLength_in_mm() > 1200) + pageHeight.setLength_in_mm(1200); + return; +} + +QString pageSize::preferredUnit() const +{ + if (currentSize >= 0) + return QString::fromLocal8Bit(staticList[currentSize].preferredUnit); + + // User-defined size. Give a preferred unit depending on the locale. + if (QLocale::system().measurementSystem() == QLocale::MetricSystem) + return QStringLiteral("mm"); + else + return QStringLiteral("in"); +} + +QString pageSize::widthString(const QString &unit) const +{ + QString answer = QStringLiteral("--"); + + if (unit == QLatin1String("cm")) + answer.setNum(pageWidth.getLength_in_cm()); + if (unit == QLatin1String("mm")) + answer.setNum(pageWidth.getLength_in_mm()); + if (unit == QLatin1String("in")) + answer.setNum(pageWidth.getLength_in_inch()); + + return answer; +} + +QString pageSize::heightString(const QString &unit) const +{ + QString answer = QStringLiteral("--"); + + if (unit == QLatin1String("cm")) + answer.setNum(pageHeight.getLength_in_cm()); + if (unit == QLatin1String("mm")) + answer.setNum(pageHeight.getLength_in_mm()); + if (unit == QLatin1String("in")) + answer.setNum(pageHeight.getLength_in_inch()); + + return answer; +} + +QStringList pageSize::pageSizeNames() +{ + QStringList names; + + for (int i = 0; staticList[i].name != nullptr; i++) + names << QString::fromLocal8Bit(staticList[i].name); + + return names; +} + +QString pageSize::formatName() const +{ + if (currentSize >= 0) + return QString::fromLocal8Bit(staticList[currentSize].name); + else + return QString(); +} + +int pageSize::getOrientation() const +{ + if (currentSize == -1) { + qCCritical(OkularDviShellDebug) << "pageSize::getOrientation: getOrientation called for page format that does not have a name." << endl; + return 0; + } + + if (pageWidth.getLength_in_mm() == staticList[currentSize].width) + return 0; + else + return 1; +} + +void pageSize::setOrientation(int orient) +{ + if (currentSize == -1) { + qCCritical(OkularDviShellDebug) << "pageSize::setOrientation: setOrientation called for page format that does not have a name." << endl; + return; + } + + if (orient == 1) { + pageWidth.setLength_in_mm(staticList[currentSize].height); + pageHeight.setLength_in_mm(staticList[currentSize].width); + } else { + pageWidth.setLength_in_mm(staticList[currentSize].width); + pageHeight.setLength_in_mm(staticList[currentSize].height); + } + emit sizeChanged(*this); +} + +QString pageSize::serialize() const +{ + if ((currentSize >= 0) && (fabs(staticList[currentSize].height - pageHeight.getLength_in_mm()) <= 0.5)) + return QString::fromLocal8Bit(staticList[currentSize].name); + else + return QStringLiteral("%1x%2").arg(pageWidth.getLength_in_mm()).arg(pageHeight.getLength_in_mm()); +} + +QString pageSize::description() const +{ + if (!isValid()) + return QString(); + + QString size = QStringLiteral(" "); + if (formatNumber() == -1) { + if (QLocale::system().measurementSystem() == QLocale::MetricSystem) + size += QStringLiteral("%1x%2 mm").arg(width().getLength_in_mm(), 0, 'f', 0).arg(height().getLength_in_mm(), 0, 'f', 0); + else + size += QStringLiteral("%1x%2 in").arg(width().getLength_in_inch(), 0, 'g', 2).arg(height().getLength_in_inch(), 0, 'g', 2); + } else { + size += formatName() + QLatin1Char('/'); + if (getOrientation() == 0) + size += i18n("portrait"); + else + size += i18n("landscape"); + } + return size + QLatin1Char(' '); +} + +void pageSize::reconstructCurrentSize() +{ + for (int i = 0; staticList[i].name != nullptr; i++) { + if ((fabs(staticList[i].width - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].height - pageHeight.getLength_in_mm()) <= 2)) { + currentSize = i; + pageWidth.setLength_in_mm(staticList[currentSize].width); + pageHeight.setLength_in_mm(staticList[currentSize].height); + return; + } + if ((fabs(staticList[i].height - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].width - pageHeight.getLength_in_mm()) <= 2)) { + currentSize = i; + pageWidth.setLength_in_mm(staticList[currentSize].height); + pageHeight.setLength_in_mm(staticList[currentSize].width); + return; + } + } + currentSize = -1; + return; +} + +int pageSize::defaultPageSize() +{ + // FIXME: static_cast(KLocale::global()->pageSize()) + // is the proper solution here. Then you can determine the values + // without using your hardcoded table too! + if (QLocale::system().measurementSystem() == QLocale::MetricSystem) + return defaultMetricPaperSize; + else + return defaultImperialPaperSize; +} diff --git a/generators/dvi/pageSize.h b/generators/dvi/pageSize.h new file mode 100644 index 0000000..b83183d --- /dev/null +++ b/generators/dvi/pageSize.h @@ -0,0 +1,280 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// pageSize.h +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2002-2005 Stefan Kebekus +// Distributed under the GPL + +#ifndef PAGESIZE_H +#define PAGESIZE_H + +#include "simplePageSize.h" + +#include + +class QString; +class QStringList; + +/* \brief This class represents physical page sizes. + +The main difference to the SimplePageSize class are the following. + +- This class knows about standard page sizes and accepts page sizes in + various formats, e.g. as a string "DIN A4", or by specifying the + page width and height. Several units (inch, millimeters, + centimeters) are possible. + +- It is made sure that page width an height are always in a reasonable + range, which is currently set to 5cm .. 50cm + +- The default constructor provides a locale-depending default. + +@author Stefan Kebekus +@version 1.0.0 +*/ + +class pageSize : public QObject, public SimplePageSize +{ + Q_OBJECT + +public: + /** \brief Default constructor, initializes the pageSize with a + reasonable default + + The default chosen depends on the locale. At the moment, A4 size + is chosen for countries with metric measurement system, and US + letter otherwise. + */ + pageSize(); + + /** \brief Initializes the pageSize with a SimplePageSize. */ + pageSize(const SimplePageSize &); + + pageSize(const pageSize &) = delete; + pageSize &operator=(const pageSize &) = delete; + + /** \brief List of standard pageSizes + + This method returns the names of standard pageSizes, + e.g. "A4". These can be used, e.g., by a QComboBox to let the user + choose known sizes. The returned list is also a list of all possible + return values of the formatName() method explained below. If you + call pageSizeNames() more than once, it is guaranteed that the + same list of strings will be returned. + + @returns QStringList that contains + */ + QStringList pageSizeNames(); + + /** \brief Set page size by name. + + Acceptable strings are + + (1) a name from the list returned by pageSizeNames(), such as "DIN + A4" + + (2) a string like "500x300", which describes a page of width 500mm + and height 300mm. + + (3) a string like "3in, 4 cm". A number of different units, + including "in", "mm" and "cm", and a few typographical units are + recognized + + If the name is not of these types, and error message is printed to + stderr using kError() and a default value, which depends on the + locale, is set. + + In any case, the values will be trimmed so as not to exceed the + minima/maxima of 5cm and 50cm, respectively. If the page size found + matches one of the standard sizes by an error of no more than 2mm, + the standard page size will be set. The signal sizeChanged() will + always be emitted. + + @param name string that represents the page size + + @returns 'True', if the parameter could be parsed, and 'false' + otherwise. + */ + bool setPageSize(const QString &name); + + /** \brief Set page size from width and height strings + + Sets the page size to "width" and "height", given in the associated + units. Currently, "mm", "cm" and "in" are supported. If a unit is + not recognized, "mm" is silently assumed, and error message is + printed to stderr using kError(). If the page size set matches one + of the standard sizes by an error of no more than 2mm, the standard + page size will be set. If width or height does not contain a + number, the result is an undefined value. However, it is guaranteed + in any case that both width and height are between the minimal and + maximal possible values, i.e. in the range 5..50 cm. If the newly + set value differs from the old value by more that 2mm for width or + height, the signal sizeChanged() will be emitted + + @param width string that represents the page width as a number, + e.g., " 300 " + + @param widthUnits units for the width string. Currently "mm", "cm" + and "in" are allowed. + + @param height string that represents the page height as a number, + e.g., " 300 " + + @param heightUnits units for the height string. Currently "mm", "cm" + and "in" are allowed. + */ + void setPageSize(const QString &width, const QString &widthUnits, const QString &height, const QString &heightUnits); + + /** \brief Set page size + + Sets the page size to "width" and "height", given in millimeter. If + the page size set matches one of the standard sizes by an error of + no more than 2mm, the standard page size will be set. Values are + trimmed so that both width and height are between the minimal and + maximal possible values, i.e. in the range 5..50 cm. If the newly + set value differs from the old value by more that 2mm for width or + height, the signal sizeChanged() will be emitted + + @param width_in_mm page width in mm + + @param height_in_mm page height in mm + */ + void setPageSize(double width_in_mm, double height_in_mm); + using SimplePageSize::setPageSize; + + /** \brief Preferred unit for the current page size + + @returns The name of the unit, one of "cm", "mm" or "in", which is + most commonly used with the current page format. For instance, + US Letter and US Legal are best given in inches, to avoid very + odd numbers. If the page format is unknown, returns a guess + based on the current locale. */ + QString preferredUnit() const; + + /** \brief Returns the page width as a string + + @param unit The unit in which the page width shall be returned. This + must be one of "cm", "mm" or "in". + + @returns a string containing a number, e.g. "3.1415", which gives the page + width in the given unit. If the unit is not recognized, the string "--" is returned. + */ + QString widthString(const QString &unit) const; + + /** \brief Returns the page height as a string + + @param unit The unit in height the page width shall be + returned. This must be one of "cm", "mm" or "in". + + @returns a string containing a number which gives the page height in + the given unit. If the unit is not recognized, the string "--" is + returned. + */ + QString heightString(const QString &unit) const; + + /** \brief Returns a name for the page size, if this is a standard + size + + @warning This method does not take care of orientation, e.g. it + will return "DIN A4" if the page size is either 210x297 or + 297x210. + + @returns A name for the current page size, if the format has a + name, or QString() otherwise. If the result is not + QString(), it is guaranteed to be one of the strings + returned by the pageSizeNames() method. + */ + QString formatName() const; + + /** \brief Returns an number for the page size, if this is a + standard size + + @warning This method does not take care of orientation, e.g. it + will return the same value if the page size is either 210x297 or + 297x210. + + @returns If the current format is one of the standard sizes, a + non-negative integer is returned, which is an index to the + QStringList returned by the pageSizeNames() method. If the + current format is none of the standard sizes, -1 is returned. + */ + int formatNumber() const + { + return currentSize; + } + + /** \brief Gets orientation for standard sizes + + If the pageSize is one of the standard sizes, i.e. formatNumber() != + -1, this method can be used to get the orientation. If the pageSize + is not a standard size, this method prints an error message stderr + using kError(). + + @returns 0 for 'portrait', or 1 for 'landscape'. If the size is none + of the standard sizes, an undefined value is returned. + */ + int getOrientation() const; + + /** \brief Returns a string that can be read by setPageSize(QString) + + @returns This method returns a string like "210x297". The numbers + are page width and height in millimeters. The setPageSize(QString) + method will understand this output. + */ + QString serialize() const; + + /** \brief Returns a textual description of the page size. */ + QString description() const; + +public Q_SLOTS: + /** \brief Sets orientation + + If the pageSize is one of the standard sizes, i.e. formatNumber() != + -1, this method can be used to set the orientation. If the pageSize + is not a standard size, this method prints an error message stderr + using kError() and does nothing. + + @param orient 0 sets 'portrait orientation', 1 sets 'landscape' + */ + void setOrientation(int orient); + +Q_SIGNALS: + /** \brief Signal emitted when the page sizes changes + + emitted to indicate that the size changed. Not emitted immediately + after construction, when the constructor sets the default + size. + + @param t a pointer to this + */ + void sizeChanged(const SimplePageSize &t); + +private: + /** Makes sure that pageWidth and pageHeight are in the permissible + range and not, e.g., negative. */ + void rectifySizes(); + + /** Tries to find one of the known sizes which matches pageWidth and + pageHeight, with an error margin of 2 millimeters. If found, the + value of 'currentsize' is set to point to the known size, and + pageWidth and pageHeight are set to the correct values for that + size. Otherwise, currentSize is set to -1 to indicate "custom + size". Note: this method does not take care of orientation, + e.g. the method will set 'currentsize' to point to "DIN A4" if + either the page size is 210x297 or 297x210. */ + void reconstructCurrentSize(); + + /** Gives a default value for currentSize, which depends on the + locale. In countries with metric system, this will be "DIN A4", + in countries with the imperial system, "US Letter". */ + int defaultPageSize(); + + /** Permissible range: 0--#Size_of_array staticList, or -1 to + indicate a "user defined setting". Other values may lead to a + segfault. */ + int currentSize; +}; + +#endif diff --git a/generators/dvi/prebookmark.h b/generators/dvi/prebookmark.h new file mode 100644 index 0000000..4e70c70 --- /dev/null +++ b/generators/dvi/prebookmark.h @@ -0,0 +1,58 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/*************************************************************************** + * Copyright (C) 2005 by Stefan Kebekus * + * kebekus@kde.org * + * * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _PREBOOKMARK_H_ +#define _PREBOOKMARK_H_ + +/*! \brief Bookmark representation + +This class presents a bookmark in a format that is used internally by +the DVI prescan routines. +*/ + +class PreBookmark +{ +public: + PreBookmark() + { + title.clear(); + anchorName.clear(); + noOfChildren = 0; + } + PreBookmark(const QString &t, const QString &a, quint16 n) + { + title = t; + anchorName = a; + noOfChildren = n; + } + + // Title of the bookmark + QString title; + + // Name of the anchor + QString anchorName; + + // Number of subordinate bookmarks + quint16 noOfChildren; +}; + +#endif diff --git a/generators/dvi/psgs.cpp b/generators/dvi/psgs.cpp new file mode 100644 index 0000000..8126f4a --- /dev/null +++ b/generators/dvi/psgs.cpp @@ -0,0 +1,353 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// ghostscript_interface +// +// Part of KDVI - A framework for multipage text/gfx viewers +// +// (C) 2004 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "debug_dvi.h" +#include "dviFile.h" +#include "pageNumber.h" +#include "psgs.h" +#include "psheader.cpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +//#define DEBUG_PSGS + +// extern char psheader[]; + +pageInfo::pageInfo(const QString &_PostScriptString) +{ + PostScriptString = new QString(_PostScriptString); + background = Qt::white; + permanentBackground = Qt::white; +} + +pageInfo::~pageInfo() +{ + if (PostScriptString != nullptr) + delete PostScriptString; +} + +// ====================================================== + +ghostscript_interface::ghostscript_interface() +{ + PostScriptHeaderString = new QString(); + + knownDevices.append(QStringLiteral("png16m")); + knownDevices.append(QStringLiteral("jpeg")); + knownDevices.append(QStringLiteral("pnn")); + knownDevices.append(QStringLiteral("pnnraw")); + gsDevice = knownDevices.begin(); +} + +ghostscript_interface::~ghostscript_interface() +{ + if (PostScriptHeaderString != nullptr) + delete PostScriptHeaderString; + qDeleteAll(pageList); +} + +void ghostscript_interface::setPostScript(const PageNumber page, const QString &PostScript) +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::setPostScript( " << page << ", ... )"; +#endif + + if (pageList.value(page) == nullptr) { + pageInfo *info = new pageInfo(PostScript); + // Check if dict is big enough + if (pageList.count() > pageList.capacity() - 2) + pageList.reserve(pageList.capacity() * 2); + pageList.insert(page, info); + } else + *(pageList.value(page)->PostScriptString) = PostScript; +} + +void ghostscript_interface::setIncludePath(const QString &_includePath) +{ + if (_includePath.isEmpty()) + includePath = QLatin1Char('*'); // Allow all files + else + includePath = _includePath + QStringLiteral("/*"); +} + +void ghostscript_interface::setBackgroundColor(const PageNumber page, const QColor &background_color, bool permanent) +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::setBackgroundColor( " << page << ", " << background_color << " )"; +#endif + + if (pageList.value(page) == nullptr) { + pageInfo *info = new pageInfo(QString()); + info->background = background_color; + if (permanent) + info->permanentBackground = background_color; + // Check if dict is big enough + if (pageList.count() > pageList.capacity() - 2) + pageList.reserve(pageList.capacity() * 2); + pageList.insert(page, info); + } else { + pageList.value(page)->background = background_color; + if (permanent) + pageList.value(page)->permanentBackground = background_color; + } +} + +void ghostscript_interface::restoreBackgroundColor(const PageNumber page) +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::restoreBackgroundColor( " << page << " )"; +#endif + if (pageList.value(page) == nullptr) + return; + + pageInfo *info = pageList.value(page); + info->background = info->permanentBackground; +} + +// Returns the background color for a certain page. This color is +// always guaranteed to be valid + +QColor ghostscript_interface::getBackgroundColor(const PageNumber page) const +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::getBackgroundColor( " << page << " )"; +#endif + + if (pageList.value(page) == nullptr) + return Qt::white; + else + return pageList.value(page)->background; +} + +void ghostscript_interface::clear() +{ + PostScriptHeaderString->truncate(0); + + // Deletes all items, removes temporary files, etc. + qDeleteAll(pageList); + pageList.clear(); +} + +void ghostscript_interface::gs_generate_graphics_file(const PageNumber page, const QString &filename, long magnification) +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::gs_generate_graphics_file( " << page << ", " << filename << " )"; +#endif + + if (knownDevices.isEmpty()) { + qCCritical(OkularDviDebug) << "No known devices found" << endl; + return; + } + + pageInfo *info = pageList.value(page); + + // Generate a PNG-file + // Step 1: Write the PostScriptString to a File + QTemporaryFile PSfile(QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + PSfile.setAutoRemove(false); + PSfile.open(); + const QString PSfileName = PSfile.fileName(); + + QTextStream os(&PSfile); + os << "%!PS-Adobe-2.0\n" + << "%%Creator: kdvi\n" + << "%%Title: KDVI temporary PostScript\n" + << "%%Pages: 1\n" + << "%%PageOrder: Ascend\n" + // HSize and VSize in 1/72 inch + << "%%BoundingBox: 0 0 " << (qint32)(72 * (pixel_page_w / resolution)) << ' ' << (qint32)(72 * (pixel_page_h / resolution)) << '\n' + << "%%EndComments\n" + << "%!\n" + << psheader + << "TeXDict begin " + // HSize in (1/(65781.76*72))inch + << (qint32)(72 * 65781 * (pixel_page_w / resolution)) + << ' ' + // VSize in (1/(65781.76*72))inch + << (qint32)(72 * 65781 * (pixel_page_h / resolution)) + << ' ' + // Magnification + << (qint32)(magnification) + // dpi and vdpi + << " 300 300" + // Name + << " (test.dvi)" + << " @start end\n" + << "TeXDict begin\n" + // Start page + << "1 0 bop 0 0 a \n"; + + if (!PostScriptHeaderString->toLatin1().isNull()) + os << PostScriptHeaderString->toLatin1(); + + if (info->background != Qt::white) { + QString colorCommand = QStringLiteral("gsave %1 %2 %3 setrgbcolor clippath fill grestore\n").arg(info->background.red() / 255.0).arg(info->background.green() / 255.0).arg(info->background.blue() / 255.0); + os << colorCommand.toLatin1(); + } + + if (!info->PostScriptString->isNull()) + os << *(info->PostScriptString); + + os << "end\n" + << "showpage \n"; + + PSfile.close(); + + // Step 2: Call GS with the File + QFile::remove(filename); + KProcess proc; + proc.setOutputChannelMode(KProcess::SeparateChannels); + QStringList argus; + argus << QStringLiteral("gs"); + argus << QStringLiteral("-dSAFER") << QStringLiteral("-dPARANOIDSAFER") << QStringLiteral("-dDELAYSAFER") << QStringLiteral("-dNOPAUSE") << QStringLiteral("-dBATCH"); + argus << QStringLiteral("-sDEVICE=%1").arg(*gsDevice); + argus << QStringLiteral("-sOutputFile=%1").arg(filename); + argus << QStringLiteral("-sExtraIncludePath=%1").arg(includePath); + argus << QStringLiteral("-g%1x%2").arg(pixel_page_w).arg(pixel_page_h); // page size in pixels + argus << QStringLiteral("-r%1").arg(resolution); // resolution in dpi + argus << QStringLiteral("-dTextAlphaBits=4 -dGraphicsAlphaBits=2"); // Antialiasing + argus << QStringLiteral("-c") << QStringLiteral("<< /PermitFileReading [ ExtraIncludePath ] /PermitFileWriting [] /PermitFileControl [] >> setuserparams .locksafe"); + argus << QStringLiteral("-f") << PSfileName; + +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << argus.join(" "); +#endif + + proc << argus; + int res = proc.execute(); + + if (res) { + // Starting ghostscript did not work. + // TODO: Issue error message, switch PS support off. + qCCritical(OkularDviDebug) << "ghostview could not be started" << endl; + } + + PSfile.remove(); + + // Check if gs has indeed produced a file. + if (QFile::exists(filename) == false) { + qCCritical(OkularDviDebug) << "GS did not produce output." << endl; + + // No. Check is the reason is that the device is not compiled into + // ghostscript. If so, try again with another device. + QString GSoutput; + proc.setReadChannel(QProcess::StandardOutput); + while (proc.canReadLine()) { + GSoutput = QString::fromLocal8Bit(proc.readLine()); + if (GSoutput.contains(QStringLiteral("Unknown device"))) { + qCDebug(OkularDviDebug) << QString::fromLatin1( + "The version of ghostview installed on this computer does not support " + "the '%1' ghostview device driver.") + .arg(*gsDevice) + << endl; + knownDevices.erase(gsDevice); + gsDevice = knownDevices.begin(); + if (knownDevices.isEmpty()) + // TODO: show a requestor of some sort. + emit error(i18n("The version of Ghostview that is installed on this computer does not contain " + "any of the Ghostview device drivers that are known to Okular. PostScript " + "support has therefore been turned off in Okular."), + -1); +#if 0 + i18n("

The Ghostview program, which Okular uses internally to display the " + "PostScript graphics that is included in this DVI file, is generally able to " + "write its output in a variety of formats. The sub-programs that Ghostview uses " + "for these tasks are called 'device drivers'; there is one device driver for " + "each format that Ghostview is able to write. Different versions of Ghostview " + "often have different sets of device drivers available. It seems that the " + "version of Ghostview that is installed on this computer does not contain " + "any of the device drivers that are known to Okular.

" + "

It seems unlikely that a regular installation of Ghostview would not contain " + "these drivers. This error may therefore point to a serious misconfiguration of " + "the Ghostview installation on your computer.

" + "

If you want to fix the problems with Ghostview, you can use the command " + "gs --help to display the list of device drivers contained in " + "Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " + "drivers. Note that Okular needs to be restarted to re-enable PostScript support." + "

")); +#endif + else { + qCDebug(OkularDviDebug) << QStringLiteral("Okular will now try to use the '%1' device driver.").arg(*gsDevice); + gs_generate_graphics_file(page, filename, magnification); + } + return; + } + } + } +} + +void ghostscript_interface::graphics(const PageNumber page, double dpi, long magnification, QPainter *paint) +{ +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "ghostscript_interface::graphics( " << page << ", " << dpi << ", ... ) called."; +#endif + + if (paint == nullptr) { + qCCritical(OkularDviDebug) << "ghostscript_interface::graphics(PageNumber page, double dpi, long magnification, QPainter *paint) called with paint == 0" << endl; + return; + } + + resolution = dpi; + + pixel_page_w = paint->viewport().width(); + pixel_page_h = paint->viewport().height(); + + pageInfo *info = pageList.value(page); + + // No PostScript? Then return immediately. + if ((info == nullptr) || (info->PostScriptString->isEmpty())) { +#ifdef DEBUG_PSGS + qCDebug(OkularDviDebug) << "No PostScript found. Not drawing anything."; +#endif + return; + } + + QTemporaryFile gfxFile; + gfxFile.open(); + const QString gfxFileName = gfxFile.fileName(); + // We are want the filename, not the file. + gfxFile.close(); + + gs_generate_graphics_file(page, gfxFileName, magnification); + + QImage MemoryCopy(gfxFileName); + paint->drawImage(0, 0, MemoryCopy); + return; +} + +QString ghostscript_interface::locateEPSfile(const QString &filename, const QUrl &base) +{ + // If the base URL indicates that the DVI file is local, try to find + // the graphics file in the directory where the DVI file resides + if (base.isLocalFile()) { + QString path = base.path(); // -> "/bar/foo.dvi" + QFileInfo fi1(path); + QFileInfo fi2(fi1.dir(), filename); + if (fi2.exists()) + return fi2.absoluteFilePath(); + } + + // Otherwise, use kpsewhich to find the eps file. + KProcess proc; + proc << QStringLiteral("kpsewhich") << filename; + proc.execute(); + return QString::fromLocal8Bit(proc.readLine().trimmed()); +} diff --git a/generators/dvi/psgs.h b/generators/dvi/psgs.h new file mode 100644 index 0000000..bb36f20 --- /dev/null +++ b/generators/dvi/psgs.h @@ -0,0 +1,110 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// ghostscript_interface +// +// Part of KDVI - A framework for multipage text/gfx viewers +// +// (C) 2004 Stefan Kebekus +// Distributed under the GPL + +#ifndef _PSGS_H_ +#define _PSGS_H_ + +#include +#include +#include +#include +#include + +class QUrl; +class PageNumber; +class QPainter; + +class pageInfo +{ +public: + pageInfo(const QString &_PostScriptString); + ~pageInfo(); + + pageInfo(const pageInfo &) = delete; + pageInfo &operator=(const pageInfo &) = delete; + + QColor background; + QColor permanentBackground; + QString *PostScriptString; +}; + +class ghostscript_interface : public QObject +{ + Q_OBJECT + +public: + ghostscript_interface(); + ~ghostscript_interface() override; + + void clear(); + + // sets the PostScript which is used on a certain page + void setPostScript(const PageNumber page, const QString &PostScript); + + // sets path from additional postscript files may be read + void setIncludePath(const QString &_includePath); + + // Sets the background color for a certain page. If permanent is false then the original + // background color can be restored by calling restoreBackground(page). + // The Option permanent = false is used when we want to display a different paper + // color as the one specified in the dvi file. + void setBackgroundColor(const PageNumber page, const QColor &background_color, bool permanent = true); + + // Restore the background to the color which was specified by the last call to setBackgroundColor() + // With option permanent = true. + void restoreBackgroundColor(const PageNumber page); + + // Draws the graphics of the page into the painter, if possible. If + // the page does not contain any graphics, nothing happens + void graphics(const PageNumber page, double dpi, long magnification, QPainter *paint); + + // Returns the background color for a certain page. If no color was + // set, Qt::white is returned. + QColor getBackgroundColor(const PageNumber page) const; + + QString *PostScriptHeaderString; + + /** This method tries to find the PostScript file 'filename' in the + DVI file's directory (if the base-URL indicates that the DVI file + is local), and, if that fails, uses kpsewhich to find the file. If + the file is found, the full path (including file name) is + returned. Otherwise, the method returns the first argument. TODO: + use the DVI file's baseURL, once this is implemented. + */ + static QString locateEPSfile(const QString &filename, const QUrl &base); + +private: + void gs_generate_graphics_file(const PageNumber page, const QString &filename, long magnification); + QHash pageList; + + double resolution; // in dots per inch + int pixel_page_w; // in pixels + int pixel_page_h; // in pixels + + QString includePath; + + // Output device that ghostscript is supposed tp use. Default is + // "png256". If that does not work, gs_generate_graphics_file will + // automatically try other known device drivers. If no known output + // device can be found, something is badly wrong. In that case, + // "gsDevice" is set to an empty string, and + // gs_generate_graphics_file will return immediately. + QList::iterator gsDevice; + + // A list of known devices, set by the constructor. This includes + // "png256", "pnm". If a device is found to not work, its name is + // removed from the list, and another device name is tried. + QStringList knownDevices; + +Q_SIGNALS: + /** Passed through to the top-level kpart. */ + void error(const QString &message, int duration); +}; + +#endif diff --git a/generators/dvi/psheader.cpp b/generators/dvi/psheader.cpp new file mode 100644 index 0000000..e91be89 --- /dev/null +++ b/generators/dvi/psheader.cpp @@ -0,0 +1,129 @@ +#ifndef _psheader_cpp_ +#define _psheader_cpp_ + +/* + * DO NOT EDIT THIS FILE! + * It was created by squeeze.c from another file (see the Makefile). + */ + +#ifndef _Xconst +#if __STDC__ +#define _Xconst const +#else +#define _Xconst +#endif +#endif + +_Xconst char psheader[] = + "\ +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S\n\ +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72\n\ +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0\n\ +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{\n\ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize\n\ +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[\n\ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round\n\ +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{\n\ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]\n\ +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin\n\ +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array\n\ +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2\n\ +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N\n\ +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A\n\ +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get\n\ +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}\n\ +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr\n\ +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3\n\ +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx\n\ +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx\n\ +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{\n\ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp\n\ +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B\n\ +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{\n\ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{\n\ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy\n\ +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}\n\ +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp\n\ +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17\n\ +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add\n\ +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{\n\ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}\n\ +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn\n\ +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put\n\ +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{\n\ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A\n\ +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{\n\ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{\n\ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X\n\ +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4\n\ +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N\n\ +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{\n\ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)\n\ +(LaserWriter 16/600)]{A length product length le{A length product exch 0\n\ +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse\n\ +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask\n\ +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}\n\ +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round\n\ +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto\n\ +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p\n\ +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}\n\ +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{\n\ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S\n\ +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end TeXDict\n\ +begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N /vs 792\n\ +N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N\n\ +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N\n\ +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{\n\ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho\n\ +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B\n\ +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{\n\ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known\n\ +{userdict/md get type/dicttype eq{userdict begin md length 10 add md\n\ +maxlength ge{/md md dup length 20 add dict copy def}if end md begin\n\ +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S\n\ +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{\n\ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll\n\ +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll\n\ +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf\n\ +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}\n\ +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1\n\ +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3\n\ +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip\n\ +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub\n\ +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{\n\ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop\n\ +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get\n\ +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr\n\ +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr\n\ +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4\n\ +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S\n\ +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{\n\ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale\n\ +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState\n\ +save N userdict maxlength dict begin/magscale true def normalscale\n\ +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts\n\ +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x\n\ +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx\n\ +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub\n\ +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{\n\ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2\n\ +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath\n\ +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict\n\ +begin/SpecialSave save N gsave normalscale currentpoint TR\n\ +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{\n\ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto\n\ +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx\n\ +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR\n\ +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse\n\ +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury\n\ +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N\n\ +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end}\n\ +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N\n\ +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX\n\ +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY\n\ +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X\n\ +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0\n\ +1 startangle endangle arc savematrix setmatrix}N end\n"; + +// int psheaderlen = 7620; +#endif diff --git a/generators/dvi/simplePageSize.cpp b/generators/dvi/simplePageSize.cpp new file mode 100644 index 0000000..0a14eda --- /dev/null +++ b/generators/dvi/simplePageSize.cpp @@ -0,0 +1,48 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// SimplePageSize.cpp +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2002-2005 Stefan Kebekus +// Distributed under the GPL + +#include + +#include "debug_dvi.h" +#include "simplePageSize.h" + +#include +#include + +double SimplePageSize::zoomForHeight(quint32 height, const QPaintDevice &pd) const +{ + if (!isValid()) { + qCCritical(OkularDviShellDebug) << "SimplePageSize::zoomForHeight() called when paper height was invalid" << endl; + return 0.1; + } + + return double(height) / (pd.logicalDpiY() * pageHeight.getLength_in_inch()); +} + +double SimplePageSize::zoomForWidth(quint32 width, const QPaintDevice &pd) const +{ + if (!isValid()) { + qCCritical(OkularDviShellDebug) << "SimplePageSize::zoomForWidth() called when paper width was invalid" << endl; + return 0.1; + } + + return double(width) / (pd.logicalDpiX() * pageWidth.getLength_in_inch()); +} + +double SimplePageSize::zoomToFitInto(const SimplePageSize &target) const +{ + if (!isValid() || isSmall() || !target.isValid()) { + qCWarning(OkularDviShellDebug) << "SimplePageSize::zoomToFitInto(...) with unsuitable source of target"; + return 1.0; + } + + double z1 = target.width() / pageWidth; + double z2 = target.height() / pageHeight; + + return qMin(z1, z2); +} diff --git a/generators/dvi/simplePageSize.h b/generators/dvi/simplePageSize.h new file mode 100644 index 0000000..77ad551 --- /dev/null +++ b/generators/dvi/simplePageSize.h @@ -0,0 +1,202 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +// +// simplePageSize.h +// +// Part of KVIEWSHELL - A framework for multipage text/gfx viewers +// +// (C) 2002-2004 Stefan Kebekus +// Distributed under the GPL + +#ifndef SIMPLEPAGESIZE_H +#define SIMPLEPAGESIZE_H + +#include "length.h" + +#include + +class QPaintDevice; + +/** \brief This class represents physical page sizes. + +This class represents page sizes. It contains nothing but two numbers, +the page width, and page height, and a few utility functions that +convert page sizes to pixel sizes and to compute the aspect ratio. A +page with width<=1mm or height<=1mm is considered invalid. pageSize is +a more elaborate class that is derived from SimplePageSize and knows +about standard paper sizes. + +@author Stefan Kebekus +@version 1.0 0 +*/ + +class SimplePageSize +{ +public: + /** Constructs an invalid SimplePageSize, with size 0x0mm */ + SimplePageSize() + { + pageWidth.setLength_in_mm(0.0); + pageHeight.setLength_in_mm(0.0); + } + + /** Constructs a SimplePagesize with given page width and height in + mm. Recall that if width or height is less or equal than 1mm, + the page size is considered 'invalid' by the isValid() + method. + + @param width + @param height + */ + SimplePageSize(const Length width, const Length height) + { + pageWidth = width; + pageHeight = height; + } + + ~SimplePageSize() + { + } + + /** \brief Sets the page width and height + + If width or height is less or equal than 1mm, the page size is + considered 'invalid' by the isValid() method. + + @param width + @param height + */ + void setPageSize(const Length width, const Length height) + { + pageWidth = width; + pageHeight = height; + } + + /** \brief Returns the page width. */ + Length width() const + { + return pageWidth; + } + + /** \brief Returns the page height. */ + Length height() const + { + return pageHeight; + } + + /** \brief Aspect ratio + + @returns if the paper size is valid, this method returns the ratio + width/height. Returns 1.0 otherwise. */ + double aspectRatio() const + { + return isValid() ? (pageWidth / pageHeight) : 1.0; + } + + /** \brief Converts the physical page size to a pixel size + + @param resolution in dots per inch + + @returns the pixel size, represented by a QSize. If the page size is + invalid, the result is undefined. */ + QSize sizeInPixel(double resolution) const + { + return QSize((int)(resolution * pageWidth.getLength_in_inch() + 0.5), (int)(resolution * pageHeight.getLength_in_inch() + 0.5)); + } + + /** \brief Zoom value required to scale to a certain height + + If the pageSize is valid, this method returns the zoom value + required to scale the page size down to 'height' pixels on the + currently used display. If the pageSize is invalid, + an error message is printed, and an undefined value is returned. + + @param height target height in pixels + @param pd the widget to be printed on. + + @returns the zoom value required to scale the page size down to + 'height' pixels. If the pageSize is invalid, an undefined value is + returned. + */ + double zoomForHeight(quint32 height, const QPaintDevice &pd) const; + + /** \brief Zoom value required to scale to a certain height + + If the pageSize is valid, this method returns the zoom value + required to scale the page size down to 'width' pixels on the + currently used display. If the pageSize is invalid, + an error message is printed, and an undefined value is returned. + + @param width target width in pixels + @param pd the widget to be printed on. + + @returns the zoom value required to scale the page size down to + 'width' pixels. If the pageSize is invalid, an undefined value is + returned. + */ + double zoomForWidth(quint32 width, const QPaintDevice &pd) const; + + /** \brief Returns a zoom to fit into a certain page size + + This method computes the larget zoom value such that *this, zoomed + by the computed values fits into the page size 'target'. If *this or + if target are invalid, or is this->isSmall() is true, an undefined + value is returned. If height or width of this is nearly 0.0, a + floating point exception may occur. + */ + double zoomToFitInto(const SimplePageSize &target) const; + + /** \brief Validity check + + @returns 'True' if the page width and height are both larger than + 1mm */ + bool isValid() const + { + return ((pageWidth.getLength_in_mm() > 1.0) && (pageHeight.getLength_in_mm() > 1.0)); + } + + /** \brief Validity check: + + @returns 'True' if the page ares is less than 1.0 square mm + */ + bool isSmall() const + { + return (pageWidth.getLength_in_mm() * pageHeight.getLength_in_mm() < 1.0); + } + + /** \brief Approximate equality + + @param size pageSize object to compare this object with + + @returns 'True' if height and width of the two objects differ by at + most 2mm, 'false' otherwise + */ + bool isNearlyEqual(const SimplePageSize &size) const + { + return (pageWidth.isNearlyEqual(size.pageWidth) && pageHeight.isNearlyEqual(size.pageHeight)); + } + + /** Test if paper size is higher than wide + + @returns 'True' if the paper size is higher than wide + */ + bool isPortrait() const + { + return (pageHeight >= pageWidth); + } + + /** Rotates by 90 degrees + + @returns a SimplePageSize with height and width swapped. The + original instance is unchanged. + */ + SimplePageSize rotate90() const + { + return SimplePageSize(pageHeight, pageWidth); + } + +protected: + Length pageWidth; + Length pageHeight; +}; + +#endif diff --git a/generators/dvi/special.cpp b/generators/dvi/special.cpp new file mode 100644 index 0000000..f7c696d --- /dev/null +++ b/generators/dvi/special.cpp @@ -0,0 +1,682 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- + +// special.cpp + +// Methods for dviRenderer which deal with "\special" commands found in the +// DVI file + +// Copyright 2000--2004, Stefan Kebekus (kebekus@kde.org). + +#include + +#include "debug_dvi.h" +#include "dviFile.h" +#include "dviRenderer.h" +#include "hyperlink.h" +#include "psgs.h" +//#include "renderedDocumentPage.h" + +#include +#include +#include + +#include "debug_dvi.h" +#include +#include +#include +#include +#include + +void dviRenderer::printErrorMsgForSpecials(const QString &msg) +{ + if (dviFile->errorCounter < 25) { + qCCritical(OkularDviDebug) << msg << endl; + dviFile->errorCounter++; + if (dviFile->errorCounter == 25) + qCCritical(OkularDviDebug) << i18n("That makes 25 errors. Further error messages will not be printed.") << endl; + } +} + +// Parses a color specification, as explained in the manual to +// dvips. If the spec could not be parsed, an invalid color will be +// returned. + +QColor dviRenderer::parseColorSpecification(const QString &colorSpec) +{ + // Initialize the map of known colors, if that is not done yet. + if (namedColors.isEmpty()) { + namedColors[QStringLiteral("Red")] = QColor((int)(255.0 * 1), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Tan")] = QColor((int)(255.0 * 0.86), (int)(255.0 * 0.58), (int)(255.0 * 0.44)); + namedColors[QStringLiteral("Blue")] = QColor((int)(255.0 * 0), (int)(255.0 * 0), (int)(255.0 * 1)); + namedColors[QStringLiteral("Cyan")] = QColor((int)(255.0 * 0), (int)(255.0 * 1), (int)(255.0 * 1)); + namedColors[QStringLiteral("Gray")] = QColor((int)(255.0 * 0.5), (int)(255.0 * 0.5), (int)(255.0 * 0.5)); + namedColors[QStringLiteral("Plum")] = QColor((int)(255.0 * 0.5), (int)(255.0 * 0), (int)(255.0 * 1)); + namedColors[QStringLiteral("Black")] = QColor((int)(255.0 * 0), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Brown")] = QColor((int)(255.0 * 0.4), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Green")] = QColor((int)(255.0 * 0), (int)(255.0 * 1), (int)(255.0 * 0)); + namedColors[QStringLiteral("Melon")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.54), (int)(255.0 * 0.5)); + namedColors[QStringLiteral("Peach")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.5), (int)(255.0 * 0.3)); + namedColors[QStringLiteral("Sepia")] = QColor((int)(255.0 * 0.3), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("White")] = QColor((int)(255.0 * 1), (int)(255.0 * 1), (int)(255.0 * 1)); + namedColors[QStringLiteral("Maroon")] = QColor((int)(255.0 * 0.68), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Orange")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.39), (int)(255.0 * 0.13)); + namedColors[QStringLiteral("Orchid")] = QColor((int)(255.0 * 0.68), (int)(255.0 * 0.36), (int)(255.0 * 1)); + namedColors[QStringLiteral("Purple")] = QColor((int)(255.0 * 0.55), (int)(255.0 * 0.14), (int)(255.0 * 1)); + namedColors[QStringLiteral("Salmon")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.47), (int)(255.0 * 0.62)); + namedColors[QStringLiteral("Violet")] = QColor((int)(255.0 * 0.21), (int)(255.0 * 0.12), (int)(255.0 * 1)); + namedColors[QStringLiteral("Yellow")] = QColor((int)(255.0 * 1), (int)(255.0 * 1), (int)(255.0 * 0)); + namedColors[QStringLiteral("Apricot")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.68), (int)(255.0 * 0.48)); + namedColors[QStringLiteral("Emerald")] = QColor((int)(255.0 * 0), (int)(255.0 * 1), (int)(255.0 * 0.5)); + namedColors[QStringLiteral("Fuchsia")] = QColor((int)(255.0 * 0.45), (int)(255.0 * 0.01), (int)(255.0 * 0.92)); + namedColors[QStringLiteral("Magenta")] = QColor((int)(255.0 * 1), (int)(255.0 * 0), (int)(255.0 * 1)); + namedColors[QStringLiteral("SkyBlue")] = QColor((int)(255.0 * 0.38), (int)(255.0 * 1), (int)(255.0 * 0.88)); + namedColors[QStringLiteral("Thistle")] = QColor((int)(255.0 * 0.88), (int)(255.0 * 0.41), (int)(255.0 * 1)); + namedColors[QStringLiteral("BrickRed")] = QColor((int)(255.0 * 0.72), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Cerulean")] = QColor((int)(255.0 * 0.06), (int)(255.0 * 0.89), (int)(255.0 * 1)); + namedColors[QStringLiteral("Lavender")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.52), (int)(255.0 * 1)); + namedColors[QStringLiteral("Mahogany")] = QColor((int)(255.0 * 0.65), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("Mulberry")] = QColor((int)(255.0 * 0.64), (int)(255.0 * 0.08), (int)(255.0 * 0.98)); + namedColors[QStringLiteral("NavyBlue")] = QColor((int)(255.0 * 0.06), (int)(255.0 * 0.46), (int)(255.0 * 1)); + namedColors[QStringLiteral("SeaGreen")] = QColor((int)(255.0 * 0.31), (int)(255.0 * 1), (int)(255.0 * 0.5)); + namedColors[QStringLiteral("TealBlue")] = QColor((int)(255.0 * 0.12), (int)(255.0 * 0.98), (int)(255.0 * 0.64)); + namedColors[QStringLiteral("BlueGreen")] = QColor((int)(255.0 * 0.15), (int)(255.0 * 1), (int)(255.0 * 0.67)); + namedColors[QStringLiteral("CadetBlue")] = QColor((int)(255.0 * 0.38), (int)(255.0 * 0.43), (int)(255.0 * 0.77)); + namedColors[QStringLiteral("Dandelion")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.71), (int)(255.0 * 0.16)); + namedColors[QStringLiteral("Goldenrod")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.9), (int)(255.0 * 0.16)); + namedColors[QStringLiteral("LimeGreen")] = QColor((int)(255.0 * 0.5), (int)(255.0 * 1), (int)(255.0 * 0)); + namedColors[QStringLiteral("OrangeRed")] = QColor((int)(255.0 * 1), (int)(255.0 * 0), (int)(255.0 * 0.5)); + namedColors[QStringLiteral("PineGreen")] = QColor((int)(255.0 * 0), (int)(255.0 * 0.75), (int)(255.0 * 0.16)); + namedColors[QStringLiteral("RawSienna")] = QColor((int)(255.0 * 0.55), (int)(255.0 * 0), (int)(255.0 * 0)); + namedColors[QStringLiteral("RedOrange")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.23), (int)(255.0 * 0.13)); + namedColors[QStringLiteral("RedViolet")] = QColor((int)(255.0 * 0.59), (int)(255.0 * 0), (int)(255.0 * 0.66)); + namedColors[QStringLiteral("Rhodamine")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.18), (int)(255.0 * 1)); + namedColors[QStringLiteral("RoyalBlue")] = QColor((int)(255.0 * 0), (int)(255.0 * 0.5), (int)(255.0 * 1)); + namedColors[QStringLiteral("RubineRed")] = QColor((int)(255.0 * 1), (int)(255.0 * 0), (int)(255.0 * 0.87)); + namedColors[QStringLiteral("Turquoise")] = QColor((int)(255.0 * 0.15), (int)(255.0 * 1), (int)(255.0 * 0.8)); + namedColors[QStringLiteral("VioletRed")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.19), (int)(255.0 * 1)); + namedColors[QStringLiteral("Aquamarine")] = QColor((int)(255.0 * 0.18), (int)(255.0 * 1), (int)(255.0 * 0.7)); + namedColors[QStringLiteral("BlueViolet")] = QColor((int)(255.0 * 0.1), (int)(255.0 * 0.05), (int)(255.0 * 0.96)); + namedColors[QStringLiteral("DarkOrchid")] = QColor((int)(255.0 * 0.6), (int)(255.0 * 0.2), (int)(255.0 * 0.8)); + namedColors[QStringLiteral("OliveGreen")] = QColor((int)(255.0 * 0), (int)(255.0 * 0.6), (int)(255.0 * 0)); + namedColors[QStringLiteral("Periwinkle")] = QColor((int)(255.0 * 0.43), (int)(255.0 * 0.45), (int)(255.0 * 1)); + namedColors[QStringLiteral("Bittersweet")] = QColor((int)(255.0 * 0.76), (int)(255.0 * 0.01), (int)(255.0 * 0)); + namedColors[QStringLiteral("BurntOrange")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.49), (int)(255.0 * 0)); + namedColors[QStringLiteral("ForestGreen")] = QColor((int)(255.0 * 0), (int)(255.0 * 0.88), (int)(255.0 * 0)); + namedColors[QStringLiteral("GreenYellow")] = QColor((int)(255.0 * 0.85), (int)(255.0 * 1), (int)(255.0 * 0.31)); + namedColors[QStringLiteral("JungleGreen")] = QColor((int)(255.0 * 0.01), (int)(255.0 * 1), (int)(255.0 * 0.48)); + namedColors[QStringLiteral("ProcessBlue")] = QColor((int)(255.0 * 0.04), (int)(255.0 * 1), (int)(255.0 * 1)); + namedColors[QStringLiteral("RoyalPurple")] = QColor((int)(255.0 * 0.25), (int)(255.0 * 0.1), (int)(255.0 * 1)); + namedColors[QStringLiteral("SpringGreen")] = QColor((int)(255.0 * 0.74), (int)(255.0 * 1), (int)(255.0 * 0.24)); + namedColors[QStringLiteral("YellowGreen")] = QColor((int)(255.0 * 0.56), (int)(255.0 * 1), (int)(255.0 * 0.26)); + namedColors[QStringLiteral("MidnightBlue")] = QColor((int)(255.0 * 0), (int)(255.0 * 0.44), (int)(255.0 * 0.57)); + namedColors[QStringLiteral("YellowOrange")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.58), (int)(255.0 * 0)); + namedColors[QStringLiteral("CarnationPink")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.37), (int)(255.0 * 1)); + namedColors[QStringLiteral("CornflowerBlue")] = QColor((int)(255.0 * 0.35), (int)(255.0 * 0.87), (int)(255.0 * 1)); + namedColors[QStringLiteral("WildStrawberry")] = QColor((int)(255.0 * 1), (int)(255.0 * 0.04), (int)(255.0 * 0.61)); + } + + QString specType = colorSpec.section(QLatin1Char(' '), 0, 0); + + if (specType.indexOf(QStringLiteral("rgb"), 0, Qt::CaseInsensitive) == 0) { + bool ok; + + double r = colorSpec.section(QLatin1Char(' '), 1, 1).toDouble(&ok); + if ((ok == false) || (r < 0.0) || (r > 1.0)) + return QColor(); + + double g = colorSpec.section(QLatin1Char(' '), 2, 2).toDouble(&ok); + if ((ok == false) || (g < 0.0) || (g > 1.0)) + return QColor(); + + double b = colorSpec.section(QLatin1Char(' '), 3, 3).toDouble(&ok); + if ((ok == false) || (b < 0.0) || (b > 1.0)) + return QColor(); + + return QColor((int)(r * 255.0 + 0.5), (int)(g * 255.0 + 0.5), (int)(b * 255.0 + 0.5)); + } + + if (specType.indexOf(QStringLiteral("hsb"), 0, Qt::CaseInsensitive) == 0) { + bool ok; + + double h = colorSpec.section(QLatin1Char(' '), 1, 1).toDouble(&ok); + if ((ok == false) || (h < 0.0) || (h > 1.0)) + return QColor(); + + double s = colorSpec.section(QLatin1Char(' '), 2, 2).toDouble(&ok); + if ((ok == false) || (s < 0.0) || (s > 1.0)) + return QColor(); + + double b = colorSpec.section(QLatin1Char(' '), 3, 3).toDouble(&ok); + if ((ok == false) || (b < 0.0) || (b > 1.0)) + return QColor(); + + return QColor::fromHsv((int)(h * 359.0 + 0.5), (int)(s * 255.0 + 0.5), (int)(b * 255.0 + 0.5)); + } + + if (specType.indexOf(QStringLiteral("cmyk"), 0, Qt::CaseInsensitive) == 0) { + bool ok; + + double c = colorSpec.section(QLatin1Char(' '), 1, 1).toDouble(&ok); + if ((ok == false) || (c < 0.0) || (c > 1.0)) + return QColor(); + + double m = colorSpec.section(QLatin1Char(' '), 2, 2).toDouble(&ok); + if ((ok == false) || (m < 0.0) || (m > 1.0)) + return QColor(); + + double y = colorSpec.section(QLatin1Char(' '), 3, 3).toDouble(&ok); + if ((ok == false) || (y < 0.0) || (y > 1.0)) + return QColor(); + + double k = colorSpec.section(QLatin1Char(' '), 3, 3).toDouble(&ok); + if ((ok == false) || (k < 0.0) || (k > 1.0)) + return QColor(); + + // Convert cmyk coordinates to rgb. + double r = 1.0 - c - k; + if (r < 0.0) + r = 0.0; + double g = 1.0 - m - k; + if (g < 0.0) + g = 0.0; + double b = 1.0 - y - k; + if (b < 0.0) + b = 0.0; + + return QColor((int)(r * 255.0 + 0.5), (int)(g * 255.0 + 0.5), (int)(b * 255.0 + 0.5)); + } + + if (specType.indexOf(QStringLiteral("gray"), 0, Qt::CaseInsensitive) == 0) { + bool ok; + + double g = colorSpec.section(QLatin1Char(' '), 1, 1).toDouble(&ok); + if ((ok == false) || (g < 0.0) || (g > 1.0)) + return QColor(); + + return QColor((int)(g * 255.0 + 0.5), (int)(g * 255.0 + 0.5), (int)(g * 255.0 + 0.5)); + } + + // Check if the color is one of the known named colors. + QMap::Iterator f = namedColors.find(specType); + if (f != namedColors.end()) + return *f; + + return QColor(specType); +} + +void dviRenderer::color_special(const QString &msg) +{ + QString const cp = msg.trimmed(); + + QString command = cp.section(QLatin1Char(' '), 0, 0); + + if (command == QLatin1String("pop")) { + // Take color off the stack + if (colorStack.isEmpty()) + printErrorMsgForSpecials(i18n("Error in DVIfile '%1', page %2. Color pop command issued when the color stack is empty.", dviFile->filename, current_page)); + else + colorStack.pop(); + return; + } + + if (command == QLatin1String("push")) { + // Get color specification + const QColor col = parseColorSpecification(cp.section(QLatin1Char(' '), 1)); + // Set color + if (col.isValid()) + colorStack.push(col); + else + colorStack.push(Qt::black); + return; + } + + // Get color specification and set the color for the rest of this + // page + QColor col = parseColorSpecification(cp); + // Set color + if (col.isValid()) + globalColor = col; + else + globalColor = Qt::black; + return; +} + +void dviRenderer::html_href_special(const QString &msg) +{ + QString cp = msg; + cp.truncate(cp.indexOf(QLatin1Char('"'))); + +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "HTML-special, href " << cp.toLatin1(); +#endif + HTML_href = new QString(cp); +} + +void dviRenderer::html_anchor_end() +{ +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "HTML-special, anchor-end"; +#endif + + if (HTML_href != nullptr) { + delete HTML_href; + HTML_href = nullptr; + } +} + +void dviRenderer::source_special(const QString &cp) +{ + // only when rendering really takes place: set source_href to the + // current special string. When characters are rendered, the + // rendering routine will then generate a DVI_HyperLink and add it + // to the proper list. This DVI_HyperLink is used to match mouse + // positions with the hyperlinks for inverse search. + if (source_href) + *source_href = cp; + else + source_href = new QString(cp); +} + +void parse_special_argument(const QString &strg, const char *argument_name, int *variable) +{ + int index = strg.indexOf(QString::fromLocal8Bit(argument_name)); + if (index >= 0) { + QString tmp = strg.mid(index + strlen(argument_name)); + index = tmp.indexOf(QLatin1Char(' ')); + if (index >= 0) + tmp.truncate(index); + + bool OK; + float const tmp_float = tmp.toFloat(&OK); + + if (OK) + *variable = int(tmp_float + 0.5); + else + // Maybe we should open a dialog here. + qCCritical(OkularDviDebug) << i18n( + "Malformed parameter in the epsf special command.\n" + "Expected a float to follow %1 in %2", + QString::fromLocal8Bit(argument_name), + strg) + << endl; + } +} + +void dviRenderer::epsf_special(const QString &cp) +{ +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "epsf-special: psfile=" << cp; +#endif + + QString include_command = cp.simplified(); + + // The line is supposed to start with "..ile=", and then comes the + // filename. Figure out what the filename is and stow it away. Of + // course, this does not work if the filename contains spaces + // (already the simplified() above is wrong). If you have + // files like this, go away. + QString EPSfilename_orig = include_command; + EPSfilename_orig.truncate(EPSfilename_orig.indexOf(QLatin1Char(' '))); + + // Strip enclosing quotation marks which are included by some LaTeX + // macro packages (but not by others). This probably means that + // graphic files are no longer found if the filename really does + // contain quotes, but we don't really care that much. + if ((EPSfilename_orig.at(0) == QLatin1Char('\"')) && (EPSfilename_orig.at(EPSfilename_orig.length() - 1) == QLatin1Char('\"'))) { + EPSfilename_orig = EPSfilename_orig.mid(1, EPSfilename_orig.length() - 2); + } + QString EPSfilename = ghostscript_interface::locateEPSfile(EPSfilename_orig, baseURL); + + // Now parse the arguments. + int llx = 0; + int lly = 0; + int urx = 0; + int ury = 0; + int rwi = 0; + int rhi = 0; + int angle = 0; + + // just to avoid ambiguities; the filename could contain keywords + include_command = include_command.mid(include_command.indexOf(QLatin1Char(' '))); + + parse_special_argument(include_command, "llx=", &llx); + parse_special_argument(include_command, "lly=", &lly); + parse_special_argument(include_command, "urx=", &urx); + parse_special_argument(include_command, "ury=", &ury); + parse_special_argument(include_command, "rwi=", &rwi); + parse_special_argument(include_command, "rhi=", &rhi); + parse_special_argument(include_command, "angle=", &angle); + + // If we have a png, gif, jpeg or mng file, we need to draw it here. + QMimeDatabase db; + QMimeType const mime_type = db.mimeTypeForFile(EPSfilename, QMimeDatabase::MatchContent); + QString const &mime_type_name = mime_type.isValid() ? mime_type.name() : QString(); + bool const isGFX = (mime_type_name == QLatin1String("image/png") || mime_type_name == QLatin1String("image/gif") || mime_type_name == QLatin1String("image/jpeg") || mime_type_name == QLatin1String("video/x-mng")); + + // So, if we do not have a PostScript file, but a graphics file, and + // if that file exists, we draw it here. + if (isGFX && QFile::exists(EPSfilename)) { + // Don't show PostScript, just draw the bounding box. For this, + // calculate the size of the bounding box in Pixels. + double bbox_width = urx - llx; + double bbox_height = ury - lly; + + if ((rwi != 0) && (bbox_width != 0)) { + bbox_height *= rwi / bbox_width; + bbox_width = rwi; + } + if ((rhi != 0) && (bbox_height != 0)) { + bbox_width *= rhi / bbox_height; + bbox_height = rhi; + } + + double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0 / 2.54; + + bbox_width *= 0.1 * 65536.0 * fontPixelPerDVIunit / shrinkfactor; + bbox_height *= 0.1 * 65536.0 * fontPixelPerDVIunit / shrinkfactor; + + QImage image(EPSfilename); + image = image.scaled((int)(bbox_width), (int)(bbox_height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + foreGroundPainter->drawImage(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - (int)bbox_height, image); + return; + } + + if (!_postscript || !QFile::exists(EPSfilename)) { + // Don't show PostScript, just draw the bounding box. For this, + // calculate the size of the bounding box in Pixels. + double bbox_width = urx - llx; + double bbox_height = ury - lly; + + if ((rwi != 0) && (bbox_width != 0)) { + bbox_height *= rwi / bbox_width; + bbox_width = rwi; + } + if ((rhi != 0) && (bbox_height != 0)) { + bbox_width *= rhi / bbox_height; + bbox_height = rhi; + } + + double fontPixelPerDVIunit = dviFile->getCmPerDVIunit() * 1200.0 / 2.54; + + bbox_width *= 0.1 * 65536.0 * fontPixelPerDVIunit / shrinkfactor; + bbox_height *= 0.1 * 65536.0 * fontPixelPerDVIunit / shrinkfactor; + + QRect bbox(((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))), currinf.data.pxl_v - (int)bbox_height, (int)bbox_width, (int)bbox_height); + + foreGroundPainter->save(); + + if (QFile::exists(EPSfilename)) + foreGroundPainter->setBrush(Qt::lightGray); + else + foreGroundPainter->setBrush(Qt::red); + foreGroundPainter->setPen(Qt::black); + foreGroundPainter->drawRoundedRect(bbox, 2, 2); + QFont f = foreGroundPainter->font(); + f.setPointSize(8); + foreGroundPainter->setFont(f); + /* if the fonts are mapped for some reason to X bitmap fonts, + the call to drawText() in the non-GUI thread will produce a crash. + Ensure that the rendering of the text is performed only if + the threaded font rendering is available */ + if (QFile::exists(EPSfilename)) + foreGroundPainter->drawText(bbox, (int)(Qt::AlignCenter), EPSfilename); + else + foreGroundPainter->drawText(bbox, (int)(Qt::AlignCenter), i18n("File not found: \n %1", EPSfilename_orig)); + foreGroundPainter->restore(); + } + + return; +} + +void dviRenderer::TPIC_flushPath_special() +{ +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "TPIC special flushPath"; +#endif + + if (number_of_elements_in_path == 0) { + printErrorMsgForSpecials(QStringLiteral("TPIC special flushPath called when path was empty.")); + return; + } + + QPen pen(Qt::black, (int)(penWidth_in_mInch * resolutionInDPI / 1000.0 + 0.5)); // Sets the pen size in milli-inches + foreGroundPainter->setPen(pen); + foreGroundPainter->drawPolyline(TPIC_path.constData(), number_of_elements_in_path); + number_of_elements_in_path = 0; +} + +void dviRenderer::TPIC_addPath_special(const QString &cp) +{ +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "TPIC special addPath: " << cp; +#endif + + // Adds a point to the path list + QString cp_noWhiteSpace = cp.trimmed(); + bool ok; + float xKoord = cp_noWhiteSpace.section(QLatin1Char(' '), 0, 0).toFloat(&ok); + if (ok == false) { + printErrorMsgForSpecials(QStringLiteral("TPIC special; cannot parse first argument in 'pn %1'.").arg(cp)); + return; + } + float yKoord = cp_noWhiteSpace.section(QLatin1Char(' '), 1, 1).toFloat(&ok); + if (ok == false) { + printErrorMsgForSpecials(QStringLiteral("TPIC special; cannot parse second argument in 'pn %1'.").arg(cp)); + return; + } + + float mag = dviFile->getMagnification() / 1000.0; + + int x = (int)(currinf.data.dvi_h / (shrinkfactor * 65536.0) + mag * xKoord * resolutionInDPI / 1000.0 + 0.5); + int y = (int)(currinf.data.pxl_v + mag * yKoord * resolutionInDPI / 1000.0 + 0.5); + + // Initialize the point array used to store the path + if (TPIC_path.size() == 0) + number_of_elements_in_path = 0; + if (TPIC_path.size() == number_of_elements_in_path) + TPIC_path.resize(number_of_elements_in_path + 100); + TPIC_path.setPoint(number_of_elements_in_path++, x, y); +} + +void dviRenderer::TPIC_setPen_special(const QString &cp) +{ +#ifdef DEBUG_SPECIAL + qCDebug(OkularDviDebug) << "TPIC special setPen: " << cp; +#endif + + // Sets the pen size in milli-inches + bool ok; + penWidth_in_mInch = cp.trimmed().toFloat(&ok); + if (ok == false) { + printErrorMsgForSpecials(QStringLiteral("TPIC special; cannot parse argument in 'pn %1'.").arg(cp)); + penWidth_in_mInch = 0.0; + return; + } +} + +void dviRenderer::applicationDoSpecial(char *cp) +{ + QString special_command = QString::fromLocal8Bit(cp); + + // First come specials which is only interpreted during rendering, + // and NOT during the prescan phase + + // font color specials + if (qstrnicmp(cp, "color", 5) == 0) { + color_special(special_command.mid(5)); + return; + } + + // HTML reference + if (qstrnicmp(cp, "html:
", 9) == 0) { + html_anchor_end(); + return; + } + + // TPIC specials + if (qstrnicmp(cp, "pn", 2) == 0) { + TPIC_setPen_special(special_command.mid(2)); + return; + } + if (qstrnicmp(cp, "pa ", 3) == 0) { + TPIC_addPath_special(special_command.mid(3)); + return; + } + if (qstrnicmp(cp, "fp", 2) == 0) { + TPIC_flushPath_special(); + return; + } + + // Encapsulated Postscript File + if (qstrnicmp(cp, "PSfile=", 7) == 0) { + epsf_special(special_command.mid(7)); + return; + } + + // source special + if (qstrnicmp(cp, "src:", 4) == 0) { + source_special(special_command.mid(4)); + return; + } + + // Unfortunately, in some TeX distribution the hyperref package uses + // the dvips driver by default, rather than the hypertex driver. As + // a result, the DVI files produced are full of PostScript that + // specifies links and anchors, and KDVI would call the ghostscript + // interpreter for every page which makes it really slow. This is a + // major nuisance, so that we try to filter and interpret the + // hypertex generated PostScript here. + if (special_command.startsWith(QLatin1String("ps:SDict begin"))) { + // Hyperref: start of hyperref rectangle. At this stage it is not + // yet clear if the rectangle will contain a hyperlink, an anchor, + // or another type of object. We suspect that this rectangle will + // define a hyperlink, allocate a QString and set HTML_href to + // point to this string. The string contains the name of the + // destination which ---due to the nature of the PostScript + // language--- will be defined only after characters are drawn and + // the hyperref rectangle has been closed. We use "glopglyph" as a + // temporary name. Since the pointer HTML_href is not NULL, the + // character drawing routines will now underline all characters in + // blue to point out that they correspond to a hyperlink. Also, as + // soon as characters are drawn, the drawing routines will + // allocate a Hyperlink and add it to the top of the vector + // currentlyDrawnPage->hyperLinkList. + if (special_command == QLatin1String("ps:SDict begin H.S end")) { + // At this stage, the vector 'hyperLinkList' should not contain + // links with unspecified destinations (i.e. destination set to + // 'glopglyph'). As a protection against bad DVI files, we make + // sure to remove all link rectangles which point to + // 'glopglyph'. + while (!currentlyDrawnPage->hyperLinkList.isEmpty()) + if (currentlyDrawnPage->hyperLinkList.last().linkText == QLatin1String("glopglyph")) + currentlyDrawnPage->hyperLinkList.pop_back(); + else + break; + + HTML_href = new QString(QStringLiteral("glopglyph")); + return; + } + + // Hyperref: end of hyperref rectangle of unknown type or hyperref + // link rectangle. In these cases we set HTML_href to NULL, which + // causes the character drawing routines to stop drawing + // characters underlined in blue. Note that the name of the + // destination is still set to "glopglyph". In a well-formed DVI + // file, this special command is immediately followed by another + // special, where the destination is specified. This special is + // treated below. + if ((special_command == QLatin1String("ps:SDict begin H.R end")) || special_command.endsWith(QLatin1String("H.L end"))) { + if (HTML_href != nullptr) { + delete HTML_href; + HTML_href = nullptr; + } + return; // end of hyperref rectangle + } + + // Hyperref: end of anchor rectangle. If this special is + // encountered, the rectangle, which was started with "ps:SDict + // begin H.S end" does not contain a link, but an anchor for a + // link. Anchors, however, have already been dealt with in the + // prescan phase and will not be considered here. Thus, we set + // HTML_href to NULL so that character drawing routines will no + // longer underline hyperlinks in blue, and remove the link from + // the hyperLinkList. NOTE: in a well-formed DVI file, the "H.A" + // special comes directly after the "H.S" special. A + // hyperlink-anchor rectangle therefore never contains characters, + // so no character will by accidentally underlined in blue. + if (special_command.endsWith(QLatin1String("H.A end"))) { + if (HTML_href != nullptr) { + delete HTML_href; + HTML_href = nullptr; + } + while (!currentlyDrawnPage->hyperLinkList.isEmpty()) + if (currentlyDrawnPage->hyperLinkList.last().linkText == QLatin1String("glopglyph")) + currentlyDrawnPage->hyperLinkList.pop_back(); + else + break; + return; // end of hyperref anchor + } + + // Hyperref: specification of a hyperref link rectangle's + // destination. As mentioned above, the destination of a hyperlink + // is specified only AFTER the rectangle has been specified. We + // will therefore go through the list of rectangles stored in + // currentlyDrawnPage->hyperLinkList, find those whose destination + // is open and fill in the value found here. NOTE: the character + // drawing routines sometimes split a single hyperlink rectangle + // into several rectangles (e.g. if the font changes, or when a + // line break is encountered) + if (special_command.startsWith(QLatin1String("ps:SDict begin [")) && special_command.endsWith(QLatin1String(" pdfmark end"))) { + if (!currentlyDrawnPage->hyperLinkList.isEmpty()) { + QString targetName = special_command.section(QLatin1Char('('), 1, 1).section(QLatin1Char(')'), 0, 0); + QVector::iterator it; + for (it = currentlyDrawnPage->hyperLinkList.begin(); it != currentlyDrawnPage->hyperLinkList.end(); ++it) + if (it->linkText == QLatin1String("glopglyph")) + it->linkText = targetName; + } + return; // hyperref definition of link/anchor/bookmark/etc + } + } + + // Detect text rotation specials that are included by the graphicx + // package. If one of these specials is found, the state of the + // painter is saved, and the coordinate system is rotated + // accordingly + if (special_command.startsWith(QLatin1String("ps: gsave currentpoint currentpoint translate ")) && special_command.endsWith(QLatin1String(" neg rotate neg exch neg exch translate"))) { + bool ok; + double angle = special_command.section(QLatin1Char(' '), 5, 5).toDouble(&ok); + if (ok == true) { + int x = ((int)((currinf.data.dvi_h) / (shrinkfactor * 65536))); + int y = currinf.data.pxl_v; + + foreGroundPainter->save(); + // Rotate about the current point + foreGroundPainter->translate(x, y); + foreGroundPainter->rotate(-angle); + foreGroundPainter->translate(-x, -y); + } else + printErrorMsgForSpecials(i18n("Error in DVIfile '%1', page %2. Could not interpret angle in text rotation special.", dviFile->filename, current_page)); + } + + // The graphicx package marks the end of rotated text with this + // special. The state of the painter is restored. + if (special_command == QLatin1String("ps: currentpoint grestore moveto")) { + foreGroundPainter->restore(); + } + + // The following special commands are not used here; they are of + // interest only during the prescan phase. We recognize them here + // anyway, to make sure that KDVI doesn't complain about + // unrecognized special commands. + if ((cp[0] == '!') || (cp[0] == '"') || (qstrnicmp(cp, "html: +#include + +/** Represents a rectangular region in a RenderedDocumentPage that contains text + + This trivial class is used in the RenderedDocumentPage class to + give a non-graphical representation of text in a rendered document + page. This is used, e.g. by text search and the text selection + functions that need to know the contents and the position of text + on a page + + @author Stefan Kebekus + @version 1.0.0 +*/ + +class TextBox +{ +public: + /** \brief Default Constructor + + The default constructor leaves all fields uninitialized. + */ + TextBox() + { + } + + /** \brief Constructor + + Trivial constructor leaves that initialized all members. + + @param re value for the box + @param lT valus for the text field + */ + TextBox(const QRect re, const QString &lT) + : box(re) + , text(lT) + { + } + + /** \brief Bounding box of the text or hyperlink + + This rectangle specifies where on the page the text or hyperlink is + found. It uses the same coordinates that were used when the + associated documentPage was rendered by the + documentRenderer.drawPage() method. The contents of the box is + graphically inverted to indicate marked text. + */ + QRect box; + + /** \brief Name of the region + + The text associated with the box is stored here. + */ + QString text; +}; + +#endif diff --git a/generators/dvi/util.cpp b/generators/dvi/util.cpp new file mode 100644 index 0000000..62182e5 --- /dev/null +++ b/generators/dvi/util.cpp @@ -0,0 +1,114 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * NOTE: + * xdvi is based on prior work as noted in the modification history, below. + */ + +/* + * DVI previewer for X. + * + * Eric Cooper, CMU, September 1985. + * + * Code derived from dvi-imagen.c. + * + * Modification history: + * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS. + * 7/1988 Modified for X.11 --Mark Eichin, MIT + * 12/1988 Added 'R' option, toolkit, magnifying glass + * --Paul Vojta, UC Berkeley. + * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto + * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ. + * 3/1990 Added VMS support --Scott Allendorf, U of Iowa + * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem + * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen + * and Lee Hetherington, MIT + * 4/1994 Added DPS support, bounding box + * --Ricardo Telichevesky + * and Luis Miguel Silveira, MIT RLE. + */ + +#include + +#include "debug_dvi.h" +#include "xdvi.h" + +#include +#include + +#include + +#include + +/* + * General utility routines. + */ + +/* + * Print error message and quit. + */ + +void oops(const QString &message) +{ + qCCritical(OkularDviDebug) << "Fatal Error:" << message << endl; + + KMessageBox::error(nullptr, i18n("Fatal error.\n\n") + message + i18n("\n\n\ +This probably means that either you found a bug in Okular,\n\ +or that the DVI file, or auxiliary files (such as font files, \n\ +or virtual font files) were really badly broken.\n\ +Okular will abort after this message. If you believe that you \n\ +found a bug, or that Okular should behave better in this situation\n\ +please report the problem.")); + exit(1); +} + +/* + * Read size bytes from the FILE fp, constructing them into a + * signed/unsigned integer. + */ +unsigned long num(FILE *fp, int size) +{ + long x = 0; + + while (size--) + x = (x << 8) | one(fp); + return x; +} + +long snum(FILE *fp, int size) +{ + long x; + +#ifdef __STDC__ + x = (signed char)getc(fp); // NOLINT(bugprone-signed-char-misuse) This code is decades old, so prefer not to touch it +#else + x = (unsigned char)getc(fp); + if (x & 0x80) + x -= 0x100; +#endif + while (--size) + x = (x << 8) | one(fp); + return x; +} diff --git a/generators/dvi/vf.cpp b/generators/dvi/vf.cpp new file mode 100644 index 0000000..7fa57f7 --- /dev/null +++ b/generators/dvi/vf.cpp @@ -0,0 +1,183 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +/* + * Copyright (c) 1994 Paul Vojta. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "debug_dvi.h" +#include "dvi.h" +#include "dviRenderer.h" +#include "xdvi.h" + +#include + +#include +#include + +extern void oops(const QString &message); + +/*** + *** VF font reading routines. + *** Public routine is read_index---because virtual characters are presumed + *** to be short, we read the whole virtual font in at once, instead of + *** faulting in characters as needed. + ***/ + +#define LONG_CHAR 242 + +/* + * These are parameters which determine whether macros are combined for + * storage allocation purposes. Small macros ( <= VF_PARM_1 bytes) are + * combined into chunks of size VF_PARM_2. + */ + +#ifndef VF_PARM_1 +#define VF_PARM_1 20 +#endif +#ifndef VF_PARM_2 +#define VF_PARM_2 256 +#endif + +/* + * The main routine + */ + +void TeXFontDefinition::read_VF_index() +{ +#ifdef DEBUG_FONTS + qCDebug(OkularDviDebug) << "font::read_VF_index()"; +#endif + FILE *VF_file = file; + unsigned char cmnd; + // available space for macros + unsigned char *avail, *availend; + + flags |= FONT_VIRTUAL; + set_char_p = &dviRenderer::set_vf_char; +#ifdef DEBUG_FONTS + qCDebug(OkularDviDebug) << "TeXFontDefinition::read_VF_index: reading VF pixel file " << filename; +#endif + // Read preamble. + fseek(VF_file, (long)one(VF_file), 1); /* skip comment */ + quint32 const file_checksum = four(VF_file); + + if (file_checksum && checksum && file_checksum != checksum) + qCCritical(OkularDviDebug) << "Checksum mismatch dvi = " << checksum << "u, vf = " << file_checksum << "u) in font file" << filename << endl; + (void)four(VF_file); /* skip design size */ + + // Read the fonts. + first_font = nullptr; + while ((cmnd = one(VF_file)) >= FNTDEF1 && cmnd <= FNTDEF4) { + int TeXnumber = num(VF_file, (int)cmnd - FNTDEF1 + 1); + quint32 checksum = four(VF_file); + quint32 scale = four(VF_file); + quint32 design = four(VF_file); + Q_UNUSED(design); + quint16 len = one(VF_file) + one(VF_file); /* sequence point in the middle */ + char *fontname = new char[len + 1]; + fread(fontname, sizeof(char), len, VF_file); + fontname[len] = '\0'; + +#ifdef DEBUG_FONTS + qCDebug(OkularDviDebug) << "Virtual font defines subfont \"" << fontname << "\" scale=" << scale << " design=" << design; +#endif + + // According to Knuth's documentation found in the web source code + // of the "vftovp" program (which seems to be the standard + // definition of virtual fonts), the "scale" is a fixed point + // number which describes extra enlargement that the virtual font + // imposes. One obtains the enlargement by dividing 2^20. + double enlargement_factor = double(scale) / (1 << 20) * enlargement; + + // TeXFontDefinition *newfontp = font_pool->appendx(fontname, checksum, (quint32)(scaled_size_in_DVI_units*enlargement_factor), enlargement_factor); + TeXFontDefinition *newfontp = font_pool->appendx(QString::fromLocal8Bit(fontname), checksum, (quint32)((double(scale) / (1 << 20)) * scaled_size_in_DVI_units), enlargement_factor); + + // Insert font in dictionary and make sure the dictionary is big + // enough. + if (vf_table.capacity() - 2 <= vf_table.count()) + // Not quite optimal. The size of the dictionary should be a + // prime. I don't care. + vf_table.reserve(vf_table.capacity() * 2); + vf_table.insert(TeXnumber, newfontp); + + if (first_font == nullptr) + first_font = newfontp; + } + + // Prepare macro array. + macrotable = new macro[max_num_of_chars_in_font]; + if (macrotable == nullptr) { + qCCritical(OkularDviDebug) << "Could not allocate memory for a macro table."; + exit(0); + } + + // Read macros. + avail = availend = nullptr; + for (; cmnd <= LONG_CHAR; cmnd = one(VF_file)) { + macro *m; + int len; + unsigned long cc; + long width; + + if (cmnd == LONG_CHAR) { /* long form packet */ + len = four(VF_file); + cc = four(VF_file); + width = four(VF_file); + if (cc >= 256) { + qCCritical(OkularDviDebug) << "Virtual character" << cc << "in font" << fontname << "ignored."; + fseek(VF_file, (long)len, 1); + continue; + } + } else { /* short form packet */ + len = cmnd; + cc = one(VF_file); + width = num(VF_file, 3); + } + m = ¯otable[cc]; + + m->dvi_advance_in_units_of_design_size_by_2e20 = width; + if (len > 0) { + if (len <= availend - avail) { + m->pos = avail; + avail += len; + } else { + m->free_me = true; + if (len <= VF_PARM_1) { + m->pos = avail = new unsigned char[VF_PARM_2]; + availend = avail + VF_PARM_2; + avail += len; + } else + m->pos = new unsigned char[len]; + } + fread((char *)m->pos, 1, len, VF_file); + m->end = m->pos + len; + } + } + if (cmnd != POST) + oops(i18n("Wrong command byte found in VF macro list: %1", cmnd)); + + fclose(VF_file); + file = nullptr; +} diff --git a/generators/dvi/xdvi.h b/generators/dvi/xdvi.h new file mode 100644 index 0000000..7cd6e56 --- /dev/null +++ b/generators/dvi/xdvi.h @@ -0,0 +1,22 @@ +// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- +#ifndef _xdvi_h +#define _xdvi_h + +/* + * Written by Eric C. Cooper, CMU + */ + +#define ROUNDUP(x, y) (((x) + (y)-1) / (y)) + +extern unsigned long num(FILE *, int); +extern long snum(FILE *, int); +extern struct WindowRec mane, currwin; + +#define one(fp) ((unsigned char)getc(fp)) +#define sone(fp) ((long)one(fp)) +#define two(fp) num(fp, 2) +#define stwo(fp) snum(fp, 2) +#define four(fp) num(fp, 4) +#define sfour(fp) snum(fp, 4) + +#endif /* _xdvi_h */ diff --git a/generators/epub/CMakeLists.txt b/generators/epub/CMakeLists.txt new file mode 100644 index 0000000..1cdd563 --- /dev/null +++ b/generators/epub/CMakeLists.txt @@ -0,0 +1,37 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_epub") + +add_subdirectory(data) + +include_directories( + ${EPUB_INCLUDE_DIR} +) + + +########### next target ############### + +set(okularGenerator_epub_PART_SRCS + converter.cpp + epubdocument.cpp + generator_epub.cpp +) + +okular_add_generator(okularGenerator_epub ${okularGenerator_epub_PART_SRCS}) + +target_link_libraries(okularGenerator_epub okularcore ${EPUB_LIBRARIES} KF5::I18n Qt5::Widgets Qt5::Xml) + + +########### autotests ############### + +add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) +ecm_add_test(autotests/epubgeneratortest.cpp + TEST_NAME "epubgeneratortest" + LINK_LIBRARIES Qt5::Test KF5::CoreAddons okularcore +) + + +########### install files ############### +install( FILES okularEPub.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_epub.desktop org.kde.mobile.okular_epub.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-epub.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) + diff --git a/generators/epub/Messages.sh b/generators/epub/Messages.sh new file mode 100755 index 0000000..900ba6b --- /dev/null +++ b/generators/epub/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp") -o $podir/okular_epub.pot diff --git a/generators/epub/README b/generators/epub/README new file mode 100644 index 0000000..eac3f64 --- /dev/null +++ b/generators/epub/README @@ -0,0 +1,10 @@ +This is a libepub based backend to watch epub books using okular +The epub library can be obtained using: + +svn co https://ebook-tools.svn.sourceforge.net/svnroot/ebook-tools/trunk ebook-tools + +The library uses standard cmake (ccmake .;make install) + +The epub standard specs can be found in: + +http://www.idpf.org/specs.htm diff --git a/generators/epub/autotests/data/test.epub b/generators/epub/autotests/data/test.epub new file mode 100644 index 0000000000000000000000000000000000000000..a56b4d0dd9188fac0767369b644d0d4c0329d57b GIT binary patch literal 357713 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
mnMl*q82LZf7=(OH`s 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

V771>puXQv@fZ+%{6BnJj#yMv}}7zD4l@udp8I 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 AQ2+n{ literal 0 HcmV?d00001 diff --git a/generators/epub/autotests/epubgeneratortest.cpp b/generators/epub/autotests/epubgeneratortest.cpp new file mode 100644 index 0000000..b708ad2 --- /dev/null +++ b/generators/epub/autotests/epubgeneratortest.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2017 by Gilbert Assaf * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "core/document.h" +#include "core/page.h" +#include "core/textpage.h" +#include "settings_core.h" + +class EpubGeneratorTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testDocumentStructure(); + void testDocumentContent(); + void cleanupTestCase(); + +private: + Okular::Document *m_document; +}; + +void EpubGeneratorTest::initTestCase() +{ + Okular::SettingsCore::instance(QStringLiteral("EpubGeneratorTest")); + m_document = new Okular::Document(nullptr); + const QString testFile = QStringLiteral(KDESRCDIR "autotests/data/test.epub"); + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(testFile); + QCOMPARE(m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess); +} + +void EpubGeneratorTest::cleanupTestCase() +{ + m_document->closeDocument(); + delete m_document; +} + +void EpubGeneratorTest::testDocumentStructure() +{ + unsigned int expectedPageNr = 3; + QCOMPARE(m_document->pages(), expectedPageNr); + QCOMPARE(m_document->metaData(QStringLiteral("DocumentTitle")).toString(), QStringLiteral("Okular Test")); + + const Okular::DocumentSynopsis *docSyn = m_document->documentSynopsis(); + QDomElement heading1 = docSyn->documentElement(); + QCOMPARE(heading1.tagName(), QStringLiteral("Lorem ipsum Section 1")); + + QDomElement heading2 = heading1.nextSiblingElement(); + QCOMPARE(heading2.tagName(), QStringLiteral("Lorem ipsum Section 2")); +} + +void EpubGeneratorTest::testDocumentContent() +{ + const Okular::Page *page0 = m_document->page(0); + QCOMPARE(page0->number(), 0); + m_document->requestTextPage(page0->number()); + QVERIFY(page0->hasTextPage()); + QCOMPARE(page0->text().trimmed(), QStringLiteral("Lorem ipsum Section 1\n\u2029This is an example Text.\n\uFFFC")); + + const Okular::Page *page1 = m_document->page(1); + QCOMPARE(page1->number(), 1); + m_document->requestTextPage(page1->number()); + QVERIFY(page1->hasTextPage()); + QCOMPARE(page1->text().trimmed(), QStringLiteral("Lorem ipsum Section 2\n\u2029This is an example Text.")); +} + +QTEST_MAIN(EpubGeneratorTest) +#include "epubgeneratortest.moc" + +/* kate: replace-tabs on; tab-width 4; */ diff --git a/generators/epub/converter.cpp b/generators/epub/converter.cpp new file mode 100644 index 0000000..c9c2057 --- /dev/null +++ b/generators/epub/converter.cpp @@ -0,0 +1,450 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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. * + ***************************************************************************/ + +#include "converter.h" + +#include +#include // Because of the HACK +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +using namespace Epub; + +Converter::Converter() + : mTextDocument(nullptr) +{ +} + +Converter::~Converter() +{ +} + +// join the char * array into one QString +QString _strPack(char **str, int size) +{ + QString res; + + res = QString::fromUtf8(str[0]); + + for (int i = 1; i < size; i++) { + res += QLatin1String(", "); + res += QString::fromUtf8(str[i]); + } + + return res; +} + +// emit data wrap function that map between epub metadata to okular's +void Converter::_emitData(Okular::DocumentInfo::Key key, enum epub_metadata type) +{ + int size; + unsigned char **data; + + data = epub_get_metadata(mTextDocument->getEpub(), type, &size); + + if (data) { + emit addMetaData(key, _strPack((char **)data, size)); + for (int i = 0; i < size; i++) + free(data[i]); + free(data); + } +} + +// Got over the blocks from start and add them to hashes use name as the +// prefix for local links +void Converter::_handle_anchors(const QTextBlock &start, const QString &name) +{ + const QString curDir = QFileInfo(name).path(); + + for (QTextBlock bit = start; bit != mTextDocument->end(); bit = bit.next()) { + for (QTextBlock::iterator fit = bit.begin(); !(fit.atEnd()); ++fit) { + QTextFragment frag = fit.fragment(); + + if (frag.isValid() && frag.charFormat().isAnchor()) { + QString hrefString = frag.charFormat().anchorHref(); + + // remove ./ or ../ + // making it easier to compare, with links + while (!hrefString.isNull() && (hrefString.at(0) == QLatin1Char('.') || hrefString.at(0) == QLatin1Char('/'))) { + hrefString.remove(0, 1); + } + + QUrl href(hrefString); + if (href.isValid() && !href.isEmpty()) { + if (href.isRelative()) { // Inside document link + if (!hrefString.indexOf(QLatin1Char('#'))) + hrefString = name + hrefString; + else if (QFileInfo(hrefString).path() == QLatin1String(".") && curDir != QLatin1String(".")) + hrefString = curDir + QLatin1Char('/') + hrefString; + + // QTextCharFormat sometimes splits a link in two + // if there's no white space between words & the first one is an anchor + // consider whole word to be an anchor + ++fit; + int fragLen = frag.length(); + if (!fit.atEnd() && ((fit.fragment().position() - frag.position()) == 1)) + fragLen += fit.fragment().length(); + --fit; + + _insert_local_links(hrefString, QPair(frag.position(), frag.position() + fragLen)); + } else { // Outside document link + Okular::BrowseAction *action = new Okular::BrowseAction(QUrl(href.toString())); + + emit addAction(action, frag.position(), frag.position() + frag.length()); + } + } + + const QStringList &names = frag.charFormat().anchorNames(); + if (!names.empty()) { + for (QStringList::const_iterator lit = names.constBegin(); lit != names.constEnd(); ++lit) { + mSectionMap.insert(name + QLatin1Char('#') + *lit, bit); + } + } + + } // end anchor case + } + } +} + +void Converter::_insert_local_links(const QString &key, const QPair value) +{ + if (mLocalLinks.contains(key)) { + mLocalLinks[key].append(value); + } else { + QVector> vec; + vec.append(value); + mLocalLinks.insert(key, vec); + } +} + +static QPoint calculateXYPosition(QTextDocument *document, int startPosition) +{ + const QTextBlock startBlock = document->findBlock(startPosition); + const QRectF startBoundingRect = document->documentLayout()->blockBoundingRect(startBlock); + + QTextLayout *startLayout = startBlock.layout(); + if (!startLayout) { + qWarning() << "Start layout not found" << startLayout; + return QPoint(); + } + + int startPos = startPosition - startBlock.position(); + const QTextLine startLine = startLayout->lineForTextPosition(startPos); + + double x = startBoundingRect.x(); + double y = startBoundingRect.y() + startLine.y(); + + y = (int)y % 800; + + return QPoint(x, y); +} + +QTextDocument *Converter::convert(const QString &fileName) +{ + EpubDocument *newDocument = new EpubDocument(fileName); + if (!newDocument->isValid()) { + emit error(i18n("Error while opening the EPub document."), -1); + delete newDocument; + return nullptr; + } + mTextDocument = newDocument; + + QTextCursor *_cursor = new QTextCursor(mTextDocument); + + mLocalLinks.clear(); + mSectionMap.clear(); + + // Emit the document meta data + _emitData(Okular::DocumentInfo::Title, EPUB_TITLE); + _emitData(Okular::DocumentInfo::Author, EPUB_CREATOR); + _emitData(Okular::DocumentInfo::Subject, EPUB_SUBJECT); + _emitData(Okular::DocumentInfo::Creator, EPUB_PUBLISHER); + + _emitData(Okular::DocumentInfo::Description, EPUB_DESCRIPTION); + + _emitData(Okular::DocumentInfo::CreationDate, EPUB_DATE); + _emitData(Okular::DocumentInfo::Category, EPUB_TYPE); + _emitData(Okular::DocumentInfo::Copyright, EPUB_RIGHTS); + emit addMetaData(Okular::DocumentInfo::MimeType, QStringLiteral("application/epub+zip")); + + struct eiterator *it; + + // iterate over the book + it = epub_get_iterator(mTextDocument->getEpub(), EITERATOR_SPINE, 0); + + // if the background color of the document is non-white it will be handled by QTextDocument::setHtml() + bool firstPage = true; + QVector movieAnnots; + QVector soundActions; + + // HACK BEGIN Get the links without CSS to be blue + // Remove if Qt ever gets fixed and the code in textdocumentgenerator.cpp works + const QPalette orig = qApp->palette(); + QPalette p = orig; + p.setColor(QPalette::Link, Qt::blue); + // HACK END + + const QSize videoSize(320, 240); + do { + if (!epub_it_get_curr(it)) { + continue; + } + + movieAnnots.clear(); + soundActions.clear(); + + const QString link = QString::fromUtf8(epub_it_get_curr_url(it)); + mTextDocument->setCurrentSubDocument(link); + QString htmlContent = QString::fromUtf8(epub_it_get_curr(it)); + + // as QTextCharFormat::anchorNames() ignores sections, replace it with

+ htmlContent.replace(QRegExp(QStringLiteral("< *section")), QStringLiteral("maxContentHeight(); + const int maxWidth = mTextDocument->maxContentWidth(); + QDomDocument dom; + if (dom.setContent(htmlContent)) { + QDomNodeList svgs = dom.elementsByTagName(QStringLiteral("svg")); + if (!svgs.isEmpty()) { + QList imgNodes; + for (int i = 0; i < svgs.length(); ++i) { + QDomNodeList images = svgs.at(i).toElement().elementsByTagName(QStringLiteral("image")); + for (int j = 0; j < images.length(); ++j) { + QString lnk = images.at(i).toElement().attribute(QStringLiteral("xlink:href")); + int ht = images.at(i).toElement().attribute(QStringLiteral("height")).toInt(); + int wd = images.at(i).toElement().attribute(QStringLiteral("width")).toInt(); + QImage img = mTextDocument->loadResource(QTextDocument::ImageResource, QUrl(lnk)).value(); + if (ht == 0) + ht = img.height(); + if (wd == 0) + wd = img.width(); + if (ht > maxHeight) + ht = maxHeight; + if (wd > maxWidth) + wd = maxWidth; + mTextDocument->addResource(QTextDocument::ImageResource, QUrl(lnk), img); + QDomDocument newDoc; + newDoc.setContent(QStringLiteral("").arg(lnk).arg(ht).arg(wd)); + imgNodes.append(newDoc.documentElement()); + } + for (const QDomNode &nd : qAsConst(imgNodes)) { + svgs.at(i).parentNode().replaceChild(nd, svgs.at(i)); + } + } + } + + // handle embedded videos + QDomNodeList videoTags = dom.elementsByTagName(QStringLiteral("video")); + while (!videoTags.isEmpty()) { + QDomNodeList sourceTags = videoTags.at(0).toElement().elementsByTagName(QStringLiteral("source")); + if (!sourceTags.isEmpty()) { + QString lnk = sourceTags.at(0).toElement().attribute(QStringLiteral("src")); + + Okular::Movie *movie = new Okular::Movie(mTextDocument->loadResource(EpubDocument::MovieResource, QUrl(lnk)).toString()); + movie->setSize(videoSize); + movie->setShowControls(true); + + Okular::MovieAnnotation *annot = new Okular::MovieAnnotation; + annot->setMovie(movie); + + movieAnnots.push_back(annot); + QDomDocument tempDoc; + tempDoc.setContent(QStringLiteral("

<video></video>
")); + videoTags.at(0).parentNode().replaceChild(tempDoc.documentElement(), videoTags.at(0)); + } + } + + // handle embedded audio + QDomNodeList audioTags = dom.elementsByTagName(QStringLiteral("audio")); + while (!audioTags.isEmpty()) { + QDomElement element = audioTags.at(0).toElement(); + bool repeat = element.hasAttribute(QStringLiteral("loop")); + QString lnk = element.attribute(QStringLiteral("src")); + + Okular::Sound *sound = new Okular::Sound(mTextDocument->loadResource(EpubDocument::AudioResource, QUrl(lnk)).toByteArray()); + + Okular::SoundAction *soundAction = new Okular::SoundAction(1.0, true, repeat, false, sound); + soundActions.push_back(soundAction); + + QDomDocument tempDoc; + tempDoc.setContent(QStringLiteral("
<audio></audio>
")); + audioTags.at(0).parentNode().replaceChild(tempDoc.documentElement(), audioTags.at(0)); + } + htmlContent = dom.toString(); + } + + // HACK BEGIN + qApp->setPalette(p); + // HACK END + + QTextBlock before; + if (firstPage) { + mTextDocument->setHtml(htmlContent); + firstPage = false; + before = mTextDocument->begin(); + } else { + before = _cursor->block(); + _cursor->insertHtml(htmlContent); + } + // HACK BEGIN + qApp->setPalette(orig); + // HACK END + + QTextCursor csr(before); // a temporary cursor pointing at the begin of the last inserted block + int index = 0; + + while (!movieAnnots.isEmpty() && !(csr = mTextDocument->find(QStringLiteral(""), csr)).isNull()) { + const int posStart = csr.position(); + const QPoint startPoint = calculateXYPosition(mTextDocument, posStart); + QImage img(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/okular-epub-movie.png"))); + img = img.scaled(videoSize); + csr.insertImage(img); + const int posEnd = csr.position(); + const QRect videoRect(startPoint, videoSize); + movieAnnots[index]->setBoundingRectangle(Okular::NormalizedRect(videoRect, mTextDocument->pageSize().width(), mTextDocument->pageSize().height())); + emit addAnnotation(movieAnnots[index++], posStart, posEnd); + csr.movePosition(QTextCursor::NextWord); + } + + csr = QTextCursor(before); + index = 0; + const QString keyToSearch(QStringLiteral("")); + while (!soundActions.isEmpty() && !(csr = mTextDocument->find(keyToSearch, csr)).isNull()) { + const int posStart = csr.position() - keyToSearch.size(); + const QImage img(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/okular-epub-sound-icon.png"))); + csr.insertImage(img); + const int posEnd = csr.position(); + qDebug() << posStart << posEnd; + ; + emit addAction(soundActions[index++], posStart, posEnd); + csr.movePosition(QTextCursor::NextWord); + } + + mSectionMap.insert(link, before); + + _handle_anchors(before, link); + + const int page = mTextDocument->pageCount(); + + // it will clear the previous format + // useful when the last line had a bullet + _cursor->insertBlock(QTextBlockFormat()); + + while (mTextDocument->pageCount() == page) + _cursor->insertText(QStringLiteral("\n")); + + } while (epub_it_get_next(it)); + + epub_free_iterator(it); + + // handle toc + struct titerator *tit; + + // FIXME: support other method beside NAVMAP and GUIDE + tit = epub_get_titerator(mTextDocument->getEpub(), TITERATOR_NAVMAP, 0); + if (!tit) + tit = epub_get_titerator(mTextDocument->getEpub(), TITERATOR_GUIDE, 0); + + if (tit) { + do { + if (epub_tit_curr_valid(tit)) { + char *clink = epub_tit_get_curr_link(tit); + QString link = QString::fromUtf8(clink); + char *label = epub_tit_get_curr_label(tit); + QTextBlock block = mTextDocument->begin(); // must point somewhere + + if (mSectionMap.contains(link)) { + block = mSectionMap.value(link); + } else { // load missing resource + char *data = nullptr; + // epub_get_data can't handle whitespace url encodings + QByteArray ba = link.replace(QLatin1String("%20"), QLatin1String(" ")).toLatin1(); + const char *clinkClean = ba.data(); + int size = epub_get_data(mTextDocument->getEpub(), clinkClean, &data); + + if (data) { + _cursor->insertBlock(); + + // try to load as image and if not load as html + block = _cursor->block(); + QImage image; + mSectionMap.insert(link, block); + if (image.loadFromData((unsigned char *)data, size)) { + mTextDocument->addResource(QTextDocument::ImageResource, QUrl(link), image); + _cursor->insertImage(link); + } else { + _cursor->insertHtml(QString::fromUtf8(data)); + // Add anchors to hashes + _handle_anchors(block, link); + } + + // Start new file in a new page + int page = mTextDocument->pageCount(); + while (mTextDocument->pageCount() == page) + _cursor->insertText(QStringLiteral("\n")); + } + + free(data); + } + + if (block.isValid()) { // be sure we actually got a block + emit addTitle(epub_tit_get_curr_depth(tit), QString::fromUtf8(label), block); + } else { + qDebug() << "Error: no block found for" << link; + } + + if (clink) + free(clink); + if (label) + free(label); + } + } while (epub_tit_next(tit)); + + epub_free_titerator(tit); + } else { + qDebug() << "no toc found"; + } + + // adding link actions + QHashIterator>> hit(mLocalLinks); + while (hit.hasNext()) { + hit.next(); + + const QTextBlock block = mSectionMap.value(hit.key()); + + for (int i = 0; i < hit.value().size(); ++i) { + if (block.isValid()) { // be sure we actually got a block + Okular::DocumentViewport viewport = calculateViewport(mTextDocument, block); + + Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); + + emit addAction(action, hit.value()[i].first, hit.value()[i].second); + } else { + qDebug() << "Error: no block found for " << hit.key(); + } + } + } + + delete _cursor; + + return mTextDocument; +} diff --git a/generators/epub/converter.h b/generators/epub/converter.h new file mode 100644 index 0000000..dab0e23 --- /dev/null +++ b/generators/epub/converter.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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 EPUB_CONVERTER_H +#define EPUB_CONVERTER_H + +#include +#include + +#include "epubdocument.h" + +namespace Epub +{ +class Converter : public Okular::TextDocumentConverter +{ + Q_OBJECT + +public: + Converter(); + ~Converter() override; + + QTextDocument *convert(const QString &fileName) override; + +private: + void _emitData(Okular::DocumentInfo::Key key, enum epub_metadata type); + void _handle_anchors(const QTextBlock &start, const QString &name); + void _insert_local_links(const QString &key, const QPair value); + EpubDocument *mTextDocument; + + QHash mSectionMap; + QHash>> mLocalLinks; +}; +} + +#endif diff --git a/generators/epub/data/CMakeLists.txt b/generators/epub/data/CMakeLists.txt new file mode 100644 index 0000000..b42c90a --- /dev/null +++ b/generators/epub/data/CMakeLists.txt @@ -0,0 +1,5 @@ + +install(FILES + okular-epub-sound-icon.png + okular-epub-movie.png + DESTINATION ${KDE_INSTALL_DATADIR}/okular/pics) diff --git a/generators/epub/data/okular-epub-movie.png b/generators/epub/data/okular-epub-movie.png new file mode 100644 index 0000000000000000000000000000000000000000..d028e44ba75463c5bac907e3b28a7666fe0eaffd GIT binary patch literal 12616 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
Rzu4#7uHtcyRsEC_nwZ7oIMSFASQqb z;j$Ruh!Wh?eRfUD^me)GKgB-~f9d=lR|EIi;I0nb{se(Ycf^pF literal 0 HcmV?d00001 diff --git a/generators/epub/data/okular-epub-sound-icon.png b/generators/epub/data/okular-epub-sound-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6587a74b272ddaf35128818d55932535c62bc5f0 GIT binary patch literal 2194 zcmV;D2yOR?P)gUIaJvm@sJ$ecNIEauLg8<{t6UL-3kD>8rne2WDO7FaA?xUfX% zcRJ4?ck<-PE9=y$^XGCC(6(*czrK3)N}fM|E-zlZke4rC%Inv!<;|Nn^7idpdH?>s zl-GFo?wuSvc1(^RKVI0hY18iIA|N?AIraYi`*P>b9gBPS?#Y7(52UcLP#!*fD32dM zmM2f1$kV4!zaPhj@0rK^n>TOD;>C;Q(W6Il_@wrc9B`moMAYWR0s=uS!~4+G0Z`_JalBeFXT^$M5|h z@(=(;H4?c2A@h7B8J z_3G8Kbm>wtdxV(%Mk0}j3>h+HQ<(&45tk%@C@6Wp#hYu^tg-DeJ3CvJEn6mAwrsH- zM@3aAZCvDCH{yu&Bw46PA z))q5aVCHWuvw)KJ0ZpOJn>UL&63CJzOKe*3Uh9GPw8r)8*UQwYQ*BfzQfwlIcb6_* zvd=DDxM0EGfaiP{N-X zT8FR>>4XsK0x>EGu%0iMrq!HAC7_^mLkm0|(kJ13~Pwj*4)F zlvw}Kc18HR5}>bB$ZS3* zPMok_)*^SoGv0A*Chs}pOqeji{<<~b_rA8#Q2PJ^FrsZtMY#3Af*AIWz0$sYdl@`< zu#E)IgFxzV&N246v{>)^3)m&E`$FiA3;`IS$78@B2^B)<*}RgHlB7k87Sg3l7h4yQ zVo^WnM59KHk|s@>NaMzhWx#*|HZnn;SMqQm(&o+(P5?#-cS#~xoD*cDMvW|?1`Qh6 zBZU^F3j{E~bLY-haJ_o30EMLCd7Pp@~>nV9SFh8^a2)hTWAR#P_ zce-`!CUJ3b7Cn3REIJ;zAl))EGo@dbBPC$=dQrqPy$-EY?+E7CIeT5 zUkJd9dPdS>b)%#nCKZST-w_qphM%~S=Td_M%q1zD0E{silqAGWtuRp1O5E>tUHiSuU`H4p@|2K z7;{wUWLnwUf`WoqbOpTVrkB57ii7*DJ6{XioNWJ1^i39gT^_{0GfXI(nbYUoyu7?Z zLQGC8kuYHIKoB+%ke!{qi)foo?#qut+&|2bpsv}tzS+8U>qWdr=ppre;NCzAk&gNK z`Oh;lGS)O~*zhmLWXumj+&?N-tQgm|YuCT$IZ3u$IX5C?yzCQGHcbU z)#Q_qE@u2BIXO8cD=TZ8A^VP~kSY+@y~12zF7)cvYh;xwRce1~vLz04WKK>`PyeTB zfsaTRb8J3fE<3#|RjTy!ADT;4h5zQ}j}3lm0D-Co)eUMG{Kf!pCK~*~ppijigCv8d zCPn_%tXZ>f%-`+3cYpMdlyx;C*~Ih zah@Ou)bz;w)&nActsoWB>pF literal 0 HcmV?d00001 diff --git a/generators/epub/epubdocument.cpp b/generators/epub/epubdocument.cpp new file mode 100644 index 0000000..dbef144 --- /dev/null +++ b/generators/epub/epubdocument.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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. * + ***************************************************************************/ + +#include "epubdocument.h" +#include +#include + +#include + +Q_LOGGING_CATEGORY(OkularEpuDebug, "org.kde.okular.generators.epu", QtWarningMsg) +using namespace Epub; + +EpubDocument::EpubDocument(const QString &fileName) + : QTextDocument() + , padding(20) +{ + mEpub = epub_open(qPrintable(fileName), 3); + + setPageSize(QSizeF(600, 800)); +} + +bool EpubDocument::isValid() +{ + return (mEpub ? true : false); +} + +EpubDocument::~EpubDocument() +{ + if (mEpub) + epub_close(mEpub); + + epub_cleanup(); +} + +struct epub *EpubDocument::getEpub() +{ + return mEpub; +} + +void EpubDocument::setCurrentSubDocument(const QString &doc) +{ + mCurrentSubDocument.clear(); + int index = doc.indexOf('/'); + if (index > 0) { + mCurrentSubDocument = QUrl::fromLocalFile(doc.left(index + 1)); + } +} + +int EpubDocument::maxContentHeight() const +{ + return pageSize().height() - (2 * padding); +} + +int EpubDocument::maxContentWidth() const +{ + return pageSize().width() - (2 * padding); +} + +void EpubDocument::checkCSS(QString &css) +{ + // remove paragraph line-heights + css.remove(QRegExp(QStringLiteral("line-height\\s*:\\s*[\\w\\.]*;"))); +} + +QVariant EpubDocument::loadResource(int type, const QUrl &name) +{ + int size; + char *data; + + QString fileInPath = mCurrentSubDocument.resolved(name).path(); + + // Get the data from the epub file + size = epub_get_data(mEpub, fileInPath.toUtf8().constData(), &data); + + QVariant resource; + + if (data) { + switch (type) { + case QTextDocument::ImageResource: { + QImage img = QImage::fromData((unsigned char *)data, size); + const int maxHeight = maxContentHeight(); + const int maxWidth = maxContentWidth(); + if (img.height() > maxHeight) + img = img.scaledToHeight(maxHeight, Qt::SmoothTransformation); + if (img.width() > maxWidth) + img = img.scaledToWidth(maxWidth, Qt::SmoothTransformation); + resource.setValue(img); + break; + } + case QTextDocument::StyleSheetResource: { + QString css = QString::fromUtf8(data); + checkCSS(css); + resource.setValue(css); + break; + } + case EpubDocument::MovieResource: { + QTemporaryFile *tmp = new QTemporaryFile(QStringLiteral("%1/okrXXXXXX").arg(QDir::tempPath()), this); + if (!tmp->open()) + qCWarning(OkularEpuDebug) << "EPUB : error creating temporary video file"; + if (tmp->write(data, size) == -1) + qCWarning(OkularEpuDebug) << "EPUB : error writing data" << tmp->errorString(); + tmp->flush(); + resource.setValue(tmp->fileName()); + break; + } + case EpubDocument::AudioResource: { + QByteArray ba(data, size); + resource.setValue(ba); + break; + } + default: + resource.setValue(QString::fromUtf8(data)); + break; + } + + free(data); + } + + // add to cache + addResource(type, name, resource); + + return resource; +} diff --git a/generators/epub/epubdocument.h b/generators/epub/epubdocument.h new file mode 100644 index 0000000..77927fc --- /dev/null +++ b/generators/epub/epubdocument.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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 EPUB_DOCUMENT_H +#define EPUB_DOCUMENT_H + +#include +#include +#include +#include +#include +#include + +namespace Epub +{ +class EpubDocument : public QTextDocument +{ + Q_OBJECT + +public: + explicit EpubDocument(const QString &fileName); + ~EpubDocument() override; + bool isValid(); + struct epub *getEpub(); + void setCurrentSubDocument(const QString &doc); + int maxContentHeight() const; + int maxContentWidth() const; + enum Multimedia { MovieResource = QTextDocument::UserResource, AudioResource }; + +protected: + QVariant loadResource(int type, const QUrl &name) override; + +private: + void checkCSS(QString &css); + + struct epub *mEpub; + QUrl mCurrentSubDocument; + + int padding; + + friend class Converter; +}; + +} +Q_DECLARE_LOGGING_CATEGORY(OkularEpuDebug) +#endif diff --git a/generators/epub/generator_epub.cpp b/generators/epub/generator_epub.cpp new file mode 100644 index 0000000..34dc4c1 --- /dev/null +++ b/generators/epub/generator_epub.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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. * + ***************************************************************************/ + +#include "generator_epub.h" + +#include "converter.h" + +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(EPubGenerator, "libokularGenerator_epub.json") + +EPubGenerator::EPubGenerator(QObject *parent, const QVariantList &args) + : Okular::TextDocumentGenerator(new Epub::Converter, QStringLiteral("okular_epub_generator_settings"), parent, args) +{ +} + +EPubGenerator::~EPubGenerator() +{ +} + +void EPubGenerator::addPages(KConfigDialog *dlg) +{ + Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + + dlg->addPage(widget, generalSettings(), i18n("EPub"), QStringLiteral("application-epub+zip"), i18n("EPub Backend Configuration")); +} + +#include "generator_epub.moc" diff --git a/generators/epub/generator_epub.h b/generators/epub/generator_epub.h new file mode 100644 index 0000000..6abd852 --- /dev/null +++ b/generators/epub/generator_epub.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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_GENERATOR_EPUB_H_ +#define _OKULAR_GENERATOR_EPUB_H_ +#include + +class EPubGenerator : public Okular::TextDocumentGenerator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + EPubGenerator(QObject *parent, const QVariantList &args); + ~EPubGenerator() override; + + // [INHERITED] reparse configuration + void addPages(KConfigDialog *dlg) override; +}; + +#endif diff --git a/generators/epub/libokularGenerator_epub.json b/generators/epub/libokularGenerator_epub.json new file mode 100644 index 0000000..f26c769 --- /dev/null +++ b/generators/epub/libokularGenerator_epub.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "elylevy@cs.huji.ac.il", + "Name": "Ely Levy", + "Name[az]": "Ely Levy", + "Name[ca@valencia]": "Ely Levy", + "Name[ca]": "Ely Levy", + "Name[cs]": "Ely Levy", + "Name[da]": "Ely Levy", + "Name[de]": "Ely Levy", + "Name[el]": "Ely Levy", + "Name[en_GB]": "Ely Levy", + "Name[es]": "Ely Levy", + "Name[et]": "Ely Levy", + "Name[eu]": "Ely Levy", + "Name[fi]": "Ely Levy", + "Name[fr]": "Ely Levy", + "Name[gl]": "Ely Levy", + "Name[ia]": "Ely Levy", + "Name[it]": "Ely Levy", + "Name[ko]": "Ely Levy", + "Name[lt]": "Ely Levy", + "Name[nl]": "Ely Levy", + "Name[nn]": "Ely Levy", + "Name[pl]": "Ely Levy", + "Name[pt]": "Ely Levy", + "Name[pt_BR]": "Ely Levy", + "Name[ru]": "Ely Levy", + "Name[sk]": "Ely Levy", + "Name[sl]": "Ely Levy", + "Name[sr@ijekavian]": "Ели Леви", + "Name[sr@ijekavianlatin]": "Eli Levi", + "Name[sr@latin]": "Eli Levi", + "Name[sr]": "Ели Леви", + "Name[sv]": "Ely Levy", + "Name[tr]": "Ely Levy", + "Name[uk]": "Ely Levy", + "Name[x-test]": "xxEly Levyxx", + "Name[zh_CN]": "Ely Levy", + "Name[zh_TW]": "Ely Levy" + } + ], + "Copyright": "© 2008 Ely Levy", + "Copyright[az]": "© 2008 Ely Levy", + "Copyright[ca@valencia]": "© 2008 Ely Levy", + "Copyright[ca]": "© 2008 Ely Levy", + "Copyright[cs]": "© 2008 Ely Levy", + "Copyright[da]": "© 2008 Ely Levy", + "Copyright[de]": "© 2008 Ely Levy", + "Copyright[el]": "© 2008 Ely Levy", + "Copyright[en_GB]": "© 2008 Ely Levy", + "Copyright[es]": "© 2008 Ely Levy", + "Copyright[et]": "© 2008: Ely Levy", + "Copyright[eu]": "© 2008 Ely Levy", + "Copyright[fi]": "© 2008 Ely Levy", + "Copyright[fr]": "© 2008 Ely Levy", + "Copyright[gl]": "© 2008 Ely Levy", + "Copyright[ia]": "© 2008 Ely Levy", + "Copyright[it]": "© 2008 Ely Levy", + "Copyright[ko]": "© 2008 Ely Levy", + "Copyright[lt]": "© 2008 Ely Levy", + "Copyright[nl]": "© 2008 Ely Levy", + "Copyright[nn]": "© 2008 Ely Levy", + "Copyright[pl]": "© 2008 Ely Levy", + "Copyright[pt]": "© 2008 Ely Levy", + "Copyright[pt_BR]": "© 2008 Ely Levy", + "Copyright[ru]": "© Ely Levy, 2008", + "Copyright[sk]": "© 2008 Ely Levy", + "Copyright[sl]": "© 2008 Ely Levy", + "Copyright[sr@ijekavian]": "© 2008, Ели Леви", + "Copyright[sr@ijekavianlatin]": "© 2008, Eli Levi", + "Copyright[sr@latin]": "© 2008, Eli Levi", + "Copyright[sr]": "© 2008, Ели Леви", + "Copyright[sv]": "© 2008 Ely Levy", + "Copyright[tr]": "© 2008 Ely Levy", + "Copyright[uk]": "© Ely Levy, 2008", + "Copyright[x-test]": "xx© 2008 Ely Levyxx", + "Copyright[zh_CN]": "© 2008 Ely Levy", + "Copyright[zh_TW]": "© 2008 Ely Levy", + "Description": "An EPub backend", + "Description[az]": "EPub modulu", + "Description[ca@valencia]": "Un dorsal per a l'EPub", + "Description[ca]": "Un dorsal per a l'EPub", + "Description[cs]": "Podpůrná vrstva EPub", + "Description[da]": "En EPub-backend", + "Description[de]": "Ein Anzeigemodul für EPUB", + "Description[el]": "Σύστημα υποστήριξης EPub", + "Description[en_GB]": "An EPub backend", + "Description[es]": "Un motor para EPub", + "Description[et]": "EPubi taustaprogramm", + "Description[eu]": "EPub-en bizkarraldeko bat", + "Description[fi]": "EPub-taustaosa", + "Description[fr]": "Un moteur EPub", + "Description[gl]": "Unha infraestrutura para EPub", + "Description[ia]": "Un retro-administration de EPub", + "Description[it]": "Backend EPub", + "Description[ko]": "EPub 백엔드", + "Description[lt]": "EPub programinė sąsaja", + "Description[nl]": "Een EPub-backend", + "Description[nn]": "Ein EPUB-motor", + "Description[pl]": "Obsługa formatu EPUB", + "Description[pt]": "Uma infra-estrutura de EPub", + "Description[pt_BR]": "Uma infraestrutura para EPub", + "Description[ru]": "Модуль поддержки формата EPub", + "Description[sk]": "EPub backend", + "Description[sl]": "Zaledje za EPub", + "Description[sr@ijekavian]": "Позадина за ЕПУБ", + "Description[sr@ijekavianlatin]": "Pozadina za EPUB", + "Description[sr@latin]": "Pozadina za EPUB", + "Description[sr]": "Позадина за ЕПУБ", + "Description[sv]": "Ett Epub-gränssnitt", + "Description[tr]": "Bir EPub arka ucu", + "Description[uk]": "Сервер EPub", + "Description[x-test]": "xxAn EPub backendxx", + "Description[zh_CN]": "EPub 后端", + "Description[zh_TW]": "EPub 後端介面", + "Id": "okular_epub", + "License": "GPL", + "MimeTypes": [ + "application/epub+zip" + ], + "Name": "EPub Backend", + "Name[az]": "EPub modulu", + "Name[ca@valencia]": "Dorsal EPub", + "Name[ca]": "Dorsal EPub", + "Name[cs]": "Podpůrná vrstva EPub", + "Name[da]": "EPub-backend", + "Name[de]": "Anzeigemodul für EPUB", + "Name[el]": "Σύστημα υποστήριξης EPub", + "Name[en_GB]": "EPub Backend", + "Name[es]": "Motor para EPub", + "Name[et]": "EPubi taustaprogramm", + "Name[eu]": "EPub-en bizkarraldekoa", + "Name[fi]": "EPub-taustaosa", + "Name[fr]": "Moteur EPub", + "Name[gl]": "Infraestrutura de EPub", + "Name[ia]": "Retro-Administration de EPub", + "Name[it]": "Backend EPub", + "Name[ko]": "EPub 백엔드", + "Name[lt]": "EPub programinė sąsaja", + "Name[nl]": "EPub-backend", + "Name[nn]": "EPUB-motor", + "Name[pl]": "Obsługa EPUB", + "Name[pt]": "Infra-Estrutura de EPub", + "Name[pt_BR]": "Infraestrutura EPub", + "Name[ru]": "Модуль поддержки формата EPub", + "Name[sk]": "EPub Backend", + "Name[sl]": "Zaledje za EPub", + "Name[sr@ijekavian]": "Позадина за ЕПУБ", + "Name[sr@ijekavianlatin]": "Pozadina za EPUB", + "Name[sr@latin]": "Pozadina za EPUB", + "Name[sr]": "Позадина за ЕПУБ", + "Name[sv]": "Epub-gränssnitt", + "Name[tr]": "EPub Arka Ucu", + "Name[uk]": "Модуль EPub", + "Name[x-test]": "xxEPub Backendxx", + "Name[zh_CN]": "EPub 后端", + "Name[zh_TW]": "EPub 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.2.3" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/epub/okularApplication_epub.desktop b/generators/epub/okularApplication_epub.desktop new file mode 100755 index 0000000..8e3adfa --- /dev/null +++ b/generators/epub/okularApplication_epub.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/epub+zip; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=1 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=epub, e-book +X-KDE-Keywords[ar]=epub, e-book +X-KDE-Keywords[az]=epub, e-book +X-KDE-Keywords[bg]=epub, e-book +X-KDE-Keywords[bs]=epub, e-book +X-KDE-Keywords[ca]=epub, e-book +X-KDE-Keywords[ca@valencia]=epub, e-book +X-KDE-Keywords[cs]=epub, e-book +X-KDE-Keywords[da]=epub,e-book +X-KDE-Keywords[de]=epub, e-book +X-KDE-Keywords[el]=epub, e-book +X-KDE-Keywords[en_GB]=epub, e-book +X-KDE-Keywords[es]=epub, e-book +X-KDE-Keywords[et]=epub, e-book, e-raamat +X-KDE-Keywords[eu]=epub, e-liburua +X-KDE-Keywords[fi]=epub, e-book, e-kirja, sähkökirja +X-KDE-Keywords[fr]=epub, e-book +X-KDE-Keywords[ga]=epub, ríomhleabhar, r-leabhar +X-KDE-Keywords[gl]=epub, e-book, libro dixital +X-KDE-Keywords[hu]=epub, e-book +X-KDE-Keywords[ia]=epub, e-book +X-KDE-Keywords[is]=epub, e-book, rafbók +X-KDE-Keywords[it]=epub, e-book +X-KDE-Keywords[ja]=epub, e-book +X-KDE-Keywords[kk]=epub, e-book +X-KDE-Keywords[km]=epub, e-book +X-KDE-Keywords[ko]=epub, e-book,전자책,이북 +X-KDE-Keywords[lt]=epub, e-book +X-KDE-Keywords[lv]=epub, e-book, e-grāmata +X-KDE-Keywords[mr]=epub, e-book +X-KDE-Keywords[nb]=epub, e-bok +X-KDE-Keywords[nds]=epub, e-book +X-KDE-Keywords[nl]=epub, e-book +X-KDE-Keywords[nn]=epub, e-book +X-KDE-Keywords[pa]=epub, e-book, ਈ-ਬੁੱਕ +X-KDE-Keywords[pl]=epub, e-book +X-KDE-Keywords[pt]=epub, e-book +X-KDE-Keywords[pt_BR]=epub, e-book +X-KDE-Keywords[ro]=epub, e-book +X-KDE-Keywords[ru]=epub, e-book, электронная книга +X-KDE-Keywords[sk]=epub, e-book +X-KDE-Keywords[sl]=epub, e-knjiga +X-KDE-Keywords[sr]=epub, e-book,ЕПУБ,е‑књига +X-KDE-Keywords[sr@ijekavian]=epub, e-book,ЕПУБ,е‑књига +X-KDE-Keywords[sr@ijekavianlatin]=epub, e-book,EPUB,e‑knjiga +X-KDE-Keywords[sr@latin]=epub, e-book,EPUB,e‑knjiga +X-KDE-Keywords[sv]=epub, e-bok +X-KDE-Keywords[tr]=epub, e-book +X-KDE-Keywords[uk]=epub,e-book,електронна,книга +X-KDE-Keywords[x-test]=xxepubxx,xx e-bookxx +X-KDE-Keywords[zh_CN]=epub, e-book,电子书 +X-KDE-Keywords[zh_TW]=epub, e-book diff --git a/generators/epub/okularEPub.desktop b/generators/epub/okularEPub.desktop new file mode 100644 index 0000000..772ee4d --- /dev/null +++ b/generators/epub/okularEPub.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/epub+zip; diff --git a/generators/epub/org.kde.mobile.okular_epub.desktop b/generators/epub/org.kde.mobile.okular_epub.desktop new file mode 100644 index 0000000..040f8bf --- /dev/null +++ b/generators/epub/org.kde.mobile.okular_epub.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +MimeType=application/epub+zip; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=epub, e-book +X-KDE-Keywords[ar]=epub, e-book +X-KDE-Keywords[az]=epub, e-book +X-KDE-Keywords[bg]=epub, e-book +X-KDE-Keywords[bs]=epub, e-book +X-KDE-Keywords[ca]=epub, e-book +X-KDE-Keywords[ca@valencia]=epub, e-book +X-KDE-Keywords[cs]=epub, e-book +X-KDE-Keywords[da]=epub,e-book +X-KDE-Keywords[de]=epub, e-book +X-KDE-Keywords[el]=epub, e-book +X-KDE-Keywords[en_GB]=epub, e-book +X-KDE-Keywords[es]=epub, e-book +X-KDE-Keywords[et]=epub, e-book, e-raamat +X-KDE-Keywords[eu]=epub, e-liburua +X-KDE-Keywords[fi]=epub, e-book, e-kirja, sähkökirja +X-KDE-Keywords[fr]=epub, e-book +X-KDE-Keywords[ga]=epub, ríomhleabhar, r-leabhar +X-KDE-Keywords[gl]=epub, e-book, libro dixital +X-KDE-Keywords[hu]=epub, e-book +X-KDE-Keywords[ia]=epub, e-book +X-KDE-Keywords[is]=epub, e-book, rafbók +X-KDE-Keywords[it]=epub, e-book +X-KDE-Keywords[ja]=epub, e-book +X-KDE-Keywords[kk]=epub, e-book +X-KDE-Keywords[km]=epub, e-book +X-KDE-Keywords[ko]=epub, e-book,전자책,이북 +X-KDE-Keywords[lt]=epub, e-book +X-KDE-Keywords[lv]=epub, e-book, e-grāmata +X-KDE-Keywords[mr]=epub, e-book +X-KDE-Keywords[nb]=epub, e-bok +X-KDE-Keywords[nds]=epub, e-book +X-KDE-Keywords[nl]=epub, e-book +X-KDE-Keywords[nn]=epub, e-book +X-KDE-Keywords[pa]=epub, e-book, ਈ-ਬੁੱਕ +X-KDE-Keywords[pl]=epub, e-book +X-KDE-Keywords[pt]=epub, e-book +X-KDE-Keywords[pt_BR]=epub, e-book +X-KDE-Keywords[ro]=epub, e-book +X-KDE-Keywords[ru]=epub, e-book, электронная книга +X-KDE-Keywords[sk]=epub, e-book +X-KDE-Keywords[sl]=epub, e-knjiga +X-KDE-Keywords[sr]=epub, e-book,ЕПУБ,е‑књига +X-KDE-Keywords[sr@ijekavian]=epub, e-book,ЕПУБ,е‑књига +X-KDE-Keywords[sr@ijekavianlatin]=epub, e-book,EPUB,e‑knjiga +X-KDE-Keywords[sr@latin]=epub, e-book,EPUB,e‑knjiga +X-KDE-Keywords[sv]=epub, e-bok +X-KDE-Keywords[tr]=epub, e-book +X-KDE-Keywords[uk]=epub,e-book,електронна,книга +X-KDE-Keywords[x-test]=xxepubxx,xx e-bookxx +X-KDE-Keywords[zh_CN]=epub, e-book,电子书 +X-KDE-Keywords[zh_TW]=epub, e-book diff --git a/generators/epub/org.kde.okular-epub.metainfo.xml b/generators/epub/org.kde.okular-epub.metainfo.xml new file mode 100644 index 0000000..04c8c7b --- /dev/null +++ b/generators/epub/org.kde.okular-epub.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-epub + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + EPub + ഈപബ്‌ + EPub + EPUB + EPUB + EPub + EPub + EPub + EPub + EPub + ЕПУБ + EPUB + ЕПУБ + EPUB + Epub + EPub + EPub + xxEPubxx + EPub + EPub + Adds support for reading E-Books + E-Books sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir llibres electrònics + Afig la implementació per a llegir llibres electrònics + Přidává podporu pro čtení e-booků + Bietet Unterstützung zum Lesen von EPub-E-Books + Προσθέτει υποστήριξη για την ανάγνωση E-Books + Adds support for reading E-Books + Permite la lectura de libros electrónicos + E-raamatute lugemise toetus + E-Liburuak irakurtzeko euskarria gehitzen du + Lisää e-kirjojen lukutuen + Permet la lecture des E-Books + Engade a posibilidade de ler libros electrónicos + Adde supporto per leger E-libros + Aggiunge il supporto per la lettura di libri digitali in formato EPub + 전자책 읽기 지원 추가 + Prideda palaikymą elektroninių knygų skaitymui + ഇ-ബുക്കുകൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van e-boeken toe + Legg til støtte for Ã¥ lesa e-bøker i EPUB-formatet + Dodaje obsługę czytania ebooków + Adiciona o suporte para a leitura de E-Books + Adiciona o suporte para leitura de E-Books + Поддержка чтения электронных книг EPub + Pridá podporu pre čítanie e-kníh + Doda podporo za branje e-knjig + Подршка за читање е‑књига + PodrÅ¡ka za čitanje e‑knjiga + Подршка за читање е‑књига + PodrÅ¡ka za čitanje e‑knjiga + Lägger till stöd för att läsa e-böcker + E-Kitapları okumak için destek ekler + Додає підтримку читання електронних книг + xxAdds support for reading E-Booksxx + 增加对电子书的阅读支持 + 加入讀取電子書的支援 + + application/epub+zip + + https://okular.kde.org + + + + + + + diff --git a/generators/fax/CMakeLists.txt b/generators/fax/CMakeLists.txt new file mode 100644 index 0000000..d8e9cd0 --- /dev/null +++ b/generators/fax/CMakeLists.txt @@ -0,0 +1,20 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_fax") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + + +########### next target ############### + +set(okularGenerator_fax_PART_SRCS generator_fax.cpp faxdocument.cpp faxexpand.cpp faxinit.cpp fax_debug.cpp) + +okular_add_generator(okularGenerator_fax ${okularGenerator_fax_PART_SRCS}) + +target_link_libraries(okularGenerator_fax okularcore KF5::I18n Qt5::Xml) + +########### install files ############### +install( FILES okularFax.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_fax.desktop org.kde.mobile.okular_fax.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-fax.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/fax/Messages.sh b/generators/fax/Messages.sh new file mode 100644 index 0000000..18e1827 --- /dev/null +++ b/generators/fax/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_fax.pot diff --git a/generators/fax/fax_debug.cpp b/generators/fax/fax_debug.cpp new file mode 100644 index 0000000..4f8810e --- /dev/null +++ b/generators/fax/fax_debug.cpp @@ -0,0 +1,21 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "fax_debug.h" +Q_LOGGING_CATEGORY(FAX_LOG, "org.kde.okular.generators.fax", QtWarningMsg) diff --git a/generators/fax/fax_debug.h b/generators/fax/fax_debug.h new file mode 100644 index 0000000..d96c5c4 --- /dev/null +++ b/generators/fax/fax_debug.h @@ -0,0 +1,26 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef FAX_DEBUG_H +#define FAX_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(FAX_LOG) + +#endif diff --git a/generators/fax/faxdocument.cpp b/generators/fax/faxdocument.cpp new file mode 100644 index 0000000..7bdbad5 --- /dev/null +++ b/generators/fax/faxdocument.cpp @@ -0,0 +1,295 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "faxdocument.h" + +#include + +#include + +#include "faxexpand.h" + +static const char FAXMAGIC[] = "\000PC Research, Inc\000\000\000\000\000\000"; + +#define FAX_DPI_FINE QPoint(203, 196) + +/* rearrange input bits into t16bits lsb-first chunks */ +static void normalize(pagenode *pn, int revbits, int swapbytes, size_t length) +{ + t32bits *p = reinterpret_cast(pn->data); + + switch ((revbits << 1) | swapbytes) { + case 0: + break; + case 1: + for (; length; length -= 4) { + t32bits t = *p; + *p++ = ((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8); + } + break; + case 2: + for (; length; length -= 4) { + t32bits t = *p; + t = ((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4); + t = ((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2); + *p++ = ((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1); + } + break; + case 3: + for (; length; length -= 4) { + t32bits t = *p; + t = ((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8); + t = ((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4); + t = ((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2); + *p++ = ((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1); + } + } +} + +static bool new_image(pagenode *pn, int width, int height) +{ + pn->image = QImage(width, height, QImage::Format_MonoLSB); + pn->image.setColor(0, qRgb(255, 255, 255)); + pn->image.setColor(1, qRgb(0, 0, 0)); + pn->bytes_per_line = pn->image.bytesPerLine(); + pn->dpi = FAX_DPI_FINE; + pn->imageData = new uchar[width * height]; + + return !pn->image.isNull(); +} + +/* get compressed data into memory */ +static unsigned char *getstrip(pagenode *pn, int strip) +{ + size_t offset, roundup; + unsigned char *data; + + union { + t16bits s; + unsigned char b[2]; + } so; +#define ShortOrder so.b[1] + so.s = 1; /* XXX */ + + QFile file(pn->filename); + if (!file.open(QIODevice::ReadOnly)) + return nullptr; + + if (pn->strips == nullptr) { + offset = 0; + pn->length = file.size(); + } else if (strip < pn->nstrips) { + offset = pn->strips[strip].offset; + pn->length = pn->strips[strip].size; + } else + return nullptr; + + /* round size to full boundary plus t32bits */ + roundup = (pn->length + 7) & ~3; + + data = new uchar[roundup]; + /* clear the last 2 t32bits, to force the expander to terminate + even if the file ends in the middle of a fax line */ + *(reinterpret_cast(data + roundup / 4 - 2)) = 0; + *(reinterpret_cast(data + roundup / 4 - 1)) = 0; + + /* we expect to get it in one gulp... */ + if (!file.seek(offset) || (size_t)file.read((char *)data, pn->length) != pn->length) { + delete[] data; + return nullptr; + } + file.close(); + + pn->data = reinterpret_cast(data); + + if (pn->strips == nullptr && memcmp(data, FAXMAGIC, sizeof(FAXMAGIC) - 1) == 0) { + /* handle ghostscript / PC Research fax file */ + pn->length -= 64; + pn->vres = data[29]; + pn->data += 32; + roundup -= 64; + } + + normalize(pn, !pn->lsbfirst, ShortOrder, roundup); + if (pn->size.height() == 0) + pn->size.setHeight(G3count(pn, pn->expander == g32expand)); + + if (pn->size.height() == 0) { + delete[] data; + pn->data = nullptr; + return nullptr; + } + + if (pn->strips == nullptr) + pn->rowsperstrip = pn->size.height(); + + pn->dataOrig = reinterpret_cast(data); + + return data; +} + +static void draw_line(pixnum *run, int lineNum, pagenode *pn) +{ + t32bits *p, *p1; /* p - current line, p1 - low-res duplicate */ + pixnum *r; /* pointer to run-lengths */ + t32bits pix; /* current pixel value */ + t32bits acc; /* pixel accumulator */ + int nacc; /* number of valid bits in acc */ + int tot; /* total pixels in line */ + int n; + + lineNum += pn->stripnum * pn->rowsperstrip; + if (lineNum >= pn->size.height()) + return; + + p = reinterpret_cast(pn->imageData + lineNum * (2 - pn->vres) * pn->bytes_per_line); + p1 = reinterpret_cast(pn->vres ? nullptr : p + pn->bytes_per_line / sizeof(*p)); + + r = run; + acc = 0; + nacc = 0; + pix = pn->inverse ? ~0 : 0; + tot = 0; + while (tot < pn->size.width()) { + n = *r++; + tot += n; + /* Watch out for buffer overruns, e.g. when n == 65535. */ + if (tot > pn->size.width()) + break; + if (pix) + acc |= (~(t32bits)0 >> nacc); + else if (nacc) + acc &= (~(t32bits)0 << (32 - nacc)); + else + acc = 0; + if (nacc + n < 32) { + nacc += n; + pix = ~pix; + continue; + } + *p++ = acc; + if (p1) + *p1++ = acc; + n -= 32 - nacc; + while (n >= 32) { + n -= 32; + *p++ = pix; + if (p1) + *p1++ = pix; + } + acc = pix; + nacc = n; + pix = ~pix; + } + if (nacc) { + *p++ = acc; + if (p1) + *p1++ = acc; + } +} + +static bool get_image(pagenode *pn) +{ + unsigned char *data = getstrip(pn, 0); + if (!data) + return false; + + if (!new_image(pn, pn->size.width(), (pn->vres ? 1 : 2) * pn->size.height())) + return false; + + (*pn->expander)(pn, draw_line); + + return true; +} + +class FaxDocument::Private +{ +public: + Private(FaxDocument *parent) + : mParent(parent) + { + mPageNode.size = QSize(1728, 0); + } + + FaxDocument *mParent; + pagenode mPageNode; + FaxDocument::DocumentType mType; +}; + +FaxDocument::FaxDocument(const QString &fileName, DocumentType type) + : d(new Private(this)) +{ + d->mPageNode.filename = fileName; + d->mPageNode.strips = nullptr; + d->mPageNode.stripnum = 0; + d->mPageNode.lsbfirst = 0; + d->mPageNode.vres = 1; + d->mPageNode.inverse = 0; + d->mPageNode.data = nullptr; + d->mPageNode.dataOrig = nullptr; + d->mPageNode.imageData = nullptr; + d->mType = type; + + if (d->mType == G3) + d->mPageNode.expander = g31expand; // or g32expand?!? + else if (d->mType == G4) + d->mPageNode.expander = g4expand; +} + +FaxDocument::~FaxDocument() +{ + delete[] d->mPageNode.dataOrig; + delete[] d->mPageNode.imageData; + delete d; +} + +bool FaxDocument::load() +{ + fax_init_tables(); + + bool ok = get_image(&(d->mPageNode)); + if (!ok) + return false; + + // byte-swapping the image + int height = d->mPageNode.size.height(); + int bytes_per_line = d->mPageNode.size.width() / 8; + + QByteArray bytes(height * bytes_per_line, 0); + for (int y = height - 1; y >= 0; --y) { + quint32 offset = y * bytes_per_line; + quint32 *source = reinterpret_cast(d->mPageNode.imageData + offset); + quint32 *dest = reinterpret_cast(bytes.data() + offset); + for (int x = (bytes_per_line / 4) - 1; x >= 0; --x) { + quint32 dv = 0, sv = *source; + for (int bit = 32; bit > 0; --bit) { + dv <<= 1; + dv |= sv & 1; + sv >>= 1; + } + *dest = dv; + ++dest; + ++source; + } + } + + // convert it into a QImage + QImage img((uchar *)bytes.data(), d->mPageNode.size.width(), d->mPageNode.size.height(), QImage::Format_MonoLSB); + img.setColor(0, qRgb(255, 255, 255)); + img.setColor(1, qRgb(0, 0, 0)); + + d->mPageNode.image = img.copy().scaled(img.width(), img.height() * 1.5); + + return true; +} + +QImage FaxDocument::image() const +{ + return d->mPageNode.image; +} diff --git a/generators/fax/faxdocument.h b/generators/fax/faxdocument.h new file mode 100644 index 0000000..65d070f --- /dev/null +++ b/generators/fax/faxdocument.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tobias Koenig * + * * + * 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 FAXDOCUMENT_H +#define FAXDOCUMENT_H + +#include + +/** + * Loads a G3/G4 fax document and provides methods + * to convert it into a QImage. + */ +class FaxDocument +{ +public: + /** + * Describes the type of the fax document. + */ + enum DocumentType { + G3, ///< G3 encoded fax document + G4 ///< G4 encoded fax document + }; + + /** + * Creates a new fax document from the given @p fileName. + * + * @param fileName The name of the fax file. + * @param type The type of the fax document. + */ + explicit FaxDocument(const QString &fileName, DocumentType type = G3); + + /** + * Destroys the fax document. + */ + ~FaxDocument(); + + FaxDocument(const FaxDocument &) = delete; + FaxDocument &operator=(const FaxDocument &) = delete; + + /** + * Loads the document. + * + * @return @c true if the document can be loaded successfully, @c false otherwise. + */ + bool load(); + + /** + * Returns the document as an image. + */ + QImage image() const; + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/generators/fax/faxexpand.cpp b/generators/fax/faxexpand.cpp new file mode 100644 index 0000000..65943e5 --- /dev/null +++ b/generators/fax/faxexpand.cpp @@ -0,0 +1,720 @@ +/* Expand one page of fax data + Copyright (C) 1990, 1995 Frank D. Cringle. + +This file is part of viewfax - g3/g4 fax processing software. + +viewfax 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. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "faxexpand.h" + +#include +#include + +#include + +#include "fax_debug.h" +// Uncomment this for verbose debug output +//#define DEBUG_FAX +#define verbose false + +pagenode::pagenode() +{ +} + +/* Note that NeedBits() only works for n <= 16 */ +#define NeedBits(n) \ + do { \ + if (BitsAvail < (n)) { \ + BitAcc |= *sp++ << BitsAvail; \ + BitsAvail += 16; \ + } \ + } while (0) +#define GetBits(n) (BitAcc & ((1 << (n)) - 1)) +#define ClrBits(n) \ + do { \ + BitAcc >>= (n); \ + BitsAvail -= (n); \ + } while (0) + +#ifdef DEBUG_FAX +#define DEBUG_SHOW putchar(BitAcc &(1 << t) ? '1' : '0') +#define LOOKUP(wid, tab) \ + do { \ + int t; \ + NeedBits(wid); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", BitAcc, BitsAvail, StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ + } while (0) + +#define SETVAL(x) \ + do { \ + *pa++ = RunLength + (x); \ + printf("SETVAL: %d\t%d\n", RunLength + (x), a0); \ + a0 += x; \ + RunLength = 0; \ + } while (0) + +const char *StateNames[] = { + "Null ", + "Pass ", + "Horiz ", + "V0 ", + "VR ", + "VL ", + "Ext ", + "TermW ", + "TermB ", + "MakeUpW", + "MakeUpB", + "MakeUp ", + "EOL ", +}; + +#else +#define LOOKUP(wid, tab) \ + do { \ + NeedBits(wid); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ + } while (0) + +#define SETVAL(x) \ + do { \ + *pa++ = RunLength + (x); \ + a0 += x; \ + RunLength = 0; \ + } while (0) +#endif + +#define dumpruns(runs) \ + do { \ + printf("-------------------- %d\n", LineNum); \ + for (pa = runs, a0 = 0; a0 < lastx; a0 += *pa++) \ + printf("%4d %d\n", a0, *pa); \ + } while (0) + +#define EndOfData(pn) (sp >= pn->data + pn->length / sizeof(*pn->data)) + +/* This macro handles coding errors in G3 data. + We redefine it below for the G4 case */ +#define SKIP_EOL \ + do { \ + while (!EndOfData(pn)) { \ + NeedBits(11); \ + if (GetBits(11) == 0) \ + break; \ + ClrBits(1); \ + } \ + ClrBits(11); \ + goto EOL; \ + } while (0) +#define eol2lab \ + EOL2: + +/* the line expanders are written as macros so that they can be reused + (twice each) but still have direct access to the local variables of + the "calling" function */ +#define expand1d() \ + do { \ + while (a0 < lastx) { \ + int done = 0; \ + while (!done) { /* white first */ \ + LOOKUP(12, WhiteTable); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto EOL; \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + case S_Ext: \ + unexpected("Extension code", LineNum); \ + SKIP_EOL; \ + break; \ + default: \ + unexpected("WhiteTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + done = a0 >= lastx; \ + while (!done) { /* then black */ \ + LOOKUP(13, BlackTable); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto EOL; \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + case S_Ext: \ + unexpected("Extension code", LineNum); \ + SKIP_EOL; \ + break; \ + default: \ + unexpected("BlackTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + } \ + EOL:; \ + } while (0) + +#define CHECK_b1 \ + do { \ + if (pa != thisrun) \ + while (b1 <= a0 && b1 < lastx) { \ + b1 += pb[0] + pb[1]; \ + pb += 2; \ + } \ + } while (0) + +#define expand2d(eolab) \ + do { \ + while (a0 < lastx) { \ + LOOKUP(7, MainTable); \ + switch (TabEnt->State) { \ + case S_Pass: \ + CHECK_b1; \ + b1 += *pb++; \ + RunLength += b1 - a0; \ + a0 = b1; \ + b1 += *pb++; \ + break; \ + case S_Horiz: \ + if ((pa - run0) & 1) { \ + int done = 0; \ + while (!done) { /* black first */ \ + LOOKUP(13, BlackTable); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + done = 0; \ + while (!done) { /* then white */ \ + LOOKUP(12, WhiteTable); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + } else { \ + int done = 0; \ + while (!done) { /* white first */ \ + LOOKUP(12, WhiteTable); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + done = 0; \ + while (!done) { /* then black */ \ + LOOKUP(13, BlackTable); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + done = 1; \ + break; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + } \ + CHECK_b1; \ + break; \ + case S_V0: \ + CHECK_b1; \ + SETVAL(b1 - a0); \ + b1 += *pb++; \ + break; \ + case S_VR: \ + CHECK_b1; \ + SETVAL(b1 - a0 + TabEnt->Param); \ + b1 += *pb++; \ + break; \ + case S_VL: \ + CHECK_b1; \ + SETVAL(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ + case S_Ext: \ + *pa++ = lastx - a0; \ + if (verbose) \ + qCDebug(FAX_LOG) << "Line " << LineNum << ": extension code\n"; \ + SKIP_EOL; \ + break; \ + case S_EOL: \ + *pa++ = lastx - a0; \ + NeedBits(4); \ + if (GetBits(4) && verbose) /* already seen 7 zeros */ \ + qCDebug(FAX_LOG) << "Line " << LineNum << ": Bad EOL\n"; \ + ClrBits(4); \ + EOLcnt = 1; \ + goto eolab; \ + break; \ + default: \ + unexpected("MainTable", LineNum); \ + SKIP_EOL; \ + break; \ + } \ + } \ + if (RunLength) { \ + if (RunLength + a0 < lastx) { \ + /* expect a final V0 */ \ + NeedBits(1); \ + if (!GetBits(1)) { \ + unexpected("MainTable", LineNum); \ + SKIP_EOL; \ + } \ + ClrBits(1); \ + } \ + SETVAL(0); \ + } \ + eol2lab; \ + } while (0) + +static void unexpected(const char *what, int LineNum) +{ + if (verbose) + qCCritical(FAX_LOG) << "Line " << LineNum << ": Unexpected state in " << what << endl; +} + +/* Expand tiff modified huffman data (g3-1d without EOLs) */ +void MHexpand(pagenode *pn, drawfunc df) +{ + int a0; /* reference element */ + int lastx; /* copy line width to register */ + t32bits BitAcc; /* bit accumulator */ + int BitsAvail; /* # valid bits in BitAcc */ + int RunLength; /* Length of current run */ + t16bits *sp; /* pointer into compressed data */ + pixnum *pa; /* pointer into new line */ + int EOLcnt; /* number of consecutive EOLs */ + int LineNum; /* line number */ + pixnum *runs; /* list of run lengths */ + struct tabent *TabEnt; + + sp = pn->data; + BitAcc = 0; + BitsAvail = 0; + lastx = pn->size.width(); + runs = (pixnum *)malloc(lastx * sizeof(pixnum)); + for (LineNum = 0; LineNum < pn->rowsperstrip;) { +#ifdef DEBUG_FAX + printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", LineNum); + fflush(stdout); +#endif + RunLength = 0; + pa = runs; + a0 = 0; + EOLcnt = 0; + if (BitsAvail & 7) /* skip to byte boundary */ + ClrBits(BitsAvail & 7); + expand1d(); + if (RunLength) + SETVAL(0); + if (a0 != lastx) { + if (verbose) + qCWarning(FAX_LOG) << "Line " << LineNum << ": length is " << a0 << " (expected " << lastx << ")\n"; + while (a0 > lastx) + a0 -= *--pa; + if (a0 < lastx) { + if ((pa - runs) & 1) + SETVAL(0); + SETVAL(lastx - a0); + } + } + (*df)(runs, LineNum++, pn); + } + free(runs); + (void)EOLcnt; // make gcc happy +} + +/* Expand group-3 1-dimensional data */ +void g31expand(pagenode *pn, drawfunc df) +{ + int a0; /* reference element */ + int lastx; /* copy line width to register */ + t32bits BitAcc; /* bit accumulator */ + int BitsAvail; /* # valid bits in BitAcc */ + int RunLength; /* Length of current run */ + t16bits *sp; /* pointer into compressed data */ + pixnum *pa; /* pointer into new line */ + int EOLcnt; /* number of consecutive EOLs */ + int LineNum; /* line number */ + pixnum *runs; /* list of run lengths */ + struct tabent *TabEnt; + + sp = pn->data; + BitAcc = 0; + BitsAvail = 0; + lastx = pn->size.width(); + runs = (pixnum *)malloc(lastx * sizeof(pixnum)); + EOLcnt = 0; + for (LineNum = 0; LineNum < pn->rowsperstrip;) { +#ifdef DEBUG_FAX + fprintf(stderr, "\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); + fprintf(stderr, "-------------------- %d\n", LineNum); + fflush(stderr); +#endif + if (EOLcnt == 0) + while (!EndOfData(pn)) { + /* skip over garbage after a coding error */ + NeedBits(11); + if (GetBits(11) == 0) + break; + ClrBits(1); + } + for (EOLcnt = 1; !EndOfData(pn); EOLcnt++) { + /* we have seen 11 zeros, which implies EOL, + skip possible fill bits too */ + while (true) { + NeedBits(8); + if (GetBits(8)) + break; + ClrBits(8); + } + while (GetBits(1) == 0) + ClrBits(1); + ClrBits(1); /* the eol flag */ + NeedBits(11); + if (GetBits(11)) + break; + ClrBits(11); + } + if (EOLcnt > 1 && EOLcnt != 6 && verbose) { + qCCritical(FAX_LOG) << "Line " << LineNum << ": bad RTC (" << EOLcnt << " EOLs)\n"; + } + if (EOLcnt >= 6 || EndOfData(pn)) { + free(runs); + return; + } + RunLength = 0; + pa = runs; + a0 = 0; + EOLcnt = 0; + expand1d(); + if (RunLength) + SETVAL(0); + if (a0 != lastx) { + if (verbose) + qCWarning(FAX_LOG) << "Line " << LineNum << ": length is " << a0 << " (expected " << lastx << ")\n"; + while (a0 > lastx) + a0 -= *--pa; + if (a0 < lastx) { + if ((pa - runs) & 1) + SETVAL(0); + SETVAL(lastx - a0); + } + } + (*df)(runs, LineNum++, pn); + } + free(runs); +} + +/* Expand group-3 2-dimensional data */ +void g32expand(pagenode *pn, drawfunc df) +{ + int RunLength; /* Length of current run */ + int a0; /* reference element */ + int b1; /* next change on previous line */ + int lastx = pn->size.width(); /* copy line width to register */ + pixnum *run0, *run1; /* run length arrays */ + pixnum *thisrun, *pa, *pb; /* pointers into runs */ + t16bits *sp; /* pointer into compressed data */ + t32bits BitAcc; /* bit accumulator */ + int BitsAvail; /* # valid bits in BitAcc */ + int EOLcnt; /* number of consecutive EOLs */ + int refline = 0; /* 1D encoded reference line */ + int LineNum; /* line number */ + struct tabent *TabEnt; + + sp = pn->data; + BitAcc = 0; + BitsAvail = 0; + /* allocate space for 2 runlength arrays */ + run0 = (pixnum *)malloc(2 * ((lastx + 5) & ~1) * sizeof(pixnum)); + run1 = run0 + ((lastx + 5) & ~1); + run1[0] = lastx; + run1[1] = 0; + EOLcnt = 0; + for (LineNum = 0; LineNum < pn->rowsperstrip;) { +#ifdef DEBUG_FAX + printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", LineNum); + fflush(stdout); +#endif + if (EOLcnt == 0) + while (!EndOfData(pn)) { + /* skip over garbage after a coding error */ + NeedBits(11); + if (GetBits(11) == 0) + break; + ClrBits(1); + } + for (EOLcnt = 1; !EndOfData(pn); EOLcnt++) { + /* we have seen 11 zeros, which implies EOL, + skip possible fill bits too */ + while (true) { + NeedBits(8); + if (GetBits(8)) + break; + ClrBits(8); + } + while (GetBits(1) == 0) + ClrBits(1); + ClrBits(1); /* the eol flag */ + NeedBits(12); + refline = GetBits(1); /* 1D / 2D flag */ + ClrBits(1); + if (GetBits(11)) + break; + ClrBits(11); + } + if (EOLcnt > 1 && EOLcnt != 6 && verbose) + qCCritical(FAX_LOG) << "Line " << LineNum << ": bad RTC (" << EOLcnt << " EOLs)\n"; + if (EOLcnt >= 6 || EndOfData(pn)) { + free(run0); + return; + } + if (LineNum == 0 && refline == 0 && verbose) + qCDebug(FAX_LOG) << "First line is 2-D encoded\n"; + RunLength = 0; + if (LineNum & 1) { + pa = run1; + pb = run0; + } else { + pa = run0; + pb = run1; + } + thisrun = pa; + EOLcnt = 0; + a0 = 0; + b1 = *pb++; + + if (refline) { + expand1d(); + } else { + expand2d(EOL2); + } + if (RunLength) + SETVAL(0); + if (a0 != lastx) { + if (verbose) + qCWarning(FAX_LOG) << "Line " << LineNum << ": length is " << a0 << " (expected " << lastx << ")\n"; + while (a0 > lastx) + a0 -= *--pa; + if (a0 < lastx) { + if ((pa - run0) & 1) + SETVAL(0); + SETVAL(lastx - a0); + } + } + SETVAL(0); /* imaginary change at end of line for reference */ + (*df)(thisrun, LineNum++, pn); + } + free(run0); +} + +/* Redefine the "skip to eol" macro. We cannot recover from coding + errors in G4 data */ +#undef SKIP_EOL +#undef eol2lab +#define SKIP_EOL \ + do { \ + if (verbose) \ + qCCritical(FAX_LOG) << "Line " << LineNum << ": G4 coding error\n"; \ + free(run0); \ + return; \ + } while (0) +#define eol2lab + +/* Expand group-4 data */ +void g4expand(pagenode *pn, drawfunc df) +{ + int RunLength; /* Length of current run */ + int a0; /* reference element */ + int b1; /* next change on previous line */ + int lastx = pn->size.width(); /* copy line width to register */ + pixnum *run0, *run1; /* run length arrays */ + pixnum *thisrun, *pa, *pb; /* pointers into runs */ + t16bits *sp; /* pointer into compressed data */ + t32bits BitAcc; /* bit accumulator */ + int BitsAvail; /* # valid bits in BitAcc */ + int LineNum; /* line number */ + int EOLcnt; + struct tabent *TabEnt; + + sp = pn->data; + BitAcc = 0; + BitsAvail = 0; + /* allocate space for 2 runlength arrays */ + run0 = (pixnum *)malloc(2 * ((lastx + 5) & ~1) * sizeof(pixnum)); + run1 = run0 + ((lastx + 5) & ~1); + run1[0] = lastx; /* initial reference line */ + run1[1] = 0; + + for (LineNum = 0; LineNum < pn->rowsperstrip;) { +#ifdef DEBUG_FAX + printf("\nBitAcc=%08lX, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", LineNum); + fflush(stdout); +#endif + RunLength = 0; + if (LineNum & 1) { + pa = run1; + pb = run0; + } else { + pa = run0; + pb = run1; + } + thisrun = pa; + a0 = 0; + b1 = *pb++; + expand2d(EOFB); + if (a0 < lastx) { + if ((pa - run0) & 1) + SETVAL(0); + SETVAL(lastx - a0); + } + SETVAL(0); /* imaginary change at end of line for reference */ + (*df)(thisrun, LineNum++, pn); + continue; + EOFB: + NeedBits(13); + if (GetBits(13) != 0x1001 && verbose) + qCCritical(FAX_LOG) << "Bad RTC\n"; + break; + } + free(run0); + (void)EOLcnt; // make gcc happy +} + +static const unsigned char zerotab[256] = {0x88, 0x07, 0x16, 0x06, 0x25, 0x05, 0x15, 0x05, 0x34, 0x04, 0x14, 0x04, 0x24, 0x04, 0x14, 0x04, 0x43, 0x03, 0x13, 0x03, 0x23, 0x03, 0x13, 0x03, 0x33, 0x03, 0x13, 0x03, 0x23, 0x03, 0x13, 0x03, + 0x52, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x32, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x42, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, 0x32, 0x02, 0x12, 0x02, 0x22, 0x02, 0x12, 0x02, + 0x61, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x41, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, + 0x51, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x41, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, 0x31, 0x01, 0x11, 0x01, 0x21, 0x01, 0x11, 0x01, + 0x70, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, + 0x50, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, + 0x60, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, + 0x50, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x40, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x30, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00}; + +#define check(v) \ + do { \ + prezeros = zerotab[v]; \ + postzeros = prezeros & 15; \ + prezeros >>= 4; \ + if (prezeros == 8) { \ + zeros += 8; \ + break; \ + } \ + if (zeros + prezeros < 11) { \ + empty = 0; \ + zeros = postzeros; \ + break; \ + } \ + zeros = postzeros; \ + if (empty) \ + EOLcnt++; \ + lines++; \ + empty = 1; \ + } while (false) + +/* count fax lines */ +int G3count(pagenode *pn, int twoD) +{ + t16bits *p = pn->data; + t16bits *end = p + pn->length / sizeof(*p); + int lines = 0; /* lines seen so far */ + int zeros = 0; /* number of consecutive zero bits seen */ + int EOLcnt = 0; /* number of consecutive EOLs seen */ + int empty = 1; /* empty line */ + int prezeros, postzeros; + + while (p < end && EOLcnt < 6) { + t16bits bits = *p++; + check(bits & 255); + if (twoD && (prezeros + postzeros == 7)) { + if (postzeros || ((bits & 0x100) == 0)) + zeros--; + } + check(bits >> 8); + if (twoD && (prezeros + postzeros == 7)) { + if (postzeros || ((p < end) && ((*p & 1) == 0))) + zeros--; + } + } + return lines - EOLcnt; /* don't count trailing EOLs */ +} diff --git a/generators/fax/faxexpand.h b/generators/fax/faxexpand.h new file mode 100644 index 0000000..1c58bf4 --- /dev/null +++ b/generators/fax/faxexpand.h @@ -0,0 +1,124 @@ +/* Include file for fax routines + Copyright (C) 1990, 1995 Frank D. Cringle. + Copyright (C) 2005 Helge Deller + +This file is part of viewfax - g3/g4 fax processing software. + +viewfax 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. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _faxexpand_h_ +#define _faxexpand_h_ + +#include + +#include +#ifndef Q_OS_WIN +#include +#endif + +#define t32bits quint32 +#define t16bits quint16 + +typedef t16bits pixnum; + +class pagenode; + +/* drawfunc() points to a function which processes a line of the + expanded image described as a list of run lengths. + run is the base of an array of lengths, starting with a + (possibly empty) white run for line number linenum. + pn points to the page descriptor */ +typedef void (*drawfunc)(pixnum *run, int linenum, class pagenode *pn); + +struct strip { /* tiff strip descriptor */ + off_t offset; /* offset in file */ + off_t size; /* size of this strip */ +}; + +/* defines for the pagenode member: type */ +#define FAX_TIFF 1 +#define FAX_RAW 2 + +class pagenode +{ /* compressed page descriptor */ +public: + pagenode(); + ~pagenode() + { + } + int nstrips; /* number of strips */ + int rowsperstrip; /* number of rows per strip */ + int stripnum; /* current strip while expanding */ + struct strip *strips; /* array of strips containing fax data in file */ + t16bits *data; /* in-memory copy of strip */ + t16bits *dataOrig; /* copy of `data', in case we shift it */ + size_t length; /* length of data */ + QSize size; /* width & height of page in pixels */ + int inverse; /* black <=> white */ + int lsbfirst; /* bit order is lsb first */ + int orient; /* orientation - upsidedown, landscape, mirrored */ + int vres; /* vertical resolution: 1 = fine */ + QPoint dpi; /* DPI horz/vert */ + void (*expander)(class pagenode *, drawfunc); + unsigned int bytes_per_line; + QString filename; /* The name of the file to be opened */ + QImage image; /* The final image */ + uchar *imageData; /* The temporary raw image data */ +}; + +/* page orientation flags */ +#define TURN_NONE 0 +#define TURN_U 1 +#define TURN_L 2 +#define TURN_M 4 + +/* fsm state codes */ +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 + +/* state table entry */ +struct tabent { + unsigned char State; + unsigned char Width; /* width of code in bits */ + pixnum Param; /* run length */ +}; + +extern struct tabent MainTable[]; /* 2-D state table */ +extern struct tabent WhiteTable[]; /* White run lengths */ +extern struct tabent BlackTable[]; /* Black run lengths */ + +void MHexpand(class pagenode *pn, drawfunc df); +void g31expand(class pagenode *pn, drawfunc df); +void g32expand(class pagenode *pn, drawfunc df); +void g4expand(class pagenode *pn, drawfunc df); + +/* initialise code tables */ +extern void fax_init_tables(); + +/* count lines in image */ +extern int G3count(class pagenode *pn, int twoD); + +#endif diff --git a/generators/fax/faxinit.cpp b/generators/fax/faxinit.cpp new file mode 100644 index 0000000..008b9c5 --- /dev/null +++ b/generators/fax/faxinit.cpp @@ -0,0 +1,118 @@ +/* Initialise fax decoder tables + Copyright (C) 1990, 1995 Frank D. Cringle. + +This file is part of viewfax - g3/g4 fax processing software. + +viewfax 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. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "faxexpand.h" +#include + +struct tabent MainTable[128]; +struct tabent WhiteTable[4096]; +struct tabent BlackTable[8192]; + +struct proto { + t16bits code; /* right justified, lsb-first, zero filled */ + t16bits val; /* (pixel count)<<4 + code width */ +}; + +static const struct proto Pass[] = {{0x0008, 4}, {0, 0}}; + +static const struct proto Horiz[] = {{0x0004, 3}, {0, 0}}; + +static const struct proto V0[] = {{0x0001, 1}, {0, 0}}; + +static const struct proto VR[] = {{0x0006, (1 << 4) + 3}, {0x0030, (2 << 4) + 6}, {0x0060, (3 << 4) + 7}, {0, 0}}; + +static const struct proto VL[] = {{0x0002, (1 << 4) + 3}, {0x0010, (2 << 4) + 6}, {0x0020, (3 << 4) + 7}, {0, 0}}; + +static const struct proto ExtV[] = {{0x0040, 7}, {0, 0}}; + +static const struct proto EOLV[] = {{0x0000, 7}, {0, 0}}; + +static const struct proto MakeUpW[] = {{0x001b, 1029}, {0x0009, 2053}, {0x003a, 3078}, {0x0076, 4103}, {0x006c, 5128}, {0x00ec, 6152}, {0x0026, 7176}, {0x00a6, 8200}, {0x0016, 9224}, {0x00e6, 10248}, + {0x0066, 11273}, {0x0166, 12297}, {0x0096, 13321}, {0x0196, 14345}, {0x0056, 15369}, {0x0156, 16393}, {0x00d6, 17417}, {0x01d6, 18441}, {0x0036, 19465}, {0x0136, 20489}, + {0x00b6, 21513}, {0x01b6, 22537}, {0x0032, 23561}, {0x0132, 24585}, {0x00b2, 25609}, {0x0006, 26630}, {0x01b2, 27657}, {0, 0}}; + +static const struct proto MakeUpB[] = {{0x03c0, 1034}, {0x0130, 2060}, {0x0930, 3084}, {0x0da0, 4108}, {0x0cc0, 5132}, {0x02c0, 6156}, {0x0ac0, 7180}, {0x06c0, 8205}, {0x16c0, 9229}, {0x0a40, 10253}, + {0x1a40, 11277}, {0x0640, 12301}, {0x1640, 13325}, {0x09c0, 14349}, {0x19c0, 15373}, {0x05c0, 16397}, {0x15c0, 17421}, {0x0dc0, 18445}, {0x1dc0, 19469}, {0x0940, 20493}, + {0x1940, 21517}, {0x0540, 22541}, {0x1540, 23565}, {0x0b40, 24589}, {0x1b40, 25613}, {0x04c0, 26637}, {0x14c0, 27661}, {0, 0}}; + +static const struct proto MakeUp[] = + {{0x0080, 28683}, {0x0180, 29707}, {0x0580, 30731}, {0x0480, 31756}, {0x0c80, 32780}, {0x0280, 33804}, {0x0a80, 34828}, {0x0680, 35852}, {0x0e80, 36876}, {0x0380, 37900}, {0x0b80, 38924}, {0x0780, 39948}, {0x0f80, 40972}, {0, 0}}; + +static const struct proto TermW[] = {{0x00ac, 8}, {0x0038, 22}, {0x000e, 36}, {0x0001, 52}, {0x000d, 68}, {0x0003, 84}, {0x0007, 100}, {0x000f, 116}, {0x0019, 133}, {0x0005, 149}, {0x001c, 165}, {0x0002, 181}, {0x0004, 198}, + {0x0030, 214}, {0x000b, 230}, {0x002b, 246}, {0x0015, 262}, {0x0035, 278}, {0x0072, 295}, {0x0018, 311}, {0x0008, 327}, {0x0074, 343}, {0x0060, 359}, {0x0010, 375}, {0x000a, 391}, {0x006a, 407}, + {0x0064, 423}, {0x0012, 439}, {0x000c, 455}, {0x0040, 472}, {0x00c0, 488}, {0x0058, 504}, {0x00d8, 520}, {0x0048, 536}, {0x00c8, 552}, {0x0028, 568}, {0x00a8, 584}, {0x0068, 600}, {0x00e8, 616}, + {0x0014, 632}, {0x0094, 648}, {0x0054, 664}, {0x00d4, 680}, {0x0034, 696}, {0x00b4, 712}, {0x0020, 728}, {0x00a0, 744}, {0x0050, 760}, {0x00d0, 776}, {0x004a, 792}, {0x00ca, 808}, {0x002a, 824}, + {0x00aa, 840}, {0x0024, 856}, {0x00a4, 872}, {0x001a, 888}, {0x009a, 904}, {0x005a, 920}, {0x00da, 936}, {0x0052, 952}, {0x00d2, 968}, {0x004c, 984}, {0x00cc, 1000}, {0x002c, 1016}, {0, 0}}; + +static const struct proto TermB[] = {{0x03b0, 10}, {0x0002, 19}, {0x0003, 34}, {0x0001, 50}, {0x0006, 67}, {0x000c, 84}, {0x0004, 100}, {0x0018, 117}, {0x0028, 134}, {0x0008, 150}, {0x0010, 167}, {0x0050, 183}, {0x0070, 199}, + {0x0020, 216}, {0x00e0, 232}, {0x0030, 249}, {0x03a0, 266}, {0x0060, 282}, {0x0040, 298}, {0x0730, 315}, {0x00b0, 331}, {0x01b0, 347}, {0x0760, 363}, {0x00a0, 379}, {0x0740, 395}, {0x00c0, 411}, + {0x0530, 428}, {0x0d30, 444}, {0x0330, 460}, {0x0b30, 476}, {0x0160, 492}, {0x0960, 508}, {0x0560, 524}, {0x0d60, 540}, {0x04b0, 556}, {0x0cb0, 572}, {0x02b0, 588}, {0x0ab0, 604}, {0x06b0, 620}, + {0x0eb0, 636}, {0x0360, 652}, {0x0b60, 668}, {0x05b0, 684}, {0x0db0, 700}, {0x02a0, 716}, {0x0aa0, 732}, {0x06a0, 748}, {0x0ea0, 764}, {0x0260, 780}, {0x0a60, 796}, {0x04a0, 812}, {0x0ca0, 828}, + {0x0240, 844}, {0x0ec0, 860}, {0x01c0, 876}, {0x0e40, 892}, {0x0140, 908}, {0x01a0, 924}, {0x09a0, 940}, {0x0d40, 956}, {0x0340, 972}, {0x05a0, 988}, {0x0660, 1004}, {0x0e60, 1020}, {0, 0}}; + +static const struct proto ExtH[] = {{0x0100, 9}, {0, 0}}; + +static const struct proto EOLH[] = {{0x0000, 11}, {0, 0}}; + +static void FillTable(struct tabent *T, int Size, const struct proto *P, int State) +{ + int limit = 1 << Size; + + while (P->val) { + int width = P->val & 15; + int param = P->val >> 4; + int incr = 1 << width; + int code; + for (code = P->code; code < limit; code += incr) { + struct tabent *E = T + code; + E->State = State; + E->Width = width; + E->Param = param; + } + P++; + } +} + +/* initialise the huffman code tables */ +void fax_init_tables() +{ + static bool already_initialized = false; + if (already_initialized) { + return; + } + already_initialized = true; + + FillTable(MainTable, 7, Pass, S_Pass); + FillTable(MainTable, 7, Horiz, S_Horiz); + FillTable(MainTable, 7, V0, S_V0); + FillTable(MainTable, 7, VR, S_VR); + FillTable(MainTable, 7, VL, S_VL); + FillTable(MainTable, 7, ExtV, S_Ext); + FillTable(MainTable, 7, EOLV, S_EOL); + FillTable(WhiteTable, 12, MakeUpW, S_MakeUpW); + FillTable(WhiteTable, 12, MakeUp, S_MakeUp); + FillTable(WhiteTable, 12, TermW, S_TermW); + FillTable(WhiteTable, 12, ExtH, S_Ext); + FillTable(WhiteTable, 12, EOLH, S_EOL); + FillTable(BlackTable, 13, MakeUpB, S_MakeUpB); + FillTable(BlackTable, 13, MakeUp, S_MakeUp); + FillTable(BlackTable, 13, TermB, S_TermB); + FillTable(BlackTable, 13, ExtH, S_Ext); + FillTable(BlackTable, 13, EOLH, S_EOL); +} diff --git a/generators/fax/generator_fax.cpp b/generators/fax/generator_fax.cpp new file mode 100644 index 0000000..69848d1 --- /dev/null +++ b/generators/fax/generator_fax.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "generator_fax.h" + +#include +#include + +#include +#include + +#include +#include + +OKULAR_EXPORT_PLUGIN(FaxGenerator, "libokularGenerator_fax.json") + +FaxGenerator::FaxGenerator(QObject *parent, const QVariantList &args) + : Generator(parent, args) +{ + setFeature(Threaded); + setFeature(PrintNative); + setFeature(PrintToFile); +} + +FaxGenerator::~FaxGenerator() +{ +} + +bool FaxGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + if (fileName.endsWith(QLatin1String(".g3"), Qt::CaseInsensitive)) + m_type = FaxDocument::G3; + else + m_type = FaxDocument::G4; + + FaxDocument faxDocument(fileName, m_type); + + if (!faxDocument.load()) { + emit error(i18n("Unable to load document"), -1); + return false; + } + + m_img = faxDocument.image(); + + pagesVector.resize(1); + + Okular::Page *page = new Okular::Page(0, m_img.width(), m_img.height(), Okular::Rotation0); + pagesVector[0] = page; + + return true; +} + +bool FaxGenerator::doCloseDocument() +{ + m_img = QImage(); + + return true; +} + +QImage FaxGenerator::image(Okular::PixmapRequest *request) +{ + // perform a smooth scaled generation + int width = request->width(); + int height = request->height(); + if (request->page()->rotation() % 2 == 1) + qSwap(width, height); + + return m_img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); +} + +Okular::DocumentInfo FaxGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + if (keys.contains(Okular::DocumentInfo::MimeType)) { + if (m_type == FaxDocument::G3) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("image/fax-g3")); + else + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("image/fax-g4")); + } + return docInfo; +} + +bool FaxGenerator::print(QPrinter &printer) +{ + QPainter p(&printer); + + QImage image(m_img); + + if ((image.width() > printer.width()) || (image.height() > printer.height())) + + image = image.scaled(printer.width(), printer.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + + p.drawImage(0, 0, image); + + return true; +} + +#include "generator_fax.moc" diff --git a/generators/fax/generator_fax.h b/generators/fax/generator_fax.h new file mode 100644 index 0000000..d1f3eee --- /dev/null +++ b/generators/fax/generator_fax.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2008 by Tobias Koenig * + * * + * 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_GENERATOR_FAX_H +#define OKULAR_GENERATOR_FAX_H + +#include + +#include + +#include "faxdocument.h" + +class FaxGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + FaxGenerator(QObject *parent, const QVariantList &args); + ~FaxGenerator() override; + + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + + bool print(QPrinter &printer) override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + +private: + QImage m_img; + FaxDocument::DocumentType m_type; +}; + +#endif diff --git a/generators/fax/libokularGenerator_fax.json b/generators/fax/libokularGenerator_fax.json new file mode 100644 index 0000000..41e0d8c --- /dev/null +++ b/generators/fax/libokularGenerator_fax.json @@ -0,0 +1,170 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "tokoe@kde.org", + "Name": "Tobias Koenig", + "Name[az]": "Tobias Koenig", + "Name[ca@valencia]": "Tobias Koenig", + "Name[ca]": "Tobias Koenig", + "Name[cs]": "Tobias Koenig", + "Name[da]": "Tobias Koenig", + "Name[de]": "Tobias Koenig", + "Name[el]": "Tobias Koenig", + "Name[en_GB]": "Tobias Koenig", + "Name[es]": "Tobias Koenig", + "Name[et]": "Tobias Koenig", + "Name[eu]": "Tobias Koenig", + "Name[fi]": "Tobias Koenig", + "Name[fr]": "Tobias Koenig", + "Name[gl]": "Tobias Koenig", + "Name[ia]": "Tobias Koenig", + "Name[it]": "Tobias Koenig", + "Name[ko]": "Tobias Koenig", + "Name[lt]": "Tobias Koenig", + "Name[nl]": "Tobias Koenig", + "Name[nn]": "Tobias König", + "Name[pl]": "Tobias Koenig", + "Name[pt]": "Tobias Koenig", + "Name[pt_BR]": "Tobias Koenig", + "Name[ru]": "Tobias König", + "Name[sk]": "Tobias Koenig", + "Name[sl]": "Tobias Koenig", + "Name[sr@ijekavian]": "Тобијас Кениг", + "Name[sr@ijekavianlatin]": "Tobijas Kenig", + "Name[sr@latin]": "Tobijas Kenig", + "Name[sr]": "Тобијас Кениг", + "Name[sv]": "Tobias Koenig", + "Name[tr]": "Tobias Koenig", + "Name[uk]": "Tobias Koenig", + "Name[x-test]": "xxTobias Koenigxx", + "Name[zh_CN]": "Tobias Koenig", + "Name[zh_TW]": "Tobias Koenig" + } + ], + "Copyright": "© 2008 Tobias Koenig", + "Copyright[az]": "© 2008 Tobias Koenig", + "Copyright[ca@valencia]": "© 2008 Tobias Koenig", + "Copyright[ca]": "© 2008 Tobias Koenig", + "Copyright[cs]": "© 2008 Tobias Koenig", + "Copyright[da]": "© 2008 Tobias Koenig", + "Copyright[de]": "© 2008 Tobias Koenig", + "Copyright[el]": "© 2008 Tobias Koenig", + "Copyright[en_GB]": "© 2008 Tobias Koenig", + "Copyright[es]": "© 2008 Tobias Koenig", + "Copyright[et]": "© 2008: Tobias Koenig", + "Copyright[eu]": "© 2008 Tobias Koenig", + "Copyright[fi]": "© 2008 Tobias Koenig", + "Copyright[fr]": "© 2008 Tobias Koenig", + "Copyright[gl]": "© 2008 Tobias Koenig", + "Copyright[ia]": "© 2008 Tobias Koenig", + "Copyright[it]": "© 2008 Tobias Koenig", + "Copyright[ko]": "© 2008 Tobias Koenig", + "Copyright[lt]": "© 2008 Tobias Koenig", + "Copyright[nl]": "© 2008 Tobias Koenig", + "Copyright[nn]": "© 2008 Tobias König", + "Copyright[pl]": "© 2008 Tobias Koenig", + "Copyright[pt]": "© 2008 Tobias Koenig", + "Copyright[pt_BR]": "© 2008 Tobias Koenig", + "Copyright[ru]": "© Tobias König, 2008", + "Copyright[sk]": "© 2008 Tobias Koenig", + "Copyright[sl]": "© 2008 Tobias Koenig", + "Copyright[sr@ijekavian]": "© 2008, Тобијас Кениг", + "Copyright[sr@ijekavianlatin]": "© 2008, Tobijas Kenig", + "Copyright[sr@latin]": "© 2008, Tobijas Kenig", + "Copyright[sr]": "© 2008, Тобијас Кениг", + "Copyright[sv]": "© 2008 Tobias Koenig", + "Copyright[tr]": "© 2008 Tobias Koenig", + "Copyright[uk]": "© Tobias Koenig, 2008", + "Copyright[x-test]": "xx© 2008 Tobias Koenigxx", + "Copyright[zh_CN]": "© 2008 Tobias Koenig", + "Copyright[zh_TW]": "© 2008 Tobias Koenig", + "Description": "A G3/G4 fax document backend", + "Description[az]": "A G3/G4 fax sənədi modulu", + "Description[ca@valencia]": "Un dorsal per a documents de fax G3/G4", + "Description[ca]": "Un dorsal per a documents de fax G3/G4", + "Description[cs]": "Implementace dokumentu faxu A G3/G4", + "Description[da]": "En G3/G4 faxdokument-backend", + "Description[de]": "Ein Anzeigemodul für G3/G4-Faxe", + "Description[el]": "Σύστημα υποστήριξης για έγγραφα τηλεμοιοτυπίας G3/G4", + "Description[en_GB]": "A G3/G4 fax document backend", + "Description[es]": "Un motor para documentos de fax G3/G4", + "Description[et]": "G3/G4 faksidokumendi taustaprogramm", + "Description[eu]": "G3/G4 fax dokumentuen bizkarraldekoa", + "Description[fi]": "G3/G4-faksitiedostotaustaosa", + "Description[fr]": "Un moteur de document fax G3/G4", + "Description[gl]": "Unha infraestrutura de documentos de fax G3/G4", + "Description[ia]": "UN retro-administration de documento fax G3/G4", + "Description[it]": "Un backend per documenti fax G3/G4", + "Description[ko]": "G3/G4 팩스 문서 백엔드", + "Description[lt]": "G3/G4 fakso dokumentų programinė sąsaja", + "Description[nl]": "Een backend voor een G3/G4 faxdocument", + "Description[nn]": "Ein motor for G3/G4-faksdokument", + "Description[pl]": "Obsługa dokumentów wysłanych faksem G3/G4", + "Description[pt]": "Uma infra-estrutura de documentos de fax G3/G4", + "Description[pt_BR]": "Uma infraestrutura para documentos de fax G3/G4", + "Description[ru]": "Модуль поддержки формата факсов G3/G4", + "Description[sk]": "Backend dokumentu faxu G3/G4", + "Description[sl]": "Zaledje za dokumente faksov G3/G4", + "Description[sr@ijekavian]": "Позадина за Г3 факс и Г4 факс документе", + "Description[sr@ijekavianlatin]": "Pozadina za G4 Fax i G3 Fax dokumente", + "Description[sr@latin]": "Pozadina za G4 Fax i G3 Fax dokumente", + "Description[sr]": "Позадина за Г3 факс и Г4 факс документе", + "Description[sv]": "Ett G3/G4 telefax-dokumentgränssnitt", + "Description[tr]": "G3/G4 faks belgesi arka ucu", + "Description[uk]": "Сервер документів факсів G3/G4", + "Description[x-test]": "xxA G3/G4 fax document backendxx", + "Description[zh_CN]": "G3/G4 传真文档后端", + "Description[zh_TW]": "G3/G4 fax 文件後端介面", + "Id": "okular_fax", + "License": "GPL", + "MimeTypes": [ + "image/fax-g3", + "image/g3fax" + ], + "Name": "Fax Backend", + "Name[az]": "Fax Backend", + "Name[ca@valencia]": "Dorsal de fax", + "Name[ca]": "Dorsal de fax", + "Name[cs]": "Implementace faxu", + "Name[da]": "Fax-backend", + "Name[de]": "Anzeigemodul für Faxe", + "Name[el]": "Σύστημα υποστήριξης fax", + "Name[en_GB]": "Fax Backend", + "Name[es]": "Motor para fax", + "Name[et]": "Faksi taustaprogramm", + "Name[eu]": "Fax-aren bizkarraldekoa", + "Name[fi]": "Faksitaustaosa", + "Name[fr]": "Moteur Fax", + "Name[gl]": "Infraestrutura de fax", + "Name[ia]": "Retro-Administration de fax", + "Name[it]": "Backend fax", + "Name[ko]": "팩스 백엔드", + "Name[lt]": "Fakso programinė sąsaja", + "Name[nl]": "Faxbackend", + "Name[nn]": "Faksmotor", + "Name[pl]": "Obsługa faksu", + "Name[pt]": "Fax Backend", + "Name[pt_BR]": "Infraestrutura de fax", + "Name[ru]": "Модуль поддержки форматов факсов", + "Name[sk]": "Fax Backend", + "Name[sl]": "Zaledje za faks", + "Name[sr@ijekavian]": "Позадина за факсове", + "Name[sr@ijekavianlatin]": "Pozadina za faksove", + "Name[sr@latin]": "Pozadina za faksove", + "Name[sr]": "Позадина за факсове", + "Name[sv]": "Telefax-gränssnitt", + "Name[tr]": "Faks Arka Ucu", + "Name[uk]": "Модуль факсів", + "Name[x-test]": "xxFax Backendxx", + "Name[zh_CN]": "传真后端", + "Name[zh_TW]": "Fax 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.1" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/fax/okularApplication_fax.desktop b/generators/fax/okularApplication_fax.desktop new file mode 100755 index 0000000..a966af4 --- /dev/null +++ b/generators/fax/okularApplication_fax.desktop @@ -0,0 +1,172 @@ +[Desktop Entry] +MimeType=image/fax-g3;image/g3fax; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=1 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true diff --git a/generators/fax/okularFax.desktop b/generators/fax/okularFax.desktop new file mode 100644 index 0000000..72b26f9 --- /dev/null +++ b/generators/fax/okularFax.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=image/fax-g3;image/g3fax; diff --git a/generators/fax/org.kde.mobile.okular_fax.desktop b/generators/fax/org.kde.mobile.okular_fax.desktop new file mode 100644 index 0000000..84ed642 --- /dev/null +++ b/generators/fax/org.kde.mobile.okular_fax.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +MimeType=image/fax-g3;image/g3fax; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true diff --git a/generators/fax/org.kde.okular-fax.metainfo.xml b/generators/fax/org.kde.okular-fax.metainfo.xml new file mode 100644 index 0000000..affcbe2 --- /dev/null +++ b/generators/fax/org.kde.okular-fax.metainfo.xml @@ -0,0 +1,92 @@ + + + org.kde.okular-fax + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Fax + Fax + Fax + Fax + Fax + Fax + Fax + Fax + Fax + Faks + Fax + Faksi + Fax + Fax + Fax + Fax + 팩스 + Faksas + ഫാക്സ് + Fax + Faks + Faks + Fax + Fax + Факсы + Fax + Faks + Факс + Faks + Факс + Faks + Telefax + Faks + факс + xxFaxxx + 传真 + 傳真 + Adds support for reading Fax documents + Faks sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents de Fax + Afig la implementació per a llegir documents de Fax + Přidává podporu pro čtení dokumentů faxu + Bietet Unterstützung zum Lesen von Fax-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων τηλεμοιοτυπίας + Adds support for reading Fax documents + Permite la lectura de documentos de fax + Faksidokumentide lugemise toetus + Fax dokumentuak irakurtzeko euskarria gehitzen du + Lisää faksitiedostojen lukutuen + Permet la lecture des documents Fax + Engade a posibilidade de ler documentos de fax + Adde supporto per leger documentos Fax + Aggiunge il supporto per la lettura di documenti Fax + 팩스 문서 읽기 지원 추가 + Prideda palaikymą fakso dokumentų skaitymui + ഫാക്സ് പ്രമാണങ്ങൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van faxdocumenten toe + Legg til støtte for Ã¥ lesa faksdokument + Dodaje obsługę czytania faksów + Adiciona o suporte para a leitura de documentos de Fax + Adiciona o suporte para leitura de documentos de fax + Поддержка чтения документов факсов + Pridá podporu pre čítanie faxových dokumentov + Doda podporo za branje faksiranih dokumentov + Подршка за читање факс докумената + PodrÅ¡ka za čitanje faks dokumenata + Подршка за читање факс докумената + PodrÅ¡ka za čitanje faks dokumenata + Lägger till stöd för att läsa telefax-dokument + Faks belgelerini okuma desteği ekler + Додає підтримку читання документів факсів + xxAdds support for reading Fax documentsxx + 增加对传真文档的阅读支持 + 加入讀取傳真文件的支援 + + image/fax-g3 + image/g3fax + + https://okular.kde.org + + + + + + + diff --git a/generators/fictionbook/16-apps-okular-fb2.png b/generators/fictionbook/16-apps-okular-fb2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a72207a179a5e3f23552ce4a134dc36a27eba13 GIT binary patch literal 969 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR^7dDgs7EMrLMaR#sLn zE-qePUNJE-85x=Xq=0{5@b~ZEKY#xG`t|GQ&!6AEef#p|%coDD-oJnU=FOWIVDR|y z<40id01WPd!JRvIZiB&1Ft~pG`ZX}P0tS~ZUAhPc=g*%%3kGMv;MA#8C&A!27#ux% z^avOnI&|nD80-gwy?giW0fSw;cJ1B1^uX51hc`8zT$_4fwcpj{Hn*1Q-e0Wzc%js* z`TTF^aeth{_H_=+_t{LpW-+0&Ns;bJ%%L@w&Gcqy~5)xu! zVj?0U!oVPuW*`I%f`fyDf`S490{s2`eSCbpyu94p++18-?CtGsZEdZrtSl@n%+1Zs z%*;$pO^uC>jljUr(9poZKwn>9S65dD479biwY0P}z(8GHT}@3*1q_sxl@-BY^0$6X zUT&ep({+eWAe5`8lq>?(XdD?BL*FZ*Om9Wo2PuVQOk>Y;0@<28M=)1_lQD`ue)Mx;kK>t*x!4rKJG| z>gwuhYHBKApscK{2nI_UHVXqYfMQ9IUoh^Bz{oCa7*lsOY)VW%P|;#f7srr_TU#gJ z=43YHVF^Asb(3hU=qi=JD>$}J+4^P!OXLsblMStj?Dpq&9WQ;LV`E*X#UQa*)FG*7 zl6QwlmY(8i_q=an1_{1XggG4&7S8ce+#Vk2SHd=RYV)1LD-NBy%jmai!?kjGA@$G= zPuPk%OIZ)7y_Mv7S+d>X(d}rT!;`c1UwE4}-CHF3Wmf2m--?03CQe7zWhytN7Ulf5 d=eYm>uKxaQ@#jmPyZicOA^12i@^HZ?UhH#gsHWoT<_yWh&t(b4g&ivftbySsaPd;9zQKTKel00uzD zT*rZN1V!SHVe!{6x)e`hfKpNWG0&0_dBo8iwKre6!#ek|htwp8fL3aQU))IP2^ zdb`=}%~t=j+xlPaOuoCb?#hnNXS;I#69oVM{{Q>)|IhdTzCQo=@$R43=YKxh_x=8^ zM-T2kxPSM}{nO9xUwQoC*8O{T@7}%h;ojkIceZ`Kv-QiJ9iQ&(zH|H5&6_u_UAuPW z%9V>3FP=Sn=Gd`gM~)mhbm-8*g9i^BIIw^J{(bxQ?b)+u=gytmwr$(IdGo$ab9Zi7 zxPJZmb?eryU%P74x)p2J0KsY?TDxZTx;3lN{ENl~2FvHkjF8}Z*3SYAy`G*PU`Sr> zRn^tiovvg! zTE+lL4?waQ3=R}C6crT}78Vv16y)dU14&@A$;-ZxPq>EyHEao^8L@N`W@`R?8kV< z)5S5Q;?~)#`~43&h_Dwd{~i2Ce1_x?_7%6KFKXqq$j>uWbQ8Z5V`b_poU+N9(|RHw zA1~YM11ijoEiTe(V)EC$mp`<*&J#-c!QT;Bi%O z_BMuM`MLKG1X4N_pgF96gsxQu2*=-da%k=LGkdF1m_JZ4KA}(nN%W#9F)!`9X!It$mye_F-J&2 zkl%pCL&Jg3pps=(`RmfD#o4c}XwNBrF7$ft&wyIHn%dw0Zfv|e^ZoC|^N%LkNv&vn zyJKDV`bG1)U+y~maKZ2A?$;EbZ^<;0Ijw#7;foThF9$a=&Cob-!kRNfp=;d+&NB(D mQg0eWRSb@XFS6ZW` * + * * + * 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. * + ***************************************************************************/ + +#include "converter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "document.h" + +using namespace FictionBook; + +class Converter::TitleInfo +{ +public: + QStringList mGenres; + QString mAuthor; + QString mTitle; + QStringList mKeywords; + QDate mDate; + QDomElement mCoverPage; + QString mLanguage; +}; + +class Converter::DocumentInfo +{ +public: + QString mAuthor; + QString mProducer; + QDate mDate; + QString mId; + QString mVersion; +}; + +Converter::Converter() + : mTextDocument(nullptr) + , mCursor(nullptr) + , mTitleInfo(nullptr) + , mDocumentInfo(nullptr) +{ +} + +Converter::~Converter() +{ + delete mTitleInfo; + delete mDocumentInfo; +} + +QTextDocument *Converter::convert(const QString &fileName) +{ + Document fbDocument(fileName); + if (!fbDocument.open()) { + emit error(fbDocument.lastErrorString(), -1); + return nullptr; + } + + mTextDocument = new QTextDocument; + mCursor = new QTextCursor(mTextDocument); + mSectionCounter = 0; + mLocalLinks.clear(); + mSectionMap.clear(); + + const QDomDocument document = fbDocument.content(); + + /** + * Set the correct page size + */ + mTextDocument->setPageSize(QSizeF(600, 800)); + + QTextFrameFormat frameFormat; + frameFormat.setMargin(20); + + QTextFrame *rootFrame = mTextDocument->rootFrame(); + rootFrame->setFrameFormat(frameFormat); + + /** + * Parse the content of the document + */ + const QDomElement documentElement = document.documentElement(); + + if (documentElement.tagName() != QLatin1String("FictionBook")) { + emit error(i18n("Document is not a valid FictionBook"), -1); + delete mCursor; + return nullptr; + } + + /** + * First we read all images, so we can calculate the size later. + */ + QDomElement element = documentElement.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("binary")) { + if (!convertBinary(element)) { + delete mCursor; + return nullptr; + } + } + + element = element.nextSiblingElement(); + } + + /** + * Read the rest... + */ + element = documentElement.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("description")) { + if (!convertDescription(element)) { + delete mCursor; + return nullptr; + } + } else if (element.tagName() == QLatin1String("body")) { + if (mTitleInfo && !mTitleInfo->mCoverPage.isNull()) { + convertCover(mTitleInfo->mCoverPage); + mCursor->insertBlock(); + } + + QTextFrame *topFrame = mCursor->currentFrame(); + + QTextFrameFormat frameFormat; + frameFormat.setBorder(2); + frameFormat.setPadding(8); + frameFormat.setBackground(Qt::lightGray); + + if (mTitleInfo && !mTitleInfo->mTitle.isEmpty()) { + mCursor->insertFrame(frameFormat); + + QTextCharFormat charFormat; + charFormat.setFontPointSize(22); + charFormat.setFontWeight(QFont::Bold); + mCursor->insertText(mTitleInfo->mTitle, charFormat); + + mCursor->setPosition(topFrame->lastPosition()); + } + + if (mTitleInfo && !mTitleInfo->mAuthor.isEmpty()) { + frameFormat.setBorder(1); + mCursor->insertFrame(frameFormat); + + QTextCharFormat charFormat; + charFormat.setFontPointSize(10); + mCursor->insertText(mTitleInfo->mAuthor, charFormat); + + mCursor->setPosition(topFrame->lastPosition()); + mCursor->insertBlock(); + } + + mCursor->insertBlock(); + + if (!convertBody(element)) { + delete mCursor; + return nullptr; + } + } + + element = element.nextSiblingElement(); + } + + /** + * Add document info. + */ + if (mTitleInfo) { + if (!mTitleInfo->mTitle.isEmpty()) + emit addMetaData(Okular::DocumentInfo::Title, mTitleInfo->mTitle); + + if (!mTitleInfo->mAuthor.isEmpty()) + emit addMetaData(Okular::DocumentInfo::Author, mTitleInfo->mAuthor); + } + + if (mDocumentInfo) { + if (!mDocumentInfo->mProducer.isEmpty()) + emit addMetaData(Okular::DocumentInfo::Producer, mDocumentInfo->mProducer); + + if (mDocumentInfo->mDate.isValid()) + emit addMetaData(Okular::DocumentInfo::CreationDate, QLocale().toString(mDocumentInfo->mDate, QLocale::ShortFormat)); + } + + QMapIterator> it(mLocalLinks); + while (it.hasNext()) { + it.next(); + + const QTextBlock block = mSectionMap[it.key()]; + if (!block.isValid()) // local link without existing target + continue; + + Okular::DocumentViewport viewport = calculateViewport(mTextDocument, block); + + Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); + + emit addAction(action, it.value().first, it.value().second); + } + + delete mCursor; + + return mTextDocument; +} + +bool Converter::convertBody(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("section")) { + mCursor->insertBlock(); + if (!convertSection(child)) + return false; + } else if (child.tagName() == QLatin1String("image")) { + if (!convertImage(child)) + return false; + } else if (child.tagName() == QLatin1String("title")) { + if (!convertTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("epigraph")) { + if (!convertEpigraph(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertDescription(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("title-info")) { + if (!convertTitleInfo(child)) + return false; + } + if (child.tagName() == QLatin1String("document-info")) { + if (!convertDocumentInfo(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertTitleInfo(const QDomElement &element) +{ + delete mTitleInfo; + mTitleInfo = new TitleInfo; + + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("genre")) { + QString genre; + if (!convertTextNode(child, genre)) + return false; + + if (!genre.isEmpty()) + mTitleInfo->mGenres.append(genre); + } else if (child.tagName() == QLatin1String("author")) { + QString firstName, middleName, lastName, dummy; + + if (!convertAuthor(child, firstName, middleName, lastName, dummy, dummy)) + return false; + + mTitleInfo->mAuthor = QStringLiteral("%1 %2 %3").arg(firstName, middleName, lastName); + } else if (child.tagName() == QLatin1String("book-title")) { + if (!convertTextNode(child, mTitleInfo->mTitle)) + return false; + } else if (child.tagName() == QLatin1String("keywords")) { + QString keywords; + if (!convertTextNode(child, keywords)) + return false; + + mTitleInfo->mKeywords = keywords.split(QLatin1Char(' '), QString::SkipEmptyParts); + } else if (child.tagName() == QLatin1String("date")) { + if (!convertDate(child, mTitleInfo->mDate)) + return false; + } else if (child.tagName() == QLatin1String("coverpage")) { + mTitleInfo->mCoverPage = child; + } else if (child.tagName() == QLatin1String("lang")) { + if (!convertTextNode(child, mTitleInfo->mLanguage)) + return false; + } + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertDocumentInfo(const QDomElement &element) +{ + delete mDocumentInfo; + mDocumentInfo = new DocumentInfo; + + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("author")) { + QString firstName, middleName, lastName, email, nickname; + + if (!convertAuthor(child, firstName, middleName, lastName, email, nickname)) + return false; + + mDocumentInfo->mAuthor = QStringLiteral("%1 %2 %3 <%4> (%5)").arg(firstName, middleName, lastName, email, nickname); + } else if (child.tagName() == QLatin1String("program-used")) { + if (!convertTextNode(child, mDocumentInfo->mProducer)) + return false; + } else if (child.tagName() == QLatin1String("date")) { + if (!convertDate(child, mDocumentInfo->mDate)) + return false; + } else if (child.tagName() == QLatin1String("id")) { + if (!convertTextNode(child, mDocumentInfo->mId)) + return false; + } else if (child.tagName() == QLatin1String("version")) { + if (!convertTextNode(child, mDocumentInfo->mVersion)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} +bool Converter::convertAuthor(const QDomElement &element, QString &firstName, QString &middleName, QString &lastName, QString &email, QString &nickname) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("first-name")) { + if (!convertTextNode(child, firstName)) + return false; + } else if (child.tagName() == QLatin1String("middle-name")) { + if (!convertTextNode(child, middleName)) + return false; + } else if (child.tagName() == QLatin1String("last-name")) { + if (!convertTextNode(child, lastName)) + return false; + } else if (child.tagName() == QLatin1String("email")) { + if (!convertTextNode(child, email)) + return false; + } else if (child.tagName() == QLatin1String("nickname")) { + if (!convertTextNode(child, nickname)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertTextNode(const QDomElement &element, QString &data) +{ + QDomNode child = element.firstChild(); + while (!child.isNull()) { + QDomText text = child.toText(); + if (!text.isNull()) + data = text.data(); + + child = child.nextSibling(); + } + + return true; +} + +bool Converter::convertDate(const QDomElement &element, QDate &date) +{ + if (element.hasAttribute(QStringLiteral("value"))) + date = QDate::fromString(element.attribute(QStringLiteral("value")), Qt::ISODate); + + return true; +} + +bool Converter::convertSection(const QDomElement &element) +{ + if (element.hasAttribute(QStringLiteral("id"))) + mSectionMap.insert(element.attribute(QStringLiteral("id")), mCursor->block()); + + mSectionCounter++; + + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("title")) { + if (!convertTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("epigraph")) { + if (!convertEpigraph(child)) + return false; + } else if (child.tagName() == QLatin1String("image")) { + if (!convertImage(child)) + return false; + } else if (child.tagName() == QLatin1String("section")) { + if (!convertSection(child)) + return false; + } else if (child.tagName() == QLatin1String("p")) { + QTextBlockFormat format; + format.setTextIndent(10); + mCursor->insertBlock(format); + if (!convertParagraph(child)) + return false; + } else if (child.tagName() == QLatin1String("poem")) { + if (!convertPoem(child)) + return false; + } else if (child.tagName() == QLatin1String("subtitle")) { + if (!convertSubTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("cite")) { + if (!convertCite(child)) + return false; + } else if (child.tagName() == QLatin1String("empty-line")) { + if (!convertEmptyLine(child)) + return false; + } else if (child.tagName() == QLatin1String("code")) { + if (!convertCode(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + mSectionCounter--; + + return true; +} + +bool Converter::convertTitle(const QDomElement &element) +{ + QTextFrame *topFrame = mCursor->currentFrame(); + + QTextFrameFormat frameFormat; + frameFormat.setBorder(1); + frameFormat.setPadding(8); + frameFormat.setBackground(Qt::lightGray); + + mCursor->insertFrame(frameFormat); + + QDomElement child = element.firstChildElement(); + + bool firstParagraph = true; + while (!child.isNull()) { + if (child.tagName() == QLatin1String("p")) { + if (firstParagraph) + firstParagraph = false; + else + mCursor->insertBlock(); + + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat titleFormat(origFormat); + titleFormat.setFontPointSize(22 - (mSectionCounter * 2)); + titleFormat.setFontWeight(QFont::Bold); + mCursor->setCharFormat(titleFormat); + + if (!convertParagraph(child)) + return false; + + mCursor->setCharFormat(origFormat); + + emit addTitle(mSectionCounter, child.text(), mCursor->block()); + + } else if (child.tagName() == QLatin1String("empty-line")) { + if (!convertEmptyLine(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + mCursor->setPosition(topFrame->lastPosition()); + + return true; +} + +bool Converter::convertParagraph(const QDomElement &element) +{ + QDomNode child = element.firstChild(); + while (!child.isNull()) { + if (child.isElement()) { + const QDomElement childElement = child.toElement(); + if (childElement.tagName() == QLatin1String("emphasis")) { + if (!convertEmphasis(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("strong")) { + if (!convertStrong(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("style")) { + if (!convertStyle(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("a")) { + if (!convertLink(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("image")) { + if (!convertImage(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("strikethrough")) { + if (!convertStrikethrough(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("code")) { + if (!convertCode(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("sup")) { + if (!convertSuperScript(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("sub")) { + if (!convertSubScript(childElement)) + return false; + } + } else if (child.isText()) { + const QDomText childText = child.toText(); + mCursor->insertText(childText.data()); + } + + child = child.nextSibling(); + } + + return true; +} + +bool Converter::convertEmphasis(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat italicFormat(origFormat); + italicFormat.setFontItalic(true); + mCursor->setCharFormat(italicFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} + +bool Converter::convertStrikethrough(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat strikeoutFormat(origFormat); + strikeoutFormat.setFontStrikeOut(true); + mCursor->setCharFormat(strikeoutFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} + +bool Converter::convertStrong(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat boldFormat(origFormat); + boldFormat.setFontWeight(QFont::Bold); + mCursor->setCharFormat(boldFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} + +bool Converter::convertStyle(const QDomElement &element) +{ + if (!convertParagraph(element)) + return false; + + return true; +} + +bool Converter::convertBinary(const QDomElement &element) +{ + const QString id = element.attribute(QStringLiteral("id")); + + const QDomText textNode = element.firstChild().toText(); + QByteArray data = textNode.data().toLatin1(); + data = QByteArray::fromBase64(data); + + mTextDocument->addResource(QTextDocument::ImageResource, QUrl(id), QImage::fromData(data)); + + return true; +} + +bool Converter::convertCover(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("image")) { + if (!convertImage(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertImage(const QDomElement &element) +{ + QString href = element.attributeNS(QStringLiteral("http://www.w3.org/1999/xlink"), QStringLiteral("href")); + + if (href.startsWith(QLatin1Char('#'))) + href = href.mid(1); + + const QImage img = qvariant_cast(mTextDocument->resource(QTextDocument::ImageResource, QUrl(href))); + + QTextImageFormat format; + format.setName(href); + + if (img.width() > 560) + format.setWidth(560); + + format.setHeight(img.height()); + + mCursor->insertImage(format); + + return true; +} + +bool Converter::convertEpigraph(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("p")) { + QTextBlockFormat format; + format.setTextIndent(10); + mCursor->insertBlock(format); + if (!convertParagraph(child)) + return false; + } else if (child.tagName() == QLatin1String("poem")) { + if (!convertPoem(child)) + return false; + } else if (child.tagName() == QLatin1String("cite")) { + if (!convertCite(child)) + return false; + } else if (child.tagName() == QLatin1String("empty-line")) { + if (!convertEmptyLine(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertPoem(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("title")) { + if (!convertTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("epigraph")) { + if (!convertEpigraph(child)) + return false; + } else if (child.tagName() == QLatin1String("empty-line")) { + if (!convertEmptyLine(child)) + return false; + } else if (child.tagName() == QLatin1String("stanza")) { + if (!convertStanza(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertSubTitle(const QDomElement &element) +{ + QTextFrame *topFrame = mCursor->currentFrame(); + + QTextFrameFormat frameFormat; + frameFormat.setBorder(1); + frameFormat.setPadding(8); + frameFormat.setBackground(Qt::lightGray); + frameFormat.setTopMargin(16); + + mCursor->insertFrame(frameFormat); + + if (!convertParagraph(element)) { + return false; + } + + mCursor->setPosition(topFrame->lastPosition()); + + return true; +} + +bool Converter::convertCite(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("p")) { + QTextBlockFormat format; + format.setTextIndent(10); + mCursor->insertBlock(format); + if (!convertParagraph(child)) + return false; + } else if (child.tagName() == QLatin1String("poem")) { + if (!convertParagraph(child)) + return false; + } else if (child.tagName() == QLatin1String("empty-line")) { + if (!convertEmptyLine(child)) + return false; + } else if (child.tagName() == QLatin1String("subtitle")) { + if (!convertSubTitle(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertEmptyLine(const QDomElement &) +{ + mCursor->insertText(QStringLiteral("\n\n")); + return true; +} + +bool Converter::convertLink(const QDomElement &element) +{ + QString href = element.attributeNS(QStringLiteral("http://www.w3.org/1999/xlink"), QStringLiteral("href")); + QString type = element.attributeNS(QStringLiteral("http://www.w3.org/1999/xlink"), QStringLiteral("type")); + + if (type == QLatin1String("note")) + mCursor->insertText(QStringLiteral("[")); + + int startPosition = mCursor->position(); + + QTextCharFormat origFormat(mCursor->charFormat()); + + QTextCharFormat format(mCursor->charFormat()); + format.setForeground(Qt::blue); + format.setFontUnderline(true); + mCursor->setCharFormat(format); + + QDomNode child = element.firstChild(); + while (!child.isNull()) { + if (child.isElement()) { + const QDomElement childElement = child.toElement(); + if (childElement.tagName() == QLatin1String("emphasis")) { + if (!convertEmphasis(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("strong")) { + if (!convertStrong(childElement)) + return false; + } else if (childElement.tagName() == QLatin1String("style")) { + if (!convertStyle(childElement)) + return false; + } + } else if (child.isText()) { + const QDomText text = child.toText(); + if (!text.isNull()) { + mCursor->insertText(text.data()); + } + } + + child = child.nextSibling(); + } + mCursor->setCharFormat(origFormat); + + int endPosition = mCursor->position(); + + if (type == QLatin1String("note")) + mCursor->insertText(QStringLiteral("]")); + + if (href.startsWith(QLatin1Char('#'))) { // local link + mLocalLinks.insert(href.mid(1), QPair(startPosition, endPosition)); + } else { + // external link + Okular::BrowseAction *action = new Okular::BrowseAction(QUrl(href)); + emit addAction(action, startPosition, endPosition); + } + + return true; +} + +bool Converter::convertStanza(const QDomElement &element) +{ + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("title")) { + if (!convertTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("subtitle")) { + if (!convertSubTitle(child)) + return false; + } else if (child.tagName() == QLatin1String("v")) { + QTextBlockFormat format; + format.setTextIndent(50); + mCursor->insertBlock(format); + if (!convertParagraph(child)) + return false; + } + + child = child.nextSiblingElement(); + } + + return true; +} + +bool Converter::convertCode(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat codeFormat(origFormat); + codeFormat.setFontFamily(QStringLiteral("monospace")); + mCursor->setCharFormat(codeFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} + +bool Converter::convertSuperScript(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat superScriptFormat(origFormat); + superScriptFormat.setVerticalAlignment(QTextCharFormat::AlignSuperScript); + mCursor->setCharFormat(superScriptFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} + +bool Converter::convertSubScript(const QDomElement &element) +{ + QTextCharFormat origFormat = mCursor->charFormat(); + + QTextCharFormat subScriptFormat(origFormat); + subScriptFormat.setVerticalAlignment(QTextCharFormat::AlignSubScript); + mCursor->setCharFormat(subScriptFormat); + + if (!convertParagraph(element)) + return false; + + mCursor->setCharFormat(origFormat); + + return true; +} diff --git a/generators/fictionbook/converter.h b/generators/fictionbook/converter.h new file mode 100644 index 0000000..de54657 --- /dev/null +++ b/generators/fictionbook/converter.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 FICTIONBOOK_CONVERTER_H +#define FICTIONBOOK_CONVERTER_H + +#include + +class QDomElement; +class QTextCursor; + +namespace FictionBook +{ +class Converter : public Okular::TextDocumentConverter +{ + Q_OBJECT + +public: + Converter(); + ~Converter() override; + + QTextDocument *convert(const QString &fileName) override; + +private: + bool convertBody(const QDomElement &element); + bool convertDescription(const QDomElement &element); + bool convertSection(const QDomElement &element); + bool convertTitle(const QDomElement &element); + bool convertParagraph(const QDomElement &element); + bool convertBinary(const QDomElement &element); + bool convertCover(const QDomElement &element); + bool convertImage(const QDomElement &element); + bool convertEpigraph(const QDomElement &element); + bool convertPoem(const QDomElement &element); + bool convertSubTitle(const QDomElement &element); + bool convertCite(const QDomElement &element); + bool convertEmptyLine(const QDomElement &element); + bool convertLink(const QDomElement &element); + bool convertEmphasis(const QDomElement &element); + bool convertStrong(const QDomElement &element); + bool convertStrikethrough(const QDomElement &element); + bool convertStyle(const QDomElement &element); + bool convertStanza(const QDomElement &element); + bool convertCode(const QDomElement &element); + bool convertSuperScript(const QDomElement &element); + bool convertSubScript(const QDomElement &element); + + bool convertTitleInfo(const QDomElement &element); + bool convertDocumentInfo(const QDomElement &element); + bool convertAuthor(const QDomElement &element, QString &firstName, QString &middleName, QString &lastName, QString &email, QString &nickname); + bool convertDate(const QDomElement &element, QDate &date); + bool convertTextNode(const QDomElement &element, QString &data); + + QTextDocument *mTextDocument; + QTextCursor *mCursor; + + class TitleInfo; + TitleInfo *mTitleInfo; + + class DocumentInfo; + DocumentInfo *mDocumentInfo; + + int mSectionCounter; + + QMap mSectionMap; + QMap> mLocalLinks; +}; + +} + +#endif diff --git a/generators/fictionbook/document.cpp b/generators/fictionbook/document.cpp new file mode 100644 index 0000000..57334eb --- /dev/null +++ b/generators/fictionbook/document.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "document.h" + +#include + +#include +#include + +using namespace FictionBook; + +Document::Document(const QString &fileName) + : mFileName(fileName) +{ +} + +bool Document::open() +{ + QIODevice *device; + + QFile file(mFileName); + KZip zip(mFileName); + if (mFileName.endsWith(QLatin1String(".fb")) || mFileName.endsWith(QLatin1String(".fb2"))) { + if (!file.open(QIODevice::ReadOnly)) { + setError(i18n("Unable to open document: %1", file.errorString())); + return false; + } + + device = &file; + } else { + if (!zip.open(QIODevice::ReadOnly)) { + setError(i18n("Document is not a valid ZIP archive")); + return false; + } + + const KArchiveDirectory *directory = zip.directory(); + if (!directory) { + setError(i18n("Invalid document structure (main directory is missing)")); + return false; + } + + const QStringList entries = directory->entries(); + + QString documentFile; + for (int i = 0; i < entries.count(); ++i) { + if (entries[i].endsWith(QLatin1String(".fb2"))) { + documentFile = entries[i]; + break; + } + } + + if (documentFile.isEmpty()) { + setError(i18n("No content found in the document")); + return false; + } + + const KArchiveFile *entry = static_cast(directory->entry(documentFile)); + // FIXME delete 'deviceì somewhen + device = entry->createDevice(); + } + + QString errorMsg; + if (!mDocument.setContent(device, true, &errorMsg)) { + setError(i18n("Invalid XML document: %1", errorMsg)); + return false; + } + + return true; +} + +QDomDocument Document::content() const +{ + return mDocument; +} + +QString Document::lastErrorString() const +{ + return mErrorString; +} + +void Document::setError(const QString &error) +{ + mErrorString = error; +} diff --git a/generators/fictionbook/document.h b/generators/fictionbook/document.h new file mode 100644 index 0000000..bf1c2aa --- /dev/null +++ b/generators/fictionbook/document.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 FICTIONBOOK_DOCUMENT_H +#define FICTIONBOOK_DOCUMENT_H + +#include +#include +#include +#include + +namespace FictionBook +{ +class Document +{ +public: + explicit Document(const QString &fileName); + + bool open(); + + QDomDocument content() const; + + QString lastErrorString() const; + +private: + void setError(const QString &); + + QString mFileName; + QDomDocument mDocument; + QString mErrorString; +}; + +} + +#endif diff --git a/generators/fictionbook/generator_fb.cpp b/generators/fictionbook/generator_fb.cpp new file mode 100644 index 0000000..19586b3 --- /dev/null +++ b/generators/fictionbook/generator_fb.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "generator_fb.h" + +#include "converter.h" + +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(FictionBookGenerator, "libokularGenerator_fb.json") + +FictionBookGenerator::FictionBookGenerator(QObject *parent, const QVariantList &args) + : Okular::TextDocumentGenerator(new FictionBook::Converter, QStringLiteral("okular_fictionbook_generator_settings"), parent, args) +{ +} + +void FictionBookGenerator::addPages(KConfigDialog *dlg) +{ + Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + + dlg->addPage(widget, generalSettings(), i18n("FictionBook"), QStringLiteral("okular-fb2"), i18n("FictionBook Backend Configuration")); +} +#include "generator_fb.moc" diff --git a/generators/fictionbook/generator_fb.h b/generators/fictionbook/generator_fb.h new file mode 100644 index 0000000..5b62d5d --- /dev/null +++ b/generators/fictionbook/generator_fb.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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_GENERATOR_FB_H_ +#define _OKULAR_GENERATOR_FB_H_ + +#include + +class FictionBookGenerator : public Okular::TextDocumentGenerator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + FictionBookGenerator(QObject *parent, const QVariantList &args); + + // [INHERITED] reparse configuration + void addPages(KConfigDialog *dlg) override; +}; + +#endif diff --git a/generators/fictionbook/hi32-app-okular-fb2.svg b/generators/fictionbook/hi32-app-okular-fb2.svg new file mode 100644 index 0000000..bbc333f --- /dev/null +++ b/generators/fictionbook/hi32-app-okular-fb2.svg @@ -0,0 +1,200 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + 2 + diff --git a/generators/fictionbook/libokularGenerator_fb.json b/generators/fictionbook/libokularGenerator_fb.json new file mode 100644 index 0000000..29486b2 --- /dev/null +++ b/generators/fictionbook/libokularGenerator_fb.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "tokoe@kde.org", + "Name": "Tobias Koenig", + "Name[az]": "Tobias Koenig", + "Name[ca@valencia]": "Tobias Koenig", + "Name[ca]": "Tobias Koenig", + "Name[cs]": "Tobias Koenig", + "Name[da]": "Tobias Koenig", + "Name[de]": "Tobias Koenig", + "Name[el]": "Tobias Koenig", + "Name[en_GB]": "Tobias Koenig", + "Name[es]": "Tobias Koenig", + "Name[et]": "Tobias Koenig", + "Name[eu]": "Tobias Koenig", + "Name[fi]": "Tobias Koenig", + "Name[fr]": "Tobias Koenig", + "Name[gl]": "Tobias Koenig", + "Name[ia]": "Tobias Koenig", + "Name[it]": "Tobias Koenig", + "Name[ko]": "Tobias Koenig", + "Name[lt]": "Tobias Koenig", + "Name[nl]": "Tobias Koenig", + "Name[nn]": "Tobias König", + "Name[pl]": "Tobias Koenig", + "Name[pt]": "Tobias Koenig", + "Name[pt_BR]": "Tobias Koenig", + "Name[ru]": "Tobias König", + "Name[sk]": "Tobias Koenig", + "Name[sl]": "Tobias Koenig", + "Name[sr@ijekavian]": "Тобијас Кениг", + "Name[sr@ijekavianlatin]": "Tobijas Kenig", + "Name[sr@latin]": "Tobijas Kenig", + "Name[sr]": "Тобијас Кениг", + "Name[sv]": "Tobias Koenig", + "Name[tr]": "Tobias Koenig", + "Name[uk]": "Tobias Koenig", + "Name[x-test]": "xxTobias Koenigxx", + "Name[zh_CN]": "Tobias Koenig", + "Name[zh_TW]": "Tobias Koenig" + } + ], + "Copyright": "© 2007-2008 Tobias Koenig", + "Copyright[az]": "© 2007-2008 Tobias Koenig", + "Copyright[ca@valencia]": "© 2007-2008 Tobias Koenig", + "Copyright[ca]": "© 2007-2008 Tobias Koenig", + "Copyright[cs]": "© 2007-2008 Tobias Koenig", + "Copyright[da]": "© 2007-2008 Tobias Koenig", + "Copyright[de]": "© 2007-2008 Tobias Koenig", + "Copyright[el]": "© 2007-2008 Tobias Koenig", + "Copyright[en_GB]": "© 2007-2008 Tobias Koenig", + "Copyright[es]": "© 2007-2008 Tobias Koenig", + "Copyright[et]": "© 2007-2008: Tobias Koenig", + "Copyright[eu]": "© 2007-2008 Tobias Koenig", + "Copyright[fi]": "© 2007–2008 Tobias Koenig", + "Copyright[fr]": "© 2007-2008 Tobias Koenig", + "Copyright[gl]": "© 2007-2008 Tobias Koenig", + "Copyright[ia]": "© 2007-2008 Tobias Koenig", + "Copyright[it]": "© 2007-2008 Tobias Koenig", + "Copyright[ko]": "© 2007-2008 Tobias Koenig", + "Copyright[lt]": "© 2007-2008 Tobias Koenig", + "Copyright[nl]": "© 2007-2008 Tobias Koenig", + "Copyright[nn]": "© 2007–2008 Tobias König", + "Copyright[pl]": "© 2007-2008 Tobias Koenig", + "Copyright[pt]": "© 2007-2008 Tobias Koenig", + "Copyright[pt_BR]": "© 2007-2008 Tobias Koenig", + "Copyright[ru]": "© Tobias König, 2007-2008", + "Copyright[sk]": "© 2007-2008 Tobias Koenig", + "Copyright[sl]": "© 2007-2008 Tobias Koenig", + "Copyright[sr@ijekavian]": "© 2007–2008, Тобијас Кениг", + "Copyright[sr@ijekavianlatin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr@latin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr]": "© 2007–2008, Тобијас Кениг", + "Copyright[sv]": "© 2007-2008 Tobias Koenig", + "Copyright[tr]": "© 2007-2008 Tobias Koenig", + "Copyright[uk]": "© Tobias Koenig, 2007–2008", + "Copyright[x-test]": "xx© 2007-2008 Tobias Koenigxx", + "Copyright[zh_CN]": "© 2007-2008 Tobias Koenig", + "Copyright[zh_TW]": "© 2007-2008 Tobias Koenig", + "Description": "A renderer for FictionBook eBooks", + "Description[az]": "FictionBook eBooks üçün tərtibatçı", + "Description[ca@valencia]": "Un renderitzador per a llibres electrònics FictionBook", + "Description[ca]": "Un renderitzador per a llibres electrònics FictionBook", + "Description[cs]": "Renderer elektronických knih Fiction Book", + "Description[da]": "En gengiver til FictionBook-e-bøger", + "Description[de]": "Ein Renderer für FictionBook-eBooks", + "Description[el]": "Πρόγραμμα αποτύπωσης για FictionBook eBooks", + "Description[en_GB]": "A renderer for FictionBook eBooks", + "Description[es]": "Un visor para libros electrónicos FictionBook", + "Description[et]": "FictionBooki e-raamatute renderdaja", + "Description[eu]": "FictionBook eLiburuentzako errendatzaile bat", + "Description[fi]": "FictionBook-e-kirjojen hahmonnin", + "Description[fr]": "Système de rendu pour les livres électroniques FictionBook", + "Description[gl]": "Un visor de libros electrónicos FictionBook.", + "Description[ia]": "Un rendition pro eBooks (Libros electronic) de FictionBook", + "Description[it]": "Un visualizzatore per ebook FictionBook", + "Description[ko]": "FictionBook 전자책 렌더러", + "Description[lt]": "FictionBook elektroninių knygų atvaizdavimas", + "Description[nl]": "Een viewer voor FictionBooks eBooks", + "Description[nn]": "Ein lesar for e-bøker av typen FictionBook", + "Description[pl]": "Wyświetlanie e-booków FictionBook", + "Description[pt]": "Um visualizador de eBooks em FictionBook", + "Description[pt_BR]": "Um interpretador de eBooks FictionBook", + "Description[ru]": "Модуль поддержки формата электронных книг FictionBook", + "Description[sk]": "Vykresľovanie e-kníh FictionBook", + "Description[sl]": "Izrisovalnik za e-knjige FictionBook", + "Description[sr@ijekavian]": "Рендерер за фикшнбук електронске књиге", + "Description[sr@ijekavianlatin]": "Renderer za FictionBook elektronske knjige", + "Description[sr@latin]": "Renderer za FictionBook elektronske knjige", + "Description[sr]": "Рендерер за фикшнбук електронске књиге", + "Description[sv]": "Ett Ã¥tergivningsprogram för Fiction Book e-böcker", + "Description[tr]": "FictionBook e-kitapları için bir oluşturucu", + "Description[uk]": "Програма для відображення електронної белетристики", + "Description[x-test]": "xxA renderer for FictionBook eBooksxx", + "Description[zh_CN]": "FictionBook 电子书渲染器", + "Description[zh_TW]": "FictionBook 電子書成像器", + "Id": "okular_fax", + "License": "GPL", + "MimeTypes": [ + "application/x-fictionbook+xml" + ], + "Name": "Fiction Book Backend", + "Name[az]": "Fiction Book modulu", + "Name[ca@valencia]": "Dorsal Fiction Book", + "Name[ca]": "Dorsal Fiction Book", + "Name[cs]": "Podpůrná vrstva Fiction Book", + "Name[da]": "Fiction Book-backend", + "Name[de]": "Anzeigemodul für FictionBook", + "Name[el]": "Σύστημα υποστήριξης Fiction Book", + "Name[en_GB]": "Fiction Book Backend", + "Name[es]": "Motor para Fiction Book", + "Name[et]": "Fiction Booki taustaprogramm", + "Name[eu]": "Fiction Book-en bizkarraldekoa", + "Name[fi]": "FictionBook-taustaosa", + "Name[fr]": "Moteur pour « FictionBook »", + "Name[gl]": "Infraestrutura para libros FictionBook", + "Name[ia]": "Retro adminisration de Fiction Book", + "Name[it]": "Backend Fiction Book", + "Name[ko]": "Fiction Book 백엔드", + "Name[lt]": "Fiction Book programinė sąsaja", + "Name[nl]": "FictionBook-backend", + "Name[nn]": "FictionBook-motor", + "Name[pl]": "Obsługa Fiction Book", + "Name[pt]": "Infra-Estrutura de Livros de Ficção", + "Name[pt_BR]": "Infraestrutura Fiction Book", + "Name[ru]": "Модуль поддержки формата FictionBook", + "Name[sk]": "Fiction Book Backend", + "Name[sl]": "Zaledje za FictionBook", + "Name[sr@ijekavian]": "Позадина за фикшнбук", + "Name[sr@ijekavianlatin]": "Pozadina za FictionBook", + "Name[sr@latin]": "Pozadina za FictionBook", + "Name[sr]": "Позадина за фикшнбук", + "Name[sv]": "Fiction Book-gränssnitt", + "Name[tr]": "Kurgu Kitabı Arka Ucu", + "Name[uk]": "Модуль FictionBook", + "Name[x-test]": "xxFiction Book Backendxx", + "Name[zh_CN]": "Fiction Book 后端", + "Name[zh_TW]": "Fiction Book 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.5" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/fictionbook/okularApplication_fb.desktop b/generators/fictionbook/okularApplication_fb.desktop new file mode 100755 index 0000000..8bce1d1 --- /dev/null +++ b/generators/fictionbook/okularApplication_fb.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/x-fictionbook+xml; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=FictionBook, e-book, fb2 +X-KDE-Keywords[ar]=FictionBook, e-book, fb2 +X-KDE-Keywords[az]=FictionBook, e-book, fb2 +X-KDE-Keywords[bg]=FictionBook, e-book, fb2 +X-KDE-Keywords[bs]=FictionBook, e-book, fb2 +X-KDE-Keywords[ca]=FictionBook, e-book, fb2 +X-KDE-Keywords[ca@valencia]=FictionBook, e-book, fb2 +X-KDE-Keywords[cs]=FictionBook, e-book, fb2 +X-KDE-Keywords[da]=FictionBook,e-book,fb2 +X-KDE-Keywords[de]=FictionBook, e-book, fb2 +X-KDE-Keywords[el]=FictionBook, e-book, fb2 +X-KDE-Keywords[en_GB]=FictionBook, e-book, fb2 +X-KDE-Keywords[es]=FictionBook, e-book, fb2 +X-KDE-Keywords[et]=FictionBook, e-book, e-raamat, fb2 +X-KDE-Keywords[eu]=FictionBook, e-liburua, fb2 +X-KDE-Keywords[fi]=FictionBook, e-book, e-kirja, sähkökirja, fb2 +X-KDE-Keywords[fr]=FictionBook, e-book, fb2 +X-KDE-Keywords[ga]=FictionBook, r-leabhar, ríomhleabhar, fb2 +X-KDE-Keywords[gl]=FictionBook, e-book, fb2, libro dixital +X-KDE-Keywords[hu]=FictionBook, e-book, fb2 +X-KDE-Keywords[ia]=FictionBook, e-book, fb2 +X-KDE-Keywords[is]=FictionBook, e-book, fb2 +X-KDE-Keywords[it]=FictionBook, e-book, fb2 +X-KDE-Keywords[ja]=FictionBook, e-book, fb2 +X-KDE-Keywords[kk]=FictionBook, e-book, fb2 +X-KDE-Keywords[km]=FictionBook, e-book, fb2 +X-KDE-Keywords[ko]=FictionBook, e-book, fb2 +X-KDE-Keywords[lt]=FictionBook, e-book, fb2 +X-KDE-Keywords[lv]=FictionBook, e-book, fb2, e-grāmata +X-KDE-Keywords[mr]=FictionBook, e-book, fb2 +X-KDE-Keywords[nb]=FictionBook, e-bok, fb2 +X-KDE-Keywords[nds]=FictionBook, e-book, fb2 +X-KDE-Keywords[nl]=Fictieboek, e-book, fb2 +X-KDE-Keywords[nn]=FictionBook, e-book, fb2 +X-KDE-Keywords[pa]=FictionBook, e-book, fb2 +X-KDE-Keywords[pl]=FictionBook, e-book, fb2 +X-KDE-Keywords[pt]=FictionBook, e-book, fb2 +X-KDE-Keywords[pt_BR]=FictionBook, e-book, fb2 +X-KDE-Keywords[ro]=FictionBook, e-book, fb2 +X-KDE-Keywords[ru]=FictionBook, e-book, fb2, электронная книга +X-KDE-Keywords[sk]=FictionBook, e-book, fb2 +X-KDE-Keywords[sl]=FictionBook, e-knjiga, fb2 +X-KDE-Keywords[sr]=FictionBook, e-book, fb2,фикшнбук,е‑књига +X-KDE-Keywords[sr@ijekavian]=FictionBook, e-book, fb2,фикшнбук,е‑књига +X-KDE-Keywords[sr@ijekavianlatin]=FictionBook, e-book, fb2,FictionBook,e‑knjiga +X-KDE-Keywords[sr@latin]=FictionBook, e-book, fb2,FictionBook,e‑knjiga +X-KDE-Keywords[sv]=FictionBook, e-bok, fb2 +X-KDE-Keywords[tr]=FictionBook, e-book, fb2 +X-KDE-Keywords[uk]=FictionBook,fb2,електронна,книга +X-KDE-Keywords[x-test]=xxFictionBookxx,xx e-bookxx,xx fb2xx +X-KDE-Keywords[zh_CN]=FictionBook, e-book, fb2,电子书,虚拟书籍 +X-KDE-Keywords[zh_TW]=FictionBook, e-book, fb2 diff --git a/generators/fictionbook/okularFb.desktop b/generators/fictionbook/okularFb.desktop new file mode 100644 index 0000000..3094347 --- /dev/null +++ b/generators/fictionbook/okularFb.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-fictionbook+xml; diff --git a/generators/fictionbook/org.kde.mobile.okular_fb.desktop b/generators/fictionbook/org.kde.mobile.okular_fb.desktop new file mode 100644 index 0000000..270d853 --- /dev/null +++ b/generators/fictionbook/org.kde.mobile.okular_fb.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +MimeType=application/x-fictionbook+xml; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=FictionBook, e-book, fb2 +X-KDE-Keywords[ar]=FictionBook, e-book, fb2 +X-KDE-Keywords[az]=FictionBook, e-book, fb2 +X-KDE-Keywords[bg]=FictionBook, e-book, fb2 +X-KDE-Keywords[bs]=FictionBook, e-book, fb2 +X-KDE-Keywords[ca]=FictionBook, e-book, fb2 +X-KDE-Keywords[ca@valencia]=FictionBook, e-book, fb2 +X-KDE-Keywords[cs]=FictionBook, e-book, fb2 +X-KDE-Keywords[da]=FictionBook,e-book,fb2 +X-KDE-Keywords[de]=FictionBook, e-book, fb2 +X-KDE-Keywords[el]=FictionBook, e-book, fb2 +X-KDE-Keywords[en_GB]=FictionBook, e-book, fb2 +X-KDE-Keywords[es]=FictionBook, e-book, fb2 +X-KDE-Keywords[et]=FictionBook, e-book, e-raamat, fb2 +X-KDE-Keywords[eu]=FictionBook, e-liburua, fb2 +X-KDE-Keywords[fi]=FictionBook, e-book, e-kirja, sähkökirja, fb2 +X-KDE-Keywords[fr]=FictionBook, e-book, fb2 +X-KDE-Keywords[ga]=FictionBook, r-leabhar, ríomhleabhar, fb2 +X-KDE-Keywords[gl]=FictionBook, e-book, fb2, libro dixital +X-KDE-Keywords[hu]=FictionBook, e-book, fb2 +X-KDE-Keywords[ia]=FictionBook, e-book, fb2 +X-KDE-Keywords[is]=FictionBook, e-book, fb2 +X-KDE-Keywords[it]=FictionBook, e-book, fb2 +X-KDE-Keywords[ja]=FictionBook, e-book, fb2 +X-KDE-Keywords[kk]=FictionBook, e-book, fb2 +X-KDE-Keywords[km]=FictionBook, e-book, fb2 +X-KDE-Keywords[ko]=FictionBook, e-book, fb2 +X-KDE-Keywords[lt]=FictionBook, e-book, fb2 +X-KDE-Keywords[lv]=FictionBook, e-book, fb2, e-grāmata +X-KDE-Keywords[mr]=FictionBook, e-book, fb2 +X-KDE-Keywords[nb]=FictionBook, e-bok, fb2 +X-KDE-Keywords[nds]=FictionBook, e-book, fb2 +X-KDE-Keywords[nl]=Fictieboek, e-book, fb2 +X-KDE-Keywords[nn]=FictionBook, e-book, fb2 +X-KDE-Keywords[pa]=FictionBook, e-book, fb2 +X-KDE-Keywords[pl]=FictionBook, e-book, fb2 +X-KDE-Keywords[pt]=FictionBook, e-book, fb2 +X-KDE-Keywords[pt_BR]=FictionBook, e-book, fb2 +X-KDE-Keywords[ro]=FictionBook, e-book, fb2 +X-KDE-Keywords[ru]=FictionBook, e-book, fb2, электронная книга +X-KDE-Keywords[sk]=FictionBook, e-book, fb2 +X-KDE-Keywords[sl]=FictionBook, e-knjiga, fb2 +X-KDE-Keywords[sr]=FictionBook, e-book, fb2,фикшнбук,е‑књига +X-KDE-Keywords[sr@ijekavian]=FictionBook, e-book, fb2,фикшнбук,е‑књига +X-KDE-Keywords[sr@ijekavianlatin]=FictionBook, e-book, fb2,FictionBook,e‑knjiga +X-KDE-Keywords[sr@latin]=FictionBook, e-book, fb2,FictionBook,e‑knjiga +X-KDE-Keywords[sv]=FictionBook, e-bok, fb2 +X-KDE-Keywords[tr]=FictionBook, e-book, fb2 +X-KDE-Keywords[uk]=FictionBook,fb2,електронна,книга +X-KDE-Keywords[x-test]=xxFictionBookxx,xx e-bookxx,xx fb2xx +X-KDE-Keywords[zh_CN]=FictionBook, e-book, fb2,电子书,虚拟书籍 +X-KDE-Keywords[zh_TW]=FictionBook, e-book, fb2 diff --git a/generators/fictionbook/org.kde.okular-fb.metainfo.xml b/generators/fictionbook/org.kde.okular-fb.metainfo.xml new file mode 100644 index 0000000..0f48929 --- /dev/null +++ b/generators/fictionbook/org.kde.okular-fb.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-fb + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + Fiction Book + FictionBook + FictionBook + FictionBook + ഫിക്ഷൻ ബുക്ക് + Fictie boek + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + FictionBook + Фикшнбук + FictionBook + Фикшнбук + FictionBook + Fiction Book + FictionBook + FictionBook + xxFictionBookxx + FictionBook + FictionBook + Adds support for reading FictionBooks + FictionBooks sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir FictionBooks + Afig la implementació per a llegir FictionBooks + Přidává podporu pro čtení formátu FictionBook + Bietet Unterstützung zum Lesen von FictionBooks + Προσθέτει υποστήριξη για την ανάγνωση FictionBooks + Adds support for reading FictionBooks + Permite la lectura de libros en formato FictionBook + FictionBooki lugemise toetus + FictionBooks irakurtzeko euskarria gehitzen du + Lisää FictionBook-lukutuen + Permet la lecture des fichiers FictionBooks + Engade a posibilidade de ler libros FictionBook + Adde supporto per leger FictionBooks + Aggiunge il supporto per la lettura di documenti in formato FictionBooks + FictionBook 읽기 지원 추가 + Prideda palaikymą FictionBook skaitymui + ഫിക്ഷൻ പുസ്തകങ്ങൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van fictie boeken toe + Legg til støtte for Ã¥ lesa e-bøker i FictionBook-formatet + Dodaje obsługę formatu FictionBook + Adiciona o suporte para a leitura de livros no formato FictionBooks + Adiciona o suporte para leitura de FictionBooks + Поддержка чтения электронных книг FictionBook + Pridá podporu pre čítanie FictionBook + Doda podporo za branje dokumentov FictionBook + Подршка за читање фикшнбук е‑књига + PodrÅ¡ka za čitanje FictionBook e‑knjiga + Подршка за читање фикшнбук е‑књига + PodrÅ¡ka za čitanje FictionBook e‑knjiga + Lägger till stöd för att läsa Fiction Book + FictionBook'ları okumak için destek ekler + Додає підтримку читання документів FictionBook (FB2) + xxAdds support for reading FictionBooksxx + 添加对 FictionBook 的阅读支持 + 加入讀取 FictionBooks 的支援 + + application/x-fictionbook+xml + + https://okular.kde.org + + + + + + + diff --git a/generators/kimgio/CMakeLists.txt b/generators/kimgio/CMakeLists.txt new file mode 100644 index 0000000..db14d74 --- /dev/null +++ b/generators/kimgio/CMakeLists.txt @@ -0,0 +1,26 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_kimgio") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CMAKE_BINARY_DIR} +) + + +########### next target ############### + +okular_add_generator(okularGenerator_kimgio generator_kimgio.cpp) +target_link_libraries(okularGenerator_kimgio okularcore KF5::KExiv2 KF5::I18n) + +if(BUILD_TESTING) + add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) + set( kimgiotest_SRCS tests/kimgiotest.cpp ${CMAKE_SOURCE_DIR}/part/pagepainter.cpp ${CMAKE_SOURCE_DIR}/part/guiutils.cpp ${CMAKE_SOURCE_DIR}/part/debug_ui.cpp ) + ecm_add_test(${kimgiotest_SRCS} TEST_NAME "kimgiotest" LINK_LIBRARIES okularcore okularpart Qt5::Svg Qt5::Test) + target_compile_definitions(kimgiotest PRIVATE -DGENERATOR_PATH="$") +endif() + + +########### install files ############### +install( FILES okularKimgio.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_kimgio.desktop org.kde.mobile.okular_kimgio.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-kimgio.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/kimgio/Messages.sh b/generators/kimgio/Messages.sh new file mode 100644 index 0000000..eb54cc2 --- /dev/null +++ b/generators/kimgio/Messages.sh @@ -0,0 +1,3 @@ +#!/bin/sh +$EXTRACTRC *.rc >> rc.cpp +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_kimgio.pot diff --git a/generators/kimgio/generator_kimgio.cpp b/generators/kimgio/generator_kimgio.cpp new file mode 100644 index 0000000..362264d --- /dev/null +++ b/generators/kimgio/generator_kimgio.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2005 by Albert Astals Cid * + * Copyright (C) 2006-2007 by Pino Toscano * + * Copyright (C) 2006-2007 by Tobias Koenig * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "generator_kimgio.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +OKULAR_EXPORT_PLUGIN(KIMGIOGenerator, "libokularGenerator_kimgio.json") + +KIMGIOGenerator::KIMGIOGenerator(QObject *parent, const QVariantList &args) + : Generator(parent, args) +{ + setFeature(ReadRawData); + setFeature(Threaded); + setFeature(TiledRendering); + setFeature(PrintNative); + setFeature(PrintToFile); + setFeature(SwapBackingFile); +} + +KIMGIOGenerator::~KIMGIOGenerator() +{ +} + +bool KIMGIOGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + emit error(i18n("Unable to load document: %1", f.errorString()), -1); + return false; + } + return loadDocumentInternal(f.readAll(), fileName, pagesVector); +} + +bool KIMGIOGenerator::loadDocumentFromData(const QByteArray &fileData, QVector &pagesVector) +{ + return loadDocumentInternal(fileData, QString(), pagesVector); +} + +bool KIMGIOGenerator::loadDocumentInternal(const QByteArray &fileData, const QString &fileName, QVector &pagesVector) +{ + QBuffer buffer; + buffer.setData(fileData); + buffer.open(QIODevice::ReadOnly); + + QImageReader reader(&buffer, QImageReader::imageFormat(&buffer)); + reader.setAutoDetectImageFormat(true); + if (!reader.read(&m_img)) { + if (!m_img.isNull()) { + emit warning(i18n("This document appears malformed. Here is a best approximation of the document's intended appearance."), -1); + } else { + emit error(i18n("Unable to load document: %1", reader.errorString()), -1); + return false; + } + } + QMimeDatabase db; + auto mime = db.mimeTypeForFileNameAndData(fileName, fileData); + docInfo.set(Okular::DocumentInfo::MimeType, mime.name()); + + // Apply transformations dictated by Exif metadata + KExiv2Iface::KExiv2 exifMetadata; + if (exifMetadata.loadFromData(fileData)) { + exifMetadata.rotateExifQImage(m_img, exifMetadata.getImageOrientation()); + } + + pagesVector.resize(1); + + Okular::Page *page = new Okular::Page(0, m_img.width(), m_img.height(), Okular::Rotation0); + pagesVector[0] = page; + + return true; +} + +KIMGIOGenerator::SwapBackingFileResult KIMGIOGenerator::swapBackingFile(QString const & /*newFileName*/, QVector & /*newPagesVector*/) +{ + // NOP: We don't actually need to do anything because all data has already + // been loaded in RAM + return SwapBackingFileNoOp; +} + +bool KIMGIOGenerator::doCloseDocument() +{ + m_img = QImage(); + + return true; +} + +QImage KIMGIOGenerator::image(Okular::PixmapRequest *request) +{ + // perform a smooth scaled generation + if (request->isTile()) { + const QRect srcRect = request->normalizedRect().geometry(m_img.width(), m_img.height()); + const QRect destRect = request->normalizedRect().geometry(request->width(), request->height()); + + QImage destImg(destRect.size(), QImage::Format_RGB32); + destImg.fill(Qt::white); + + QPainter p(&destImg); + p.setRenderHint(QPainter::SmoothPixmapTransform); + p.drawImage(destImg.rect(), m_img, srcRect); + + return destImg; + } else { + int width = request->width(); + int height = request->height(); + if (request->page()->rotation() % 2 == 1) + qSwap(width, height); + + return m_img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } +} + +bool KIMGIOGenerator::print(QPrinter &printer) +{ + QPainter p(&printer); + + QImage image(m_img); + + if ((image.width() > printer.width()) || (image.height() > printer.height())) + + image = image.scaled(printer.width(), printer.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + + p.drawImage(0, 0, image); + + return true; +} + +Okular::DocumentInfo KIMGIOGenerator::generateDocumentInfo(const QSet &keys) const +{ + Q_UNUSED(keys); + + return docInfo; +} + +#include "generator_kimgio.moc" diff --git a/generators/kimgio/generator_kimgio.h b/generators/kimgio/generator_kimgio.h new file mode 100644 index 0000000..78c2152 --- /dev/null +++ b/generators/kimgio/generator_kimgio.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2005 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_GENERATOR_KIMGIO_H_ +#define _OKULAR_GENERATOR_KIMGIO_H_ + +#include +#include + +#include + +class KIMGIOGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + KIMGIOGenerator(QObject *parent, const QVariantList &args); + ~KIMGIOGenerator() override; + + // [INHERITED] load a document and fill up the pagesVector + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + bool loadDocumentFromData(const QByteArray &fileData, QVector &pagesVector) override; + SwapBackingFileResult swapBackingFile(QString const &newFileName, QVector &newPagesVector) override; + + // [INHERITED] print document using already configured kprinter + bool print(QPrinter &printer) override; + + // [INHERITED] document information + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + +private: + bool loadDocumentInternal(const QByteArray &fileData, const QString &fileName, QVector &pagesVector); + +private: + QImage m_img; + Okular::DocumentInfo docInfo; +}; + +#endif diff --git a/generators/kimgio/libokularGenerator_kimgio.json b/generators/kimgio/libokularGenerator_kimgio.json new file mode 100644 index 0000000..6700855 --- /dev/null +++ b/generators/kimgio/libokularGenerator_kimgio.json @@ -0,0 +1,270 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "aacid@kde.org", + "Name": "Albert Astals Cid", + "Name[az]": "Albert Astals Cid", + "Name[ca@valencia]": "Albert Astals Cid", + "Name[ca]": "Albert Astals Cid", + "Name[cs]": "Albert Astals Cid", + "Name[da]": "Albert Astals Cid", + "Name[de]": "Albert Astals Cid", + "Name[el]": "Albert Astals Cid", + "Name[en_GB]": "Albert Astals Cid", + "Name[es]": "Albert Astals Cid", + "Name[et]": "Albert Astals Cid", + "Name[eu]": "Albert Astals Cid", + "Name[fi]": "Albert Astals Cid", + "Name[fr]": "Albert Astals Cid", + "Name[gl]": "Albert Astals Cid", + "Name[ia]": "Albert Astals Cid", + "Name[it]": "Albert Astals Cid", + "Name[ko]": "Albert Astals Cid", + "Name[lt]": "Albert Astals Cid", + "Name[nl]": "Albert Astals Cid", + "Name[nn]": "Albert Astals Cid", + "Name[pl]": "Albert Astals Cid", + "Name[pt]": "Albert Astals Cid", + "Name[pt_BR]": "Albert Astals Cid", + "Name[ru]": "Albert Astals Cid", + "Name[sk]": "Albert Astals Cid", + "Name[sl]": "Albert Astals Cid", + "Name[sr@ijekavian]": "Алберт Асталс Сид", + "Name[sr@ijekavianlatin]": "Albert Astals Sid", + "Name[sr@latin]": "Albert Astals Sid", + "Name[sr]": "Алберт Асталс Сид", + "Name[sv]": "Albert Astals Cid", + "Name[tr]": "Albert Astals Cid", + "Name[uk]": "Albert Astals Cid", + "Name[x-test]": "xxAlbert Astals Cidxx", + "Name[zh_CN]": "Albert Astals Cid", + "Name[zh_TW]": "Albert Astals Cid" + }, + { + "Email": "pino@kde.org", + "Name": "Pino Toscano", + "Name[az]": "Pino Toscano", + "Name[ca@valencia]": "Pino Toscano", + "Name[ca]": "Pino Toscano", + "Name[cs]": "Pino Toscano", + "Name[da]": "Pino Toscano", + "Name[de]": "Pino Toscano", + "Name[el]": "Pino Toscano", + "Name[en_GB]": "Pino Toscano", + "Name[es]": "Pino Toscano", + "Name[et]": "Pino Toscano", + "Name[eu]": "Pino Toscano", + "Name[fi]": "Pino Toscano", + "Name[fr]": "Pino Toscano", + "Name[gl]": "Pino Toscano", + "Name[ia]": "Pino Toscano", + "Name[it]": "Pino Toscano", + "Name[ko]": "Pino Toscano", + "Name[lt]": "Pino Toscano", + "Name[nl]": "Pino Toscano", + "Name[nn]": "Pino Toscano", + "Name[pl]": "Pino Toscano", + "Name[pt]": "Pino Toscano", + "Name[pt_BR]": "Pino Toscano", + "Name[ru]": "Pino Toscano", + "Name[sk]": "Pino Toscano", + "Name[sl]": "Pino Toscano", + "Name[sr@ijekavian]": "Пино Тоскано", + "Name[sr@ijekavianlatin]": "Pino Toskano", + "Name[sr@latin]": "Pino Toskano", + "Name[sr]": "Пино Тоскано", + "Name[sv]": "Pino Toscano", + "Name[tr]": "Pino Toscano", + "Name[uk]": "Pino Toscano", + "Name[x-test]": "xxPino Toscanoxx", + "Name[zh_CN]": "Pino Toscano", + "Name[zh_TW]": "Pino Toscano" + }, + { + "Email": "tokoe@kde.org", + "Name": "Tobias Koenig", + "Name[az]": "Tobias Koenig", + "Name[ca@valencia]": "Tobias Koenig", + "Name[ca]": "Tobias Koenig", + "Name[cs]": "Tobias Koenig", + "Name[da]": "Tobias Koenig", + "Name[de]": "Tobias Koenig", + "Name[el]": "Tobias Koenig", + "Name[en_GB]": "Tobias Koenig", + "Name[es]": "Tobias Koenig", + "Name[et]": "Tobias Koenig", + "Name[eu]": "Tobias Koenig", + "Name[fi]": "Tobias Koenig", + "Name[fr]": "Tobias Koenig", + "Name[gl]": "Tobias Koenig", + "Name[ia]": "Tobias Koenig", + "Name[it]": "Tobias Koenig", + "Name[ko]": "Tobias Koenig", + "Name[lt]": "Tobias Koenig", + "Name[nl]": "Tobias Koenig", + "Name[nn]": "Tobias König", + "Name[pl]": "Tobias Koenig", + "Name[pt]": "Tobias Koenig", + "Name[pt_BR]": "Tobias Koenig", + "Name[ru]": "Tobias König", + "Name[sk]": "Tobias Koenig", + "Name[sl]": "Tobias Koenig", + "Name[sr@ijekavian]": "Тобијас Кениг", + "Name[sr@ijekavianlatin]": "Tobijas Kenig", + "Name[sr@latin]": "Tobijas Kenig", + "Name[sr]": "Тобијас Кениг", + "Name[sv]": "Tobias Koenig", + "Name[tr]": "Tobias Koenig", + "Name[uk]": "Tobias Koenig", + "Name[x-test]": "xxTobias Koenigxx", + "Name[zh_CN]": "Tobias Koenig", + "Name[zh_TW]": "Tobias Koenig" + } + ], + "Copyright": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[az]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[ca@valencia]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[ca]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[cs]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[da]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[de]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[el]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[en_GB]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[es]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[et]": "© 2005, 2009: Albert Astals Cid\n© 2006-2007: Pino Toscano\n© 2006-2007: Tobias Koenig", + "Copyright[eu]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[fi]": "© 2005, 2009 Albert Astals Cid\n© 2006–2007 Pino Toscano\n© 2006–2007 Tobias Koenig", + "Copyright[fr]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[gl]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[ia]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[it]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[ko]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[lt]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[nl]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[nn]": "© 2005, 2009 Albert Astals Cid\n© 2006–2007 Pino Toscano\n© 2006–2007 Tobias Koenig", + "Copyright[pl]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[pt]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[pt_BR]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[ru]": "© Albert Astals Cid, 2005, 2009\n© Pino Toscano, 2006-2007\n© Tobias König, 2006-2007", + "Copyright[sk]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[sl]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[sr@ijekavian]": "© 2005, 2009, Алберт Асталс Сид\n© 2006–2007, Пино Тоскано\n© 2006–2007, Тобијас Кениг", + "Copyright[sr@ijekavianlatin]": "© 2005, 2009, Albert Astals Sid\n© 2006–2007, Pino Toskano\n© 2006–2007, Tobijas Kenig", + "Copyright[sr@latin]": "© 2005, 2009, Albert Astals Sid\n© 2006–2007, Pino Toskano\n© 2006–2007, Tobijas Kenig", + "Copyright[sr]": "© 2005, 2009, Алберт Асталс Сид\n© 2006–2007, Пино Тоскано\n© 2006–2007, Тобијас Кениг", + "Copyright[sv]": "© 2005,2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[tr]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[uk]": "© Albert Astals Cid, 2005, 2009 \n© Pino Toscano, 2006–2007\n© Tobias Koenig, 2006–2007", + "Copyright[x-test]": "xx© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenigxx", + "Copyright[zh_CN]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Copyright[zh_TW]": "© 2005, 2009 Albert Astals Cid\n© 2006-2007 Pino Toscano\n© 2006-2007 Tobias Koenig", + "Description": "A simple image backend", + "Description[az]": "Sadə şəkil modulu", + "Description[ca@valencia]": "Un dorsal d'imatges senzill", + "Description[ca]": "Un dorsal d'imatges senzill", + "Description[cs]": "Jednoduchá podpůrná vrstva obrázků", + "Description[da]": "En simpel billed-backend", + "Description[de]": "Ein einfaches Anzeigemodul für Bilder", + "Description[el]": "Ένα απλό σύστημα υποστήριξης εικόνων", + "Description[en_GB]": "A simple image backend", + "Description[es]": "Un sencillo motor para imágenes", + "Description[et]": "Lihtne pildi taustaprogramm", + "Description[eu]": "Irudien bizkarraldeko xume bat", + "Description[fi]": "Yksinkertainen kuvataustaosa", + "Description[fr]": "Un moteur simple pour image", + "Description[gl]": "Unha infraestrutura simple para imaxes", + "Description[ia]": "Un simplice retroadministration de image", + "Description[it]": "Un semplice backend per le immagini", + "Description[ko]": "간단한 그림 백엔드", + "Description[lt]": "Paprasta paveikslų programinė sąsaja", + "Description[nl]": "Een eenvoudige afbeeldingsbackend", + "Description[nn]": "Ein enkel biletmotor", + "Description[pl]": "Wyświetlanie obrazów", + "Description[pt]": "Uma infra-estrutura de imagens simples", + "Description[pt_BR]": "Uma infraestrutura simples de imagens", + "Description[ru]": "Модуль поддержки форматов изображений", + "Description[sk]": "Backend jednoduchých obrázkov", + "Description[sl]": "Preprosto zaledje za slike", + "Description[sr@ijekavian]": "Једноставна позадина за слике", + "Description[sr@ijekavianlatin]": "Jednostavna pozadina za slike", + "Description[sr@latin]": "Jednostavna pozadina za slike", + "Description[sr]": "Једноставна позадина за слике", + "Description[sv]": "Ett enkelt bildgränssnitt", + "Description[tr]": "Basit bir görüntü arka ucu", + "Description[uk]": "Проста програма для зображень", + "Description[x-test]": "xxA simple image backendxx", + "Description[zh_CN]": "简单的图像后端", + "Description[zh_TW]": "簡易的圖片後端介面", + "Id": "okular_kimgio", + "License": "GPL", + "MimeTypes": [ + "image/bmp", + "image/x-dds", + "image/x-eps", + "image/x-exr", + "image/gif", + "image/x-hdr", + "image/x-ico", + "image/jp2", + "image/jpeg", + "video/x-mng", + "image/x-portable-bitmap", + "image/x-pcx", + "image/x-portable-graymap", + "image/png", + "image/x-portable-pixmap", + "image/x-psd", + "image/x-rgb", + "image/x-tga", + "image/tiff", + "image/x-xbitmap", + "image/x-xcf", + "image/x-xpixmap" + ], + "Name": "Image Backend", + "Name[az]": "Image Backend", + "Name[ca@valencia]": "Dorsal d'imatges", + "Name[ca]": "Dorsal d'imatges", + "Name[cs]": "Podpůrná vrstva obrázků", + "Name[da]": "Billed-backend", + "Name[de]": "Anzeigemodul für Bilder", + "Name[el]": "Σύστημα υποστήριξης εικόνας", + "Name[en_GB]": "Image Backend", + "Name[es]": "Motor para imágenes", + "Name[et]": "Pildi taustaprogramm", + "Name[eu]": "Irudien bizkarraldekoa", + "Name[fi]": "Kuvataustaosa", + "Name[fr]": "Moteur image", + "Name[gl]": "Infraestrutura de imaxe", + "Name[ia]": "Retro-Administration de Image", + "Name[it]": "Backend immagini", + "Name[ko]": "그림 백엔드", + "Name[lt]": "Paveikslų programinė sąsaja", + "Name[nl]": "Afbeeldings-backend", + "Name[nn]": "Biletmotor", + "Name[pl]": "Obsługa obrazów", + "Name[pt]": "Infra-Estrutura de Imagens", + "Name[pt_BR]": "Infraestrutura de imagens", + "Name[ru]": "Модуль поддержки форматов изображений", + "Name[sk]": "Backend obrázkov", + "Name[sl]": "Zaledje za slike", + "Name[sr@ijekavian]": "Позадина за слике", + "Name[sr@ijekavianlatin]": "Pozadina za slike", + "Name[sr@latin]": "Pozadina za slike", + "Name[sr]": "Позадина за слике", + "Name[sv]": "Bildgränssnitt", + "Name[tr]": "Resim Arka Ucu", + "Name[uk]": "Модуль зображень", + "Name[x-test]": "xxImage Backendxx", + "Name[zh_CN]": "图像后端", + "Name[zh_TW]": "圖片後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.2" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/kimgio/okularApplication_kimgio.desktop b/generators/kimgio/okularApplication_kimgio.desktop new file mode 100755 index 0000000..37c805a --- /dev/null +++ b/generators/kimgio/okularApplication_kimgio.desktop @@ -0,0 +1,172 @@ +[Desktop Entry] +MimeType=image/bmp;image/x-dds;image/x-eps;image/x-exr;image/gif;image/x-hdr;image/x-ico;image/jp2;image/jpeg;video/x-mng;image/x-portable-bitmap;image/x-pcx;image/x-portable-graymap;image/png;image/x-portable-pixmap;image/x-psd;image/x-rgb;image/x-tga;image/tiff;image/x-xbitmap;image/x-xcf;image/x-xpixmap;image/x-gzeps;image/x-bzeps; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=1 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true diff --git a/generators/kimgio/okularKimgio.desktop b/generators/kimgio/okularKimgio.desktop new file mode 100644 index 0000000..cfc2946 --- /dev/null +++ b/generators/kimgio/okularKimgio.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=image/bmp;image/x-dds;image/x-eps;image/x-exr;image/gif;image/x-hdr;image/x-ico;image/jp2;image/jpeg;video/x-mng;image/x-portable-bitmap;image/x-pcx;image/x-portable-graymap;image/png;image/x-portable-pixmap;image/x-psd;image/x-rgb;image/x-tga;image/tiff;image/x-xbitmap;image/x-xcf;image/x-xpixmap;image/x-gzeps;image/x-bzeps; diff --git a/generators/kimgio/org.kde.mobile.okular_kimgio.desktop b/generators/kimgio/org.kde.mobile.okular_kimgio.desktop new file mode 100755 index 0000000..a00f48f --- /dev/null +++ b/generators/kimgio/org.kde.mobile.okular_kimgio.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +MimeType=image/bmp;image/x-dds;image/x-eps;image/x-exr;image/gif;image/x-hdr;image/x-ico;image/jp2;image/jpeg;video/x-mng;image/x-portable-bitmap;image/x-pcx;image/x-portable-graymap;image/png;image/x-portable-pixmap;image/x-psd;image/x-rgb;image/x-tga;image/tiff;image/x-xbitmap;image/x-xcf;image/x-xpixmap;image/x-gzeps;image/x-bzeps; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true diff --git a/generators/kimgio/org.kde.okular-kimgio.metainfo.xml b/generators/kimgio/org.kde.okular-kimgio.metainfo.xml new file mode 100644 index 0000000..c47c67c --- /dev/null +++ b/generators/kimgio/org.kde.okular-kimgio.metainfo.xml @@ -0,0 +1,114 @@ + + + org.kde.okular-kimgio + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Images + Şəkillər + Imatges + Imatges + Obrázky + Bilder + Εικόνες + Images + Imágenes + Pildid + Irudiak + Kuvat + Images + Imaxes + Images + Immagini + 그림 + Paveikslai + ചിത്രങ്ങള്‍ + Afbeeldingen + Bilete + Obrazy + Imagens + Imagens + Изображения + Obrázky + Slike + Слике + Slike + Слике + Slike + Bilder + Resimler + Зображення + xxImagesxx + 图片 + 影像 + Adds support for reading many image formats + Şəkil formatlarının oxunması dəstəyini əlavə edir + Afegeix la implementació per a llegir molts formats d'imatge + Afig la implementació per a llegir molts formats d'imatge + Přidává podporu pro čtení formátů obrázků + Bietet Unterstützung zum Lesen von vielen Bildformaten + Προσθέτει υποστήριξη για την ανάγνωση πολλών τύπων αποθήκευσης εικόνων + Adds support for reading many image formats + Permite la lectura de diversos formatos de imagen + Paljude pildivormingute lugemise toetus + Irudi formatu ugari irakurtzeko euskarria gehitzen du + Lisää monien kuvatiedostomuotojen lukutuen + Permet la lecture de nombreux formats d'images + Engade a posibilidade de ler moitos formatos de imaxe + Adde supporto per leger formatos de image + Aggiunge il supporto per la lettura di vari formati di immagini + 다양한 그림 형식 읽기 지원 추가 + Prideda palaikymą daugelio paveikslų formatų skaitymui + നിരവധി ചിത്ര ഫോർമാറ്റുകൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Ondersteuning toevoegen om vele afbeeldingsformaten te lezen + Legg til støtte for Ã¥ lesa mange ulike biletformat + Dodaje obsługę wielu formatów obrazów + Adiciona o suporte para ler muitos formatos de imagem + Adiciona o suporte para leitura de muitos formatos de imagem + Поддержка чтения многих форматов изображений + Pridá podporu pre čítanie mnohých obrazových formátov + Doda podporo za branje Å¡tevilnih slikovnih vrst + Подршка за читање разних формата слика + PodrÅ¡ka za čitanje raznih formata slika + Подршка за читање разних формата слика + PodrÅ¡ka za čitanje raznih formata slika + Lägger till stöd för att läsa mÃ¥nga bildformat + Birçok resim biçimini okuma desteği ekler + Додає підтримку читання зображень у багатьох форматах + xxAdds support for reading many image formatsxx + 支持多种图片格式的阅读 + 加入讀取許多影像格式的支援 + + image/bmp + image/x-dds + image/x-eps + image/x-exr + image/gif + image/x-hdr + image/x-ico + image/jp2 + image/jpeg + video/x-mng + image/x-portable-bitmap + image/x-pcx + image/x-portable-graymap + image/png + image/x-portable-pixmap + image/x-psd + image/x-rgb + image/x-tga + image/tiff + image/x-xbitmap + image/x-xcf + image/x-xpixmap + image/x-gzeps + image/x-bzeps + + https://okular.kde.org + + + + + + + diff --git a/generators/kimgio/tests/data/testExifOrientation-0.jpg b/generators/kimgio/tests/data/testExifOrientation-0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ccc9a569bbcf89c96ccd21393528779fd2bdb36 GIT binary patch literal 447 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJh$? zV3cBD1+y6#ycnh7>>x%Bs2U~)1}0&IdZ1bmNC0A>ZjcQOjQ?*lID>4Y2!ITs$N-S$ z{|6WZIT)B2n3)-s7?=bZnFSgDA7Ky$Iu7VgWWWU!mK1>4hY)9DWnpGu0!oQsXkY+| z3Zfgs@c$MA4>KdsDrP|jdxpJDDW{sWGBkqSk9LaH85$n$JT|9brO|Trw7!aqi!Xjo kp2+b>Q{t0%uT-4R=B4LO&*qc4V_fj`^wa0_`2XJo0D|>B9RL6T literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-0mirror.jpg b/generators/kimgio/tests/data/testExifOrientation-0mirror.jpg new file mode 100644 index 0000000000000000000000000000000000000000..12a49f4bc64f769afb04a6f93eef70a47e5d0e8a GIT binary patch literal 457 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJg+< zAR)!T3T87fcri-D*+GmN2sKQ?P&Ok_B?Ke@DG(260|Vp#+YHVi8z}-HLntx;r1}2= z20;#>x0sn3l^B==8JPtc{~uux1v(DsPGrCZ6qXlYU}9up0tE#Wu(Gi;uyBYna|(-y z0TqZ~Xk!403Zfgv@c$MA4>K@01(^jI>=`!C^j@FCIw$Vjso*&NB$k6}Te9t@xlY-* wOnidejV+DG*R|c-Zl)@ppuZwsKttecBX_@p#lgqAHDO_4cVx1Hn*ZMf0Qadoi~s-t literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-180.jpg b/generators/kimgio/tests/data/testExifOrientation-180.jpg new file mode 100644 index 0000000000000000000000000000000000000000..41fd545bd85623b3834d506390e1a8d803609ad1 GIT binary patch literal 463 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJhH? zD8;}EW-~B&F-pVPL5vzuHB1Z)Ou|q$BTyv-BmgN84`>4eGI7|v{TMopcnGew&G8{%|RoUPrG;S+-d$!(~JNA FO#lNsLNx#Y literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-180mirror.jpg b/generators/kimgio/tests/data/testExifOrientation-180mirror.jpg new file mode 100644 index 0000000000000000000000000000000000000000..60f8e446d83ccd0e4b104446f6b512d6c46d9ef2 GIT binary patch literal 456 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJg+v zAR)!T3T87fcri-D*+GmNP&G^p3{1jMHX~3a1S9|{5D#br1LObO49*}MDFPrvC^7(~ z`Tqe1K@J8c24-ePB?cxzMrJ|A|3?@^fsO;Z6B%#;g=GYQ-eO`#l44Bm<7<_#hv=|r|I2c$Ng&3HDEJh%k zfl-Qq70hN}@M4sPvx68lplX;H7?^~iY(}6;2uJ`@ARf>L2FCxl8Js~jQUpMTP-Fl| z^Zx@3f*e4{GBGnMF)#@-G7B>PKf)jibR5u~$bbtdEF%C>i4bRDWn*Aw;^1Tl%8Fp< zVE~B=qMO9<{}uxeGb7M8WBm<7<_#hv=|r|I2c$Ng&3HDEJg-a zARz@Jfoui_FGguNJBU#Os)mVyfk_z32C0I81Rw?C0c~Jl{C}Il8Dt|x0AvV727omG zKfoZ!0dy=AGoum%lOQ9rAmjfd45C2C0o{oVxPZcv0ucKU;%uxeK)paI5ey9sAW=bd zV;KJ5V&GwB1X{%`$Y9T~w<+aRlU9aCu=~+Yu{uM;!=1;S*n*fO~Js|)9 literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-90.jpg b/generators/kimgio/tests/data/testExifOrientation-90.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b3a2182f9eddd1a8878591799a57f6894a75ddba GIT binary patch literal 456 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJg-4 zAR)!T3T87fcri-D*+GmNP&G^p3{1jMHX~3a1S9|{5D#br1LObO49*}MDFPrvC^7(~ z`Tqe1K@Ol}nV1=s7?=bZnFSgDA7Ky$Iu7VgWWWU!mJ?uLVq{@Pl450NV_@MBWfl?R z1j>tG=wbkg3LsONNcpQ#Rn=IzN xhEMpS-wn=+kWDe=zOr&kcFOq*dJb(H1Qs^Fv6c;NezRuB4&5DBma_l92>|VEJRbl6 literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-90mirror.jpg b/generators/kimgio/tests/data/testExifOrientation-90mirror.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04e7301be08e1fafd27f057661172d2873753956 GIT binary patch literal 462 zcmex=Bm<7<_#hv=|r|I2c$Ng&3HDEJg-) zAR)!T3T87fcri-D*+GmNP&G^p3{1jMHX~3a1S9|{5D#br1LObO49*}MDFPrvC^7(~ z`Tqe1K@Ol}nV1=s7?=bZnFSgDA7Ky$Iu7VgWWWg&RuEudWM*bXl450J2kK_ws4o6 zdujUlOo;jOfZpF1wt6mcEZ0&q+10Q=V7`D&eOk#%W63{tfku)$x92~(6EsEs|4jhZ C9zrPq literal 0 HcmV?d00001 diff --git a/generators/kimgio/tests/data/testExifOrientation-noexif.jpg b/generators/kimgio/tests/data/testExifOrientation-noexif.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d0a50bb6d6aa33e6d753644b80096ad959896d4 GIT binary patch literal 347 zcmex=>2hprJQQg%FqaQKiVl)XJ~l1^Vpn%l}5|e)A}kdF249Vc_POjO^Hw5y;5;Lo0pzD UJ)2MFj&Z@$(@&qz * + * * + * 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. * + ***************************************************************************/ + +#include "../../settings_core.h" +#include "../generator_kimgio.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +class KIMGIOTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void testExifOrientation_data(); + void testExifOrientation(); +}; + +void KIMGIOTest::initTestCase() +{ + // Make sure we find the okularGenerator_kimgio that we build just now and not the system one + QFileInfo lib(QStringLiteral(GENERATOR_PATH)); + QVERIFY2(lib.exists(), GENERATOR_PATH); + QStringList libPaths = QCoreApplication::libraryPaths(); + libPaths.prepend(lib.absolutePath()); + QCoreApplication::setLibraryPaths(libPaths); + QVERIFY(!KPluginLoader::findPlugin(QStringLiteral("okularGenerator_kimgio")).isEmpty()); + // make sure we didn't break the search path for image formats: + auto availableFormats = QImageReader::supportedImageFormats(); + QVERIFY2(availableFormats.contains("jpeg"), availableFormats.join(", ").constData()); +} + +// The following images have different Exif orientation tags, but they all +// are a 3x2 rectangle whose top-left pixel is black, and whose other pixels are +// white. Note that, due to JPEG lossy compression, some pixels are not pure +// white. In testExifOrientation, we only check the top-left and bottom-right +// corners. +void KIMGIOTest::testExifOrientation_data() +{ + QTest::addColumn("imgPath"); + + // No Exif metadata at all + QTest::newRow("No Exif metadata") << KDESRCDIR "tests/data/testExifOrientation-noexif.jpg"; + + // No Exif orientation information + QTest::newRow("Unspecified") << KDESRCDIR "tests/data/testExifOrientation-unspecified.jpg"; + + // Valid Orientation values + QTest::newRow("Horizontal (normal)") << KDESRCDIR "tests/data/testExifOrientation-0.jpg"; + QTest::newRow("Mirror horizontal") << KDESRCDIR "tests/data/testExifOrientation-0mirror.jpg"; + QTest::newRow("Rotate 90 CW") << KDESRCDIR "tests/data/testExifOrientation-90.jpg"; + QTest::newRow("Mirror horizontal and rotate 90 CW") << KDESRCDIR "tests/data/testExifOrientation-90mirror.jpg"; + QTest::newRow("Rotate 180") << KDESRCDIR "tests/data/testExifOrientation-180.jpg"; + QTest::newRow("Mirror vertical") << KDESRCDIR "tests/data/testExifOrientation-180mirror.jpg"; + QTest::newRow("Rotate 270 CW") << KDESRCDIR "tests/data/testExifOrientation-270.jpg"; + QTest::newRow("Mirror horizontal and rotate 270 CW") << KDESRCDIR "tests/data/testExifOrientation-270mirror.jpg"; +} + +void KIMGIOTest::testExifOrientation() +{ + QFETCH(QString, imgPath); + QMimeDatabase db; + + Okular::SettingsCore::instance(QStringLiteral("kimgiotest")); + Okular::Document *m_document = new Okular::Document(nullptr); + const QMimeType mime = db.mimeTypeForFile(imgPath); + + Okular::DocumentObserver *dummyDocumentObserver = new Okular::DocumentObserver(); + m_document->addObserver(dummyDocumentObserver); + + // Load image + QCOMPARE((int)m_document->openDocument(imgPath, QUrl(), mime), (int)Okular::Document::OpenSuccess); + m_document->setRotation(0); // Test the default rotation + QCOMPARE(m_document->pages(), 1u); + + // Check size + QCOMPARE(m_document->page(0)->width(), double(3)); + QCOMPARE(m_document->page(0)->height(), double(2)); + + // Generate pixmap + Okular::PixmapRequest *req = new Okular::PixmapRequest(dummyDocumentObserver, 0, 3, 2, 1, Okular::PixmapRequest::NoFeature); + m_document->requestPixmaps(QLinkedList() << req); + QVERIFY(m_document->page(0)->hasPixmap(dummyDocumentObserver, 3, 2)); + + // Obtain image + QImage img(3, 2, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + PagePainter::paintPageOnPainter(&p, m_document->page(0), dummyDocumentObserver, 0, 3, 2, QRect(0, 0, 3, 2)); + + // Verify pixel data + QCOMPARE(img.pixel(0, 0), qRgb(0, 0, 0)); + QCOMPARE(img.pixel(2, 1), qRgb(255, 255, 255)); + + m_document->removeObserver(dummyDocumentObserver); + delete dummyDocumentObserver; + delete m_document; +} + +QTEST_MAIN(KIMGIOTest) +#include "kimgiotest.moc" diff --git a/generators/markdown/CMakeLists.txt b/generators/markdown/CMakeLists.txt new file mode 100644 index 0000000..6e8b0f1 --- /dev/null +++ b/generators/markdown/CMakeLists.txt @@ -0,0 +1,25 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_markdown") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + + +########### next target ############### + +set(okularGenerator_md_PART_SRCS + converter.cpp + generator_md.cpp +) + + +okular_add_generator(okularGenerator_md ${okularGenerator_md_PART_SRCS}) + +target_link_libraries(okularGenerator_md PRIVATE okularcore KF5::I18n KF5::KIOCore discount::Lib) + +########### install files ############### +install( FILES okularMd.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_md.desktop org.kde.mobile.okular_md.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-md.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) + diff --git a/generators/markdown/Messages.sh b/generators/markdown/Messages.sh new file mode 100644 index 0000000..d6aa0a0 --- /dev/null +++ b/generators/markdown/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_markdown.pot diff --git a/generators/markdown/converter.cpp b/generators/markdown/converter.cpp new file mode 100644 index 0000000..cbfe69c --- /dev/null +++ b/generators/markdown/converter.cpp @@ -0,0 +1,239 @@ +/*************************************************************************** + * Copyright (C) 2017 by Julian Wolff * + * * + * 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. * + ***************************************************************************/ + +#include "converter.h" + +#include + +#include +#include +#include +#include + +#include + +#include "debug_md.h" + +extern "C" { +#include +} + +// older versions of discount might not have these flags. +// defining them to 0 allows us to convert without them +#ifndef MKD_FENCEDCODE +#define MKD_FENCEDCODE 0 +#endif + +#ifndef MKD_GITHUBTAGS +#define MKD_GITHUBTAGS 0 +#endif + +#ifndef MKD_AUTOLINK +#define MKD_AUTOLINK 0 +#endif + +#define PAGE_WIDTH 980 +#define PAGE_HEIGHT 1307 +#define PAGE_MARGIN 45 +#define CONTENT_WIDTH (PAGE_WIDTH - 2 * PAGE_MARGIN) + +using namespace Markdown; + +Converter::Converter() + : m_markdownFile(nullptr) + , m_isFancyPantsEnabled(true) +{ +} + +Converter::~Converter() +{ + if (m_markdownFile) { + fclose(m_markdownFile); + } +} + +QTextDocument *Converter::convert(const QString &fileName) +{ + m_markdownFile = fopen(fileName.toLocal8Bit(), "rb"); + if (!m_markdownFile) { + emit error(i18n("Failed to open the document"), -1); + return nullptr; + } + + m_fileDir = QDir(fileName.left(fileName.lastIndexOf('/'))); + + QTextDocument *doc = convertOpenFile(); + QHash internalLinks; + QHash documentAnchors; + extractLinks(doc->rootFrame(), internalLinks, documentAnchors); + + for (auto linkIt = internalLinks.constBegin(); linkIt != internalLinks.constEnd(); ++linkIt) { + auto anchorIt = documentAnchors.constFind(linkIt.key()); + if (anchorIt != documentAnchors.constEnd()) { + const Okular::DocumentViewport viewport = calculateViewport(doc, anchorIt.value()); + Okular::GotoAction *action = new Okular::GotoAction(QString(), viewport); + emit addAction(action, linkIt.value().position(), linkIt.value().position() + linkIt.value().length()); + } else { + qDebug() << "Could not find destination for" << linkIt.key(); + } + } + + return doc; +} + +void Converter::convertAgain() +{ + setDocument(convertOpenFile()); +} + +QTextDocument *Converter::convertOpenFile() +{ + rewind(m_markdownFile); + + MMIOT *markdownHandle = mkd_in(m_markdownFile, 0); + + int flags = MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK | MKD_TOC | MKD_IDANCHOR; + if (!m_isFancyPantsEnabled) + flags |= MKD_NOPANTS; + if (!mkd_compile(markdownHandle, flags)) { + emit error(i18n("Failed to compile the Markdown document."), -1); + return nullptr; + } + + char *htmlDocument; + const int size = mkd_document(markdownHandle, &htmlDocument); + + const QString html = QString::fromUtf8(htmlDocument, size); + + QTextDocument *textDocument = new QTextDocument; + textDocument->setPageSize(QSizeF(PAGE_WIDTH, PAGE_HEIGHT)); + textDocument->setHtml(html); + if (generator()) + textDocument->setDefaultFont(generator()->generalSettings()->font()); + + mkd_cleanup(markdownHandle); + + QTextFrameFormat frameFormat; + frameFormat.setMargin(PAGE_MARGIN); + + QTextFrame *rootFrame = textDocument->rootFrame(); + rootFrame->setFrameFormat(frameFormat); + + convertImages(rootFrame, m_fileDir, textDocument); + + return textDocument; +} + +void Converter::extractLinks(QTextFrame *parent, QHash &internalLinks, QHash &documentAnchors) +{ + for (QTextFrame::iterator it = parent->begin(); !it.atEnd(); ++it) { + QTextFrame *textFrame = it.currentFrame(); + const QTextBlock textBlock = it.currentBlock(); + + if (textFrame) { + extractLinks(textFrame, internalLinks, documentAnchors); + } else if (textBlock.isValid()) { + extractLinks(textBlock, internalLinks, documentAnchors); + } + } +} + +void Converter::extractLinks(const QTextBlock &parent, QHash &internalLinks, QHash &documentAnchors) +{ + for (QTextBlock::iterator it = parent.begin(); !it.atEnd(); ++it) { + const QTextFragment textFragment = it.fragment(); + if (textFragment.isValid()) { + const QTextCharFormat textCharFormat = textFragment.charFormat(); + if (textCharFormat.isAnchor()) { + const QString href = textCharFormat.anchorHref(); + if (href.startsWith('#')) { // It's an internal link, store it and we'll resolve it at the end + internalLinks.insert(href.mid(1), textFragment); + } else { + Okular::BrowseAction *action = new Okular::BrowseAction(QUrl(textCharFormat.anchorHref())); + emit addAction(action, textFragment.position(), textFragment.position() + textFragment.length()); + } + + const QStringList anchorNames = textCharFormat.anchorNames(); + for (const QString &anchorName : anchorNames) { + documentAnchors.insert(anchorName, parent); + } + } + } + } +} + +void Converter::convertImages(QTextFrame *parent, const QDir &dir, QTextDocument *textDocument) +{ + for (QTextFrame::iterator it = parent->begin(); !it.atEnd(); ++it) { + QTextFrame *textFrame = it.currentFrame(); + const QTextBlock textBlock = it.currentBlock(); + + if (textFrame) { + convertImages(textFrame, dir, textDocument); + } else if (textBlock.isValid()) { + convertImages(textBlock, dir, textDocument); + } + } +} + +void Converter::convertImages(const QTextBlock &parent, const QDir &dir, QTextDocument *textDocument) +{ + for (QTextBlock::iterator it = parent.begin(); !it.atEnd(); ++it) { + const QTextFragment textFragment = it.fragment(); + if (textFragment.isValid()) { + const QTextCharFormat textCharFormat = textFragment.charFormat(); + if (textCharFormat.isImageFormat()) { + // TODO: Show images from http URIs + + QTextImageFormat format; + + const qreal specifiedHeight = textCharFormat.toImageFormat().height(); + const qreal specifiedWidth = textCharFormat.toImageFormat().width(); + + format.setName(QDir::cleanPath(dir.absoluteFilePath(textCharFormat.toImageFormat().name()))); + const QImage img = QImage(format.name()); + + setImageSize(format, specifiedWidth, specifiedHeight, img.width(), img.height()); + + QTextCursor cursor(textDocument); + cursor.setPosition(textFragment.position(), QTextCursor::MoveAnchor); + cursor.setPosition(textFragment.position() + textFragment.length(), QTextCursor::KeepAnchor); + cursor.removeSelectedText(); + cursor.insertImage(format); + } + } + } +} + +void Converter::setImageSize(QTextImageFormat &format, const qreal specifiedWidth, const qreal specifiedHeight, const qreal originalWidth, const qreal originalHeight) +{ + qreal width = 0; + qreal height = 0; + + const bool hasSpecifiedSize = specifiedHeight > 0 || specifiedWidth > 0; + if (hasSpecifiedSize) { + width = specifiedWidth; + height = specifiedHeight; + if (width == 0 && originalHeight > 0) { + width = originalWidth * height / originalHeight; + } else if (height == 0 && originalWidth > 0) { + height = originalHeight * width / originalWidth; + } + } else { + width = originalWidth; + height = originalHeight; + } + + if (width > CONTENT_WIDTH) { + height = height * CONTENT_WIDTH / width; + width = CONTENT_WIDTH; + } + format.setWidth(width); + format.setHeight(height); +} diff --git a/generators/markdown/converter.h b/generators/markdown/converter.h new file mode 100644 index 0000000..a4e1e2d --- /dev/null +++ b/generators/markdown/converter.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2017 by Julian Wolff * + * * + * 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 MARKDOWN_CONVERTER_H +#define MARKDOWN_CONVERTER_H + +#include + +#include +#include + +class QTextBlock; +class QTextFrame; + +namespace Markdown +{ +class Converter : public Okular::TextDocumentConverter +{ + Q_OBJECT + +public: + Converter(); + ~Converter() override; + + QTextDocument *convert(const QString &fileName) override; + + void convertAgain(); + + void setFancyPantsEnabled(bool b) + { + m_isFancyPantsEnabled = b; + } + bool isFancyPantsEnabled() const + { + return m_isFancyPantsEnabled; + } + + QTextDocument *convertOpenFile(); + +private: + void extractLinks(QTextFrame *parent, QHash &internalLinks, QHash &documentAnchors); + void extractLinks(const QTextBlock &parent, QHash &internalLinks, QHash &documentAnchors); + void convertImages(QTextFrame *parent, const QDir &dir, QTextDocument *textDocument); + void convertImages(const QTextBlock &parent, const QDir &dir, QTextDocument *textDocument); + void setImageSize(QTextImageFormat &format, const qreal specifiedWidth, const qreal specifiedHeight, const qreal originalWidth, const qreal originalHeight); + + FILE *m_markdownFile; + QDir m_fileDir; + bool m_isFancyPantsEnabled; +}; + +} + +#endif diff --git a/generators/markdown/debug_md.h b/generators/markdown/debug_md.h new file mode 100644 index 0000000..cab7ec4 --- /dev/null +++ b/generators/markdown/debug_md.h @@ -0,0 +1,19 @@ + +/*************************************************************************** + * Copyright (C) 2006 by Luigi Toscano * + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_MD_H +#define OKULAR_DEBUG_MD_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularMdDebug) + +#endif diff --git a/generators/markdown/generator_md.cpp b/generators/markdown/generator_md.cpp new file mode 100644 index 0000000..0431bbe --- /dev/null +++ b/generators/markdown/generator_md.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2017 by Julian Wolff * + * * + * 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. * + ***************************************************************************/ + +#include "generator_md.h" + +#include "converter.h" +#include "debug_md.h" + +#include +#include +#include + +#include + +OKULAR_EXPORT_PLUGIN(MarkdownGenerator, "libokularGenerator_md.json") + +MarkdownGenerator::MarkdownGenerator(QObject *parent, const QVariantList &args) + : Okular::TextDocumentGenerator(new Markdown::Converter, QStringLiteral("okular_markdown_generator_settings"), parent, args) +{ + Okular::TextDocumentSettings *mdSettings = generalSettings(); + + mdSettings->addItemBool(QStringLiteral("SmartyPants"), m_isFancyPantsConfigEnabled, true); + mdSettings->load(); + m_wasFancyPantsConfigEnabled = m_isFancyPantsConfigEnabled; + Markdown::Converter *c = static_cast(converter()); + c->setFancyPantsEnabled(m_isFancyPantsConfigEnabled); +} + +bool MarkdownGenerator::reparseConfig() +{ + const bool textDocumentGeneratorChangedConfig = Okular::TextDocumentGenerator::reparseConfig(); + + if (m_wasFancyPantsConfigEnabled != m_isFancyPantsConfigEnabled) { + m_wasFancyPantsConfigEnabled = m_isFancyPantsConfigEnabled; + + Markdown::Converter *c = static_cast(converter()); + c->setFancyPantsEnabled(m_isFancyPantsConfigEnabled); + c->convertAgain(); + setTextDocument(c->document()); + + return true; + } + + return textDocumentGeneratorChangedConfig; +} + +void MarkdownGenerator::addPages(KConfigDialog *dlg) +{ + Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + + QCheckBox *enableSmartyPants = new QCheckBox(dlg); + enableSmartyPants->setObjectName(QStringLiteral("kcfg_SmartyPants")); + widget->addRow(i18n("Enable SmartyPants formatting"), enableSmartyPants); + + dlg->addPage(widget, generalSettings(), i18n("Markdown"), QStringLiteral("text-markdown"), i18n("Markdown Backend Configuration")); +} + +Q_LOGGING_CATEGORY(OkularMdDebug, "org.kde.okular.generators.md", QtWarningMsg) + +#include "generator_md.moc" diff --git a/generators/markdown/generator_md.h b/generators/markdown/generator_md.h new file mode 100644 index 0000000..e9a1361 --- /dev/null +++ b/generators/markdown/generator_md.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2017 by Julian Wolff * + * * + * 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_GENERATOR_MD_H_ +#define _OKULAR_GENERATOR_MD_H_ + +#include + +class MarkdownGenerator : public Okular::TextDocumentGenerator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + MarkdownGenerator(QObject *parent, const QVariantList &args); + + // [INHERITED] reparse configuration + bool reparseConfig() override; + void addPages(KConfigDialog *dlg) override; + +private: + bool m_isFancyPantsConfigEnabled = true; + bool m_wasFancyPantsConfigEnabled = true; +}; + +#endif diff --git a/generators/markdown/libokularGenerator_md.json b/generators/markdown/libokularGenerator_md.json new file mode 100644 index 0000000..4ed08d2 --- /dev/null +++ b/generators/markdown/libokularGenerator_md.json @@ -0,0 +1,133 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "wolff@julianwolff.de", + "Name": "Julian Wolff", + "Name[az]": "Julian Wolff", + "Name[ca@valencia]": "Julian Wolff", + "Name[ca]": "Julian Wolff", + "Name[cs]": "Julian Wolff", + "Name[da]": "Julian Wolff", + "Name[de]": "Julian Wolff", + "Name[el]": "Julian Wolff", + "Name[en_GB]": "Julian Wolff", + "Name[es]": "Julian Wolff", + "Name[et]": "Julian Wolff", + "Name[eu]": "Julian Wolff", + "Name[fi]": "Julian Wolff", + "Name[fr]": "Julian Wolff", + "Name[gl]": "Julian Wolff", + "Name[ia]": "Julian Wolff", + "Name[it]": "Julian Wolff", + "Name[ko]": "Julian Wolff", + "Name[lt]": "Julian Wolff", + "Name[nl]": "Julian Wolff", + "Name[nn]": "Julian Wolff", + "Name[pl]": "Julian Wolff", + "Name[pt]": "Julian Wolff", + "Name[pt_BR]": "Juliano", + "Name[ru]": "Julian Wolff", + "Name[sk]": "Julian Wolff", + "Name[sl]": "Julian Wolff", + "Name[sr@ijekavian]": "Јулијан Волф", + "Name[sr@ijekavianlatin]": "Julijan Volf", + "Name[sr@latin]": "Julijan Volf", + "Name[sr]": "Јулијан Волф", + "Name[sv]": "Julian Wolff", + "Name[tr]": "Julian Wolff", + "Name[uk]": "Julian Wolff", + "Name[x-test]": "xxJulian Wolffxx", + "Name[zh_CN]": "Julian Wolff", + "Name[zh_TW]": "Julian Wolff" + } + ], + "Copyright": "© 2017 Julian Wolff", + "Copyright[az]": "© 2017 Julian Wolff", + "Copyright[ca@valencia]": "© 2017 Julian Wolff", + "Copyright[ca]": "© 2017 Julian Wolff", + "Copyright[cs]": "© 2017 Julian Wolff", + "Copyright[da]": "© 2017 Julian Wolff", + "Copyright[de]": "© 2017 Julian Wolff", + "Copyright[el]": "© 2017 Julian Wolff", + "Copyright[en_GB]": "© 2017 Julian Wolff", + "Copyright[es]": "© 2017 Julian Wolff", + "Copyright[et]": "© 2017: Julian Wolff", + "Copyright[eu]": "© 2017 Julian Wolff", + "Copyright[fi]": "© 2017 Julian Wolff", + "Copyright[fr]": "© 2017 Julian Wolff", + "Copyright[gl]": "© 2017 Julian Wolff", + "Copyright[ia]": "© 2017 Julian Wolff", + "Copyright[it]": "© 2017 Julian Wolff", + "Copyright[ko]": "© 2017 Julian Wolff", + "Copyright[lt]": "© 2017 Julian Wolff", + "Copyright[nl]": "© 2017 Julian Wolff", + "Copyright[nn]": "© 2017 Julian Wolff", + "Copyright[pl]": "© 2017 Julian Wolff", + "Copyright[pt]": "© 2017 Julian Wolff", + "Copyright[pt_BR]": "© 2017 Julian Wolff", + "Copyright[ru]": "© Julian Wolff, 2017", + "Copyright[sk]": "© 2017 Julian Wolff", + "Copyright[sl]": "© 2017 Julian Wolff", + "Copyright[sr@ijekavian]": "© 2017, Јулијан Волф", + "Copyright[sr@ijekavianlatin]": "© 2017, Julijan Volf", + "Copyright[sr@latin]": "© 2017, Julijan Volf", + "Copyright[sr]": "© 2017, Јулијан Волф", + "Copyright[sv]": "© 2017 Julian Wolff", + "Copyright[tr]": "© 2017 Julian Wolff", + "Copyright[uk]": "© Julian Wolff, 2017", + "Copyright[x-test]": "xx© 2017 Julian Wolffxx", + "Copyright[zh_CN]": "© 2017 Julian Wolff", + "Copyright[zh_TW]": "© 2017 Julian Wolff", + "Id": "okular_markdown", + "License": "GPL", + "MimeTypes": [ + "text/markdown", + "text/x-markdown" + ], + "Name": "Markdown Backend", + "Name[az]": "Markdown modulu", + "Name[ca@valencia]": "Dorsal Markdown", + "Name[ca]": "Dorsal Markdown", + "Name[cs]": "Podpůrná vrstva Markdown", + "Name[da]": "Markdown-backend", + "Name[de]": "Anzeigemodul für Markdown", + "Name[el]": "Σύστημα υποστήριξης markdown", + "Name[en_GB]": "Markdown Backend", + "Name[es]": "Motor para Markdown", + "Name[et]": "Markdowni taustaprogramm", + "Name[eu]": "Markdown-en bizkarraldekoa", + "Name[fi]": "Markdown-taustaosa", + "Name[fr]": "Moteur de markdown", + "Name[gl]": "Infraestrutura de Markdown", + "Name[ia]": "Retro-Administration Markdown", + "Name[it]": "Backend Markdown", + "Name[ko]": "Markdown 백엔드", + "Name[lt]": "Markdown programinė sąsaja", + "Name[nl]": "Markdown-backend", + "Name[nn]": "Markdown-motor", + "Name[pl]": "Obsługa Markdown", + "Name[pt]": "Infra-Estrutura de Markdown", + "Name[pt_BR]": "Infraestrutura Markdown", + "Name[ru]": "Модуль поддержки формата Markdown", + "Name[sk]": "Markdown backend", + "Name[sl]": "Zaledje za Markdown", + "Name[sr@ijekavian]": "Позадина за маркдаун", + "Name[sr@ijekavianlatin]": "Pozadina za Markdown", + "Name[sr@latin]": "Pozadina za Markdown", + "Name[sr]": "Позадина за маркдаун", + "Name[sv]": "Markdown-gränssnitt", + "Name[tr]": "Markdown Arka Ucu", + "Name[uk]": "Модуль Markdown", + "Name[x-test]": "xxMarkdown Backendxx", + "Name[zh_CN]": "Markdown 后端", + "Name[zh_TW]": "Markdown 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.0" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/markdown/okularApplication_md.desktop b/generators/markdown/okularApplication_md.desktop new file mode 100644 index 0000000..93f6a11 --- /dev/null +++ b/generators/markdown/okularApplication_md.desktop @@ -0,0 +1,211 @@ +[Desktop Entry] +MimeType=text/markdown; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[lv]=Dokumentu skatÄ«tājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiÅ«ryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=Markdown +X-KDE-Keywords[az]=Markdown +X-KDE-Keywords[ca]=Markdown +X-KDE-Keywords[ca@valencia]=Markdown +X-KDE-Keywords[cs]=Markdown +X-KDE-Keywords[da]=Markdown +X-KDE-Keywords[de]=Markdown +X-KDE-Keywords[el]=Markdown +X-KDE-Keywords[en_GB]=Markdown +X-KDE-Keywords[es]=Markdown +X-KDE-Keywords[et]=Markdown +X-KDE-Keywords[eu]=Markdown +X-KDE-Keywords[fi]=Markdown +X-KDE-Keywords[fr]=Markdown +X-KDE-Keywords[gl]=Markdown +X-KDE-Keywords[hu]=Markdown +X-KDE-Keywords[ia]=Markdown +X-KDE-Keywords[is]=Markdown +X-KDE-Keywords[it]=Markdown +X-KDE-Keywords[ko]=Markdown +X-KDE-Keywords[lt]=Markdown +X-KDE-Keywords[nl]=Markdown +X-KDE-Keywords[nn]=Markdown +X-KDE-Keywords[pl]=Markdown +X-KDE-Keywords[pt]=Markdown +X-KDE-Keywords[pt_BR]=Markdown +X-KDE-Keywords[ru]=Markdown +X-KDE-Keywords[sk]=Markdown +X-KDE-Keywords[sl]=Markdown +X-KDE-Keywords[sr]=Markdown,маркдаун +X-KDE-Keywords[sr@ijekavian]=Markdown,маркдаун +X-KDE-Keywords[sr@ijekavianlatin]=Markdown,Markdown +X-KDE-Keywords[sr@latin]=Markdown,Markdown +X-KDE-Keywords[sv]=Markdown +X-KDE-Keywords[tr]=Markdown +X-KDE-Keywords[uk]=Markdown +X-KDE-Keywords[x-test]=xxMarkdownxx +X-KDE-Keywords[zh_CN]=Markdown +X-KDE-Keywords[zh_TW]=Markdown diff --git a/generators/markdown/okularMd.desktop b/generators/markdown/okularMd.desktop new file mode 100644 index 0000000..4534e27 --- /dev/null +++ b/generators/markdown/okularMd.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=text/markdown; diff --git a/generators/markdown/org.kde.mobile.okular_md.desktop b/generators/markdown/org.kde.mobile.okular_md.desktop new file mode 100644 index 0000000..55691b4 --- /dev/null +++ b/generators/markdown/org.kde.mobile.okular_md.desktop @@ -0,0 +1,201 @@ +[Desktop Entry] +MimeType=text/markdown; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=LasÄ«tājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiÅ«ryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=ŽiÅ«ryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatÄ«tājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=Markdown +X-KDE-Keywords[az]=Markdown +X-KDE-Keywords[ca]=Markdown +X-KDE-Keywords[ca@valencia]=Markdown +X-KDE-Keywords[cs]=Markdown +X-KDE-Keywords[da]=Markdown +X-KDE-Keywords[de]=Markdown +X-KDE-Keywords[el]=Markdown +X-KDE-Keywords[en_GB]=Markdown +X-KDE-Keywords[es]=Markdown +X-KDE-Keywords[et]=Markdown +X-KDE-Keywords[eu]=Markdown +X-KDE-Keywords[fi]=Markdown +X-KDE-Keywords[fr]=Markdown +X-KDE-Keywords[gl]=Markdown +X-KDE-Keywords[hu]=Markdown +X-KDE-Keywords[ia]=Markdown +X-KDE-Keywords[is]=Markdown +X-KDE-Keywords[it]=Markdown +X-KDE-Keywords[ko]=Markdown +X-KDE-Keywords[lt]=Markdown +X-KDE-Keywords[nl]=Markdown +X-KDE-Keywords[nn]=Markdown +X-KDE-Keywords[pl]=Markdown +X-KDE-Keywords[pt]=Markdown +X-KDE-Keywords[pt_BR]=Markdown +X-KDE-Keywords[ru]=Markdown +X-KDE-Keywords[sk]=Markdown +X-KDE-Keywords[sl]=Markdown +X-KDE-Keywords[sr]=Markdown,маркдаун +X-KDE-Keywords[sr@ijekavian]=Markdown,маркдаун +X-KDE-Keywords[sr@ijekavianlatin]=Markdown,Markdown +X-KDE-Keywords[sr@latin]=Markdown,Markdown +X-KDE-Keywords[sv]=Markdown +X-KDE-Keywords[tr]=Markdown +X-KDE-Keywords[uk]=Markdown +X-KDE-Keywords[x-test]=xxMarkdownxx +X-KDE-Keywords[zh_CN]=Markdown +X-KDE-Keywords[zh_TW]=Markdown diff --git a/generators/markdown/org.kde.okular-md.metainfo.xml b/generators/markdown/org.kde.okular-md.metainfo.xml new file mode 100644 index 0000000..a27b8a6 --- /dev/null +++ b/generators/markdown/org.kde.okular-md.metainfo.xml @@ -0,0 +1,89 @@ + + + org.kde.okular-md + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + മാർക്ഡൗൺ + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Markdown + Маркдаун + Markdown + Маркдаун + Markdown + Markdown + Markdown + xxMarkdownxx + Markdown + Markdown + Adds support for reading Markdown documents + Markdown sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents en Markdown + Afig la implementació per a llegir documents en Markdown + Přidává podporu pro čtení dokumentů Markdown + Bietet Unterstützung zum Lesen von Markdown-Dokumenten + Προσθέτει υποστήριξη για ανάγνωση Markdown εγγράφων + Adds support for reading Markdown documents + Permite la lectura de documentos Markdown + Markdowni dokumentide lugemise toetuse lisamine + Markdown dokumentuak irakurtzeko euskarria gehitzen du + Lisää Markdown-tiedostojen lukutuen + Permet la lecture des documents Markdown + Engade a posibilidade de ler documentos Markdown + Adde supporto per leger documentos Markdown + Aggiunge il supporto per la lettura di documenti Markdown + Markdown 문서 읽기 지원 추가 + Prideda palaikymą Markdown dokumentų skaitymui + മാർക്ഡൗൺ പ്രമാണങ്ങൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van Markdown-documenten toe + Legg til støtte for Ã¥ lesa Markdown-dokument + Dodaje obsługę dokumentów Markdown + Adiciona o suporte para a leitura de documentos em Markdown + Adiciona o suporte para leitura de documentos em Markdown + Поддержка чтения документов Markdown + Pridá podporu pre čítanie Markdown dokumentov + Doda podporo za branje dokumentov Markdown + Подршка за читање маркдаун докумената + PodrÅ¡ka za čitanje Markdown dokumenata + Подршка за читање маркдаун докумената + PodrÅ¡ka za čitanje Markdown dokumenata + Lägger till stöd för att läsa Markdown-dokument + Додає підтримку читання документів Markdown + xxAdds support for reading Markdown documentsxx + 添加阅读 Markdown 文档的支持 + 增加讀取 Markdown 文件的支援 + + text/markdown + + https://okular.kde.org + + + + + + + diff --git a/generators/mobipocket/CMakeLists.txt b/generators/mobipocket/CMakeLists.txt new file mode 100644 index 0000000..68179b4 --- /dev/null +++ b/generators/mobipocket/CMakeLists.txt @@ -0,0 +1,19 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_mobi") + +########### next target ############### + +set(okularGenerator_mobi_PART_SRCS + mobidocument.cpp + generator_mobi.cpp + converter.cpp +) + +okular_add_generator(okularGenerator_mobi ${okularGenerator_mobi_PART_SRCS}) + +target_link_libraries(okularGenerator_mobi okularcore qmobipocket KF5::I18n Qt5::Gui) + +########### install files ############### +install( FILES okularMobi.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_mobi.desktop org.kde.mobile.okular_mobi.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-mobipocket.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/mobipocket/Messages.sh b/generators/mobipocket/Messages.sh new file mode 100755 index 0000000..6e6c94f --- /dev/null +++ b/generators/mobipocket/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT *.cpp -o $podir/okular_mobi.pot diff --git a/generators/mobipocket/converter.cpp b/generators/mobipocket/converter.cpp new file mode 100644 index 0000000..3ad41aa --- /dev/null +++ b/generators/mobipocket/converter.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jakub Stachowski * + * * + * 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. * + ***************************************************************************/ + +#include "converter.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace Mobi; + +Converter::Converter() +{ +} + +Converter::~Converter() +{ +} + +void Converter::handleMetadata(const QMap &metadata) +{ + QMapIterator it(metadata); + while (it.hasNext()) { + it.next(); + switch (it.key()) { + case Mobipocket::Document::Title: + emit addMetaData(Okular::DocumentInfo::Title, it.value()); + break; + case Mobipocket::Document::Author: + emit addMetaData(Okular::DocumentInfo::Author, it.value()); + break; + case Mobipocket::Document::Description: + emit addMetaData(Okular::DocumentInfo::Description, it.value()); + break; + case Mobipocket::Document::Subject: + emit addMetaData(Okular::DocumentInfo::Subject, it.value()); + break; + case Mobipocket::Document::Copyright: + emit addMetaData(Okular::DocumentInfo::Copyright, it.value()); + break; + } + } +} + +QTextDocument *Converter::convert(const QString &fileName) +{ + MobiDocument *newDocument = new MobiDocument(fileName); + if (!newDocument->mobi()->isValid()) { + emit error(i18n("Error while opening the Mobipocket document."), -1); + delete newDocument; + return nullptr; + } + if (newDocument->mobi()->hasDRM()) { + emit error(i18n("This book is protected by DRM and can be displayed only on designated device"), -1); + delete newDocument; + return nullptr; + } + + handleMetadata(newDocument->mobi()->metadata()); + newDocument->setPageSize(QSizeF(600, 800)); + + QTextFrameFormat frameFormat; + frameFormat.setMargin(20); + QTextFrame *rootFrame = newDocument->rootFrame(); + rootFrame->setFrameFormat(frameFormat); + QMap> links; + QMap targets; + + // go over whole document and add all tags to links or targets map + for (QTextBlock it = newDocument->begin(); it != newDocument->end(); it = it.next()) + for (QTextBlock::iterator fit = it.begin(); !fit.atEnd(); ++fit) { + QTextFragment frag = fit.fragment(); + QTextCharFormat format = frag.charFormat(); + if (!format.isAnchor()) + continue; + // link + if (!format.anchorHref().isEmpty()) + links[format.anchorHref()] = QPair(frag.position(), frag.position() + frag.length()); + const QStringList anchors = format.anchorNames(); + if (!anchors.isEmpty()) { + // link targets + for (const QString &name : anchors) + targets[QLatin1Char('#') + name] = it; + } + } + + // create link actions + QMapIterator> it(links); + while (it.hasNext()) { + it.next(); + QUrl u(it.key()); + // external or internal link + if (!u.isRelative()) + emit addAction(new Okular::BrowseAction(QUrl(it.key())), it.value().first, it.value().second); + else { + // is there valid target? + if (!targets.contains(it.key()) || !targets[it.key()].isValid()) + continue; + emit addAction(new Okular::GotoAction(QString(), calculateViewport(newDocument, targets[it.key()])), it.value().first, it.value().second); + } + } + + return newDocument; +} diff --git a/generators/mobipocket/converter.h b/generators/mobipocket/converter.h new file mode 100644 index 0000000..d4f224a --- /dev/null +++ b/generators/mobipocket/converter.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jakub Stachowski * + * * + * 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 MOBI_CONVERTER_H +#define MOBI_CONVERTER_H + +#include +#include + +#include "mobidocument.h" +#include + +namespace Mobi +{ +class Converter : public Okular::TextDocumentConverter +{ + Q_OBJECT +public: + Converter(); + ~Converter() override; + + QTextDocument *convert(const QString &fileName) override; + +private: + void handleMetadata(const QMap &metadata); +}; +} + +#endif diff --git a/generators/mobipocket/generator_mobi.cpp b/generators/mobipocket/generator_mobi.cpp new file mode 100644 index 0000000..bb62c84 --- /dev/null +++ b/generators/mobipocket/generator_mobi.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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. * + ***************************************************************************/ +#include "generator_mobi.h" + +#include "converter.h" + +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(MobiGenerator, "libokularGenerator_mobi.json") + +MobiGenerator::MobiGenerator(QObject *parent, const QVariantList &args) + : Okular::TextDocumentGenerator(new Mobi::Converter, QStringLiteral("okular_mobi_generator_settings"), parent, args) +{ +} + +void MobiGenerator::addPages(KConfigDialog *dlg) +{ + Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + + dlg->addPage(widget, generalSettings(), i18n("Mobipocket"), QStringLiteral("application-x-mobipocket-ebook"), i18n("Mobipocket Backend Configuration")); +} + +#include "generator_mobi.moc" diff --git a/generators/mobipocket/generator_mobi.h b/generators/mobipocket/generator_mobi.h new file mode 100644 index 0000000..6ea6e3a --- /dev/null +++ b/generators/mobipocket/generator_mobi.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2008 by Ely Levy * + * * + * 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_GENERATOR_MOBI_H +#define OKULAR_GENERATOR_MOBI_H +#include + +class MobiGenerator : public Okular::TextDocumentGenerator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + MobiGenerator(QObject *parent, const QVariantList &args); + ~MobiGenerator() override + { + } + + // [INHERITED] reparse configuration + void addPages(KConfigDialog *dlg) override; +}; + +#endif diff --git a/generators/mobipocket/libokularGenerator_mobi.json b/generators/mobipocket/libokularGenerator_mobi.json new file mode 100644 index 0000000..071cb1f --- /dev/null +++ b/generators/mobipocket/libokularGenerator_mobi.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "qbast@go2.pl", + "Name": "Jakub Stachowski", + "Name[az]": "Jakub Stachowski", + "Name[ca@valencia]": "Jakub Stachowski", + "Name[ca]": "Jakub Stachowski", + "Name[cs]": "Jakub Stachowski", + "Name[da]": "Jakub Stachowski", + "Name[de]": "Jakub Stachowski", + "Name[el]": "Jakub Stachowski", + "Name[en_GB]": "Jakub Stachowski", + "Name[es]": "Jakub Stachowski", + "Name[et]": "Jakub Stachowski", + "Name[eu]": "Jakub Stachowski", + "Name[fi]": "Jakub Stachowski", + "Name[fr]": "Jakub Stachowski", + "Name[gl]": "Jakub Stachowski", + "Name[ia]": " Jakub Stachowski", + "Name[it]": "Jakub Stachowski", + "Name[ko]": "Jakub Stachowski", + "Name[lt]": "Jakub Stachowski", + "Name[nl]": "Jakub Stachowski", + "Name[nn]": "Jakub Stachowski", + "Name[pl]": "Jakub Stachowski", + "Name[pt]": "Jakub Stachowski", + "Name[pt_BR]": "Jakub Stachowski", + "Name[ru]": "Jakub Stachowski", + "Name[sk]": "Jakub Stachowski", + "Name[sl]": "Jakub Stachowski", + "Name[sr@ijekavian]": "Јакуб Стаховски", + "Name[sr@ijekavianlatin]": "Jakub Stahovski", + "Name[sr@latin]": "Jakub Stahovski", + "Name[sr]": "Јакуб Стаховски", + "Name[sv]": "Jakub Stachowski", + "Name[tr]": "Jakub Stachowski", + "Name[uk]": "Jakub Stachowski", + "Name[x-test]": "xxJakub Stachowskixx", + "Name[zh_CN]": "Jakub Stachowski", + "Name[zh_TW]": "Jakub Stachowski" + } + ], + "Copyright": "© 2008-2009 Jakub Stachowski", + "Copyright[az]": "© 2008-2009 Jakub Stachowski", + "Copyright[ca@valencia]": "© 2008-2009 Jakub Stachowski", + "Copyright[ca]": "© 2008-2009 Jakub Stachowski", + "Copyright[cs]": "© 2008-2009 Jakub Stachowski", + "Copyright[da]": "© 2008-2009 Jakub Stachowski", + "Copyright[de]": "© 2008-2009 Jakub Stachowski", + "Copyright[el]": "© 2008-2009 Jakub Stachowski", + "Copyright[en_GB]": "© 2008-2009 Jakub Stachowski", + "Copyright[es]": "© 2008-2009 Jakub Stachowski", + "Copyright[et]": "© 2008-2009: Jakub Stachowski", + "Copyright[eu]": "© 2008-2009 Jakub Stachowski", + "Copyright[fi]": "© 2008–2009 Jakub Stachowski", + "Copyright[fr]": "© 2008-2009 Jakub Stachowski", + "Copyright[gl]": "© 2008-2009 Jakub Stachowski", + "Copyright[ia]": "© 2008-2009 Jakub Stachowski", + "Copyright[it]": "© 2008-2009 Jakub Stachowski", + "Copyright[ko]": "© 2008-2009 Jakub Stachowski", + "Copyright[lt]": "© 2008-2009 Jakub Stachowski", + "Copyright[nl]": "© 2008-2009 Jakub Stachowski", + "Copyright[nn]": "© 2008–2009 Jakub Stachowski", + "Copyright[pl]": "© 2008-2009 Jakub Stachowski", + "Copyright[pt]": "© 2008-2009 Jakub Stachowski", + "Copyright[pt_BR]": "© 2008-2009 Jakub Stachowski", + "Copyright[ru]": "© Jakub Stachowski, 2008-2009", + "Copyright[sk]": "© 2008-2009 Jakub Stachowski", + "Copyright[sl]": "© 2008-2009 Jakub Stachowski", + "Copyright[sr@ijekavian]": "© 2008—2009, Јакуб Стаховски", + "Copyright[sr@ijekavianlatin]": "© 2008—2009, Jakub Stahovski", + "Copyright[sr@latin]": "© 2008—2009, Jakub Stahovski", + "Copyright[sr]": "© 2008—2009, Јакуб Стаховски", + "Copyright[sv]": "© 2008-2009 Jakub Stachowski", + "Copyright[tr]": "© 2008-2009 Jakub Stachowski", + "Copyright[uk]": "© Jakub Stachowski, 2008–2009", + "Copyright[x-test]": "xx© 2008-2009 Jakub Stachowskixx", + "Copyright[zh_CN]": "© 2008-2009 Jakub Stachowski", + "Copyright[zh_TW]": "© 2008-2009 Jakub Stachowski", + "Description": "A mobipocket backend", + "Description[az]": "Mobipocket modulu", + "Description[ca@valencia]": "Un dorsal per al Mobipocket", + "Description[ca]": "Un dorsal per al Mobipocket", + "Description[cs]": " Implementace Mobipocket", + "Description[da]": "En mobipocket-backend", + "Description[de]": "Ein Anzeigemodul für Mobipocket-Dateien", + "Description[el]": "Σύστημα υποστήριξης mobipocket", + "Description[en_GB]": "A mobipocket backend", + "Description[es]": "Un motor para mobipocket", + "Description[et]": "Mobipocketi taustaprogramm", + "Description[eu]": "Mobipocket-en bizkarraldeko bat", + "Description[fi]": "MobiPocket-taustaosa", + "Description[fr]": "Un moteur Mobipocket", + "Description[gl]": "Unha infraestrutura para mobipocket", + "Description[ia]": "Un retro-administration de Mobipocket", + "Description[it]": "Un backend per mobipocket", + "Description[ko]": "Mobipocket 백엔드", + "Description[lt]": "Mobipocket programinė sąsaja", + "Description[nl]": "Een mobipocket-backend", + "Description[nn]": "Ein Mobipocket-motor", + "Description[pl]": "Obsługa formatu MOBI", + "Description[pt]": "Uma infra-estrutura de Mobipocket", + "Description[pt_BR]": "Uma infraestrutura do mobipocket", + "Description[ru]": "Модуль поддержки формата Mobipocket", + "Description[sk]": "Mobipocket backend", + "Description[sl]": "Zaledje za Mobipocket", + "Description[sr@ijekavian]": "Позадина за Мобипокет", + "Description[sr@ijekavianlatin]": "Pozadina za Mobipocket", + "Description[sr@latin]": "Pozadina za Mobipocket", + "Description[sr]": "Позадина за Мобипокет", + "Description[sv]": "Ett Mobipocket-gränssnitt", + "Description[tr]": "Bir mobipocket arka ucu", + "Description[uk]": "Сервер mobipocket", + "Description[x-test]": "xxA mobipocket backendxx", + "Description[zh_CN]": "Mobipocket 后端", + "Description[zh_TW]": "Mobipocket 後端介面", + "Id": "okular_mobi", + "License": "GPL", + "MimeTypes": [ + "application/x-mobipocket-ebook" + ], + "Name": "Mobipocket Backend", + "Name[az]": "Mobipocket modulu", + "Name[ca@valencia]": "Dorsal Mobipocket", + "Name[ca]": "Dorsal Mobipocket", + "Name[cs]": " Implementace Mobipocket", + "Name[da]": "Mobipocket-backend", + "Name[de]": "Anzeigemodul für Mobipocket-Dateien", + "Name[el]": "Σύστημα υποστήριξης Mobipocket", + "Name[en_GB]": "Mobipocket Backend", + "Name[es]": "Motor para Mobipocket", + "Name[et]": "Mobipocketi taustaprogramm", + "Name[eu]": "Mobipocket-en bizkarraldekoa", + "Name[fi]": "Mobipocket-taustaosa", + "Name[fr]": "Moteur Mobipocket", + "Name[gl]": "Infraestrutura para Mobipocket", + "Name[ia]": "Retro-administration de Mobipocket", + "Name[it]": "Backend Mobipocket", + "Name[ko]": "Mobipocket 백엔드", + "Name[lt]": "Mobipocket programinė sąsaja", + "Name[nl]": "Mobipocket-backend", + "Name[nn]": "Mobipocket-motor", + "Name[pl]": "Obsługa Mobipocket", + "Name[pt]": "Infra-Estrutura de Mobipocket", + "Name[pt_BR]": "Infraestrutura Mobipocket", + "Name[ru]": "Модуль поддержки формата Mobipocket", + "Name[sk]": "Mobipocket Backend", + "Name[sl]": "Zaledje za Mobipocket", + "Name[sr@ijekavian]": "Позадина за Мобипокет", + "Name[sr@ijekavianlatin]": "Pozadina za Mobipocket", + "Name[sr@latin]": "Pozadina za Mobipocket", + "Name[sr]": "Позадина за Мобипокет", + "Name[sv]": "Mobipocket-gränssnitt", + "Name[tr]": "Mobipocket Arka Ucu", + "Name[uk]": "Модуль Mobipocket", + "Name[x-test]": "xxMobipocket Backendxx", + "Name[zh_CN]": "Mobipocket 后端", + "Name[zh_TW]": "Mobipocket 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.1" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/mobipocket/mobidocument.cpp b/generators/mobipocket/mobidocument.cpp new file mode 100644 index 0000000..b8c7013 --- /dev/null +++ b/generators/mobipocket/mobidocument.cpp @@ -0,0 +1,123 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jakub Stachowski * + * * + * 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. * + ***************************************************************************/ +#include "mobidocument.h" +#include // Because of the HACK +#include +#include +#include +#include // Because of the HACK +#include +#include +#include + +using namespace Mobi; + +MobiDocument::MobiDocument(const QString &fileName) + : QTextDocument() +{ + file = new Mobipocket::QFileStream(fileName); + doc = new Mobipocket::Document(file); + if (doc->isValid()) { + QString text = doc->text(); + QString header = text.left(1024); + if (header.contains(QStringLiteral("")) || header.contains(QStringLiteral(""))) { + // HACK BEGIN Get the links without CSS to be blue + // Remove if Qt ever gets fixed and the code in textdocumentgenerator.cpp works + const QPalette orig = qApp->palette(); + QPalette p = orig; + p.setColor(QPalette::Link, Qt::blue); + qApp->setPalette(p); + // HACK END + + setHtml(fixMobiMarkup(text)); + + // HACK BEGIN + qApp->setPalette(orig); + // HACK END + } else { + setPlainText(text); + } + } +} + +MobiDocument::~MobiDocument() +{ + delete doc; + delete file; +} + +QVariant MobiDocument::loadResource(int type, const QUrl &name) +{ + if (type != QTextDocument::ImageResource || name.scheme() != QString(QStringLiteral("pdbrec"))) + return QVariant(); + bool ok; + quint16 recnum = name.path().midRef(1).toUShort(&ok); + if (!ok || recnum >= doc->imageCount()) + return QVariant(); + + QVariant resource; + resource.setValue(doc->getImage(recnum - 1)); + addResource(type, name, resource); + + return resource; +} + +// starting from 'pos', find position in the string that is not inside a tag +int outsideTag(const QString &data, int pos) +{ + for (int i = pos - 1; i >= 0; i--) { + if (data[i] == QLatin1Char('>')) + return pos; + if (data[i] == QLatin1Char('<')) + return i; + } + return pos; +} + +QString MobiDocument::fixMobiMarkup(const QString &data) +{ + QString ret = data; + QMap anchorPositions; + static QRegExp anchors(QStringLiteral(" it(anchorPositions); + while (it.hasNext()) { + it.next(); + // link pointing outside the document, ignore + if ((it.key() + offset) >= ret.size()) + continue; + int fixedpos = outsideTag(ret, it.key() + offset); + ret.insert(fixedpos, QStringLiteral(" ")); + // inserting anchor shifts all offsets after the anchor + offset += 21 + it.value().size(); + } + + // replace links referencing filepos with normal internal links + ret.replace(anchors, QStringLiteral(" where recindex is number of + // record containing image + static QRegExp imgs(QStringLiteral(""), Qt::CaseInsensitive); + + imgs.setMinimal(true); + ret.replace(imgs, QStringLiteral("")); + ret.replace(QStringLiteral(""), QStringLiteral("

")); + + return ret; +} diff --git a/generators/mobipocket/mobidocument.h b/generators/mobipocket/mobidocument.h new file mode 100644 index 0000000..f8eda7b --- /dev/null +++ b/generators/mobipocket/mobidocument.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2008 by Jakub Stachowski * + * * + * 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 MOBI_DOCUMENT_H +#define MOBI_DOCUMENT_H + +#include +#include +#include + +class QFile; +namespace Mobipocket +{ +class Document; +class QFileStream; +} + +namespace Mobi +{ +class MobiDocument : public QTextDocument +{ + Q_OBJECT + +public: + explicit MobiDocument(const QString &fileName); + ~MobiDocument() override; + + Mobipocket::Document *mobi() const + { + return doc; + } + +protected: + QVariant loadResource(int type, const QUrl &name) override; + +private: + QString fixMobiMarkup(const QString &data); + Mobipocket::Document *doc; + Mobipocket::QFileStream *file; +}; + +} +#endif diff --git a/generators/mobipocket/okularApplication_mobi.desktop b/generators/mobipocket/okularApplication_mobi.desktop new file mode 100755 index 0000000..0cefc5b --- /dev/null +++ b/generators/mobipocket/okularApplication_mobi.desktop @@ -0,0 +1,219 @@ +[Desktop Entry] +MimeType=application/x-mobipocket-ebook; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +TryExec=okular +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=1 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=mobipocket +X-KDE-Keywords[az]=mobipocket +X-KDE-Keywords[bg]=mobipocket +X-KDE-Keywords[bs]=mobipocket +X-KDE-Keywords[ca]=mobipocket +X-KDE-Keywords[ca@valencia]=mobipocket +X-KDE-Keywords[cs]=mobipocket +X-KDE-Keywords[da]=mobipocket +X-KDE-Keywords[de]=Mobipocket +X-KDE-Keywords[el]=mobipocket +X-KDE-Keywords[en_GB]=mobipocket +X-KDE-Keywords[es]=mobipocket +X-KDE-Keywords[et]=mobipocket +X-KDE-Keywords[eu]=Mobipocket +X-KDE-Keywords[fi]=mobipocket +X-KDE-Keywords[fr]=mobipocket +X-KDE-Keywords[gl]=mobipocket +X-KDE-Keywords[hu]=mobipocket +X-KDE-Keywords[ia]=mobipocket +X-KDE-Keywords[is]=mobipocket +X-KDE-Keywords[it]=mobipocket +X-KDE-Keywords[ja]=mobipocket +X-KDE-Keywords[kk]=mobipocket +X-KDE-Keywords[ko]=mobipocket +X-KDE-Keywords[lt]=mobipocket +X-KDE-Keywords[nb]=mobipocket +X-KDE-Keywords[nds]=Mobipocket +X-KDE-Keywords[nl]=mobipocket +X-KDE-Keywords[nn]=mobipocket +X-KDE-Keywords[pa]=mobipocket +X-KDE-Keywords[pl]=mobipocket +X-KDE-Keywords[pt]=mobipocket +X-KDE-Keywords[pt_BR]=mobipocket +X-KDE-Keywords[ru]=mobipocket +X-KDE-Keywords[sk]=mobipocket +X-KDE-Keywords[sl]=mobipocket,mobi +X-KDE-Keywords[sr]=mobipocket,Мобипокет +X-KDE-Keywords[sr@ijekavian]=mobipocket,Мобипокет +X-KDE-Keywords[sr@ijekavianlatin]=mobipocket,Mobipocket +X-KDE-Keywords[sr@latin]=mobipocket,Mobipocket +X-KDE-Keywords[sv]=mobipocket +X-KDE-Keywords[tr]=mobipocket +X-KDE-Keywords[uk]=mobipocket +X-KDE-Keywords[x-test]=xxmobipocketxx +X-KDE-Keywords[zh_CN]=mobipocket +X-KDE-Keywords[zh_TW]=mobipocket diff --git a/generators/mobipocket/okularMobi.desktop b/generators/mobipocket/okularMobi.desktop new file mode 100644 index 0000000..0a891b0 --- /dev/null +++ b/generators/mobipocket/okularMobi.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-mobipocket-ebook; diff --git a/generators/mobipocket/org.kde.mobile.okular_mobi.desktop b/generators/mobipocket/org.kde.mobile.okular_mobi.desktop new file mode 100755 index 0000000..036644b --- /dev/null +++ b/generators/mobipocket/org.kde.mobile.okular_mobi.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +MimeType=application/x-mobipocket-ebook; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true diff --git a/generators/mobipocket/org.kde.okular-mobipocket.metainfo.xml b/generators/mobipocket/org.kde.okular-mobipocket.metainfo.xml new file mode 100644 index 0000000..b64eccb --- /dev/null +++ b/generators/mobipocket/org.kde.okular-mobipocket.metainfo.xml @@ -0,0 +1,114 @@ + + + org.kde.okular-mobipocket + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + മൊബിപോക്കറ്റ്‌ + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Mobipocket + Мобипокет + Mobipocket + Мобипокет + Mobipocket + Mobipocket + Mobipocket + Mobipocket + xxMobipocketxx + Mobipocket + Mobipocket + Adds support for reading Mobipocket E-books + Mobipocket E-books sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir llibres electrònics Mobipocket + Afig la implementació per a llegir llibres electrònics Mobipocket + Přidává podporu pro čtení e-booků Mobipocket + Bietet Unterstützung zum Lesen von Mobipocket-E-Books + Προσθέτει υποστήριξη για την ανάνγωση Mobipocket E-Books + Adds support for reading Mobipocket E-books + Permite la lectura de libros electrónicos en formato Mobipocket + Mobipocketi e-raamatute lugemise toetus + Mobipocket e-liburuak irakurtzeko euskarria gehitzen du + Lisää MobiPocket-e-kirjojen lukutuen + Ajouter la gestion en lecture des livres électroniques Mobipocket + Engade a posibilidade de ler libros electrónicos Mobipocket + Adde supporto per leger E-libros in Mobipocket + Aggiunge il supporto per la lettura di libri digitali in formato Mobipocket + Mobipocket 전자책 읽기 지원 추가 + Prideda palaikymą Mobipocket elektroninių knygų skaitymui + മൊബിപോക്കറ്റ്‌ ഈ-ബുക്കുകൾ വായിക്കുന്നതിനുള്ള പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van Mobipocket e-boeken toe + Legg til støtte for å lesa e-bøker i Mobipocket-formatet + Dodaje obsługę formatu Mobipocket + Adiciona o suporte para ler E-books da Mobipocket + Adiciona o suporte para leitura de E-books da Mobipocket + Поддержка чтения электронных книг Mobipocket + Pridá podporu pre čítanie e-kníh Mobipocket + Doda podporo za branje e-knjig Mobipocket + Подршка за читање мобипокет е‑књига + Podrška za čitanje Mobipocket e‑knjiga + Подршка за читање мобипокет е‑књига + Podrška za čitanje Mobipocket e‑knjiga + Lägger till stöd för att läsa Mobipocket e-böcker + Mobipocket E-kitaplarını okuma desteği ekler + Додає підтримку читання електронних книг у форматі Mobipocket + xxAdds support for reading Mobipocket E-booksxx + 增加对 Mobipocket 电子书的支持 + 加入讀取 Mobipocket 電子書的支援 + + image/bmp + image/x-dds + image/x-eps + image/x-exr + image/gif + image/x-hdr + image/x-ico + image/jp2 + image/jpeg + video/x-mng + image/x-portable-bitmap + image/x-pcx + image/x-portable-graymap + image/png + image/x-portable-pixmap + image/x-psd + image/x-rgb + image/x-tga + image/tiff + image/x-xbitmap + image/x-xcf + image/x-xpixmap + image/x-gzeps + image/x-bzeps + + https://okular.kde.org + + + + + + + diff --git a/generators/plucker/CMakeLists.txt b/generators/plucker/CMakeLists.txt new file mode 100644 index 0000000..0852100 --- /dev/null +++ b/generators/plucker/CMakeLists.txt @@ -0,0 +1,32 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_plucker") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../generators/plucker/unpluck + ${JPEG_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} +) + +set(qunpluck_SRCS + unpluck/config.cpp + unpluck/image.cpp + unpluck/qunpluck.cpp + unpluck/unpluck.cpp + unpluck/util.cpp +) + +########### next target ############### + +set(okularGenerator_plucker_SRCS + generator_plucker.cpp +) + +okular_add_generator(okularGenerator_plucker ${okularGenerator_plucker_SRCS} ${qunpluck_SRCS}) + +target_link_libraries(okularGenerator_plucker okularcore KF5::KIOCore KF5::I18n ${MATH_LIB} ${JPEG_LIBRARY} ${ZLIB_LIBRARY}) + +########### install files ############### +install( FILES okularPlucker.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_plucker.desktop org.kde.mobile.okular_plucker.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-plucker.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/plucker/Messages.sh b/generators/plucker/Messages.sh new file mode 100644 index 0000000..ca538c8 --- /dev/null +++ b/generators/plucker/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_plucker.pot diff --git a/generators/plucker/generator_plucker.cpp b/generators/plucker/generator_plucker.cpp new file mode 100644 index 0000000..f130e2a --- /dev/null +++ b/generators/plucker/generator_plucker.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "generator_plucker.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include + +OKULAR_EXPORT_PLUGIN(PluckerGenerator, "libokularGenerator_plucker.json") + +static void calculateBoundingRect(QTextDocument *document, int startPosition, int endPosition, QRectF &rect) +{ + const QTextBlock startBlock = document->findBlock(startPosition); + const QRectF startBoundingRect = document->documentLayout()->blockBoundingRect(startBlock); + + const QTextBlock endBlock = document->findBlock(endPosition); + const QRectF endBoundingRect = document->documentLayout()->blockBoundingRect(endBlock); + + QTextLayout *startLayout = startBlock.layout(); + QTextLayout *endLayout = endBlock.layout(); + + int startPos = startPosition - startBlock.position(); + int endPos = endPosition - endBlock.position(); + const QTextLine startLine = startLayout->lineForTextPosition(startPos); + const QTextLine endLine = endLayout->lineForTextPosition(endPos); + + double x = startBoundingRect.x() + startLine.cursorToX(startPos); + double y = startBoundingRect.y() + startLine.y(); + double r = endBoundingRect.x() + endLine.cursorToX(endPos); + double b = endBoundingRect.y() + endLine.y() + endLine.height(); + + const QSizeF size = document->size(); + rect = QRectF(x / size.width(), y / size.height(), (r - x) / size.width(), (b - y) / size.height()); +} + +PluckerGenerator::PluckerGenerator(QObject *parent, const QVariantList &args) + : Generator(parent, args) +{ +} + +PluckerGenerator::~PluckerGenerator() +{ +} + +bool PluckerGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + QUnpluck unpluck; + + if (!unpluck.open(fileName)) + return false; + + mPages = unpluck.pages(); + mLinks = unpluck.links(); + + const QMap infos = unpluck.infos(); + QMapIterator it(infos); + while (it.hasNext()) { + it.next(); + if (!it.value().isEmpty()) { + if (it.key() == QLatin1String("name")) + mDocumentInfo.set(QStringLiteral("name"), it.value(), i18n("Name")); + else if (it.key() == QLatin1String("title")) + mDocumentInfo.set(Okular::DocumentInfo::Title, it.value()); + else if (it.key() == QLatin1String("author")) + mDocumentInfo.set(Okular::DocumentInfo::Author, it.value()); + else if (it.key() == QLatin1String("time")) + mDocumentInfo.set(Okular::DocumentInfo::CreationDate, it.value()); + } + } + + pagesVector.resize(mPages.count()); + + for (int i = 0; i < mPages.count(); ++i) { + QSizeF size = mPages[i]->size(); + Okular::Page *page = new Okular::Page(i, size.width(), size.height(), Okular::Rotation0); + pagesVector[i] = page; + } + + return true; +} + +bool PluckerGenerator::doCloseDocument() +{ + mLinkAdded.clear(); + mLinks.clear(); + + qDeleteAll(mPages); + mPages.clear(); + + // do not use clear() for the following, otherwise its type is changed + mDocumentInfo = Okular::DocumentInfo(); + + return true; +} + +Okular::DocumentInfo PluckerGenerator::generateDocumentInfo(const QSet & /*keys*/) const +{ + return mDocumentInfo; +} + +QImage PluckerGenerator::image(Okular::PixmapRequest *request) +{ + const QSizeF size = mPages[request->pageNumber()]->size(); + + QImage image(request->width(), request->height(), QImage::Format_ARGB32_Premultiplied); + image.fill(Qt::white); + + QPainter p; + p.begin(&image); + + qreal width = request->width(); + qreal height = request->height(); + + p.scale(width / (qreal)size.width(), height / (qreal)size.height()); + mPages[request->pageNumber()]->drawContents(&p); + p.end(); + + if (!mLinkAdded.contains(request->pageNumber())) { + QLinkedList objects; + for (int i = 0; i < mLinks.count(); ++i) { + if (mLinks[i].page == request->pageNumber()) { + QTextDocument *document = mPages[request->pageNumber()]; + + QRectF rect; + calculateBoundingRect(document, mLinks[i].start, mLinks[i].end, rect); + + objects.append(new Okular::ObjectRect(rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, mLinks[i].link)); + } + } + + if (!objects.isEmpty()) + request->page()->setObjectRects(objects); + + mLinkAdded.insert(request->pageNumber()); + } + + return image; +} + +Okular::ExportFormat::List PluckerGenerator::exportFormats() const +{ + static Okular::ExportFormat::List formats; + if (formats.isEmpty()) + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText)); + + return formats; +} + +bool PluckerGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format) +{ + if (format.mimeType().name() == QLatin1String("text/plain")) { + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + return false; + + QTextStream out(&file); + for (int i = 0; i < mPages.count(); ++i) { + out << mPages[i]->toPlainText(); + } + + return true; + } + + return false; +} + +bool PluckerGenerator::print(QPrinter &) +{ + /* + for ( int i = 0; i < mPages.count(); ++i ) + mPages[ i ]->print( &printer ); + */ + return true; +} + +#include "generator_plucker.moc" diff --git a/generators/plucker/generator_plucker.h b/generators/plucker/generator_plucker.h new file mode 100644 index 0000000..69aecdc --- /dev/null +++ b/generators/plucker/generator_plucker.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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_GENERATOR_PLUCKER_H_ +#define _OKULAR_GENERATOR_PLUCKER_H_ + +#include +#include + +#include + +#include "qunpluck.h" + +class QTextDocument; + +class PluckerGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + PluckerGenerator(QObject *parent, const QVariantList &args); + ~PluckerGenerator() override; + + // [INHERITED] load a document and fill up the pagesVector + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + // [INHERITED] document information + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + + // [INHERITED] perform actions on document / pages + QImage image(Okular::PixmapRequest *request) override; + + // [INHERITED] text exporting + Okular::ExportFormat::List exportFormats() const override; + bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override; + + // [INHERITED] print document using already configured kprinter + bool print(QPrinter &printer) override; + +protected: + bool doCloseDocument() override; + +private: + QList mPages; + QSet mLinkAdded; + Link::List mLinks; + Okular::DocumentInfo mDocumentInfo; +}; + +#endif diff --git a/generators/plucker/libokularGenerator_plucker.json b/generators/plucker/libokularGenerator_plucker.json new file mode 100644 index 0000000..b2fc48b --- /dev/null +++ b/generators/plucker/libokularGenerator_plucker.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "tokoe@kde.org", + "Name": "Tobias Koenig", + "Name[az]": "Tobias Koenig", + "Name[ca@valencia]": "Tobias Koenig", + "Name[ca]": "Tobias Koenig", + "Name[cs]": "Tobias Koenig", + "Name[da]": "Tobias Koenig", + "Name[de]": "Tobias Koenig", + "Name[el]": "Tobias Koenig", + "Name[en_GB]": "Tobias Koenig", + "Name[es]": "Tobias Koenig", + "Name[et]": "Tobias Koenig", + "Name[eu]": "Tobias Koenig", + "Name[fi]": "Tobias Koenig", + "Name[fr]": "Tobias Koenig", + "Name[gl]": "Tobias Koenig", + "Name[ia]": "Tobias Koenig", + "Name[it]": "Tobias Koenig", + "Name[ko]": "Tobias Koenig", + "Name[lt]": "Tobias Koenig", + "Name[nl]": "Tobias Koenig", + "Name[nn]": "Tobias König", + "Name[pl]": "Tobias Koenig", + "Name[pt]": "Tobias Koenig", + "Name[pt_BR]": "Tobias Koenig", + "Name[ru]": "Tobias König", + "Name[sk]": "Tobias Koenig", + "Name[sl]": "Tobias Koenig", + "Name[sr@ijekavian]": "Тобијас Кениг", + "Name[sr@ijekavianlatin]": "Tobijas Kenig", + "Name[sr@latin]": "Tobijas Kenig", + "Name[sr]": "Тобијас Кениг", + "Name[sv]": "Tobias Koenig", + "Name[tr]": "Tobias Koenig", + "Name[uk]": "Tobias Koenig", + "Name[x-test]": "xxTobias Koenigxx", + "Name[zh_CN]": "Tobias Koenig", + "Name[zh_TW]": "Tobias Koenig" + } + ], + "Copyright": "© 2007-2008 Tobias Koenig", + "Copyright[az]": "© 2007-2008 Tobias Koenig", + "Copyright[ca@valencia]": "© 2007-2008 Tobias Koenig", + "Copyright[ca]": "© 2007-2008 Tobias Koenig", + "Copyright[cs]": "© 2007-2008 Tobias Koenig", + "Copyright[da]": "© 2007-2008 Tobias Koenig", + "Copyright[de]": "© 2007-2008 Tobias Koenig", + "Copyright[el]": "© 2007-2008 Tobias Koenig", + "Copyright[en_GB]": "© 2007-2008 Tobias Koenig", + "Copyright[es]": "© 2007-2008 Tobias Koenig", + "Copyright[et]": "© 2007-2008: Tobias Koenig", + "Copyright[eu]": "© 2007-2008 Tobias Koenig", + "Copyright[fi]": "© 2007–2008 Tobias Koenig", + "Copyright[fr]": "© 2007-2008 Tobias Koenig", + "Copyright[gl]": "© 2007-2008 Tobias Koenig", + "Copyright[ia]": "© 2007-2008 Tobias Koenig", + "Copyright[it]": "© 2007-2008 Tobias Koenig", + "Copyright[ko]": "© 2007-2008 Tobias Koenig", + "Copyright[lt]": "© 2007-2008 Tobias Koenig", + "Copyright[nl]": "© 2007-2008 Tobias Koenig", + "Copyright[nn]": "© 2007–2008 Tobias König", + "Copyright[pl]": "© 2007-2008 Tobias Koenig", + "Copyright[pt]": "© 2007-2008 Tobias Koenig", + "Copyright[pt_BR]": "© 2007-2008 Tobias Koenig", + "Copyright[ru]": "© Tobias König, 2007-2008", + "Copyright[sk]": "© 2007-2008 Tobias Koenig", + "Copyright[sl]": "© 2007-2008 Tobias Koenig", + "Copyright[sr@ijekavian]": "© 2007–2008, Тобијас Кениг", + "Copyright[sr@ijekavianlatin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr@latin]": "© 2007–2008, Tobijas Kenig", + "Copyright[sr]": "© 2007–2008, Тобијас Кениг", + "Copyright[sv]": "© 2007-2008 Tobias Koenig", + "Copyright[tr]": "© 2007-2008 Tobias Koenig", + "Copyright[uk]": "© Tobias Koenig, 2007–2008", + "Copyright[x-test]": "xx© 2007-2008 Tobias Koenigxx", + "Copyright[zh_CN]": "© 2007-2008 Tobias Koenig", + "Copyright[zh_TW]": "© 2007-2008 Tobias Koenig", + "Description": "A renderer for Plucker eBooks", + "Description[az]": "Plucker eBooks üçün təsvirləmə", + "Description[ca@valencia]": "Un renderitzador per a llibres electrònics Plucker", + "Description[ca]": "Un renderitzador per a llibres electrònics Plucker", + "Description[cs]": "Renderer elektronických knih Plucker", + "Description[da]": "En gengiver til Plucker-e-bøger", + "Description[de]": "Ein Renderer für Plucker eBooks", + "Description[el]": "Πρόγραμμα αποτύπωσης για Plucker eBooks", + "Description[en_GB]": "A renderer for Plucker eBooks", + "Description[es]": "Un visor de libros electrónicos Plucker", + "Description[et]": "Pluckeri e-raamatute renderdaja", + "Description[eu]": "Plucker eLiburuentzako errendatzaile bat", + "Description[fi]": "Plucker-e-kirjojen hahmonnin", + "Description[fr]": "Système de rendu pour les livres électroniques Plucker", + "Description[gl]": "Un visor de libros electrónicos Plucker", + "Description[ia]": "Un rendition pro eBooks (Libros electronic) de Plucker", + "Description[it]": "Un visualizzatore per eBook Plucker", + "Description[ko]": "Plucker 전자책 렌더러", + "Description[lt]": "Plucker elektroninių knygų atvaizdavimas", + "Description[nl]": "Een viewer voor Plucker eBooks", + "Description[nn]": "Ein gjengjevar for Plucker-e-bøker", + "Description[pl]": "Wyświetlanie e-booków Plucker", + "Description[pt]": "Um visualizador de eBooks do Plucker", + "Description[pt_BR]": "Um interpretador de eBooks Plucker", + "Description[ru]": "Модуль поддержки формата электронных книг Plucker", + "Description[sk]": "Vykresľovanie e-kníh Plucker", + "Description[sl]": "Izrisovalnik za e-knjige Plucker", + "Description[sr@ijekavian]": "Рендерер за Плакерове е‑књиге", + "Description[sr@ijekavianlatin]": "Renderer za Pluckerove e‑knjige", + "Description[sr@latin]": "Renderer za Pluckerove e‑knjige", + "Description[sr]": "Рендерер за Плакерове е‑књиге", + "Description[sv]": "Ett återgivningsprogram för Plucker e-böcker", + "Description[tr]": "Plucker e-kitapları için bir oluşturucu", + "Description[uk]": "Програма для відображення ел. книг Plucker", + "Description[x-test]": "xxA renderer for Plucker eBooksxx", + "Description[zh_CN]": "Plucker 电子书渲染器", + "Description[zh_TW]": "Plucker 電子書成像器", + "Id": "okular_plucker", + "License": "GPL", + "MimeTypes": [ + "application/prs.plucker" + ], + "Name": "Plucker Document Backend", + "Name[az]": "Plucker sənədi modulu", + "Name[ca@valencia]": "Dorsal per a documents Plucker", + "Name[ca]": "Dorsal per a documents Plucker", + "Name[cs]": "Podpůrná vrstva Plucker Dokumentu", + "Name[da]": "Plucker-dokument-backend", + "Name[de]": "Anzeigemodul für Plucker-Dokumente", + "Name[el]": "Σύστημα υποστήριξης εγγράφων Plucker", + "Name[en_GB]": "Plucker Document Backend", + "Name[es]": "Motor para documento de Plucker", + "Name[et]": "Pluckeri dokumendi taustaprogramm", + "Name[eu]": "Plucker dokumentuen bizkarraldekoa", + "Name[fi]": "Plucker-tiedostotaustaosa", + "Name[fr]": "Moteur de document Plucker", + "Name[gl]": "Infraestrutura para documentos Plucker", + "Name[ia]": "Un retro-administration de documento Plucker", + "Name[it]": "Backend per documenti Plucker", + "Name[ko]": "Plucker 문서 백엔드", + "Name[lt]": "Plucker dokumentų programinė sąsaja", + "Name[nl]": "Plucker Document-backend", + "Name[nn]": "Plucker-dokumentmotor", + "Name[pl]": "Obsługa Plucker", + "Name[pt]": "Infra-Estrutura de Documentos do Plucker", + "Name[pt_BR]": "Infraestrutura de documentos Plucker", + "Name[ru]": "Модуль поддержки формата Plucker", + "Name[sk]": "Backend dokumentov Plucker", + "Name[sl]": "Zaledje za dokumente Plucker", + "Name[sr@ijekavian]": "Позадина за Плакерови документе", + "Name[sr@ijekavianlatin]": "Pozadina za Pluckerovi dokumente", + "Name[sr@latin]": "Pozadina za Pluckerovi dokumente", + "Name[sr]": "Позадина за Плакерови документе", + "Name[sv]": "Plucker-dokumentgränssnitt", + "Name[tr]": "Plucker Belgesi Arka Ucu", + "Name[uk]": "Модуль документів Plucker", + "Name[x-test]": "xxPlucker Document Backendxx", + "Name[zh_CN]": "Plucker 文档后端", + "Name[zh_TW]": "Pluker 文件後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.1" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/plucker/okularApplication_plucker.desktop b/generators/plucker/okularApplication_plucker.desktop new file mode 100755 index 0000000..6a923a8 --- /dev/null +++ b/generators/plucker/okularApplication_plucker.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/prs.plucker; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=plucker +X-KDE-Keywords[ar]=plucker +X-KDE-Keywords[az]=plucker +X-KDE-Keywords[bg]=plucker +X-KDE-Keywords[bs]=plucker +X-KDE-Keywords[ca]=plucker +X-KDE-Keywords[ca@valencia]=plucker +X-KDE-Keywords[cs]=plucker +X-KDE-Keywords[da]=plucker +X-KDE-Keywords[de]=plucker +X-KDE-Keywords[el]=plucker +X-KDE-Keywords[en_GB]=plucker +X-KDE-Keywords[es]=plucker +X-KDE-Keywords[et]=plucker +X-KDE-Keywords[eu]=plucker +X-KDE-Keywords[fi]=plucker +X-KDE-Keywords[fr]=plucker +X-KDE-Keywords[ga]=plucker +X-KDE-Keywords[gl]=plucker +X-KDE-Keywords[hu]=plucker +X-KDE-Keywords[ia]=plucker +X-KDE-Keywords[is]=plucker +X-KDE-Keywords[it]=plucker +X-KDE-Keywords[ja]=plucker +X-KDE-Keywords[kk]=plucker +X-KDE-Keywords[km]=plucker +X-KDE-Keywords[ko]=plucker +X-KDE-Keywords[lt]=plucker +X-KDE-Keywords[lv]=plucker +X-KDE-Keywords[mr]=प्लकर +X-KDE-Keywords[nb]=plucker +X-KDE-Keywords[nds]=Plucker +X-KDE-Keywords[nl]=plucker +X-KDE-Keywords[nn]=plucker +X-KDE-Keywords[pa]=ਪਲੱਕਰ +X-KDE-Keywords[pl]=plucker +X-KDE-Keywords[pt]=plucker +X-KDE-Keywords[pt_BR]=plucker +X-KDE-Keywords[ro]=plucker +X-KDE-Keywords[ru]=plucker +X-KDE-Keywords[sk]=plucker +X-KDE-Keywords[sl]=plucker +X-KDE-Keywords[sr]=plucker,Плакер +X-KDE-Keywords[sr@ijekavian]=plucker,Плакер +X-KDE-Keywords[sr@ijekavianlatin]=plucker,Plucker +X-KDE-Keywords[sr@latin]=plucker,Plucker +X-KDE-Keywords[sv]=plucker +X-KDE-Keywords[tr]=plucker +X-KDE-Keywords[uk]=plucker +X-KDE-Keywords[x-test]=xxpluckerxx +X-KDE-Keywords[zh_CN]=plucker +X-KDE-Keywords[zh_TW]=plucker diff --git a/generators/plucker/okularPlucker.desktop b/generators/plucker/okularPlucker.desktop new file mode 100644 index 0000000..9feb193 --- /dev/null +++ b/generators/plucker/okularPlucker.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/prs.plucker; diff --git a/generators/plucker/org.kde.mobile.okular_plucker.desktop b/generators/plucker/org.kde.mobile.okular_plucker.desktop new file mode 100644 index 0000000..0fa23ba --- /dev/null +++ b/generators/plucker/org.kde.mobile.okular_plucker.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +MimeType=application/prs.plucker; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=plucker +X-KDE-Keywords[ar]=plucker +X-KDE-Keywords[az]=plucker +X-KDE-Keywords[bg]=plucker +X-KDE-Keywords[bs]=plucker +X-KDE-Keywords[ca]=plucker +X-KDE-Keywords[ca@valencia]=plucker +X-KDE-Keywords[cs]=plucker +X-KDE-Keywords[da]=plucker +X-KDE-Keywords[de]=plucker +X-KDE-Keywords[el]=plucker +X-KDE-Keywords[en_GB]=plucker +X-KDE-Keywords[es]=plucker +X-KDE-Keywords[et]=plucker +X-KDE-Keywords[eu]=plucker +X-KDE-Keywords[fi]=plucker +X-KDE-Keywords[fr]=plucker +X-KDE-Keywords[ga]=plucker +X-KDE-Keywords[gl]=plucker +X-KDE-Keywords[hu]=plucker +X-KDE-Keywords[ia]=plucker +X-KDE-Keywords[is]=plucker +X-KDE-Keywords[it]=plucker +X-KDE-Keywords[ja]=plucker +X-KDE-Keywords[kk]=plucker +X-KDE-Keywords[km]=plucker +X-KDE-Keywords[ko]=plucker +X-KDE-Keywords[lt]=plucker +X-KDE-Keywords[lv]=plucker +X-KDE-Keywords[mr]=प्लकर +X-KDE-Keywords[nb]=plucker +X-KDE-Keywords[nds]=Plucker +X-KDE-Keywords[nl]=plucker +X-KDE-Keywords[nn]=plucker +X-KDE-Keywords[pa]=ਪਲੱਕਰ +X-KDE-Keywords[pl]=plucker +X-KDE-Keywords[pt]=plucker +X-KDE-Keywords[pt_BR]=plucker +X-KDE-Keywords[ro]=plucker +X-KDE-Keywords[ru]=plucker +X-KDE-Keywords[sk]=plucker +X-KDE-Keywords[sl]=plucker +X-KDE-Keywords[sr]=plucker,Плакер +X-KDE-Keywords[sr@ijekavian]=plucker,Плакер +X-KDE-Keywords[sr@ijekavianlatin]=plucker,Plucker +X-KDE-Keywords[sr@latin]=plucker,Plucker +X-KDE-Keywords[sv]=plucker +X-KDE-Keywords[tr]=plucker +X-KDE-Keywords[uk]=plucker +X-KDE-Keywords[x-test]=xxpluckerxx +X-KDE-Keywords[zh_CN]=plucker +X-KDE-Keywords[zh_TW]=plucker diff --git a/generators/plucker/org.kde.okular-plucker.metainfo.xml b/generators/plucker/org.kde.okular-plucker.metainfo.xml new file mode 100644 index 0000000..9196bb3 --- /dev/null +++ b/generators/plucker/org.kde.okular-plucker.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-plucker + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + plucker + Plucker + പ്ലക്കർ + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Plucker + Плакер + Plucker + Плакер + Plucker + Plucker + Plucker + Plucker + xxPluckerxx + Plucker + Plucker + Adds support for reading Plucker documents + Plucker sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents Plucker + Afig la implementació per a llegir documents Plucker + Přidává podporu pro čtení dokumentů Plucker + Bietet Unterstützung zum Lesen von Plucker-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων Plucker + Adds support for reading Plucker documents + Permite la lectura de documentos en formato Plucker + Pluckeri dokumentide lugemise toetus + Plucker dokumentuak irakurtzeko euskarria gehitzen du + Lisää Plucker-tiedostojen lukutuen + Permet la lecture des documents Plucker + Engade a posibilidade de ler documentos de Plucker + Adde supporto per leger documentos Plucker + Aggiunge il supporto per la lettura di documenti Plucker + Plucker 문서 읽기 지원 추가 + Prideda palaikymą Plucker dokumentų skaitymui + പ്ലക്കർ പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van Plucker-documenten toe + Legg til støtte for å lesa Plucker-dokument + Dodaje obsługę dokumentów Plucker + Adiciona o suporte para ler documentos do Plucker + Adiciona o suporte para leitura de documentos do Plucker + Поддержка чтения документов Plucker + Pridá podporu pre čítanie dokumentov Plucker + Doda podporo za branje dokumentov Plucker + Подршка за читање плакер докумената + Podrška za čitanje Plucker dokumenata + Подршка за читање плакер докумената + Podrška za čitanje Plucker dokumenata + Lägger till stöd för att läsa Plucker-dokument + Plucker belgelerini okuma desteği ekler + Додає підтримку читання документів Plucker + xxAdds support for reading Plucker documentsxx + 增加对 Plucker 文档的阅读支持 + 加入讀取 Plucker 文件的支援 + + application/prs.plucker + + https://okular.kde.org + + + + + + + diff --git a/generators/plucker/unpluck/config.cpp b/generators/plucker/unpluck/config.cpp new file mode 100644 index 0000000..e693504 --- /dev/null +++ b/generators/plucker/unpluck/config.cpp @@ -0,0 +1,326 @@ +/* -*- mode: c; indent-tabs-mode: nil; -*- + * $Id: config.c,v 1.3 2003/12/28 20:59:21 chrish Exp $ + * + * config -- read and parse the Plucker config files + * Copyright (c) 2002, Bill Janssen + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if !defined(WIN32) +#include /* for lseek, etc. */ +#else +#include +#endif +#include +#include +#include + +#include /* for assert() */ +#include /* for errno */ +#include /* for O_RDONLY */ +#include /* for strndup() */ +#include /* for fstat() */ +#include + +#include "unpluck.h" +#include "unpluckint.h" + +#define STRINGIFY(s) STRINGIFY2(s) +#define STRINGIFY2(s) #s + +#define MAX_LINE_SIZE 1023 + +#define COMMENT_CHARS "#;" +#define SEGMENT_LEAD_CHAR '[' +#define SEGMENT_END_CHAR ']' +#define OPTION_SEPARATOR_CHARS "=:" + +HashTable *SectionsTable = nullptr; + +static HashTable *GetOrCreateSegment(const char *name) +{ + HashTable *target; + + if (SectionsTable == nullptr) + SectionsTable = _plkr_NewHashTable(23); + + if ((target = (HashTable *)_plkr_FindInTable(SectionsTable, name)) == nullptr) { + target = _plkr_NewHashTable(53); + _plkr_AddToTable(SectionsTable, name, target); + } + + return target; +} + +static int ReadConfigFile(const char *filename) +{ + HashTable *current_segment = nullptr; + FILE *fp = fopen(filename, "r"); + char *ptr; + char *str_end; + char *str_begin; + char *charptr; + char *current_option; + char *option_value; + char linebuf[MAX_LINE_SIZE + 1]; + int linelen; + int len2; + int buf_index; + int status; + int line_number; + + if (fp == nullptr) { + _plkr_message("Can't open config file %s", filename); + return 0; + } + + current_segment = GetOrCreateSegment("default"); + current_option = nullptr; + + status = 1; /* optimistic */ + line_number = 0; + + while (true) { + ptr = fgets(linebuf, sizeof(linebuf) - 1, fp); + if (ptr == nullptr) + break; + + line_number += 1; + linebuf[strlen(linebuf) - 1] = 0; /* strip newline */ + if (linebuf[strlen(linebuf) - 1] == '\r') + linebuf[strlen(linebuf) - 1] = 0; /* strip carriage return */ + + /* fprintf (stderr, "%s:%d: line is '%s'\n", filename, line_number, linebuf); */ + + linelen = strlen(linebuf); + for (buf_index = 0; linebuf[buf_index] != 0; buf_index++) + if (!isspace(linebuf[buf_index])) + break; + + if (linebuf[buf_index] == 0) + /* blank line */ + continue; + + if ((strchr(COMMENT_CHARS, linebuf[0]) != nullptr) || (strncmp(linebuf, "rem", 3) == 0) || (strncmp(linebuf, "REM", 3) == 0)) + /* comment */ + continue; + + /* At this point we have a valid thing */ + + if (linebuf[buf_index] == SEGMENT_LEAD_CHAR) { + if ((str_end = strchr(linebuf + buf_index + 1, SEGMENT_END_CHAR)) == nullptr) { + /* invalid segment line */ + _plkr_message("%s:%d: Invalid segment line '%s'", filename, line_number, linebuf); + goto error_exit; + } + str_begin = linebuf + buf_index + 1; + for (charptr = str_begin; charptr < str_end; charptr++) + *charptr = tolower(*charptr); + *str_end = 0; + current_segment = GetOrCreateSegment(str_begin); + /* fprintf (stderr, "Current segment is now %p (%s)\n", current_segment, str_begin); */ + if (current_option) + free(current_option); + current_option = nullptr; + + } else if ((linebuf[0] == ' ' || linebuf[0] == '\t') && current_option != nullptr) { + /* continuation line */ + str_begin = (char *)_plkr_RemoveFromTable(current_segment, current_option); + for (str_end = linebuf + strlen(linebuf) - 1; str_end > linebuf && isspace(*str_end); str_end--) + ; + charptr = (char *)malloc(strlen(str_begin) + (str_end - (linebuf + buf_index)) + 2); + strcpy(charptr, str_begin); + len2 = strlen(charptr); + charptr[len2] = '\n'; + strncpy(charptr + len2 + 1, linebuf + buf_index, str_end - (linebuf + buf_index)); + charptr[len2 + (str_end - (linebuf + buf_index)) + 1] = '\0'; + _plkr_AddToTable(current_segment, current_option, charptr); + free(str_begin); + + } else if ((int)strcspn(linebuf, OPTION_SEPARATOR_CHARS) < linelen) { + /* possible option line */ + + for (str_begin = linebuf + buf_index, ptr = str_begin; isalnum(*ptr) || (*ptr == '.') || (*ptr == '_') || (*ptr == '-'); ptr++) + ; + if (ptr == str_begin) { + _plkr_message("%s:%d: Invalid option line '%s'", filename, line_number, linebuf); + goto error_exit; + } + + for (charptr = str_begin; charptr < ptr; charptr++) + *charptr = tolower(*charptr); + str_end = ptr; + + while (isspace(*ptr) && (*ptr != '\0')) + ptr++; + + if (strchr(OPTION_SEPARATOR_CHARS, *ptr) != nullptr) + ptr++; + else { + _plkr_message("%s:%d: Invalid option line '%s'", filename, line_number, linebuf); + goto error_exit; + } + + while (isspace(*ptr) && (*ptr != '\0')) + ptr++; + + if (*ptr == 0) { + _plkr_message("%s:%d: Invalid option line '%s'", filename, line_number, linebuf); + goto error_exit; + } + + if (current_option) + free(current_option); + current_option = _plkr_strndup(str_begin, str_end - str_begin); + + option_value = _plkr_strndup(ptr, strlen(ptr)); + + ptr = (char *)_plkr_RemoveFromTable(current_segment, current_option); + if (ptr) + free(ptr); + _plkr_AddToTable(current_segment, current_option, option_value); + /* fprintf (stderr, "Added value '%s' for option '%p:%s'\n", option_value, current_segment, current_option); */ + + } else { + _plkr_message("%s:%d: Bad line '%s'", filename, line_number, linebuf); + goto error_exit; + } + } + +good_exit: + + if (current_option) + free(current_option); + fclose(fp); + return status; + +error_exit: + status = 0; + goto good_exit; +} + +static void TryReadConfigFile(const char *dir, const char *name) +{ + char *filename; + + if (dir == nullptr || name == nullptr) + return; + + filename = (char *)malloc(strlen(dir) + strlen(name) + 2); + strcpy(filename, dir); + strcpy(filename + strlen(filename), STRINGIFY(FILE_SEPARATOR_CHAR_S)); + strcpy(filename + strlen(filename), name); + if (!ReadConfigFile(filename)) + _plkr_message("Error reading config file %s", filename); + free(filename); +} + +static void InitializeConfigInfo() +{ + const char *config_dir = STRINGIFY(PLUCKER_CONFIG_DIR); + const char *system_config_file_name = STRINGIFY(SYS_CONFIG_FILE_NAME); + const char *user_config_filename = STRINGIFY(USER_CONFIG_FILE_NAME); + char *home = getenv("HOME"); // clazy:exclude=raw-environment-function + + TryReadConfigFile(config_dir, system_config_file_name); + if (home != nullptr) + TryReadConfigFile(home, user_config_filename); +} + +char *plkr_GetConfigString(const char *section_name, const char *option_name, char *default_value) +{ + char *value = nullptr; + HashTable *section; + + if (SectionsTable == nullptr) + InitializeConfigInfo(); + + if (SectionsTable == nullptr) + return default_value; + + if (section_name != nullptr) { + if ((section = (HashTable *)_plkr_FindInTable(SectionsTable, section_name)) != nullptr) + value = (char *)_plkr_FindInTable(section, option_name); + } + if (value == nullptr && ((section_name == nullptr) || (strcmp(section_name, "default") != 0))) { + if ((section = (HashTable *)_plkr_FindInTable(SectionsTable, STRINGIFY(OS_SECTION_NAME))) != nullptr) + value = (char *)_plkr_FindInTable(section, option_name); + } + if (value == nullptr && ((section_name == nullptr) || (strcmp(section_name, "default") != 0))) { + if ((section = (HashTable *)_plkr_FindInTable(SectionsTable, "default")) != nullptr) + value = (char *)_plkr_FindInTable(section, option_name); + } + + return ((value == nullptr) ? default_value : value); +} + +long int plkr_GetConfigInt(const char *section_name, const char *option_name, long int default_value) +{ + char *svalue = plkr_GetConfigString(section_name, option_name, nullptr); + char *endptr; + long int value; + + if (svalue == nullptr) + return default_value; + + value = strtol(svalue, &endptr, 0); + if (*endptr != 0) { + _plkr_message("Bad int value string '%s' for option %s:%s", svalue, (section_name ? section_name : "default"), option_name); + return default_value; + } else { + return value; + } +} + +double plkr_GetConfigFloat(const char *section_name, const char *option_name, double default_value) +{ + char *svalue = plkr_GetConfigString(section_name, option_name, nullptr); + char *endptr; + double value; + + if (svalue == nullptr) + return default_value; + + value = strtod(svalue, &endptr); + if (*endptr != 0) { + _plkr_message("Bad float value string '%s' for option %s:%s", svalue, (section_name ? section_name : "default"), option_name); + return default_value; + } else { + return value; + } +} + +int plkr_GetConfigBoolean(const char *section_name, const char *option_name, int default_value) +{ + char *svalue = plkr_GetConfigString(section_name, option_name, nullptr); + + if (svalue == nullptr) + return default_value; + + if ((strcmp(svalue, "1") == 0) || (strcmp(svalue, "true") == 0) || (strcmp(svalue, "TRUE") == 0) || (strcmp(svalue, "on") == 0) || (strcmp(svalue, "ON") == 0) || (strcmp(svalue, "t") == 0) || (strcmp(svalue, "T") == 0) || + (strcmp(svalue, "True") == 0)) + return 1; + + else if ((strcmp(svalue, "0") == 0) || (strcmp(svalue, "false") == 0) || (strcmp(svalue, "FALSE") == 0) || (strcmp(svalue, "off") == 0) || (strcmp(svalue, "OFF") == 0) || (strcmp(svalue, "F") == 0) || (strcmp(svalue, "f") == 0) || + (strcmp(svalue, "False") == 0)) + return 0; + + else { + _plkr_message("Bad boolean value string '%s' for option %s:%s", svalue, (section_name ? section_name : "default"), option_name); + return default_value; + } +} diff --git a/generators/plucker/unpluck/image.cpp b/generators/plucker/unpluck/image.cpp new file mode 100644 index 0000000..fd4bb26 --- /dev/null +++ b/generators/plucker/unpluck/image.cpp @@ -0,0 +1,469 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * Based on code written by Bill Janssen 2002 * + * * + * 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. * + ***************************************************************************/ + +#include +#include + +#include +#include + +/* This code requires the Independent JPEG Group libjpeg library, version 6b or later */ +extern "C" { +#include "jpeglib.h" +} + +#include "image.h" + +#define GET_FUNCTION_CODE_TYPE(x) (((x) >> 3) & 0x1F) +#define GET_FUNCTION_CODE_DATALEN(x) ((x)&0x7) + +#define CELLS(row, col) cells[row * cols + col] + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Code to decode the Palm image format to JPEG *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8) | ((p)[1])) +#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3])) + +#define PALM_IS_COMPRESSED_FLAG 0x8000 +#define PALM_HAS_COLORMAP_FLAG 0x4000 +#define PALM_HAS_TRANSPARENCY_FLAG 0x2000 +#define PALM_DIRECT_COLOR_FLAG 0x0400 +#define PALM_4_BYTE_FIELD_FLAG 0x0200 + +#define PALM_COMPRESSION_SCANLINE 0x00 +#define PALM_COMPRESSION_RLE 0x01 +#define PALM_COMPRESSION_PACKBITS 0x02 +#define PALM_COMPRESSION_NONE 0xFF + +#define PALM_COLORMAP_SIZE 232 + +typedef struct { + unsigned char red; + unsigned char green; + unsigned char blue; +} ColorMapEntry; + +static ColorMapEntry Palm8BitColormap[] = { + {255, 255, 255}, {255, 204, 255}, {255, 153, 255}, {255, 102, 255}, {255, 51, 255}, {255, 0, 255}, {255, 255, 204}, {255, 204, 204}, {255, 153, 204}, {255, 102, 204}, {255, 51, 204}, {255, 0, 204}, {255, 255, 153}, + {255, 204, 153}, {255, 153, 153}, {255, 102, 153}, {255, 51, 153}, {255, 0, 153}, {204, 255, 255}, {204, 204, 255}, {204, 153, 255}, {204, 102, 255}, {204, 51, 255}, {204, 0, 255}, {204, 255, 204}, {204, 204, 204}, + {204, 153, 204}, {204, 102, 204}, {204, 51, 204}, {204, 0, 204}, {204, 255, 153}, {204, 204, 153}, {204, 153, 153}, {204, 102, 153}, {204, 51, 153}, {204, 0, 153}, {153, 255, 255}, {153, 204, 255}, {153, 153, 255}, + {153, 102, 255}, {153, 51, 255}, {153, 0, 255}, {153, 255, 204}, {153, 204, 204}, {153, 153, 204}, {153, 102, 204}, {153, 51, 204}, {153, 0, 204}, {153, 255, 153}, {153, 204, 153}, {153, 153, 153}, {153, 102, 153}, + {153, 51, 153}, {153, 0, 153}, {102, 255, 255}, {102, 204, 255}, {102, 153, 255}, {102, 102, 255}, {102, 51, 255}, {102, 0, 255}, {102, 255, 204}, {102, 204, 204}, {102, 153, 204}, {102, 102, 204}, {102, 51, 204}, + {102, 0, 204}, {102, 255, 153}, {102, 204, 153}, {102, 153, 153}, {102, 102, 153}, {102, 51, 153}, {102, 0, 153}, {51, 255, 255}, {51, 204, 255}, {51, 153, 255}, {51, 102, 255}, {51, 51, 255}, {51, 0, 255}, + {51, 255, 204}, {51, 204, 204}, {51, 153, 204}, {51, 102, 204}, {51, 51, 204}, {51, 0, 204}, {51, 255, 153}, {51, 204, 153}, {51, 153, 153}, {51, 102, 153}, {51, 51, 153}, {51, 0, 153}, {0, 255, 255}, + {0, 204, 255}, {0, 153, 255}, {0, 102, 255}, {0, 51, 255}, {0, 0, 255}, {0, 255, 204}, {0, 204, 204}, {0, 153, 204}, {0, 102, 204}, {0, 51, 204}, {0, 0, 204}, {0, 255, 153}, {0, 204, 153}, + {0, 153, 153}, {0, 102, 153}, {0, 51, 153}, {0, 0, 153}, {255, 255, 102}, {255, 204, 102}, {255, 153, 102}, {255, 102, 102}, {255, 51, 102}, {255, 0, 102}, {255, 255, 51}, {255, 204, 51}, {255, 153, 51}, + {255, 102, 51}, {255, 51, 51}, {255, 0, 51}, {255, 255, 0}, {255, 204, 0}, {255, 153, 0}, {255, 102, 0}, {255, 51, 0}, {255, 0, 0}, {204, 255, 102}, {204, 204, 102}, {204, 153, 102}, {204, 102, 102}, + {204, 51, 102}, {204, 0, 102}, {204, 255, 51}, {204, 204, 51}, {204, 153, 51}, {204, 102, 51}, {204, 51, 51}, {204, 0, 51}, {204, 255, 0}, {204, 204, 0}, {204, 153, 0}, {204, 102, 0}, {204, 51, 0}, + {204, 0, 0}, {153, 255, 102}, {153, 204, 102}, {153, 153, 102}, {153, 102, 102}, {153, 51, 102}, {153, 0, 102}, {153, 255, 51}, {153, 204, 51}, {153, 153, 51}, {153, 102, 51}, {153, 51, 51}, {153, 0, 51}, + {153, 255, 0}, {153, 204, 0}, {153, 153, 0}, {153, 102, 0}, {153, 51, 0}, {153, 0, 0}, {102, 255, 102}, {102, 204, 102}, {102, 153, 102}, {102, 102, 102}, {102, 51, 102}, {102, 0, 102}, {102, 255, 51}, + {102, 204, 51}, {102, 153, 51}, {102, 102, 51}, {102, 51, 51}, {102, 0, 51}, {102, 255, 0}, {102, 204, 0}, {102, 153, 0}, {102, 102, 0}, {102, 51, 0}, {102, 0, 0}, {51, 255, 102}, {51, 204, 102}, + {51, 153, 102}, {51, 102, 102}, {51, 51, 102}, {51, 0, 102}, {51, 255, 51}, {51, 204, 51}, {51, 153, 51}, {51, 102, 51}, {51, 51, 51}, {51, 0, 51}, {51, 255, 0}, {51, 204, 0}, {51, 153, 0}, + {51, 102, 0}, {51, 51, 0}, {51, 0, 0}, {0, 255, 102}, {0, 204, 102}, {0, 153, 102}, {0, 102, 102}, {0, 51, 102}, {0, 0, 102}, {0, 255, 51}, {0, 204, 51}, {0, 153, 51}, {0, 102, 51}, + {0, 51, 51}, {0, 0, 51}, {0, 255, 0}, {0, 204, 0}, {0, 153, 0}, {0, 102, 0}, {0, 51, 0}, {17, 17, 17}, {34, 34, 34}, {68, 68, 68}, {85, 85, 85}, {119, 119, 119}, {136, 136, 136}, + {170, 170, 170}, {187, 187, 187}, {221, 221, 221}, {238, 238, 238}, {192, 192, 192}, {128, 0, 0}, {128, 0, 128}, {0, 128, 0}, {0, 128, 128}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, + {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, + {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + +static ColorMapEntry Palm1BitColormap[] = {{255, 255, 255}, {0, 0, 0}}; + +static ColorMapEntry Palm2BitColormap[] = {{255, 255, 255}, {192, 192, 192}, {128, 128, 128}, {0, 0, 0}}; + +static ColorMapEntry Palm4BitColormap[] = {{255, 255, 255}, + {238, 238, 238}, + {221, 221, 221}, + {204, 204, 204}, + {187, 187, 187}, + {170, 170, 170}, + {153, 153, 153}, + {136, 136, 136}, + {119, 119, 119}, + {102, 102, 102}, + {85, 85, 85}, + {68, 68, 68}, + {51, 51, 51}, + {34, 34, 34}, + {17, 17, 17}, + {0, 0, 0}}; + +bool TranscribePalmImageToJPEG(unsigned char *image_bytes_in, QImage &image) +{ + unsigned int width; + unsigned int height; + unsigned int bytes_per_row; + unsigned int flags; + // unsigned int next_depth_offset; + unsigned int bits_per_pixel; + // unsigned int version; + // unsigned int transparent_index; + unsigned int compression_type; + unsigned int i; + unsigned int j; + unsigned int inval; + unsigned int inbit; + unsigned int mask; + unsigned int incount; + unsigned int palm_red_bits = 0; + unsigned int palm_green_bits = 0; + unsigned int palm_blue_bits = 0; + unsigned char *palm_ptr; + // unsigned char* x_ptr; + // unsigned char* imagedata = 0; + unsigned char *inbyte; + unsigned char *rowbuf; + unsigned char *lastrow; + unsigned char *imagedatastart; + unsigned char *palmimage; + ColorMapEntry *colormap; + + JSAMPLE *jpeg_row; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + + palmimage = image_bytes_in; + width = READ_BIGENDIAN_SHORT(palmimage + 0); + height = READ_BIGENDIAN_SHORT(palmimage + 2); + bytes_per_row = READ_BIGENDIAN_SHORT(palmimage + 4); + flags = READ_BIGENDIAN_SHORT(palmimage + 6); + bits_per_pixel = palmimage[8]; + // version = palmimage[9]; + // next_depth_offset = READ_BIGENDIAN_SHORT (palmimage + 10); + // transparent_index = palmimage[12]; + compression_type = palmimage[13]; + /* bytes 14 and 15 are reserved by Palm and always 0 */ + + if (compression_type == PALM_COMPRESSION_PACKBITS) { + return false; + } else if ((compression_type != PALM_COMPRESSION_NONE) && (compression_type != PALM_COMPRESSION_RLE) && (compression_type != PALM_COMPRESSION_SCANLINE)) { + return false; + } + + /* as of PalmOS 4.0, there are 6 different kinds of Palm pixmaps: + + 1, 2, or 4 bit grayscale + 8-bit StaticColor using the Palm standard colormap + 8-bit PseudoColor using a user-specified colormap + 16-bit DirectColor using 5 bits for red, 6 for green, and 5 for blue + + Each of these can be compressed with one of four compression schemes, + "RLE", "Scanline", "PackBits", or none. + + We begin by constructing the colormap. + */ + + if (flags & PALM_HAS_COLORMAP_FLAG) { + return false; + } else if (bits_per_pixel == 1) { + colormap = Palm1BitColormap; + imagedatastart = palmimage + 16; + } else if (bits_per_pixel == 2) { + colormap = Palm2BitColormap; + imagedatastart = palmimage + 16; + } else if (bits_per_pixel == 4) { + colormap = Palm4BitColormap; + imagedatastart = palmimage + 16; + } else if (bits_per_pixel == 8) { + colormap = Palm8BitColormap; + imagedatastart = palmimage + 16; + } else if (bits_per_pixel == 16 && (flags & PALM_DIRECT_COLOR_FLAG)) { + colormap = nullptr; + palm_red_bits = palmimage[16]; + palm_green_bits = palmimage[17]; + palm_blue_bits = palmimage[18]; + if (palm_blue_bits > 8 || palm_green_bits > 8 || palm_red_bits > 8) { + return false; + } + if (bits_per_pixel > (8 * sizeof(unsigned long))) { + return false; + } + imagedatastart = palmimage + 24; + } else { + return false; + } + + QTemporaryFile tempFile; + tempFile.open(); + FILE *outfile = fopen(QFile::encodeName(tempFile.fileName()).constData(), "w"); + if (!outfile) + return false; + + /* now create the JPEG image row buffer */ + jpeg_row = (JSAMPLE *)malloc(sizeof(JSAMPLE) * (width * 3)); + + /* Use standard JPEG error processing */ + cinfo.err = jpeg_std_error(&jerr); + /* Initialize the JPEG compression object. */ + jpeg_create_compress(&cinfo); + + jpeg_stdio_dest(&cinfo, outfile); + + cinfo.image_width = width; /* image width and height, in pixels */ + cinfo.image_height = height; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, 100, true /* limit to baseline-JPEG values */); + + row_pointer[0] = &jpeg_row[0]; + + jpeg_start_compress(&cinfo, true); + + /* row by row, uncompress the Palm image and copy it to the JPEG buffer */ + rowbuf = (unsigned char *)malloc(bytes_per_row * width); + lastrow = (unsigned char *)malloc(bytes_per_row * width); + for (i = 0, palm_ptr = imagedatastart /*, x_ptr = imagedata*/; i < height; ++i) { + /* first, uncompress the Palm image */ + if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_RLE)) { + for (j = 0; j < bytes_per_row;) { + incount = *palm_ptr++; + inval = *palm_ptr++; + if (incount + j <= bytes_per_row * width) { + memset(rowbuf + j, inval, incount); + j += incount; + } else { + free(rowbuf); + free(lastrow); + free(jpeg_row); + + jpeg_destroy_compress(&cinfo); + + fclose(outfile); + + return false; + } + } + } else if ((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_SCANLINE)) { + for (j = 0; j < bytes_per_row; j += 8) { + incount = *palm_ptr++; + inval = ((bytes_per_row - j) < 8) ? (bytes_per_row - j) : 8; + for (inbit = 0; inbit < inval; inbit += 1) { + if (incount & (1 << (7 - inbit))) + rowbuf[j + inbit] = *palm_ptr++; + else + rowbuf[j + inbit] = lastrow[j + inbit]; + } + } + memcpy(lastrow, rowbuf, bytes_per_row); + } else if (((flags & PALM_IS_COMPRESSED_FLAG) && (compression_type == PALM_COMPRESSION_NONE)) || (flags & PALM_IS_COMPRESSED_FLAG) == 0) { + memcpy(rowbuf, palm_ptr, bytes_per_row); + palm_ptr += bytes_per_row; + } + + /* next, write it to the GDK bitmap */ + if (colormap) { + mask = (1 << bits_per_pixel) - 1; + for (inbit = 8 - bits_per_pixel, inbyte = rowbuf, j = 0; j < width; ++j) { + inval = ((*inbyte) & (mask << inbit)) >> inbit; + /* correct for oddity of the 8-bit color Palm pixmap... */ + if ((bits_per_pixel == 8) && (inval == 0xFF)) + inval = 231; + /* now lookup the correct color and set the pixel in the GTK bitmap */ + jpeg_row[(j * 3) + 0] = colormap[inval].red; + jpeg_row[(j * 3) + 1] = colormap[inval].green; + jpeg_row[(j * 3) + 2] = colormap[inval].blue; + if (!inbit) { + ++inbyte; + inbit = 8 - bits_per_pixel; + } else { + inbit -= bits_per_pixel; + } + } + } else if (!colormap && bits_per_pixel == 16) { + for (inbyte = rowbuf, j = 0; j < width; ++j) { + inval = (inbyte[0] << 8) | inbyte[1]; + jpeg_row[(j * 3) + 0] = (inval >> (bits_per_pixel - palm_red_bits)) & ((1 << palm_red_bits) - 1); + jpeg_row[(j * 3) + 1] = (inval >> palm_blue_bits) & ((1 << palm_green_bits) - 1); + jpeg_row[(j * 3) + 2] = (inval >> 0) & ((1 << palm_blue_bits) - 1); + inbyte += 2; + } + } + + (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + free(rowbuf); + free(lastrow); + free(jpeg_row); + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + fclose(outfile); + + return image.load(tempFile.fileName()); +} + +typedef struct { + unsigned int width; + unsigned int height; + unsigned int bytes_per_row; + unsigned int flags; + unsigned int next_depth_offset; + unsigned int bits_per_pixel; + unsigned int version; + unsigned int transparent_index; + unsigned int compression_type; + unsigned int palm_red_bits; + unsigned int palm_green_bits; + unsigned int palm_blue_bits; + unsigned char *bytes; + +} PALMPIX; + +bool TranscribeMultiImageRecord(plkr_Document *doc, QImage &image, unsigned char *bytes) +{ + unsigned char *pbytes = nullptr; + unsigned char *outbytes = nullptr; + unsigned char *outptr = nullptr; + unsigned char *ptr = &bytes[12]; + plkr_DataRecordType ptype; + PALMPIX *cells = nullptr; + PALMPIX *acell = nullptr; + unsigned int record_id = 0; + int plen = 0; + unsigned int x = 0; + unsigned int y = 0; + unsigned int cols = 0; + unsigned int rows = 0; + unsigned int width = 0; + unsigned int height = 0; + unsigned int bytes_per_row = 0; + unsigned int flags = 0; + unsigned int bits_per_pixel = 0; + unsigned int version = 0; + unsigned int transparent_index = 0; + unsigned int compression_type = 0; + unsigned int palm_red_bits = 0; + unsigned int palm_green_bits = 0; + unsigned int palm_blue_bits = 0; + unsigned int outlen = 0; + unsigned int offset = 0; + bool status = true; + + cols = (bytes[8] << 8) + bytes[9]; + rows = (bytes[10] << 8) + bytes[11]; + + cells = (PALMPIX *)calloc(cols * rows, sizeof(PALMPIX)); + + height = 0; + for (y = 0; y < rows; y++) { + width = 0; + bytes_per_row = 0; + for (x = 0; x < cols; x++) { + acell = &CELLS(y, x); + record_id = (ptr[0] << 8) + ptr[1]; + ptr += 2; + pbytes = plkr_GetRecordBytes(doc, record_id, &plen, &ptype); + if (pbytes == nullptr) { + free(cells); + return false; + } + + pbytes += 8; + acell->width = READ_BIGENDIAN_SHORT(&pbytes[0]); + width += acell->width; + acell->height = READ_BIGENDIAN_SHORT(&pbytes[2]); + acell->bytes_per_row = READ_BIGENDIAN_SHORT(&pbytes[4]); + bytes_per_row += acell->bytes_per_row; + acell->flags = READ_BIGENDIAN_SHORT(&pbytes[6]); + flags = acell->flags; + acell->bits_per_pixel = pbytes[8]; + bits_per_pixel = acell->bits_per_pixel; + acell->version = pbytes[9]; + version = acell->version; + acell->next_depth_offset = READ_BIGENDIAN_SHORT(&pbytes[10]); + acell->transparent_index = pbytes[12]; + transparent_index = acell->transparent_index; + acell->compression_type = pbytes[13]; + compression_type = acell->compression_type; + + if (acell->flags & PALM_HAS_COLORMAP_FLAG) { + free(cells); + return false; + } + + acell->bytes = pbytes + 16; + offset = 16; + if (acell->bits_per_pixel == 16 && (acell->flags & PALM_DIRECT_COLOR_FLAG)) { + acell->palm_red_bits = pbytes[16]; + palm_red_bits = acell->palm_red_bits; + acell->palm_green_bits = pbytes[17]; + palm_green_bits = acell->palm_green_bits; + acell->palm_blue_bits = pbytes[18]; + palm_blue_bits = acell->palm_blue_bits; + acell->bytes = pbytes + 24; + offset = 24; + } + } + height += acell->height; + } + + outlen = bytes_per_row * height + offset; + outbytes = (unsigned char *)malloc(outlen); + outptr = outbytes; + + *outptr++ = width >> 8; + *outptr++ = width; + *outptr++ = height >> 8; + *outptr++ = height; + *outptr++ = bytes_per_row >> 8; + *outptr++ = bytes_per_row; + *outptr++ = flags >> 8; + *outptr++ = flags; + *outptr++ = bits_per_pixel; + *outptr++ = version; + *outptr++ = 0; /* next_depth_offset */ + *outptr++ = 0; + *outptr++ = transparent_index; + *outptr++ = compression_type; + *outptr++ = 0; + *outptr++ = 0; + + if (acell->bits_per_pixel == 16 && (acell->flags & PALM_DIRECT_COLOR_FLAG)) { + *outptr++ = palm_red_bits; + *outptr++ = palm_green_bits; + *outptr++ = palm_blue_bits; + *outptr++ = 0; + *outptr++ = 0; + *outptr++ = 0; + *outptr++ = 0; + *outptr++ = 0; + } + + for (y = 0; y < rows; y++) { + int i, h; + acell = &CELLS(y, 0); + h = acell->height; + for (i = 0; i < h; i++) { + for (x = 0; x < cols; x++) { + acell = &CELLS(y, x); + memcpy(outptr, acell->bytes, acell->bytes_per_row); + acell->bytes += acell->bytes_per_row; + outptr += acell->bytes_per_row; + } + } + } + + status = TranscribePalmImageToJPEG(outbytes, image); + + free(outbytes); + free(cells); + + return status; +} diff --git a/generators/plucker/unpluck/image.h b/generators/plucker/unpluck/image.h new file mode 100644 index 0000000..d0172ec --- /dev/null +++ b/generators/plucker/unpluck/image.h @@ -0,0 +1,22 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * Based on code written by Bill Janssen 2002 * + * * + * 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 IMAGE_H +#define IMAGE_H + +#include "unpluck.h" + +class QImage; + +bool TranscribePalmImageToJPEG(unsigned char *image_bytes_in, QImage &image); +bool TranscribeMultiImageRecord(plkr_Document *doc, QImage &image, unsigned char *bytes); + +#endif diff --git a/generators/plucker/unpluck/qunpluck.cpp b/generators/plucker/unpluck/qunpluck.cpp new file mode 100644 index 0000000..67b6e5e --- /dev/null +++ b/generators/plucker/unpluck/qunpluck.cpp @@ -0,0 +1,1095 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * Based on code written by Bill Janssen 2002 * + * * + * 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. * + ***************************************************************************/ + +#include "qunpluck.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "image.h" + +#define GET_FUNCTION_CODE_TYPE(x) (((x) >> 3) & 0x1F) +#define GET_FUNCTION_CODE_DATALEN(x) ((x)&0x7) + +#define CELLS(row, col) cells[row * cols + col] + +#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8) | ((p)[1])) +#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3])) +/* +static void LinkRecords + ( + char* dir + ) +{ + RecordNode* ptr; + char* realfilename; + char* linkname; + + realfilename = (char*)malloc (strlen (dir) + 20); + linkname = (char*)malloc (strlen (dir) + 20); + + for (ptr = records; ptr != NULL; ptr = ptr->next) { + if (ptr->page_id != ptr->index) { + sprintf (realfilename, "%s/r%d.html", dir, ptr->page_id); + sprintf (linkname, "%s/r%d.html", dir, ptr->index); + link (realfilename, linkname); + } + } + + free (realfilename); + free (linkname); +} +*/ + +class Context +{ +public: + int recordId; + QTextDocument *document; + QTextCursor *cursor; + QStack stack; + QList images; + + QString linkUrl; + int linkStart; + int linkPage; +}; + +class RecordNode +{ +public: + int index; + int page_id; + bool done; +}; + +static Okular::DocumentViewport calculateViewport(QTextDocument *document, const QTextBlock &block) +{ + if (!block.isValid()) + return Okular::DocumentViewport(); + + const QRectF rect = document->documentLayout()->blockBoundingRect(block); + const QSizeF size = document->size(); + + int page = qRound(rect.y()) / qRound(size.height()); + + Okular::DocumentViewport viewport(page); + viewport.rePos.normalizedX = (double)rect.x() / (double)size.width(); + viewport.rePos.normalizedY = (double)rect.y() / (double)size.height(); + viewport.rePos.enabled = true; + viewport.rePos.pos = Okular::DocumentViewport::Center; + + return viewport; +} + +QUnpluck::QUnpluck() + : mDocument(nullptr) +{ +} + +QUnpluck::~QUnpluck() +{ + mLinks.clear(); + mNamedTargets.clear(); + mPages.clear(); +} + +bool QUnpluck::open(const QString &fileName) +{ + mLinks.clear(); + mNamedTargets.clear(); + mPages.clear(); + + mDocument = plkr_OpenDBFile(QFile::encodeName(fileName).data()); + if (!mDocument) { + mErrorString = QObject::tr("Unable to open document"); + return false; + } + + // bool status = true; + + mInfo.insert(QStringLiteral("name"), QString::fromLocal8Bit(plkr_GetName(mDocument))); + mInfo.insert(QStringLiteral("title"), QString::fromLocal8Bit(plkr_GetTitle(mDocument))); + mInfo.insert(QStringLiteral("author"), QString::fromLocal8Bit(plkr_GetAuthor(mDocument))); + mInfo.insert(QStringLiteral("time"), QDateTime::fromSecsSinceEpoch(plkr_GetPublicationTime(mDocument)).toString()); + + AddRecord(plkr_GetHomeRecordID(mDocument)); + + int number = GetNextRecordNumber(); + while (number > 0) { + /*status = */ TranscribeRecord(number); + number = GetNextRecordNumber(); + } + + // Iterate over all records again to add those which aren't linked directly + for (int i = 1; i < plkr_GetRecordCount(mDocument); ++i) + AddRecord(plkr_GetUidForIndex(mDocument, i)); + + number = GetNextRecordNumber(); + while (number > 0) { + /*status = */ TranscribeRecord(number); + number = GetNextRecordNumber(); + } + + for (int i = 0; i < mRecords.count(); ++i) + delete mRecords[i]; + + mRecords.clear(); + + plkr_CloseDoc(mDocument); + + /** + * Calculate hash map + */ + QHash pageHash; + for (int i = 0; i < mContext.count(); ++i) + pageHash.insert(mContext[i]->recordId, i); + + /** + * Convert ids + */ + for (int i = 0; i < mContext.count(); ++i) { + Context *context = mContext[i]; + for (int j = 0; j < context->images.count(); ++j) { + int imgNumber = context->images[j]; + context->document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("%1.jpg").arg(imgNumber)), mImages[imgNumber]); + } + + mPages.append(context->document); + } + qDeleteAll(mContext); + mContext.clear(); + + // convert record_id into page + for (int i = 0; i < mLinks.count(); ++i) { + mLinks[i].page = pageHash[mLinks[i].page]; + if (mLinks[i].url.startsWith(QLatin1String("page:"))) { + int page = mLinks[i].url.midRef(5).toInt(); + Okular::DocumentViewport viewport(pageHash[page]); + viewport.rePos.normalizedX = 0; + viewport.rePos.normalizedY = 0; + viewport.rePos.enabled = true; + viewport.rePos.pos = Okular::DocumentViewport::TopLeft; + mLinks[i].link = new Okular::GotoAction(QString(), viewport); + } else if (mLinks[i].url.startsWith(QLatin1String("para:"))) { + QPair data = mNamedTargets[mLinks[i].url]; + + QTextDocument *document = mPages[mLinks[i].page]; + + Okular::DocumentViewport viewport = calculateViewport(document, data.second); + + mLinks[i].link = new Okular::GotoAction(QString(), viewport); + } else { + mLinks[i].link = new Okular::BrowseAction(QUrl(mLinks[i].url)); + } + } + + return true; +} + +int QUnpluck::GetNextRecordNumber() +{ + int index = 0; + + for (int pos = 0; pos < mRecords.count(); ++pos) { + if (!mRecords[pos]->done) { + index = mRecords[pos]->index; + break; + } + } + + return index; +} + +int QUnpluck::GetPageID(int index) +{ + for (int pos = 0; pos < mRecords.count(); ++pos) { + if (mRecords[pos]->index == index) { + return mRecords[pos]->page_id; + } + } + + return 0; +} + +void QUnpluck::AddRecord(int index) +{ + for (int pos = 0; pos < mRecords.count(); ++pos) { + if (mRecords[pos]->index == index) { + return; + } + } + + RecordNode *node = new RecordNode; + node->done = false; + node->index = index; + node->page_id = index; + + mRecords.append(node); +} + +void QUnpluck::MarkRecordDone(int index) +{ + for (int pos = 0; pos < mRecords.count(); ++pos) { + if (mRecords[pos]->index == index) { + mRecords[pos]->done = true; + return; + } + } + + AddRecord(index); + MarkRecordDone(index); +} + +void QUnpluck::SetPageID(int index, int page_id) +{ + for (int pos = 0; pos < mRecords.count(); ++pos) { + if (mRecords[pos]->index == index) { + mRecords[pos]->page_id = page_id; + return; + } + } + + AddRecord(index); + SetPageID(index, page_id); +} + +QString QUnpluck::MailtoURLFromBytes(unsigned char *record_data) +{ + unsigned char *bytes = record_data + 8; + + int to_offset = (bytes[0] << 8) + bytes[1]; + int cc_offset = (bytes[2] << 8) + bytes[3]; + int subject_offset = (bytes[4] << 8) + bytes[5]; + int body_offset = (bytes[6] << 8) + bytes[7]; + + QString url(QStringLiteral("mailto:")); + if (to_offset != 0) + url += QString::fromLatin1((char *)(bytes + to_offset)); + + if ((cc_offset != 0) || (subject_offset != 0) || (body_offset != 0)) + url += QLatin1String("?"); + + if (cc_offset != 0) + url += QLatin1String("cc=") + QString::fromLatin1((char *)(bytes + cc_offset)); + + if (subject_offset != 0) + url += QLatin1String("subject=") + QString::fromLatin1((char *)(bytes + subject_offset)); + + if (body_offset != 0) + url += QLatin1String("body=") + QString::fromLatin1((char *)(bytes + body_offset)); + + return url; +} + +QImage QUnpluck::TranscribeImageRecord(unsigned char *bytes) +{ + QImage image; + + TranscribePalmImageToJPEG(bytes + 8, image); + + return image; +} + +void QUnpluck::DoStyle(Context *context, int style, bool start) +{ + if (start) { + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + + int pointSize = qRound(format.fontPointSize()); + switch (style) { + case 1: + format.setFontWeight(QFont::Bold); + pointSize += 3; + break; + case 2: + format.setFontWeight(QFont::Bold); + pointSize += 2; + break; + case 3: + format.setFontWeight(QFont::Bold); + pointSize += 1; + break; + case 4: + format.setFontWeight(QFont::Bold); + break; + case 5: + format.setFontWeight(QFont::Bold); + pointSize += -1; + break; + case 6: + format.setFontWeight(QFont::Bold); + pointSize += -2; + break; + case 7: + format.setFontWeight(QFont::Bold); + break; + case 8: + format.setFontFamily(QStringLiteral("Courier New,courier")); + break; + } + format.setFontPointSize(qMax(pointSize, 1)); + context->cursor->setCharFormat(format); + } else { + if (!context->stack.isEmpty()) + context->cursor->setCharFormat(context->stack.pop()); + } +} + +void QUnpluck::ParseText(plkr_Document *doc, unsigned char *ptr, int text_len, int *font, int *style, Context *context) +{ + unsigned char *end; + int fctype; + int fclen; + + end = ptr + text_len; + while (ptr < end) { + if (ptr[0]) { + context->cursor->insertText(QString::fromLocal8Bit((char *)ptr)); + ptr += strlen((char *)ptr); + } else { + fctype = GET_FUNCTION_CODE_TYPE(ptr[1]); + fclen = 2 + GET_FUNCTION_CODE_DATALEN(ptr[1]); + switch (fctype) { + case PLKR_TFC_LINK: + switch (fclen) { + case 4: /* ANCHOR_BEGIN */ + { + int record_id = (ptr[2] << 8) + ptr[3]; + + /** TODO: + plkr_DataRecordType type = + (plkr_DataRecordType)plkr_GetRecordType (doc, record_id); + if (type == + PLKR_DRTYPE_IMAGE + || type == + PLKR_DRTYPE_IMAGE_COMPRESSED) + output += QString( "
" ).arg(record_id); + else + output += QString( "" ).arg(record_id); + */ + AddRecord(record_id); + } break; + case 2: /* ANCHOR_END */ + // TODO: output += QString( "" ); + break; + } + ptr += fclen; + break; + case PLKR_TFC_FONT: + DoStyle(context, *style, false); + *style = ptr[2]; + DoStyle(context, *style, true); + ptr += fclen; + break; + case PLKR_TFC_NEWLINE: { + // TODO: remove the setCharFormat when Qt is fixed + QTextCharFormat format(context->cursor->charFormat()); + context->cursor->insertText(QStringLiteral("\n")); + context->cursor->setCharFormat(format); + ptr += fclen; + break; + } + case PLKR_TFC_BITALIC: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontItalic(true); + context->cursor->setCharFormat(format); + ptr += fclen; + break; + } + case PLKR_TFC_EITALIC: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontItalic(false); + context->cursor->setCharFormat(format); + ptr += fclen; + break; + } + case PLKR_TFC_COLOR: + if (*font) { + (*font)--; + if (!context->stack.isEmpty()) + context->cursor->setCharFormat(context->stack.pop()); + } + + { + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + + format.setForeground(QColor((ptr[2] << 16), (ptr[3] << 8), ptr[4])); + context->cursor->setCharFormat(format); + } + + (*font)++; + ptr += fclen; + break; + case PLKR_TFC_BULINE: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontUnderline(true); + context->cursor->setCharFormat(format); + ptr += fclen; + } break; + case PLKR_TFC_EULINE: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontUnderline(false); + context->cursor->setCharFormat(format); + ptr += fclen; + } break; + case PLKR_TFC_BSTRIKE: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontStrikeOut(true); + context->cursor->setCharFormat(format); + ptr += fclen; + break; + } + case PLKR_TFC_ESTRIKE: { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontStrikeOut(false); + context->cursor->setCharFormat(format); + ptr += fclen; + break; + } + case PLKR_TFC_TABLE: + if (fclen == 4) { + int record_id, datalen; + plkr_DataRecordType type = (plkr_DataRecordType)0; + unsigned char *bytes = nullptr; + + record_id = (ptr[2] << 8) + ptr[3]; + bytes = plkr_GetRecordBytes(doc, record_id, &datalen, &type); + TranscribeTableRecord(doc, context, bytes); + } + ptr += fclen; + break; + default: + ptr += fclen; + } + } + } +} + +bool QUnpluck::TranscribeTableRecord(plkr_Document *doc, Context *context, unsigned char *bytes) +{ + unsigned char *ptr = &bytes[24]; + unsigned char *end; + // char* align_names[] = { "left", "right", "center" }; + // bool in_row = false; + // int cols; + int size; + // int rows; + // int border; + int record_id; + // int align; + int text_len; + // int colspan; + // int rowspan; + int font = 0; + int style = 0; + int fctype; + int fclen; + // long border_color; + // long link_color; + + size = (bytes[8] << 8) + bytes[9]; + // cols = (bytes[10] << 8) + bytes[11]; + // rows = (bytes[12] << 8) + bytes[13]; + // border = bytes[15]; + // border_color = (bytes[17] << 16) + (bytes[18] << 8) + (bytes[19] << 8); + // link_color = (bytes[21] << 16) + (bytes[22] << 8) + (bytes[23] << 8); + + end = ptr + size - 1; + /** + output += QString( "\n" ).arg(border, border_color, link_color); + */ + while (ptr < end) { + if (ptr[0] == '\0') { + fctype = GET_FUNCTION_CODE_TYPE(ptr[1]); + fclen = 2 + GET_FUNCTION_CODE_DATALEN(ptr[1]); + switch (fctype) { + case PLKR_TFC_TABLE: + switch (fclen) { + case 2: /* NEW_ROW */ + /* + if (in_row) + output += QString( "\n" ); + output += QString( "\n" ); + in_row = true; + */ + ptr += fclen; + break; + case 9: /* NEW_CELL */ + // align = ptr[2]; + // colspan = ptr[5]; + // rowspan = ptr[6]; + /** + output += QString( "\n" ); + break; + default: + ptr += fclen; + } + break; + default: + ptr += fclen; + } + } else { + // output += QString( "
" ).arg( + align_names[align], colspan, rowspan ); +// border_color); +*/ + if ((record_id = READ_BIGENDIAN_SHORT(&ptr[3]))) { + QTextCharFormat format = context->cursor->charFormat(); + context->cursor->insertImage(QStringLiteral("%1.jpg").arg(record_id)); + context->cursor->setCharFormat(format); + context->images.append(record_id); + AddRecord(record_id); + } + DoStyle(context, style, true); + text_len = READ_BIGENDIAN_SHORT(&ptr[7]); + ptr += fclen; + ParseText(doc, ptr, text_len, &font, &style, context); + ptr += text_len; + DoStyle(context, style, false); + // output += QString( "
\n" ); + return false; + } + } + + // output += QString( "\n" ); + return true; +} + +typedef struct { + int size; + int attributes; +} ParagraphInfo; + +static ParagraphInfo *ParseParagraphInfo(unsigned char *bytes, int *nparas) +{ + ParagraphInfo *paragraph_info; + int j; + int n; + + n = (bytes[2] << 8) + bytes[3]; + paragraph_info = (ParagraphInfo *)malloc(sizeof(ParagraphInfo) * n); + for (j = 0; j < n; j++) { + paragraph_info[j].size = (bytes[8 + (j * 4) + 0] << 8) + bytes[8 + (j * 4) + 1]; + paragraph_info[j].attributes = (bytes[8 + (j * 4) + 2] << 8) + bytes[8 + (j * 4) + 3]; + } + *nparas = n; + return paragraph_info; +} + +bool QUnpluck::TranscribeTextRecord(plkr_Document *doc, int id, Context *context, unsigned char *bytes, plkr_DataRecordType type) +{ + unsigned char *ptr; + unsigned char *run; + unsigned char *para_start; + unsigned char *data; + unsigned char *start; + ParagraphInfo *paragraphs; + bool first_record_of_page = true; + bool current_link; + bool current_italic; + bool current_struckthrough; + bool current_underline; + int fctype; + int fclen; + int para_index; + int para_len; + int textlen; + int data_len; + int current_font; + int record_index; + // int current_alignment; + // int current_left_margin; + // int current_right_margin; + int nparagraphs; + // long current_color; + + record_index = id; + + paragraphs = ParseParagraphInfo(bytes, &nparagraphs); + start = bytes + 8 + ((bytes[2] << 8) + bytes[3]) * 4; + + for (para_index = 0, ptr = start, run = start; para_index < nparagraphs; para_index++) { + para_len = paragraphs[para_index].size; + + /* If the paragraph is the last in the record, and it consists + of a link to the next record in the logical page, we trim off + the paragraph and instead insert the whole page */ + + if (((para_index + 1) == nparagraphs) && (para_len == (sizeof("Click here for the next part") + 5)) && (*ptr == 0) && (ptr[1] == ((PLKR_TFC_LINK << 3) + 2)) && (strcmp((char *)(ptr + 4), "Click here for the next part") == 0)) { + record_index = (ptr[2] << 8) + ptr[3]; + if ((data = plkr_GetRecordBytes(doc, record_index, &data_len, &type)) == nullptr) { + // ShowWarning ("Can't open record %d!", record_index); + free(paragraphs); + return false; + } else if (!(type == PLKR_DRTYPE_TEXT_COMPRESSED || type == PLKR_DRTYPE_TEXT)) { + // ShowWarning ("Bad record type %d in record linked from end of record %d", type, id); + free(paragraphs); + return false; + } + first_record_of_page = false; + para_index = 0; + ptr = data + 8 + ((data[2] << 8) + data[3]) * 4; + run = ptr; + free(paragraphs); + paragraphs = ParseParagraphInfo(data, &nparagraphs); + para_len = paragraphs[para_index].size; + MarkRecordDone(record_index); + SetPageID(record_index, id); + } + + if ((para_index == 0) && !first_record_of_page && (*ptr == 0) && (ptr[1] == ((PLKR_TFC_LINK << 3) + 2)) && (strcmp((char *)(ptr + 4), "Click here for the previous part") == 0)) { + /* throw away this inserted paragraph */ + ptr += para_len; + run = ptr; + continue; + } + + QTextCharFormat format(context->cursor->charFormat()); + QTextBlockFormat blockFormat(context->cursor->blockFormat()); + blockFormat.setAlignment(Qt::AlignLeft); + context->cursor->insertBlock(blockFormat); + context->cursor->setCharFormat(format); + + mNamedTargets.insert(QStringLiteral("para:%1-%2").arg(record_index).arg(para_index), QPair(GetPageID(record_index), context->cursor->block())); + + current_link = false; + + /* at the beginning of a paragraph, we start with a clean graphics context */ + current_font = 0; + // current_alignment = 0; + // current_color = 0; + current_italic = false; + current_underline = false; + current_struckthrough = false; + // current_left_margin = 0; + // current_right_margin = 0; + + for (para_start = ptr, textlen = 0; (ptr - para_start) < para_len;) { + if (*ptr == 0) { + /* function code */ + + if ((ptr - run) > 0) { + /* write out any pending text */ + context->cursor->insertText(QString::fromLatin1((char *)run, ptr - run)); + textlen += (ptr - run); + } + + ptr++; + fctype = GET_FUNCTION_CODE_TYPE(*ptr); + fclen = GET_FUNCTION_CODE_DATALEN(*ptr); + ptr++; + + if (fctype == PLKR_TFC_NEWLINE) { + // TODO: remove the setCharFormat when Qt is fixed + QTextCharFormat format(context->cursor->charFormat()); + context->cursor->insertText(QStringLiteral("\n")); + context->cursor->setCharFormat(format); + } else if (fctype == PLKR_TFC_LINK) { + int record_id, real_record_id, datalen; + plkr_DataRecordType type = (plkr_DataRecordType)0; + unsigned char *bytes = nullptr; + char *url = nullptr; + + if (fclen == 0) { + if (current_link) { + if (!context->stack.isEmpty()) + context->cursor->setCharFormat(context->stack.pop()); + + if (!context->linkUrl.isEmpty()) { + Link link; + link.url = context->linkUrl; + link.start = context->linkStart; + link.end = context->cursor->position(); + link.page = GetPageID(id); + mLinks.append(link); + } + } + current_link = false; + } else { + record_id = (ptr[0] << 8) + ptr[1]; + bytes = plkr_GetRecordBytes(doc, record_id, &datalen, &type); + if (!bytes) { + url = plkr_GetRecordURL(doc, record_id); + } + if (bytes && (type == PLKR_DRTYPE_MAILTO)) { + context->linkUrl = MailtoURLFromBytes(bytes); + context->linkStart = context->cursor->position(); + + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + format.setForeground(Qt::blue); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + context->cursor->setCharFormat(format); + current_link = true; + } else if (!bytes && url) { + context->linkUrl = QString::fromLatin1(url); + context->linkStart = context->cursor->position(); + + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + format.setForeground(Qt::blue); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + context->cursor->setCharFormat(format); + current_link = true; + } else if (bytes && (fclen == 2)) { + AddRecord(record_id); + real_record_id = GetPageID(record_id); + if (type == PLKR_DRTYPE_IMAGE || type == PLKR_DRTYPE_IMAGE_COMPRESSED) { + context->linkUrl = QStringLiteral("%1.jpg").arg(record_id); + context->linkStart = context->cursor->position(); + } else { + context->linkUrl = QStringLiteral("page:%1").arg(real_record_id); + context->linkStart = context->cursor->position(); + } + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + format.setForeground(Qt::blue); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + context->cursor->setCharFormat(format); + current_link = true; + } else if (bytes && (fclen == 4)) { + AddRecord(record_id); + + context->linkUrl = QStringLiteral("para:%1-%2").arg(record_id).arg((ptr[2] << 8) + ptr[3]); + context->linkStart = context->cursor->position(); + + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + format.setForeground(Qt::blue); + format.setUnderlineStyle(QTextCharFormat::SingleUnderline); + context->cursor->setCharFormat(format); + current_link = true; + } else { + // ShowWarning("odd link found: record_id=%d, bytes=0x%p, type=%d, url=%s", record_id, bytes, type, (url ? url : "0x0")); + } + } + + } else if (fctype == PLKR_TFC_FONT) { + if (current_font != *ptr) { + if (!context->stack.isEmpty()) + context->cursor->setCharFormat(context->stack.pop()); + + QTextCharFormat format(context->cursor->charFormat()); + context->stack.push(format); + + int pointSize = qRound(format.fontPointSize()); + if (*ptr == 1) { + format.setFontWeight(QFont::Bold); + pointSize += 3; + } else if (*ptr == 2) { + format.setFontWeight(QFont::Bold); + pointSize += 2; + } else if (*ptr == 3) { + format.setFontWeight(QFont::Bold); + pointSize += 1; + } else if (*ptr == 4) { + format.setFontWeight(QFont::Bold); + } else if (*ptr == 5) { + format.setFontWeight(QFont::Bold); + pointSize += -1; + } else if (*ptr == 6) { + format.setFontWeight(QFont::Bold); + pointSize += -2; + } else if (*ptr == 7) { + format.setFontWeight(QFont::Bold); + } else if (*ptr == 8) { + format.setFontFamily(QStringLiteral("Courier New,courier")); + } else if (*ptr == 11) { + format.setVerticalAlignment(QTextCharFormat::AlignSuperScript); + } + format.setFontPointSize(qMax(pointSize, 1)); + + context->cursor->setCharFormat(format); + + current_font = *ptr; + } + + } else if (fctype == PLKR_TFC_BITALIC) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontItalic(true); + context->cursor->setCharFormat(format); + + current_italic = true; + + } else if (fctype == PLKR_TFC_EITALIC) { + if (current_italic) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontItalic(false); + context->cursor->setCharFormat(format); + current_italic = false; + } + + } else if (fctype == PLKR_TFC_BULINE) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontUnderline(true); + context->cursor->setCharFormat(format); + current_underline = true; + + } else if (fctype == PLKR_TFC_EULINE) { + if (current_underline) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontUnderline(false); + context->cursor->setCharFormat(format); + current_underline = false; + } + + } else if (fctype == PLKR_TFC_BSTRIKE) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontStrikeOut(true); + context->cursor->setCharFormat(format); + current_struckthrough = true; + + } else if (fctype == PLKR_TFC_ESTRIKE) { + if (current_struckthrough) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontStrikeOut(false); + context->cursor->setCharFormat(format); + current_struckthrough = false; + } + + } else if (fctype == PLKR_TFC_HRULE) { + QTextCharFormat charFormat = context->cursor->charFormat(); + QTextBlockFormat oldBlockFormat = context->cursor->blockFormat(); + + QTextBlockFormat blockFormat; + blockFormat.setProperty(QTextFormat::BlockTrailingHorizontalRulerWidth, QStringLiteral("100%")); + context->cursor->insertBlock(blockFormat); + context->cursor->insertBlock(oldBlockFormat); + context->cursor->setCharFormat(charFormat); + } else if (fctype == PLKR_TFC_ALIGN) { + // current_alignment = 0; + + if (*ptr < 4) { + QTextBlockFormat format(context->cursor->blockFormat()); + if (*ptr == 0) + format.setAlignment(Qt::AlignLeft); + else if (*ptr == 1) + format.setAlignment(Qt::AlignRight); + else if (*ptr == 2) + format.setAlignment(Qt::AlignCenter); + else if (*ptr == 3) + format.setAlignment(Qt::AlignJustify); + + QTextCharFormat charFormat(context->cursor->charFormat()); + context->cursor->insertBlock(format); + context->cursor->setCharFormat(charFormat); + + // current_alignment = (*ptr) + 1; + } + + } else if (fctype == PLKR_TFC_MARGINS) { + /* Not easy to set, in HTML */ +#if 0 + output += QString( "" ).arg(ptr[0], ptr[1]); + if (current_left_margin != ptr[0] + || current_right_margin != ptr[1]) { + if (current_right_margin != 0) + fprintf (fp, " ", + current_right_margin); + fprintf (fp, "\n"); + } + current_left_margin = ptr[0]; + current_right_margin = ptr[1]; + if (current_right_margin > 0 + || current_left_margin > 0) { + fprintf (fp, ""); + if (current_left_margin != 0) { + fprintf (fp, ""); + } + fprintf (fp, "
", + current_left_margin); + if ((ptr - run) > 2) { + fwrite (run, 1, ((ptr - 2) - run), fp); + textlen += ((ptr - 2) - run); + } + else { + fprintf (fp, " "); + } + fprintf (fp, ""); + if (current_left_margin == 0 && (ptr - run) > 2) { + fwrite (run, 1, ((ptr - 2) - run), fp); + textlen += ((ptr - 2) - run); + } + } + else { + if ((ptr - run) > 2) { + fwrite (run, 1, ((ptr - 2) - run), fp); + textlen += ((ptr - 2) - run); + } + } +#endif + + // current_left_margin = ptr[0]; + // current_right_margin = ptr[1]; + + } else if (fctype == PLKR_TFC_COLOR) { + /* not sure what to do here yet */ + /* + fprintf (fp, "", + ptr[0], ptr[1], ptr[2]);*/ + // current_color = + // (ptr[0] << 16) + (ptr[1] << 8) + ptr[2]; + + } else if (fctype == PLKR_TFC_IMAGE || fctype == PLKR_TFC_IMAGE2) { + QTextCharFormat format = context->cursor->charFormat(); + context->cursor->insertImage(QStringLiteral("%1.jpg").arg((ptr[0] << 8) + ptr[1])); + context->images.append((ptr[0] << 8) + ptr[1]); + context->cursor->setCharFormat(format); + AddRecord((ptr[0] << 8) + ptr[1]); + + } else if (fctype == PLKR_TFC_TABLE) { + int record_id, datalen; + plkr_DataRecordType type = (plkr_DataRecordType)0; + unsigned char *bytes = nullptr; + + record_id = (ptr[0] << 8) + ptr[1]; + bytes = plkr_GetRecordBytes(doc, record_id, &datalen, &type); + + TranscribeTableRecord(doc, context, bytes); + + } else if (fctype == PLKR_TFC_UCHAR) { + if (fclen == 3) + context->cursor->insertText(QChar((ptr[1] << 8) + ptr[2])); + else if (fclen == 5) + context->cursor->insertText(QChar((ptr[3] << 8) + ptr[4])); + /* skip over alternate text */ + ptr += ptr[0]; + + } else { + /* ignore function */ + // output += QString( "" ).arg(fctype); + } + + ptr += fclen; + run = ptr; + } else { + ptr++; + } + } + + if ((ptr - run) > 0) { + /* output any pending text at the end of the paragraph */ + context->cursor->insertText(QString::fromLatin1((char *)run, ptr - run)); + textlen += (ptr - run); + run = ptr; + } + + /* clear the graphics state again */ + + if (current_font > 0 && current_font < 9) { + if (!context->stack.isEmpty()) + context->cursor->setCharFormat(context->stack.pop()); + } + + if (current_italic) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontItalic(false); + context->cursor->setCharFormat(format); + } + if (current_underline) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontUnderline(false); + context->cursor->setCharFormat(format); + } + if (current_struckthrough) { + QTextCharFormat format(context->cursor->charFormat()); + format.setFontStrikeOut(false); + context->cursor->setCharFormat(format); + } +#if 0 + if (current_alignment > 0) { + context->cursor->insertBlock(); + } + + if (current_right_margin > 0) + fprintf (fp, " 
", + current_right_margin); + else if (current_left_margin > 0) + fprintf (fp, ""); + + /* end the paragraph */ + context->cursor->insertBlock(); +#endif + } + free(paragraphs); + return true; +} + +bool QUnpluck::TranscribeRecord(int index) +{ + plkr_DataRecordType type; + int data_len; + bool status = true; + + unsigned char *data = plkr_GetRecordBytes(mDocument, index, &data_len, &type); + if (!data) { + MarkRecordDone(index); + return false; + } + + if (type == PLKR_DRTYPE_TEXT_COMPRESSED || type == PLKR_DRTYPE_TEXT) { + QTextDocument *document = new QTextDocument; + + QTextFrameFormat format(document->rootFrame()->frameFormat()); + format.setMargin(20); + document->rootFrame()->setFrameFormat(format); + + Context *context = new Context; + context->recordId = index; + context->document = document; + context->cursor = new QTextCursor(document); + + QTextCharFormat charFormat; + charFormat.setFontPointSize(10); + charFormat.setFontFamily(QStringLiteral("Helvetica")); + context->cursor->setCharFormat(charFormat); + + status = TranscribeTextRecord(mDocument, index, context, data, type); + document->setTextWidth(600); + + delete context->cursor; + mContext.append(context); + } else if (type == PLKR_DRTYPE_IMAGE_COMPRESSED || type == PLKR_DRTYPE_IMAGE) { + QImage image = TranscribeImageRecord(data); + mImages.insert(index, image); + } else if (type == PLKR_DRTYPE_MULTIIMAGE) { + QImage image; + if (TranscribeMultiImageRecord(mDocument, image, data)) + mImages.insert(index, image); + } else { + status = false; + } + + // plkr_GetHomeRecordID (doc))) + + MarkRecordDone(index); + + return status; +} diff --git a/generators/plucker/unpluck/qunpluck.h b/generators/plucker/unpluck/qunpluck.h new file mode 100644 index 0000000..40efb56 --- /dev/null +++ b/generators/plucker/unpluck/qunpluck.h @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * Based on code written by Bill Janssen 2002 * + * * + * 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 QUNPLUCK_H +#define QUNPLUCK_H + +#include +#include +#include +#include + +#include "unpluck.h" + +class Context; +class RecordNode; +class QTextDocument; + +namespace Okular +{ +class Action; +} + +class Link +{ +public: + Link() + : link(nullptr) + { + } + + typedef QVector List; + + Okular::Action *link; + QString url; + int page; + int start; + int end; +}; + +class QUnpluck +{ +public: + QUnpluck(); + ~QUnpluck(); + + QUnpluck(const QUnpluck &) = delete; + QUnpluck &operator=(const QUnpluck &) = delete; + + bool open(const QString &fileName); + + QList pages() const + { + return mPages; + } + Link::List links() const + { + return mLinks; + } + QMap infos() const + { + return mInfo; + } + +private: + int GetNextRecordNumber(); + int GetPageID(int index); + void AddRecord(int index); + void MarkRecordDone(int index); + void SetPageID(int index, int page_id); + QString MailtoURLFromBytes(unsigned char *record_data); + void DoStyle(Context *context, int style, bool start); + bool TranscribeRecord(int index); + QImage TranscribeImageRecord(unsigned char *bytes); + bool TranscribeTableRecord(plkr_Document *doc, Context *context, unsigned char *bytes); + bool TranscribeTextRecord(plkr_Document *doc, int id, Context *context, unsigned char *bytes, plkr_DataRecordType type); + void ParseText(plkr_Document *doc, unsigned char *ptr, int text_len, int *font, int *style, Context *context); + + plkr_Document *mDocument; + QList mRecords; + + QList mContext; + QList mPages; + QMap> mNamedTargets; + QMap mImages; + QMap mInfo; + QString mErrorString; + Link::List mLinks; +}; + +#endif diff --git a/generators/plucker/unpluck/unpluck.cpp b/generators/plucker/unpluck/unpluck.cpp new file mode 100644 index 0000000..06d3fc3 --- /dev/null +++ b/generators/plucker/unpluck/unpluck.cpp @@ -0,0 +1,947 @@ +/* -*- mode: c; indent-tabs-mode: nil; -*- + * $Id: unpluck.c,v 1.12 2003/12/28 20:59:21 chrish Exp $ + * + * unpluck -- a library to read Plucker data files + * Copyright (c) 2002, Bill Janssen + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if !defined(WIN32) +#include /* for lseek, etc. */ +#else +#include +#endif +#include /* for assert() */ +#include /* for errno */ +#include /* for O_RDONLY */ +#include +#include /* for strndup() */ +#include /* for fstat() */ +#include + +#include + +#include "unpluck.h" +#include "unpluckint.h" + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Decompression code (taken from the Plucker PalmOS viewer *****/ +/***** sources, Copyright (c) 1998-2002, by Mark Ian Lillywhite *****/ +/***** and Michael Nordstr�m, also under the GPL) *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +/* uncompress DOC compressed document/image */ +static unsigned int UncompressDOC(unsigned char *src, /* in: compressed document */ + unsigned int src_len, /* in: size of compressed document */ + unsigned char *dest, /* out: buffer to put uncompressed + document in */ + unsigned int dest_len /* out: size of buffer to put uncompressed + document in */ +) +{ + // unsigned int offset; + unsigned int src_index; + unsigned int dest_index; + + assert(src != nullptr && src_len != 0 && dest != nullptr && dest_len != 0); + + // offset = 0; + src_index = 0; + dest_index = 0; + memset(dest, 0, dest_len); + + while (src_index < src_len) { + unsigned int token; + + token = (unsigned int)src[src_index++]; + if (0 < token && token < 9) { + while (token != 0) { + dest[dest_index++] = src[src_index++]; + token--; + } + } else if (token < 0x80) { + dest[dest_index++] = token; + } else if (0xc0 <= token) { + dest[dest_index++] = ' '; + dest[dest_index++] = token ^ 0x80; + } else { + int m; + int n; + + token *= 256; + token += src[src_index++]; + + m = (token & 0x3fff) / 8; + n = token & 7; + n += 3; + while (n != 0) { + dest[dest_index] = dest[dest_index - m]; + dest_index++; + n--; + } + } + } + assert(src_index == src_len && dest_index == dest_len); + + return 1; +} + +/* uncompress ZLib compressed document/image */ +static unsigned int UncompressZLib(unsigned char *src, /* in: compressed document */ + unsigned int src_len, /* in: size of compressed document */ + unsigned char *dest, /* out: buffer to put uncompressed + document in */ + unsigned int dest_len, /* out: size of buffer to put uncompressed + document in */ + unsigned char *owner_id /* in: owner-id key */ +) +{ + z_stream z; + unsigned int err; + unsigned int keylen; + unsigned int i; + unsigned char keybuf[OWNER_ID_HASH_LEN]; + + assert(src != nullptr && src_len != 0 && dest != nullptr && dest_len != 0); + + keylen = (owner_id == nullptr) ? 0 : MIN(src_len, OWNER_ID_HASH_LEN); + + memset(&z, 0, sizeof z); + + if (owner_id != nullptr) { + for (i = 0; i < keylen; i++) + keybuf[i] = src[i] ^ owner_id[i]; + z.next_in = keybuf; + z.avail_in = keylen; + + } else { + z.next_in = src; + z.avail_in = src_len; + } + + z.next_out = dest; + z.avail_out = dest_len; + + err = inflateInit(&z); + if (err != Z_OK) { + return err; + } + + do { + if (z.avail_in == 0 && keylen > 0) { + z.next_in = src + keylen; + z.avail_in = src_len - keylen; + } + + err = inflate(&z, Z_SYNC_FLUSH); + + } while (err == Z_OK); + + if (err != Z_STREAM_END) + return err; + + assert(z.total_out == dest_len); + + return inflateEnd(&z); +} + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** "Open" the DB (read the headers and parse the various *****/ +/***** metadata, like URLs, default categories, charsets, etc.) *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +static void FreePluckerDoc(plkr_Document *doc) +{ + if (doc->name != nullptr) + free(doc->name); + if (doc->title != nullptr) + free(doc->title); + if (doc->author != nullptr) + free(doc->author); + if (doc->records != nullptr) { + int i; + for (i = 0; i < doc->nrecords; i++) { + if (doc->records[i].cache != nullptr) + free(doc->records[i].cache); + } + free(doc->records); + } + if (doc->urls != nullptr) + free(doc->urls); + if (doc->handle != nullptr) + doc->handle->free(doc->handle); + free(doc); +} + +static plkr_DataRecord *FindRecordByIndex(plkr_Document *doc, int record_index) +{ + int imin; + int imax; + int itest; + + for (imin = 0, imax = doc->nrecords; imin < imax;) { + itest = imin + (imax - imin) / 2; + /* _plkr_message("imin = %2d, imax = %2d, itest = %2d (%2d), record_index = %2d", + imin, imax, itest, doc->records[itest].uid, record_index); */ + if (doc->records[itest].uid == record_index) + return &doc->records[itest]; + else if (record_index > doc->records[itest].uid) + imin = itest + 1; + else if (record_index < doc->records[itest].uid) + imax = itest; + } + return nullptr; +} + +static int +GetUncompressedRecord(plkr_Document *doc, plkr_DBHandle handle, int record_index, unsigned char *buffer, int buffer_size, plkr_DataRecordType expected_type, unsigned char **buffer_out, int *buffer_size_out, plkr_DataRecord **record_out) +{ + /* read whole data record, including header, into buffer. If some part of the + record is compressed, uncompress it. If "buffer" is NULL, allocate enough + bytes to fit. Returns TRUE if read is successful, and sets "buffer_out" and + "buffer_size_out" and "record_out" on successful return. */ + + plkr_DataRecord *record; + unsigned char *tbuffer = buffer; + int size_needed; + int blen = buffer_size; + + record = FindRecordByIndex(doc, record_index); + if (record == nullptr) { + _plkr_message("No record with index %d", record_index); + return FALSE; + }; + if (expected_type != PLKR_DRTYPE_NONE && record->type != expected_type) { + _plkr_message("Record %d has unexpected type %d; expected %d", record_index, record->type, expected_type); + return FALSE; + } + + /* figure size needed */ + size_needed = record->uncompressed_size + 8; + if ((record->type == PLKR_DRTYPE_TEXT_COMPRESSED) || (record->type == PLKR_DRTYPE_TEXT)) + size_needed += 4 * record->nparagraphs; + + if (!buffer) { + if (buffer_out == nullptr) { + _plkr_message("No output buffer"); + return FALSE; + } else if (record->cache) { + tbuffer = record->cache; + size_needed = record->cached_size; + } else { + tbuffer = (unsigned char *)malloc(size_needed); + blen = size_needed; + } + } else { + tbuffer = buffer; + if (buffer_size < size_needed) { + _plkr_message("Buffer too small; needs %d", size_needed); + return FALSE; + } else if (record->cache) { + memcpy(buffer, record->cache, record->cached_size); + size_needed = record->cached_size; + } + } + + if (!record->cache) { + if ((record->type == PLKR_DRTYPE_TEXT_COMPRESSED) || (record->type == PLKR_DRTYPE_IMAGE_COMPRESSED) || (record->type == PLKR_DRTYPE_TABLE_COMPRESSED) || (record->type == PLKR_DRTYPE_GLYPHPAGE) || + (record->type == PLKR_DRTYPE_LINKS_COMPRESSED)) { + unsigned char *start_of_data, *output_ptr; + int len_of_data, buffer_remaining, buf_to_use; + unsigned char *buf = (unsigned char *)malloc(record->size); + + if (!handle->seek(handle, record->offset) || (handle->read(handle, buf, record->size, record->size) != record->size)) { + _plkr_message("Bad read from DBHandle while reading record %d", record->uid); + free(buf); + if (tbuffer != buffer) + free(tbuffer); + return FALSE; + } + +#if 0 + _plkr_message + ("data record %d (%d): uid is %d, # paras = %d, size = %d, type = %d", + record_index, record->size, (buf[0] << 8) + buf[1], + (buf[2] << 8) + buf[3], (buf[4] << 8) + buf[5], buf[6]); +#endif + + memcpy(tbuffer, buf, 8); + output_ptr = tbuffer + 8; + buffer_remaining = blen - 8; + start_of_data = buf + 8; + len_of_data = record->size - 8; + if (record->type == PLKR_DRTYPE_TEXT_COMPRESSED) { + /* skip over the paragraph headers */ + memcpy(output_ptr, start_of_data, 4 * record->nparagraphs); + start_of_data += (4 * record->nparagraphs); + len_of_data -= (4 * record->nparagraphs); + output_ptr += (4 * record->nparagraphs); + buffer_remaining -= (4 * record->nparagraphs); + } + + buf_to_use = size_needed - (start_of_data - buf); + if (doc->compression == PLKR_COMPRESSION_ZLIB) { + if (UncompressZLib(start_of_data, len_of_data, output_ptr, buf_to_use, (doc->owner_id_required ? doc->owner_id_key : nullptr)) != Z_OK) { + _plkr_message("Bad Zlib uncompress of record %d", record_index); + free(buf); + if (tbuffer != buffer) + free(tbuffer); + return FALSE; + }; + } else if (doc->compression == PLKR_COMPRESSION_DOC) { + if (UncompressDOC(start_of_data, len_of_data, output_ptr, buf_to_use) != 1) { + _plkr_message("Bad DOC uncompress of record %d", record_index); + free(buf); + if (tbuffer != buffer) + free(tbuffer); + return FALSE; + }; + } + free(buf); + } else { + /* all the record types which don't use compression */ + if (!handle->seek(handle, record->offset) || (handle->read(handle, tbuffer, blen, size_needed) != size_needed)) { + _plkr_message("Bad read from DBHandle while reading record %d", record->uid); + if (tbuffer != buffer) + free(tbuffer); + return FALSE; + } + } + } + + if (record_out) + *record_out = record; + if (buffer_out) + *buffer_out = tbuffer; + if (buffer_size_out) + *buffer_size_out = size_needed; + return TRUE; +} + +static int ParseCategories(plkr_Document *newdoc, plkr_DBHandle handle) +{ + struct _plkr_CategoryName *categories; + struct _plkr_CategoryName *newc; + plkr_DataRecord *record; + unsigned char *buf; + unsigned char *ptr; + int bufsize; + + if (GetUncompressedRecord(newdoc, handle, newdoc->default_category_record_uid, nullptr, 0, PLKR_DRTYPE_CATEGORY, &buf, &bufsize, &record)) { + /* keep the record data, since the list of char * ptrs will point into it */ + record->cache = buf; + record->cached_size = bufsize; + categories = nullptr; + for (ptr = buf + 8; (ptr - buf) < bufsize;) { + newc = (struct _plkr_CategoryName *)malloc(sizeof(struct _plkr_CategoryName)); + newc->next = categories; + categories = newc; + newc->name = (char *)ptr; + ptr += (strlen((char *)ptr) + 1); + } + newdoc->default_categories = categories; + return TRUE; + } else { + return FALSE; + } +} + +static int ParseMetadata(plkr_Document *newdoc, plkr_DBHandle handle) +{ + unsigned char *buf; + unsigned char *ptr; + int bufsize; + int nsubrecords; + int typecode; + int subrecord_length; + int i; + + if (!GetUncompressedRecord(newdoc, handle, newdoc->metadata_record_uid, nullptr, 0, PLKR_DRTYPE_METADATA, &buf, &bufsize, nullptr)) { + return FALSE; + } else { + nsubrecords = (buf[8] << 8) + buf[9]; + for (i = 0, ptr = buf + 10; i < nsubrecords; i++) { + typecode = (ptr[0] << 8) + ptr[1]; + subrecord_length = ((ptr[2] << 8) + ptr[3]) * 2; + + if (typecode == PLKR_MDTYPE_DEFAULTCHARSET) { + newdoc->default_charset_mibenum = (ptr[4] << 8) + ptr[5]; + ptr += 6; + + } else if (typecode == PLKR_MDTYPE_EXCEPTCHARSETS) { + int i, n, record_id, mibenum; + plkr_DataRecord *record; + + ptr += 4; + for (i = 0, n = subrecord_length / 4; i < n; i++, ptr += 4) { + record_id = (ptr[0] << 8) + ptr[1]; + mibenum = (ptr[2] << 8) + ptr[3]; + record = FindRecordByIndex(newdoc, record_id); + if (record == nullptr) { + _plkr_message("Can't find record with id %d", record_id); + free(buf); + return FALSE; + } + record->charset_mibenum = mibenum; + } + + } else if (typecode == PLKR_MDTYPE_OWNERIDCRC) { + newdoc->owner_id_required = TRUE; + ptr += 8; + + } else if (typecode == PLKR_MDTYPE_AUTHOR) { + newdoc->author = _plkr_strndup((char *)(ptr + 4), subrecord_length); + ptr += (4 + subrecord_length); + + } else if (typecode == PLKR_MDTYPE_TITLE) { + newdoc->title = _plkr_strndup((char *)(ptr + 4), subrecord_length); + ptr += (4 + subrecord_length); + + } else if (typecode == PLKR_MDTYPE_PUBLICATIONTIME) { + newdoc->publication_time = READ_BIGENDIAN_LONG(ptr + 4) - PLKR_TIMEADJUST; + ptr += 8; + + } else { + _plkr_message("Bad metadata typecode %d encountered in metadata record", typecode); + free(buf); + return FALSE; + } + } + free(buf); + return TRUE; + } +} + +static int ParseURLs(plkr_Document *newdoc, plkr_DBHandle handle) +{ + plkr_DataRecord *record; + unsigned char *buf; + unsigned char *ptr; + char **urls; + int id; + int i; + int n; + int count; + int nurls; + int bufsize; + + struct url_index_record { + int last_url_index; + int record_id; + } * records; + + buf = nullptr; + urls = nullptr; + records = nullptr; + + if (!GetUncompressedRecord(newdoc, handle, newdoc->urls_index_record_uid, nullptr, 0, PLKR_DRTYPE_LINKS_INDEX, &buf, &bufsize, nullptr)) { + return FALSE; + } else { + n = ((buf[4] << 8) + buf[5]) / 4; + records = (struct url_index_record *)malloc(n * sizeof(*records)); + for (i = 0, nurls = 0; i < n; i++) { + ptr = buf + 8 + (i * 4); + records[i].last_url_index = (ptr[0] << 8) + ptr[1]; + records[i].record_id = (ptr[2] << 8) + ptr[3]; +#ifdef DEBUGURLS + _plkr_message("index %3d: last = %d, record_id = %d", i, records[i].last_url_index, records[i].record_id); +#endif /* def DEBUGURLS */ + nurls = MAX(nurls, records[i].last_url_index); + } + free(buf); + buf = nullptr; + } + + urls = (char **)malloc(nurls * sizeof(char *)); + memset(urls, 0, nurls * sizeof(char *)); + + for (count = 0, i = 0; i < n; i++) { + id = records[i].record_id; + if (!GetUncompressedRecord(newdoc, handle, id, nullptr, 0, PLKR_DRTYPE_NONE, &buf, &bufsize, &record)) { + goto errout4; + } + if (record->type != PLKR_DRTYPE_LINKS && record->type != PLKR_DRTYPE_LINKS_COMPRESSED) { + _plkr_message("Supposed URLs record has bad type %d", record->type); + goto errout4; + } + record->cache = buf; + record->cached_size = bufsize; + buf = nullptr; + for (ptr = record->cache + 8; (ptr - record->cache) < record->cached_size; ptr += (strlen((char *)ptr) + 1)) { +#ifdef DEBUGURLS + _plkr_message("%3d: %s", count, ptr); +#endif /* def DEBUGURLS */ + assert(count < nurls); + urls[count++] = (char *)ptr; + } + } + free(records); + newdoc->urls = urls; + newdoc->nurls = nurls; + + return TRUE; + +errout4: + if (buf != nullptr) + free(buf); + free(urls); + free(records); + return FALSE; +} + +plkr_Document *plkr_OpenDoc(plkr_DBHandle handle) +{ + ReservedRecordEntry reserved[MAX_RESERVED]; + plkr_DataRecord *record; + plkr_Document *newdoc; + unsigned char utilbuf[128]; + static char id_stamp[9] = "DataPlkr"; + int i; + int nreserved; + int records_size; + int compression; + + if (!handle->seek(handle, 0) || (handle->read(handle, utilbuf, sizeof(utilbuf), 78) != 78)) { + _plkr_message("Bad read of DB header"); + return nullptr; + } + + /* check for type stamp */ + if (strncmp((char *)(utilbuf + 60), id_stamp, 8) != 0) { + _plkr_message("Bad magic number"); + return nullptr; + } + + /* check for version 1 */ + i = (utilbuf[34] << 8) + utilbuf[35]; + if (i != 1) { + _plkr_message("Not version 1 of Plucker format; version %d", i); + return nullptr; + } + + /* get the title, creation time, and last modification time from header */ + newdoc = (plkr_Document *)malloc(sizeof(plkr_Document)); + memset(newdoc, 0, sizeof(plkr_Document)); + newdoc->name = (char *)_plkr_strndup((char *)utilbuf, MIN(strlen((char *)utilbuf), 32)); + newdoc->creation_time = (time_t)((utilbuf[36] << 24) + (utilbuf[37] << 16) + (utilbuf[38] << 8) + utilbuf[39] - PLKR_TIMEADJUST); + newdoc->modification_time = (time_t)((utilbuf[40] << 24) + (utilbuf[41] << 16) + (utilbuf[42] << 8) + utilbuf[43] - PLKR_TIMEADJUST); + newdoc->nrecords = (utilbuf[76] << 8) + utilbuf[77]; + + /* Now read the record-list to find out where the records are */ + records_size = sizeof(plkr_DataRecord) * newdoc->nrecords; + newdoc->records = (plkr_DataRecord *)malloc(records_size); + memset(newdoc->records, 0, records_size); + for (i = 0; i < newdoc->nrecords; i++) { + if (handle->read(handle, utilbuf, sizeof(utilbuf), 8) != 8) { + _plkr_message("Bad read of record list"); + FreePluckerDoc(newdoc); + return nullptr; + } + newdoc->records[i].offset = (utilbuf[0] << 24) + (utilbuf[1] << 16) + (utilbuf[2] << 8) + utilbuf[3]; + } + + /* process the index record */ + if (!handle->seek(handle, newdoc->records[0].offset) || (handle->read(handle, utilbuf, sizeof(utilbuf), 6) != 6)) { + _plkr_message("Bad read of index record"); + FreePluckerDoc(newdoc); + return nullptr; + } + if ((utilbuf[0] << 8) + utilbuf[1] != 1) { + _plkr_message("index record has bad UID %d", (utilbuf[0] << 8) + utilbuf[1]); + FreePluckerDoc(newdoc); + return nullptr; + } + newdoc->records[0].uid = 1; + compression = (utilbuf[2] << 8) + utilbuf[3]; + if (compression == PLKR_COMPRESSION_DOC) + newdoc->compression = PLKR_COMPRESSION_DOC; + else if (compression == PLKR_COMPRESSION_ZLIB) + newdoc->compression = PLKR_COMPRESSION_ZLIB; + else { + _plkr_message("Unknown compression type %d", compression); + FreePluckerDoc(newdoc); + return nullptr; + } + nreserved = (utilbuf[4] << 8) + utilbuf[5]; + if (nreserved > MAX_RESERVED) { + _plkr_message("Too many reserved records (%d) for software", nreserved); + FreePluckerDoc(newdoc); + return nullptr; + } + for (i = 0; i < nreserved; i++) { + if (handle->read(handle, utilbuf, sizeof(utilbuf), 4) != 4) { + _plkr_message("Bad read of reserved record list"); + FreePluckerDoc(newdoc); + return nullptr; + } + reserved[i].name = (ReservedRecordName)((utilbuf[0] << 8) + utilbuf[1]); + reserved[i].uid = (utilbuf[2] << 8) + utilbuf[3]; + } + + /* OK, now process the data records */ + newdoc->max_record_size = 0; + for (i = 1; i < newdoc->nrecords; i++) { + record = newdoc->records + i; + if (!handle->seek(handle, record->offset) || (handle->read(handle, utilbuf, sizeof(utilbuf), 8) != 8)) { + _plkr_message("Can't read header of record %d", i); + FreePluckerDoc(newdoc); + return nullptr; + } + newdoc->records[i - 1].size = record->offset - newdoc->records[i - 1].offset; + record->uid = (utilbuf[0] << 8) + utilbuf[1]; + record->nparagraphs = (utilbuf[2] << 8) + utilbuf[3]; + record->uncompressed_size = (utilbuf[4] << 8) + utilbuf[5]; + record->type = (plkr_DataRecordType)utilbuf[6]; + newdoc->max_record_size = MAX(newdoc->max_record_size, record->uncompressed_size); + } + /* To get the size of the last record we subtract its offset from the total size of the DB. */ + if ((i = handle->size(handle)) == 0) { + _plkr_message("Can't obtain size of DB"); + FreePluckerDoc(newdoc); + return nullptr; + }; + record = newdoc->records + (newdoc->nrecords - 1); + record->size = i - record->offset; + /* make sure the uncompressed size is set, now that we know the record sizes */ + for (i = 0; i < newdoc->nrecords; i++) { + record = newdoc->records + i; + if (record->uncompressed_size == 0) { + if (record->type == PLKR_DRTYPE_LINKS_COMPRESSED || record->type == PLKR_DRTYPE_TEXT_COMPRESSED || record->type == PLKR_DRTYPE_TABLE_COMPRESSED || record->type == PLKR_DRTYPE_IMAGE_COMPRESSED) { + _plkr_message("Bad uncompressed size 0 in record uid %d", record->uid); + FreePluckerDoc(newdoc); + return nullptr; + } else { + record->uncompressed_size = record->size - 8; + } + } +#ifdef DEBUGOPEN + { + static char *types[] = {"TEXT", "TEXTC", "IMAGE", "IMAGEC", "MAILTO", "URLINDEX", "URLS", "URLSC", "BOOKMARKS", "CATEGORIES", "METADATA"}; + _plkr_message("%3d: type=%10s, offset=%07x, size=%5d, uncompressed_size=%5d", record->uid, types[MIN(record->type, sizeof(types) / sizeof(char *))], record->offset, record->size, record->uncompressed_size); + } +#endif + } + + /* find the reserved records */ + + /* do metadata first, to find out whether we need an owner_id key */ + for (i = 0; i < nreserved; i++) { + if (reserved[i].name == PLKR_METADATA_NAME) { + newdoc->metadata_record_uid = reserved[i].uid; + if (!ParseMetadata(newdoc, handle)) { + _plkr_message("Error parsing metadata record"); + FreePluckerDoc(newdoc); + return nullptr; + } + } + } + + if (newdoc->owner_id_required) { + /* we need to set up the owner-id key before uncompressing + any records... */ + + char *owner_id = plkr_GetConfigString(nullptr, "owner_id", nullptr); + + if (owner_id != nullptr) { + unsigned long crc; + int owner_id_len = strlen(owner_id); + crc = crc32(0L, nullptr, 0); + crc = crc32(crc, (const Bytef *)owner_id, owner_id_len); + for (i = 0; i < 10; i++) { + crc = crc32(crc, (const Bytef *)owner_id, owner_id_len); + newdoc->owner_id_key[(i * 4) + 0] = (unsigned char)((crc >> 24) & 0xFF); + newdoc->owner_id_key[(i * 4) + 1] = (unsigned char)((crc >> 16) & 0xFF); + newdoc->owner_id_key[(i * 4) + 2] = (unsigned char)((crc >> 8) & 0xFF); + newdoc->owner_id_key[(i * 4) + 3] = (unsigned char)(crc & 0xFF); + } + } else { + _plkr_message("Document requires owner-id to open"); + FreePluckerDoc(newdoc); + return nullptr; + } + } + + /* now do the rest of the reserved records */ + + for (i = 0; i < nreserved; i++) { + if (reserved[i].name == PLKR_HOME_NAME) + newdoc->home_record_uid = reserved[i].uid; + else if (reserved[i].name == PLKR_DEFAULT_CATEGORY_NAME) { + newdoc->default_category_record_uid = reserved[i].uid; + if (!ParseCategories(newdoc, handle)) { + _plkr_message("Error parsing default-categories record"); + FreePluckerDoc(newdoc); + return nullptr; + } + } else if (reserved[i].name == PLKR_URLS_INDEX_NAME) { + newdoc->urls_index_record_uid = reserved[i].uid; + if (!ParseURLs(newdoc, handle)) { + _plkr_message("Error parsing URLs records"); + FreePluckerDoc(newdoc); + return nullptr; + } + } + } + + newdoc->handle = handle; + +#ifdef DEBUGOPEN + /* test the record fetch by fetching them! */ + for (i = 1; i < newdoc->nrecords; i++) { + plkr_DataRecordType type; + int n; + printf( + "==============================================\n" + "record %3d (%d bytes)\n", + newdoc->records[i].uid, + newdoc->records[i].size); + (void)plkr_GetRecordBytes(newdoc, newdoc->records[i].uid, &n, &type); + } +#endif + + return newdoc; +} + +int plkr_GetUidForIndex(plkr_Document *doc, int record_index) +{ + return doc->records[record_index].uid; +} + +void plkr_CloseDoc(plkr_Document *doc) +{ + if (doc == nullptr) { + _plkr_message("Attempt to free NULL doc"); + } else { + FreePluckerDoc(doc); + } +} + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** An implementation of a file-based DBHandle *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +static int FpSeek(plkr_DBHandle handle, long offset) +{ + long result; + + result = lseek(handle->dbprivate, offset, SEEK_SET); + if (result != offset) { + _plkr_message("Unable to seek fp %d to offset %lu -- %lu instead\n", handle->dbprivate, offset, result); + } + return (result == offset); +} + +static int FpRead(plkr_DBHandle handle, unsigned char *buffer, int buffersize, int readsize) +{ + int result; + + result = read(handle->dbprivate, buffer, MIN(buffersize, readsize)); + if (result != readsize) { + _plkr_message("Unable to read %d bytes from fp %d -- read %d instead\n", MIN(buffersize, readsize), handle->dbprivate, result); + } + return (result); +} + +static void FpFree(plkr_DBHandle handle) +{ + int fp = handle->dbprivate; + + if (fp > 0) + close(fp); +} + +static long FpSize(plkr_DBHandle handle) +{ + int fp = handle->dbprivate; + + struct stat buf; + + if (fstat(fp, &buf) != 0) { + _plkr_message("Can't stat file; errno %d", errno); + return 0; + }; + return buf.st_size; +} + +plkr_Document *plkr_OpenDBFile(const char *filename) +{ + plkr_DBHandle handle; + plkr_Document *doc; + int fp; + +#if !defined(WIN32) + fp = open(filename, O_RDONLY); +#else + fp = open(filename, O_RDONLY | O_BINARY); +#endif + if (fp < 0) { + _plkr_message("Can't open file %s", filename); + return nullptr; + } + handle = (plkr_DBHandle)malloc(sizeof(*handle)); + handle->dbprivate = fp; + handle->seek = FpSeek; + handle->read = FpRead; + handle->free = FpFree; + handle->size = FpSize; + doc = plkr_OpenDoc(handle); + if (doc == nullptr) + close(fp); + return doc; +} + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Routines to access individual uncompressed records *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +int plkr_CopyRecordBytes(plkr_Document *doc, int record_index, unsigned char *output_buffer, int output_buffer_size, plkr_DataRecordType *type) +{ + plkr_DataRecord *record; + int output_size; + + if (!FindRecordByIndex(doc, record_index)) + return 0; + + if (!GetUncompressedRecord(doc, doc->handle, record_index, output_buffer, output_buffer_size, PLKR_DRTYPE_NONE, nullptr, &output_size, &record)) + return 0; + else { + *type = record->type; + return output_size; + } +} + +unsigned char *plkr_GetRecordBytes(plkr_Document *doc, int record_index, int *size, plkr_DataRecordType *type) +{ + plkr_DataRecord *record; + unsigned char *buf; + + if (!FindRecordByIndex(doc, record_index)) + return nullptr; + + if (!GetUncompressedRecord(doc, doc->handle, record_index, nullptr, 0, PLKR_DRTYPE_NONE, &buf, size, &record)) + return nullptr; + else { + if (!record->cache) { + record->cache = buf; + record->cached_size = *size; + } + *type = record->type; + return buf; + } +} + +int plkr_GetHomeRecordID(plkr_Document *doc) +{ + return doc->home_record_uid; +} + +char *plkr_GetName(plkr_Document *doc) +{ + return doc->name; +} + +char *plkr_GetTitle(plkr_Document *doc) +{ + return doc->title; +} + +char *plkr_GetAuthor(plkr_Document *doc) +{ + return doc->author; +} + +int plkr_GetDefaultCharset(plkr_Document *doc) +{ + return doc->default_charset_mibenum; +} + +unsigned long plkr_GetPublicationTime(plkr_Document *doc) +{ + if (doc->publication_time) + return (unsigned long)doc->publication_time; + else + return (unsigned long)doc->creation_time; +} + +plkr_CategoryList plkr_GetDefaultCategories(plkr_Document *doc) +{ + return doc->default_categories; +} + +int plkr_GetRecordCount(plkr_Document *doc) +{ + return doc->nrecords; +} + +int plkr_GetMaxRecordSize(plkr_Document *doc) +{ + return doc->max_record_size; +} + +char *plkr_GetRecordURL(plkr_Document *doc, int record_index) +{ + if (record_index < 1 || record_index > doc->nurls) + return nullptr; + else + return (doc->urls[record_index - 1]); +} + +int plkr_HasRecordWithID(plkr_Document *doc, int record_index) +{ + return (FindRecordByIndex(doc, record_index) != nullptr); +} + +int plkr_GetRecordType(plkr_Document *doc, int record_index) +{ + plkr_DataRecord *r; + + r = FindRecordByIndex(doc, record_index); + if (r) + return r->type; + else + return PLKR_DRTYPE_NONE; +} + +int plkr_GetRecordCharset(plkr_Document *doc, int record_index) +{ + plkr_DataRecord *r; + + r = FindRecordByIndex(doc, record_index); + if (r && ((r->type == PLKR_DRTYPE_TEXT_COMPRESSED) || (r->type == PLKR_DRTYPE_TEXT))) { + if (r->charset_mibenum == 0) + return doc->default_charset_mibenum; + else + return r->charset_mibenum; + } else + return 0; +} diff --git a/generators/plucker/unpluck/unpluck.h b/generators/plucker/unpluck/unpluck.h new file mode 100644 index 0000000..4c08a95 --- /dev/null +++ b/generators/plucker/unpluck/unpluck.h @@ -0,0 +1,300 @@ +/* -*- mode: c; indent-tabs-mode: nil; -*- + * $Id: unpluck.h,v 1.8 2003/12/28 20:59:21 chrish Exp $ + * + * unpluck -- a library to read Plucker data files + * Copyright (c) 2002, Bill Janssen + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef UNPLUCK_H +#define UNPLUCK_H +/* + * This header file should be included after an #include of glib.h + */ + +/* This represents a raw Palm DB. It's intended to be an abstraction + of a file pointer, so that raw memory can also be used. */ +typedef struct plkr_DBHandle_s *plkr_DBHandle; +struct plkr_DBHandle_s { + int dbprivate; + + /* Call seek to position the DB stream at the "offset" byte from the start of the DB. + Returns non-zero if seek has been successfully done, zero otherwise. */ + int (*seek)(plkr_DBHandle handle, long offset); + + /* Call read to read "readsize" bytes into "buffer", which is at least "buffersize" bytes large. + Returns number of bytes read. */ + int (*read)(plkr_DBHandle handle, unsigned char *buffer, int buffersize, int readsize); + + /* When called will return total size of DB */ + long (*size)(plkr_DBHandle handle); + + /* Hook that will be called when unpluck finishes with the handle. */ + void (*free)(plkr_DBHandle handle); +}; + +typedef enum { + PLKR_DRTYPE_TEXT = 0, + PLKR_DRTYPE_TEXT_COMPRESSED = 1, + PLKR_DRTYPE_IMAGE = 2, + PLKR_DRTYPE_IMAGE_COMPRESSED = 3, + PLKR_DRTYPE_MAILTO = 4, + PLKR_DRTYPE_LINKS_INDEX = 5, + PLKR_DRTYPE_LINKS = 6, + PLKR_DRTYPE_LINKS_COMPRESSED = 7, + PLKR_DRTYPE_BOOKMARKS = 8, + PLKR_DRTYPE_CATEGORY = 9, + PLKR_DRTYPE_METADATA = 10, + PLKR_DRTYPE_GLYPHPAGE = 11, + PLKR_DRTYPE_FONT_PAGE = 12, + PLKR_DRTYPE_TABLE = 13, + PLKR_DRTYPE_TABLE_COMPRESSED = 14, + PLKR_DRTYPE_MULTIIMAGE = 15, + + /* this record type is not used in the Plucker DB */ + PLKR_DRTYPE_NONE = 0xFFFF +} plkr_DataRecordType; + +#define PLKR_FC_CODE(v) (((v) >> 3) & 0x1F) + +typedef enum { + PLKR_TFC_LINK = PLKR_FC_CODE(0x0A), /* page or span link start or end */ + PLKR_TFC_FONT = PLKR_FC_CODE(0x11), /* set font */ + PLKR_TFC_IMAGE = PLKR_FC_CODE(0x1A), /* embedded image */ + PLKR_TFC_MARGINS = PLKR_FC_CODE(0x22), /* set left and right margins */ + PLKR_TFC_ALIGN = PLKR_FC_CODE(0x29), /* set text alignment */ + PLKR_TFC_HRULE = PLKR_FC_CODE(0x33), /* horizontal rule */ + PLKR_TFC_NEWLINE = PLKR_FC_CODE(0x38), /* start new line */ + PLKR_TFC_BITALIC = PLKR_FC_CODE(0x40), /* begin italic text */ + PLKR_TFC_EITALIC = PLKR_FC_CODE(0x48), /* end italic text */ + PLKR_TFC_COLOR = PLKR_FC_CODE(0x53), /* set text color */ + PLKR_TFC_IMAGE2 = PLKR_FC_CODE(0x5C), /* double embedded image */ + PLKR_TFC_BULINE = PLKR_FC_CODE(0x60), /* begin underline text */ + PLKR_TFC_EULINE = PLKR_FC_CODE(0x68), /* end underline text */ + PLKR_TFC_BSTRIKE = PLKR_FC_CODE(0x70), /* begin struck-through text */ + PLKR_TFC_ESTRIKE = PLKR_FC_CODE(0x78), /* end struck-through text */ + PLKR_TFC_UCHAR = PLKR_FC_CODE(0x83), /* 16 or 32 bit Unicode character */ + PLKR_TFC_GLYPH = PLKR_FC_CODE(0x88), /* glyph run */ + PLKR_TFC_TABLE = PLKR_FC_CODE(0x90) /* table data */ +} plkr_TextFunctionCodes; + +typedef enum { PLKR_FONT_REGULAR = 0, PLKR_FONT_H1 = 1, PLKR_FONT_H2 = 2, PLKR_FONT_H3 = 3, PLKR_FONT_H4 = 4, PLKR_FONT_H5 = 5, PLKR_FONT_H6 = 6, PLKR_FONT_REGULARBOLD = 7, PLKR_FONT_FIXEDWIDTH = 8 } plkr_FontStyles; + +typedef struct _plkr_CategoryName { + char *name; + struct _plkr_CategoryName *next; +} * plkr_CategoryList; + +typedef struct plkr_Document_s plkr_Document; + +/* ====================================================================== */ + +/* A number of functions defined in the library */ + +/* plkr_OpenDBFile + + Opens a Plucker document stored as a file indicated by "filename", + and returns a document handle. A NULL value is returned if some + aspect of the open or parse of the document structure fails. + This call consumes a file descriptor, which is held till a subsequent + call to plkr_CloseDoc. +*/ +plkr_Document *plkr_OpenDBFile(const char * /* filename */ +); + +/* plkr_OpenDoc + + A more general form of open. The caller can pass in a + plkr_DBHandle which might provide access to the bytes of the + document in an arbitrary way. A NULL value is returned if some + aspect of the open or parse of the document structure fails. +*/ +plkr_Document *plkr_OpenDoc(plkr_DBHandle); + +/* plkr_CloseDoc + + Closes the document and frees all storage associated with it, + including cached record data. Invokes the "free" method on + the plkr_DBHandle used to open the document. After this call, + the plkr_Document pointer is now invalid. +*/ +void plkr_CloseDoc(plkr_Document *); + +/* plkr_CopyRecordBytes + + Copies the uncompressed bytes of the data of the specified record + to the user-provided output buffer, and returns the number of bytes + copied. This call does not cache the uncompressed bytes. The type + of the record is returned in the "type" parameter. Zero bytes + will be copied if the output buffer is too small for the record + data. A 64K buffer will always be large enough; a call to + plkr_GetMaxRecordSize will return the uncompressed size of the largest + record in the document. +*/ +int plkr_CopyRecordBytes(plkr_Document *, int /* record_index */, unsigned char * /* output_buffer */, int /* output_buffer_size */, plkr_DataRecordType * /* output: type */ +); + +/* plkr_GetUidForIndex + + Retrieve the uid of the record with the given index. +*/ +int plkr_GetUidForIndex(plkr_Document *, int /* record_index */ +); + +/* plkr_GetRecordBytes + + Retrieve a static pointer to a buffer containing the uncompressed + data of the specified record. This causes the buffer to be cached + by the implementation; do not free() the returned pointer! The + size of the buffer is returned through the "size" parameter; the + type of the record is returned through the "type" parameter. + May return NULL if the "record_index" value is out-of-range. +*/ +unsigned char *plkr_GetRecordBytes(plkr_Document *, int /* record_index */, int * /* output: size */, plkr_DataRecordType * /* output: type */ +); + +/* plkr_GetRecordURL + + Retrieve a static pointer to the URL string for the specified record. + May return NULL if "record_index" is out-of-range, or if no URLs were + included in the document. Fetching the URL for the home page is a good + way to test for the latter. +*/ +char *plkr_GetRecordURL(plkr_Document *, int record_index); + +/* plkr_GetHomeRecordID + + Retrieve the record UID for the 'home' page, the root node of the + document. +*/ +int plkr_GetHomeRecordID(plkr_Document *); + +/* plkr_GetName + + Retrieve a static pointer to the short name of the document. +*/ +char *plkr_GetName(plkr_Document *); + +/* plkr_GetTitle + + Retrieve a static pointer to the title of the document. Returns NULL if no title was specified. +*/ +char *plkr_GetTitle(plkr_Document *); + +/* plkr_GetAuthor + + Retrieve a static pointer to the name of the author of the document. Returns NULL if no author was specified. +*/ +char *plkr_GetAuthor(plkr_Document *); + +/* plkr_GetDefaultCharset + + Returns the IANA mibenum of the default charset used in the document, or 0 if none was specified. +*/ +int plkr_GetDefaultCharset(plkr_Document *); + +/* plkr_GetPublicationTime + + Returns the time of publication of the document as an unsigned integer. If no explicit + publication time was included in the document, returns the creation date, which may be more recent. + Time is expressed as seconds past 12:00 am, Jan 1, 1970 -- the UNIX "epoch". +*/ +unsigned long plkr_GetPublicationTime(plkr_Document *); + +/* plkr_GetRecordCount + + Returns the number of records in the document. +*/ +int plkr_GetRecordCount(plkr_Document *); + +/* plkr_GetMaxRecordSize + + Returns the uncompressed data size of the largest record in the document. +*/ +int plkr_GetMaxRecordSize(plkr_Document *); + +/* plkr_GetDefaultCategories + + Retrieve a static GSList of char * values that are the default categories + assigned to the document. +*/ +plkr_CategoryList plkr_GetDefaultCategories(plkr_Document *); + +/* plkr_HasRecordWithID + + Returns 1 if the document has a record with the specified ID, 0 otherwise. +*/ +int plkr_HasRecordWithID(plkr_Document *, int /* ID */ +); + +/* plkr_GetRecordType + + Returns type of record, or PLKR_DRTYPE_NONE if record doesn't exist. +*/ +int plkr_GetRecordType(plkr_Document *, int /* ID */ +); + +/* plkr_GetRecordCharset + + Returns the mibenum of the charset of the record, if the record is a text record, + or 0 if the record doesn't exist or is not a text record. +*/ +int plkr_GetRecordCharset(plkr_Document *, int /* ID */ +); + +/* plkr_ShowMessages + + Controls whether or not message display is enabled. Call with 1 for messages + to be displayed, 0 for no display. Initial value is 0. Returns previous value. +*/ +int plkr_ShowMessages(int); + +/* plkr_GetConfigString + + Returns the string value for the option named "option_name" in section named + "section_name", if any, or "default_value" if no setting for that name. + If "section_name" is NULL, the default section ("default") is used. Section + names and option names should be all lowercase. +*/ +char *plkr_GetConfigString(const char *section_name, const char *option_name, char *default_value); + +/* plkr_GetConfigInt + + Returns the int value for the option named "option_name" in section named + "section_name", if any, or "default_value" if no setting for that name. + If "section_name" is NULL, the default section ("default") is used. Section + names and option names should be all lowercase. +*/ +long int plkr_GetConfigInt(const char *section_name, const char *option_name, long int default_value); + +/* plkr_GetConfigFloat + + Returns the double value for the option named "option_name" in section named + "section_name", if any, or "default_value" if no setting for that name. + If "section_name" is NULL, the default section ("default") is used. Section + names and option names should be all lowercase. +*/ +double plkr_GetConfigFloat(const char *section_name, const char *option_name, double default_value); + +/* plkr_GetConfigBoolean + + Returns the boolean value for the option named "option_name" in section named + "section_name", if any, or "default_value" if no setting for that name. + If "section_name" is NULL, the default section ("default") is used. Section + names and option names should be all lowercase. +*/ +int plkr_GetConfigBoolean(const char *section_name, const char *option_name, int default_value); +#endif diff --git a/generators/plucker/unpluck/unpluckint.h b/generators/plucker/unpluck/unpluckint.h new file mode 100644 index 0000000..1784e43 --- /dev/null +++ b/generators/plucker/unpluck/unpluckint.h @@ -0,0 +1,143 @@ +/* -*- mode: c; indent-tabs-mode: nil; -*- + * $Id: unpluckint.h,v 1.5 2003/12/28 20:59:21 chrish Exp $ + * + * unpluck -- a library to read Plucker data files + * Copyright (c) 2002, Bill Janssen + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef UNPLUGINT_H +#define UNPLUGINT_H +/* + * This header file should be included after an #include of glib.h + */ + +#define PLKR_TIMEADJUST \ + 2082848400 /* difference in seconds between \ + Palm timebase of 12 AM Jan 1, 1904, \ + and UNIX timebase of 12 AM Jan 1, 1970 */ + +#define MAX_RESERVED 8 + +#define OWNER_ID_HASH_LEN 40 + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#define READ_BIGENDIAN_SHORT(p) (((p)[0] << 8) | ((p)[1])) +#define READ_BIGENDIAN_LONG(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3])) + +typedef enum { PLKR_HOME_NAME = 0, PLKR_URLS_INDEX_NAME = 2, PLKR_DEFAULT_CATEGORY_NAME = 3, PLKR_METADATA_NAME = 4 } ReservedRecordName; + +typedef struct { + int uid; + ReservedRecordName name; +} ReservedRecordEntry; + +typedef enum { PLKR_MDTYPE_DEFAULTCHARSET = 1, PLKR_MDTYPE_EXCEPTCHARSETS = 2, PLKR_MDTYPE_OWNERIDCRC = 3, PLKR_MDTYPE_AUTHOR = 4, PLKR_MDTYPE_TITLE = 5, PLKR_MDTYPE_PUBLICATIONTIME = 6 } MetadataTypecodes; + +typedef enum { PLKR_COMPRESSION_DOC = 1, PLKR_COMPRESSION_ZLIB = 2 } plkr_CompressionType; + +typedef struct plkr_DataRecord_s plkr_DataRecord; + +/* A structure to hold information about each record */ +struct plkr_DataRecord_s { + long offset; + int size; /* size in DB */ + int uncompressed_size; /* size of compressed portion, when uncompressed */ + int cached_size; /* size of cached buffer, if cache is non-NULL */ + int uid; + int nparagraphs; + plkr_DataRecordType type; + unsigned char *cache; /* cache of uncompressed full record */ + int charset_mibenum; +}; + +/* The main data structure for the document */ +struct plkr_Document_s { + plkr_DBHandle handle; + char *name; /* short name in header */ + char *title; /* title in metadata, if any */ + char *author; /* author in metadata, if any */ + time_t publication_time; /* from metadata, if at all */ + time_t creation_time; /* from header */ + time_t modification_time; + plkr_CompressionType compression; + int nrecords; + plkr_DataRecord *records; + int max_record_size; + int home_record_uid; + int default_category_record_uid; + int metadata_record_uid; + int urls_index_record_uid; + char **urls; + int nurls; + plkr_CategoryList default_categories; + int default_charset_mibenum; + int owner_id_required; /* 1 for yes, 0 for no */ + unsigned char owner_id_key[40]; +}; + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Some simple utility routines so we don't need GLib *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +typedef struct HashTable HashTable; + +void _plkr_message(const char *formatSpec, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 1, 2))) +#endif + ; +/* Display the message to stderr */ + +char *_plkr_strndup(const char *str, int len); +/* return a freshly-malloced copy of str */ + +HashTable *_plkr_NewHashTable(int size); +/* create an instance of a string-keyed hash table and return it. + "size" is the number of buckets to start with -- should be prime. */ + +void *_plkr_FindInTable(HashTable *ht, const char *key); +/* lookup the specified "key" in the specified "ht". */ + +void *_plkr_RemoveFromTable(HashTable *ht, const char *key); +/* remove the entry with "key" from the table, if present, and return + the value as the result. */ + +int _plkr_AddToTable(HashTable *ht, const char *key, void *obj); +/* Add the specified "obj" to the table with key "key". Returns + 0 if key is already in table (and doesn't add "obj"), and returns + 1 if key was added to table. */ + +#endif diff --git a/generators/plucker/unpluck/util.cpp b/generators/plucker/unpluck/util.cpp new file mode 100644 index 0000000..e505757 --- /dev/null +++ b/generators/plucker/unpluck/util.cpp @@ -0,0 +1,215 @@ +/* -*- mode: c; indent-tabs-mode: nil; -*- + * $Id: util.c,v 1.3 2003/12/28 20:59:21 chrish Exp $ + * + * util -- Some simple utility routines so we don't need GLib + * Copyright (c) 2002, Bill Janssen + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#if !defined(WIN32) +#include /* for lseek, etc. */ +#else +#include +#endif +#include /* for assert() */ +#include /* for errno */ +#include /* for O_RDONLY */ +#include /* for _plkr_message */ +#include /* for stderr */ +#include +#include /* for strndup() */ +#include /* for fstat() */ +#include + +#include + +#include "unpluck.h" +#include "unpluckint.h" + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Messages *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +static int ShowMessages = 0; + +void _plkr_message(const char *formatSpec, ...) +{ + va_list ap; + + va_start(ap, formatSpec); + + if (ShowMessages) { + (void)vfprintf(stderr, formatSpec, ap); + fprintf(stderr, "\n"); + } + + va_end(ap); +} + +int plkr_ShowMessages(int val) +{ + int oldval = ShowMessages; + + ShowMessages = val; + return oldval; +} + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** String Utilities *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +char *_plkr_strndup(const char *str, int len) +{ + char *dup; + + dup = (char *)malloc(len + 1); + strncpy(dup, str, len); + dup[len] = 0; + return dup; +} + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** Simple hash table maps string keys to void * values *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +typedef struct { + char *he_key; + void *he_data; +} HashEntry; + +typedef struct { + int hs_count; + int hs_allocated; + HashEntry *hs_entries; +} HashTableSlot; + +struct HashTable { + int ht_size; + int ht_nPairs; + HashTableSlot *ht_slots; +}; + +#define HASH_INCREMENT_SIZE 5 + +#define hashtable_slot(ht, index) (&((ht)->ht_slots[index])) +#define hashtable_hash_index(ht, key) (HashString((key), (ht)->ht_size)) +#define hashtable_compare_keys(ht, key1, key2) (CompareStrings((key1), (key2))) + +static int CompareStrings(const char *key1, const char *key2) +{ + return (strcmp(key1, key2) == 0); +} + +static int HashString(const char *str, int size) +{ + unsigned long crc; + + crc = crc32(0L, nullptr, 0); + crc = crc32(crc, (const Bytef *)str, strlen(str)); + return (crc % size); +} + +void *_plkr_FindInTable(HashTable *ht, const char *key) +{ + HashTableSlot *slot; + int count; + + if (ht == nullptr) + return (nullptr); + slot = hashtable_slot(ht, hashtable_hash_index(ht, key)); + for (count = slot->hs_count; count > 0; count -= 1) + if (hashtable_compare_keys(ht, key, slot->hs_entries[count - 1].he_key)) + return (slot->hs_entries[count - 1].he_data); + return (nullptr); +} + +void *_plkr_RemoveFromTable(HashTable *ht, const char *key) +{ + HashTableSlot *slot; + int count; + + if (ht == nullptr) + return (nullptr); + + slot = hashtable_slot(ht, hashtable_hash_index(ht, key)); + for (count = 0; count < slot->hs_count; count += 1) + if (hashtable_compare_keys(ht, slot->hs_entries[count].he_key, key)) { + void *data = slot->hs_entries[count].he_data; + free(slot->hs_entries[count].he_key); + if ((1 + (unsigned)count) < (unsigned)slot->hs_count) + slot->hs_entries[count] = slot->hs_entries[slot->hs_count - 1]; + --ht->ht_nPairs; + if (--slot->hs_count <= 0) { + free(slot->hs_entries); + slot->hs_entries = nullptr; + slot->hs_allocated = 0; + slot->hs_count = 0; + } + return (data); + } + return (nullptr); +} + +int _plkr_AddToTable(HashTable *ht, const char *key, void *obj) +{ + HashTableSlot *slot; + int count; + + if (ht == nullptr) + return (0); + + slot = hashtable_slot(ht, hashtable_hash_index(ht, key)); + + for (count = slot->hs_count; count > 0; count -= 1) + if (hashtable_compare_keys(ht, key, slot->hs_entries[count - 1].he_key)) + return (0); + + if (slot->hs_allocated == 0) { + slot->hs_allocated = HASH_INCREMENT_SIZE; + slot->hs_entries = (HashEntry *)malloc(sizeof(HashEntry) * slot->hs_allocated); + slot->hs_count = 0; + } else if (slot->hs_count >= slot->hs_allocated) + slot->hs_entries = (HashEntry *)realloc(slot->hs_entries, (slot->hs_allocated += HASH_INCREMENT_SIZE) * sizeof(HashEntry)); + slot->hs_entries[slot->hs_count].he_key = _plkr_strndup(key, strlen(key)); + slot->hs_entries[slot->hs_count].he_data = obj; + slot->hs_count += 1; + ht->ht_nPairs += 1; + return (1); +} + +HashTable *_plkr_NewHashTable(int size) +{ + HashTable *newHash = (HashTable *)malloc(sizeof(HashTable)); + + newHash->ht_size = size; + newHash->ht_nPairs = 0; + newHash->ht_slots = (HashTableSlot *)malloc(sizeof(HashTableSlot) * size); + memset((void *)(newHash->ht_slots), 0, sizeof(HashTableSlot) * size); + return (newHash); +} diff --git a/generators/poppler/CMakeLists.txt b/generators/poppler/CMakeLists.txt new file mode 100644 index 0000000..a0f2954 --- /dev/null +++ b/generators/poppler/CMakeLists.txt @@ -0,0 +1,49 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_poppler") + +add_subdirectory( conf ) + +set(CMAKE_REQUIRED_LIBRARIES Poppler::Qt5 Qt5::Core Qt5::Gui) + +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::FormFieldChoice *ffc = nullptr; + ffc->choicesWithExportValues(); + return 0; +} +" HAVE_POPPLER_0_87) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/config-okular-poppler.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/config-okular-poppler.h +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + +########### next target ############### + +set(okularGenerator_poppler_PART_SRCS + generator_pdf.cpp + formfields.cpp + annots.cpp + pdfsignatureutils.cpp +) + +ki18n_wrap_ui(okularGenerator_poppler_PART_SRCS + conf/pdfsettingswidget.ui +) + +kconfig_add_kcfg_files(okularGenerator_poppler_PART_SRCS conf/pdfsettings.kcfgc ) + +okular_add_generator(okularGenerator_poppler ${okularGenerator_poppler_PART_SRCS}) + +target_link_libraries(okularGenerator_poppler okularcore KF5::I18n KF5::Completion Poppler::Qt5 Qt5::Xml) + +########### install files ############### +install( FILES okularPoppler.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_pdf.desktop org.kde.mobile.okular_pdf.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-poppler.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/poppler/Messages.sh b/generators/poppler/Messages.sh new file mode 100644 index 0000000..a931f7d --- /dev/null +++ b/generators/poppler/Messages.sh @@ -0,0 +1,4 @@ +#!/bin/sh +$EXTRACTRC $(find conf/ -name "*.ui" -o -name "*.kcfg") >> rc.cpp || exit 11 +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_poppler.pot +rm -f rc.cpp diff --git a/generators/poppler/annots.cpp b/generators/poppler/annots.cpp new file mode 100644 index 0000000..66328bf --- /dev/null +++ b/generators/poppler/annots.cpp @@ -0,0 +1,759 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * Copyright (C) 2012 by Guillermo A. Amaral B. * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "annots.h" + +// qt/kde includes +#include +#include + +#include +#include + +#include "debug_pdf.h" +#include "generator_pdf.h" +#include "popplerembeddedfile.h" + +Q_DECLARE_METATYPE(Poppler::Annotation *) + +extern Okular::Sound *createSoundFromPopplerSound(const Poppler::SoundObject *popplerSound); +extern Okular::Movie *createMovieFromPopplerMovie(const Poppler::MovieObject *popplerMovie); +extern Okular::Movie *createMovieFromPopplerScreen(const Poppler::LinkRendition *popplerScreen); +extern QPair createMovieFromPopplerRichMedia(const Poppler::RichMediaAnnotation *popplerRichMedia); + +static void disposeAnnotation(const Okular::Annotation *ann) +{ + Poppler::Annotation *popplerAnn = qvariant_cast(ann->nativeId()); + delete popplerAnn; +} + +static QPointF normPointToPointF(const Okular::NormalizedPoint &pt) +{ + return QPointF(pt.x, pt.y); +} + +static QRectF normRectToRectF(const Okular::NormalizedRect &rect) +{ + return QRectF(QPointF(rect.left, rect.top), QPointF(rect.right, rect.bottom)); +} + +// Poppler and Okular share the same flag values, but we don't want to export internal flags +static int maskExportedFlags(int flags) +{ + return flags & + (Okular::Annotation::Hidden | Okular::Annotation::FixedSize | Okular::Annotation::FixedRotation | Okular::Annotation::DenyPrint | Okular::Annotation::DenyWrite | Okular::Annotation::DenyDelete | + Okular::Annotation::ToggleHidingOnMouse); +} + +// BEGIN PopplerAnnotationProxy implementation +PopplerAnnotationProxy::PopplerAnnotationProxy(Poppler::Document *doc, QMutex *userMutex, QHash *annotsOnOpenHash) + : ppl_doc(doc) + , mutex(userMutex) + , annotationsOnOpenHash(annotsOnOpenHash) +{ +} + +PopplerAnnotationProxy::~PopplerAnnotationProxy() +{ +} + +bool PopplerAnnotationProxy::supports(Capability cap) const +{ + switch (cap) { + case Addition: + case Modification: + case Removal: + return true; + default: + return false; + } +} + +void PopplerAnnotationProxy::notifyAddition(Okular::Annotation *okl_ann, int page) +{ + // Export annotation to DOM + QDomDocument doc; + QDomElement dom_ann = doc.createElement(QStringLiteral("root")); + Okular::AnnotationUtils::storeAnnotation(okl_ann, dom_ann, doc); + + QMutexLocker ml(mutex); + + // Create poppler annotation + Poppler::Annotation *ppl_ann = Poppler::AnnotationUtils::createAnnotation(dom_ann); + + // Poppler doesn't render StampAnnotations yet + if (ppl_ann->subType() != Poppler::Annotation::AStamp) + okl_ann->setFlags(okl_ann->flags() | Okular::Annotation::ExternallyDrawn); + + // Poppler stores highlight points in swapped order + if (ppl_ann->subType() == Poppler::Annotation::AHighlight) { + Poppler::HighlightAnnotation *hlann = static_cast(ppl_ann); + QList quads = hlann->highlightQuads(); + QMutableListIterator it(quads); + while (it.hasNext()) { + Poppler::HighlightAnnotation::Quad &q = it.next(); + QPointF t; + t = q.points[3]; + q.points[3] = q.points[0]; + q.points[0] = t; + t = q.points[2]; + q.points[2] = q.points[1]; + q.points[1] = t; + } + hlann->setHighlightQuads(quads); + } + + // Bind poppler object to page + Poppler::Page *ppl_page = ppl_doc->page(page); + ppl_page->addAnnotation(ppl_ann); + delete ppl_page; + + // Set pointer to poppler annotation as native Id + okl_ann->setNativeId(QVariant::fromValue(ppl_ann)); + okl_ann->setDisposeDataFunction(disposeAnnotation); + + qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); +} + +void PopplerAnnotationProxy::notifyModification(const Okular::Annotation *okl_ann, int page, bool appearanceChanged) +{ + Q_UNUSED(page); + Q_UNUSED(appearanceChanged); + + Poppler::Annotation *ppl_ann = qvariant_cast(okl_ann->nativeId()); + + if (!ppl_ann) // Ignore non-native annotations + return; + + QMutexLocker ml(mutex); + + if (okl_ann->flags() & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)) { + // Okular ui already renders the annotation on its own + ppl_ann->setFlags(Poppler::Annotation::Hidden); + return; + } + + // Set basic properties + // Note: flags and boundary must be set first in order to correctly handle + // FixedRotation annotations. + ppl_ann->setFlags(maskExportedFlags(okl_ann->flags())); + ppl_ann->setBoundary(normRectToRectF(okl_ann->boundingRectangle())); + + ppl_ann->setAuthor(okl_ann->author()); + ppl_ann->setContents(okl_ann->contents()); + + // Set style + Poppler::Annotation::Style s; + s.setColor(okl_ann->style().color()); + s.setWidth(okl_ann->style().width()); + s.setOpacity(okl_ann->style().opacity()); + ppl_ann->setStyle(s); + + // Set type-specific properties (if any) + switch (ppl_ann->subType()) { + case Poppler::Annotation::AText: { + const Okular::TextAnnotation *okl_txtann = static_cast(okl_ann); + Poppler::TextAnnotation *ppl_txtann = static_cast(ppl_ann); + ppl_txtann->setTextIcon(okl_txtann->textIcon()); + ppl_txtann->setTextFont(okl_txtann->textFont()); + ppl_txtann->setTextColor(okl_txtann->textColor()); + ppl_txtann->setInplaceAlign(okl_txtann->inplaceAlignment()); + ppl_txtann->setCalloutPoints(QVector()); + ppl_txtann->setInplaceIntent((Poppler::TextAnnotation::InplaceIntent)okl_txtann->inplaceIntent()); + break; + } + case Poppler::Annotation::ALine: { + const Okular::LineAnnotation *okl_lineann = static_cast(okl_ann); + Poppler::LineAnnotation *ppl_lineann = static_cast(ppl_ann); + QLinkedList points; + const QLinkedList annotPoints = okl_lineann->linePoints(); + for (const Okular::NormalizedPoint &p : annotPoints) { + points.append(normPointToPointF(p)); + } + ppl_lineann->setLinePoints(points); + ppl_lineann->setLineStartStyle((Poppler::LineAnnotation::TermStyle)okl_lineann->lineStartStyle()); + ppl_lineann->setLineEndStyle((Poppler::LineAnnotation::TermStyle)okl_lineann->lineEndStyle()); + ppl_lineann->setLineClosed(okl_lineann->lineClosed()); + ppl_lineann->setLineInnerColor(okl_lineann->lineInnerColor()); + ppl_lineann->setLineLeadingForwardPoint(okl_lineann->lineLeadingForwardPoint()); + ppl_lineann->setLineLeadingBackPoint(okl_lineann->lineLeadingBackwardPoint()); + ppl_lineann->setLineShowCaption(okl_lineann->showCaption()); + ppl_lineann->setLineIntent((Poppler::LineAnnotation::LineIntent)okl_lineann->lineIntent()); + break; + } + case Poppler::Annotation::AGeom: { + const Okular::GeomAnnotation *okl_geomann = static_cast(okl_ann); + Poppler::GeomAnnotation *ppl_geomann = static_cast(ppl_ann); + ppl_geomann->setGeomType((Poppler::GeomAnnotation::GeomType)okl_geomann->geometricalType()); + ppl_geomann->setGeomInnerColor(okl_geomann->geometricalInnerColor()); + break; + } + case Poppler::Annotation::AHighlight: { + const Okular::HighlightAnnotation *okl_hlann = static_cast(okl_ann); + Poppler::HighlightAnnotation *ppl_hlann = static_cast(ppl_ann); + ppl_hlann->setHighlightType((Poppler::HighlightAnnotation::HighlightType)okl_hlann->highlightType()); + break; + } + case Poppler::Annotation::AStamp: { + const Okular::StampAnnotation *okl_stampann = static_cast(okl_ann); + Poppler::StampAnnotation *ppl_stampann = static_cast(ppl_ann); + ppl_stampann->setStampIconName(okl_stampann->stampIconName()); + break; + } + case Poppler::Annotation::AInk: { + const Okular::InkAnnotation *okl_inkann = static_cast(okl_ann); + Poppler::InkAnnotation *ppl_inkann = static_cast(ppl_ann); + QList> paths; + const QList> inkPathsList = okl_inkann->inkPaths(); + for (const QLinkedList &path : inkPathsList) { + QLinkedList points; + for (const Okular::NormalizedPoint &p : path) { + points.append(normPointToPointF(p)); + } + paths.append(points); + } + ppl_inkann->setInkPaths(paths); + break; + } + default: + qCDebug(OkularPdfDebug) << "Type-specific property modification is not implemented for this annotation type"; + break; + } + + qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); +} + +void PopplerAnnotationProxy::notifyRemoval(Okular::Annotation *okl_ann, int page) +{ + Poppler::Annotation *ppl_ann = qvariant_cast(okl_ann->nativeId()); + + if (!ppl_ann) // Ignore non-native annotations + return; + + QMutexLocker ml(mutex); + + Poppler::Page *ppl_page = ppl_doc->page(page); + annotationsOnOpenHash->remove(okl_ann); + ppl_page->removeAnnotation(ppl_ann); // Also destroys ppl_ann + delete ppl_page; + + okl_ann->setNativeId(QVariant::fromValue(0)); // So that we don't double-free in disposeAnnotation + + qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); +} +// END PopplerAnnotationProxy implementation + +static Okular::Annotation::LineStyle popplerToOkular(Poppler::Annotation::LineStyle s) +{ + switch (s) { + case Poppler::Annotation::Solid: + return Okular::Annotation::Solid; + case Poppler::Annotation::Dashed: + return Okular::Annotation::Dashed; + case Poppler::Annotation::Beveled: + return Okular::Annotation::Beveled; + case Poppler::Annotation::Inset: + return Okular::Annotation::Inset; + case Poppler::Annotation::Underline: + return Okular::Annotation::Underline; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << s; + } + + return Okular::Annotation::Solid; +} + +static Okular::Annotation::LineEffect popplerToOkular(Poppler::Annotation::LineEffect e) +{ + switch (e) { + case Poppler::Annotation::NoEffect: + return Okular::Annotation::NoEffect; + case Poppler::Annotation::Cloudy: + return Okular::Annotation::Cloudy; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << e; + } + + return Okular::Annotation::NoEffect; +} + +static Okular::Annotation::RevisionScope popplerToOkular(Poppler::Annotation::RevScope s) +{ + switch (s) { + case Poppler::Annotation::Root: + Q_UNREACHABLE(); + case Poppler::Annotation::Reply: + return Okular::Annotation::Reply; + case Poppler::Annotation::Group: + return Okular::Annotation::Group; + case Poppler::Annotation::Delete: + return Okular::Annotation::Delete; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << s; + } + + return Okular::Annotation::Reply; +} + +static Okular::Annotation::RevisionType popplerToOkular(Poppler::Annotation::RevType t) +{ + switch (t) { + case Poppler::Annotation::None: + return Okular::Annotation::None; + case Poppler::Annotation::Marked: + return Okular::Annotation::Marked; + case Poppler::Annotation::Unmarked: + return Okular::Annotation::Unmarked; + case Poppler::Annotation::Accepted: + return Okular::Annotation::Accepted; + case Poppler::Annotation::Rejected: + return Okular::Annotation::Rejected; + case Poppler::Annotation::Cancelled: + return Okular::Annotation::Cancelled; + case Poppler::Annotation::Completed: + return Okular::Annotation::Completed; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << t; + } + + return Okular::Annotation::None; +} + +static Okular::TextAnnotation::TextType popplerToOkular(Poppler::TextAnnotation::TextType ptt) +{ + switch (ptt) { + case Poppler::TextAnnotation::Linked: + return Okular::TextAnnotation::Linked; + case Poppler::TextAnnotation::InPlace: + return Okular::TextAnnotation::InPlace; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << ptt; + } + + return Okular::TextAnnotation::Linked; +} + +static Okular::TextAnnotation::InplaceIntent popplerToOkular(Poppler::TextAnnotation::InplaceIntent pii) +{ + switch (pii) { + case Poppler::TextAnnotation::Unknown: + return Okular::TextAnnotation::Unknown; + case Poppler::TextAnnotation::Callout: + return Okular::TextAnnotation::Callout; + case Poppler::TextAnnotation::TypeWriter: + return Okular::TextAnnotation::TypeWriter; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pii; + } + + return Okular::TextAnnotation::Unknown; +} + +static Okular::LineAnnotation::TermStyle popplerToOkular(Poppler::LineAnnotation::TermStyle pts) +{ + switch (pts) { + case Poppler::LineAnnotation::Square: + return Okular::LineAnnotation::Square; + case Poppler::LineAnnotation::Circle: + return Okular::LineAnnotation::Circle; + case Poppler::LineAnnotation::Diamond: + return Okular::LineAnnotation::Diamond; + case Poppler::LineAnnotation::OpenArrow: + return Okular::LineAnnotation::OpenArrow; + case Poppler::LineAnnotation::ClosedArrow: + return Okular::LineAnnotation::ClosedArrow; + case Poppler::LineAnnotation::None: + return Okular::LineAnnotation::None; + case Poppler::LineAnnotation::Butt: + return Okular::LineAnnotation::Butt; + case Poppler::LineAnnotation::ROpenArrow: + return Okular::LineAnnotation::ROpenArrow; + case Poppler::LineAnnotation::RClosedArrow: + return Okular::LineAnnotation::RClosedArrow; + case Poppler::LineAnnotation::Slash: + return Okular::LineAnnotation::Slash; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pts; + } + + return Okular::LineAnnotation::None; +} + +static Okular::LineAnnotation::LineIntent popplerToOkular(Poppler::LineAnnotation::LineIntent pli) +{ + switch (pli) { + case Poppler::LineAnnotation::Unknown: + return Okular::LineAnnotation::Unknown; + case Poppler::LineAnnotation::Arrow: + return Okular::LineAnnotation::Arrow; + case Poppler::LineAnnotation::Dimension: + return Okular::LineAnnotation::Dimension; + case Poppler::LineAnnotation::PolygonCloud: + return Okular::LineAnnotation::PolygonCloud; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pli; + } + + return Okular::LineAnnotation::Unknown; +} + +static Okular::GeomAnnotation::GeomType popplerToOkular(Poppler::GeomAnnotation::GeomType pgt) +{ + switch (pgt) { + case Poppler::GeomAnnotation::InscribedSquare: + return Okular::GeomAnnotation::InscribedSquare; + case Poppler::GeomAnnotation::InscribedCircle: + return Okular::GeomAnnotation::InscribedCircle; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pgt; + } + + return Okular::GeomAnnotation::InscribedSquare; +} + +static Okular::HighlightAnnotation::HighlightType popplerToOkular(Poppler::HighlightAnnotation::HighlightType pht) +{ + switch (pht) { + case Poppler::HighlightAnnotation::Highlight: + return Okular::HighlightAnnotation::Highlight; + case Poppler::HighlightAnnotation::Squiggly: + return Okular::HighlightAnnotation::Squiggly; + case Poppler::HighlightAnnotation::Underline: + return Okular::HighlightAnnotation::Underline; + case Poppler::HighlightAnnotation::StrikeOut: + return Okular::HighlightAnnotation::StrikeOut; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pht; + } + + return Okular::HighlightAnnotation::Highlight; +} + +static Okular::CaretAnnotation::CaretSymbol popplerToOkular(Poppler::CaretAnnotation::CaretSymbol pcs) +{ + switch (pcs) { + case Poppler::CaretAnnotation::None: + return Okular::CaretAnnotation::None; + case Poppler::CaretAnnotation::P: + return Okular::CaretAnnotation::P; + default: + qWarning() << Q_FUNC_INFO << "unknown value" << pcs; + } + + return Okular::CaretAnnotation::None; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::TextAnnotation *popplerAnnotation) +{ + Okular::TextAnnotation *oTextAnn = new Okular::TextAnnotation(); + + oTextAnn->setTextType(popplerToOkular(popplerAnnotation->textType())); + oTextAnn->setTextIcon(popplerAnnotation->textIcon()); + oTextAnn->setTextFont(popplerAnnotation->textFont()); + oTextAnn->setTextColor(popplerAnnotation->textColor()); + // this works because we use the same 0:left, 1:center, 2:right meaning both in poppler and okular + oTextAnn->setInplaceAlignment(popplerAnnotation->inplaceAlign()); + oTextAnn->setInplaceIntent(popplerToOkular(popplerAnnotation->inplaceIntent())); + for (int i = 0; i < 3; ++i) { + const QPointF p = popplerAnnotation->calloutPoint(i); + oTextAnn->setInplaceCallout({p.x(), p.y()}, i); + } + + return oTextAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::LineAnnotation *popplerAnnotation) +{ + Okular::LineAnnotation *oLineAnn = new Okular::LineAnnotation(); + + oLineAnn->setLineStartStyle(popplerToOkular(popplerAnnotation->lineStartStyle())); + oLineAnn->setLineEndStyle(popplerToOkular(popplerAnnotation->lineEndStyle())); + oLineAnn->setLineClosed(popplerAnnotation->isLineClosed()); + oLineAnn->setLineInnerColor(popplerAnnotation->lineInnerColor()); + oLineAnn->setLineLeadingForwardPoint(popplerAnnotation->lineLeadingForwardPoint()); + oLineAnn->setLineLeadingBackwardPoint(popplerAnnotation->lineLeadingBackPoint()); + oLineAnn->setShowCaption(popplerAnnotation->lineShowCaption()); + oLineAnn->setLineIntent(popplerToOkular(popplerAnnotation->lineIntent())); + + QLinkedList points; + const QLinkedList popplerPoints = popplerAnnotation->linePoints(); + for (const QPointF &p : popplerPoints) { + points << Okular::NormalizedPoint(p.x(), p.y()); + } + oLineAnn->setLinePoints(points); + + return oLineAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::GeomAnnotation *popplerAnnotation) +{ + Okular::GeomAnnotation *oGeomAnn = new Okular::GeomAnnotation(); + + oGeomAnn->setGeometricalType(popplerToOkular(popplerAnnotation->geomType())); + oGeomAnn->setGeometricalInnerColor(popplerAnnotation->geomInnerColor()); + + return oGeomAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::HighlightAnnotation *popplerAnnotation) +{ + Okular::HighlightAnnotation *oHighlightAnn = new Okular::HighlightAnnotation(); + + oHighlightAnn->setHighlightType(popplerToOkular(popplerAnnotation->highlightType())); + + const QList popplerHq = popplerAnnotation->highlightQuads(); + QList &okularHq = oHighlightAnn->highlightQuads(); + + for (const Poppler::HighlightAnnotation::Quad &popplerQ : popplerHq) { + Okular::HighlightAnnotation::Quad q; + + // Poppler stores highlight points in swapped order + q.setPoint(Okular::NormalizedPoint(popplerQ.points[0].x(), popplerQ.points[0].y()), 3); + q.setPoint(Okular::NormalizedPoint(popplerQ.points[1].x(), popplerQ.points[1].y()), 2); + q.setPoint(Okular::NormalizedPoint(popplerQ.points[2].x(), popplerQ.points[2].y()), 1); + q.setPoint(Okular::NormalizedPoint(popplerQ.points[3].x(), popplerQ.points[3].y()), 0); + + q.setCapStart(popplerQ.capStart); + q.setCapEnd(popplerQ.capEnd); + q.setFeather(popplerQ.feather); + okularHq << q; + } + + return oHighlightAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::InkAnnotation *popplerAnnotation) +{ + Okular::InkAnnotation *oInkAnn = new Okular::InkAnnotation(); + + const QList> popplerInkPaths = popplerAnnotation->inkPaths(); + QList> okularInkPaths; + for (const QLinkedList &popplerInkPath : popplerInkPaths) { + QLinkedList okularInkPath; + for (const QPointF &popplerPoint : popplerInkPath) { + okularInkPath << Okular::NormalizedPoint(popplerPoint.x(), popplerPoint.y()); + } + okularInkPaths << okularInkPath; + } + + oInkAnn->setInkPaths(okularInkPaths); + + return oInkAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::CaretAnnotation *popplerAnnotation) +{ + Okular::CaretAnnotation *oCaretAnn = new Okular::CaretAnnotation(); + + oCaretAnn->setCaretSymbol(popplerToOkular(popplerAnnotation->caretSymbol())); + + return oCaretAnn; +} + +static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::StampAnnotation *popplerAnnotation) +{ + Okular::StampAnnotation *oStampAnn = new Okular::StampAnnotation(); + + oStampAnn->setStampIconName(popplerAnnotation->stampIconName()); + + return oStampAnn; +} + +Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::Annotation *popplerAnnotation, const Poppler::Page &popplerPage, bool *doDelete) +{ + Okular::Annotation *okularAnnotation = nullptr; + *doDelete = true; + bool tieToOkularAnn = false; + bool externallyDrawn = false; + switch (popplerAnnotation->subType()) { + case Poppler::Annotation::AFileAttachment: { + Poppler::FileAttachmentAnnotation *attachann = static_cast(popplerAnnotation); + Okular::FileAttachmentAnnotation *f = new Okular::FileAttachmentAnnotation(); + okularAnnotation = f; + tieToOkularAnn = true; + *doDelete = false; + + f->setFileIconName(attachann->fileIconName()); + f->setEmbeddedFile(new PDFEmbeddedFile(attachann->embeddedFile())); + + break; + } + case Poppler::Annotation::ASound: { + Poppler::SoundAnnotation *soundann = static_cast(popplerAnnotation); + Okular::SoundAnnotation *s = new Okular::SoundAnnotation(); + okularAnnotation = s; + + s->setSoundIconName(soundann->soundIconName()); + s->setSound(createSoundFromPopplerSound(soundann->sound())); + + break; + } + case Poppler::Annotation::AMovie: { + Poppler::MovieAnnotation *movieann = static_cast(popplerAnnotation); + Okular::MovieAnnotation *m = new Okular::MovieAnnotation(); + okularAnnotation = m; + tieToOkularAnn = true; + *doDelete = false; + + m->setMovie(createMovieFromPopplerMovie(movieann->movie())); + + break; + } + case Poppler::Annotation::AWidget: { + okularAnnotation = new Okular::WidgetAnnotation(); + break; + } + case Poppler::Annotation::AScreen: { + Okular::ScreenAnnotation *m = new Okular::ScreenAnnotation(); + okularAnnotation = m; + tieToOkularAnn = true; + *doDelete = false; + break; + } + case Poppler::Annotation::ARichMedia: { + Poppler::RichMediaAnnotation *richmediaann = static_cast(popplerAnnotation); + const QPair result = createMovieFromPopplerRichMedia(richmediaann); + + if (result.first) { + Okular::RichMediaAnnotation *r = new Okular::RichMediaAnnotation(); + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = r; + + r->setMovie(result.first); + r->setEmbeddedFile(result.second); + } + + break; + } + case Poppler::Annotation::AText: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::ALine: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::AGeom: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::AHighlight: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::AInk: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::ACaret: { + externallyDrawn = true; + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + } + case Poppler::Annotation::AStamp: + tieToOkularAnn = true; + *doDelete = false; + okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); + break; + default: { + break; + } + } + if (okularAnnotation) { + // the Contents field might have lines separated by \r + QString contents = popplerAnnotation->contents(); + contents.replace(QLatin1Char('\r'), QLatin1Char('\n')); + + okularAnnotation->setAuthor(popplerAnnotation->author()); + okularAnnotation->setContents(contents); + okularAnnotation->setUniqueName(popplerAnnotation->uniqueName()); + okularAnnotation->setModificationDate(popplerAnnotation->modificationDate()); + okularAnnotation->setCreationDate(popplerAnnotation->creationDate()); + okularAnnotation->setFlags(popplerAnnotation->flags() | Okular::Annotation::External); + okularAnnotation->setBoundingRectangle(Okular::NormalizedRect::fromQRectF(popplerAnnotation->boundary())); + + if (externallyDrawn) + okularAnnotation->setFlags(okularAnnotation->flags() | Okular::Annotation::ExternallyDrawn); + + // Convert the poppler annotation style to Okular annotation style + Okular::Annotation::Style &okularStyle = okularAnnotation->style(); + const Poppler::Annotation::Style popplerStyle = popplerAnnotation->style(); + okularStyle.setColor(popplerStyle.color()); + okularStyle.setOpacity(popplerStyle.opacity()); + okularStyle.setWidth(popplerStyle.width()); + okularStyle.setLineStyle(popplerToOkular(popplerStyle.lineStyle())); + okularStyle.setXCorners(popplerStyle.xCorners()); + okularStyle.setYCorners(popplerStyle.yCorners()); + const QVector &dashArray = popplerStyle.dashArray(); + if (dashArray.size() > 0) + okularStyle.setMarks(dashArray[0]); + if (dashArray.size() > 1) + okularStyle.setSpaces(dashArray[1]); + okularStyle.setLineEffect(popplerToOkular(popplerStyle.lineEffect())); + okularStyle.setEffectIntensity(popplerStyle.effectIntensity()); + + // Convert the poppler annotation popup to Okular annotation window + Okular::Annotation::Window &okularWindow = okularAnnotation->window(); + const Poppler::Annotation::Popup popplerPopup = popplerAnnotation->popup(); + // This assumes that both "flags" int mean the same, but since we don't use the flags in okular anywhere it's not really that important + okularWindow.setFlags(popplerPopup.flags()); + const QRectF popplerGeometry = popplerPopup.geometry(); + const QSize popplerPageSize = popplerPage.pageSize(); + okularWindow.setTopLeft(Okular::NormalizedPoint(popplerGeometry.top(), popplerGeometry.left(), popplerPageSize.width(), popplerPageSize.height())); + okularWindow.setWidth(popplerGeometry.width()); + okularWindow.setHeight(popplerGeometry.height()); + okularWindow.setTitle(popplerPopup.title()); + okularWindow.setSummary(popplerPopup.summary()); + + // Convert the poppler revisions to Okular revisions + QLinkedList &okularRevisions = okularAnnotation->revisions(); + okularRevisions.clear(); // We can remove this once we stop calling Okular::AnnotationUtils::createAnnotation + const QList popplerRevisions = popplerAnnotation->revisions(); + for (Poppler::Annotation *popplerRevision : popplerRevisions) { + bool deletePopplerRevision; + Okular::Annotation::Revision okularRevision; + okularRevision.setAnnotation(createAnnotationFromPopplerAnnotation(popplerRevision, popplerPage, &deletePopplerRevision)); + okularRevision.setScope(popplerToOkular(popplerRevision->revisionScope())); + okularRevision.setType(popplerToOkular(popplerRevision->revisionType())); + okularRevisions << okularRevision; + + if (deletePopplerRevision) { + delete popplerRevision; + } + } + + if (tieToOkularAnn) { + okularAnnotation->setNativeId(QVariant::fromValue(popplerAnnotation)); + okularAnnotation->setDisposeDataFunction(disposeAnnotation); + } + } + return okularAnnotation; +} diff --git a/generators/poppler/annots.h b/generators/poppler/annots.h new file mode 100644 index 0000000..11031fb --- /dev/null +++ b/generators/poppler/annots.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_GENERATOR_PDF_ANNOTS_H_ +#define _OKULAR_GENERATOR_PDF_ANNOTS_H_ + +#include +#include + +#include + +#include "config-okular-poppler.h" +#include "core/annotations.h" + +extern Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::Annotation *popplerAnnotation, const Poppler::Page &popplerPage, bool *doDelete); + +class PopplerAnnotationProxy : public Okular::AnnotationProxy +{ +public: + PopplerAnnotationProxy(Poppler::Document *doc, QMutex *userMutex, QHash *annotsOnOpenHash); + ~PopplerAnnotationProxy() override; + + bool supports(Capability capability) const override; + void notifyAddition(Okular::Annotation *okl_ann, int page) override; + void notifyModification(const Okular::Annotation *okl_ann, int page, bool appearanceChanged) override; + void notifyRemoval(Okular::Annotation *okl_ann, int page) override; + +private: + Poppler::Document *ppl_doc; + QMutex *mutex; + QHash *annotationsOnOpenHash; +}; + +#endif diff --git a/generators/poppler/conf/CMakeLists.txt b/generators/poppler/conf/CMakeLists.txt new file mode 100644 index 0000000..72bb84a --- /dev/null +++ b/generators/poppler/conf/CMakeLists.txt @@ -0,0 +1,3 @@ + +install(FILES pdfsettings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) + diff --git a/generators/poppler/conf/pdfsettings.kcfg b/generators/poppler/conf/pdfsettings.kcfg new file mode 100644 index 0000000..65ea82d --- /dev/null +++ b/generators/poppler/conf/pdfsettings.kcfg @@ -0,0 +1,18 @@ + + + + + + No + + + + + + + + + diff --git a/generators/poppler/conf/pdfsettings.kcfgc b/generators/poppler/conf/pdfsettings.kcfgc new file mode 100644 index 0000000..45f7635 --- /dev/null +++ b/generators/poppler/conf/pdfsettings.kcfgc @@ -0,0 +1,4 @@ +File=pdfsettings.kcfg +ClassName=PDFSettings +Mutators=true +Singleton=true diff --git a/generators/poppler/conf/pdfsettingswidget.ui b/generators/poppler/conf/pdfsettingswidget.ui new file mode 100644 index 0000000..488ad30 --- /dev/null +++ b/generators/poppler/conf/pdfsettingswidget.ui @@ -0,0 +1,49 @@ + + + PDFSettingsWidget + + + + QFormLayout::ExpandingFieldsGrow + + + + + Enhance thin lines: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + No + + + + + Solid + + + + + Shape + + + + + + + + + KComboBox + QComboBox +
kcombobox.h
+
+
+ + +
diff --git a/generators/poppler/config-okular-poppler.h.cmake b/generators/poppler/config-okular-poppler.h.cmake new file mode 100644 index 0000000..0aa62f0 --- /dev/null +++ b/generators/poppler/config-okular-poppler.h.cmake @@ -0,0 +1,3 @@ +/* Defined if we have the 0.87 version of the Poppler library */ +#cmakedefine HAVE_POPPLER_0_87 1 + diff --git a/generators/poppler/debug_pdf.h b/generators/poppler/debug_pdf.h new file mode 100644 index 0000000..0395790 --- /dev/null +++ b/generators/poppler/debug_pdf.h @@ -0,0 +1,17 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_PDF_H +#define OKULAR_DEBUG_PDF_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularPdfDebug) + +#endif diff --git a/generators/poppler/formfields.cpp b/generators/poppler/formfields.cpp new file mode 100644 index 0000000..817d2cf --- /dev/null +++ b/generators/poppler/formfields.cpp @@ -0,0 +1,460 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2018 by Intevation GmbH * + * Copyright (C) 2019 by Oliver Sander * + * * + * 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. * + ***************************************************************************/ + +#include "formfields.h" + +#include "core/action.h" + +#include "pdfsignatureutils.h" + +#include + +extern Okular::Action *createLinkFromPopplerLink(const Poppler::Link *popplerLink, bool deletePopplerLink = true); +#define SET_ANNOT_ACTIONS \ + setAdditionalAction(Okular::Annotation::CursorEntering, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::CursorEnteringAction))); \ + setAdditionalAction(Okular::Annotation::CursorLeaving, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::CursorLeavingAction))); \ + setAdditionalAction(Okular::Annotation::MousePressed, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::MousePressedAction))); \ + setAdditionalAction(Okular::Annotation::MouseReleased, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::MouseReleasedAction))); \ + setAdditionalAction(Okular::Annotation::FocusIn, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::FocusInAction))); \ + setAdditionalAction(Okular::Annotation::FocusOut, createLinkFromPopplerLink(m_field->additionalAction(Poppler::Annotation::FocusOutAction))); + +#define SET_ACTIONS \ + setActivationAction(createLinkFromPopplerLink(m_field->activationAction())); \ + setAdditionalAction(Okular::FormField::FieldModified, createLinkFromPopplerLink(m_field->additionalAction(Poppler::FormField::FieldModified))); \ + setAdditionalAction(Okular::FormField::FormatField, createLinkFromPopplerLink(m_field->additionalAction(Poppler::FormField::FormatField))); \ + setAdditionalAction(Okular::FormField::ValidateField, createLinkFromPopplerLink(m_field->additionalAction(Poppler::FormField::ValidateField))); \ + setAdditionalAction(Okular::FormField::CalculateField, createLinkFromPopplerLink(m_field->additionalAction(Poppler::FormField::CalculateField))); \ + SET_ANNOT_ACTIONS + +PopplerFormFieldButton::PopplerFormFieldButton(std::unique_ptr field) + : Okular::FormFieldButton() + , m_field(std::move(field)) +{ + m_rect = Okular::NormalizedRect::fromQRectF(m_field->rect()); + m_id = m_field->id(); + SET_ACTIONS +} + +Okular::NormalizedRect PopplerFormFieldButton::rect() const +{ + return m_rect; +} + +int PopplerFormFieldButton::id() const +{ + return m_id; +} + +QString PopplerFormFieldButton::name() const +{ + return m_field->name(); +} + +QString PopplerFormFieldButton::uiName() const +{ + return m_field->uiName(); +} + +QString PopplerFormFieldButton::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + +bool PopplerFormFieldButton::isReadOnly() const +{ + return m_field->isReadOnly(); +} + +void PopplerFormFieldButton::setReadOnly(bool value) +{ + m_field->setReadOnly(value); +} + +bool PopplerFormFieldButton::isVisible() const +{ + return m_field->isVisible(); +} + +void PopplerFormFieldButton::setVisible(bool value) +{ + m_field->setVisible(value); +} + +bool PopplerFormFieldButton::isPrintable() const +{ + return m_field->isPrintable(); +} + +void PopplerFormFieldButton::setPrintable(bool value) +{ + m_field->setPrintable(value); +} + +Okular::FormFieldButton::ButtonType PopplerFormFieldButton::buttonType() const +{ + switch (m_field->buttonType()) { + case Poppler::FormFieldButton::Push: + return Okular::FormFieldButton::Push; + case Poppler::FormFieldButton::CheckBox: + return Okular::FormFieldButton::CheckBox; + case Poppler::FormFieldButton::Radio: + return Okular::FormFieldButton::Radio; + } + return Okular::FormFieldButton::Push; +} + +QString PopplerFormFieldButton::caption() const +{ + return m_field->caption(); +} + +bool PopplerFormFieldButton::state() const +{ + return m_field->state(); +} + +void PopplerFormFieldButton::setState(bool state) +{ + m_field->setState(state); +} + +QList PopplerFormFieldButton::siblings() const +{ + return m_field->siblings(); +} + +Poppler::FormFieldIcon PopplerFormFieldButton::icon() const +{ + return m_field->icon(); +} + +void PopplerFormFieldButton::setIcon(Okular::FormField *field) +{ + if (field->type() == Okular::FormField::FormButton) { + PopplerFormFieldButton *button = static_cast(field); + m_field->setIcon(button->icon()); + } +} + +PopplerFormFieldText::PopplerFormFieldText(std::unique_ptr field) + : Okular::FormFieldText() + , m_field(std::move(field)) +{ + m_rect = Okular::NormalizedRect::fromQRectF(m_field->rect()); + m_id = m_field->id(); + SET_ACTIONS +} + +Okular::NormalizedRect PopplerFormFieldText::rect() const +{ + return m_rect; +} + +int PopplerFormFieldText::id() const +{ + return m_id; +} + +QString PopplerFormFieldText::name() const +{ + return m_field->name(); +} + +QString PopplerFormFieldText::uiName() const +{ + return m_field->uiName(); +} + +QString PopplerFormFieldText::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + +bool PopplerFormFieldText::isReadOnly() const +{ + return m_field->isReadOnly(); +} + +void PopplerFormFieldText::setReadOnly(bool value) +{ + m_field->setReadOnly(value); +} + +bool PopplerFormFieldText::isVisible() const +{ + return m_field->isVisible(); +} + +void PopplerFormFieldText::setVisible(bool value) +{ + m_field->setVisible(value); +} + +bool PopplerFormFieldText::isPrintable() const +{ + return m_field->isPrintable(); +} + +void PopplerFormFieldText::setPrintable(bool value) +{ + m_field->setPrintable(value); +} + +Okular::FormFieldText::TextType PopplerFormFieldText::textType() const +{ + switch (m_field->textType()) { + case Poppler::FormFieldText::Normal: + return Okular::FormFieldText::Normal; + case Poppler::FormFieldText::Multiline: + return Okular::FormFieldText::Multiline; + case Poppler::FormFieldText::FileSelect: + return Okular::FormFieldText::FileSelect; + } + return Okular::FormFieldText::Normal; +} + +QString PopplerFormFieldText::text() const +{ + return m_field->text(); +} + +void PopplerFormFieldText::setText(const QString &text) +{ + m_field->setText(text); +} + +void PopplerFormFieldText::setAppearanceText(const QString &text) +{ + m_field->setAppearanceText(text); +} + +bool PopplerFormFieldText::isPassword() const +{ + return m_field->isPassword(); +} + +bool PopplerFormFieldText::isRichText() const +{ + return m_field->isRichText(); +} + +int PopplerFormFieldText::maximumLength() const +{ + return m_field->maximumLength(); +} + +Qt::Alignment PopplerFormFieldText::textAlignment() const +{ + return Qt::AlignTop | m_field->textAlignment(); +} + +bool PopplerFormFieldText::canBeSpellChecked() const +{ + return m_field->canBeSpellChecked(); +} + +PopplerFormFieldChoice::PopplerFormFieldChoice(std::unique_ptr field) + : Okular::FormFieldChoice() + , m_field(std::move(field)) +{ + m_rect = Okular::NormalizedRect::fromQRectF(m_field->rect()); + m_id = m_field->id(); + SET_ACTIONS + +#ifdef HAVE_POPPLER_0_87 + QMap values; + const auto fieldChoicesWithExportValues = m_field->choicesWithExportValues(); + for (const QPair &value : fieldChoicesWithExportValues) { + values.insert(value.first, value.second); + } + setExportValues(values); +#endif +} + +Okular::NormalizedRect PopplerFormFieldChoice::rect() const +{ + return m_rect; +} + +int PopplerFormFieldChoice::id() const +{ + return m_id; +} + +QString PopplerFormFieldChoice::name() const +{ + return m_field->name(); +} + +QString PopplerFormFieldChoice::uiName() const +{ + return m_field->uiName(); +} + +QString PopplerFormFieldChoice::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + +bool PopplerFormFieldChoice::isReadOnly() const +{ + return m_field->isReadOnly(); +} + +void PopplerFormFieldChoice::setReadOnly(bool value) +{ + m_field->setReadOnly(value); +} + +bool PopplerFormFieldChoice::isVisible() const +{ + return m_field->isVisible(); +} + +void PopplerFormFieldChoice::setVisible(bool value) +{ + m_field->setVisible(value); +} + +bool PopplerFormFieldChoice::isPrintable() const +{ + return m_field->isPrintable(); +} + +void PopplerFormFieldChoice::setPrintable(bool value) +{ + m_field->setPrintable(value); +} + +Okular::FormFieldChoice::ChoiceType PopplerFormFieldChoice::choiceType() const +{ + switch (m_field->choiceType()) { + case Poppler::FormFieldChoice::ComboBox: + return Okular::FormFieldChoice::ComboBox; + case Poppler::FormFieldChoice::ListBox: + return Okular::FormFieldChoice::ListBox; + } + return Okular::FormFieldChoice::ListBox; +} + +QStringList PopplerFormFieldChoice::choices() const +{ + return m_field->choices(); +} + +bool PopplerFormFieldChoice::isEditable() const +{ + return m_field->isEditable(); +} + +bool PopplerFormFieldChoice::multiSelect() const +{ + return m_field->multiSelect(); +} + +QList PopplerFormFieldChoice::currentChoices() const +{ + return m_field->currentChoices(); +} + +void PopplerFormFieldChoice::setCurrentChoices(const QList &choices) +{ + m_field->setCurrentChoices(choices); +} + +QString PopplerFormFieldChoice::editChoice() const +{ + return m_field->editChoice(); +} + +void PopplerFormFieldChoice::setEditChoice(const QString &text) +{ + m_field->setEditChoice(text); +} + +Qt::Alignment PopplerFormFieldChoice::textAlignment() const +{ + return Qt::AlignTop | m_field->textAlignment(); +} + +bool PopplerFormFieldChoice::canBeSpellChecked() const +{ + return m_field->canBeSpellChecked(); +} + +PopplerFormFieldSignature::PopplerFormFieldSignature(std::unique_ptr field) + : Okular::FormFieldSignature() + , m_field(std::move(field)) +{ + m_rect = Okular::NormalizedRect::fromQRectF(m_field->rect()); + m_id = m_field->id(); + m_info = new PopplerSignatureInfo(m_field->validate(Poppler::FormFieldSignature::ValidateVerifyCertificate)); + SET_ACTIONS +} + +PopplerFormFieldSignature::~PopplerFormFieldSignature() +{ + delete m_info; +} + +Okular::NormalizedRect PopplerFormFieldSignature::rect() const +{ + return m_rect; +} + +int PopplerFormFieldSignature::id() const +{ + return m_id; +} + +QString PopplerFormFieldSignature::name() const +{ + return m_field->name(); +} + +QString PopplerFormFieldSignature::uiName() const +{ + return m_field->uiName(); +} + +QString PopplerFormFieldSignature::fullyQualifiedName() const +{ + return m_field->fullyQualifiedName(); +} + +bool PopplerFormFieldSignature::isReadOnly() const +{ + return m_field->isReadOnly(); +} + +bool PopplerFormFieldSignature::isVisible() const +{ + return m_field->isVisible(); +} + +PopplerFormFieldSignature::SignatureType PopplerFormFieldSignature::signatureType() const +{ + switch (m_field->signatureType()) { + case Poppler::FormFieldSignature::AdbePkcs7sha1: + return Okular::FormFieldSignature::AdbePkcs7sha1; + case Poppler::FormFieldSignature::AdbePkcs7detached: + return Okular::FormFieldSignature::AdbePkcs7detached; + case Poppler::FormFieldSignature::EtsiCAdESdetached: + return Okular::FormFieldSignature::EtsiCAdESdetached; + default: + return Okular::FormFieldSignature::UnknownType; + } +} + +const Okular::SignatureInfo &PopplerFormFieldSignature::signatureInfo() const +{ + return *m_info; +} diff --git a/generators/poppler/formfields.h b/generators/poppler/formfields.h new file mode 100644 index 0000000..b00717b --- /dev/null +++ b/generators/poppler/formfields.h @@ -0,0 +1,153 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2019 by Oliver Sander * + * * + * 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_GENERATOR_PDF_FORMFIELDS_H_ +#define _OKULAR_GENERATOR_PDF_FORMFIELDS_H_ + +#include "core/form.h" +#include +#include + +class PopplerFormFieldButton : public Okular::FormFieldButton +{ +public: + explicit PopplerFormFieldButton(std::unique_ptr field); + + // inherited from Okular::FormField + Okular::NormalizedRect rect() const override; + int id() const override; + QString name() const override; + QString uiName() const override; + QString fullyQualifiedName() const override; + bool isReadOnly() const override; + void setReadOnly(bool value) override; + bool isVisible() const override; + void setVisible(bool value) override; + bool isPrintable() const override; + void setPrintable(bool value) override; + + // inherited from Okular::FormFieldButton + ButtonType buttonType() const override; + QString caption() const override; + bool state() const override; + void setState(bool state) override; + QList siblings() const override; + void setIcon(Okular::FormField *field) override; + /* + * Supported only in newer versions of Poppler library. + * + * @since 1.9 + */ + Poppler::FormFieldIcon icon() const; + +private: + std::unique_ptr m_field; + Okular::NormalizedRect m_rect; + int m_id; +}; + +class PopplerFormFieldText : public Okular::FormFieldText +{ +public: + explicit PopplerFormFieldText(std::unique_ptr field); + + // inherited from Okular::FormField + Okular::NormalizedRect rect() const override; + int id() const override; + QString name() const override; + QString uiName() const override; + QString fullyQualifiedName() const override; + bool isReadOnly() const override; + void setReadOnly(bool value) override; + bool isVisible() const override; + void setVisible(bool value) override; + bool isPrintable() const override; + void setPrintable(bool value) override; + + // inherited from Okular::FormFieldText + Okular::FormFieldText::TextType textType() const override; + QString text() const override; + void setText(const QString &text) override; + void setAppearanceText(const QString &text) override; + bool isPassword() const override; + bool isRichText() const override; + int maximumLength() const override; + Qt::Alignment textAlignment() const override; + bool canBeSpellChecked() const override; + +private: + std::unique_ptr m_field; + Okular::NormalizedRect m_rect; + int m_id; +}; + +class PopplerFormFieldChoice : public Okular::FormFieldChoice +{ +public: + explicit PopplerFormFieldChoice(std::unique_ptr field); + + // inherited from Okular::FormField + Okular::NormalizedRect rect() const override; + int id() const override; + QString name() const override; + QString uiName() const override; + QString fullyQualifiedName() const override; + bool isReadOnly() const override; + void setReadOnly(bool value) override; + bool isVisible() const override; + void setVisible(bool value) override; + bool isPrintable() const override; + void setPrintable(bool value) override; + + // inherited from Okular::FormFieldChoice + ChoiceType choiceType() const override; + QStringList choices() const override; + bool isEditable() const override; + bool multiSelect() const override; + QList currentChoices() const override; + void setCurrentChoices(const QList &choices) override; + QString editChoice() const override; + void setEditChoice(const QString &text) override; + Qt::Alignment textAlignment() const override; + bool canBeSpellChecked() const override; + +private: + std::unique_ptr m_field; + Okular::NormalizedRect m_rect; + int m_id; +}; + +class PopplerFormFieldSignature : public Okular::FormFieldSignature +{ +public: + PopplerFormFieldSignature(std::unique_ptr field); + ~PopplerFormFieldSignature() override; + + // inherited from Okular::FormField + Okular::NormalizedRect rect() const override; + int id() const override; + QString name() const override; + QString uiName() const override; + QString fullyQualifiedName() const override; + bool isReadOnly() const override; + bool isVisible() const override; + + // inherited from Okular::FormFieldSignature + SignatureType signatureType() const override; + const Okular::SignatureInfo &signatureInfo() const override; + +private: + std::unique_ptr m_field; + Okular::SignatureInfo *m_info; + Okular::NormalizedRect m_rect; + int m_id; +}; + +#endif diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp new file mode 100644 index 0000000..02c7f71 --- /dev/null +++ b/generators/poppler/generator_pdf.cpp @@ -0,0 +1,1865 @@ +/*************************************************************************** + * Copyright (C) 2004-2008 by Albert Astals Cid * + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2012 by Guillermo A. Amaral B. * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * Copyright (C) 2019 by Oliver Sander * + * * + * 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. * + ***************************************************************************/ + +#include + +#include "generator_pdf.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pdfsettings.h" +#include "ui_pdfsettingswidget.h" + +#include +#include + +#include "annots.h" +#include "debug_pdf.h" +#include "formfields.h" +#include "popplerembeddedfile.h" + +Q_DECLARE_METATYPE(Poppler::Annotation *) +Q_DECLARE_METATYPE(Poppler::FontInfo) +Q_DECLARE_METATYPE(const Poppler::LinkMovie *) +Q_DECLARE_METATYPE(const Poppler::LinkRendition *) +Q_DECLARE_METATYPE(const Poppler::LinkOCGState *) + +#define POPPLER_VERSION_MACRO ((POPPLER_VERSION_MAJOR << 16) | (POPPLER_VERSION_MINOR << 8) | (POPPLER_VERSION_MICRO)) + +static const int defaultPageWidth = 595; +static const int defaultPageHeight = 842; + +class PDFOptionsPage : public Okular::PrintOptionsWidget +{ + Q_OBJECT + +public: + enum ScaleMode { FitToPrintableArea, FitToPage, None }; + Q_ENUM(ScaleMode) + + PDFOptionsPage() + { + setWindowTitle(i18n("PDF Options")); + QVBoxLayout *layout = new QVBoxLayout(this); + m_printAnnots = new QCheckBox(i18n("Print annotations"), this); + m_printAnnots->setToolTip(i18n("Include annotations in the printed document")); + m_printAnnots->setWhatsThis(i18n("Includes annotations in the printed document. You can disable this if you want to print the original unannotated document.")); + layout->addWidget(m_printAnnots); + m_forceRaster = new QCheckBox(i18n("Force rasterization"), this); + m_forceRaster->setToolTip(i18n("Rasterize into an image before printing")); + m_forceRaster->setWhatsThis(i18n("Forces the rasterization of each page into an image before printing it. This usually gives somewhat worse results, but is useful when printing documents that appear to print incorrectly.")); + layout->addWidget(m_forceRaster); + + QWidget *formWidget = new QWidget(this); + QFormLayout *printBackendLayout = new QFormLayout(formWidget); + + m_scaleMode = new QComboBox; + m_scaleMode->insertItem(FitToPrintableArea, i18n("Fit to printable area"), FitToPrintableArea); + m_scaleMode->insertItem(FitToPage, i18n("Fit to full page"), FitToPage); + m_scaleMode->insertItem(None, i18n("None; print original size"), None); + m_scaleMode->setToolTip(i18n("Scaling mode for the printed pages")); + printBackendLayout->addRow(i18n("Scale mode:"), m_scaleMode); + + layout->addWidget(formWidget); + + layout->addStretch(1); + + setPrintAnnots(true); // Default value + } + + bool ignorePrintMargins() const override + { + return scaleMode() == FitToPage; + } + + bool printAnnots() + { + return m_printAnnots->isChecked(); + } + + void setPrintAnnots(bool printAnnots) + { + m_printAnnots->setChecked(printAnnots); + } + + bool printForceRaster() + { + return m_forceRaster->isChecked(); + } + + void setPrintForceRaster(bool forceRaster) + { + m_forceRaster->setChecked(forceRaster); + } + + ScaleMode scaleMode() const + { + return m_scaleMode->currentData().value(); + } + +private: + QCheckBox *m_printAnnots; + QCheckBox *m_forceRaster; + QComboBox *m_scaleMode; +}; + +static void fillViewportFromLinkDestination(Okular::DocumentViewport &viewport, const Poppler::LinkDestination &destination) +{ + viewport.pageNumber = destination.pageNumber() - 1; + + if (!viewport.isValid()) + return; + + // get destination position + // TODO add other attributes to the viewport (taken from link) + // switch ( destination->getKind() ) + // { + // case destXYZ: + if (destination.isChangeLeft() || destination.isChangeTop()) { + // TODO remember to change this if we implement DPI and/or rotation + double left, top; + left = destination.left(); + top = destination.top(); + + viewport.rePos.normalizedX = left; + viewport.rePos.normalizedY = top; + viewport.rePos.enabled = true; + viewport.rePos.pos = Okular::DocumentViewport::TopLeft; + } + /* TODO + if ( dest->getChangeZoom() ) + make zoom change*/ + /* break; + + default: + // implement the others cases + break;*/ + // } +} + +Okular::Sound *createSoundFromPopplerSound(const Poppler::SoundObject *popplerSound) +{ + Okular::Sound *sound = popplerSound->soundType() == Poppler::SoundObject::Embedded ? new Okular::Sound(popplerSound->data()) : new Okular::Sound(popplerSound->url()); + sound->setSamplingRate(popplerSound->samplingRate()); + sound->setChannels(popplerSound->channels()); + sound->setBitsPerSample(popplerSound->bitsPerSample()); + switch (popplerSound->soundEncoding()) { + case Poppler::SoundObject::Raw: + sound->setSoundEncoding(Okular::Sound::Raw); + break; + case Poppler::SoundObject::Signed: + sound->setSoundEncoding(Okular::Sound::Signed); + break; + case Poppler::SoundObject::muLaw: + sound->setSoundEncoding(Okular::Sound::muLaw); + break; + case Poppler::SoundObject::ALaw: + sound->setSoundEncoding(Okular::Sound::ALaw); + break; + } + return sound; +} + +Okular::Movie *createMovieFromPopplerMovie(const Poppler::MovieObject *popplerMovie) +{ + Okular::Movie *movie = new Okular::Movie(popplerMovie->url()); + movie->setSize(popplerMovie->size()); + movie->setRotation((Okular::Rotation)(popplerMovie->rotation() / 90)); + movie->setShowControls(popplerMovie->showControls()); + movie->setPlayMode((Okular::Movie::PlayMode)popplerMovie->playMode()); + movie->setAutoPlay(false); // will be triggered by external MovieAnnotation + movie->setShowPosterImage(popplerMovie->showPosterImage()); + movie->setPosterImage(popplerMovie->posterImage()); + return movie; +} + +Okular::Movie *createMovieFromPopplerScreen(const Poppler::LinkRendition *popplerScreen) +{ + Poppler::MediaRendition *rendition = popplerScreen->rendition(); + Okular::Movie *movie = nullptr; + if (rendition->isEmbedded()) + movie = new Okular::Movie(rendition->fileName(), rendition->data()); + else + movie = new Okular::Movie(rendition->fileName()); + movie->setSize(rendition->size()); + movie->setShowControls(rendition->showControls()); + if (rendition->repeatCount() == 0) { + movie->setPlayMode(Okular::Movie::PlayRepeat); + } else { + movie->setPlayMode(Okular::Movie::PlayLimited); + movie->setPlayRepetitions(rendition->repeatCount()); + } + movie->setAutoPlay(rendition->autoPlay()); + return movie; +} + +QPair createMovieFromPopplerRichMedia(const Poppler::RichMediaAnnotation *popplerRichMedia) +{ + const QPair emptyResult(nullptr, nullptr); + + /** + * To convert a Flash/Video based RichMedia annotation to a movie, we search for the first + * Flash/Video richmedia instance and parse the flashVars parameter for the 'source' identifier. + * That identifier is then used to find the associated embedded file through the assets + * mapping. + */ + const Poppler::RichMediaAnnotation::Content *content = popplerRichMedia->content(); + if (!content) + return emptyResult; + + const QList configurations = content->configurations(); + if (configurations.isEmpty()) + return emptyResult; + + const Poppler::RichMediaAnnotation::Configuration *configuration = configurations[0]; + + const QList instances = configuration->instances(); + if (instances.isEmpty()) + return emptyResult; + + const Poppler::RichMediaAnnotation::Instance *instance = instances[0]; + + if ((instance->type() != Poppler::RichMediaAnnotation::Instance::TypeFlash) && (instance->type() != Poppler::RichMediaAnnotation::Instance::TypeVideo)) + return emptyResult; + + const Poppler::RichMediaAnnotation::Params *params = instance->params(); + if (!params) + return emptyResult; + + QString sourceId; + bool playbackLoops = false; + + const QStringList flashVars = params->flashVars().split(QLatin1Char('&')); + for (const QString &flashVar : flashVars) { + const int pos = flashVar.indexOf(QLatin1Char('=')); + if (pos == -1) + continue; + + const QString key = flashVar.left(pos); + const QString value = flashVar.mid(pos + 1); + + if (key == QLatin1String("source")) + sourceId = value; + else if (key == QLatin1String("loop")) + playbackLoops = (value == QLatin1String("true") ? true : false); + } + + if (sourceId.isEmpty()) + return emptyResult; + + const QList assets = content->assets(); + if (assets.isEmpty()) + return emptyResult; + + Poppler::RichMediaAnnotation::Asset *matchingAsset = nullptr; + for (Poppler::RichMediaAnnotation::Asset *asset : assets) { + if (asset->name() == sourceId) { + matchingAsset = asset; + break; + } + } + + if (!matchingAsset) + return emptyResult; + + Poppler::EmbeddedFile *embeddedFile = matchingAsset->embeddedFile(); + if (!embeddedFile) + return emptyResult; + + Okular::EmbeddedFile *pdfEmbeddedFile = new PDFEmbeddedFile(embeddedFile); + + Okular::Movie *movie = new Okular::Movie(embeddedFile->name(), embeddedFile->data()); + movie->setPlayMode(playbackLoops ? Okular::Movie::PlayRepeat : Okular::Movie::PlayLimited); + + if (popplerRichMedia && popplerRichMedia->settings() && popplerRichMedia->settings()->activation()) { + if (popplerRichMedia->settings()->activation()->condition() == Poppler::RichMediaAnnotation::Activation::PageOpened || + popplerRichMedia->settings()->activation()->condition() == Poppler::RichMediaAnnotation::Activation::PageVisible) { + movie->setAutoPlay(true); + } else { + movie->setAutoPlay(false); + } + + } else { + movie->setAutoPlay(false); + } + + return qMakePair(movie, pdfEmbeddedFile); +} + +/** + * Note: the function will take ownership of the popplerLink object. + */ +Okular::Action *createLinkFromPopplerLink(const Poppler::Link *popplerLink, bool deletePopplerLink = true) +{ + if (!popplerLink) + return nullptr; + + Okular::Action *link = nullptr; + const Poppler::LinkGoto *popplerLinkGoto; + const Poppler::LinkExecute *popplerLinkExecute; + const Poppler::LinkBrowse *popplerLinkBrowse; + const Poppler::LinkAction *popplerLinkAction; + const Poppler::LinkSound *popplerLinkSound; + const Poppler::LinkJavaScript *popplerLinkJS; + const Poppler::LinkMovie *popplerLinkMovie; + const Poppler::LinkRendition *popplerLinkRendition; + Okular::DocumentViewport viewport; + + switch (popplerLink->linkType()) { + case Poppler::Link::None: + break; + + case Poppler::Link::Goto: { + popplerLinkGoto = static_cast(popplerLink); + const Poppler::LinkDestination dest = popplerLinkGoto->destination(); + const QString destName = dest.destinationName(); + if (destName.isEmpty()) { + fillViewportFromLinkDestination(viewport, dest); + link = new Okular::GotoAction(popplerLinkGoto->fileName(), viewport); + } else { + link = new Okular::GotoAction(popplerLinkGoto->fileName(), destName); + } + } break; + + case Poppler::Link::Execute: + popplerLinkExecute = static_cast(popplerLink); + link = new Okular::ExecuteAction(popplerLinkExecute->fileName(), popplerLinkExecute->parameters()); + break; + + case Poppler::Link::Browse: + popplerLinkBrowse = static_cast(popplerLink); + link = new Okular::BrowseAction(QUrl(popplerLinkBrowse->url())); + break; + + case Poppler::Link::Action: + popplerLinkAction = static_cast(popplerLink); + link = new Okular::DocumentAction((Okular::DocumentAction::DocumentActionType)popplerLinkAction->actionType()); + break; + + case Poppler::Link::Sound: { + popplerLinkSound = static_cast(popplerLink); + Poppler::SoundObject *popplerSound = popplerLinkSound->sound(); + Okular::Sound *sound = createSoundFromPopplerSound(popplerSound); + link = new Okular::SoundAction(popplerLinkSound->volume(), popplerLinkSound->synchronous(), popplerLinkSound->repeat(), popplerLinkSound->mix(), sound); + } break; + + case Poppler::Link::JavaScript: { + popplerLinkJS = static_cast(popplerLink); + link = new Okular::ScriptAction(Okular::JavaScript, popplerLinkJS->script()); + } break; + + case Poppler::Link::Rendition: { + if (!deletePopplerLink) { + // If links should not be deleted it probably means that they + // are part of a nextActions chain. There is no support + // to resolveMediaLinkReferences on nextActions. It would also + // be necessary to ensure that resolveMediaLinkReferences does + // not delete the Links which are part of a nextActions list + // to avoid a double deletion. + qCDebug(OkularPdfDebug) << "parsing rendition link without deletion is not supported. Action chain might be broken."; + break; + } + deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references + + popplerLinkRendition = static_cast(popplerLink); + + Okular::RenditionAction::OperationType operation = Okular::RenditionAction::None; + switch (popplerLinkRendition->action()) { + case Poppler::LinkRendition::NoRendition: + operation = Okular::RenditionAction::None; + break; + case Poppler::LinkRendition::PlayRendition: + operation = Okular::RenditionAction::Play; + break; + case Poppler::LinkRendition::StopRendition: + operation = Okular::RenditionAction::Stop; + break; + case Poppler::LinkRendition::PauseRendition: + operation = Okular::RenditionAction::Pause; + break; + case Poppler::LinkRendition::ResumeRendition: + operation = Okular::RenditionAction::Resume; + break; + }; + + Okular::Movie *movie = nullptr; + if (popplerLinkRendition->rendition()) + movie = createMovieFromPopplerScreen(popplerLinkRendition); + + Okular::RenditionAction *renditionAction = new Okular::RenditionAction(operation, movie, Okular::JavaScript, popplerLinkRendition->script()); + renditionAction->setNativeId(QVariant::fromValue(popplerLinkRendition)); + link = renditionAction; + } break; + + case Poppler::Link::Movie: { + if (!deletePopplerLink) { + // See comment above in Link::Rendition + qCDebug(OkularPdfDebug) << "parsing movie link without deletion is not supported. Action chain might be broken."; + break; + } + deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references + + popplerLinkMovie = static_cast(popplerLink); + + Okular::MovieAction::OperationType operation = Okular::MovieAction::Play; + switch (popplerLinkMovie->operation()) { + case Poppler::LinkMovie::Play: + operation = Okular::MovieAction::Play; + break; + case Poppler::LinkMovie::Stop: + operation = Okular::MovieAction::Stop; + break; + case Poppler::LinkMovie::Pause: + operation = Okular::MovieAction::Pause; + break; + case Poppler::LinkMovie::Resume: + operation = Okular::MovieAction::Resume; + break; + }; + + Okular::MovieAction *movieAction = new Okular::MovieAction(operation); + movieAction->setNativeId(QVariant::fromValue(popplerLinkMovie)); + link = movieAction; + } break; + + case Poppler::Link::Hide: { + const Poppler::LinkHide *l = static_cast(popplerLink); + QStringList scripts; + const QVector targets = l->targets(); + for (const QString &target : targets) { + scripts << QStringLiteral("getField(\"%1\").hidden = %2;").arg(target).arg(l->isShowAction() ? QLatin1String("false") : QLatin1String("true")); + } + link = new Okular::ScriptAction(Okular::JavaScript, scripts.join(QLatin1Char('\n'))); + } break; + + case Poppler::Link::OCGState: + link = new Okular::BackendOpaqueAction(); + link->setNativeId(QVariant::fromValue(static_cast(popplerLink))); + deletePopplerLink = false; + break; + } + + if (link) { + QVector nextActions; + const QVector nextLinks = popplerLink->nextLinks(); + for (const Poppler::Link *nl : nextLinks) { + nextActions << createLinkFromPopplerLink(nl, false); + } + link->setNextActions(nextActions); + } + + if (deletePopplerLink) + delete popplerLink; + + return link; +} + +/** + * Note: the function will take ownership of the popplerLink objects. + */ +static QLinkedList generateLinks(const QList &popplerLinks) +{ + QLinkedList links; + for (const Poppler::Link *popplerLink : popplerLinks) { + QRectF linkArea = popplerLink->linkArea(); + double nl = linkArea.left(), nt = linkArea.top(), nr = linkArea.right(), nb = linkArea.bottom(); + // create the rect using normalized coords and attach the Okular::Link to it + Okular::ObjectRect *rect = new Okular::ObjectRect(nl, nt, nr, nb, false, Okular::ObjectRect::Action, createLinkFromPopplerLink(popplerLink)); + // add the ObjectRect to the container + links.push_front(rect); + } + return links; +} + +/** NOTES on threading: + * internal: thread race prevention is done via the 'docLock' mutex. the + * mutex is needed only because we have the asynchronous thread; else + * the operations are all within the 'gui' thread, scheduled by the + * Qt scheduler and no mutex is needed. + * external: dangerous operations are all locked via mutex internally, and the + * only needed external thing is the 'canGeneratePixmap' method + * that tells if the generator is free (since we don't want an + * internal queue to store PixmapRequests). A generatedPixmap call + * without the 'ready' flag set, results in undefined behavior. + * So, as example, printing while generating a pixmap asynchronously is safe, + * it might only block the gui thread by 1) waiting for the mutex to unlock + * in async thread and 2) doing the 'heavy' print operation. + */ + +OKULAR_EXPORT_PLUGIN(PDFGenerator, "libokularGenerator_poppler.json") + +static void PDFGeneratorPopplerDebugFunction(const QString &message, const QVariant &closure) +{ + Q_UNUSED(closure); + qCDebug(OkularPdfDebug) << "[Poppler]" << message; +} + +PDFGenerator::PDFGenerator(QObject *parent, const QVariantList &args) + : Generator(parent, args) + , pdfdoc(nullptr) + , docSynopsisDirty(true) + , docEmbeddedFilesDirty(true) + , nextFontPage(0) + , annotProxy(nullptr) +{ + setFeature(Threaded); + setFeature(TextExtraction); + setFeature(FontInfo); +#ifdef Q_OS_WIN32 + setFeature(PrintNative); +#else + setFeature(PrintPostscript); +#endif + if (Okular::FilePrinter::ps2pdfAvailable()) + setFeature(PrintToFile); + setFeature(ReadRawData); + setFeature(TiledRendering); + setFeature(SwapBackingFile); + setFeature(SupportsCancelling); + + // You only need to do it once not for each of the documents but it is cheap enough + // so doing it all the time won't hurt either + Poppler::setDebugErrorFunction(PDFGeneratorPopplerDebugFunction, QVariant()); +} + +PDFGenerator::~PDFGenerator() +{ + delete pdfOptionsPage; +} + +// BEGIN Generator inherited functions +Okular::Document::OpenResult PDFGenerator::loadDocumentWithPassword(const QString &filePath, QVector &pagesVector, const QString &password) +{ +#ifndef NDEBUG + if (pdfdoc) { + qCDebug(OkularPdfDebug) << "PDFGenerator: multiple calls to loadDocument. Check it."; + return Okular::Document::OpenError; + } +#endif + // create PDFDoc for the given file + pdfdoc = Poppler::Document::load(filePath, nullptr, nullptr); + return init(pagesVector, password); +} + +Okular::Document::OpenResult PDFGenerator::loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector &pagesVector, const QString &password) +{ +#ifndef NDEBUG + if (pdfdoc) { + qCDebug(OkularPdfDebug) << "PDFGenerator: multiple calls to loadDocument. Check it."; + return Okular::Document::OpenError; + } +#endif + // create PDFDoc for the given file + pdfdoc = Poppler::Document::loadFromData(fileData, nullptr, nullptr); + return init(pagesVector, password); +} + +Okular::Document::OpenResult PDFGenerator::init(QVector &pagesVector, const QString &password) +{ + if (!pdfdoc) + return Okular::Document::OpenError; + + if (pdfdoc->isLocked()) { + pdfdoc->unlock(password.toLatin1(), password.toLatin1()); + + if (pdfdoc->isLocked()) { + delete pdfdoc; + pdfdoc = nullptr; + return Okular::Document::OpenNeedsPassword; + } + } + + // build Pages (currentPage was set -1 by deletePages) + int pageCount = pdfdoc->numPages(); + if (pageCount < 0) { + delete pdfdoc; + pdfdoc = nullptr; + return Okular::Document::OpenError; + } + pagesVector.resize(pageCount); + rectsGenerated.fill(false, pageCount); + + annotationsOnOpenHash.clear(); + + loadPages(pagesVector, 0, false); + + // update the configuration + reparseConfig(); + + // create annotation proxy + annotProxy = new PopplerAnnotationProxy(pdfdoc, userMutex(), &annotationsOnOpenHash); + + // the file has been loaded correctly + return Okular::Document::OpenSuccess; +} + +PDFGenerator::SwapBackingFileResult PDFGenerator::swapBackingFile(QString const &newFileName, QVector &newPagesVector) +{ + const QBitArray oldRectsGenerated = rectsGenerated; + + doCloseDocument(); + auto openResult = loadDocumentWithPassword(newFileName, newPagesVector, QString()); + if (openResult != Okular::Document::OpenSuccess) + return SwapBackingFileError; + + // Recreate links if needed since they are done on image() and image() is not called when swapping the file + // since the page is already rendered + if (oldRectsGenerated.count() == rectsGenerated.count()) { + for (int i = 0; i < oldRectsGenerated.count(); ++i) { + if (oldRectsGenerated[i]) { + Okular::Page *page = newPagesVector[i]; + Poppler::Page *pp = pdfdoc->page(i); + if (pp) { + page->setObjectRects(generateLinks(pp->links())); + rectsGenerated[i] = true; + resolveMediaLinkReferences(page); + delete pp; + } + } + } + } + + return SwapBackingFileReloadInternalData; +} + +bool PDFGenerator::doCloseDocument() +{ + // remove internal objects + userMutex()->lock(); + delete annotProxy; + annotProxy = nullptr; + delete pdfdoc; + pdfdoc = nullptr; + userMutex()->unlock(); + docSynopsisDirty = true; + docSyn.clear(); + docEmbeddedFilesDirty = true; + qDeleteAll(docEmbeddedFiles); + docEmbeddedFiles.clear(); + nextFontPage = 0; + rectsGenerated.clear(); + + return true; +} + +void PDFGenerator::loadPages(QVector &pagesVector, int rotation, bool clear) +{ + // TODO XPDF 3.01 check + const int count = pagesVector.count(); + double w = 0, h = 0; + for (int i = 0; i < count; i++) { + // get xpdf page + Poppler::Page *p = pdfdoc->page(i); + Okular::Page *page; + if (p) { + const QSizeF pSize = p->pageSizeF(); + w = pSize.width() / 72.0 * dpi().width(); + h = pSize.height() / 72.0 * dpi().height(); + Okular::Rotation orientation = Okular::Rotation0; + switch (p->orientation()) { + case Poppler::Page::Landscape: + orientation = Okular::Rotation90; + break; + case Poppler::Page::UpsideDown: + orientation = Okular::Rotation180; + break; + case Poppler::Page::Seascape: + orientation = Okular::Rotation270; + break; + case Poppler::Page::Portrait: + orientation = Okular::Rotation0; + break; + } + if (rotation % 2 == 1) + qSwap(w, h); + // init a Okular::page, add transition and annotation information + page = new Okular::Page(i, w, h, orientation); + addTransition(p, page); + if (true) // TODO real check + addAnnotations(p, page); + Poppler::Link *tmplink = p->action(Poppler::Page::Opening); + if (tmplink) { + page->setPageAction(Okular::Page::Opening, createLinkFromPopplerLink(tmplink)); + } + tmplink = p->action(Poppler::Page::Closing); + if (tmplink) { + page->setPageAction(Okular::Page::Closing, createLinkFromPopplerLink(tmplink)); + } + page->setDuration(p->duration()); + page->setLabel(p->label()); + + QLinkedList okularFormFields; +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(0, 89, 0) + if (i > 0) // for page 0 we handle the form fields at the end + okularFormFields = getFormFields(p); +#else + okularFormFields = getFormFields(p); +#endif + if (!okularFormFields.isEmpty()) + page->setFormFields(okularFormFields); + // kWarning(PDFDebug).nospace() << page->width() << "x" << page->height(); + +#ifdef PDFGENERATOR_DEBUG + qCDebug(OkularPdfDebug) << "load page" << i << "with rotation" << rotation << "and orientation" << orientation; +#endif + delete p; + + if (clear && pagesVector[i]) + delete pagesVector[i]; + } else { + page = new Okular::Page(i, defaultPageWidth, defaultPageHeight, Okular::Rotation0); + } + // set the Okular::page at the right position in document's pages vector + pagesVector[i] = page; + } + + // Once we've added the signatures to all pages except page 0, we add all the missing signatures there + // we do that because there's signatures that don't belong to any page, but okular needs a page<->signature mapping + if (count > 0) { +#if POPPLER_VERSION_MACRO >= QT_VERSION_CHECK(0, 89, 0) + const QVector allSignatures = pdfdoc->signatures(); + std::unique_ptr page0(pdfdoc->page(0)); + QLinkedList page0FormFields = getFormFields(page0.get()); + + for (Poppler::FormFieldSignature *s : allSignatures) { + bool createSignature = true; + const QString fullyQualifiedName = s->fullyQualifiedName(); + auto compareSignatureByFullyQualifiedName = [&fullyQualifiedName](const Okular::FormField *off) { return off->fullyQualifiedName() == fullyQualifiedName; }; + + // See if the signature is in one of the already loaded page (i.e. 1 to end) + for (Okular::Page *p : qAsConst(pagesVector)) { + const QLinkedList pageFormFields = p->formFields(); + if (std::find_if(pageFormFields.begin(), pageFormFields.end(), compareSignatureByFullyQualifiedName) != pageFormFields.end()) { + delete s; + createSignature = false; + break; + } + } + // See if the signature is in page 0 + if (createSignature && std::find_if(page0FormFields.constBegin(), page0FormFields.constEnd(), compareSignatureByFullyQualifiedName) != page0FormFields.constEnd()) { + delete s; + createSignature = false; + } + // Otherwise it's a page-less signature, add it to page 0 + if (createSignature) { + Okular::FormField *of = new PopplerFormFieldSignature(std::unique_ptr(s)); + page0FormFields.append(of); + } + } + + if (!page0FormFields.isEmpty()) + pagesVector[0]->setFormFields(page0FormFields); +#endif + } +} + +Okular::DocumentInfo PDFGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("application/pdf")); + + userMutex()->lock(); + + if (pdfdoc) { + // compile internal structure reading properties from PDFDoc + if (keys.contains(Okular::DocumentInfo::Title)) + docInfo.set(Okular::DocumentInfo::Title, pdfdoc->info(QStringLiteral("Title"))); + if (keys.contains(Okular::DocumentInfo::Subject)) + docInfo.set(Okular::DocumentInfo::Subject, pdfdoc->info(QStringLiteral("Subject"))); + if (keys.contains(Okular::DocumentInfo::Author)) + docInfo.set(Okular::DocumentInfo::Author, pdfdoc->info(QStringLiteral("Author"))); + if (keys.contains(Okular::DocumentInfo::Keywords)) + docInfo.set(Okular::DocumentInfo::Keywords, pdfdoc->info(QStringLiteral("Keywords"))); + if (keys.contains(Okular::DocumentInfo::Creator)) + docInfo.set(Okular::DocumentInfo::Creator, pdfdoc->info(QStringLiteral("Creator"))); + if (keys.contains(Okular::DocumentInfo::Producer)) + docInfo.set(Okular::DocumentInfo::Producer, pdfdoc->info(QStringLiteral("Producer"))); + if (keys.contains(Okular::DocumentInfo::CreationDate)) + docInfo.set(Okular::DocumentInfo::CreationDate, QLocale().toString(pdfdoc->date(QStringLiteral("CreationDate")), QLocale::LongFormat)); + if (keys.contains(Okular::DocumentInfo::ModificationDate)) + docInfo.set(Okular::DocumentInfo::ModificationDate, QLocale().toString(pdfdoc->date(QStringLiteral("ModDate")), QLocale::LongFormat)); + if (keys.contains(Okular::DocumentInfo::CustomKeys)) { + int major, minor; + pdfdoc->getPdfVersion(&major, &minor); + docInfo.set(QStringLiteral("format"), i18nc("PDF v. ", "PDF v. %1.%2", major, minor), i18n("Format")); + docInfo.set(QStringLiteral("encryption"), pdfdoc->isEncrypted() ? i18n("Encrypted") : i18n("Unencrypted"), i18n("Security")); + docInfo.set(QStringLiteral("optimization"), pdfdoc->isLinearized() ? i18n("Yes") : i18n("No"), i18n("Optimized")); + } + + docInfo.set(Okular::DocumentInfo::Pages, QString::number(pdfdoc->numPages())); + } + userMutex()->unlock(); + + return docInfo; +} + +const Okular::DocumentSynopsis *PDFGenerator::generateDocumentSynopsis() +{ + if (!docSynopsisDirty) + return &docSyn; + + if (!pdfdoc) + return nullptr; + + userMutex()->lock(); + const QVector outline = pdfdoc->outline(); + userMutex()->unlock(); + + if (outline.isEmpty()) + return nullptr; + + addSynopsisChildren(outline, &docSyn); + + docSynopsisDirty = false; + return &docSyn; +} + +static Okular::FontInfo::FontType convertPopplerFontInfoTypeToOkularFontInfoType(Poppler::FontInfo::Type type) +{ + switch (type) { + case Poppler::FontInfo::Type1: + return Okular::FontInfo::Type1; + break; + case Poppler::FontInfo::Type1C: + return Okular::FontInfo::Type1C; + break; + case Poppler::FontInfo::Type3: + return Okular::FontInfo::Type3; + break; + case Poppler::FontInfo::TrueType: + return Okular::FontInfo::TrueType; + break; + case Poppler::FontInfo::CIDType0: + return Okular::FontInfo::CIDType0; + break; + case Poppler::FontInfo::CIDType0C: + return Okular::FontInfo::CIDType0C; + break; + case Poppler::FontInfo::CIDTrueType: + return Okular::FontInfo::CIDTrueType; + break; + case Poppler::FontInfo::Type1COT: + return Okular::FontInfo::Type1COT; + break; + case Poppler::FontInfo::TrueTypeOT: + return Okular::FontInfo::TrueTypeOT; + break; + case Poppler::FontInfo::CIDType0COT: + return Okular::FontInfo::CIDType0COT; + break; + case Poppler::FontInfo::CIDTrueTypeOT: + return Okular::FontInfo::CIDTrueTypeOT; + break; + case Poppler::FontInfo::unknown: + default:; + } + return Okular::FontInfo::Unknown; +} + +static Okular::FontInfo::EmbedType embedTypeForPopplerFontInfo(const Poppler::FontInfo &fi) +{ + Okular::FontInfo::EmbedType ret = Okular::FontInfo::NotEmbedded; + if (fi.isEmbedded()) { + if (fi.isSubset()) { + ret = Okular::FontInfo::EmbeddedSubset; + } else { + ret = Okular::FontInfo::FullyEmbedded; + } + } + return ret; +} + +Okular::FontInfo::List PDFGenerator::fontsForPage(int page) +{ + Okular::FontInfo::List list; + + if (page != nextFontPage) + return list; + + QList fonts; + userMutex()->lock(); + + Poppler::FontIterator *it = pdfdoc->newFontIterator(page); + if (it->hasNext()) { + fonts = it->next(); + } + delete it; + userMutex()->unlock(); + + for (const Poppler::FontInfo &font : qAsConst(fonts)) { + Okular::FontInfo of; + of.setName(font.name()); + of.setSubstituteName(font.substituteName()); + of.setType(convertPopplerFontInfoTypeToOkularFontInfoType(font.type())); + of.setEmbedType(embedTypeForPopplerFontInfo(font)); + of.setFile(font.file()); + of.setCanBeExtracted(of.embedType() != Okular::FontInfo::NotEmbedded); + + QVariant nativeId; + nativeId.setValue(font); + of.setNativeId(nativeId); + + list.append(of); + } + + ++nextFontPage; + + return list; +} + +const QList *PDFGenerator::embeddedFiles() const +{ + if (docEmbeddedFilesDirty) { + userMutex()->lock(); + const QList &popplerFiles = pdfdoc->embeddedFiles(); + for (Poppler::EmbeddedFile *pef : popplerFiles) { + docEmbeddedFiles.append(new PDFEmbeddedFile(pef)); + } + userMutex()->unlock(); + + docEmbeddedFilesDirty = false; + } + + return &docEmbeddedFiles; +} + +QAbstractItemModel *PDFGenerator::layersModel() const +{ + return pdfdoc->hasOptionalContent() ? pdfdoc->optionalContentModel() : nullptr; +} + +void PDFGenerator::opaqueAction(const Okular::BackendOpaqueAction *action) +{ + const Poppler::LinkOCGState *popplerLink = action->nativeId().value(); + pdfdoc->optionalContentModel()->applyLink(const_cast(popplerLink)); +} + +bool PDFGenerator::isAllowed(Okular::Permission permission) const +{ + bool b = true; + switch (permission) { + case Okular::AllowModify: + b = pdfdoc->okToChange(); + break; + case Okular::AllowCopy: + b = pdfdoc->okToCopy(); + break; + case Okular::AllowPrint: + b = pdfdoc->okToPrint(); + break; + case Okular::AllowNotes: + b = pdfdoc->okToAddNotes(); + break; + case Okular::AllowFillForms: + b = pdfdoc->okToFillForm(); + break; + default:; + } + return b; +} + +struct RenderImagePayload { + RenderImagePayload(PDFGenerator *g, Okular::PixmapRequest *r) + : generator(g) + , request(r) + { + // Don't report partial updates for the first 500 ms + timer.setInterval(500); + timer.setSingleShot(true); + timer.start(); + } + + PDFGenerator *generator; + Okular::PixmapRequest *request; + QTimer timer; +}; +Q_DECLARE_METATYPE(RenderImagePayload *) + +static bool shouldDoPartialUpdateCallback(const QVariant &vPayload) +{ + auto payload = vPayload.value(); + + // Since the timer lives in a thread without an event loop we need to stop it ourselves + // when the remaining time has reached 0 + if (payload->timer.isActive() && payload->timer.remainingTime() == 0) { + payload->timer.stop(); + } + + return !payload->timer.isActive(); +} + +static void partialUpdateCallback(const QImage &image, const QVariant &vPayload) +{ + auto payload = vPayload.value(); + // clang-format off + // Otherwise the Okular::PixmapRequest* gets turned into Okular::PixmapRequest * that is not normalized and is slightly slower + QMetaObject::invokeMethod(payload->generator, "signalPartialPixmapRequest", Qt::QueuedConnection, Q_ARG(Okular::PixmapRequest*, payload->request), Q_ARG(QImage, image)); + // clang-format on +} + +static bool shouldAbortRenderCallback(const QVariant &vPayload) +{ + auto payload = vPayload.value(); + return payload->request->shouldAbortRender(); +} + +QImage PDFGenerator::image(Okular::PixmapRequest *request) +{ + // debug requests to this (xpdf) generator + // qCDebug(OkularPdfDebug) << "id: " << request->id << " is requesting " << (request->async ? "ASYNC" : "sync") << " pixmap for page " << request->page->number() << " [" << request->width << " x " << request->height << "]."; + + // compute dpi used to get an image with desired width and height + Okular::Page *page = request->page(); + + double pageWidth = page->width(), pageHeight = page->height(); + + if (page->rotation() % 2) + qSwap(pageWidth, pageHeight); + + qreal fakeDpiX = request->width() / pageWidth * dpi().width(); + qreal fakeDpiY = request->height() / pageHeight * dpi().height(); + + // generate links rects only the first time + bool genObjectRects = !rectsGenerated.at(page->number()); + + // 0. LOCK [waits for the thread end] + userMutex()->lock(); + + if (request->shouldAbortRender()) { + userMutex()->unlock(); + return QImage(); + } + + // 1. Set OutputDev parameters and Generate contents + // note: thread safety is set on 'false' for the GUI (this) thread + Poppler::Page *p = pdfdoc->page(page->number()); + + // 2. Take data from outputdev and attach it to the Page + QImage img; + if (p) { + if (request->isTile()) { + const QRect rect = request->normalizedRect().geometry(request->width(), request->height()); + if (request->partialUpdatesWanted()) { + RenderImagePayload payload(this, request); + img = p->renderToImage( + fakeDpiX, fakeDpiY, rect.x(), rect.y(), rect.width(), rect.height(), Poppler::Page::Rotate0, partialUpdateCallback, shouldDoPartialUpdateCallback, shouldAbortRenderCallback, QVariant::fromValue(&payload)); + } else { + RenderImagePayload payload(this, request); + img = p->renderToImage(fakeDpiX, fakeDpiY, rect.x(), rect.y(), rect.width(), rect.height(), Poppler::Page::Rotate0, nullptr, nullptr, shouldAbortRenderCallback, QVariant::fromValue(&payload)); + } + } else { + if (request->partialUpdatesWanted()) { + RenderImagePayload payload(this, request); + img = p->renderToImage(fakeDpiX, fakeDpiY, -1, -1, -1, -1, Poppler::Page::Rotate0, partialUpdateCallback, shouldDoPartialUpdateCallback, shouldAbortRenderCallback, QVariant::fromValue(&payload)); + } else { + RenderImagePayload payload(this, request); + img = p->renderToImage(fakeDpiX, fakeDpiY, -1, -1, -1, -1, Poppler::Page::Rotate0, nullptr, nullptr, shouldAbortRenderCallback, QVariant::fromValue(&payload)); + } + } + } else { + img = QImage(request->width(), request->height(), QImage::Format_Mono); + img.fill(Qt::white); + } + + if (p && genObjectRects) { + // TODO previously we extracted Image type rects too, but that needed porting to poppler + // and as we are not doing anything with Image type rects i did not port it, have a look at + // dead gp_outputdev.cpp on image extraction + page->setObjectRects(generateLinks(p->links())); + rectsGenerated[request->page()->number()] = true; + + resolveMediaLinkReferences(page); + } + + // 3. UNLOCK [re-enables shared access] + userMutex()->unlock(); + + delete p; + + return img; +} + +template +void resolveMediaLinks(Okular::Action *action, enum Okular::Annotation::SubType subType, QHash &annotationsHash) +{ + OkularLinkType *okularAction = static_cast(action); + + const PopplerLinkType *popplerLink = action->nativeId().value(); + + QHashIterator it(annotationsHash); + while (it.hasNext()) { + it.next(); + + if (it.key()->subType() == subType) { + const PopplerAnnotationType *popplerAnnotation = static_cast(it.value()); + + if (popplerLink->isReferencedAnnotation(popplerAnnotation)) { + okularAction->setAnnotation(static_cast(it.key())); + okularAction->setNativeId(QVariant()); + delete popplerLink; // delete the associated Poppler::LinkMovie object, it's not needed anymore + break; + } + } + } +} + +void PDFGenerator::resolveMediaLinkReference(Okular::Action *action) +{ + if (!action) + return; + + if ((action->actionType() != Okular::Action::Movie) && (action->actionType() != Okular::Action::Rendition)) + return; + + resolveMediaLinks(action, Okular::Annotation::AMovie, annotationsOnOpenHash); + resolveMediaLinks(action, Okular::Annotation::AScreen, annotationsOnOpenHash); +} + +void PDFGenerator::resolveMediaLinkReferences(Okular::Page *page) +{ + resolveMediaLinkReference(const_cast(page->pageAction(Okular::Page::Opening))); + resolveMediaLinkReference(const_cast(page->pageAction(Okular::Page::Closing))); + + const QLinkedList annotations = page->annotations(); + for (Okular::Annotation *annotation : annotations) { + if (annotation->subType() == Okular::Annotation::AScreen) { + Okular::ScreenAnnotation *screenAnnotation = static_cast(annotation); + resolveMediaLinkReference(screenAnnotation->additionalAction(Okular::Annotation::PageOpening)); + resolveMediaLinkReference(screenAnnotation->additionalAction(Okular::Annotation::PageClosing)); + } + + if (annotation->subType() == Okular::Annotation::AWidget) { + Okular::WidgetAnnotation *widgetAnnotation = static_cast(annotation); + resolveMediaLinkReference(widgetAnnotation->additionalAction(Okular::Annotation::PageOpening)); + resolveMediaLinkReference(widgetAnnotation->additionalAction(Okular::Annotation::PageClosing)); + } + } + + const QLinkedList fields = page->formFields(); + for (Okular::FormField *field : fields) { + resolveMediaLinkReference(field->activationAction()); + } +} + +struct TextExtractionPayload { + TextExtractionPayload(Okular::TextRequest *r) + : request(r) + { + } + + Okular::TextRequest *request; +}; +Q_DECLARE_METATYPE(TextExtractionPayload *) + +static bool shouldAbortTextExtractionCallback(const QVariant &vPayload) +{ + auto payload = vPayload.value(); + return payload->request->shouldAbortExtraction(); +} + +Okular::TextPage *PDFGenerator::textPage(Okular::TextRequest *request) +{ + const Okular::Page *page = request->page(); +#ifdef PDFGENERATOR_DEBUG + qCDebug(OkularPdfDebug) << "page" << page->number(); +#endif + // build a TextList... + QList textList; + double pageWidth, pageHeight; + userMutex()->lock(); + Poppler::Page *pp = pdfdoc->page(page->number()); + if (pp) { + TextExtractionPayload payload(request); + textList = pp->textList(Poppler::Page::Rotate0, shouldAbortTextExtractionCallback, QVariant::fromValue(&payload)); + const QSizeF s = pp->pageSizeF(); + pageWidth = s.width(); + pageHeight = s.height(); + } else { + pageWidth = defaultPageWidth; + pageHeight = defaultPageHeight; + } + delete pp; + userMutex()->unlock(); + + if (textList.isEmpty() && request->shouldAbortExtraction()) + return nullptr; + + Okular::TextPage *tp = abstractTextPage(textList, pageHeight, pageWidth, (Poppler::Page::Rotation)page->orientation()); + qDeleteAll(textList); + return tp; +} + +void PDFGenerator::requestFontData(const Okular::FontInfo &font, QByteArray *data) +{ + Poppler::FontInfo fi = font.nativeId().value(); + *data = pdfdoc->fontData(fi); +} + +#define DUMMY_QPRINTER_COPY +bool PDFGenerator::print(QPrinter &printer) +{ + bool printAnnots = true; + bool forceRasterize = false; + PDFOptionsPage::ScaleMode scaleMode = PDFOptionsPage::FitToPrintableArea; + + if (pdfOptionsPage) { + printAnnots = pdfOptionsPage->printAnnots(); + forceRasterize = pdfOptionsPage->printForceRaster(); + scaleMode = pdfOptionsPage->scaleMode(); + } + +#ifdef Q_OS_WIN + // Windows can only print by rasterization, because that is + // currently the only way Okular implements printing without using UNIX-specific + // tools like 'lpr'. + forceRasterize = true; +#endif + + if (forceRasterize) { + pdfdoc->setRenderHint(Poppler::Document::HideAnnotations, !printAnnots); + + if (pdfOptionsPage) { + // If requested, scale to full page instead of the printable area + printer.setFullPage(pdfOptionsPage->ignorePrintMargins()); + } + + QPainter painter; + painter.begin(&printer); + + QList pageList = Okular::FilePrinter::pageList(printer, pdfdoc->numPages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + for (int i = 0; i < pageList.count(); ++i) { + if (i != 0) + printer.newPage(); + + const int page = pageList.at(i) - 1; + userMutex()->lock(); + std::unique_ptr pp(pdfdoc->page(page)); + if (pp) { + QSizeF pageSize = pp->pageSizeF(); // Unit is 'points' (i.e., 1/72th of an inch) + QRect painterWindow = painter.window(); // Unit is 'QPrinter::DevicePixel' + + // Default: no scaling at all, but we need to go from DevicePixel units to 'points' + // Warning: We compute the horizontal scaling, and later assume that the vertical scaling will be the same. + double scaling = printer.paperRect(QPrinter::DevicePixel).width() / printer.paperRect(QPrinter::Point).width(); + + if (scaleMode != PDFOptionsPage::None) { + // Get the two scaling factors needed to fit the page onto paper horizontally or vertically + auto horizontalScaling = painterWindow.width() / pageSize.width(); + auto verticalScaling = painterWindow.height() / pageSize.height(); + + // We use the smaller of the two for both directions, to keep the aspect ratio + scaling = std::min(horizontalScaling, verticalScaling); + } + +#ifdef Q_OS_WIN + QImage img = pp->renderToImage(printer.physicalDpiX(), printer.physicalDpiY()); +#else + // UNIX: Same resolution as the postscript rasterizer; see discussion at https://git.reviewboard.kde.org/r/130218/ + QImage img = pp->renderToImage(300, 300); +#endif + painter.drawImage(QRectF(QPointF(0, 0), scaling * pp->pageSizeF()), img); + } + userMutex()->unlock(); + } + painter.end(); + return true; + } + +#ifdef DUMMY_QPRINTER_COPY + // Get the real page size to pass to the ps generator + QPrinter dummy(QPrinter::PrinterResolution); + dummy.setFullPage(true); + dummy.setOrientation(printer.orientation()); + dummy.setPageSize(printer.pageSize()); + dummy.setPaperSize(printer.paperSize(QPrinter::Millimeter), QPrinter::Millimeter); + int width = dummy.width(); + int height = dummy.height(); +#else + int width = printer.width(); + int height = printer.height(); +#endif + + if (width <= 0 || height <= 0) { + lastPrintError = InvalidPageSizePrintError; + return false; + } + + // Create the tempfile to send to FilePrinter, which will manage the deletion + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + if (!tf.open()) { + lastPrintError = TemporaryFileOpenPrintError; + return false; + } + QString tempfilename = tf.fileName(); + + // Generate the list of pages to be printed as selected in the print dialog + QList pageList = Okular::FilePrinter::pageList(printer, pdfdoc->numPages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + + // TODO rotation + + tf.setAutoRemove(false); + + QString pstitle = metaData(QStringLiteral("Title"), QVariant()).toString(); + if (pstitle.trimmed().isEmpty()) { + pstitle = document()->currentDocument().fileName(); + } + + Poppler::PSConverter *psConverter = pdfdoc->psConverter(); + + psConverter->setOutputDevice(&tf); + + psConverter->setPageList(pageList); + psConverter->setPaperWidth(width); + psConverter->setPaperHeight(height); + psConverter->setRightMargin(0); + psConverter->setBottomMargin(0); + psConverter->setLeftMargin(0); + psConverter->setTopMargin(0); + psConverter->setStrictMargins(false); + psConverter->setForceRasterize(forceRasterize); + psConverter->setTitle(pstitle); + + if (!printAnnots) + psConverter->setPSOptions(psConverter->psOptions() | Poppler::PSConverter::HideAnnotations); + + userMutex()->lock(); + if (psConverter->convert()) { + userMutex()->unlock(); + delete psConverter; + tf.close(); + + const Okular::FilePrinter::ScaleMode filePrinterScaleMode = (scaleMode == PDFOptionsPage::None) ? Okular::FilePrinter::ScaleMode::NoScaling : Okular::FilePrinter::ScaleMode::FitToPrintArea; + + int ret = + Okular::FilePrinter::printFile(printer, tempfilename, document()->orientation(), Okular::FilePrinter::SystemDeletesFiles, Okular::FilePrinter::ApplicationSelectsPages, document()->bookmarkedPageRange(), filePrinterScaleMode); + + lastPrintError = Okular::FilePrinter::printError(ret); + + return (lastPrintError == NoPrintError); + } else { + lastPrintError = FileConversionPrintError; + delete psConverter; + userMutex()->unlock(); + } + + tf.close(); + + return false; +} + +QVariant PDFGenerator::metaData(const QString &key, const QVariant &option) const +{ + if (key == QLatin1String("StartFullScreen")) { + QMutexLocker ml(userMutex()); + // asking for the 'start in fullscreen mode' (pdf property) + if (pdfdoc->pageMode() == Poppler::Document::FullScreen) + return true; + } else if (key == QLatin1String("NamedViewport") && !option.toString().isEmpty()) { + Okular::DocumentViewport viewport; + QString optionString = option.toString(); + + // asking for the page related to a 'named link destination'. the + // option is the link name. @see addSynopsisChildren. + userMutex()->lock(); + Poppler::LinkDestination *ld = pdfdoc->linkDestination(optionString); + userMutex()->unlock(); + if (ld) { + fillViewportFromLinkDestination(viewport, *ld); + } + delete ld; + if (viewport.pageNumber >= 0) + return viewport.toString(); + } else if (key == QLatin1String("DocumentTitle")) { + userMutex()->lock(); + QString title = pdfdoc->info(QStringLiteral("Title")); + userMutex()->unlock(); + return title; + } else if (key == QLatin1String("OpenTOC")) { + QMutexLocker ml(userMutex()); + if (pdfdoc->pageMode() == Poppler::Document::UseOutlines) + return true; + } else if (key == QLatin1String("DocumentScripts") && option.toString() == QLatin1String("JavaScript")) { + QMutexLocker ml(userMutex()); + return pdfdoc->scripts(); + } else if (key == QLatin1String("HasUnsupportedXfaForm")) { + QMutexLocker ml(userMutex()); + return pdfdoc->formType() == Poppler::Document::XfaForm; + } else if (key == QLatin1String("FormCalculateOrder")) { + QMutexLocker ml(userMutex()); + return QVariant::fromValue>(pdfdoc->formCalculateOrder()); + } else if (key == QLatin1String("GeneratorExtraDescription")) { + if (Poppler::Version::string() == QStringLiteral(POPPLER_VERSION)) { + return i18n("Using Poppler %1", Poppler::Version::string()); + } else { + return i18n("Using Poppler %1\n\nBuilt against Poppler %2", Poppler::Version::string(), POPPLER_VERSION); + } + } + return QVariant(); +} + +bool PDFGenerator::reparseConfig() +{ + if (!pdfdoc) + return false; + + bool somethingchanged = false; + // load paper color + QColor color = documentMetaData(PaperColorMetaData, true).value(); + // if paper color is changed we have to rebuild every visible pixmap in addition + // to the outputDevice. it's the 'heaviest' case, other effect are just recoloring + // over the page rendered on 'standard' white background. + if (color != pdfdoc->paperColor()) { + userMutex()->lock(); + pdfdoc->setPaperColor(color); + userMutex()->unlock(); + somethingchanged = true; + } + bool aaChanged = setDocumentRenderHints(); + somethingchanged = somethingchanged || aaChanged; + return somethingchanged; +} + +void PDFGenerator::addPages(KConfigDialog *dlg) +{ + Ui_PDFSettingsWidget pdfsw; + QWidget *w = new QWidget(dlg); + pdfsw.setupUi(w); + dlg->addPage(w, PDFSettings::self(), i18n("PDF"), QStringLiteral("application-pdf"), i18n("PDF Backend Configuration")); +} + +bool PDFGenerator::setDocumentRenderHints() +{ + bool changed = false; + const Poppler::Document::RenderHints oldhints = pdfdoc->renderHints(); +#define SET_HINT(hintname, hintdefvalue, hintflag) \ + { \ + bool newhint = documentMetaData(hintname, hintdefvalue).toBool(); \ + if (newhint != oldhints.testFlag(hintflag)) { \ + pdfdoc->setRenderHint(hintflag, newhint); \ + changed = true; \ + } \ + } + SET_HINT(GraphicsAntialiasMetaData, true, Poppler::Document::Antialiasing) + SET_HINT(TextAntialiasMetaData, true, Poppler::Document::TextAntialiasing) + SET_HINT(TextHintingMetaData, false, Poppler::Document::TextHinting) +#undef SET_HINT + // load thin line mode + const int thinLineMode = PDFSettings::enhanceThinLines(); + const bool enableThinLineSolid = thinLineMode == PDFSettings::EnumEnhanceThinLines::Solid; + const bool enableShapeLineSolid = thinLineMode == PDFSettings::EnumEnhanceThinLines::Shape; + const bool thinLineSolidWasEnabled = (oldhints & Poppler::Document::ThinLineSolid) == Poppler::Document::ThinLineSolid; + const bool thinLineShapeWasEnabled = (oldhints & Poppler::Document::ThinLineShape) == Poppler::Document::ThinLineShape; + if (enableThinLineSolid != thinLineSolidWasEnabled) { + pdfdoc->setRenderHint(Poppler::Document::ThinLineSolid, enableThinLineSolid); + changed = true; + } + if (enableShapeLineSolid != thinLineShapeWasEnabled) { + pdfdoc->setRenderHint(Poppler::Document::ThinLineShape, enableShapeLineSolid); + changed = true; + } + return changed; +} + +Okular::ExportFormat::List PDFGenerator::exportFormats() const +{ + static Okular::ExportFormat::List formats; + if (formats.isEmpty()) { + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText)); + } + + return formats; +} + +bool PDFGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format) +{ + if (format.mimeType().inherits(QStringLiteral("text/plain"))) { + QFile f(fileName); + if (!f.open(QIODevice::WriteOnly)) + return false; + + QTextStream ts(&f); + int num = document()->pages(); + for (int i = 0; i < num; ++i) { + QString text; + userMutex()->lock(); + Poppler::Page *pp = pdfdoc->page(i); + if (pp) { + text = pp->text(QRect()).normalized(QString::NormalizationForm_KC); + } + userMutex()->unlock(); + ts << text; + delete pp; + } + f.close(); + + return true; + } + + return false; +} + +// END Generator inherited functions + +inline void append(Okular::TextPage *ktp, const QString &s, double l, double b, double r, double t) +{ + // kWarning(PDFDebug).nospace() << "text: " << s << " at (" << l << "," << t << ")x(" << r <<","<append(s, new Okular::NormalizedRect(l, t, r, b)); +} + +Okular::TextPage *PDFGenerator::abstractTextPage(const QList &text, double height, double width, int rot) +{ + Q_UNUSED(rot); + Okular::TextPage *ktp = new Okular::TextPage; + Poppler::TextBox *next; +#ifdef PDFGENERATOR_DEBUG + qCDebug(OkularPdfDebug) << "getting text page in generator pdf - rotation:" << rot; +#endif + QString s; + bool addChar; + for (const Poppler::TextBox *word : text) { + const int qstringCharCount = word->text().length(); + next = word->nextWord(); + int textBoxChar = 0; + for (int j = 0; j < qstringCharCount; j++) { + const QChar c = word->text().at(j); + if (c.isHighSurrogate()) { + s = c; + addChar = false; + } else if (c.isLowSurrogate()) { + s += c; + addChar = true; + } else { + s = c; + addChar = true; + } + + if (addChar) { + QRectF charBBox = word->charBoundingBox(textBoxChar); + append(ktp, (j == qstringCharCount - 1 && !next) ? (s + QLatin1Char('\n')) : s, charBBox.left() / width, charBBox.bottom() / height, charBBox.right() / width, charBBox.top() / height); + textBoxChar++; + } + } + + if (word->hasSpaceAfter() && next) { + // TODO Check with a document with vertical text + // probably won't work and we will need to do comparisons + // between wordBBox and nextWordBBox to see if they are + // vertically or horizontally aligned + QRectF wordBBox = word->boundingBox(); + QRectF nextWordBBox = next->boundingBox(); + append(ktp, QStringLiteral(" "), wordBBox.right() / width, wordBBox.bottom() / height, nextWordBBox.left() / width, wordBBox.top() / height); + } + } + return ktp; +} + +void PDFGenerator::addSynopsisChildren(const QVector &outlineItems, QDomNode *parentDestination) +{ + for (const Poppler::OutlineItem &outlineItem : outlineItems) { + QDomElement item = docSyn.createElement(outlineItem.name()); + parentDestination->appendChild(item); + + item.setAttribute(QStringLiteral("ExternalFileName"), outlineItem.externalFileName()); + const QSharedPointer outlineDestination = outlineItem.destination(); + if (outlineDestination) { + const QString destinationName = outlineDestination->destinationName(); + if (!destinationName.isEmpty()) { + item.setAttribute(QStringLiteral("ViewportName"), destinationName); + } else { + Okular::DocumentViewport vp; + fillViewportFromLinkDestination(vp, *outlineDestination); + item.setAttribute(QStringLiteral("Viewport"), vp.toString()); + } + } + item.setAttribute(QStringLiteral("Open"), outlineItem.isOpen()); + item.setAttribute(QStringLiteral("URL"), outlineItem.uri()); + + if (outlineItem.hasChildren()) + addSynopsisChildren(outlineItem.children(), &item); + } +} + +void PDFGenerator::addAnnotations(Poppler::Page *popplerPage, Okular::Page *page) +{ + QSet subtypes; + subtypes << Poppler::Annotation::AFileAttachment << Poppler::Annotation::ASound << Poppler::Annotation::AMovie << Poppler::Annotation::AWidget << Poppler::Annotation::AScreen << Poppler::Annotation::AText << Poppler::Annotation::ALine + << Poppler::Annotation::AGeom << Poppler::Annotation::AHighlight << Poppler::Annotation::AInk << Poppler::Annotation::AStamp << Poppler::Annotation::ACaret; + + const QList popplerAnnotations = popplerPage->annotations(subtypes); + + for (Poppler::Annotation *a : popplerAnnotations) { + bool doDelete = true; + Okular::Annotation *newann = createAnnotationFromPopplerAnnotation(a, *popplerPage, &doDelete); + if (newann) { + page->addAnnotation(newann); + + if (a->subType() == Poppler::Annotation::AScreen) { + Poppler::ScreenAnnotation *annotScreen = static_cast(a); + Okular::ScreenAnnotation *screenAnnotation = static_cast(newann); + + // The activation action + const Poppler::Link *actionLink = annotScreen->action(); + if (actionLink) + screenAnnotation->setAction(createLinkFromPopplerLink(actionLink)); + + // The additional actions + const Poppler::Link *pageOpeningLink = annotScreen->additionalAction(Poppler::Annotation::PageOpeningAction); + if (pageOpeningLink) + screenAnnotation->setAdditionalAction(Okular::Annotation::PageOpening, createLinkFromPopplerLink(pageOpeningLink)); + + const Poppler::Link *pageClosingLink = annotScreen->additionalAction(Poppler::Annotation::PageClosingAction); + if (pageClosingLink) + screenAnnotation->setAdditionalAction(Okular::Annotation::PageClosing, createLinkFromPopplerLink(pageClosingLink)); + } + + if (a->subType() == Poppler::Annotation::AWidget) { + Poppler::WidgetAnnotation *annotWidget = static_cast(a); + Okular::WidgetAnnotation *widgetAnnotation = static_cast(newann); + + // The additional actions + const Poppler::Link *pageOpeningLink = annotWidget->additionalAction(Poppler::Annotation::PageOpeningAction); + if (pageOpeningLink) + widgetAnnotation->setAdditionalAction(Okular::Annotation::PageOpening, createLinkFromPopplerLink(pageOpeningLink)); + + const Poppler::Link *pageClosingLink = annotWidget->additionalAction(Poppler::Annotation::PageClosingAction); + if (pageClosingLink) + widgetAnnotation->setAdditionalAction(Okular::Annotation::PageClosing, createLinkFromPopplerLink(pageClosingLink)); + } + + if (!doDelete) + annotationsOnOpenHash.insert(newann, a); + } + if (doDelete) + delete a; + } +} + +void PDFGenerator::addTransition(Poppler::Page *pdfPage, Okular::Page *page) +// called on opening when MUTEX is not used +{ + Poppler::PageTransition *pdfTransition = pdfPage->transition(); + if (!pdfTransition || pdfTransition->type() == Poppler::PageTransition::Replace) + return; + + Okular::PageTransition *transition = new Okular::PageTransition(); + switch (pdfTransition->type()) { + case Poppler::PageTransition::Replace: + // won't get here, added to avoid warning + break; + case Poppler::PageTransition::Split: + transition->setType(Okular::PageTransition::Split); + break; + case Poppler::PageTransition::Blinds: + transition->setType(Okular::PageTransition::Blinds); + break; + case Poppler::PageTransition::Box: + transition->setType(Okular::PageTransition::Box); + break; + case Poppler::PageTransition::Wipe: + transition->setType(Okular::PageTransition::Wipe); + break; + case Poppler::PageTransition::Dissolve: + transition->setType(Okular::PageTransition::Dissolve); + break; + case Poppler::PageTransition::Glitter: + transition->setType(Okular::PageTransition::Glitter); + break; + case Poppler::PageTransition::Fly: + transition->setType(Okular::PageTransition::Fly); + break; + case Poppler::PageTransition::Push: + transition->setType(Okular::PageTransition::Push); + break; + case Poppler::PageTransition::Cover: + transition->setType(Okular::PageTransition::Cover); + break; + case Poppler::PageTransition::Uncover: + transition->setType(Okular::PageTransition::Uncover); + break; + case Poppler::PageTransition::Fade: + transition->setType(Okular::PageTransition::Fade); + break; + } + + transition->setDuration(pdfTransition->durationReal()); + + switch (pdfTransition->alignment()) { + case Poppler::PageTransition::Horizontal: + transition->setAlignment(Okular::PageTransition::Horizontal); + break; + case Poppler::PageTransition::Vertical: + transition->setAlignment(Okular::PageTransition::Vertical); + break; + } + + switch (pdfTransition->direction()) { + case Poppler::PageTransition::Inward: + transition->setDirection(Okular::PageTransition::Inward); + break; + case Poppler::PageTransition::Outward: + transition->setDirection(Okular::PageTransition::Outward); + break; + } + + transition->setAngle(pdfTransition->angle()); + transition->setScale(pdfTransition->scale()); + transition->setIsRectangular(pdfTransition->isRectangular()); + + page->setTransition(transition); +} + +QLinkedList PDFGenerator::getFormFields(Poppler::Page *popplerPage) +{ + if (!popplerPage) { + return {}; + } + + const QList popplerFormFields = popplerPage->formFields(); + QLinkedList okularFormFields; + for (Poppler::FormField *f : popplerFormFields) { + Okular::FormField *of = nullptr; + switch (f->type()) { + case Poppler::FormField::FormButton: + of = new PopplerFormFieldButton(std::unique_ptr(static_cast(f))); + break; + case Poppler::FormField::FormText: + of = new PopplerFormFieldText(std::unique_ptr(static_cast(f))); + break; + case Poppler::FormField::FormChoice: + of = new PopplerFormFieldChoice(std::unique_ptr(static_cast(f))); + break; + case Poppler::FormField::FormSignature: { + of = new PopplerFormFieldSignature(std::unique_ptr(static_cast(f))); + break; + } + default:; + } + if (of) + // form field created, good - it will take care of the Poppler::FormField + okularFormFields.append(of); + else + // no form field available - delete the Poppler::FormField + delete f; + } + + return okularFormFields; +} + +PDFGenerator::PrintError PDFGenerator::printError() const +{ + return lastPrintError; +} + +Okular::PrintOptionsWidget *PDFGenerator::printConfigurationWidget() const +{ + if (!pdfOptionsPage) { + const_cast(this)->pdfOptionsPage = new PDFOptionsPage(); + } + return pdfOptionsPage; +} + +bool PDFGenerator::supportsOption(SaveOption option) const +{ + switch (option) { + case SaveChanges: { + return true; + } + default:; + } + return false; +} + +bool PDFGenerator::save(const QString &fileName, SaveOptions options, QString *errorText) +{ + Q_UNUSED(errorText); + Poppler::PDFConverter *pdfConv = pdfdoc->pdfConverter(); + + pdfConv->setOutputFileName(fileName); + if (options & SaveChanges) + pdfConv->setPDFOptions(pdfConv->pdfOptions() | Poppler::PDFConverter::WithChanges); + + QMutexLocker locker(userMutex()); + + QHashIterator it(annotationsOnOpenHash); + while (it.hasNext()) { + it.next(); + + if (it.value()->uniqueName().isEmpty()) { + it.value()->setUniqueName(it.key()->uniqueName()); + } + } + + bool success = pdfConv->convert(); + if (!success) { + switch (pdfConv->lastError()) { + case Poppler::BaseConverter::NotSupportedInputFileError: + // This can only happen with Poppler before 0.22 which did not have qt5 version + break; + + case Poppler::BaseConverter::NoError: + case Poppler::BaseConverter::FileLockedError: + // we can't get here + break; + + case Poppler::BaseConverter::OpenOutputError: + // the default text message is good for this case + break; + } + } + delete pdfConv; + return success; +} + +Okular::AnnotationProxy *PDFGenerator::annotationProxy() const +{ + return annotProxy; +} + +#include "generator_pdf.moc" + +Q_LOGGING_CATEGORY(OkularPdfDebug, "org.kde.okular.generators.pdf", QtWarningMsg) + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/generators/poppler/generator_pdf.h b/generators/poppler/generator_pdf.h new file mode 100644 index 0000000..64f2c5b --- /dev/null +++ b/generators/poppler/generator_pdf.h @@ -0,0 +1,154 @@ +/*************************************************************************** + * Copyright (C) 2004-2008 by Albert Astals Cid * + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_GENERATOR_PDF_H_ +#define _OKULAR_GENERATOR_PDF_H_ + +//#include "synctex/synctex_parser.h" +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +class PDFOptionsPage; +class PopplerAnnotationProxy; + +/** + * @short A generator that builds contents from a PDF document. + * + * All Generator features are supported and implemented by this one. + * Internally this holds a reference to xpdf's core objects and provides + * contents generation using the PDFDoc object and a couple of OutputDevices + * called Okular::OutputDev and Okular::TextDev (both defined in gp_outputdev.h). + * + * For generating page contents we tell PDFDoc to render a page and grab + * contents from out OutputDevs when rendering finishes. + * + */ +class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, public Okular::PrintInterface, public Okular::SaveInterface +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + Q_INTERFACES(Okular::ConfigInterface) + Q_INTERFACES(Okular::PrintInterface) + Q_INTERFACES(Okular::SaveInterface) + +public: + PDFGenerator(QObject *parent, const QVariantList &args); + ~PDFGenerator() override; + + // [INHERITED] load a document and fill up the pagesVector + Okular::Document::OpenResult loadDocumentWithPassword(const QString &filePath, QVector &pagesVector, const QString &password) override; + Okular::Document::OpenResult loadDocumentFromDataWithPassword(const QByteArray &fileData, QVector &pagesVector, const QString &password) override; + void loadPages(QVector &pagesVector, int rotation = -1, bool clear = false); + // [INHERITED] document information + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + Okular::FontInfo::List fontsForPage(int page) override; + const QList *embeddedFiles() const override; + PageSizeMetric pagesSizeMetric() const override + { + return Pixels; + } + QAbstractItemModel *layersModel() const override; + void opaqueAction(const Okular::BackendOpaqueAction *action) override; + + // [INHERITED] document information + bool isAllowed(Okular::Permission permission) const override; + + // [INHERITED] perform actions on document / pages + QImage image(Okular::PixmapRequest *request) override; + + // [INHERITED] print page using an already configured kprinter + bool print(QPrinter &printer) override; + + // [INHERITED] reply to some metadata requests + QVariant metaData(const QString &key, const QVariant &option) const override; + + // [INHERITED] reparse configuration + bool reparseConfig() override; + void addPages(KConfigDialog *) override; + + // [INHERITED] text exporting + Okular::ExportFormat::List exportFormats() const override; + bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override; + + // [INHERITED] print interface + Okular::PrintOptionsWidget *printConfigurationWidget() const override; + + // [INHERITED] save interface + bool supportsOption(SaveOption) const override; + bool save(const QString &fileName, SaveOptions options, QString *errorText) override; + Okular::AnnotationProxy *annotationProxy() const override; + +protected: + SwapBackingFileResult swapBackingFile(QString const &newFileName, QVector &newPagesVector) override; + bool doCloseDocument() override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + Q_INVOKABLE Okular::Generator::PrintError printError() const; + +protected Q_SLOTS: + void requestFontData(const Okular::FontInfo &font, QByteArray *data); + +private: + Okular::Document::OpenResult init(QVector &pagesVector, const QString &password); + + // create the document synopsis hierarchy + void addSynopsisChildren(const QVector &outlineItems, QDomNode *parentDestination); + // fetch annotations from the pdf file and add they to the page + void addAnnotations(Poppler::Page *popplerPage, Okular::Page *page); + // fetch the transition information and add it to the page + void addTransition(Poppler::Page *pdfPage, Okular::Page *page); + // fetch the poppler page form fields + QLinkedList getFormFields(Poppler::Page *popplerPage); + + Okular::TextPage *abstractTextPage(const QList &text, double height, double width, int rot); + + void resolveMediaLinkReferences(Okular::Page *page); + void resolveMediaLinkReference(Okular::Action *action); + + bool setDocumentRenderHints(); + + // poppler dependent stuff + Poppler::Document *pdfdoc; + + // misc variables for document info and synopsis caching + bool docSynopsisDirty; + Okular::DocumentSynopsis docSyn; + mutable bool docEmbeddedFilesDirty; + mutable QList docEmbeddedFiles; + int nextFontPage; + PopplerAnnotationProxy *annotProxy; + // the hash below only contains annotations that were present on the file at open time + // this is enough for what we use it for + QHash annotationsOnOpenHash; + + QBitArray rectsGenerated; + + QPointer pdfOptionsPage; + + PrintError lastPrintError; +}; + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/generators/poppler/libokularGenerator_poppler.json b/generators/poppler/libokularGenerator_poppler.json new file mode 100644 index 0000000..a83548e --- /dev/null +++ b/generators/poppler/libokularGenerator_poppler.json @@ -0,0 +1,171 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "aacid@kde.org", + "Name": "Albert Astals Cid", + "Name[az]": "Albert Astals Cid", + "Name[ca@valencia]": "Albert Astals Cid", + "Name[ca]": "Albert Astals Cid", + "Name[cs]": "Albert Astals Cid", + "Name[da]": "Albert Astals Cid", + "Name[de]": "Albert Astals Cid", + "Name[el]": "Albert Astals Cid", + "Name[en_GB]": "Albert Astals Cid", + "Name[es]": "Albert Astals Cid", + "Name[et]": "Albert Astals Cid", + "Name[eu]": "Albert Astals Cid", + "Name[fi]": "Albert Astals Cid", + "Name[fr]": "Albert Astals Cid", + "Name[gl]": "Albert Astals Cid", + "Name[ia]": "Albert Astals Cid", + "Name[it]": "Albert Astals Cid", + "Name[ko]": "Albert Astals Cid", + "Name[lt]": "Albert Astals Cid", + "Name[nl]": "Albert Astals Cid", + "Name[nn]": "Albert Astals Cid", + "Name[pl]": "Albert Astals Cid", + "Name[pt]": "Albert Astals Cid", + "Name[pt_BR]": "Albert Astals Cid", + "Name[ru]": "Albert Astals Cid", + "Name[sk]": "Albert Astals Cid", + "Name[sl]": "Albert Astals Cid", + "Name[sr@ijekavian]": "Алберт Асталс Сид", + "Name[sr@ijekavianlatin]": "Albert Astals Sid", + "Name[sr@latin]": "Albert Astals Sid", + "Name[sr]": "Алберт Асталс Сид", + "Name[sv]": "Albert Astals Cid", + "Name[tr]": "Albert Astals Cid", + "Name[uk]": "Albert Astals Cid", + "Name[x-test]": "xxAlbert Astals Cidxx", + "Name[zh_CN]": "Albert Astals Cid", + "Name[zh_TW]": "Albert Astals Cid" + } + ], + "Copyright": "© 2005-2008 Albert Astals Cid", + "Copyright[az]": "© 2005-2008 Albert Astals Cid", + "Copyright[ca@valencia]": "© 2005-2008 Albert Astals Cid", + "Copyright[ca]": "© 2005-2008 Albert Astals Cid", + "Copyright[cs]": "© 2005-2008 Albert Astals Cid", + "Copyright[da]": "© 2005-2008 Albert Astals Cid", + "Copyright[de]": "© 2005-2008 Albert Astals Cid", + "Copyright[el]": "© 2005-2008 Albert Astals Cid", + "Copyright[en_GB]": "© 2005-2008 Albert Astals Cid", + "Copyright[es]": "© 2005-2008 Albert Astals Cid", + "Copyright[et]": "© 2005-2008: Albert Astals Cid", + "Copyright[eu]": "© 2005-2008 Albert Astals Cid", + "Copyright[fi]": "© 2005–2008 Albert Astals Cid", + "Copyright[fr]": "© 2005-2008 Albert Astals Cid", + "Copyright[gl]": "© 2005-2008 Albert Astals Cid", + "Copyright[ia]": "Albert Astals Cid", + "Copyright[it]": "© 2005-2008 Albert Astals Cid", + "Copyright[ko]": "© 2005-2008 Albert Astals Cid", + "Copyright[lt]": "© 2005-2008 Albert Astals Cid", + "Copyright[nl]": "© 2005-2008 Albert Astals Cid", + "Copyright[nn]": "© 2005–2008 Albert Astals Cid", + "Copyright[pl]": "© 2005-2008 Albert Astals Cid", + "Copyright[pt]": "© 2005-2008 Albert Astals Cid", + "Copyright[pt_BR]": "© 2005-2008 Albert Astals Cid", + "Copyright[ru]": "© Albert Astals Cid, 2005-2008", + "Copyright[sk]": "© 2005-2008 Albert Astals Cid", + "Copyright[sl]": "© 2005-2008 Albert Astals Cid", + "Copyright[sr@ijekavian]": "© 2005–2008, Алберт Асталс Сид", + "Copyright[sr@ijekavianlatin]": "© 2005–2008, Albert Astals Sid", + "Copyright[sr@latin]": "© 2005–2008, Albert Astals Sid", + "Copyright[sr]": "© 2005–2008, Алберт Асталс Сид", + "Copyright[sv]": "© 2005-2008 Albert Astals Cid", + "Copyright[tr]": "© 2005-2008 Albert Astals Cid", + "Copyright[uk]": "© Albert Astals Cid, 2005–2008", + "Copyright[x-test]": "xx© 2005-2008 Albert Astals Cidxx", + "Copyright[zh_CN]": "© 2005-2008 Albert Astals Cid", + "Copyright[zh_TW]": "© 2005-2008 Albert Astals Cid", + "Description": "A PDF file renderer", + "Description[az]": "PDF faylı tərtibatçısı", + "Description[ca@valencia]": "Un renderitzador per als fitxers PDF", + "Description[ca]": "Un renderitzador per als fitxers PDF", + "Description[cs]": "Vykreslovač PDF souborů", + "Description[da]": "En gengiver til PDF-filer", + "Description[de]": "Ein Renderer für PDF-Dateien", + "Description[el]": "Πρόγραμμα αποτύπωσης για PDF αρχεία", + "Description[en_GB]": "A PDF file renderer", + "Description[es]": "Un visor de archivos PDF", + "Description[et]": "PDF-faili renderdaja", + "Description[eu]": "PDF fitxategi errendatzaile bat", + "Description[fi]": "PDF-tiedostohahmonnin", + "Description[fr]": "Système de rendu pour les fichiers « PDF »", + "Description[gl]": "Un visor de ficheiros PDF", + "Description[ia]": "Un renditor de file de PDF", + "Description[it]": "Un visualizzatore di file PDF", + "Description[ko]": "PDF 파일 렌더러", + "Description[lt]": "PDF failų atvaizdavimas", + "Description[nl]": "Een PDF-bestandsviewer", + "Description[nn]": "Ein gjengjevar for PDF-filer", + "Description[pl]": "Wyświetlanie plików PDF", + "Description[pt]": "Um visualizador de ficheiros PDF", + "Description[pt_BR]": "Um interpretador de arquivos PDF", + "Description[ru]": "Модуль поддержки формата PDF", + "Description[sk]": "Vykresľovanie PDF súborov", + "Description[sl]": "Izrisovalnik datotek PDF", + "Description[sr@ijekavian]": "Рендерер ПДФ фајлова", + "Description[sr@ijekavianlatin]": "Renderer PDF fajlova", + "Description[sr@latin]": "Renderer PDF fajlova", + "Description[sr]": "Рендерер ПДФ фајлова", + "Description[sv]": "Ett återgivningsprogram för PDF-filer", + "Description[tr]": "PDF dosyası oluşturucu", + "Description[uk]": "Програма для показу файлів PDF", + "Description[x-test]": "xxA PDF file rendererxx", + "Description[zh_CN]": "PDF 文件渲染器", + "Description[zh_TW]": "PDF 檔成像器", + "Id": "okular_poppler", + "License": "GPL", + "MimeTypes": [ + "application/x-pdf", + "application/pdf", + "application/x-wwf" + ], + "Name": "PDF Backend", + "Name[az]": "PDF modulu", + "Name[ca@valencia]": "Dorsal PDF", + "Name[ca]": "Dorsal PDF", + "Name[cs]": "Podpůrná vrstva PDF", + "Name[da]": "PDF-backend", + "Name[de]": "PDF-Anzeigemodul", + "Name[el]": "Σύστημα υποστήριξης PDF", + "Name[en_GB]": "PDF Backend", + "Name[es]": "Motor para PDF", + "Name[et]": "PDF-i taustaprogramm", + "Name[eu]": "PDFen bizkarraldekoa", + "Name[fi]": "PDF-taustaosa", + "Name[fr]": "Moteur PDF", + "Name[gl]": "Infraestrutura de PDF", + "Name[ia]": "Retro-administration de PDF", + "Name[it]": "Backend PDF", + "Name[ko]": "PDF 백엔드", + "Name[lt]": "PDF programinė sąsaja", + "Name[nl]": "PDF-backend", + "Name[nn]": "PDF-motor", + "Name[pl]": "Obsługa PDF", + "Name[pt]": "Infra-Estrutura de PDF", + "Name[pt_BR]": "Infraestrutura PDF", + "Name[ru]": "Модуль поддержки формата PDF", + "Name[sk]": "PDF Backend", + "Name[sl]": "Zaledje za PDF", + "Name[sr@ijekavian]": "Позадина за ПДФ", + "Name[sr@ijekavianlatin]": "Pozadina za PDF", + "Name[sr@latin]": "Pozadina za PDF", + "Name[sr]": "Позадина за ПДФ", + "Name[sv]": "PDF-gränssnitt", + "Name[tr]": "PDF Arka Ucu", + "Name[uk]": "Модуль PDF", + "Name[x-test]": "xxPDF Backendxx", + "Name[zh_CN]": "PDF 后端", + "Name[zh_TW]": "PDF 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.6.5" + }, + "X-KDE-Priority": 1, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/poppler/okularApplication_pdf.desktop b/generators/poppler/okularApplication_pdf.desktop new file mode 100755 index 0000000..3edf34b --- /dev/null +++ b/generators/poppler/okularApplication_pdf.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/pdf;application/x-gzpdf;application/x-bzpdf;application/x-wwf; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=8 +Categories=Qt;KDE;Graphics;Viewer; +X-KDE-Keywords=PDF, Portable Document Format +X-KDE-Keywords[ar]=PDF, Portable Document Format +X-KDE-Keywords[az]=PDF, Portable Document Format +X-KDE-Keywords[bg]=PDF, Portable Document Format +X-KDE-Keywords[bs]=PDF, Portable Document Format +X-KDE-Keywords[ca]=PDF, Format de document portable +X-KDE-Keywords[ca@valencia]=PDF, Format de document portable +X-KDE-Keywords[cs]=PDF, Portable Document Format +X-KDE-Keywords[da]=PDF,Portable Document Format +X-KDE-Keywords[de]=PDF, Portable Document Format +X-KDE-Keywords[el]=PDF, Portable Document Format +X-KDE-Keywords[en_GB]=PDF, Portable Document Format +X-KDE-Keywords[es]=PDF, Formato de Documento Portable +X-KDE-Keywords[et]=PDF, Portable Document Format +X-KDE-Keywords[eu]=PDF, Portable Document Format (Dokumentu Formatu Eramangarria) +X-KDE-Keywords[fi]=PDF, Portable Document Format +X-KDE-Keywords[fr]=PDF, Portable Document Format +X-KDE-Keywords[ga]=PDF, Portable Document Format +X-KDE-Keywords[gl]=PDF, Formato portátil de documentos +X-KDE-Keywords[hu]=PDF, Portable Document Format +X-KDE-Keywords[ia]=PDF, Formato de Documento Portabile +X-KDE-Keywords[is]=PDF, Portable Document Format +X-KDE-Keywords[it]=PDF, Portable Document Format, formato per documenti portabile +X-KDE-Keywords[ja]=PDF +X-KDE-Keywords[kk]=PDF, Portable Document Format +X-KDE-Keywords[km]=PDF, Portable Document Format +X-KDE-Keywords[ko]=PDF, Portable Document Format +X-KDE-Keywords[lt]=PDF, Portable Document Format, Portable Document formatas, PDF formatas +X-KDE-Keywords[lv]=PDF, Portable Document formāts +X-KDE-Keywords[mr]=PDF, Portable Document Format +X-KDE-Keywords[nb]=PDF, Portabelt Dokument Format +X-KDE-Keywords[nds]=PDF, Porteerbor Dokmentformaat +X-KDE-Keywords[nl]=PDF, Portable Document Format +X-KDE-Keywords[nn]=PDF, Portabelt dokumentformat +X-KDE-Keywords[pa]=PDF, ਪੋਰਟੇਬਲ ਡੌਕੂਮੈਂਟ ਫਾਰਮੈਟ +X-KDE-Keywords[pl]=PDF, Przenośny Format Dokumentu +X-KDE-Keywords[pt]=PDF, Formato de Documento Portável +X-KDE-Keywords[pt_BR]=PDF, Formato de documento portável +X-KDE-Keywords[ro]=PDF, Portable Document Format +X-KDE-Keywords[ru]=PDF, Portable Document Format +X-KDE-Keywords[sk]=PDF, Portable Document Format +X-KDE-Keywords[sl]=PDF, Portable Document Format +X-KDE-Keywords[sr]=PDF, Portable Document Format,ПДФ +X-KDE-Keywords[sr@ijekavian]=PDF, Portable Document Format,ПДФ +X-KDE-Keywords[sr@ijekavianlatin]=PDF, Portable Document Format,PDF +X-KDE-Keywords[sr@latin]=PDF, Portable Document Format,PDF +X-KDE-Keywords[sv]=PDF, Portabelt dokumentformat +X-KDE-Keywords[tr]=PDF, Taşınabilir Belge Biçimi +X-KDE-Keywords[uk]=PDF,Portable Document Format,пдф +X-KDE-Keywords[x-test]=xxPDFxx,xx Portable Document Formatxx +X-KDE-Keywords[zh_CN]=PDF, Portable Document Format,开放文档格式 +X-KDE-Keywords[zh_TW]=PDF, Portable Document Format +NoDisplay=true diff --git a/generators/poppler/okularPoppler.desktop b/generators/poppler/okularPoppler.desktop new file mode 100644 index 0000000..7f55eb8 --- /dev/null +++ b/generators/poppler/okularPoppler.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/x-pdf;application/pdf;application/x-gzpdf;application/x-bzpdf;application/x-wwf; diff --git a/generators/poppler/org.kde.mobile.okular_pdf.desktop b/generators/poppler/org.kde.mobile.okular_pdf.desktop new file mode 100644 index 0000000..4a5cd5b --- /dev/null +++ b/generators/poppler/org.kde.mobile.okular_pdf.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +MimeType=application/pdf;application/x-gzpdf;application/x-bzpdf;application/x-wwf; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=PDF, Portable Document Format +X-KDE-Keywords[ar]=PDF, Portable Document Format +X-KDE-Keywords[az]=PDF, Portable Document Format +X-KDE-Keywords[bg]=PDF, Portable Document Format +X-KDE-Keywords[bs]=PDF, Portable Document Format +X-KDE-Keywords[ca]=PDF, Format de document portable +X-KDE-Keywords[ca@valencia]=PDF, Format de document portable +X-KDE-Keywords[cs]=PDF, Portable Document Format +X-KDE-Keywords[da]=PDF,Portable Document Format +X-KDE-Keywords[de]=PDF, Portable Document Format +X-KDE-Keywords[el]=PDF, Portable Document Format +X-KDE-Keywords[en_GB]=PDF, Portable Document Format +X-KDE-Keywords[es]=PDF, Formato de Documento Portable +X-KDE-Keywords[et]=PDF, Portable Document Format +X-KDE-Keywords[eu]=PDF, Portable Document Format (Dokumentu Formatu Eramangarria) +X-KDE-Keywords[fi]=PDF, Portable Document Format +X-KDE-Keywords[fr]=PDF, Portable Document Format +X-KDE-Keywords[ga]=PDF, Portable Document Format +X-KDE-Keywords[gl]=PDF, Formato portátil de documentos +X-KDE-Keywords[hu]=PDF, Portable Document Format +X-KDE-Keywords[ia]=PDF, Formato de Documento Portabile +X-KDE-Keywords[is]=PDF, Portable Document Format +X-KDE-Keywords[it]=PDF, Portable Document Format, formato per documenti portabile +X-KDE-Keywords[ja]=PDF +X-KDE-Keywords[kk]=PDF, Portable Document Format +X-KDE-Keywords[km]=PDF, Portable Document Format +X-KDE-Keywords[ko]=PDF, Portable Document Format +X-KDE-Keywords[lt]=PDF, Portable Document Format, Portable Document formatas, PDF formatas +X-KDE-Keywords[lv]=PDF, Portable Document formāts +X-KDE-Keywords[mr]=PDF, Portable Document Format +X-KDE-Keywords[nb]=PDF, Portabelt Dokument Format +X-KDE-Keywords[nds]=PDF, Porteerbor Dokmentformaat +X-KDE-Keywords[nl]=PDF, Portable Document Format +X-KDE-Keywords[nn]=PDF, Portabelt dokumentformat +X-KDE-Keywords[pa]=PDF, ਪੋਰਟੇਬਲ ਡੌਕੂਮੈਂਟ ਫਾਰਮੈਟ +X-KDE-Keywords[pl]=PDF, Przenośny Format Dokumentu +X-KDE-Keywords[pt]=PDF, Formato de Documento Portável +X-KDE-Keywords[pt_BR]=PDF, Formato de documento portável +X-KDE-Keywords[ro]=PDF, Portable Document Format +X-KDE-Keywords[ru]=PDF, Portable Document Format +X-KDE-Keywords[sk]=PDF, Portable Document Format +X-KDE-Keywords[sl]=PDF, Portable Document Format +X-KDE-Keywords[sr]=PDF, Portable Document Format,ПДФ +X-KDE-Keywords[sr@ijekavian]=PDF, Portable Document Format,ПДФ +X-KDE-Keywords[sr@ijekavianlatin]=PDF, Portable Document Format,PDF +X-KDE-Keywords[sr@latin]=PDF, Portable Document Format,PDF +X-KDE-Keywords[sv]=PDF, Portabelt dokumentformat +X-KDE-Keywords[tr]=PDF, Taşınabilir Belge Biçimi +X-KDE-Keywords[uk]=PDF,Portable Document Format,пдф +X-KDE-Keywords[x-test]=xxPDFxx,xx Portable Document Formatxx +X-KDE-Keywords[zh_CN]=PDF, Portable Document Format,开放文档格式 +X-KDE-Keywords[zh_TW]=PDF, Portable Document Format diff --git a/generators/poppler/org.kde.okular-poppler.metainfo.xml b/generators/poppler/org.kde.okular-poppler.metainfo.xml new file mode 100644 index 0000000..3898b59 --- /dev/null +++ b/generators/poppler/org.kde.okular-poppler.metainfo.xml @@ -0,0 +1,94 @@ + + + org.kde.okular-poppler + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + പി ടി എഫ് + PDF + PDF + PDF + PDF + PDF + PDF + PDF + PDF + ПДФ + PDF + ПДФ + PDF + PDF + PDF + PDF + xxPDFxx + PDF + PDF + Adds support for reading PDF documents + PDF sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents PDF + Afig la implementació per a llegir documents PDF + Přidává podporu pro čtení dokumentů PDF + Bietet Unterstützung zum Lesen von PDF-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων PDF + Adds support for reading PDF documents + Permite la lectura de documentos PDF + PDF-dokumentide lugemise toetus + PDF dokumentuak irakurtzeko euskarria gehitzen du + Lisää PDF-tiedostojen lukutuen + Permet la lecture des documents PDF + Engade a posibilidade de ler documentos PDF + Adde supporto per leger documentos PDF + Aggiunge il supporto per la lettura di documenti PDF + PDF 문서 읽기 지원 추가 + Prideda palaikymą PDF dokumentų skaitymui + പി ടി ഫ് പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van PDF-documenten toe + Legg til støtte for å lesa PDF-dokument + Dodaje obsługę dokumentów PDF + Adiciona o suporte para ler documentos em PDF + Adiciona o suporte para leitura de documentos em PDF + Поддержка чтения документов PDF + Pridá podporu pre čítanie PDF dokumentov + Doda podporo za branje dokumentov PDF + Подршка за читање ПДФ докумената + Podrška za čitanje PDF dokumenata + Подршка за читање ПДФ докумената + Podrška za čitanje PDF dokumenata + Lägger till stöd för att läsa PDF-dokument + PDF belgelerini okuma desteği ekler + Додає підтримку читання документів PDF + xxAdds support for reading PDF documentsxx + 增加对 PDF 文档的阅读支持 + 加入讀取 PDF 文件的支援 + + application/pdf + application/x-gzpdf + application/x-bzpdf + application/x-wwf + + https://okular.kde.org + + + + + + + diff --git a/generators/poppler/pdfsignatureutils.cpp b/generators/poppler/pdfsignatureutils.cpp new file mode 100644 index 0000000..1cc2135 --- /dev/null +++ b/generators/poppler/pdfsignatureutils.cpp @@ -0,0 +1,240 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "pdfsignatureutils.h" + +#include +#include + +PopplerCertificateInfo::PopplerCertificateInfo(const Poppler::CertificateInfo &info) + : m_info(info) +{ +} + +PopplerCertificateInfo::~PopplerCertificateInfo() +{ +} + +bool PopplerCertificateInfo::isNull() const +{ + return m_info.isNull(); +} + +int PopplerCertificateInfo::version() const +{ + return m_info.version(); +} + +QByteArray PopplerCertificateInfo::serialNumber() const +{ + return m_info.serialNumber(); +} + +QString PopplerCertificateInfo::issuerInfo(PopplerCertificateInfo::EntityInfoKey key) const +{ + QString str = m_info.issuerInfo(static_cast(key)); + return !str.isEmpty() ? str : i18n("Not Available"); +} + +QString PopplerCertificateInfo::subjectInfo(PopplerCertificateInfo::EntityInfoKey key) const +{ + QString str = m_info.subjectInfo(static_cast(key)); + return !str.isEmpty() ? str : i18n("Not Available"); +} + +QDateTime PopplerCertificateInfo::validityStart() const +{ + return m_info.validityStart(); +} + +QDateTime PopplerCertificateInfo::validityEnd() const +{ + return m_info.validityEnd(); +} + +PopplerCertificateInfo::KeyUsageExtensions PopplerCertificateInfo::keyUsageExtensions() const +{ + Poppler::CertificateInfo::KeyUsageExtensions popplerKu = m_info.keyUsageExtensions(); + KeyUsageExtensions ku = KuNone; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuDigitalSignature)) + ku |= KuDigitalSignature; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuNonRepudiation)) + ku |= KuNonRepudiation; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyEncipherment)) + ku |= KuKeyEncipherment; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuDataEncipherment)) + ku |= KuDataEncipherment; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyAgreement)) + ku |= KuKeyAgreement; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuKeyCertSign)) + ku |= KuKeyCertSign; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuClrSign)) + ku |= KuClrSign; + if (popplerKu.testFlag(Poppler::CertificateInfo::KuEncipherOnly)) + ku |= KuEncipherOnly; + return ku; +} + +QByteArray PopplerCertificateInfo::publicKey() const +{ + return m_info.publicKey(); +} + +PopplerCertificateInfo::PublicKeyType PopplerCertificateInfo::publicKeyType() const +{ + switch (m_info.publicKeyType()) { + case Poppler::CertificateInfo::RsaKey: + return RsaKey; + case Poppler::CertificateInfo::DsaKey: + return DsaKey; + case Poppler::CertificateInfo::EcKey: + return EcKey; + case Poppler::CertificateInfo::OtherKey: + return OtherKey; + } + + return OtherKey; +} + +int PopplerCertificateInfo::publicKeyStrength() const +{ + return m_info.publicKeyStrength(); +} + +bool PopplerCertificateInfo::isSelfSigned() const +{ + return m_info.isSelfSigned(); +} + +QByteArray PopplerCertificateInfo::certificateData() const +{ + return m_info.certificateData(); +} + +PopplerSignatureInfo::PopplerSignatureInfo(const Poppler::SignatureValidationInfo &info) + : m_info(info) +{ + m_certfiticateInfo = new PopplerCertificateInfo(m_info.certificateInfo()); +} + +PopplerSignatureInfo::~PopplerSignatureInfo() +{ + delete m_certfiticateInfo; +} + +PopplerSignatureInfo::SignatureStatus PopplerSignatureInfo::signatureStatus() const +{ + switch (m_info.signatureStatus()) { + case Poppler::SignatureValidationInfo::SignatureValid: + return SignatureValid; + case Poppler::SignatureValidationInfo::SignatureInvalid: + return SignatureInvalid; + case Poppler::SignatureValidationInfo::SignatureDigestMismatch: + return SignatureDigestMismatch; + case Poppler::SignatureValidationInfo::SignatureDecodingError: + return SignatureDecodingError; + case Poppler::SignatureValidationInfo::SignatureGenericError: + return SignatureGenericError; + case Poppler::SignatureValidationInfo::SignatureNotFound: + return SignatureNotFound; + case Poppler::SignatureValidationInfo::SignatureNotVerified: + return SignatureNotVerified; + default: + return SignatureStatusUnknown; + } +} + +PopplerSignatureInfo::CertificateStatus PopplerSignatureInfo::certificateStatus() const +{ + switch (m_info.certificateStatus()) { + case Poppler::SignatureValidationInfo::CertificateTrusted: + return CertificateTrusted; + case Poppler::SignatureValidationInfo::CertificateUntrustedIssuer: + return CertificateUntrustedIssuer; + case Poppler::SignatureValidationInfo::CertificateUnknownIssuer: + return CertificateUnknownIssuer; + case Poppler::SignatureValidationInfo::CertificateRevoked: + return CertificateRevoked; + case Poppler::SignatureValidationInfo::CertificateExpired: + return CertificateExpired; + case Poppler::SignatureValidationInfo::CertificateGenericError: + return CertificateGenericError; + case Poppler::SignatureValidationInfo::CertificateNotVerified: + return CertificateNotVerified; + default: + return CertificateStatusUnknown; + } +} + +PopplerSignatureInfo::HashAlgorithm PopplerSignatureInfo::hashAlgorithm() const +{ + switch (m_info.hashAlgorithm()) { + case Poppler::SignatureValidationInfo::HashAlgorithmMd2: + return HashAlgorithmMd2; + case Poppler::SignatureValidationInfo::HashAlgorithmMd5: + return HashAlgorithmMd5; + case Poppler::SignatureValidationInfo::HashAlgorithmSha1: + return HashAlgorithmSha1; + case Poppler::SignatureValidationInfo::HashAlgorithmSha256: + return HashAlgorithmSha256; + case Poppler::SignatureValidationInfo::HashAlgorithmSha384: + return HashAlgorithmSha384; + case Poppler::SignatureValidationInfo::HashAlgorithmSha512: + return HashAlgorithmSha512; + case Poppler::SignatureValidationInfo::HashAlgorithmSha224: + return HashAlgorithmSha224; + default: + return HashAlgorithmUnknown; + } +} + +QString PopplerSignatureInfo::signerName() const +{ + return m_info.signerName(); +} + +QString PopplerSignatureInfo::signerSubjectDN() const +{ + return m_info.signerSubjectDN(); +} + +QString PopplerSignatureInfo::location() const +{ + return m_info.location(); +} + +QString PopplerSignatureInfo::reason() const +{ + return m_info.reason(); +} + +QDateTime PopplerSignatureInfo::signingTime() const +{ + return QDateTime::fromSecsSinceEpoch(m_info.signingTime()); +} + +QByteArray PopplerSignatureInfo::signature() const +{ + return m_info.signature(); +} + +QList PopplerSignatureInfo::signedRangeBounds() const +{ + return m_info.signedRangeBounds(); +} + +bool PopplerSignatureInfo::signsTotalDocument() const +{ + return m_info.signsTotalDocument(); +} + +const Okular::CertificateInfo &PopplerSignatureInfo::certificateInfo() const +{ + return *m_certfiticateInfo; +} diff --git a/generators/poppler/pdfsignatureutils.h b/generators/poppler/pdfsignatureutils.h new file mode 100644 index 0000000..4da1219 --- /dev/null +++ b/generators/poppler/pdfsignatureutils.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_GENERATOR_PDF_SIGNATUREUTILS_H_ +#define _OKULAR_GENERATOR_PDF_SIGNATUREUTILS_H_ + +#include + +#include "core/signatureutils.h" + +#include + +class PopplerCertificateInfo : public Okular::CertificateInfo +{ +public: + PopplerCertificateInfo(const Poppler::CertificateInfo &info); + ~PopplerCertificateInfo() override; + + bool isNull() const override; + int version() const override; + QByteArray serialNumber() const override; + QString issuerInfo(EntityInfoKey) const override; + QString subjectInfo(EntityInfoKey) const override; + QDateTime validityStart() const override; + QDateTime validityEnd() const override; + KeyUsageExtensions keyUsageExtensions() const override; + QByteArray publicKey() const override; + PublicKeyType publicKeyType() const override; + int publicKeyStrength() const override; + bool isSelfSigned() const override; + QByteArray certificateData() const override; + +private: + Poppler::CertificateInfo m_info; +}; + +class PopplerSignatureInfo : public Okular::SignatureInfo +{ +public: + PopplerSignatureInfo(const Poppler::SignatureValidationInfo &info); + ~PopplerSignatureInfo() override; + + SignatureStatus signatureStatus() const override; + CertificateStatus certificateStatus() const override; + QString signerName() const override; + QString signerSubjectDN() const override; + QString location() const override; + QString reason() const override; + HashAlgorithm hashAlgorithm() const override; + QDateTime signingTime() const override; + QByteArray signature() const override; + QList signedRangeBounds() const override; + bool signsTotalDocument() const override; + const Okular::CertificateInfo &certificateInfo() const override; + +private: + Poppler::SignatureValidationInfo m_info; + Okular::CertificateInfo *m_certfiticateInfo; +}; + +#endif diff --git a/generators/poppler/popplerembeddedfile.h b/generators/poppler/popplerembeddedfile.h new file mode 100644 index 0000000..6fe3f90 --- /dev/null +++ b/generators/poppler/popplerembeddedfile.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2006-2008 by Albert Astals Cid * + * * + * 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 POPPLEREMBEDDEDFILE_H +#define POPPLEREMBEDDEDFILE_H + +#include + +#include + +class PDFEmbeddedFile : public Okular::EmbeddedFile +{ +public: + PDFEmbeddedFile(Poppler::EmbeddedFile *f) + : ef(f) + { + } + + QString name() const override + { + return ef->name(); + } + + QString description() const override + { + return ef->description(); + } + + QByteArray data() const override + { + return ef->data(); + } + + int size() const override + { + int s = ef->size(); + return s <= 0 ? -1 : s; + } + + QDateTime modificationDate() const override + { + return ef->modDate(); + } + + QDateTime creationDate() const override + { + return ef->createDate(); + } + +private: + Poppler::EmbeddedFile *ef; +}; + +#endif diff --git a/generators/spectre/16-apps-okular-gv.png b/generators/spectre/16-apps-okular-gv.png new file mode 100644 index 0000000000000000000000000000000000000000..bbba0e1f0f888bbc9b29545357760719c178aa4e GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJe}GSjYpQNKka_3Mo&W#;ulgSv zqB2Vn$Y(4G@(X5gcy=QV$g%fyaSW-r)!M_z#h}2$bouZ9^PH+?5+xfN*>|NWL@hfo z+xrF&lftSm4E$FFRe}UcwAmy}|8=H(^Zhi>H-cHZJ%CZ*R8gTY&?p8^S3j3^P6c}XzwtZ2UV36> z;S}<`z3H>zu7KO^5A%*0rd<^5kG*gVDwOC zuRisgQSKjuLv>}k^?@_|pVqTlnjhFFGw0XpyZzopr E0K5KWp8x;= literal 0 HcmV?d00001 diff --git a/generators/spectre/CMakeLists.txt b/generators/spectre/CMakeLists.txt new file mode 100644 index 0000000..5d6927d --- /dev/null +++ b/generators/spectre/CMakeLists.txt @@ -0,0 +1,36 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_ghostview") + +add_subdirectory( conf ) + +include_directories( + ${LIBSPECTRE_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${CMAKE_CURRENT_BINARY_DIR}/../.. +) + +########### next target ############### + +set(okularGenerator_ghostview_SRCS + generator_ghostview.cpp + rendererthread.cpp + spectre_debug.cpp +) + +ki18n_wrap_ui(okularGenerator_ghostview_SRCS + conf/gssettingswidget.ui +) + +kconfig_add_kcfg_files(okularGenerator_ghostview_SRCS conf/gssettings.kcfgc ) + + +okular_add_generator(okularGenerator_ghostview ${okularGenerator_ghostview_SRCS}) + +target_link_libraries(okularGenerator_ghostview okularcore ${LIBSPECTRE_LIBRARY} KF5::I18n Qt5::Xml) + +########### install files ############### + +install( PROGRAMS okularApplication_ghostview.desktop org.kde.mobile.okular_ghostview.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES okularGhostview.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +ecm_install_icons(ICONS 16-apps-okular-gv.png 32-apps-okular-gv.png DESTINATION ${KDE_INSTALL_DATADIR}/okular/icons) +install( FILES org.kde.okular-spectre.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/spectre/DESIGN b/generators/spectre/DESIGN new file mode 100644 index 0000000..31ddcfb --- /dev/null +++ b/generators/spectre/DESIGN @@ -0,0 +1,12 @@ +Quick Spectre Generator design explanation +-------------------------------------------- + +libgs has a limitation that there can only be a gs instance per process. + +To overcome that problem there is zero (when no ps document has been opened) +or one GSRendererThread thread running (when on or more ps documents are open +in the same okular process) + +As there is only one GSRendererThread for potentially N GSGenerator, the imageDone +signal from GSRendererThread also emits the request and the GSGenerator checks +if it is its request that was done or from another GSGenerator. diff --git a/generators/spectre/Messages.sh b/generators/spectre/Messages.sh new file mode 100644 index 0000000..ff2de97 --- /dev/null +++ b/generators/spectre/Messages.sh @@ -0,0 +1,4 @@ +#!/bin/sh +$EXTRACTRC $(find conf/ -name "*.ui" -o -name "*.kcfg") >> rc.cpp || exit 11 +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_ghostview.pot +rm -f rc.cpp diff --git a/generators/spectre/conf/CMakeLists.txt b/generators/spectre/conf/CMakeLists.txt new file mode 100644 index 0000000..b51035d --- /dev/null +++ b/generators/spectre/conf/CMakeLists.txt @@ -0,0 +1,3 @@ + +install(FILES gssettings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) + diff --git a/generators/spectre/conf/gssettings.kcfg b/generators/spectre/conf/gssettings.kcfg new file mode 100644 index 0000000..423492e --- /dev/null +++ b/generators/spectre/conf/gssettings.kcfg @@ -0,0 +1,16 @@ + + + + + + + Determines whether Ghostscript should be allowed to use platform fonts, if false only usage of fonts embedded in the document will be allowed. + true + + + + + diff --git a/generators/spectre/conf/gssettings.kcfgc b/generators/spectre/conf/gssettings.kcfgc new file mode 100644 index 0000000..7cfd0f3 --- /dev/null +++ b/generators/spectre/conf/gssettings.kcfgc @@ -0,0 +1,4 @@ +File=gssettings.kcfg +ClassName=GSSettings +Mutators=true +Singleton=true diff --git a/generators/spectre/conf/gssettingswidget.ui b/generators/spectre/conf/gssettingswidget.ui new file mode 100644 index 0000000..d6085da --- /dev/null +++ b/generators/spectre/conf/gssettingswidget.ui @@ -0,0 +1,61 @@ + + GSSettingsWidget + + + + 0 + 0 + 328 + 73 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + General Settings + + + + + + true + + + &Use platform fonts + + + + + + + + + + Qt::Vertical + + + + 10 + 5 + + + + + + + + + diff --git a/generators/spectre/generator_ghostview.cpp b/generators/spectre/generator_ghostview.cpp new file mode 100644 index 0000000..8e8e9de --- /dev/null +++ b/generators/spectre/generator_ghostview.cpp @@ -0,0 +1,293 @@ +/*************************************************************************** + * Copyright (C) 2007-2008 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "generator_ghostview.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "gssettings.h" +#include "ui_gssettingswidget.h" + +#include "rendererthread.h" +#include "spectre_debug.h" + +OKULAR_EXPORT_PLUGIN(GSGenerator, "libokularGenerator_ghostview.json") + +GSGenerator::GSGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) + , m_internalDocument(nullptr) + , m_request(nullptr) +{ + setFeature(PrintPostscript); + setFeature(PrintToFile); + + GSRendererThread *renderer = GSRendererThread::getCreateRenderer(); + if (!renderer->isRunning()) + renderer->start(); + connect(renderer, &GSRendererThread::imageDone, this, &GSGenerator::slotImageGenerated, Qt::QueuedConnection); +} + +GSGenerator::~GSGenerator() +{ +} + +bool GSGenerator::reparseConfig() +{ + bool changed = false; + if (m_internalDocument) { +#define SET_HINT(hintname, hintdefvalue, hintvar) \ + { \ + bool newhint = documentMetaData(hintname, hintdefvalue).toBool(); \ + if (newhint != cache_##hintvar) { \ + cache_##hintvar = newhint; \ + changed = true; \ + } \ + } + SET_HINT(GraphicsAntialiasMetaData, true, AAgfx) + SET_HINT(TextAntialiasMetaData, true, AAtext) +#undef SET_HINT + } + return changed; +} + +void GSGenerator::addPages(KConfigDialog *dlg) +{ + Ui_GSSettingsWidget gsw; + QWidget *w = new QWidget(dlg); + gsw.setupUi(w); + dlg->addPage(w, GSSettings::self(), i18n("Ghostscript"), QStringLiteral("okular-gv"), i18n("Ghostscript Backend Configuration")); +} + +bool GSGenerator::print(QPrinter &printer) +{ + bool result = false; + + // Create tempfile to write to + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + + // Get list of pages to print + QList pageList = Okular::FilePrinter::pageList(printer, spectre_document_get_n_pages(m_internalDocument), document()->currentPage() + 1, document()->bookmarkedPageList()); + + // Default to Postscript export, but if printing to PDF use that instead + SpectreExporterFormat exportFormat = SPECTRE_EXPORTER_FORMAT_PS; + if (printer.outputFileName().right(3) == QLatin1String("pdf")) { + exportFormat = SPECTRE_EXPORTER_FORMAT_PDF; + tf.setFileTemplate(QDir::tempPath() + QLatin1String("/okular_XXXXXX.pdf")); + } + + if (!tf.open()) + return false; + + SpectreExporter *exporter = spectre_exporter_new(m_internalDocument, exportFormat); + SpectreStatus exportStatus = spectre_exporter_begin(exporter, tf.fileName().toLatin1().constData()); + + int i = 0; + while (i < pageList.count() && exportStatus == SPECTRE_STATUS_SUCCESS) { + exportStatus = spectre_exporter_do_page(exporter, pageList.at(i) - 1); + i++; + } + + SpectreStatus endStatus = SPECTRE_STATUS_EXPORTER_ERROR; + if (exportStatus == SPECTRE_STATUS_SUCCESS) + endStatus = spectre_exporter_end(exporter); + + spectre_exporter_free(exporter); + + const QString fileName = tf.fileName(); + tf.close(); + + if (exportStatus == SPECTRE_STATUS_SUCCESS && endStatus == SPECTRE_STATUS_SUCCESS) { + tf.setAutoRemove(false); + int ret = Okular::FilePrinter::printFile(printer, fileName, document()->orientation(), Okular::FilePrinter::SystemDeletesFiles, Okular::FilePrinter::ApplicationSelectsPages, document()->bookmarkedPageRange()); + if (ret >= 0) + result = true; + } + + return result; +} + +bool GSGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + cache_AAtext = documentMetaData(TextAntialiasMetaData, true).toBool(); + cache_AAgfx = documentMetaData(GraphicsAntialiasMetaData, true).toBool(); + + m_internalDocument = spectre_document_new(); + spectre_document_load(m_internalDocument, QFile::encodeName(fileName).constData()); + const SpectreStatus loadStatus = spectre_document_status(m_internalDocument); + if (loadStatus != SPECTRE_STATUS_SUCCESS) { + qCDebug(OkularSpectreDebug) << "ERR:" << spectre_status_to_string(loadStatus); + spectre_document_free(m_internalDocument); + m_internalDocument = nullptr; + return false; + } + pagesVector.resize(spectre_document_get_n_pages(m_internalDocument)); + qCDebug(OkularSpectreDebug) << "Page count:" << pagesVector.count(); + return loadPages(pagesVector); +} + +bool GSGenerator::doCloseDocument() +{ + spectre_document_free(m_internalDocument); + m_internalDocument = nullptr; + + return true; +} + +void GSGenerator::slotImageGenerated(QImage *img, Okular::PixmapRequest *request) +{ + // This can happen as GSInterpreterCMD is a singleton and on creation signals all the slots + // of all the generators attached to it + if (request != m_request) + return; + + if (!request->page()->isBoundingBoxKnown()) + updatePageBoundingBox(request->page()->number(), Okular::Utils::imageBoundingBox(img)); + + m_request = nullptr; + QPixmap *pix = new QPixmap(QPixmap::fromImage(*img)); + delete img; + request->page()->setPixmap(request->observer(), pix); + signalPixmapRequestDone(request); +} + +bool GSGenerator::loadPages(QVector &pagesVector) +{ + for (uint i = 0; i < spectre_document_get_n_pages(m_internalDocument); i++) { + SpectrePage *page; + int width = 0, height = 0; + SpectreOrientation pageOrientation = SPECTRE_ORIENTATION_PORTRAIT; + page = spectre_document_get_page(m_internalDocument, i); + if (spectre_document_status(m_internalDocument)) { + qCDebug(OkularSpectreDebug) << "Error getting page" << i << spectre_status_to_string(spectre_document_status(m_internalDocument)); + } else { + spectre_page_get_size(page, &width, &height); + pageOrientation = spectre_page_get_orientation(page); + } + spectre_page_free(page); + if (pageOrientation % 2 == 1) + qSwap(width, height); + pagesVector[i] = new Okular::Page(i, width, height, orientation(pageOrientation)); + } + return pagesVector.count() > 0; +} + +void GSGenerator::generatePixmap(Okular::PixmapRequest *req) +{ + qCDebug(OkularSpectreDebug) << "receiving" << *req; + + SpectrePage *page = spectre_document_get_page(m_internalDocument, req->pageNumber()); + + GSRendererThread *renderer = GSRendererThread::getCreateRenderer(); + + GSRendererThreadRequest gsreq(this); + gsreq.spectrePage = page; + gsreq.platformFonts = GSSettings::platformFonts(); + int graphicsAA = 1; + int textAA = 1; + if (cache_AAgfx) + graphicsAA = 4; + if (cache_AAtext) + textAA = 4; + gsreq.textAAbits = textAA; + gsreq.graphicsAAbits = graphicsAA; + + gsreq.orientation = req->page()->orientation(); + if (req->page()->rotation() == Okular::Rotation90 || req->page()->rotation() == Okular::Rotation270) { + gsreq.magnify = qMax((double)req->height() / req->page()->width(), (double)req->width() / req->page()->height()); + } else { + gsreq.magnify = qMax((double)req->width() / req->page()->width(), (double)req->height() / req->page()->height()); + } + gsreq.request = req; + m_request = req; + renderer->addRequest(gsreq); +} + +bool GSGenerator::canGeneratePixmap() const +{ + return !m_request; +} + +Okular::DocumentInfo GSGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + if (keys.contains(Okular::DocumentInfo::Title)) + docInfo.set(Okular::DocumentInfo::Title, spectre_document_get_title(m_internalDocument)); + if (keys.contains(Okular::DocumentInfo::Author)) + docInfo.set(Okular::DocumentInfo::Author, spectre_document_get_for(m_internalDocument)); + if (keys.contains(Okular::DocumentInfo::Creator)) + docInfo.set(Okular::DocumentInfo::Creator, spectre_document_get_creator(m_internalDocument)); + if (keys.contains(Okular::DocumentInfo::CreationDate)) + docInfo.set(Okular::DocumentInfo::CreationDate, spectre_document_get_creation_date(m_internalDocument)); + if (keys.contains(Okular::DocumentInfo::CustomKeys)) + docInfo.set(QStringLiteral("dscversion"), spectre_document_get_format(m_internalDocument), i18n("Document version")); + + if (keys.contains(Okular::DocumentInfo::MimeType)) { + int languageLevel = spectre_document_get_language_level(m_internalDocument); + if (languageLevel > 0) + docInfo.set(QStringLiteral("langlevel"), QString::number(languageLevel), i18n("Language Level")); + if (spectre_document_is_eps(m_internalDocument)) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("image/x-eps")); + else + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("application/postscript")); + } + + if (keys.contains(Okular::DocumentInfo::Pages)) + docInfo.set(Okular::DocumentInfo::Pages, QString::number(spectre_document_get_n_pages(m_internalDocument))); + + return docInfo; +} + +Okular::Rotation GSGenerator::orientation(SpectreOrientation pageOrientation) const +{ + switch (pageOrientation) { + case SPECTRE_ORIENTATION_PORTRAIT: + return Okular::Rotation0; + case SPECTRE_ORIENTATION_LANDSCAPE: + return Okular::Rotation90; + case SPECTRE_ORIENTATION_REVERSE_PORTRAIT: + return Okular::Rotation180; + case SPECTRE_ORIENTATION_REVERSE_LANDSCAPE: + return Okular::Rotation270; + } + // get rid of warnings, should never happen + return Okular::Rotation0; +} + +QVariant GSGenerator::metaData(const QString &key, const QVariant &option) const +{ + Q_UNUSED(option) + if (key == QLatin1String("DocumentTitle")) { + const char *title = spectre_document_get_title(m_internalDocument); + if (title) + return QString::fromLatin1(title); + } + return QVariant(); +} + +#include "generator_ghostview.moc" diff --git a/generators/spectre/generator_ghostview.h b/generators/spectre/generator_ghostview.h new file mode 100644 index 0000000..f98b221 --- /dev/null +++ b/generators/spectre/generator_ghostview.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2007 by Albert Astals Cid * + * * + * 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_GENERATOR_GHOSTVIEW_H_ +#define _OKULAR_GENERATOR_GHOSTVIEW_H_ + +#include +#include + +#include + +class GSGenerator : public Okular::Generator, public Okular::ConfigInterface +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + Q_INTERFACES(Okular::ConfigInterface) + +public: + /** virtual methods to reimplement **/ + // load a document and fill up the pagesVector + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + // Document description and Table of contents + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override + { + return nullptr; + } + const Okular::DocumentFonts *generateDocumentFonts() + { + return nullptr; + } + + // page contents generation + bool canGeneratePixmap() const override; + void generatePixmap(Okular::PixmapRequest *request) override; + + QVariant metaData(const QString &key, const QVariant &option) const override; + + // print document using already configured kprinter + bool print(QPrinter & /*printer*/) override; + QString fileName() const; + + bool reparseConfig() override; + void addPages(KConfigDialog *dlg) override; + + /** constructor **/ + GSGenerator(QObject *parent, const QVariantList &args); + ~GSGenerator() override; + +public Q_SLOTS: + void slotImageGenerated(QImage *img, Okular::PixmapRequest *request); + +protected: + bool doCloseDocument() override; + +private: + bool loadPages(QVector &pagesVector); + Okular::Rotation orientation(SpectreOrientation orientation) const; + + // backendish stuff + SpectreDocument *m_internalDocument; + + Okular::PixmapRequest *m_request; + + bool cache_AAtext; + bool cache_AAgfx; +}; + +#endif diff --git a/generators/spectre/libokularGenerator_ghostview.json b/generators/spectre/libokularGenerator_ghostview.json new file mode 100644 index 0000000..5423c5b --- /dev/null +++ b/generators/spectre/libokularGenerator_ghostview.json @@ -0,0 +1,170 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "aacid@kde.org", + "Name": "Albert Astals Cid", + "Name[az]": "Albert Astals Cid", + "Name[ca@valencia]": "Albert Astals Cid", + "Name[ca]": "Albert Astals Cid", + "Name[cs]": "Albert Astals Cid", + "Name[da]": "Albert Astals Cid", + "Name[de]": "Albert Astals Cid", + "Name[el]": "Albert Astals Cid", + "Name[en_GB]": "Albert Astals Cid", + "Name[es]": "Albert Astals Cid", + "Name[et]": "Albert Astals Cid", + "Name[eu]": "Albert Astals Cid", + "Name[fi]": "Albert Astals Cid", + "Name[fr]": "Albert Astals Cid", + "Name[gl]": "Albert Astals Cid", + "Name[ia]": "Albert Astals Cid", + "Name[it]": "Albert Astals Cid", + "Name[ko]": "Albert Astals Cid", + "Name[lt]": "Albert Astals Cid", + "Name[nl]": "Albert Astals Cid", + "Name[nn]": "Albert Astals Cid", + "Name[pl]": "Albert Astals Cid", + "Name[pt]": "Albert Astals Cid", + "Name[pt_BR]": "Albert Astals Cid", + "Name[ru]": "Albert Astals Cid", + "Name[sk]": "Albert Astals Cid", + "Name[sl]": "Albert Astals Cid", + "Name[sr@ijekavian]": "Алберт Асталс Сид", + "Name[sr@ijekavianlatin]": "Albert Astals Sid", + "Name[sr@latin]": "Albert Astals Sid", + "Name[sr]": "Алберт Асталс Сид", + "Name[sv]": "Albert Astals Cid", + "Name[tr]": "Albert Astals Cid", + "Name[uk]": "Albert Astals Cid", + "Name[x-test]": "xxAlbert Astals Cidxx", + "Name[zh_CN]": "Albert Astals Cid", + "Name[zh_TW]": "Albert Astals Cid" + } + ], + "Copyright": "© 2007-2008 Albert Astals Cid", + "Copyright[az]": "© 2007-2008 Albert Astals Cid", + "Copyright[ca@valencia]": "© 2007-2008 Albert Astals Cid", + "Copyright[ca]": "© 2007-2008 Albert Astals Cid", + "Copyright[cs]": "© 2007-2008 Albert Astals Cid", + "Copyright[da]": "© 2007-2008 Albert Astals Cid", + "Copyright[de]": "© 2007-2008 Albert Astals Cid", + "Copyright[el]": "© 2007-2008 Albert Astals Cid", + "Copyright[en_GB]": "© 2007-2008 Albert Astals Cid", + "Copyright[es]": "© 2007-2008 Albert Astals Cid", + "Copyright[et]": "© 2007-2008: Albert Astals Cid", + "Copyright[eu]": "© 2007-2008 Albert Astals Cid", + "Copyright[fi]": "© 2007–2008 Albert Astals Cid", + "Copyright[fr]": "© 2007-2008 Albert Astals Cid", + "Copyright[gl]": "© 2007-2008 Albert Astals Cid", + "Copyright[ia]": "Albert Astals Cid", + "Copyright[it]": "© 2007-2008 Albert Astals Cid", + "Copyright[ko]": "© 2007-2008 Albert Astals Cid", + "Copyright[lt]": "© 2007-2008 Albert Astals Cid", + "Copyright[nl]": "© 2007-2008 Albert Astals Cid", + "Copyright[nn]": "© 2007–2008 Albert Astals Cid", + "Copyright[pl]": "© 2007-2008 Albert Astals Cid", + "Copyright[pt]": "© 2007-2008 Albert Astals Cid", + "Copyright[pt_BR]": "© 2007-2008 Albert Astals Cid", + "Copyright[ru]": "© Albert Astals Cid, 2007-2008", + "Copyright[sk]": "© 2007-2008 Albert Astals Cid", + "Copyright[sl]": "© 2007-2008 Albert Astals Cid", + "Copyright[sr@ijekavian]": "© 2007–2008, Алберт Асталс Сид", + "Copyright[sr@ijekavianlatin]": "© 2007–2008, Albert Astals Sid", + "Copyright[sr@latin]": "© 2007–2008, Albert Astals Sid", + "Copyright[sr]": "© 2007–2008, Алберт Асталс Сид", + "Copyright[sv]": "© 2007-2008 Albert Astals Cid", + "Copyright[tr]": "© 2007-2008 Albert Astals Cid", + "Copyright[uk]": "© Albert Astals Cid, 2007–2008", + "Copyright[x-test]": "xx© 2007-2008 Albert Astals Cidxx", + "Copyright[zh_CN]": "© 2007-2008 Albert Astals Cid", + "Copyright[zh_TW]": "© 2007-2008 Albert Astals Cid", + "Description": "A PostScript file renderer based on the Spectre library", + "Description[az]": "Spectre library'ə əsasında PostScript fayl tərtibatçısı", + "Description[ca@valencia]": "Un renderitzador per a fitxers PostScript basat en la biblioteca Spectre", + "Description[ca]": "Un renderitzador per a fitxers PostScript basat en la biblioteca Spectre", + "Description[cs]": "Vykreslovač souborů PostScript založený na knihovně Spectre.", + "Description[da]": "En gengiver til PostScript-filer baseret på Spectre-biblioteket", + "Description[de]": "Ein Renderer für PostScript-Dateien entwickelt aus der Spectre-Bibliothek", + "Description[el]": "Πρόγραμμα αποτύπωσης αρχείων PostScript με βάση τη βιβλιοθήκη Spectre", + "Description[en_GB]": "A PostScript file renderer based on the Spectre library", + "Description[es]": "Un visor de archivos PostScript basado en la biblioteca Spectre", + "Description[et]": "PostScript-faili renderdaja Spectre teegi alusel", + "Description[eu]": "PostScript fitxategien errendatzaile bat Spectre liburutegian oinarritua", + "Description[fi]": "Spectre-kirjastoon pohjautuva PostScript-tiedostohahmonnin", + "Description[fr]": "Système de rendu pour les fichiers « PostScript » utilisant la bibliothèque Spectre", + "Description[gl]": "Un renderizador de ficheiros PostScript baseado na biblioteca Spectre.", + "Description[ia]": "Un renditor de file Postscript basate sur bibliotheca Spectre", + "Description[it]": "Un visualizzatore di file PostScript basato sulla libreria Spectre", + "Description[ko]": "Spectre 라이브러리를 사용하는 포스트스크립트 파일 렌더러", + "Description[lt]": "PostScript failų atvaizdavimas pagrįstas Spectre biblioteka", + "Description[nl]": "Een renderer van PostScript bestanden gebaseerd op de bibliotheek Spectre", + "Description[nn]": "Ein gjengjevar for PostScript-filer, basert på Spectre-biblioteket", + "Description[pl]": "Wyświetlanie plików PostScript oparte o bibliotekę Spectre", + "Description[pt]": "Um visualzador de ficheiros PostScript com base na biblioteca Spectre", + "Description[pt_BR]": "Um interpretador de arquivos PostScript com base na biblioteca Spectre", + "Description[ru]": "Модуль поддержки формата PostScript на основе библиотеки Spectre", + "Description[sk]": "Renderovač PostScript súborov založený na knižnici Spectre", + "Description[sl]": "Izrisovalnik datotek PostScript, ki temelji na knjižnici Spectre", + "Description[sr@ijekavian]": "Рендерер постскрипт фајлова на основу библиотеке Спектер", + "Description[sr@ijekavianlatin]": "Renderer PostScript fajlova na osnovu biblioteke Spectre", + "Description[sr@latin]": "Renderer PostScript fajlova na osnovu biblioteke Spectre", + "Description[sr]": "Рендерер постскрипт фајлова на основу библиотеке Спектер", + "Description[sv]": "Ett återgivningsprogram för Postscript-filer baserat på Spectre-biblioteket", + "Description[tr]": "Spectre kitaplığına dayalı bir PostScript dosya oluşturucu", + "Description[uk]": "Обробник файлів PostScript на основі бібліотеки Spectre", + "Description[x-test]": "xxA PostScript file renderer based on the Spectre libraryxx", + "Description[zh_CN]": "基于 Spectre 库的 PostScript 文件渲染器", + "Description[zh_TW]": "基於 Spectre 函式庫的 PostScript 檔成像器", + "Id": "okular_ghostview", + "License": "GPL", + "MimeTypes": [ + "application/postscript", + "image/x-eps" + ], + "Name": "PS Backend", + "Name[az]": "PS modulu", + "Name[ca@valencia]": "Dorsal PS", + "Name[ca]": "Dorsal PS", + "Name[cs]": "Podpůrná vrstva PS", + "Name[da]": "PS-backend", + "Name[de]": "PS-Anzeigemodul", + "Name[el]": "Σύστημα υποστήριξης PS", + "Name[en_GB]": "PS Backend", + "Name[es]": "Motor para PS", + "Name[et]": "PS-i taustaprogramm", + "Name[eu]": "PS-ren bizkarraldekoa", + "Name[fi]": "PS-taustaosa", + "Name[fr]": "Moteur PS", + "Name[gl]": "Infraestrutura para PS", + "Name[ia]": "Retro-Administration de PS", + "Name[it]": "Backend PS", + "Name[ko]": "PS 백엔드", + "Name[lt]": "PS programinė sąsaja", + "Name[nl]": "PS-backend", + "Name[nn]": "PS-motor", + "Name[pl]": "Obsługa PS", + "Name[pt]": "Infra-Estrutura de PS", + "Name[pt_BR]": "Infraestrutura PS", + "Name[ru]": "Модуль поддержки формата PS", + "Name[sk]": "PS Backend", + "Name[sl]": "Zaledje za PS", + "Name[sr@ijekavian]": "Позадина за постскрипт", + "Name[sr@ijekavianlatin]": "Pozadina za PostScript", + "Name[sr@latin]": "Pozadina za PostScript", + "Name[sr]": "Позадина за постскрипт", + "Name[sv]": "PS-gränssnitt", + "Name[tr]": "PS Arka Ucu", + "Name[uk]": "Модуль PS", + "Name[x-test]": "xxPS Backendxx", + "Name[zh_CN]": "PS 后端", + "Name[zh_TW]": "PS 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1.7" + }, + "X-KDE-Priority": 2, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/spectre/okularApplication_ghostview.desktop b/generators/spectre/okularApplication_ghostview.desktop new file mode 100755 index 0000000..140f415 --- /dev/null +++ b/generators/spectre/okularApplication_ghostview.desktop @@ -0,0 +1,219 @@ +[Desktop Entry] +MimeType=application/postscript;image/x-eps;application/x-gzpostscript;application/x-bzpostscript;image/x-gzeps;image/x-bzeps; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +X-KDE-Keywords=PS, PostScript +X-KDE-Keywords[az]=PS, PostScript +X-KDE-Keywords[bg]=PS, PostScript +X-KDE-Keywords[bs]=PS, Postscript +X-KDE-Keywords[ca]=PS, PostScript +X-KDE-Keywords[ca@valencia]=PS, PostScript +X-KDE-Keywords[cs]=PS, PostScript +X-KDE-Keywords[da]=PS, Postscript +X-KDE-Keywords[de]=PS, PostScript +X-KDE-Keywords[el]=PS, PostScript +X-KDE-Keywords[en_GB]=PS, PostScript +X-KDE-Keywords[es]=PS, PostScript +X-KDE-Keywords[et]=PS, PostScript +X-KDE-Keywords[eu]=PS, PostScript +X-KDE-Keywords[fi]=PS, PostScript +X-KDE-Keywords[fr]=PS, PostScript +X-KDE-Keywords[gl]=PS, PostScript +X-KDE-Keywords[hu]=PS, PostScript +X-KDE-Keywords[ia]=PS, PostScript +X-KDE-Keywords[is]=PS, PostScript +X-KDE-Keywords[it]=PS, PostScript +X-KDE-Keywords[ja]=PS, PostScript, ポストスクリプト +X-KDE-Keywords[kk]=PS, PostScript +X-KDE-Keywords[ko]=PS, PostScript +X-KDE-Keywords[lt]=PS, PostScript +X-KDE-Keywords[mr]=PS, पोस्ट स्क्रिप्ट +X-KDE-Keywords[nb]=PS, PostScript +X-KDE-Keywords[nds]=PS, PostScript +X-KDE-Keywords[nl]=PS, PostScript +X-KDE-Keywords[nn]=PS, PostScript +X-KDE-Keywords[pa]=PS, ਪੋਸਟਸਕ੍ਰਿਪਟ +X-KDE-Keywords[pl]=PS, PostScript +X-KDE-Keywords[pt]=PS, PostScript +X-KDE-Keywords[pt_BR]=PS, PostScript +X-KDE-Keywords[ru]=PS, PostScript +X-KDE-Keywords[sk]=PS, PostScript +X-KDE-Keywords[sl]=PS, PostScript +X-KDE-Keywords[sr]=PS,PostScript,постскрипт,ПС +X-KDE-Keywords[sr@ijekavian]=PS,PostScript,постскрипт,ПС +X-KDE-Keywords[sr@ijekavianlatin]=PS,PostScript,PostScript,PS +X-KDE-Keywords[sr@latin]=PS,PostScript,PostScript,PS +X-KDE-Keywords[sv]=PS, Postscript +X-KDE-Keywords[tr]=PS, PostScript +X-KDE-Keywords[uk]=PS, PostScript +X-KDE-Keywords[x-test]=xxPSxx,xx PostScriptxx +X-KDE-Keywords[zh_CN]=PS, PostScript +X-KDE-Keywords[zh_TW]=PS, PostScript +NoDisplay=true diff --git a/generators/spectre/okularGhostview.desktop b/generators/spectre/okularGhostview.desktop new file mode 100644 index 0000000..09b7103 --- /dev/null +++ b/generators/spectre/okularGhostview.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +InitialPreference=6 +Type=Service +MimeType=application/postscript;image/x-eps;application/x-gzpostscript;application/x-bzpostscript;image/x-gzeps;image/x-bzeps; diff --git a/generators/spectre/org.kde.mobile.okular_ghostview.desktop b/generators/spectre/org.kde.mobile.okular_ghostview.desktop new file mode 100644 index 0000000..323bc84 --- /dev/null +++ b/generators/spectre/org.kde.mobile.okular_ghostview.desktop @@ -0,0 +1,210 @@ +[Desktop Entry] +MimeType=application/postscript;image/x-eps;application/x-gzpostscript;application/x-bzpostscript;image/x-gzeps;image/x-bzeps; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=PS, PostScript +X-KDE-Keywords[az]=PS, PostScript +X-KDE-Keywords[bg]=PS, PostScript +X-KDE-Keywords[bs]=PS, Postscript +X-KDE-Keywords[ca]=PS, PostScript +X-KDE-Keywords[ca@valencia]=PS, PostScript +X-KDE-Keywords[cs]=PS, PostScript +X-KDE-Keywords[da]=PS, Postscript +X-KDE-Keywords[de]=PS, PostScript +X-KDE-Keywords[el]=PS, PostScript +X-KDE-Keywords[en_GB]=PS, PostScript +X-KDE-Keywords[es]=PS, PostScript +X-KDE-Keywords[et]=PS, PostScript +X-KDE-Keywords[eu]=PS, PostScript +X-KDE-Keywords[fi]=PS, PostScript +X-KDE-Keywords[fr]=PS, PostScript +X-KDE-Keywords[gl]=PS, PostScript +X-KDE-Keywords[hu]=PS, PostScript +X-KDE-Keywords[ia]=PS, PostScript +X-KDE-Keywords[is]=PS, PostScript +X-KDE-Keywords[it]=PS, PostScript +X-KDE-Keywords[ja]=PS, PostScript, ポストスクリプト +X-KDE-Keywords[kk]=PS, PostScript +X-KDE-Keywords[ko]=PS, PostScript +X-KDE-Keywords[lt]=PS, PostScript +X-KDE-Keywords[mr]=PS, पोस्ट स्क्रिप्ट +X-KDE-Keywords[nb]=PS, PostScript +X-KDE-Keywords[nds]=PS, PostScript +X-KDE-Keywords[nl]=PS, PostScript +X-KDE-Keywords[nn]=PS, PostScript +X-KDE-Keywords[pa]=PS, ਪੋਸਟਸਕ੍ਰਿਪਟ +X-KDE-Keywords[pl]=PS, PostScript +X-KDE-Keywords[pt]=PS, PostScript +X-KDE-Keywords[pt_BR]=PS, PostScript +X-KDE-Keywords[ru]=PS, PostScript +X-KDE-Keywords[sk]=PS, PostScript +X-KDE-Keywords[sl]=PS, PostScript +X-KDE-Keywords[sr]=PS,PostScript,постскрипт,ПС +X-KDE-Keywords[sr@ijekavian]=PS,PostScript,постскрипт,ПС +X-KDE-Keywords[sr@ijekavianlatin]=PS,PostScript,PostScript,PS +X-KDE-Keywords[sr@latin]=PS,PostScript,PostScript,PS +X-KDE-Keywords[sv]=PS, Postscript +X-KDE-Keywords[tr]=PS, PostScript +X-KDE-Keywords[uk]=PS, PostScript +X-KDE-Keywords[x-test]=xxPSxx,xx PostScriptxx +X-KDE-Keywords[zh_CN]=PS, PostScript +X-KDE-Keywords[zh_TW]=PS, PostScript diff --git a/generators/spectre/org.kde.okular-spectre.metainfo.xml b/generators/spectre/org.kde.okular-spectre.metainfo.xml new file mode 100644 index 0000000..13440da --- /dev/null +++ b/generators/spectre/org.kde.okular-spectre.metainfo.xml @@ -0,0 +1,98 @@ + + + org.kde.okular-spectre + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + 포스트스크립트 + PostScript + പോസ്റ്റ്സ്ക്രിപ്റ്റ് + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + PostScript + Постскрипт + PostScript + Постскрипт + PostScript + Postscript + PostScript + PostScript + xxPostScriptxx + PostScript + PostScript + Adds support for reading PostScript documents + PostScript sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents PostScript + Afig la implementació per a llegir documents PostScript + Přidává podporu pro čtení dokumentů PostScript + Bietet Unterstützung zum Lesen von PostScript-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων PostScript + Adds support for reading PostScript documents + Permite la lectura de documentos PostScript + PostScript-dokumentide lugemise toetus + PostScript dokumentuak irakurtzeko euskarria gehitzen du + Lisää PostScript-tiedostojen lukutuen + Permet la lecture des documents PostScript + Engade a posibilidade de ler documentos PostScript + Adde supporto per leger documentos PostScript + Dukungan tambahan untuk pembacaan dokumen PostScript + Aggiunge il supporto per la lettura di documenti PostScript + 포스트스크립트 문서 읽기 지원 추가 + Prideda palaikymą PostScript dokumentų skaitymui + പോസ്റ്റ്സ്ക്രിപ്റ്റ് പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van PostScript-documenten toe + Legg til støtte for å lesa PostScript-dokument + Dodaje obsługę dokumentów PostScript + Adiciona o suporte para ler documentos em PostScript + Adiciona o suporte para leitura de documentos em PostScript + Поддержка чтения документов PostScript + Pridá podporu pre čítanie dokumentov PostScript + Doda podporo za branje dokumentov PostScript + Подршка за читање постскрипт докумената + Podrška za čitanje PostScript dokumenata + Подршка за читање постскрипт докумената + Podrška za čitanje PostScript dokumenata + Lägger till stöd för att läsa Postscript-dokument + PostScript belgelerini okuma desteği ekler + Додає підтримку читання документів PostScript + xxAdds support for reading PostScript documentsxx + 增加对 PostScript 文档的阅读支持 + 加入讀取 PostScript 文件的支援 + + application/postscript + image/x-eps + application/x-gzpostscript + application/x-bzpostscript + image/x-gzeps + image/x-bzepsapplication/pdf + + https://okular.kde.org + + + + + + + diff --git a/generators/spectre/rendererthread.cpp b/generators/spectre/rendererthread.cpp new file mode 100644 index 0000000..196433e --- /dev/null +++ b/generators/spectre/rendererthread.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2007 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "rendererthread.h" + +#include + +#include "spectre_debug.h" + +#include "core/generator.h" +#include "core/page.h" +#include "core/utils.h" + +GSRendererThread *GSRendererThread::theRenderer = nullptr; + +GSRendererThread *GSRendererThread::getCreateRenderer() +{ + if (!theRenderer) + theRenderer = new GSRendererThread(); + return theRenderer; +} + +GSRendererThread::GSRendererThread() +{ + m_renderContext = spectre_render_context_new(); +} + +GSRendererThread::~GSRendererThread() +{ + spectre_render_context_free(m_renderContext); +} + +void GSRendererThread::addRequest(const GSRendererThreadRequest &req) +{ + m_queueMutex.lock(); + m_queue.enqueue(req); + m_queueMutex.unlock(); + m_semaphore.release(); +} + +void GSRendererThread::run() +{ + while (true) { + m_semaphore.acquire(); + { + m_queueMutex.lock(); + GSRendererThreadRequest req = m_queue.dequeue(); + m_queueMutex.unlock(); + + spectre_render_context_set_scale(m_renderContext, req.magnify, req.magnify); + spectre_render_context_set_use_platform_fonts(m_renderContext, req.platformFonts); + spectre_render_context_set_antialias_bits(m_renderContext, req.graphicsAAbits, req.textAAbits); + // Do not use spectre_render_context_set_rotation makes some files not render correctly, e.g. bug210499.ps + // so we basically do the rendering without any rotation and then rotate to the orientation as needed + // spectre_render_context_set_rotation(m_renderContext, req.orientation); + + unsigned char *data = nullptr; + int row_length = 0; + int wantedWidth = req.request->width(); + int wantedHeight = req.request->height(); + + if (req.orientation % 2) + qSwap(wantedWidth, wantedHeight); + + spectre_page_render(req.spectrePage, m_renderContext, &data, &row_length); + + // Qt needs the missing alpha of QImage::Format_RGB32 to be 0xff + if (data && data[3] != 0xff) { + for (int i = 3; i < row_length * wantedHeight; i += 4) + data[i] = 0xff; + } + + QImage img; + if (row_length == wantedWidth * 4) { + img = QImage(data, wantedWidth, wantedHeight, QImage::Format_RGB32); + } else { + // In case this ends up beign very slow we can try with some memmove + QImage aux(data, row_length / 4, wantedHeight, QImage::Format_RGB32); + img = QImage(aux.copy(0, 0, wantedWidth, wantedHeight)); + } + + switch (req.orientation) { + case Okular::Rotation90: { + QTransform m; + m.rotate(90); + img = img.transformed(m); + break; + } + + case Okular::Rotation180: { + QTransform m; + m.rotate(180); + img = img.transformed(m); + break; + } + case Okular::Rotation270: { + QTransform m; + m.rotate(270); + img = img.transformed(m); + } + } + + QImage *image = new QImage(img.copy()); + free(data); + + if (image->width() != req.request->width() || image->height() != req.request->height()) { + qCWarning(OkularSpectreDebug).nospace() << "Generated image does not match wanted size: " + << "[" << image->width() << "x" << image->height() << "] vs requested " + << "[" << req.request->width() << "x" << req.request->height() << "]"; + QImage aux = image->scaled(wantedWidth, wantedHeight); + delete image; + image = new QImage(aux); + } + emit imageDone(image, req.request); + + spectre_page_free(req.spectrePage); + } + } +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/generators/spectre/rendererthread.h b/generators/spectre/rendererthread.h new file mode 100644 index 0000000..78f2101 --- /dev/null +++ b/generators/spectre/rendererthread.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2007 by Albert Astals Cid * + * * + * 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_GSRENDERERTHREAD_H_ +#define _OKULAR_GSRENDERERTHREAD_H_ + +#include +#include +#include +#include +#include + +#include + +class QImage; +class GSGenerator; + +namespace Okular +{ +class PixmapRequest; +} + +struct GSRendererThreadRequest { + GSRendererThreadRequest(GSGenerator *_owner) + : owner(_owner) + , request(nullptr) + , spectrePage(nullptr) + , textAAbits(1) + , graphicsAAbits(1) + , magnify(1.0) + , orientation(0) + , platformFonts(true) + { + } + + GSGenerator *owner; + Okular::PixmapRequest *request; + SpectrePage *spectrePage; + int textAAbits; + int graphicsAAbits; + double magnify; + int orientation; + bool platformFonts; +}; +Q_DECLARE_TYPEINFO(GSRendererThreadRequest, Q_MOVABLE_TYPE); + +class GSRendererThread : public QThread +{ + Q_OBJECT +public: + static GSRendererThread *getCreateRenderer(); + + ~GSRendererThread() override; + + void addRequest(const GSRendererThreadRequest &req); + +Q_SIGNALS: + void imageDone(QImage *image, Okular::PixmapRequest *request); + +private: + GSRendererThread(); + + QSemaphore m_semaphore; + + static GSRendererThread *theRenderer; + + void run() override; + + SpectreRenderContext *m_renderContext; + QQueue m_queue; + QMutex m_queueMutex; +}; + +#endif diff --git a/generators/spectre/spectre_debug.cpp b/generators/spectre/spectre_debug.cpp new file mode 100644 index 0000000..740a12c --- /dev/null +++ b/generators/spectre/spectre_debug.cpp @@ -0,0 +1,21 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "spectre_debug.h" +Q_LOGGING_CATEGORY(OkularSpectreDebug, "org.kde.okular.generators.spectre", QtWarningMsg) diff --git a/generators/spectre/spectre_debug.h b/generators/spectre/spectre_debug.h new file mode 100644 index 0000000..048d368 --- /dev/null +++ b/generators/spectre/spectre_debug.h @@ -0,0 +1,26 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SPECTRE_DEBUG_H +#define SPECTRE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(OkularSpectreDebug) + +#endif diff --git a/generators/tiff/CMakeLists.txt b/generators/tiff/CMakeLists.txt new file mode 100644 index 0000000..a73d853 --- /dev/null +++ b/generators/tiff/CMakeLists.txt @@ -0,0 +1,22 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_tiff") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${TIFF_INCLUDE_DIR} +) + + +########### next target ############### + +set(okularGenerator_tiff_SRCS + generator_tiff.cpp +) + +okular_add_generator(okularGenerator_tiff ${okularGenerator_tiff_SRCS}) +target_link_libraries(okularGenerator_tiff okularcore ${TIFF_LIBRARIES} KF5::I18n) + +########### install files ############### +install( FILES okularTiff.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_tiff.desktop org.kde.mobile.okular_tiff.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-tiff.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/tiff/Messages.sh b/generators/tiff/Messages.sh new file mode 100644 index 0000000..b20a143 --- /dev/null +++ b/generators/tiff/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_tiff.pot diff --git a/generators/tiff/generator_tiff.cpp b/generators/tiff/generator_tiff.cpp new file mode 100644 index 0000000..79eea1e --- /dev/null +++ b/generators/tiff/generator_tiff.cpp @@ -0,0 +1,410 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "generator_tiff.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define TiffDebug 4714 + +tsize_t okular_tiffReadProc(thandle_t handle, tdata_t buf, tsize_t size) +{ + QIODevice *device = static_cast(handle); + return device->isReadable() ? device->read(static_cast(buf), size) : -1; +} + +tsize_t okular_tiffWriteProc(thandle_t handle, tdata_t buf, tsize_t size) +{ + QIODevice *device = static_cast(handle); + return device->write(static_cast(buf), size); +} + +toff_t okular_tiffSeekProc(thandle_t handle, toff_t offset, int whence) +{ + QIODevice *device = static_cast(handle); + switch (whence) { + case SEEK_SET: + device->seek(offset); + break; + case SEEK_CUR: + device->seek(device->pos() + offset); + break; + case SEEK_END: + device->seek(device->size() + offset); + break; + } + + return device->pos(); +} + +int okular_tiffCloseProc(thandle_t handle) +{ + Q_UNUSED(handle) + return 0; +} + +toff_t okular_tiffSizeProc(thandle_t handle) +{ + QIODevice *device = static_cast(handle); + return device->size(); +} + +int okular_tiffMapProc(thandle_t, tdata_t *, toff_t *) +{ + return 0; +} + +void okular_tiffUnmapProc(thandle_t, tdata_t, toff_t) +{ +} + +class TIFFGenerator::Private +{ +public: + Private() + : tiff(nullptr) + , dev(nullptr) + { + } + + TIFF *tiff; + QByteArray data; + QIODevice *dev; +}; + +static QDateTime convertTIFFDateTime(const char *tiffdate) +{ + if (!tiffdate) + return QDateTime(); + + return QDateTime::fromString(QString::fromLatin1(tiffdate), QStringLiteral("yyyy:MM:dd HH:mm:ss")); +} + +static void adaptSizeToResolution(TIFF *tiff, ttag_t whichres, double dpi, uint32 *size) +{ + float resvalue = 1.0; + uint16 resunit = 0; + if (!TIFFGetField(tiff, whichres, &resvalue) || !TIFFGetFieldDefaulted(tiff, TIFFTAG_RESOLUTIONUNIT, &resunit)) + return; + + float newsize = *size / resvalue; + switch (resunit) { + case RESUNIT_INCH: + *size = (uint32)(newsize * dpi); + break; + case RESUNIT_CENTIMETER: + *size = (uint32)(newsize * 10.0 / 25.4 * dpi); + break; + case RESUNIT_NONE: + break; + } +} + +static Okular::Rotation readTiffRotation(TIFF *tiff) +{ + uint32 tiffOrientation = 0; + + if (!TIFFGetField(tiff, TIFFTAG_ORIENTATION, &tiffOrientation)) + return Okular::Rotation0; + + Okular::Rotation ret = Okular::Rotation0; + switch (tiffOrientation) { + case ORIENTATION_TOPLEFT: + case ORIENTATION_TOPRIGHT: + ret = Okular::Rotation0; + break; + case ORIENTATION_BOTRIGHT: + case ORIENTATION_BOTLEFT: + ret = Okular::Rotation180; + break; + case ORIENTATION_LEFTTOP: + case ORIENTATION_LEFTBOT: + ret = Okular::Rotation270; + break; + case ORIENTATION_RIGHTTOP: + case ORIENTATION_RIGHTBOT: + ret = Okular::Rotation90; + break; + } + + return ret; +} + +OKULAR_EXPORT_PLUGIN(TIFFGenerator, "libokularGenerator_tiff.json") + +TIFFGenerator::TIFFGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) + , d(new Private) +{ + setFeature(Threaded); + setFeature(PrintNative); + setFeature(PrintToFile); + setFeature(ReadRawData); +} + +TIFFGenerator::~TIFFGenerator() +{ + if (d->tiff) { + TIFFClose(d->tiff); + d->tiff = nullptr; + } + + delete d; +} + +bool TIFFGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + QFile *qfile = new QFile(fileName); + qfile->open(QIODevice::ReadOnly); + d->dev = qfile; + d->data = QFile::encodeName(QFileInfo(*qfile).fileName()); + return loadTiff(pagesVector, d->data.constData()); +} + +bool TIFFGenerator::loadDocumentFromData(const QByteArray &fileData, QVector &pagesVector) +{ + d->data = fileData; + QBuffer *qbuffer = new QBuffer(&d->data); + qbuffer->open(QIODevice::ReadOnly); + d->dev = qbuffer; + return loadTiff(pagesVector, ""); +} + +bool TIFFGenerator::loadTiff(QVector &pagesVector, const char *name) +{ + d->tiff = TIFFClientOpen(name, "r", d->dev, okular_tiffReadProc, okular_tiffWriteProc, okular_tiffSeekProc, okular_tiffCloseProc, okular_tiffSizeProc, okular_tiffMapProc, okular_tiffUnmapProc); + if (!d->tiff) { + delete d->dev; + d->dev = nullptr; + d->data.clear(); + return false; + } + + loadPages(pagesVector); + + return true; +} + +bool TIFFGenerator::doCloseDocument() +{ + // closing the old document + if (d->tiff) { + TIFFClose(d->tiff); + d->tiff = nullptr; + delete d->dev; + d->dev = nullptr; + d->data.clear(); + m_pageMapping.clear(); + } + + return true; +} + +QImage TIFFGenerator::image(Okular::PixmapRequest *request) +{ + bool generated = false; + QImage img; + + if (TIFFSetDirectory(d->tiff, mapPage(request->page()->number()))) { + int rotation = request->page()->rotation(); + uint32 width = 1; + uint32 height = 1; + uint32 orientation = 0; + TIFFGetField(d->tiff, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(d->tiff, TIFFTAG_IMAGELENGTH, &height); + + if (!TIFFGetField(d->tiff, TIFFTAG_ORIENTATION, &orientation)) + orientation = ORIENTATION_TOPLEFT; + + QImage image(width, height, QImage::Format_RGB32); + uint32 *data = reinterpret_cast(image.bits()); + + // read data + if (TIFFReadRGBAImageOriented(d->tiff, width, height, data, orientation) != 0) { + // an image read by ReadRGBAImage is ABGR, we need ARGB, so swap red and blue + uint32 size = width * height; + for (uint32 i = 0; i < size; ++i) { + uint32 red = (data[i] & 0x00FF0000) >> 16; + uint32 blue = (data[i] & 0x000000FF) << 16; + data[i] = (data[i] & 0xFF00FF00) + red + blue; + } + + int reqwidth = request->width(); + int reqheight = request->height(); + if (rotation % 2 == 1) + qSwap(reqwidth, reqheight); + img = image.scaled(reqwidth, reqheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + generated = true; + } + } + + if (!generated) { + img = QImage(request->width(), request->height(), QImage::Format_RGB32); + img.fill(qRgb(255, 255, 255)); + } + + return img; +} + +Okular::DocumentInfo TIFFGenerator::generateDocumentInfo(const QSet &keys) const +{ + Okular::DocumentInfo docInfo; + if (d->tiff) { + if (keys.contains(Okular::DocumentInfo::MimeType)) + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("image/tiff")); + + if (keys.contains(Okular::DocumentInfo::Description)) { + char *buffer = nullptr; + TIFFGetField(d->tiff, TIFFTAG_IMAGEDESCRIPTION, &buffer); + docInfo.set(Okular::DocumentInfo::Description, buffer ? QString::fromLatin1(buffer) : QString()); + } + + if (keys.contains(Okular::DocumentInfo::Producer)) { + char *buffer = nullptr; + TIFFGetField(d->tiff, TIFFTAG_SOFTWARE, &buffer); + docInfo.set(Okular::DocumentInfo::Producer, buffer ? QString::fromLatin1(buffer) : QString()); + } + + if (keys.contains(Okular::DocumentInfo::Copyright)) { + char *buffer = nullptr; + TIFFGetField(d->tiff, TIFFTAG_COPYRIGHT, &buffer); + docInfo.set(Okular::DocumentInfo::Copyright, buffer ? QString::fromLatin1(buffer) : QString()); + } + + if (keys.contains(Okular::DocumentInfo::Author)) { + char *buffer = nullptr; + TIFFGetField(d->tiff, TIFFTAG_ARTIST, &buffer); + docInfo.set(Okular::DocumentInfo::Author, buffer ? QString::fromLatin1(buffer) : QString()); + } + + if (keys.contains(Okular::DocumentInfo::CreationDate)) { + char *buffer = nullptr; + TIFFGetField(d->tiff, TIFFTAG_DATETIME, &buffer); + QDateTime date = convertTIFFDateTime(buffer); + docInfo.set(Okular::DocumentInfo::CreationDate, date.isValid() ? QLocale().toString(date, QLocale::LongFormat) : QString()); + } + } + + return docInfo; +} + +void TIFFGenerator::loadPages(QVector &pagesVector) +{ + if (!d->tiff) + return; + + tdir_t dirs = TIFFNumberOfDirectories(d->tiff); + pagesVector.resize(dirs); + tdir_t realdirs = 0; + + uint32 width = 0; + uint32 height = 0; + + const QSizeF dpi = Okular::Utils::realDpi(nullptr); + for (tdir_t i = 0; i < dirs; ++i) { + if (!TIFFSetDirectory(d->tiff, i)) + continue; + + if (TIFFGetField(d->tiff, TIFFTAG_IMAGEWIDTH, &width) != 1 || TIFFGetField(d->tiff, TIFFTAG_IMAGELENGTH, &height) != 1) + continue; + + adaptSizeToResolution(d->tiff, TIFFTAG_XRESOLUTION, dpi.width(), &width); + adaptSizeToResolution(d->tiff, TIFFTAG_YRESOLUTION, dpi.height(), &height); + + Okular::Page *page = new Okular::Page(realdirs, width, height, readTiffRotation(d->tiff)); + pagesVector[realdirs] = page; + + m_pageMapping[realdirs] = i; + + ++realdirs; + } + + pagesVector.resize(realdirs); +} + +bool TIFFGenerator::print(QPrinter &printer) +{ + uint32 width = 0; + uint32 height = 0; + + QPainter p(&printer); + + QList pageList = Okular::FilePrinter::pageList(printer, document()->pages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + + for (int i = 0; i < pageList.count(); ++i) { + if (!TIFFSetDirectory(d->tiff, mapPage(pageList[i] - 1))) + continue; + + if (TIFFGetField(d->tiff, TIFFTAG_IMAGEWIDTH, &width) != 1 || TIFFGetField(d->tiff, TIFFTAG_IMAGELENGTH, &height) != 1) + continue; + + QImage image(width, height, QImage::Format_RGB32); + uint32 *data = reinterpret_cast(image.bits()); + + // read data + if (TIFFReadRGBAImageOriented(d->tiff, width, height, data, ORIENTATION_TOPLEFT) != 0) { + // an image read by ReadRGBAImage is ABGR, we need ARGB, so swap red and blue + uint32 size = width * height; + for (uint32 j = 0; j < size; ++j) { + uint32 red = (data[j] & 0x00FF0000) >> 16; + uint32 blue = (data[j] & 0x000000FF) << 16; + data[j] = (data[j] & 0xFF00FF00) + red + blue; + } + } + + if (i != 0) + printer.newPage(); + + QSize targetSize = printer.pageRect().size(); + + if ((image.width() < targetSize.width()) && (image.height() < targetSize.height())) { + // draw small images at 100% (don't scale up) + p.drawImage(0, 0, image); + } else { + // fit to page + p.drawImage(0, 0, image.scaled(targetSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } + } + + return true; +} + +int TIFFGenerator::mapPage(int page) const +{ + QHash::const_iterator it = m_pageMapping.find(page); + if (it == m_pageMapping.end()) { + qCWarning(OkularTiffDebug) << "Requesting unmapped page" << page << ":" << m_pageMapping; + return -1; + } + return it.value(); +} + +Q_LOGGING_CATEGORY(OkularTiffDebug, "org.kde.okular.generators.tiff", QtWarningMsg) + +#include "generator_tiff.moc" diff --git a/generators/tiff/generator_tiff.h b/generators/tiff/generator_tiff.h new file mode 100644 index 0000000..cc4d8df --- /dev/null +++ b/generators/tiff/generator_tiff.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 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_GENERATOR_TIFF_H_ +#define _OKULAR_GENERATOR_TIFF_H_ + +#include + +#include +#include + +class TIFFGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + TIFFGenerator(QObject *parent, const QVariantList &args); + ~TIFFGenerator() override; + + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + bool loadDocumentFromData(const QByteArray &fileData, QVector &pagesVector) override; + + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + + bool print(QPrinter &printer) override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + +private: + class Private; + Private *const d; + + bool loadTiff(QVector &pagesVector, const char *name); + void loadPages(QVector &pagesVector); + int mapPage(int page) const; + + QHash m_pageMapping; +}; + +Q_DECLARE_LOGGING_CATEGORY(OkularTiffDebug) + +#endif diff --git a/generators/tiff/libokularGenerator_tiff.json b/generators/tiff/libokularGenerator_tiff.json new file mode 100644 index 0000000..455bd54 --- /dev/null +++ b/generators/tiff/libokularGenerator_tiff.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "pino@kde.org", + "Name": "Pino Toscano", + "Name[az]": "Pino Toscano", + "Name[ca@valencia]": "Pino Toscano", + "Name[ca]": "Pino Toscano", + "Name[cs]": "Pino Toscano", + "Name[da]": "Pino Toscano", + "Name[de]": "Pino Toscano", + "Name[el]": "Pino Toscano", + "Name[en_GB]": "Pino Toscano", + "Name[es]": "Pino Toscano", + "Name[et]": "Pino Toscano", + "Name[eu]": "Pino Toscano", + "Name[fi]": "Pino Toscano", + "Name[fr]": "Pino Toscano", + "Name[gl]": "Pino Toscano", + "Name[ia]": "Pino Toscano", + "Name[it]": "Pino Toscano", + "Name[ko]": "Pino Toscano", + "Name[lt]": "Pino Toscano", + "Name[nl]": "Pino Toscano", + "Name[nn]": "Pino Toscano", + "Name[pl]": "Pino Toscano", + "Name[pt]": "Pino Toscano", + "Name[pt_BR]": "Pino Toscano", + "Name[ru]": "Pino Toscano", + "Name[sk]": "Pino Toscano", + "Name[sl]": "Pino Toscano", + "Name[sr@ijekavian]": "Пино Тоскано", + "Name[sr@ijekavianlatin]": "Pino Toskano", + "Name[sr@latin]": "Pino Toskano", + "Name[sr]": "Пино Тоскано", + "Name[sv]": "Pino Toscano", + "Name[tr]": "Pino Toscano", + "Name[uk]": "Pino Toscano", + "Name[x-test]": "xxPino Toscanoxx", + "Name[zh_CN]": "Pino Toscano", + "Name[zh_TW]": "Pino Toscano" + } + ], + "Copyright": "© 2006-2008 Pino Toscano", + "Copyright[az]": "© 2006-2008 Pino Toscano", + "Copyright[ca@valencia]": "© 2006-2008 Pino Toscano", + "Copyright[ca]": "© 2006-2008 Pino Toscano", + "Copyright[cs]": "© 2006-2008 Pino Toscano", + "Copyright[da]": "© 2006-2008 Pino Toscano", + "Copyright[de]": "© 2006-2008 Pino Toscano", + "Copyright[el]": "© 2006-2008 Pino Toscano", + "Copyright[en_GB]": "© 2006-2008 Pino Toscano", + "Copyright[es]": "© 2006-2008 Pino Toscano", + "Copyright[et]": "© 2006-2008: Pino Toscano", + "Copyright[eu]": "© 2006-2008 Pino Toscano", + "Copyright[fi]": "© 2006–2008 Pino Toscano", + "Copyright[fr]": "© 2006-2008 Pino Toscano", + "Copyright[gl]": "© 2006-2008 Pino Toscano", + "Copyright[ia]": "© 2006-2008 Pino Toscano", + "Copyright[it]": "© 2006-2008 Pino Toscano", + "Copyright[ko]": "© 2006-2008 Pino Toscano", + "Copyright[lt]": "© 2006-2008 Pino Toscano", + "Copyright[nl]": "© 2006-2008 Pino Toscano", + "Copyright[nn]": "© 2006–2008 Pino Toscano", + "Copyright[pl]": "© 2006-2008 Pino Toscano", + "Copyright[pt]": "© 2006-2008 Pino Toscano", + "Copyright[pt_BR]": "© 2006-2008 Pino Toscano", + "Copyright[ru]": "© Pino Toscano, 2006-2008", + "Copyright[sk]": "© 2006-2008 Pino Toscano", + "Copyright[sl]": "© 2006-2008 Pino Toscano", + "Copyright[sr@ijekavian]": "© 2006–2008, Пино Тоскано", + "Copyright[sr@ijekavianlatin]": "© 2006–2008, Pino Toskano", + "Copyright[sr@latin]": "© 2006–2008, Pino Toskano", + "Copyright[sr]": "© 2006–2008, Пино Тоскано", + "Copyright[sv]": "© 2006-2008 Pino Toscano", + "Copyright[tr]": "© 2006-2008 Pino Toscano", + "Copyright[uk]": "© Pino Toscano, 2006–2008", + "Copyright[x-test]": "xx© 2006-2008 Pino Toscanoxx", + "Copyright[zh_CN]": "© 2006-2008 Pino Toscano", + "Copyright[zh_TW]": "© 2006-2008 Pino Toscano", + "Description": "A TIFF backend", + "Description[az]": "TİFF modulu", + "Description[ca@valencia]": "Un dorsal per al TIFF", + "Description[ca]": "Un dorsal per al TIFF", + "Description[cs]": "Podpůrná vrstva pro TIFF", + "Description[da]": "En TIFF-backend", + "Description[de]": "Ein Anzeigemodul für TIFF", + "Description[el]": "Σύστημα υποστήριξης TIFF", + "Description[en_GB]": "A TIFF backend", + "Description[es]": "Un motor para TIFF", + "Description[et]": "TIFF-i taustaprogramm", + "Description[eu]": "TIFFen bizkarraldeko bat", + "Description[fi]": "TIFF-taustaosa", + "Description[fr]": "Un moteur TIFF", + "Description[gl]": "Unha infraestrutura para TIFF", + "Description[ia]": "Un retro-administration de TIFF", + "Description[it]": "Un backend per TIFF", + "Description[ko]": "TIFF 백엔드", + "Description[lt]": "TIFF programinė sąsaja", + "Description[nl]": "Een TIFF-backend", + "Description[nn]": "Ein TIFF-motor", + "Description[pl]": "Obsługa formatu TIFF", + "Description[pt]": "Uma infra-estrutura de TIFF", + "Description[pt_BR]": "Uma infraestrutura de imagens TIFF", + "Description[ru]": "Модуль поддержки формата TIFF", + "Description[sk]": "TIFF backend", + "Description[sl]": "Zaledje za TIFF", + "Description[sr@ijekavian]": "Позадина за ТИФФ", + "Description[sr@ijekavianlatin]": "Pozadina za TIFF", + "Description[sr@latin]": "Pozadina za TIFF", + "Description[sr]": "Позадина за ТИФФ", + "Description[sv]": "Ett TIFF-gränssnitt", + "Description[tr]": "Bir TIFF arka ucu", + "Description[uk]": "Програма для TIFF", + "Description[x-test]": "xxA TIFF backendxx", + "Description[zh_CN]": "TIFF 后端", + "Description[zh_TW]": "TIFF 後端介面", + "Id": "okular_tiff", + "License": "GPL", + "MimeTypes": [ + "image/tiff" + ], + "Name": "TIFF Backend", + "Name[az]": "TİFF modulu", + "Name[ca@valencia]": "Dorsal TIFF", + "Name[ca]": "Dorsal TIFF", + "Name[cs]": "Podpůrná vrstva pro TIFF", + "Name[da]": "TIFF-backend", + "Name[de]": "Anzeigemodul für TIFF", + "Name[el]": "Σύστημα υποστήριξης TIFF", + "Name[en_GB]": "TIFF Backend", + "Name[es]": "Motor para TIFF", + "Name[et]": "TIFF-i taustaprogramm", + "Name[eu]": "TIFFen bizkarraldekoa", + "Name[fi]": "TIFF-taustaosa", + "Name[fr]": "Moteur TIFF", + "Name[gl]": "Infraestrutura para TIFF", + "Name[ia]": "Retro-Administration de TIFF", + "Name[it]": "Backend TIFF", + "Name[ko]": "TIFF 백엔드", + "Name[lt]": "TIFF programinė sąsaja", + "Name[nl]": "TIFF-backend", + "Name[nn]": "TIFF-motor", + "Name[pl]": "Obsługa TIFF", + "Name[pt]": "Infra-Estrutura de TIFF", + "Name[pt_BR]": "Infraestrutura TIFF", + "Name[ru]": "Модуль поддержки формата TIFF", + "Name[sk]": "TIFF Backend", + "Name[sl]": "Zaledje za TIFF", + "Name[sr@ijekavian]": "Позадина за ТИФФ", + "Name[sr@ijekavianlatin]": "Pozadina za TIFF", + "Name[sr@latin]": "Pozadina za TIFF", + "Name[sr]": "Позадина за ТИФФ", + "Name[sv]": "TIFF-gränssnitt", + "Name[tr]": "TIFF Arka Ucu", + "Name[uk]": "Модуль TIFF", + "Name[x-test]": "xxTIFF Backendxx", + "Name[zh_CN]": "TIFF 后端", + "Name[zh_TW]": "TIFF 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.2.4" + }, + "X-KDE-Priority": 4, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/tiff/okularApplication_tiff.desktop b/generators/tiff/okularApplication_tiff.desktop new file mode 100755 index 0000000..b07ff92 --- /dev/null +++ b/generators/tiff/okularApplication_tiff.desktop @@ -0,0 +1,172 @@ +[Desktop Entry] +MimeType=image/tiff; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=1 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true diff --git a/generators/tiff/okularTiff.desktop b/generators/tiff/okularTiff.desktop new file mode 100644 index 0000000..d218eb7 --- /dev/null +++ b/generators/tiff/okularTiff.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=image/tiff; diff --git a/generators/tiff/org.kde.mobile.okular_tiff.desktop b/generators/tiff/org.kde.mobile.okular_tiff.desktop new file mode 100644 index 0000000..d7de589 --- /dev/null +++ b/generators/tiff/org.kde.mobile.okular_tiff.desktop @@ -0,0 +1,163 @@ +[Desktop Entry] +MimeType=image/tiff; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true diff --git a/generators/tiff/org.kde.okular-tiff.metainfo.xml b/generators/tiff/org.kde.okular-tiff.metainfo.xml new file mode 100644 index 0000000..95c85c4 --- /dev/null +++ b/generators/tiff/org.kde.okular-tiff.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-tiff + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Tiff + Tiff + TIFF + TIFF + Tiff + Tiff + Tiff + Tiff + Tiff + TIFF + Tiff + TIFF + Tiff + Tiff + TIFF + Tiff + TIFF + Tiff + ടിഫ് + Tiff + TIFF + TIFF + TIFF + TIFF + TIFF + Tiff + Tiff + ТИФФ + TIFF + ТИФФ + TIFF + TIFF + Tiff + Tiff + xxTiffxx + TIFF + Tiff + Adds support for reading Tiff documents + Tiff sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents TIFF + Afig la implementació per a llegir documents TIFF + Přidává podporu pro čtení dokumentů Tiff + Bietet Unterstützung zum Lesen von TIFF-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων Tiff + Adds support for reading Tiff documents + Permite la lectura de documentos Tiff + TIFF-dokumentide lugemise toetus + Tiff dokumentuak irakurtzeko euskarria gehitzen du + Lisää TIFF-kuvatiedostojen lukutuen + Permet la lecture des documents Tiff + Engade a posibilidade de ler documentos Tiff + Adde supporto per leger documentos Tiff + Aggiunge il supporto per la lettura di documenti Tiff + TIFF 문서 읽기 지원 추가 + Prideda palaikymą Tiff dokumentų skaitymui + ടിഫ് പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van Tiff-documenten toe + Legg til støtte for å lesa TIFF-dokument + Dodaje obsługę formatu TIFF + Adiciona o suporte para ler documentos em TIFF + Adiciona o suporte para leitura de documentos em TIFF + Поддержка чтения документов TIFF + Pridá podporu pre čítanie Tiff dokumentov + Doda podporo za branje dokumentov Tiff + Подршка за читање ТИФФ докумената + Podrška za čitanje TIFF dokumenata + Подршка за читање ТИФФ докумената + Podrška za čitanje TIFF dokumenata + Lägger till stöd för att läsa TIFF-dokument + Tiff belgelerini okuma desteği ekler + Додає підтримку читання документів TIFF + xxAdds support for reading Tiff documentsxx + 增加对 TIFF 文档的阅读支持 + 加入讀取 Tiff 文件的支援 + + image/tiff + + https://okular.kde.org + + + + + + + diff --git a/generators/txt/CMakeLists.txt b/generators/txt/CMakeLists.txt new file mode 100644 index 0000000..709771d --- /dev/null +++ b/generators/txt/CMakeLists.txt @@ -0,0 +1,24 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_txt") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + +########### next target ############### + +set(okularGenerator_txt_SRCS + generator_txt.cpp + converter.cpp + document.cpp +) + + +okular_add_generator(okularGenerator_txt ${okularGenerator_txt_SRCS}) + +target_link_libraries(okularGenerator_txt okularcore Qt5::Core KF5::I18n) + +########### install files ############### +install( FILES okularTxt.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_txt.desktop org.kde.mobile.okular_txt.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-txt.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/txt/Messages.sh b/generators/txt/Messages.sh new file mode 100644 index 0000000..95c4e1c --- /dev/null +++ b/generators/txt/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_txt.pot diff --git a/generators/txt/converter.cpp b/generators/txt/converter.cpp new file mode 100644 index 0000000..18998df --- /dev/null +++ b/generators/txt/converter.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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. * + ***************************************************************************/ + +#include "converter.h" + +#include + +#include "document.h" + +using namespace Txt; + +Converter::Converter() +{ +} + +Converter::~Converter() +{ +} + +QTextDocument *Converter::convert(const QString &fileName) +{ + Document *textDocument = new Document(fileName); + + textDocument->setPageSize(QSizeF(600, 800)); + + QTextFrameFormat frameFormat; + frameFormat.setMargin(20); + + QTextFrame *rootFrame = textDocument->rootFrame(); + rootFrame->setFrameFormat(frameFormat); + + emit addMetaData(Okular::DocumentInfo::MimeType, QStringLiteral("text/plain")); + + return textDocument; +} diff --git a/generators/txt/converter.h b/generators/txt/converter.h new file mode 100644 index 0000000..ae77b6f --- /dev/null +++ b/generators/txt/converter.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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 TXT_CONVERTER_H +#define TXT_CONVERTER_H + +#include +#include + +namespace Txt +{ +class Converter : public Okular::TextDocumentConverter +{ + Q_OBJECT + +public: + Converter(); + ~Converter() override; + + QTextDocument *convert(const QString &fileName) override; +}; +} + +#endif diff --git a/generators/txt/debug_txt.h b/generators/txt/debug_txt.h new file mode 100644 index 0000000..f0f21ca --- /dev/null +++ b/generators/txt/debug_txt.h @@ -0,0 +1,18 @@ +/*************************************************************************** + * Copyright (C) 2006 by Luigi Toscano * + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_TXT_H +#define OKULAR_DEBUG_TXT_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularTxtDebug) + +#endif diff --git a/generators/txt/document.cpp b/generators/txt/document.cpp new file mode 100644 index 0000000..33cf2f7 --- /dev/null +++ b/generators/txt/document.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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. * + ***************************************************************************/ + +#include "document.h" + +#include +#include +#include + +#include +#include + +#include "debug_txt.h" + +using namespace Txt; + +Document::Document(const QString &fileName) +{ +#ifdef TXT_DEBUG + qCDebug(OkularTxtDebug) << "Opening file" << fileName; +#endif + + QFile plainFile(fileName); + if (!plainFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCDebug(OkularTxtDebug) << "Can't open file" << plainFile.fileName(); + return; + } + + const QByteArray buffer = plainFile.readAll(); + setPlainText(toUnicode(buffer)); +} + +Document::~Document() +{ +} + +QString Document::toUnicode(const QByteArray &array) +{ + QByteArray encoding; + KEncodingProber prober(KEncodingProber::Universal); + int charsFeeded = 0; + int chunkSize = 3000; // ~= number of symbols in page. + + // Try to detect encoding. + while (encoding.isEmpty() && charsFeeded < array.size()) { + prober.feed(array.mid(charsFeeded, chunkSize)); + charsFeeded += chunkSize; + + if (prober.confidence() >= 0.5) { + encoding = prober.encoding(); + break; + } + } + + if (encoding.isEmpty()) { + return QString(); + } + + qCDebug(OkularTxtDebug) << "Detected" << prober.encoding() << "encoding" + << "based on" << charsFeeded << "chars"; + return QTextCodec::codecForName(encoding)->toUnicode(array); +} + +Q_LOGGING_CATEGORY(OkularTxtDebug, "org.kde.okular.generators.txt", QtWarningMsg) diff --git a/generators/txt/document.h b/generators/txt/document.h new file mode 100644 index 0000000..e080756 --- /dev/null +++ b/generators/txt/document.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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 _TXT_DOCUMENT_H_ +#define _TXT_DOCUMENT_H_ + +#include + +namespace Txt +{ +class Document : public QTextDocument +{ + Q_OBJECT + +public: + explicit Document(const QString &fileName); + ~Document() override; + +private: + QString toUnicode(const QByteArray &array); +}; +} + +#endif diff --git a/generators/txt/generator_txt.cpp b/generators/txt/generator_txt.cpp new file mode 100644 index 0000000..40a2222 --- /dev/null +++ b/generators/txt/generator_txt.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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. * + ***************************************************************************/ + +#include "generator_txt.h" +#include "converter.h" + +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(TxtGenerator, "libokularGenerator_txt.json") + +TxtGenerator::TxtGenerator(QObject *parent, const QVariantList &args) + : Okular::TextDocumentGenerator(new Txt::Converter, QStringLiteral("okular_txt_generator_settings"), parent, args) +{ +} + +void TxtGenerator::addPages(KConfigDialog *dlg) +{ + Okular::TextDocumentSettingsWidget *widget = new Okular::TextDocumentSettingsWidget(); + + dlg->addPage(widget, generalSettings(), i18n("Txt"), QStringLiteral("text-plain"), i18n("Txt Backend Configuration")); +} + +#include "generator_txt.moc" diff --git a/generators/txt/generator_txt.h b/generators/txt/generator_txt.h new file mode 100644 index 0000000..1b64d82 --- /dev/null +++ b/generators/txt/generator_txt.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2013 by Azat Khuzhin * + * * + * 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 _GENERATOR_TXT_H_ +#define _GENERATOR_TXT_H_ + +#include + +class TxtGenerator : public Okular::TextDocumentGenerator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) + +public: + TxtGenerator(QObject *parent, const QVariantList &args); + ~TxtGenerator() override + { + } + + void addPages(KConfigDialog *dlg) override; +}; + +#endif diff --git a/generators/txt/libokularGenerator_txt.json b/generators/txt/libokularGenerator_txt.json new file mode 100644 index 0000000..ac186dd --- /dev/null +++ b/generators/txt/libokularGenerator_txt.json @@ -0,0 +1,169 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "a3at.mail@gmail.com", + "Name": "Azat Khuzhin", + "Name[az]": "Azat Khuzhin", + "Name[ca@valencia]": "Azat Khuzhin", + "Name[ca]": "Azat Khuzhin", + "Name[cs]": "Azat Khuzhin", + "Name[da]": "Azat Khuzhin", + "Name[de]": "Azat Khuzhin", + "Name[el]": "Azat Khuzhin", + "Name[en_GB]": "Azat Khuzhin", + "Name[es]": "Azat Khuzhin", + "Name[et]": "Azat Khuzhin", + "Name[eu]": "Azat Khuzhin", + "Name[fi]": "Azat Khuzhin", + "Name[fr]": "Azat Khuzhin", + "Name[gl]": "Azat Khuzhin", + "Name[ia]": "Azat Khuzhin", + "Name[it]": "Azat Khuzhin", + "Name[ko]": "Azat Khuzhin", + "Name[lt]": "Azat Khuzhin", + "Name[nl]": "Azat Khuzhin", + "Name[nn]": "Azat Khuzhin", + "Name[pl]": "Azat Khuzhin", + "Name[pt]": "Azat Khuzhin", + "Name[pt_BR]": "Azat Khuzhin", + "Name[ru]": "Азат Хужин", + "Name[sk]": "Azat Khuzhin", + "Name[sl]": "Azat Khuzhin", + "Name[sr@ijekavian]": "Азат Хужин", + "Name[sr@ijekavianlatin]": "Azat Hužin", + "Name[sr@latin]": "Azat Hužin", + "Name[sr]": "Азат Хужин", + "Name[sv]": "Azat Khuzhin", + "Name[tr]": "Azat Khuzhin", + "Name[uk]": "Azat Khuzhin", + "Name[x-test]": "xxAzat Khuzhinxx", + "Name[zh_CN]": "Azat Khuzhin", + "Name[zh_TW]": "Azat Khuzhin" + } + ], + "Copyright": "© 2013 Azat Khuzhin", + "Copyright[az]": "© 2013 Azat Khuzhin", + "Copyright[ca@valencia]": "© 2013 Azat Khuzhin", + "Copyright[ca]": "© 2013 Azat Khuzhin", + "Copyright[cs]": "© 2013 Azat Khuzhin", + "Copyright[da]": "© 2013 Azat Khuzhin", + "Copyright[de]": "© 2013 Azat Khuzhin", + "Copyright[el]": "© 2013 Azat Khuzhin", + "Copyright[en_GB]": "© 2013 Azat Khuzhin", + "Copyright[es]": "© 2013 Azat Khuzhin", + "Copyright[et]": "© 2013: Azat Khuzhin", + "Copyright[eu]": "© 2013 Azat Khuzhin", + "Copyright[fi]": "© 2013 Azat Khuzhin", + "Copyright[fr]": "© 2013 Azat Khuzhin", + "Copyright[gl]": "© 2013 Azat Khuzhin", + "Copyright[ia]": "© 2013 Azat Khuzhin", + "Copyright[it]": "© 2013 Azat Khuzhin", + "Copyright[ko]": "© 2013 Azat Khuzhin", + "Copyright[lt]": "© 2013 Azat Khuzhin", + "Copyright[nl]": "© 2013 Azat Khuzhin", + "Copyright[nn]": "© 2013 Azat Khuzhin", + "Copyright[pl]": "© 2013 Azat Khuzhin", + "Copyright[pt]": "© 2013 Azat Khuzhin", + "Copyright[pt_BR]": "© 2013 Azat Khuzhin", + "Copyright[ru]": "© Азат Хужин, 2013", + "Copyright[sk]": "© 2013 Azat Khuzhin", + "Copyright[sl]": "© 2013 Azat Khuzhin", + "Copyright[sr@ijekavian]": "© 2013, Азат Хужин", + "Copyright[sr@ijekavianlatin]": "© 2013, Azat Hužin", + "Copyright[sr@latin]": "© 2013, Azat Hužin", + "Copyright[sr]": "© 2013, Азат Хужин", + "Copyright[sv]": "© 2013 Azat Khuzhin", + "Copyright[tr]": "© 2013 Azat Khuzhin", + "Copyright[uk]": "© Azat Khuzhin, 2013", + "Copyright[x-test]": "xx© 2013 Azat Khuzhinxx", + "Copyright[zh_CN]": "© 2013 Azat Khuzhin", + "Copyright[zh_TW]": "© 2013 Azat Khuzhin", + "Description": "Txt backend", + "Description[az]": "Txt modulu", + "Description[ca@valencia]": "Dorsal txt", + "Description[ca]": "Dorsal txt", + "Description[cs]": "Podpůrná vrstva txt", + "Description[da]": "Txt-backend", + "Description[de]": "Anzeigemodul für Textformat", + "Description[el]": "Σύστημα υποστήριξης txt", + "Description[en_GB]": "Txt backend", + "Description[es]": "Motor Txt", + "Description[et]": "Txt taustaprogramm", + "Description[eu]": "Txt-ren bizkarraldekoa", + "Description[fi]": "Txt-taustaosa", + "Description[fr]": "Moteur Txt", + "Description[gl]": "Infraestrutura para txt.", + "Description[ia]": "Retro-administration per Txt ", + "Description[it]": "Backend di testo semplice", + "Description[ko]": "TXT 백엔드", + "Description[lt]": "Txt programinė sąsaja", + "Description[nl]": "Txt-backend", + "Description[nn]": "Txt-motor", + "Description[pl]": "Obsługa plików tekstowych", + "Description[pt]": "Infra-estrutura de TXT", + "Description[pt_BR]": "Infraestrutura Txt", + "Description[ru]": "Модуль поддержки формата Txt", + "Description[sk]": "Txt backend", + "Description[sl]": "Zaledje za txt", + "Description[sr@ijekavian]": "Позадина за текст", + "Description[sr@ijekavianlatin]": "Pozadina za tekst", + "Description[sr@latin]": "Pozadina za tekst", + "Description[sr]": "Позадина за текст", + "Description[sv]": "Textgränssnitt", + "Description[tr]": "Txt arka ucu", + "Description[uk]": "Модуль тексту", + "Description[x-test]": "xxTxt backendxx", + "Description[zh_CN]": "纯文本后端", + "Description[zh_TW]": "Txt 後端介面", + "Id": "okular_txt", + "License": "GPL", + "MimeTypes": [ + "text/plain" + ], + "Name": "Txt Backend", + "Name[az]": "Txt modulu", + "Name[ca@valencia]": "Dorsal txt", + "Name[ca]": "Dorsal txt", + "Name[cs]": "Podpůrná vrstva txt", + "Name[da]": "Txt-backend", + "Name[de]": "Anzeigemodul für Textformat", + "Name[el]": "Σύστημα υποστήριξης txt", + "Name[en_GB]": "Txt Backend", + "Name[es]": "Motor para Txt", + "Name[et]": "Txt taustaprogramm", + "Name[eu]": "Txt-ren bizkarraldekoa", + "Name[fi]": "Txt-taustaosa", + "Name[fr]": "Moteur Txt", + "Name[gl]": "Infraestrutura para txt", + "Name[ia]": "Retro-administration per Txt ", + "Name[it]": "Backend di testo semplice", + "Name[ko]": "TXT 백엔드", + "Name[lt]": "Txt programinė sąsaja", + "Name[nl]": "Txt-backend", + "Name[nn]": "Txt-motor", + "Name[pl]": "Obsługa plików tekstowych", + "Name[pt]": "Infra-Estrutura de TXT", + "Name[pt_BR]": "Infraestrutura Txt", + "Name[ru]": "Модуль поддержки формата Txt", + "Name[sk]": "Txt backend", + "Name[sl]": "Zaledje za txt", + "Name[sr@ijekavian]": "Позадина за текст", + "Name[sr@ijekavianlatin]": "Pozadina za tekst", + "Name[sr@latin]": "Pozadina za tekst", + "Name[sr]": "Позадина за текст", + "Name[sv]": "Textgränssnitt", + "Name[tr]": "Txt Arka Ucu", + "Name[uk]": "Модуль тексту", + "Name[x-test]": "xxTxt Backendxx", + "Name[zh_CN]": "纯文本后端", + "Name[zh_TW]": "Txt 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.1" + }, + "X-KDE-Priority": 2, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": true +} diff --git a/generators/txt/okularApplication_txt.desktop b/generators/txt/okularApplication_txt.desktop new file mode 100644 index 0000000..73369ff --- /dev/null +++ b/generators/txt/okularApplication_txt.desktop @@ -0,0 +1,220 @@ +[Desktop Entry] +MimeType=text/plain; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=3 +Categories=Qt;KDE;Graphics;Viewer; +NoDisplay=true +X-KDE-Keywords=txt +X-KDE-Keywords[az]=txt +X-KDE-Keywords[bg]=txt +X-KDE-Keywords[bs]=txt +X-KDE-Keywords[ca]=txt +X-KDE-Keywords[ca@valencia]=txt +X-KDE-Keywords[cs]=txt +X-KDE-Keywords[da]=txt +X-KDE-Keywords[de]=Text +X-KDE-Keywords[el]=txt +X-KDE-Keywords[en_GB]=txt +X-KDE-Keywords[es]=txt +X-KDE-Keywords[et]=txt +X-KDE-Keywords[eu]=txt +X-KDE-Keywords[fi]=txt +X-KDE-Keywords[fr]=txt +X-KDE-Keywords[gl]=txt +X-KDE-Keywords[hu]=txt +X-KDE-Keywords[ia]=txt +X-KDE-Keywords[is]=txt +X-KDE-Keywords[it]=txt, testo +X-KDE-Keywords[ja]=txt +X-KDE-Keywords[kk]=txt +X-KDE-Keywords[ko]=txt +X-KDE-Keywords[lt]=txt +X-KDE-Keywords[mr]=txt +X-KDE-Keywords[nb]=txt +X-KDE-Keywords[nds]=txt +X-KDE-Keywords[nl]=txt +X-KDE-Keywords[nn]=txt +X-KDE-Keywords[pa]=txt +X-KDE-Keywords[pl]=txt +X-KDE-Keywords[pt]=txt +X-KDE-Keywords[pt_BR]=txt +X-KDE-Keywords[ru]=txt +X-KDE-Keywords[sk]=txt +X-KDE-Keywords[sl]=txt +X-KDE-Keywords[sr]=txt,обични,текст +X-KDE-Keywords[sr@ijekavian]=txt,обични,текст +X-KDE-Keywords[sr@ijekavianlatin]=txt,obični,tekst +X-KDE-Keywords[sr@latin]=txt,obični,tekst +X-KDE-Keywords[sv]=txt +X-KDE-Keywords[tr]=txt +X-KDE-Keywords[ug]=txt +X-KDE-Keywords[uk]=txt +X-KDE-Keywords[x-test]=xxtxtxx +X-KDE-Keywords[zh_CN]=txt +X-KDE-Keywords[zh_TW]=txt diff --git a/generators/txt/okularTxt.desktop b/generators/txt/okularTxt.desktop new file mode 100644 index 0000000..20fc725 --- /dev/null +++ b/generators/txt/okularTxt.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=text/plain; diff --git a/generators/txt/org.kde.mobile.okular_txt.desktop b/generators/txt/org.kde.mobile.okular_txt.desktop new file mode 100644 index 0000000..93e25af --- /dev/null +++ b/generators/txt/org.kde.mobile.okular_txt.desktop @@ -0,0 +1,211 @@ +[Desktop Entry] +MimeType=text/plain; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=txt +X-KDE-Keywords[az]=txt +X-KDE-Keywords[bg]=txt +X-KDE-Keywords[bs]=txt +X-KDE-Keywords[ca]=txt +X-KDE-Keywords[ca@valencia]=txt +X-KDE-Keywords[cs]=txt +X-KDE-Keywords[da]=txt +X-KDE-Keywords[de]=Text +X-KDE-Keywords[el]=txt +X-KDE-Keywords[en_GB]=txt +X-KDE-Keywords[es]=txt +X-KDE-Keywords[et]=txt +X-KDE-Keywords[eu]=txt +X-KDE-Keywords[fi]=txt +X-KDE-Keywords[fr]=txt +X-KDE-Keywords[gl]=txt +X-KDE-Keywords[hu]=txt +X-KDE-Keywords[ia]=txt +X-KDE-Keywords[is]=txt +X-KDE-Keywords[it]=txt, testo +X-KDE-Keywords[ja]=txt +X-KDE-Keywords[kk]=txt +X-KDE-Keywords[ko]=txt +X-KDE-Keywords[lt]=txt +X-KDE-Keywords[mr]=txt +X-KDE-Keywords[nb]=txt +X-KDE-Keywords[nds]=txt +X-KDE-Keywords[nl]=txt +X-KDE-Keywords[nn]=txt +X-KDE-Keywords[pa]=txt +X-KDE-Keywords[pl]=txt +X-KDE-Keywords[pt]=txt +X-KDE-Keywords[pt_BR]=txt +X-KDE-Keywords[ru]=txt +X-KDE-Keywords[sk]=txt +X-KDE-Keywords[sl]=txt +X-KDE-Keywords[sr]=txt,обични,текст +X-KDE-Keywords[sr@ijekavian]=txt,обични,текст +X-KDE-Keywords[sr@ijekavianlatin]=txt,obični,tekst +X-KDE-Keywords[sr@latin]=txt,obični,tekst +X-KDE-Keywords[sv]=txt +X-KDE-Keywords[tr]=txt +X-KDE-Keywords[ug]=txt +X-KDE-Keywords[uk]=txt +X-KDE-Keywords[x-test]=xxtxtxx +X-KDE-Keywords[zh_CN]=txt +X-KDE-Keywords[zh_TW]=txt diff --git a/generators/txt/org.kde.okular-txt.metainfo.xml b/generators/txt/org.kde.okular-txt.metainfo.xml new file mode 100644 index 0000000..5841438 --- /dev/null +++ b/generators/txt/org.kde.okular-txt.metainfo.xml @@ -0,0 +1,90 @@ + + + org.kde.okular-txt + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Text + Text + Text + Text + Text + Text + Text + Text + Texto + Tekst + Testua + Teksti + Texte + Texto + Texto + Testo + 텍스트 + Tekstas + വാചകം + Tekst + Tekst + Tekst + Texto + Texto + Текст + Text + Besedilo + Текст + Tekst + Текст + Tekst + Text + Metin + Текст + xxTextxx + 文本 + 文字 + Adds support for reading plain text documents + Adi mətn sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents de text net + Afig la implementació per a llegir documents de text net + Přidává podporu pro čtení dokumentů v čistém textu + Bietet Unterstützung zum Lesen von Text-Dokumenten + Προσθέτει υποστήριξη για την ανάνγωση εγγράφων απλού κειμένου + Adds support for reading plain text documents + Permite la lectura de documentos de texto sin formato + Lihttekstidokumentide lugemise toetus + Testu arrunteko dokumentuak irakurtzeko euskarria gehitzen du + Lisää paljaiden tekstitiedostojen lukutuen + Permet la lecture des fichiers texte + Engade a posibilidade de ler documentos de texto simple + Adde supporto per leger documentos plan + Aggiunge il supporto per la lettura di documenti in testo semplice + 일반 텍스트 문서 읽기 지원 추가 + Prideda palaikymą grynų tekstinių dokumentų skaitymui + Voegt ondersteuning voor lezen van gewone tekstdocumenten toe + Legg til støtte for å lesa reintekstdokument + Dodaje obsługę zwykłych plików tekstowych + Adiciona o suporte para ler documentos em texto simples + Adiciona o suporte para leitura de documentos em texto simples + Поддержка чтения простых текстовых документов + Pridá podporu pre čítanie čistých textových dokumentov + Doda podporo za branje besedilnih dokumentov + Подршка за читање докумената у обичном тексту + Podrška za čitanje dokumenata u običnom tekstu + Подршка за читање докумената у обичном тексту + Podrška za čitanje dokumenata u običnom tekstu + Lägger till stöd för att läsa enkla textdokument + Düz metin belgelerini okuma desteği ekler + Додає підтримку читання звичайних текстових документів + xxAdds support for reading plain text documentsxx + 增加对纯文本文档的支持 + 加入讀取純文字文件的支援 + + text/plain + + https://okular.kde.org + + + + + + + diff --git a/generators/xps/.emacs-dirvars b/generators/xps/.emacs-dirvars new file mode 100644 index 0000000..5f00d7b --- /dev/null +++ b/generators/xps/.emacs-dirvars @@ -0,0 +1,12 @@ +;; -*- emacs-lisp -*- +;; +;; This file is processed by the dirvars emacs package. Each variable +;; setting below is performed when this dirvars file is loaded. +;; +indent-tabs-mode: nil +tab-width: 8 +c-basic-offset: 4 +evaluate: (c-set-offset 'innamespace '0) +kde-emacs-after-parent-string: "" +evaluate: (c-set-offset 'inline-open '0) +kdab-qt-version: 4 diff --git a/generators/xps/CMakeLists.txt b/generators/xps/CMakeLists.txt new file mode 100644 index 0000000..a71ec9e --- /dev/null +++ b/generators/xps/CMakeLists.txt @@ -0,0 +1,22 @@ +remove_definitions(-DTRANSLATION_DOMAIN="okular") +add_definitions(-DTRANSLATION_DOMAIN="okular_xps") + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + + +########### next target ############### + +set(okularGenerator_xps_SRCS + generator_xps.cpp +) + +okular_add_generator(okularGenerator_xps ${okularGenerator_xps_SRCS}) + +target_link_libraries(okularGenerator_xps okularcore KF5::Archive KF5::I18n KF5::KIOCore Qt5::PrintSupport Qt5::Xml) + +########### install files ############### +install( FILES okularXps.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) +install( PROGRAMS okularApplication_xps.desktop org.kde.mobile.okular_xps.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) +install( FILES org.kde.okular-xps.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/xps/Messages.sh b/generators/xps/Messages.sh new file mode 100644 index 0000000..e3d4fd0 --- /dev/null +++ b/generators/xps/Messages.sh @@ -0,0 +1,2 @@ +#!/bin/sh +$XGETTEXT $(find . -name "*.cpp" -o -name "*.h") -o $podir/okular_xps.pot diff --git a/generators/xps/generator_xps.cpp b/generators/xps/generator_xps.cpp new file mode 100644 index 0000000..14dce59 --- /dev/null +++ b/generators/xps/generator_xps.cpp @@ -0,0 +1,2163 @@ +/* + Copyright (C) 2006, 2009 Brad Hards + + 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 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "generator_xps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +OKULAR_EXPORT_PLUGIN(XpsGenerator, "libokularGenerator_xps.json") + +Q_DECLARE_METATYPE(QGradient *) +Q_DECLARE_METATYPE(XpsPathFigure *) +Q_DECLARE_METATYPE(XpsPathGeometry *) + +// From Qt4 +static int hex2int(char hex) +{ + QChar hexchar = QLatin1Char(hex); + int v; + if (hexchar.isDigit()) + v = hexchar.digitValue(); + else if (hexchar >= QLatin1Char('A') && hexchar <= QLatin1Char('F')) + v = hexchar.cell() - 'A' + 10; + else if (hexchar >= QLatin1Char('a') && hexchar <= QLatin1Char('f')) + v = hexchar.cell() - 'a' + 10; + else + v = -1; + return v; +} + +// Modified from Qt4 +static QColor hexToRgba(const QByteArray &name) +{ + const int len = name.length(); + if (len == 0 || name[0] != '#') + return QColor(); + int r, g, b; + int a = 255; + if (len == 7) { + r = (hex2int(name[1]) << 4) + hex2int(name[2]); + g = (hex2int(name[3]) << 4) + hex2int(name[4]); + b = (hex2int(name[5]) << 4) + hex2int(name[6]); + } else if (len == 9) { + a = (hex2int(name[1]) << 4) + hex2int(name[2]); + r = (hex2int(name[3]) << 4) + hex2int(name[4]); + g = (hex2int(name[5]) << 4) + hex2int(name[6]); + b = (hex2int(name[7]) << 4) + hex2int(name[8]); + } else { + r = g = b = -1; + } + if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255) { + return QColor(); + } + return QColor(r, g, b, a); +} + +static QRectF stringToRectF(const QString &data) +{ + QStringList numbers = data.split(QLatin1Char(',')); + QPointF origin(numbers.at(0).toDouble(), numbers.at(1).toDouble()); + QSizeF size(numbers.at(2).toDouble(), numbers.at(3).toDouble()); + return QRectF(origin, size); +} + +static bool parseGUID(const QString &guidString, unsigned short guid[16]) +{ + if (guidString.length() <= 35) { + return false; + } + + // Maps bytes to positions in guidString + const static int indexes[] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34}; + + for (int i = 0; i < 16; i++) { + int hex1 = hex2int(guidString[indexes[i]].cell()); + int hex2 = hex2int(guidString[indexes[i] + 1].cell()); + + if ((hex1 < 0) || (hex2 < 0)) { + return false; + } + + guid[i] = hex1 * 16 + hex2; + } + + return true; +} + +// Read next token of abbreviated path data +static bool nextAbbPathToken(AbbPathToken *token) +{ + int *curPos = &token->curPos; + QString data = token->data; + + while ((*curPos < data.length()) && (data.at(*curPos).isSpace())) { + (*curPos)++; + } + + if (*curPos == data.length()) { + token->type = abtEOF; + return true; + } + + QChar ch = data.at(*curPos); + + if (ch.isNumber() || (ch == QLatin1Char('+')) || (ch == QLatin1Char('-'))) { + int start = *curPos; + while ((*curPos < data.length()) && (!data.at(*curPos).isSpace()) && (data.at(*curPos) != QLatin1Char(',') && (!data.at(*curPos).isLetter() || data.at(*curPos) == QLatin1Char('e')))) { + (*curPos)++; + } + token->number = data.midRef(start, *curPos - start).toDouble(); + token->type = abtNumber; + + } else if (ch == QLatin1Char(',')) { + token->type = abtComma; + (*curPos)++; + } else if (ch.isLetter()) { + token->type = abtCommand; + token->command = data.at(*curPos).cell(); + (*curPos)++; + } else { + (*curPos)++; + return false; + } + + return true; +} + +/** + Read point (two reals delimited by comma) from abbreviated path data +*/ +static QPointF getPointFromString(AbbPathToken *token, bool relative, const QPointF currentPosition) +{ + // TODO Check grammar + + QPointF result; + result.rx() = token->number; + nextAbbPathToken(token); + nextAbbPathToken(token); // , + result.ry() = token->number; + nextAbbPathToken(token); + + if (relative) { + result += currentPosition; + } + + return result; +} + +/** + Read point (two reals delimited by comma) from string +*/ +static QPointF getPointFromString(const QString &string) +{ + const int commaPos = string.indexOf(QLatin1Char(QLatin1Char(','))); + if (commaPos == -1 || string.indexOf(QLatin1Char(QLatin1Char(',')), commaPos + 1) != -1) + return QPointF(); + + QPointF result; + bool ok = false; + QStringRef ref = string.midRef(0, commaPos); + result.setX(QString::fromRawData(ref.constData(), ref.count()).toDouble(&ok)); + if (!ok) + return QPointF(); + + ref = string.midRef(commaPos + 1); + result.setY(QString::fromRawData(ref.constData(), ref.count()).toDouble(&ok)); + if (!ok) + return QPointF(); + + return result; +} + +static Qt::FillRule fillRuleFromString(const QString &data, Qt::FillRule def = Qt::OddEvenFill) +{ + if (data == QLatin1String("EvenOdd")) { + return Qt::OddEvenFill; + } else if (data == QLatin1String("NonZero")) { + return Qt::WindingFill; + } + return def; +} + +/** + Parse an abbreviated path "Data" description + \param data the string containing the whitespace separated values + + \see XPS specification 4.2.3 and Appendix G +*/ +static QPainterPath parseAbbreviatedPathData(const QString &data) +{ + QPainterPath path; + + AbbPathToken token; + + token.data = data; + token.curPos = 0; + + nextAbbPathToken(&token); + + // Used by Smooth cubic curve (command s) + char lastCommand = ' '; + QPointF lastSecondControlPoint; + + while (true) { + if (token.type != abtCommand) { + if (token.type != abtEOF) { + qCWarning(OkularXpsDebug).nospace() << "Error in parsing abbreviated path data (" << token.type << "@" << token.curPos << "): " << data; + } + return path; + } + + char command = QChar::fromLatin1(token.command).toLower().cell(); + bool isRelative = QChar::fromLatin1(token.command).isLower(); + QPointF currPos = path.currentPosition(); + nextAbbPathToken(&token); + + switch (command) { + case 'f': + int rule; + rule = (int)token.number; + if (rule == 0) { + path.setFillRule(Qt::OddEvenFill); + } else if (rule == 1) { + // In xps specs rule 1 means NonZero fill. I think it's equivalent to WindingFill but I'm not sure + path.setFillRule(Qt::WindingFill); + } + nextAbbPathToken(&token); + break; + case 'm': // Move + while (token.type == abtNumber) { + QPointF point = getPointFromString(&token, isRelative, currPos); + path.moveTo(point); + } + break; + case 'l': // Line + while (token.type == abtNumber) { + QPointF point = getPointFromString(&token, isRelative, currPos); + path.lineTo(point); + } + break; + case 'h': // Horizontal line + while (token.type == abtNumber) { + double x = token.number; + if (isRelative) + x += path.currentPosition().x(); + path.lineTo(x, path.currentPosition().y()); + nextAbbPathToken(&token); + } + break; + case 'v': // Vertical line + while (token.type == abtNumber) { + double y = token.number; + if (isRelative) + y += path.currentPosition().y(); + path.lineTo(path.currentPosition().x(), y); + nextAbbPathToken(&token); + } + break; + case 'c': // Cubic bezier curve + while (token.type == abtNumber) { + QPointF firstControl = getPointFromString(&token, isRelative, currPos); + QPointF secondControl = getPointFromString(&token, isRelative, currPos); + QPointF endPoint = getPointFromString(&token, isRelative, currPos); + path.cubicTo(firstControl, secondControl, endPoint); + + lastSecondControlPoint = secondControl; + } + break; + case 'q': // Quadratic bezier curve + while (token.type == abtNumber) { + QPointF point1 = getPointFromString(&token, isRelative, currPos); + QPointF point2 = getPointFromString(&token, isRelative, currPos); + path.quadTo(point1, point2); + } + break; + case 's': // Smooth cubic bezier curve + while (token.type == abtNumber) { + QPointF firstControl; + if ((lastCommand == 's') || (lastCommand == 'c')) { + firstControl = lastSecondControlPoint + (lastSecondControlPoint + path.currentPosition()); + } else { + firstControl = path.currentPosition(); + } + QPointF secondControl = getPointFromString(&token, isRelative, currPos); + QPointF endPoint = getPointFromString(&token, isRelative, currPos); + path.cubicTo(firstControl, secondControl, endPoint); + } + break; + case 'a': // Arc + // TODO Implement Arc drawing + while (token.type == abtNumber) { + /*QPointF rp =*/getPointFromString(&token, isRelative, currPos); + /*double r = token.number;*/ + nextAbbPathToken(&token); + /*double fArc = token.number; */ + nextAbbPathToken(&token); + /*double fSweep = token.number; */ + nextAbbPathToken(&token); + /*QPointF point = */ getPointFromString(&token, isRelative, currPos); + } + break; + case 'z': // Close path + path.closeSubpath(); + break; + } + + lastCommand = command; + } + + return path; +} + +/** + Parse a "Matrix" attribute string + \param csv the comma separated list of values + \return the QTransform corresponding to the affine transform + given in the attribute + + \see XPS specification 7.4.1 +*/ +static QTransform attsToMatrix(const QString &csv) +{ + QStringList values = csv.split(QLatin1Char(',')); + if (values.count() != 6) { + return QTransform(); // that is an identity matrix - no effect + } + return QTransform(values.at(0).toDouble(), values.at(1).toDouble(), values.at(2).toDouble(), values.at(3).toDouble(), values.at(4).toDouble(), values.at(5).toDouble()); +} + +/** + \return Brush with given color or brush specified by reference to resource +*/ +static QBrush parseRscRefColorForBrush(const QString &data) +{ + if (data[0] == QLatin1Char('{')) { + // TODO + qCWarning(OkularXpsDebug) << "Reference" << data; + return QBrush(); + } else { + return QBrush(hexToRgba(data.toLatin1())); + } +} + +/** + \return Pen with given color or Pen specified by reference to resource +*/ +static QPen parseRscRefColorForPen(const QString &data) +{ + if (data[0] == QLatin1Char('{')) { + // TODO + qCWarning(OkularXpsDebug) << "Reference" << data; + return QPen(); + } else { + return QPen(hexToRgba(data.toLatin1())); + } +} + +/** + \return Matrix specified by given data or by referenced dictionary +*/ +static QTransform parseRscRefMatrix(const QString &data) +{ + if (data[0] == QLatin1Char('{')) { + // TODO + qCWarning(OkularXpsDebug) << "Reference" << data; + return QTransform(); + } else { + return attsToMatrix(data); + } +} + +/** + \return Path specified by given data or by referenced dictionary +*/ +static QPainterPath parseRscRefPath(const QString &data) +{ + if (data[0] == QLatin1Char('{')) { + // TODO + qCWarning(OkularXpsDebug) << "Reference" << data; + return QPainterPath(); + } else { + return parseAbbreviatedPathData(data); + } +} + +/** + \return The path of the entry +*/ +static QString entryPath(const QString &entry) +{ + const QChar slash = QChar::fromLatin1('/'); + const int index = entry.lastIndexOf(slash); + QString ret = entry.mid(0, index); + if (index > 0) { + ret.append(slash); + } + if (!ret.startsWith(slash)) + ret.prepend(slash); + return ret; +} + +/** + \return The path of the entry +*/ +static QString entryPath(const KZipFileEntry *entry) +{ + return entryPath(entry->path()); +} + +/** + \return The absolute path of the \p location, according to \p path if it's non-absolute +*/ +static QString absolutePath(const QString &path, const QString &location) +{ + QString retPath; + if (location.startsWith(QLatin1Char('/'))) { + // already absolute + retPath = location; + } else { + QUrl u = QUrl::fromLocalFile(path); + QUrl u2 = QUrl(location); + retPath = u.resolved(u2).toDisplayString(QUrl::PreferLocalFile); + } + // it seems paths & file names can also be percent-encoded + // (XPS won't ever finish surprising me) + if (retPath.contains(QLatin1Char('%'))) { + retPath = QUrl::fromPercentEncoding(retPath.toUtf8()); + } + return retPath; +} + +/** + Read the content of an archive entry in both the cases: + a) single file + + foobar + b) directory + + foobar/ + + [0].piece + + [1].piece + + ... + + [x].last.piece + + \see XPS specification 10.1.2 +*/ +static QByteArray readFileOrDirectoryParts(const KArchiveEntry *entry, QString *pathOfFile = nullptr) +{ + QByteArray data; + if (entry->isDirectory()) { + const KArchiveDirectory *relDir = static_cast(entry); + QStringList entries = relDir->entries(); + std::sort(entries.begin(), entries.end()); + for (const QString &entry : qAsConst(entries)) { + const KArchiveEntry *relSubEntry = relDir->entry(entry); + if (!relSubEntry->isFile()) + continue; + + const KZipFileEntry *relSubFile = static_cast(relSubEntry); + data.append(relSubFile->data()); + } + } else { + const KZipFileEntry *relFile = static_cast(entry); + data.append(relFile->data()); + if (pathOfFile) { + *pathOfFile = entryPath(relFile); + } + } + return data; +} + +/** + Load the resource \p fileName from the specified \p archive using the case sensitivity \p cs +*/ +static const KArchiveEntry *loadEntry(KZip *archive, const QString &fileName, Qt::CaseSensitivity cs) +{ + // first attempt: loading the entry straight as requested + const KArchiveEntry *entry = archive->directory()->entry(fileName); + // in case sensitive mode, or if we actually found something, return what we found + if (cs == Qt::CaseSensitive || entry) { + return entry; + } + + QString path; + QString entryName; + const int index = fileName.lastIndexOf(QChar::fromLatin1('/')); + if (index > 0) { + path = fileName.left(index); + entryName = fileName.mid(index + 1); + } else { + path = QLatin1Char('/'); + entryName = fileName; + } + const KArchiveEntry *newEntry = archive->directory()->entry(path); + if (newEntry->isDirectory()) { + const KArchiveDirectory *relDir = static_cast(newEntry); + QStringList relEntries = relDir->entries(); + std::sort(relEntries.begin(), relEntries.end()); + for (const QString &relEntry : qAsConst(relEntries)) { + if (relEntry.compare(entryName, Qt::CaseInsensitive) == 0) { + return relDir->entry(relEntry); + } + } + } + return nullptr; +} + +static const KZipFileEntry *loadFile(KZip *archive, const QString &fileName, Qt::CaseSensitivity cs) +{ + const KArchiveEntry *entry = loadEntry(archive, fileName, cs); + return entry->isFile() ? static_cast(entry) : nullptr; +} + +/** + \return The name of a resource from the \p fileName +*/ +static QString resourceName(const QString &fileName) +{ + QString resource = fileName; + const int slashPos = fileName.lastIndexOf(QLatin1Char('/')); + const int dotPos = fileName.lastIndexOf(QLatin1Char('.')); + if (slashPos > -1) { + if (dotPos > -1 && dotPos > slashPos) { + resource = fileName.mid(slashPos + 1, dotPos - slashPos - 1); + } else { + resource = fileName.mid(slashPos + 1); + } + } + return resource; +} + +static QColor interpolatedColor(const QColor &c1, const QColor &c2) +{ + QColor res; + res.setAlpha((c1.alpha() + c2.alpha()) / 2); + res.setRed((c1.red() + c2.red()) / 2); + res.setGreen((c1.green() + c2.green()) / 2); + res.setBlue((c1.blue() + c2.blue()) / 2); + return res; +} + +static bool xpsGradientLessThan(const XpsGradient &g1, const XpsGradient &g2) +{ + return qFuzzyCompare(g1.offset, g2.offset) ? g1.color.name() < g2.color.name() : g1.offset < g2.offset; +} + +static int xpsGradientWithOffset(const QList &gradients, double offset) +{ + int i = 0; + for (const XpsGradient &grad : gradients) { + if (grad.offset == offset) { + return i; + } + ++i; + } + return -1; +} + +/** + Preprocess a list of gradients. + + \see XPS specification 11.3.1.1 +*/ +static void preprocessXpsGradients(QList &gradients) +{ + if (gradients.isEmpty()) + return; + + // sort the gradients (case 1.) + std::stable_sort(gradients.begin(), gradients.end(), xpsGradientLessThan); + + // no gradient with stop 0.0 (case 2.) + if (xpsGradientWithOffset(gradients, 0.0) == -1) { + int firstGreaterThanZero = 0; + while (firstGreaterThanZero < gradients.count() && gradients.at(firstGreaterThanZero).offset < 0.0) + ++firstGreaterThanZero; + // case 2.a: no gradients with stop less than 0.0 + if (firstGreaterThanZero == 0) { + gradients.prepend(XpsGradient(0.0, gradients.first().color)); + } + // case 2.b: some gradients with stop more than 0.0 + else if (firstGreaterThanZero != gradients.count()) { + QColor col1 = gradients.at(firstGreaterThanZero - 1).color; + QColor col2 = gradients.at(firstGreaterThanZero).color; + for (int i = 0; i < firstGreaterThanZero; ++i) { + gradients.removeFirst(); + } + gradients.prepend(XpsGradient(0.0, interpolatedColor(col1, col2))); + } + // case 2.c: no gradients with stop more than 0.0 + else { + XpsGradient newGrad(0.0, gradients.last().color); + gradients.clear(); + gradients.append(newGrad); + } + } + + if (gradients.isEmpty()) + return; + + // no gradient with stop 1.0 (case 3.) + if (xpsGradientWithOffset(gradients, 1.0) == -1) { + int firstLessThanOne = gradients.count() - 1; + while (firstLessThanOne >= 0 && gradients.at(firstLessThanOne).offset > 1.0) + --firstLessThanOne; + // case 2.a: no gradients with stop greater than 1.0 + if (firstLessThanOne == gradients.count() - 1) { + gradients.append(XpsGradient(1.0, gradients.last().color)); + } + // case 2.b: some gradients with stop more than 1.0 + else if (firstLessThanOne != -1) { + QColor col1 = gradients.at(firstLessThanOne).color; + QColor col2 = gradients.at(firstLessThanOne + 1).color; + for (int i = firstLessThanOne + 1; i < gradients.count(); ++i) { + gradients.removeLast(); + } + gradients.append(XpsGradient(1.0, interpolatedColor(col1, col2))); + } + // case 2.c: no gradients with stop less than 1.0 + else { + XpsGradient newGrad(1.0, gradients.first().color); + gradients.clear(); + gradients.append(newGrad); + } + } +} + +static void addXpsGradientsToQGradient(const QList &gradients, QGradient *qgrad) +{ + for (const XpsGradient &grad : gradients) { + qgrad->setColorAt(grad.offset, grad.color); + } +} + +static void applySpreadStyleToQGradient(const QString &style, QGradient *qgrad) +{ + if (style.isEmpty()) + return; + + if (style == QLatin1String("Pad")) { + qgrad->setSpread(QGradient::PadSpread); + } else if (style == QLatin1String("Reflect")) { + qgrad->setSpread(QGradient::ReflectSpread); + } else if (style == QLatin1String("Repeat")) { + qgrad->setSpread(QGradient::RepeatSpread); + } +} + +/** + Read an UnicodeString + \param raw the raw value of UnicodeString + + \see XPS specification 5.1.4 +*/ +static QString unicodeString(const QString &raw) +{ + QString ret; + if (raw.startsWith(QLatin1String("{}"))) { + ret = raw.mid(2); + } else { + ret = raw; + } + return ret; +} + +XpsHandler::XpsHandler(XpsPage *page) + : m_page(page) +{ + m_painter = nullptr; +} + +XpsHandler::~XpsHandler() +{ +} + +bool XpsHandler::startDocument() +{ + qCWarning(OkularXpsDebug) << "start document" << m_page->m_fileName; + + XpsRenderNode node; + node.name = QStringLiteral("document"); + m_nodes.push(node); + + return true; +} + +bool XpsHandler::startElement(const QString &nameSpace, const QString &localName, const QString &qname, const QXmlAttributes &atts) +{ + Q_UNUSED(nameSpace) + Q_UNUSED(qname) + + XpsRenderNode node; + node.name = localName; + node.attributes = atts; + processStartElement(node); + m_nodes.push(node); + + return true; +} + +bool XpsHandler::endElement(const QString &nameSpace, const QString &localName, const QString &qname) +{ + Q_UNUSED(nameSpace) + Q_UNUSED(qname) + + XpsRenderNode node = m_nodes.pop(); + if (node.name != localName) { + qCWarning(OkularXpsDebug) << "Name doesn't match"; + } + processEndElement(node); + node.children.clear(); + m_nodes.top().children.append(node); + + return true; +} + +void XpsHandler::processGlyph(XpsRenderNode &node) +{ + // TODO Currently ignored attributes: CaretStops, DeviceFontName, IsSideways, OpacityMask, Name, FixedPage.NavigateURI, xml:lang, x:key + // TODO Indices is only partially implemented + // TODO Currently ignored child elements: Clip, OpacityMask + // Handled separately: RenderTransform + + QString att; + + m_painter->save(); + + // Get font (doesn't work well because qt doesn't allow to load font from file) + // This works despite the fact that font size isn't specified in points as required by qt. It's because I set point size to be equal to drawing unit. + float fontSize = node.attributes.value(QStringLiteral("FontRenderingEmSize")).toFloat(); + // qCWarning(OkularXpsDebug) << "Font Rendering EmSize:" << fontSize; + // a value of 0.0 means the text is not visible (see XPS specs, chapter 12, "Glyphs") + if (fontSize < 0.1) { + m_painter->restore(); + return; + } + const QString absoluteFileName = absolutePath(entryPath(m_page->fileName()), node.attributes.value(QStringLiteral("FontUri"))); + QFont font = m_page->m_file->getFontByName(absoluteFileName, fontSize); + att = node.attributes.value(QStringLiteral("StyleSimulations")); + if (!att.isEmpty()) { + if (att == QLatin1String("ItalicSimulation")) { + font.setItalic(true); + } else if (att == QLatin1String("BoldSimulation")) { + font.setBold(true); + } else if (att == QLatin1String("BoldItalicSimulation")) { + font.setItalic(true); + font.setBold(true); + } + } + m_painter->setFont(font); + + // Origin + QPointF origin(node.attributes.value(QStringLiteral("OriginX")).toDouble(), node.attributes.value(QStringLiteral("OriginY")).toDouble()); + + // Fill + QBrush brush; + att = node.attributes.value(QStringLiteral("Fill")); + if (att.isEmpty()) { + QVariant data = node.getChildData(QStringLiteral("Glyphs.Fill")); + if (data.canConvert()) { + brush = data.value(); + } else { + // no "Fill" attribute and no "Glyphs.Fill" child, so show nothing + // (see XPS specs, 5.10) + m_painter->restore(); + return; + } + } else { + brush = parseRscRefColorForBrush(att); + if (brush.style() > Qt::NoBrush && brush.style() < Qt::LinearGradientPattern && brush.color().alpha() == 0) { + m_painter->restore(); + return; + } + } + m_painter->setBrush(brush); + m_painter->setPen(QPen(brush, 0)); + + // Opacity + att = node.attributes.value(QStringLiteral("Opacity")); + if (!att.isEmpty()) { + bool ok = true; + double value = att.toDouble(&ok); + if (ok && value >= 0.1) { + m_painter->setOpacity(value); + } else { + m_painter->restore(); + return; + } + } + + // RenderTransform + att = node.attributes.value(QStringLiteral("RenderTransform")); + if (!att.isEmpty()) { + m_painter->setWorldTransform(parseRscRefMatrix(att), true); + } + + // Clip + att = node.attributes.value(QStringLiteral("Clip")); + if (!att.isEmpty()) { + QPainterPath clipPath = parseRscRefPath(att); + if (!clipPath.isEmpty()) { + m_painter->setClipPath(clipPath); + } + } + + // BiDiLevel - default Left-to-Right + m_painter->setLayoutDirection(Qt::LeftToRight); + att = node.attributes.value(QStringLiteral("BiDiLevel")); + if (!att.isEmpty()) { + if ((att.toInt() % 2) == 1) { + // odd BiDiLevel, so Right-to-Left + m_painter->setLayoutDirection(Qt::RightToLeft); + } + } + + // Indices - partial handling only + att = node.attributes.value(QStringLiteral("Indices")); + QList advanceWidths; + if (!att.isEmpty()) { + QStringList indicesElements = att.split(QLatin1Char(';')); + for (int i = 0; i < indicesElements.size(); ++i) { + if (indicesElements.at(i).contains(QStringLiteral(","))) { + QStringList parts = indicesElements.at(i).split(QLatin1Char(',')); + if (parts.size() == 2) { + // regular advance case, no offsets + advanceWidths.append(parts.at(1).toDouble() * fontSize / 100.0); + } else if (parts.size() == 3) { + // regular advance case, with uOffset + qreal AdvanceWidth = parts.at(1).toDouble() * fontSize / 100.0; + qreal uOffset = parts.at(2).toDouble() / 100.0; + advanceWidths.append(AdvanceWidth + uOffset); + } else { + // has vertical offset, but don't know how to handle that yet + qCWarning(OkularXpsDebug) << "Unhandled Indices element: " << indicesElements.at(i); + advanceWidths.append(-1.0); + } + } else { + // no special advance case + advanceWidths.append(-1.0); + } + } + } + + // UnicodeString + QString stringToDraw(unicodeString(node.attributes.value(QStringLiteral("UnicodeString")))); + QPointF originAdvance(0, 0); + QFontMetrics metrics = m_painter->fontMetrics(); + for (int i = 0; i < stringToDraw.size(); ++i) { + QChar thisChar = stringToDraw.at(i); + m_painter->drawText(origin + originAdvance, QString(thisChar)); + const qreal advanceWidth = advanceWidths.value(i, qreal(-1.0)); + if (advanceWidth > 0.0) { + originAdvance.rx() += advanceWidth; + } else { + originAdvance.rx() += metrics.horizontalAdvance(thisChar); + } + } + // qCWarning(OkularXpsDebug) << "Glyphs: " << atts.value("Fill") << ", " << atts.value("FontUri"); + // qCWarning(OkularXpsDebug) << " Origin: " << atts.value("OriginX") << "," << atts.value("OriginY"); + // qCWarning(OkularXpsDebug) << " Unicode: " << atts.value("UnicodeString"); + + m_painter->restore(); +} + +void XpsHandler::processFill(XpsRenderNode &node) +{ + // TODO Ignored child elements: VirtualBrush + + if (node.children.size() != 1) { + qCWarning(OkularXpsDebug) << "Fill element should have exactly one child"; + } else { + node.data = node.children[0].data; + } +} + +void XpsHandler::processStroke(XpsRenderNode &node) +{ + // TODO Ignored child elements: VirtualBrush + + if (node.children.size() != 1) { + qCWarning(OkularXpsDebug) << "Stroke element should have exactly one child"; + } else { + node.data = node.children[0].data; + } +} + +void XpsHandler::processImageBrush(XpsRenderNode &node) +{ + // TODO Ignored attributes: Opacity, x:key, TileMode, ViewBoxUnits, ViewPortUnits + // TODO Check whether transformation works for non standard situations (viewbox different that whole image, Transform different that simple move & scale, Viewport different than [0, 0, 1, 1] + + QString att; + QBrush brush; + + QRectF viewport = stringToRectF(node.attributes.value(QStringLiteral("Viewport"))); + QRectF viewbox = stringToRectF(node.attributes.value(QStringLiteral("Viewbox"))); + QImage image = m_page->loadImageFromFile(node.attributes.value(QStringLiteral("ImageSource"))); + + // Matrix which can transform [0, 0, 1, 1] rectangle to given viewbox + QTransform viewboxMatrix = QTransform(viewbox.width() * image.physicalDpiX() / 96, 0, 0, viewbox.height() * image.physicalDpiY() / 96, viewbox.x(), viewbox.y()); + + // Matrix which can transform [0, 0, 1, 1] rectangle to given viewport + // TODO Take ViewPort into account + QTransform viewportMatrix; + att = node.attributes.value(QStringLiteral("Transform")); + if (att.isEmpty()) { + QVariant data = node.getChildData(QStringLiteral("ImageBrush.Transform")); + if (data.canConvert()) { + viewportMatrix = data.value(); + } else { + viewportMatrix = QTransform(); + } + } else { + viewportMatrix = parseRscRefMatrix(att); + } + viewportMatrix = viewportMatrix * QTransform(viewport.width(), 0, 0, viewport.height(), viewport.x(), viewport.y()); + + brush = QBrush(image); + brush.setTransform(viewboxMatrix.inverted() * viewportMatrix); + + node.data = QVariant::fromValue(brush); +} + +void XpsHandler::processPath(XpsRenderNode &node) +{ + // TODO Ignored attributes: Clip, OpacityMask, StrokeEndLineCap, StorkeStartLineCap, Name, FixedPage.NavigateURI, xml:lang, x:key, AutomationProperties.Name, AutomationProperties.HelpText, SnapsToDevicePixels + // TODO Ignored child elements: RenderTransform, Clip, OpacityMask + // Handled separately: RenderTransform + m_painter->save(); + + QString att; + QVariant data; + + // Get path + XpsPathGeometry *pathdata = node.getChildData(QStringLiteral("Path.Data")).value(); + att = node.attributes.value(QStringLiteral("Data")); + if (!att.isEmpty()) { + QPainterPath path = parseRscRefPath(att); + delete pathdata; + pathdata = new XpsPathGeometry(); + pathdata->paths.append(new XpsPathFigure(path, true)); + } + if (!pathdata) { + // nothing to draw + m_painter->restore(); + return; + } + + // Set Fill + att = node.attributes.value(QStringLiteral("Fill")); + QBrush brush; + if (!att.isEmpty()) { + brush = parseRscRefColorForBrush(att); + } else { + data = node.getChildData(QStringLiteral("Path.Fill")); + if (data.canConvert()) { + brush = data.value(); + } + } + m_painter->setBrush(brush); + + // Stroke (pen) + att = node.attributes.value(QStringLiteral("Stroke")); + QPen pen(Qt::transparent); + if (!att.isEmpty()) { + pen = parseRscRefColorForPen(att); + } else { + data = node.getChildData(QStringLiteral("Path.Stroke")); + if (data.canConvert()) { + pen.setBrush(data.value()); + } + } + att = node.attributes.value(QStringLiteral("StrokeThickness")); + if (!att.isEmpty()) { + bool ok = false; + int thickness = att.toInt(&ok); + if (ok) + pen.setWidth(thickness); + } + att = node.attributes.value(QStringLiteral("StrokeDashArray")); + if (!att.isEmpty()) { + const QStringList pieces = att.split(QLatin1Char(' '), QString::SkipEmptyParts); + QVector dashPattern(pieces.count()); + bool ok = false; + for (int i = 0; i < pieces.count(); ++i) { + qreal value = pieces.at(i).toInt(&ok); + if (ok) { + dashPattern[i] = value; + } else { + break; + } + } + if (ok) { + pen.setDashPattern(dashPattern); + } + } + att = node.attributes.value(QStringLiteral("StrokeDashOffset")); + if (!att.isEmpty()) { + bool ok = false; + int offset = att.toInt(&ok); + if (ok) + pen.setDashOffset(offset); + } + att = node.attributes.value(QStringLiteral("StrokeDashCap")); + if (!att.isEmpty()) { + Qt::PenCapStyle cap = Qt::FlatCap; + if (att == QLatin1String("Flat")) { + cap = Qt::FlatCap; + } else if (att == QLatin1String("Round")) { + cap = Qt::RoundCap; + } else if (att == QLatin1String("Square")) { + cap = Qt::SquareCap; + } + // ### missing "Triangle" + pen.setCapStyle(cap); + } + att = node.attributes.value(QStringLiteral("StrokeLineJoin")); + if (!att.isEmpty()) { + Qt::PenJoinStyle joinStyle = Qt::MiterJoin; + if (att == QLatin1String("Miter")) { + joinStyle = Qt::MiterJoin; + } else if (att == QLatin1String("Bevel")) { + joinStyle = Qt::BevelJoin; + } else if (att == QLatin1String("Round")) { + joinStyle = Qt::RoundJoin; + } + pen.setJoinStyle(joinStyle); + } + att = node.attributes.value(QStringLiteral("StrokeMiterLimit")); + if (!att.isEmpty()) { + bool ok = false; + double limit = att.toDouble(&ok); + if (ok) { + // we have to divide it by two, as XPS consider half of the stroke width, + // while Qt the whole of it + pen.setMiterLimit(limit / 2); + } + } + m_painter->setPen(pen); + + // Opacity + att = node.attributes.value(QStringLiteral("Opacity")); + if (!att.isEmpty()) { + m_painter->setOpacity(att.toDouble()); + } + + // RenderTransform + att = node.attributes.value(QStringLiteral("RenderTransform")); + if (!att.isEmpty()) { + m_painter->setWorldTransform(parseRscRefMatrix(att), true); + } + if (!pathdata->transform.isIdentity()) { + m_painter->setWorldTransform(pathdata->transform, true); + } + + for (const XpsPathFigure *figure : qAsConst(pathdata->paths)) { + m_painter->setBrush(figure->isFilled ? brush : QBrush()); + m_painter->drawPath(figure->path); + } + + delete pathdata; + + m_painter->restore(); +} + +void XpsHandler::processPathData(XpsRenderNode &node) +{ + if (node.children.size() != 1) { + qCWarning(OkularXpsDebug) << "Path.Data element should have exactly one child"; + } else { + node.data = node.children[0].data; + } +} + +void XpsHandler::processPathGeometry(XpsRenderNode &node) +{ + XpsPathGeometry *geom = new XpsPathGeometry(); + + for (const XpsRenderNode &child : qAsConst(node.children)) { + if (child.data.canConvert()) { + XpsPathFigure *figure = child.data.value(); + geom->paths.append(figure); + } + } + + QString att; + + att = node.attributes.value(QStringLiteral("Figures")); + if (!att.isEmpty()) { + QPainterPath path = parseRscRefPath(att); + qDeleteAll(geom->paths); + geom->paths.clear(); + geom->paths.append(new XpsPathFigure(path, true)); + } + + att = node.attributes.value(QStringLiteral("FillRule")); + if (!att.isEmpty()) { + geom->fillRule = fillRuleFromString(att); + } + + // Transform + att = node.attributes.value(QStringLiteral("Transform")); + if (!att.isEmpty()) { + geom->transform = parseRscRefMatrix(att); + } + + if (!geom->paths.isEmpty()) { + node.data = QVariant::fromValue(geom); + } else { + delete geom; + } +} + +void XpsHandler::processPathFigure(XpsRenderNode &node) +{ + // TODO Ignored child elements: ArcSegment + + QString att; + QPainterPath path; + + att = node.attributes.value(QStringLiteral("StartPoint")); + if (!att.isEmpty()) { + QPointF point = getPointFromString(att); + path.moveTo(point); + } else { + return; + } + + for (const XpsRenderNode &child : qAsConst(node.children)) { + bool isStroked = true; + att = node.attributes.value(QStringLiteral("IsStroked")); + if (!att.isEmpty()) { + isStroked = att == QLatin1String("true"); + } + if (!isStroked) { + continue; + } + + // PolyLineSegment + if (child.name == QLatin1String("PolyLineSegment")) { + att = child.attributes.value(QStringLiteral("Points")); + if (!att.isEmpty()) { + const QStringList points = att.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (const QString &p : points) { + QPointF point = getPointFromString(p); + path.lineTo(point); + } + } + } + // PolyBezierSegment + else if (child.name == QLatin1String("PolyBezierSegment")) { + att = child.attributes.value(QStringLiteral("Points")); + if (!att.isEmpty()) { + const QStringList points = att.split(QLatin1Char(' '), QString::SkipEmptyParts); + if (points.count() % 3 == 0) { + for (int i = 0; i < points.count();) { + QPointF firstControl = getPointFromString(points.at(i++)); + QPointF secondControl = getPointFromString(points.at(i++)); + QPointF endPoint = getPointFromString(points.at(i++)); + path.cubicTo(firstControl, secondControl, endPoint); + } + } + } + } + // PolyQuadraticBezierSegment + else if (child.name == QLatin1String("PolyQuadraticBezierSegment")) { + att = child.attributes.value(QStringLiteral("Points")); + if (!att.isEmpty()) { + const QStringList points = att.split(QLatin1Char(' '), QString::SkipEmptyParts); + if (points.count() % 2 == 0) { + for (int i = 0; i < points.count();) { + QPointF point1 = getPointFromString(points.at(i++)); + QPointF point2 = getPointFromString(points.at(i++)); + path.quadTo(point1, point2); + } + } + } + } + } + + bool closePath = false; + att = node.attributes.value(QStringLiteral("IsClosed")); + if (!att.isEmpty()) { + closePath = att == QLatin1String("true"); + } + if (closePath) { + path.closeSubpath(); + } + + bool isFilled = true; + att = node.attributes.value(QStringLiteral("IsFilled")); + if (!att.isEmpty()) { + isFilled = att == QLatin1String("true"); + } + + if (!path.isEmpty()) { + node.data = QVariant::fromValue(new XpsPathFigure(path, isFilled)); + } +} + +void XpsHandler::processStartElement(XpsRenderNode &node) +{ + if (node.name == QLatin1String("Canvas")) { + m_painter->save(); + QString att = node.attributes.value(QStringLiteral("RenderTransform")); + if (!att.isEmpty()) { + m_painter->setWorldTransform(parseRscRefMatrix(att), true); + } + att = node.attributes.value(QStringLiteral("Opacity")); + if (!att.isEmpty()) { + double value = att.toDouble(); + if (value > 0.0 && value <= 1.0) { + m_painter->setOpacity(m_painter->opacity() * value); + } else { + // setting manually to 0 is necessary to "disable" + // all the stuff inside + m_painter->setOpacity(0.0); + } + } + } +} + +void XpsHandler::processEndElement(XpsRenderNode &node) +{ + if (node.name == QLatin1String("Glyphs")) { + processGlyph(node); + } else if (node.name == QLatin1String("Path")) { + processPath(node); + } else if (node.name == QLatin1String("MatrixTransform")) { + // TODO Ignoring x:key + node.data = QVariant::fromValue(QTransform(attsToMatrix(node.attributes.value(QStringLiteral("Matrix"))))); + } else if ((node.name == QLatin1String("Canvas.RenderTransform")) || (node.name == QLatin1String("Glyphs.RenderTransform")) || (node.name == QLatin1String("Path.RenderTransform"))) { + QVariant data = node.getRequiredChildData(QStringLiteral("MatrixTransform")); + if (data.canConvert()) { + m_painter->setWorldTransform(data.value(), true); + } + } else if (node.name == QLatin1String("Canvas")) { + m_painter->restore(); + } else if ((node.name == QLatin1String("Path.Fill")) || (node.name == QLatin1String("Glyphs.Fill"))) { + processFill(node); + } else if (node.name == QLatin1String("Path.Stroke")) { + processStroke(node); + } else if (node.name == QLatin1String("SolidColorBrush")) { + // TODO Ignoring opacity, x:key + node.data = QVariant::fromValue(QBrush(QColor(hexToRgba(node.attributes.value(QStringLiteral("Color")).toLatin1())))); + } else if (node.name == QLatin1String("ImageBrush")) { + processImageBrush(node); + } else if (node.name == QLatin1String("ImageBrush.Transform")) { + node.data = node.getRequiredChildData(QStringLiteral("MatrixTransform")); + } else if (node.name == QLatin1String("LinearGradientBrush")) { + const XpsRenderNode *gradients = node.findChild(QStringLiteral("LinearGradientBrush.GradientStops")); + if (gradients && gradients->data.canConvert()) { + QPointF start = getPointFromString(node.attributes.value(QStringLiteral("StartPoint"))); + QPointF end = getPointFromString(node.attributes.value(QStringLiteral("EndPoint"))); + QLinearGradient *qgrad = static_cast(gradients->data.value()); + qgrad->setStart(start); + qgrad->setFinalStop(end); + applySpreadStyleToQGradient(node.attributes.value(QStringLiteral("SpreadMethod")), qgrad); + node.data = QVariant::fromValue(QBrush(*qgrad)); + delete qgrad; + } + } else if (node.name == QLatin1String("RadialGradientBrush")) { + const XpsRenderNode *gradients = node.findChild(QStringLiteral("RadialGradientBrush.GradientStops")); + if (gradients && gradients->data.canConvert()) { + QPointF center = getPointFromString(node.attributes.value(QStringLiteral("Center"))); + QPointF origin = getPointFromString(node.attributes.value(QStringLiteral("GradientOrigin"))); + double radiusX = node.attributes.value(QStringLiteral("RadiusX")).toDouble(); + double radiusY = node.attributes.value(QStringLiteral("RadiusY")).toDouble(); + QRadialGradient *qgrad = static_cast(gradients->data.value()); + qgrad->setCenter(center); + qgrad->setFocalPoint(origin); + // TODO what in case of different radii? + qgrad->setRadius(qMin(radiusX, radiusY)); + applySpreadStyleToQGradient(node.attributes.value(QStringLiteral("SpreadMethod")), qgrad); + node.data = QVariant::fromValue(QBrush(*qgrad)); + delete qgrad; + } + } else if (node.name == QLatin1String("LinearGradientBrush.GradientStops")) { + QList gradients; + for (const XpsRenderNode &child : qAsConst(node.children)) { + double offset = child.attributes.value(QStringLiteral("Offset")).toDouble(); + QColor color = hexToRgba(child.attributes.value(QStringLiteral("Color")).toLatin1()); + gradients.append(XpsGradient(offset, color)); + } + preprocessXpsGradients(gradients); + if (!gradients.isEmpty()) { + QLinearGradient *qgrad = new QLinearGradient(); + addXpsGradientsToQGradient(gradients, qgrad); + node.data = QVariant::fromValue(qgrad); + } + } else if (node.name == QLatin1String("RadialGradientBrush.GradientStops")) { + QList gradients; + for (const XpsRenderNode &child : qAsConst(node.children)) { + double offset = child.attributes.value(QStringLiteral("Offset")).toDouble(); + QColor color = hexToRgba(child.attributes.value(QStringLiteral("Color")).toLatin1()); + gradients.append(XpsGradient(offset, color)); + } + preprocessXpsGradients(gradients); + if (!gradients.isEmpty()) { + QRadialGradient *qgrad = new QRadialGradient(); + addXpsGradientsToQGradient(gradients, qgrad); + node.data = QVariant::fromValue(qgrad); + } + } else if (node.name == QLatin1String("PathFigure")) { + processPathFigure(node); + } else if (node.name == QLatin1String("PathGeometry")) { + processPathGeometry(node); + } else if (node.name == QLatin1String("Path.Data")) { + processPathData(node); + } else { + // qCWarning(OkularXpsDebug) << "Unknown element: " << node->name; + } +} + +XpsPage::XpsPage(XpsFile *file, const QString &fileName) + : m_file(file) + , m_fileName(fileName) + , m_pageIsRendered(false) +{ + m_pageImage = nullptr; + + // qCWarning(OkularXpsDebug) << "page file name: " << fileName; + + const KZipFileEntry *pageFile = static_cast(m_file->xpsArchive()->directory()->entry(fileName)); + + QXmlStreamReader xml; + xml.addData(readFileOrDirectoryParts(pageFile)); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && (xml.name() == QStringLiteral("FixedPage"))) { + QXmlStreamAttributes attributes = xml.attributes(); + m_pageSize.setWidth(attributes.value(QStringLiteral("Width")).toString().toDouble()); + m_pageSize.setHeight(attributes.value(QStringLiteral("Height")).toString().toDouble()); + break; + } + } + if (xml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse XPS page:" << xml.errorString(); + } +} + +XpsPage::~XpsPage() +{ + delete m_pageImage; +} + +bool XpsPage::renderToImage(QImage *p) +{ + if ((m_pageImage == nullptr) || (m_pageImage->size() != p->size())) { + delete m_pageImage; + m_pageImage = new QImage(p->size(), QImage::Format_ARGB32); + // Set one point = one drawing unit. Useful for fonts, because xps specifies font size using drawing units, not points as usual + m_pageImage->setDotsPerMeterX(2835); + m_pageImage->setDotsPerMeterY(2835); + + m_pageIsRendered = false; + } + if (!m_pageIsRendered) { + m_pageImage->fill(qRgba(255, 255, 255, 255)); + QPainter painter(m_pageImage); + renderToPainter(&painter); + m_pageIsRendered = true; + } + + *p = *m_pageImage; + + return true; +} + +bool XpsPage::renderToPainter(QPainter *painter) +{ + XpsHandler handler(this); + handler.m_painter = painter; + handler.m_painter->setWorldTransform(QTransform().scale((qreal)painter->device()->width() / size().width(), (qreal)painter->device()->height() / size().height())); + QXmlSimpleReader parser; + parser.setContentHandler(&handler); + parser.setErrorHandler(&handler); + const KZipFileEntry *pageFile = static_cast(m_file->xpsArchive()->directory()->entry(m_fileName)); + QByteArray data = readFileOrDirectoryParts(pageFile); + QBuffer buffer(&data); + QXmlInputSource source(&buffer); + bool ok = parser.parse(source); + qCWarning(OkularXpsDebug) << "Parse result: " << ok; + + return true; +} + +QSizeF XpsPage::size() const +{ + return m_pageSize; +} + +QFont XpsFile::getFontByName(const QString &absoluteFileName, float size) +{ + // qCWarning(OkularXpsDebug) << "trying to get font: " << fileName << ", size: " << size; + + int index = m_fontCache.value(absoluteFileName, -1); + if (index == -1) { + index = loadFontByName(absoluteFileName); + m_fontCache[absoluteFileName] = index; + } + if (index == -1) { + qCWarning(OkularXpsDebug) << "Requesting unknown font:" << absoluteFileName; + return QFont(); + } + + const QStringList fontFamilies = m_fontDatabase.applicationFontFamilies(index); + if (fontFamilies.isEmpty()) { + qCWarning(OkularXpsDebug) << "The unexpected has happened. No font family for a known font:" << absoluteFileName << index; + return QFont(); + } + const QString fontFamily = fontFamilies[0]; + const QStringList fontStyles = m_fontDatabase.styles(fontFamily); + if (fontStyles.isEmpty()) { + qCWarning(OkularXpsDebug) << "The unexpected has happened. No font style for a known font family:" << absoluteFileName << index << fontFamily; + return QFont(); + } + const QString fontStyle = fontStyles[0]; + return m_fontDatabase.font(fontFamily, fontStyle, qRound(size)); +} + +int XpsFile::loadFontByName(const QString &absoluteFileName) +{ + // qCWarning(OkularXpsDebug) << "font file name: " << absoluteFileName; + + const KArchiveEntry *fontFile = loadEntry(m_xpsArchive, absoluteFileName, Qt::CaseInsensitive); + if (!fontFile) { + return -1; + } + + QByteArray fontData = readFileOrDirectoryParts(fontFile); // once per file, according to the docs + + int result = m_fontDatabase.addApplicationFontFromData(fontData); + if (-1 == result) { + // Try to deobfuscate font + // TODO Use deobfuscation depending on font content type, don't do it always when standard loading fails + + const QString baseName = resourceName(absoluteFileName); + + unsigned short guid[16]; + if (!parseGUID(baseName, guid)) { + qCWarning(OkularXpsDebug) << "File to load font - file name isn't a GUID"; + } else { + if (fontData.length() < 32) { + qCWarning(OkularXpsDebug) << "Font file is too small"; + } else { + // Obfuscation - xor bytes in font binary with bytes from guid (font's filename) + const static int mapping[] = {15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3}; + for (int i = 0; i < 16; i++) { + fontData[i] = fontData[i] ^ guid[mapping[i]]; + fontData[i + 16] = fontData[i + 16] ^ guid[mapping[i]]; + } + result = m_fontDatabase.addApplicationFontFromData(fontData); + } + } + } + + // qCWarning(OkularXpsDebug) << "Loaded font: " << m_fontDatabase.applicationFontFamilies( result ); + + return result; // a font ID +} + +KZip *XpsFile::xpsArchive() +{ + return m_xpsArchive; +} + +QImage XpsPage::loadImageFromFile(const QString &fileName) +{ + // qCWarning(OkularXpsDebug) << "image file name: " << fileName; + + if (fileName.at(0) == QLatin1Char('{')) { + // for example: '{ColorConvertedBitmap /Resources/bla.wdp /Resources/foobar.icc}' + // TODO: properly read a ColorConvertedBitmap + return QImage(); + } + + QString absoluteFileName = absolutePath(entryPath(m_fileName), fileName); + const KZipFileEntry *imageFile = loadFile(m_file->xpsArchive(), absoluteFileName, Qt::CaseInsensitive); + if (!imageFile) { + // image not found + return QImage(); + } + + /* WORKAROUND: + XPS standard requires to use 96dpi for images which doesn't have dpi specified (in file). When Qt loads such an image, + it sets its dpi to qt_defaultDpi and doesn't allow to find out that it happend. + + To workaround this I used this procedure: load image, set its dpi to 96, load image again. When dpi isn't set in file, + dpi set by me stays unchanged. + + Trolltech task ID: 159527. + + */ + + QImage image; + QByteArray data = imageFile->data(); + + QBuffer buffer(&data); + buffer.open(QBuffer::ReadOnly); + + QImageReader reader(&buffer); + image = reader.read(); + + image.setDotsPerMeterX(qRound(96 / 0.0254)); + image.setDotsPerMeterY(qRound(96 / 0.0254)); + + buffer.seek(0); + reader.setDevice(&buffer); + reader.read(&image); + + return image; +} + +Okular::TextPage *XpsPage::textPage() +{ + // qCWarning(OkularXpsDebug) << "Parsing XpsPage, text extraction"; + + Okular::TextPage *textPage = new Okular::TextPage(); + + const KZipFileEntry *pageFile = static_cast(m_file->xpsArchive()->directory()->entry(m_fileName)); + QXmlStreamReader xml; + xml.addData(readFileOrDirectoryParts(pageFile)); + + QTransform matrix = QTransform(); + QStack matrices; + matrices.push(QTransform()); + bool useMatrix = false; + QXmlStreamAttributes glyphsAtts; + + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement()) { + if (xml.name() == QStringLiteral("Canvas")) { + matrices.push(matrix); + + QString att = xml.attributes().value(QStringLiteral("RenderTransform")).toString(); + if (!att.isEmpty()) { + matrix = parseRscRefMatrix(att) * matrix; + } + } else if ((xml.name() == QStringLiteral("Canvas.RenderTransform")) || (xml.name() == QStringLiteral("Glyphs.RenderTransform"))) { + useMatrix = true; + } else if (xml.name() == QStringLiteral("MatrixTransform")) { + if (useMatrix) { + matrix = attsToMatrix(xml.attributes().value(QStringLiteral("Matrix")).toString()) * matrix; + } + } else if (xml.name() == QStringLiteral("Glyphs")) { + matrices.push(matrix); + glyphsAtts = xml.attributes(); + } else if ((xml.name() == QStringLiteral("Path")) || (xml.name() == QStringLiteral("Path.Fill")) || (xml.name() == QStringLiteral("SolidColorBrush")) || (xml.name() == QStringLiteral("ImageBrush")) || + (xml.name() == QStringLiteral("ImageBrush.Transform")) || (xml.name() == QStringLiteral("Path.OpacityMask")) || (xml.name() == QStringLiteral("Path.Data")) || (xml.name() == QStringLiteral("PathGeometry")) || + (xml.name() == QStringLiteral("PathFigure")) || (xml.name() == QStringLiteral("PolyLineSegment"))) { + // those are only graphical - no use in text handling + } else if ((xml.name() == QStringLiteral("FixedPage")) || (xml.name() == QStringLiteral("FixedPage.Resources"))) { + // not useful for text extraction + } else { + qCWarning(OkularXpsDebug) << "Unhandled element in Text Extraction start: " << xml.name().toString(); + } + } else if (xml.isEndElement()) { + if (xml.name() == QStringLiteral("Canvas")) { + matrix = matrices.pop(); + } else if ((xml.name() == QStringLiteral("Canvas.RenderTransform")) || (xml.name() == QStringLiteral("Glyphs.RenderTransform"))) { + useMatrix = false; + } else if (xml.name() == QStringLiteral("MatrixTransform")) { + // not clear if we need to do anything here yet. + } else if (xml.name() == QStringLiteral("Glyphs")) { + QString att = glyphsAtts.value(QStringLiteral("RenderTransform")).toString(); + if (!att.isEmpty()) { + matrix = parseRscRefMatrix(att) * matrix; + } + QString text = unicodeString(glyphsAtts.value(QStringLiteral("UnicodeString")).toString()); + + // Get font (doesn't work well because qt doesn't allow to load font from file) + const QString absoluteFileName = absolutePath(entryPath(m_fileName), glyphsAtts.value(QStringLiteral("FontUri")).toString()); + QFont font = m_file->getFontByName(absoluteFileName, glyphsAtts.value(QStringLiteral("FontRenderingEmSize")).toString().toFloat() * 72 / 96); + QFontMetrics metrics = QFontMetrics(font); + // Origin + QPointF origin(glyphsAtts.value(QStringLiteral("OriginX")).toString().toDouble(), glyphsAtts.value(QStringLiteral("OriginY")).toString().toDouble()); + + int lastWidth = 0; + for (int i = 0; i < text.length(); i++) { + const int width = metrics.horizontalAdvance(text, i + 1); + + Okular::NormalizedRect *rect = + new Okular::NormalizedRect((origin.x() + lastWidth) / m_pageSize.width(), (origin.y() - metrics.height()) / m_pageSize.height(), (origin.x() + width) / m_pageSize.width(), origin.y() / m_pageSize.height()); + rect->transform(matrix); + textPage->append(text.mid(i, 1), rect); + + lastWidth = width; + } + + matrix = matrices.pop(); + } else if ((xml.name() == QStringLiteral("Path")) || (xml.name() == QStringLiteral("Path.Fill")) || (xml.name() == QStringLiteral("SolidColorBrush")) || (xml.name() == QStringLiteral("ImageBrush")) || + (xml.name() == QStringLiteral("ImageBrush.Transform")) || (xml.name() == QStringLiteral("Path.OpacityMask")) || (xml.name() == QStringLiteral("Path.Data")) || (xml.name() == QStringLiteral("PathGeometry")) || + (xml.name() == QStringLiteral("PathFigure")) || (xml.name() == QStringLiteral("PolyLineSegment"))) { + // those are only graphical - no use in text handling + } else if ((xml.name() == QStringLiteral("FixedPage")) || (xml.name() == QStringLiteral("FixedPage.Resources"))) { + // not useful for text extraction + } else { + qCWarning(OkularXpsDebug) << "Unhandled element in Text Extraction end: " << xml.name().toString(); + } + } + } + if (xml.error()) { + qCWarning(OkularXpsDebug) << "Error parsing XpsPage text: " << xml.errorString(); + } + return textPage; +} + +void XpsDocument::parseDocumentStructure(const QString &documentStructureFileName) +{ + qCWarning(OkularXpsDebug) << "document structure file name: " << documentStructureFileName; + m_haveDocumentStructure = false; + + const KZipFileEntry *documentStructureFile = static_cast(m_file->xpsArchive()->directory()->entry(documentStructureFileName)); + + QXmlStreamReader xml; + xml.addData(documentStructureFile->data()); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.isStartElement()) { + if (xml.name() == QStringLiteral("DocumentStructure")) { + // just a container for optional outline and story elements - nothing to do here + } else if (xml.name() == QStringLiteral("DocumentStructure.Outline")) { + qCWarning(OkularXpsDebug) << "found DocumentStructure.Outline"; + } else if (xml.name() == QStringLiteral("DocumentOutline")) { + qCWarning(OkularXpsDebug) << "found DocumentOutline"; + m_docStructure = new Okular::DocumentSynopsis; + } else if (xml.name() == QStringLiteral("OutlineEntry")) { + m_haveDocumentStructure = true; + QXmlStreamAttributes attributes = xml.attributes(); + int outlineLevel = attributes.value(QStringLiteral("OutlineLevel")).toString().toInt(); + QString description = attributes.value(QStringLiteral("Description")).toString(); + QDomElement synopsisElement = m_docStructure->createElement(description); + synopsisElement.setAttribute(QStringLiteral("OutlineLevel"), outlineLevel); + QString target = attributes.value(QStringLiteral("OutlineTarget")).toString(); + int hashPosition = target.lastIndexOf(QLatin1Char('#')); + target = target.mid(hashPosition + 1); + // qCWarning(OkularXpsDebug) << "target: " << target; + Okular::DocumentViewport viewport; + viewport.pageNumber = m_docStructurePageMap.value(target); + synopsisElement.setAttribute(QStringLiteral("Viewport"), viewport.toString()); + if (outlineLevel == 1) { + // qCWarning(OkularXpsDebug) << "Description: " + // << outlineEntryElement.attribute( "Description" ); + m_docStructure->appendChild(synopsisElement); + } else { + // find the last next highest element (so it this is level 3, we need + // to find the most recent level 2 node) + QDomNode maybeParentNode = m_docStructure->lastChild(); + while (!maybeParentNode.isNull()) { + if (maybeParentNode.toElement().attribute(QStringLiteral("OutlineLevel")).toInt() == (outlineLevel - 1)) { + // we have the right parent + maybeParentNode.appendChild(synopsisElement); + break; + } + maybeParentNode = maybeParentNode.lastChild(); + } + } + } else if (xml.name() == QStringLiteral("Story")) { + // we need to handle Story here, but I have no idea what to do with it. + } else if (xml.name() == QStringLiteral("StoryFragment")) { + // we need to handle StoryFragment here, but I have no idea what to do with it. + } else if (xml.name() == QStringLiteral("StoryFragmentReference")) { + // we need to handle StoryFragmentReference here, but I have no idea what to do with it. + } else { + qCWarning(OkularXpsDebug) << "Unhandled entry in DocumentStructure: " << xml.name().toString(); + } + } + } +} + +const Okular::DocumentSynopsis *XpsDocument::documentStructure() +{ + return m_docStructure; +} + +bool XpsDocument::hasDocumentStructure() +{ + return m_haveDocumentStructure; +} + +XpsDocument::XpsDocument(XpsFile *file, const QString &fileName) + : m_file(file) + , m_haveDocumentStructure(false) + , m_docStructure(nullptr) +{ + qCWarning(OkularXpsDebug) << "document file name: " << fileName; + + const KArchiveEntry *documentEntry = file->xpsArchive()->directory()->entry(fileName); + QString documentFilePath = fileName; + const QString documentEntryPath = entryPath(fileName); + + QXmlStreamReader docXml; + docXml.addData(readFileOrDirectoryParts(documentEntry, &documentFilePath)); + while (!docXml.atEnd()) { + docXml.readNext(); + if (docXml.isStartElement()) { + if (docXml.name() == QStringLiteral("PageContent")) { + QString pagePath = docXml.attributes().value(QStringLiteral("Source")).toString(); + qCWarning(OkularXpsDebug) << "Page Path: " << pagePath; + XpsPage *page = new XpsPage(file, absolutePath(documentFilePath, pagePath)); + m_pages.append(page); + } else if (docXml.name() == QStringLiteral("PageContent.LinkTargets")) { + // do nothing - wait for the real LinkTarget elements + } else if (docXml.name() == QStringLiteral("LinkTarget")) { + QString targetName = docXml.attributes().value(QStringLiteral("Name")).toString(); + if (!targetName.isEmpty()) { + m_docStructurePageMap[targetName] = m_pages.count() - 1; + } + } else if (docXml.name() == QStringLiteral("FixedDocument")) { + // we just ignore this - it is just a container + } else { + qCWarning(OkularXpsDebug) << "Unhandled entry in FixedDocument: " << docXml.name().toString(); + } + } + } + if (docXml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse main XPS document file: " << docXml.errorString(); + } + + // There might be a relationships entry for this document - typically used to tell us where to find the + // content structure description + + // We should be able to find this using a reference from some other part of the document, but I can't see it. + const int slashPosition = fileName.lastIndexOf(QLatin1Char('/')); + const QString documentRelationshipFile = absolutePath(documentEntryPath, QStringLiteral("_rels/") + fileName.mid(slashPosition + 1) + QStringLiteral(".rels")); + + const KZipFileEntry *relFile = static_cast(file->xpsArchive()->directory()->entry(documentRelationshipFile)); + + QString documentStructureFile; + if (relFile) { + QXmlStreamReader xml; + xml.addData(readFileOrDirectoryParts(relFile)); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && (xml.name() == QStringLiteral("Relationship"))) { + QXmlStreamAttributes attributes = xml.attributes(); + if (attributes.value(QStringLiteral("Type")).toString() == QLatin1String("http://schemas.microsoft.com/xps/2005/06/documentstructure")) { + documentStructureFile = attributes.value(QStringLiteral("Target")).toString(); + } else { + qCWarning(OkularXpsDebug) << "Unknown document relationships element: " << attributes.value(QStringLiteral("Type")).toString() << " : " << attributes.value(QStringLiteral("Target")).toString(); + } + } + } + if (xml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse XPS page relationships file ( " << documentRelationshipFile << " ) - " << xml.errorString(); + } + } else { // the page relationship file didn't exist in the zipfile + // this isn't fatal + qCWarning(OkularXpsDebug) << "Could not open Document relationship file from " << documentRelationshipFile; + } + + if (!documentStructureFile.isEmpty()) { + // qCWarning(OkularXpsDebug) << "Document structure filename: " << documentStructureFile; + // make the document path absolute + documentStructureFile = absolutePath(documentEntryPath, documentStructureFile); + // qCWarning(OkularXpsDebug) << "Document structure absolute path: " << documentStructureFile; + parseDocumentStructure(documentStructureFile); + } +} + +XpsDocument::~XpsDocument() +{ + qDeleteAll(m_pages); + m_pages.clear(); + + if (m_docStructure) + delete m_docStructure; +} + +int XpsDocument::numPages() const +{ + return m_pages.size(); +} + +XpsPage *XpsDocument::page(int pageNum) const +{ + return m_pages.at(pageNum); +} + +XpsFile::XpsFile() +{ +} + +XpsFile::~XpsFile() +{ + for (int fontId : qAsConst(m_fontCache)) { + m_fontDatabase.removeApplicationFont(fontId); + } +} + +bool XpsFile::loadDocument(const QString &filename) +{ + m_xpsArchive = new KZip(filename); + if (m_xpsArchive->open(QIODevice::ReadOnly) == true) { + qCWarning(OkularXpsDebug) << "Successful open of " << m_xpsArchive->fileName(); + } else { + qCWarning(OkularXpsDebug) << "Could not open XPS archive: " << m_xpsArchive->fileName(); + delete m_xpsArchive; + return false; + } + + // The only fixed entry in XPS is /_rels/.rels + const KArchiveEntry *relEntry = m_xpsArchive->directory()->entry(QStringLiteral("_rels/.rels")); + if (!relEntry) { + // this might occur if we can't read the zip directory, or it doesn't have the relationships entry + return false; + } + + QXmlStreamReader relXml; + relXml.addData(readFileOrDirectoryParts(relEntry)); + + QString fixedRepresentationFileName; + // We work through the relationships document and pull out each element. + while (!relXml.atEnd()) { + relXml.readNext(); + if (relXml.isStartElement()) { + if (relXml.name() == QStringLiteral("Relationship")) { + QXmlStreamAttributes attributes = relXml.attributes(); + QString type = attributes.value(QStringLiteral("Type")).toString(); + QString target = attributes.value(QStringLiteral("Target")).toString(); + if (QStringLiteral("http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail") == type) { + m_thumbnailFileName = target; + } else if (QStringLiteral("http://schemas.microsoft.com/xps/2005/06/fixedrepresentation") == type) { + fixedRepresentationFileName = target; + } else if (QStringLiteral("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties") == type) { + m_corePropertiesFileName = target; + } else if (QStringLiteral("http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin") == type) { + m_signatureOrigin = target; + } else { + qCWarning(OkularXpsDebug) << "Unknown relationships element: " << type << " : " << target; + } + } else if (relXml.name() == QStringLiteral("Relationships")) { + // nothing to do here - this is just the container level + } else { + qCWarning(OkularXpsDebug) << "unexpected element in _rels/.rels: " << relXml.name().toString(); + } + } + } + if (relXml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse _rels/.rels: " << relXml.errorString(); + return false; + } + + if (fixedRepresentationFileName.isEmpty()) { + // FixedRepresentation is a required part of the XPS document + return false; + } + + const KArchiveEntry *fixedRepEntry = m_xpsArchive->directory()->entry(fixedRepresentationFileName); + QString fixedRepresentationFilePath = fixedRepresentationFileName; + + QXmlStreamReader fixedRepXml; + fixedRepXml.addData(readFileOrDirectoryParts(fixedRepEntry, &fixedRepresentationFileName)); + + while (!fixedRepXml.atEnd()) { + fixedRepXml.readNext(); + if (fixedRepXml.isStartElement()) { + if (fixedRepXml.name() == QStringLiteral("DocumentReference")) { + const QString source = fixedRepXml.attributes().value(QStringLiteral("Source")).toString(); + XpsDocument *doc = new XpsDocument(this, absolutePath(fixedRepresentationFilePath, source)); + for (int lv = 0; lv < doc->numPages(); ++lv) { + // our own copy of the pages list + m_pages.append(doc->page(lv)); + } + m_documents.append(doc); + } else if (fixedRepXml.name() == QStringLiteral("FixedDocumentSequence")) { + // we don't do anything here - this is just a container for one or more DocumentReference elements + } else { + qCWarning(OkularXpsDebug) << "Unhandled entry in FixedDocumentSequence: " << fixedRepXml.name().toString(); + } + } + } + if (fixedRepXml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse FixedRepresentation file:" << fixedRepXml.errorString(); + return false; + } + + return true; +} + +Okular::DocumentInfo XpsFile::generateDocumentInfo() const +{ + Okular::DocumentInfo docInfo; + + docInfo.set(Okular::DocumentInfo::MimeType, QStringLiteral("application/oxps")); + + if (!m_corePropertiesFileName.isEmpty()) { + const KZipFileEntry *corepropsFile = static_cast(m_xpsArchive->directory()->entry(m_corePropertiesFileName)); + + QXmlStreamReader xml; + xml.addData(corepropsFile->data()); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isEndElement()) + break; + if (xml.isStartElement()) { + if (xml.name() == QStringLiteral("title")) { + docInfo.set(Okular::DocumentInfo::Title, xml.readElementText()); + } else if (xml.name() == QStringLiteral("subject")) { + docInfo.set(Okular::DocumentInfo::Subject, xml.readElementText()); + } else if (xml.name() == QStringLiteral("description")) { + docInfo.set(Okular::DocumentInfo::Description, xml.readElementText()); + } else if (xml.name() == QStringLiteral("creator")) { + docInfo.set(Okular::DocumentInfo::Creator, xml.readElementText()); + } else if (xml.name() == QStringLiteral("category")) { + docInfo.set(Okular::DocumentInfo::Category, xml.readElementText()); + } else if (xml.name() == QStringLiteral("created")) { + QDateTime createdDate = QDateTime::fromString(xml.readElementText(), QStringLiteral("yyyy-MM-ddThh:mm:ssZ")); + docInfo.set(Okular::DocumentInfo::CreationDate, QLocale().toString(createdDate, QLocale::LongFormat)); + } else if (xml.name() == QStringLiteral("modified")) { + QDateTime modifiedDate = QDateTime::fromString(xml.readElementText(), QStringLiteral("yyyy-MM-ddThh:mm:ssZ")); + docInfo.set(Okular::DocumentInfo::ModificationDate, QLocale().toString(modifiedDate, QLocale::LongFormat)); + } else if (xml.name() == QStringLiteral("keywords")) { + docInfo.set(Okular::DocumentInfo::Keywords, xml.readElementText()); + } else if (xml.name() == QStringLiteral("revision")) { + docInfo.set(QStringLiteral("revision"), xml.readElementText(), i18n("Revision")); + } + } + } + if (xml.error()) { + qCWarning(OkularXpsDebug) << "Could not parse XPS core properties:" << xml.errorString(); + } + } else { + qCWarning(OkularXpsDebug) << "No core properties filename"; + } + + docInfo.set(Okular::DocumentInfo::Pages, QString::number(numPages())); + + return docInfo; +} + +bool XpsFile::closeDocument() +{ + qDeleteAll(m_documents); + m_documents.clear(); + + delete m_xpsArchive; + + return true; +} + +int XpsFile::numPages() const +{ + return m_pages.size(); +} + +int XpsFile::numDocuments() const +{ + return m_documents.size(); +} + +XpsDocument *XpsFile::document(int documentNum) const +{ + return m_documents.at(documentNum); +} + +XpsPage *XpsFile::page(int pageNum) const +{ + return m_pages.at(pageNum); +} + +XpsGenerator::XpsGenerator(QObject *parent, const QVariantList &args) + : Okular::Generator(parent, args) + , m_xpsFile(nullptr) +{ + setFeature(TextExtraction); + setFeature(PrintNative); + setFeature(PrintToFile); + setFeature(Threaded); + userMutex(); +} + +XpsGenerator::~XpsGenerator() +{ +} + +bool XpsGenerator::loadDocument(const QString &fileName, QVector &pagesVector) +{ + m_xpsFile = new XpsFile(); + + m_xpsFile->loadDocument(fileName); + pagesVector.resize(m_xpsFile->numPages()); + + int pagesVectorOffset = 0; + + for (int docNum = 0; docNum < m_xpsFile->numDocuments(); ++docNum) { + XpsDocument *doc = m_xpsFile->document(docNum); + for (int pageNum = 0; pageNum < doc->numPages(); ++pageNum) { + QSizeF pageSize = doc->page(pageNum)->size(); + pagesVector[pagesVectorOffset] = new Okular::Page(pagesVectorOffset, pageSize.width(), pageSize.height(), Okular::Rotation0); + ++pagesVectorOffset; + } + } + + return true; +} + +bool XpsGenerator::doCloseDocument() +{ + m_xpsFile->closeDocument(); + delete m_xpsFile; + m_xpsFile = nullptr; + + return true; +} + +QImage XpsGenerator::image(Okular::PixmapRequest *request) +{ + QMutexLocker lock(userMutex()); + QSize size((int)request->width(), (int)request->height()); + QImage image(size, QImage::Format_RGB32); + XpsPage *pageToRender = m_xpsFile->page(request->page()->number()); + pageToRender->renderToImage(&image); + return image; +} + +Okular::TextPage *XpsGenerator::textPage(Okular::TextRequest *request) +{ + QMutexLocker lock(userMutex()); + XpsPage *xpsPage = m_xpsFile->page(request->page()->number()); + return xpsPage->textPage(); +} + +Okular::DocumentInfo XpsGenerator::generateDocumentInfo(const QSet &keys) const +{ + Q_UNUSED(keys); + + qCWarning(OkularXpsDebug) << "generating document metadata"; + + return m_xpsFile->generateDocumentInfo(); +} + +const Okular::DocumentSynopsis *XpsGenerator::generateDocumentSynopsis() +{ + qCWarning(OkularXpsDebug) << "generating document synopsis"; + + // we only generate the synopsis for the first file. + if (!m_xpsFile || !m_xpsFile->document(0)) + return nullptr; + + if (m_xpsFile->document(0)->hasDocumentStructure()) + return m_xpsFile->document(0)->documentStructure(); + + return nullptr; +} + +Okular::ExportFormat::List XpsGenerator::exportFormats() const +{ + static Okular::ExportFormat::List formats; + if (formats.isEmpty()) { + formats.append(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText)); + } + return formats; +} + +bool XpsGenerator::exportTo(const QString &fileName, const Okular::ExportFormat &format) +{ + if (format.mimeType().inherits(QStringLiteral("text/plain"))) { + QFile f(fileName); + if (!f.open(QIODevice::WriteOnly)) + return false; + + QTextStream ts(&f); + for (int i = 0; i < m_xpsFile->numPages(); ++i) { + Okular::TextPage *textPage = m_xpsFile->page(i)->textPage(); + QString text = textPage->text(); + ts << text; + ts << QLatin1Char('\n'); + delete textPage; + } + f.close(); + + return true; + } + + return false; +} + +bool XpsGenerator::print(QPrinter &printer) +{ + QList pageList = Okular::FilePrinter::pageList(printer, document()->pages(), document()->currentPage() + 1, document()->bookmarkedPageList()); + + QPainter painter(&printer); + + for (int i = 0; i < pageList.count(); ++i) { + if (i != 0) + printer.newPage(); + + const int page = pageList.at(i) - 1; + XpsPage *pageToRender = m_xpsFile->page(page); + pageToRender->renderToPainter(&painter); + } + + return true; +} + +const XpsRenderNode *XpsRenderNode::findChild(const QString &name) const +{ + for (const XpsRenderNode &child : children) { + if (child.name == name) { + return &child; + } + } + + return nullptr; +} + +QVariant XpsRenderNode::getRequiredChildData(const QString &name) const +{ + const XpsRenderNode *child = findChild(name); + if (child == nullptr) { + qCWarning(OkularXpsDebug) << "Required element " << name << " is missing in " << this->name; + return QVariant(); + } + + return child->data; +} + +QVariant XpsRenderNode::getChildData(const QString &name) const +{ + const XpsRenderNode *child = findChild(name); + if (child == nullptr) { + return QVariant(); + } else { + return child->data; + } +} + +Q_LOGGING_CATEGORY(OkularXpsDebug, "org.kde.okular.generators.xps", QtWarningMsg) + +#include "generator_xps.moc" diff --git a/generators/xps/generator_xps.h b/generators/xps/generator_xps.h new file mode 100644 index 0000000..f07ef5a --- /dev/null +++ b/generators/xps/generator_xps.h @@ -0,0 +1,341 @@ +/* + Copyright (C) 2006 Brad Hards + + 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 + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef _OKULAR_GENERATOR_XPS_H_ +#define _OKULAR_GENERATOR_XPS_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef enum { abtCommand, abtNumber, abtComma, abtEOF } AbbPathTokenType; + +class AbbPathToken +{ +public: + QString data; + int curPos; + + AbbPathTokenType type; + char command; + double number; +}; + +/** + Holds information about xml element during SAX parsing of page +*/ +class XpsRenderNode +{ +public: + QString name; + QVector children; + QXmlAttributes attributes; + QVariant data; + + const XpsRenderNode *findChild(const QString &name) const; + QVariant getRequiredChildData(const QString &name) const; + QVariant getChildData(const QString &name) const; +}; + +struct XpsGradient { + XpsGradient(double o, const QColor &c) + : offset(o) + , color(c) + { + } + + double offset; + QColor color; +}; + +/** + Types of data in XpsRenderNode::data. Name of each type consist of Xps and + name of xml element which data it holds +*/ +typedef QTransform XpsMatrixTransform; +typedef QTransform XpsRenderTransform; +typedef QBrush XpsFill; +struct XpsPathFigure { + XpsPathFigure(const QPainterPath &_path, bool filled) + : path(_path) + , isFilled(filled) + { + } + + QPainterPath path; + bool isFilled; +}; +struct XpsPathGeometry { + XpsPathGeometry() + : fillRule(Qt::OddEvenFill) + { + } + ~XpsPathGeometry() + { + qDeleteAll(paths); + } + + XpsPathGeometry(const XpsPathGeometry &) = delete; + XpsPathGeometry &operator=(const XpsPathGeometry &) = delete; + + QList paths; + Qt::FillRule fillRule; + XpsMatrixTransform transform; +}; + +class XpsPage; +class XpsFile; + +class XpsHandler : public QXmlDefaultHandler +{ +public: + explicit XpsHandler(XpsPage *page); + ~XpsHandler() override; + + bool startElement(const QString &nameSpace, const QString &localName, const QString &qname, const QXmlAttributes &atts) override; + bool endElement(const QString &nameSpace, const QString &localName, const QString &qname) override; + bool startDocument() override; + +protected: + XpsPage *m_page; + + void processStartElement(XpsRenderNode &node); + void processEndElement(XpsRenderNode &node); + + // Methods for processing of different xml elements + void processGlyph(XpsRenderNode &node); + void processPath(XpsRenderNode &node); + void processPathData(XpsRenderNode &node); + void processFill(XpsRenderNode &node); + void processStroke(XpsRenderNode &node); + void processImageBrush(XpsRenderNode &node); + void processPathGeometry(XpsRenderNode &node); + void processPathFigure(XpsRenderNode &node); + + QPainter *m_painter; + + QImage m_image; + + QStack m_nodes; + + friend class XpsPage; +}; + +class XpsPage +{ +public: + XpsPage(XpsFile *file, const QString &fileName); + ~XpsPage(); + + XpsPage(const XpsPage &) = delete; + XpsPage &operator=(const XpsPage &) = delete; + + QSizeF size() const; + bool renderToImage(QImage *p); + bool renderToPainter(QPainter *painter); + Okular::TextPage *textPage(); + + QImage loadImageFromFile(const QString &filename); + QString fileName() const + { + return m_fileName; + } + +private: + XpsFile *m_file; + const QString m_fileName; + + QSizeF m_pageSize; + + QString m_thumbnailFileName; + bool m_thumbnailMightBeAvailable; + QImage m_thumbnail; + bool m_thumbnailIsLoaded; + + QImage *m_pageImage; + bool m_pageIsRendered; + + friend class XpsHandler; + friend class XpsTextExtractionHandler; +}; + +/** + Represents one of the (perhaps the only) documents in an XpsFile +*/ +class XpsDocument +{ +public: + XpsDocument(XpsFile *file, const QString &fileName); + ~XpsDocument(); + + XpsDocument(const XpsDocument &) = delete; + XpsDocument &operator=(const XpsDocument &) = delete; + + /** + the total number of pages in this document + */ + int numPages() const; + + /** + obtain a certain page from this document + + \param pageNum the number of the page to return + + \note page numbers are zero based - they run from 0 to + numPages() - 1 + */ + XpsPage *page(int pageNum) const; + + /** + whether this document has a Document Structure + */ + bool hasDocumentStructure(); + + /** + the document structure for this document, if available + */ + const Okular::DocumentSynopsis *documentStructure(); + +private: + void parseDocumentStructure(const QString &documentStructureFileName); + + QList m_pages; + XpsFile *m_file; + bool m_haveDocumentStructure; + Okular::DocumentSynopsis *m_docStructure; + QMap m_docStructurePageMap; +}; + +/** + Represents the contents of a Microsoft XML Paper Specification + format document. +*/ +class XpsFile +{ +public: + XpsFile(); + ~XpsFile(); + + XpsFile(const XpsFile &) = delete; + XpsFile &operator=(const XpsFile &) = delete; + + bool loadDocument(const QString &fileName); + bool closeDocument(); + + Okular::DocumentInfo generateDocumentInfo() const; + + QImage thumbnail(); + + /** + the total number of XpsDocuments with this file + */ + int numDocuments() const; + + /** + the total number of pages in all the XpsDocuments within this + file + */ + int numPages() const; + + /** + a page from the file + + \param pageNum the page number of the page to return + + \note page numbers are zero based - they run from 0 to + numPages() - 1 + */ + XpsPage *page(int pageNum) const; + + /** + obtain a certain document from this file + + \param documentNum the number of the document to return + + \note document numbers are zero based - they run from 0 to + numDocuments() - 1 + */ + XpsDocument *document(int documentNum) const; + + QFont getFontByName(const QString &absoluteFileName, float size); + + KZip *xpsArchive(); + +private: + int loadFontByName(const QString &absoluteFileName); + + QList m_documents; + QList m_pages; + + QString m_thumbnailFileName; + bool m_thumbnailMightBeAvailable; + QImage m_thumbnail; + bool m_thumbnailIsLoaded; + + QString m_corePropertiesFileName; + + QString m_signatureOrigin; + + KZip *m_xpsArchive; + + QMap m_fontCache; + QFontDatabase m_fontDatabase; +}; + +class XpsGenerator : public Okular::Generator +{ + Q_OBJECT + Q_INTERFACES(Okular::Generator) +public: + XpsGenerator(QObject *parent, const QVariantList &args); + ~XpsGenerator() override; + + bool loadDocument(const QString &fileName, QVector &pagesVector) override; + + Okular::DocumentInfo generateDocumentInfo(const QSet &keys) const override; + const Okular::DocumentSynopsis *generateDocumentSynopsis() override; + + Okular::ExportFormat::List exportFormats() const override; + bool exportTo(const QString &fileName, const Okular::ExportFormat &format) override; + + bool print(QPrinter &printer) override; + +protected: + bool doCloseDocument() override; + QImage image(Okular::PixmapRequest *request) override; + Okular::TextPage *textPage(Okular::TextRequest *request) override; + +private: + XpsFile *m_xpsFile; +}; + +Q_DECLARE_LOGGING_CATEGORY(OkularXpsDebug) + +#endif diff --git a/generators/xps/libokularGenerator_xps.json b/generators/xps/libokularGenerator_xps.json new file mode 100644 index 0000000..57f5a3d --- /dev/null +++ b/generators/xps/libokularGenerator_xps.json @@ -0,0 +1,250 @@ +{ + "KPlugin": { + "Authors": [ + { + "Email": "bradh@frogmouth.net", + "Name": "Brad Hards", + "Name[az]": "Brad Hards", + "Name[ca@valencia]": "Brad Hards", + "Name[ca]": "Brad Hards", + "Name[cs]": "Brad Hards", + "Name[da]": "Brad Hards", + "Name[de]": "Brad Hards", + "Name[el]": "Brad Hards", + "Name[en_GB]": "Brad Hards", + "Name[es]": "Brad Hards", + "Name[et]": "Brad Hards", + "Name[eu]": "Brad Hards", + "Name[fi]": "Brad Hards", + "Name[fr]": "Brad Hards", + "Name[gl]": "Brad Hards", + "Name[ia]": "Brad Hards", + "Name[it]": "Brad Hards", + "Name[ko]": "Brad Hards", + "Name[lt]": "Brad Hards", + "Name[nl]": "Brad Hards", + "Name[nn]": "Brad Hards", + "Name[pl]": "Brad Hards", + "Name[pt]": "Brad Hards", + "Name[pt_BR]": "Brad Hards", + "Name[ru]": "Brad Hards", + "Name[sk]": "Brad Hards", + "Name[sl]": "Brad Hards", + "Name[sr@ijekavian]": "Бред Хардс", + "Name[sr@ijekavianlatin]": "Bred Hards", + "Name[sr@latin]": "Bred Hards", + "Name[sr]": "Бред Хардс", + "Name[sv]": "Brad Hards", + "Name[tr]": "Brad Hards", + "Name[uk]": "Brad Hards", + "Name[x-test]": "xxBrad Hardsxx", + "Name[zh_CN]": "Brad Hards", + "Name[zh_TW]": "Brad Hards" + }, + { + "Email": "jiri.klement@gmail.com", + "Name": "Jiri Klement", + "Name[az]": "Jiri Klement", + "Name[ca@valencia]": "Jiri Klement", + "Name[ca]": "Jiri Klement", + "Name[cs]": "Jiří Klement", + "Name[da]": "Jiri Klement", + "Name[de]": "Jiri Klement", + "Name[el]": "Jiri Klement", + "Name[en_GB]": "Jiri Klement", + "Name[es]": "Jiri Klement", + "Name[et]": "Jiri Klement", + "Name[eu]": "Jiri Klement", + "Name[fi]": "Jiri Klement", + "Name[fr]": "Jiri Klement", + "Name[gl]": "Jiri Klement", + "Name[ia]": "Jiri Klement", + "Name[it]": "Jiri Klement", + "Name[ko]": "Jiri Klement", + "Name[lt]": "Jiri Klement", + "Name[nl]": "Jiri Klement", + "Name[nn]": "Jiri Klement", + "Name[pl]": "Jiri Klement", + "Name[pt]": "Jiri Klement", + "Name[pt_BR]": "Jiri Klement", + "Name[ru]": "Jiri Klement", + "Name[sk]": "Jiri Klement", + "Name[sl]": "Jiri Klement", + "Name[sr@ijekavian]": "Јиржи Клемент", + "Name[sr@ijekavianlatin]": "Jirži Klement", + "Name[sr@latin]": "Jirži Klement", + "Name[sr]": "Јиржи Клемент", + "Name[sv]": "Jiri Klement", + "Name[tr]": "Jiri Klement", + "Name[uk]": "Jiri Klement", + "Name[x-test]": "xxJiri Klementxx", + "Name[zh_CN]": "Jiri Klement", + "Name[zh_TW]": "Jiri Klement" + }, + { + "Email": "pino@kde.org", + "Name": "Pino Toscano", + "Name[az]": "Pino Toscano", + "Name[ca@valencia]": "Pino Toscano", + "Name[ca]": "Pino Toscano", + "Name[cs]": "Pino Toscano", + "Name[da]": "Pino Toscano", + "Name[de]": "Pino Toscano", + "Name[el]": "Pino Toscano", + "Name[en_GB]": "Pino Toscano", + "Name[es]": "Pino Toscano", + "Name[et]": "Pino Toscano", + "Name[eu]": "Pino Toscano", + "Name[fi]": "Pino Toscano", + "Name[fr]": "Pino Toscano", + "Name[gl]": "Pino Toscano", + "Name[ia]": "Pino Toscano", + "Name[it]": "Pino Toscano", + "Name[ko]": "Pino Toscano", + "Name[lt]": "Pino Toscano", + "Name[nl]": "Pino Toscano", + "Name[nn]": "Pino Toscano", + "Name[pl]": "Pino Toscano", + "Name[pt]": "Pino Toscano", + "Name[pt_BR]": "Pino Toscano", + "Name[ru]": "Pino Toscano", + "Name[sk]": "Pino Toscano", + "Name[sl]": "Pino Toscano", + "Name[sr@ijekavian]": "Пино Тоскано", + "Name[sr@ijekavianlatin]": "Pino Toskano", + "Name[sr@latin]": "Pino Toskano", + "Name[sr]": "Пино Тоскано", + "Name[sv]": "Pino Toscano", + "Name[tr]": "Pino Toscano", + "Name[uk]": "Pino Toscano", + "Name[x-test]": "xxPino Toscanoxx", + "Name[zh_CN]": "Pino Toscano", + "Name[zh_TW]": "Pino Toscano" + } + ], + "Copyright": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[az]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[ca@valencia]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[ca]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[cs]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[da]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[de]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[el]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[en_GB]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[es]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[et]": "© 2006-2007: Brad Hards\n© 2007: Jiri Klement\n© 2008: Pino Toscano", + "Copyright[eu]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[fi]": "© 2006–2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[fr]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[gl]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[ia]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[it]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[ko]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[lt]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[nl]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[nn]": "© 2006–2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[pl]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[pt]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[pt_BR]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[ru]": "© Brad Hards, 2006-2007\n© Jiri Klement, 2007\n© Pino Toscano, 2008", + "Copyright[sk]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[sl]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[sr@ijekavian]": "© 2006–2007, Бред Хардс\n© 2007, Јиржи Клемент\n© 2008, Пино Тоскано", + "Copyright[sr@ijekavianlatin]": "© 2006–2007, Bred Hards\n© 2007, Jirži Klement\n© 2008, Pino Toskano", + "Copyright[sr@latin]": "© 2006–2007, Bred Hards\n© 2007, Jirži Klement\n© 2008, Pino Toskano", + "Copyright[sr]": "© 2006–2007, Бред Хардс\n© 2007, Јиржи Клемент\n© 2008, Пино Тоскано", + "Copyright[sv]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[tr]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[uk]": "© Brad Hards, 2006–2007\n© Jiri Klement, 2007\n© Pino Toscano, 2008", + "Copyright[x-test]": "xx© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscanoxx", + "Copyright[zh_CN]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Copyright[zh_TW]": "© 2006-2007 Brad Hards\n© 2007 Jiri Klement\n© 2008 Pino Toscano", + "Description": "An XPS backend", + "Description[az]": "XPS modulu", + "Description[ca@valencia]": "Un dorsal per a l'XPS", + "Description[ca]": "Un dorsal per a l'XPS", + "Description[cs]": "Podpůrná vrstva XPS", + "Description[da]": "En XPS-backend", + "Description[de]": "Ein Anzeigemodul für XPS", + "Description[el]": "Σύστημα υποστήριξης XPS", + "Description[en_GB]": "An XPS backend", + "Description[es]": "Un motor para XPS", + "Description[et]": "XPS-i taustaprogramm", + "Description[eu]": "XPS-ren bizkarraldeko bat", + "Description[fi]": "XPS-taustaosa", + "Description[fr]": "Un moteur XPS", + "Description[gl]": "Unha infraestrutura para XPS", + "Description[ia]": "Un retro-administration de XPS", + "Description[it]": "Un backend per XPS", + "Description[ko]": "XPS 백엔드", + "Description[lt]": "XPS programinė sąsaja", + "Description[nl]": "Een XPS-backend", + "Description[nn]": "Ein XPS-motor", + "Description[pl]": "Obsługa formatu XPS", + "Description[pt]": "Uma infra-estrutura de XPS", + "Description[pt_BR]": "Uma infraestrutura XPS", + "Description[ru]": "Модуль поддержки формата XPS", + "Description[sk]": "XPS backend", + "Description[sl]": "Zaledje za XPS", + "Description[sr@ijekavian]": "Позадина за ИксПС", + "Description[sr@ijekavianlatin]": "Pozadina za XPS", + "Description[sr@latin]": "Pozadina za XPS", + "Description[sr]": "Позадина за ИксПС", + "Description[sv]": "Ett XPS-gränssnitt", + "Description[tr]": "Bir XPS arka ucu", + "Description[uk]": "Програма для XPS", + "Description[x-test]": "xxAn XPS backendxx", + "Description[zh_CN]": "XPS 后端", + "Description[zh_TW]": "XPS 後端介面", + "Id": "okular_xps", + "License": "GPL", + "MimeTypes": [ + "application/oxps", + "application/vnd.ms-xpsdocument" + ], + "Name": "XPS Backend", + "Name[az]": "XPS modulu", + "Name[ca@valencia]": "Dorsal XPS", + "Name[ca]": "Dorsal XPS", + "Name[cs]": "Podpůrná vrstva XPS", + "Name[da]": "XPS-backend", + "Name[de]": "Anzeigemodul für XPS", + "Name[el]": "Σύστημα υποστήριξης XPS", + "Name[en_GB]": "XPS Backend", + "Name[es]": "Motor para XPS", + "Name[et]": "XPS-i taustaprogramm", + "Name[eu]": "XPS-ren bizkarraldekoa", + "Name[fi]": "XPS-taustaosa", + "Name[fr]": "Moteur XPS", + "Name[gl]": "Infraestrutura para XPS", + "Name[ia]": "Retro-Administration de XPS", + "Name[it]": "Backend XPS", + "Name[ko]": "XPS 백엔드", + "Name[lt]": "XPS programinė sąsaja", + "Name[nl]": "XPS-backend", + "Name[nn]": "XPS-motor", + "Name[pl]": "Obsługa XPS", + "Name[pt]": "Infra-Estrutura de XPS", + "Name[pt_BR]": "Infraestrutura XPS", + "Name[ru]": "Модуль поддержки формата XPS", + "Name[sk]": "XPS Backend", + "Name[sl]": "Zaledje za XPS", + "Name[sr@ijekavian]": "Позадина за ИксПС", + "Name[sr@ijekavianlatin]": "Pozadina za XPS", + "Name[sr@latin]": "Pozadina za XPS", + "Name[sr]": "Позадина за ИксПС", + "Name[sv]": "XPS-gränssnitt", + "Name[tr]": "XPS Arka Ucu", + "Name[uk]": "Модуль XPS", + "Name[x-test]": "xxXPS Backendxx", + "Name[zh_CN]": "XPS 后端", + "Name[zh_TW]": "XPS 後端介面", + "ServiceTypes": [ + "okular/Generator" + ], + "Version": "0.3.3" + }, + "X-KDE-Priority": 4, + "X-KDE-okularAPIVersion": 1, + "X-KDE-okularHasInternalSettings": false +} diff --git a/generators/xps/okularApplication_xps.desktop b/generators/xps/okularApplication_xps.desktop new file mode 100755 index 0000000..940dce2 --- /dev/null +++ b/generators/xps/okularApplication_xps.desktop @@ -0,0 +1,224 @@ +[Desktop Entry] +MimeType=application/oxps;application/vnd.ms-xpsdocument; +Terminal=false +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document Viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[eo]=Dokumenta rigardilo +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fa]=مشاهده‌گر سند +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de documents +GenericName[ga]=Amharcán Cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hi]=दस्तावेज़ प्रदर्शक +GenericName[hne]=कागद प्रदर्सक +GenericName[hr]=Preglednik dokumenata +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[km]=កម្មវិធី​មើល​ឯកសារ +GenericName[ko]=문서 뷰어 +GenericName[ku]=Nîşanderê Belgeyan +GenericName[lt]=Dokumentų žiūryklė +GenericName[lv]=Dokumentu skatītājs +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[ne]=कागजात दर्शक +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[oc]=Visualizaire de documents +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de Documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sq]=Shikues dokumentesh +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[th]=เครื่องมือแสดงเอกสาร +GenericName[tr]=Belge Gösterici +GenericName[ug]=پۈتۈك كۆرگۈ +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument Viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Universal document viewer +Comment[az]=Sənədə universal baxış vasitəsi +Comment[ca]=Visor universal de documents +Comment[ca@valencia]=Visor universal de documents +Comment[cs]=Univerzální prohlížeč dokumentů +Comment[da]=Universel dokumentfremviser +Comment[de]=Universeller Dokumentenbetrachter +Comment[el]=Καθολικός προβολέας εγγράφων +Comment[en_GB]=Universal document viewer +Comment[es]=Visor de documentos universal +Comment[et]=Universaalne dokumendinäitaja +Comment[eu]=Dokumentu erakusle unibertsala +Comment[fi]=Yleinen asiakirjakatselin +Comment[fr]=Afficheur de document universel +Comment[gl]=Visor de documentos universal +Comment[hu]=Univerzális dokumentummegjelenítő +Comment[ia]=Visor de documento universal +Comment[is]=Fjölhæfur skjalaskoðari +Comment[it]=Visore di documenti universale +Comment[ko]=만능 문서 뷰어 +Comment[lt]=Universali dokumentų žiūryklė +Comment[nl]=Universele documentviewer +Comment[nn]=Dokumentvisar for mange format +Comment[pa]=ਯੂਨੀਵਰਸਲ ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +Comment[pl]=Wszechstronna przeglądarka dokumentów +Comment[pt]=Visualizador de documentos universal +Comment[pt_BR]=Visualizador de documentos universal +Comment[ru]=Универсальная программа просмотра документов +Comment[sk]=Univerzálny prehliadač dokumentov +Comment[sl]=Vsestranski pregledovalnik dokumentov +Comment[sr]=Универзални приказивач докумената +Comment[sr@ijekavian]=Универзални приказивач докумената +Comment[sr@ijekavianlatin]=Univerzalni prikazivač dokumenata +Comment[sr@latin]=Univerzalni prikazivač dokumenata +Comment[sv]=Generell dokumentvisare +Comment[tr]=Evrensel belge görüntüleyici +Comment[uk]=Універсальний переглядач документів +Comment[x-test]=xxUniversal document viewerxx +Comment[zh_CN]=通用文档查看器 +Comment[zh_TW]=通用文件檢視器 +Exec=okular %U +Icon=okular +Type=Application +InitialPreference=7 +Categories=Qt;KDE;Graphics;Viewer; +X-KDE-Keywords=XPS +X-KDE-Keywords[ar]=XPS +X-KDE-Keywords[az]=XPS +X-KDE-Keywords[bg]=XPS +X-KDE-Keywords[bs]=XPS +X-KDE-Keywords[ca]=XPS +X-KDE-Keywords[ca@valencia]=XPS +X-KDE-Keywords[cs]=XPS +X-KDE-Keywords[da]=XPS +X-KDE-Keywords[de]=XPS +X-KDE-Keywords[el]=XPS +X-KDE-Keywords[en_GB]=XPS +X-KDE-Keywords[es]=XPS +X-KDE-Keywords[et]=XPS +X-KDE-Keywords[eu]=XPS +X-KDE-Keywords[fi]=XPS +X-KDE-Keywords[fr]=XPS +X-KDE-Keywords[ga]=XPS +X-KDE-Keywords[gl]=XPS +X-KDE-Keywords[hu]=XPS +X-KDE-Keywords[ia]=XPS +X-KDE-Keywords[is]=XPS +X-KDE-Keywords[it]=XPS +X-KDE-Keywords[ja]=XPS +X-KDE-Keywords[kk]=XPS +X-KDE-Keywords[km]=XPS +X-KDE-Keywords[ko]=XPS +X-KDE-Keywords[lt]=XPS +X-KDE-Keywords[lv]=XPS +X-KDE-Keywords[mr]=XPS +X-KDE-Keywords[nb]=XPS +X-KDE-Keywords[nds]=XPS +X-KDE-Keywords[nl]=XPS +X-KDE-Keywords[nn]=XPS +X-KDE-Keywords[pa]=XPS +X-KDE-Keywords[pl]=XPS +X-KDE-Keywords[pt]=XPS +X-KDE-Keywords[pt_BR]=XPS +X-KDE-Keywords[ro]=XPS +X-KDE-Keywords[ru]=XPS +X-KDE-Keywords[sk]=XPS +X-KDE-Keywords[sl]=XPS +X-KDE-Keywords[sr]=XPS,ИксПС +X-KDE-Keywords[sr@ijekavian]=XPS,ИксПС +X-KDE-Keywords[sr@ijekavianlatin]=XPS,XPS +X-KDE-Keywords[sr@latin]=XPS,XPS +X-KDE-Keywords[sv]=XPS +X-KDE-Keywords[tr]=XPS +X-KDE-Keywords[uk]=XPS +X-KDE-Keywords[x-test]=xxXPSxx +X-KDE-Keywords[zh_CN]=XPS +X-KDE-Keywords[zh_TW]=XPS +NoDisplay=true diff --git a/generators/xps/okularXps.desktop b/generators/xps/okularXps.desktop new file mode 100644 index 0000000..2072a20 --- /dev/null +++ b/generators/xps/okularXps.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart +X-KDE-Library=okularpart +Type=Service +MimeType=application/oxps;application/vnd.ms-xpsdocument; diff --git a/generators/xps/org.kde.mobile.okular_xps.desktop b/generators/xps/org.kde.mobile.okular_xps.desktop new file mode 100644 index 0000000..251874f --- /dev/null +++ b/generators/xps/org.kde.mobile.okular_xps.desktop @@ -0,0 +1,215 @@ +[Desktop Entry] +MimeType=application/oxps;application/vnd.ms-xpsdocument; +Name=Reader +Name[ar]=التصيير +Name[az]=Oxuyucu +Name[bg]=Четец +Name[bs]=Čitač +Name[ca]=Lector +Name[ca@valencia]=Lector +Name[cs]=Čtečka +Name[da]=Læser +Name[de]=Lesegerät +Name[el]=Πρόγραμμα ανάγνωσης +Name[en_GB]=Reader +Name[es]=Lector +Name[et]=Lugeja +Name[eu]=Irakurlea +Name[fi]=Lukija +Name[fr]=Lecteur +Name[ga]=Léitheoir +Name[gl]=Lector +Name[hu]=Olvasó +Name[ia]=Lector +Name[is]=Lesari +Name[it]=Lettore +Name[kk]=Оқу құралы +Name[ko]=리더 +Name[lt]=Skaitytuvas +Name[lv]=Lasītājs +Name[mr]=वाचक +Name[nb]=Leser +Name[nds]=Leser +Name[nl]=Lezer +Name[nn]=Lesar +Name[pa]=ਰੀਡਰ +Name[pl]=Czytnik +Name[pt]=Leitor +Name[pt_BR]=Leitor +Name[ro]=Cititor +Name[ru]=Просмотрщик +Name[sk]=Čítačka +Name[sl]=Bralnik +Name[sr]=Читач +Name[sr@ijekavian]=Читач +Name[sr@ijekavianlatin]=Čitač +Name[sr@latin]=Čitač +Name[sv]=Läsprogram +Name[tr]=Okuyucu +Name[ug]=ئوقۇغۇ +Name[uk]=Переглядач +Name[x-test]=xxReaderxx +Name[zh_CN]=阅读器 +Name[zh_TW]=閱讀器 +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Comment=Viewer for various types of documents +Comment[ar]=عارض للعديد من أنواع المستندات +Comment[az]=Müxtəlif növlü sənədlər üçün görüntüləyici +Comment[bg]=Преглед на различни видове документи +Comment[bs]=Pregledač raznih vrsta dokumenata +Comment[ca]=Visor de diversos tipus de documents +Comment[ca@valencia]=Visor de diversos tipus de documents +Comment[cs]=Prohlížeč různých typů dokumentů +Comment[da]=Fremviser af diverse dokumenttyper +Comment[de]=Betrachter für verschiedene Arten von Dokumenten +Comment[el]=Πρόγραμμα προβολής για διάφορους τύπους εγγράφων +Comment[en_GB]=Viewer for various types of documents +Comment[es]=Visor de diversos tipos de documentos +Comment[et]=Eri tüüpi dokumentide näitaja +Comment[eu]=Hainbat dokumentu moten erakuslea +Comment[fi]=Monenlaisten asiakirjojen katseluohjelma +Comment[fr]=Afficheur pour différents types de documents +Comment[ga]=Amharcán le haghaidh cáipéisí éagsúla +Comment[gl]=Visor de varios tipos de documentos. +Comment[hu]=Megjelenítő különféle típusú dokumentumokhoz +Comment[ia]=Visor pro varie typos de documento +Comment[is]=Skoðari fyrir ýmsar gerðir skjala +Comment[it]=Visore per vari tipi di documenti +Comment[kk]=Түрлі құжаттар қарау құралы +Comment[ko]=여러 형식의 문서 뷰어 +Comment[lt]=Žiūryklė įvairiems dokumentų tipams +Comment[lv]=Dažādu dokumentu tipu skatītājs +Comment[mr]=विविध प्रकारच्या दस्तऐवजांचा प्रदर्शक +Comment[nb]=Framviser for forskjellige dokumenttyper +Comment[nds]=Kieker för en Reeg Dokmenttypen +Comment[nl]=Viewer voor verschillende typen documenten +Comment[nn]=Framvisar for forskjellige dokumenttypar +Comment[pa]=ਕਈ ਕਿਸਮ ਦੇ ਡੌਕੂਮੈਂਟ ਵੇਖਾਉਣ ਲਈ ਦਰਸ਼ਕ +Comment[pl]=Przeglądarka dla różnych typów dokumentów +Comment[pt]=Visualizador de vários tipos de documentos +Comment[pt_BR]=Visualizador para vários tipos de documentos +Comment[ro]=Vizualizor pentru diferite tipuri de documente +Comment[ru]=Программа для просмотра различных типов документов +Comment[sk]=Prehliadač pre rôzne typy dokumentov +Comment[sl]=Pregledovalnik raznih vrst dokumentov +Comment[sr]=Приказивач различитих врста докумената +Comment[sr@ijekavian]=Приказивач различитих врста докумената +Comment[sr@ijekavianlatin]=Prikazivač različitih vrsta dokumenata +Comment[sr@latin]=Prikazivač različitih vrsta dokumenata +Comment[sv]=Visningsprogram för diverse typer av dokument +Comment[tr]=Çeşitli belge türü için görüntüleyici +Comment[ug]=ھەر خىل تىپتىكى پۈتۈكلەرنى كۆرىدىغان پروگرامما +Comment[uk]=Програма для перегляду документів різних типів +Comment[x-test]=xxViewer for various types of documentsxx +Comment[zh_CN]=可以查看多种文档的工具 +Comment[zh_TW]=多種型態文件的檢視器 + +TryExec=okularkirigami +Exec=okularkirigami %u +Terminal=false +Icon=okular +Type=Application +Categories=Qt;KDE;Graphics;Office;Viewer; +InitialPreference=2 +NoDisplay=true +X-KDE-Keywords=XPS +X-KDE-Keywords[ar]=XPS +X-KDE-Keywords[az]=XPS +X-KDE-Keywords[bg]=XPS +X-KDE-Keywords[bs]=XPS +X-KDE-Keywords[ca]=XPS +X-KDE-Keywords[ca@valencia]=XPS +X-KDE-Keywords[cs]=XPS +X-KDE-Keywords[da]=XPS +X-KDE-Keywords[de]=XPS +X-KDE-Keywords[el]=XPS +X-KDE-Keywords[en_GB]=XPS +X-KDE-Keywords[es]=XPS +X-KDE-Keywords[et]=XPS +X-KDE-Keywords[eu]=XPS +X-KDE-Keywords[fi]=XPS +X-KDE-Keywords[fr]=XPS +X-KDE-Keywords[ga]=XPS +X-KDE-Keywords[gl]=XPS +X-KDE-Keywords[hu]=XPS +X-KDE-Keywords[ia]=XPS +X-KDE-Keywords[is]=XPS +X-KDE-Keywords[it]=XPS +X-KDE-Keywords[ja]=XPS +X-KDE-Keywords[kk]=XPS +X-KDE-Keywords[km]=XPS +X-KDE-Keywords[ko]=XPS +X-KDE-Keywords[lt]=XPS +X-KDE-Keywords[lv]=XPS +X-KDE-Keywords[mr]=XPS +X-KDE-Keywords[nb]=XPS +X-KDE-Keywords[nds]=XPS +X-KDE-Keywords[nl]=XPS +X-KDE-Keywords[nn]=XPS +X-KDE-Keywords[pa]=XPS +X-KDE-Keywords[pl]=XPS +X-KDE-Keywords[pt]=XPS +X-KDE-Keywords[pt_BR]=XPS +X-KDE-Keywords[ro]=XPS +X-KDE-Keywords[ru]=XPS +X-KDE-Keywords[sk]=XPS +X-KDE-Keywords[sl]=XPS +X-KDE-Keywords[sr]=XPS,ИксПС +X-KDE-Keywords[sr@ijekavian]=XPS,ИксПС +X-KDE-Keywords[sr@ijekavianlatin]=XPS,XPS +X-KDE-Keywords[sr@latin]=XPS,XPS +X-KDE-Keywords[sv]=XPS +X-KDE-Keywords[tr]=XPS +X-KDE-Keywords[uk]=XPS +X-KDE-Keywords[x-test]=xxXPSxx +X-KDE-Keywords[zh_CN]=XPS +X-KDE-Keywords[zh_TW]=XPS diff --git a/generators/xps/org.kde.okular-xps.metainfo.xml b/generators/xps/org.kde.okular-xps.metainfo.xml new file mode 100644 index 0000000..da78345 --- /dev/null +++ b/generators/xps/org.kde.okular-xps.metainfo.xml @@ -0,0 +1,91 @@ + + + org.kde.okular-xps + org.kde.okular.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + എക്സ് പി എസ് + XPS + XPS + XPS + XPS + XPS + XPS + XPS + XPS + ИксПС + XPS + ИксПС + XPS + XPS + XPS + XPS + xxXPSxx + XPS + XPS + Adds support for reading XPS documents + XPS sənədlərini oxumaq üçün dəstək əlavə edir + Afegeix la implementació per a llegir documents XPS + Afig la implementació per a llegir documents XPS + Přidává podporu pro čtení dokumentů XPS + Bietet Unterstützung zum Lesen von XPS-Dokumenten + Προσθέτει υποστήριξη για την ανάγνωση εγγράφων XPS + Adds support for reading XPS documents + Permite la lectura de documentos XPS + XPS-dokumentide lugemise toetus + XPS dokumentuak irakurtzeko euskarria gehitzen du + Lisää XPS-tiedostojen lukutuen + Permet la lecture des documents XPS + Engade a posibilidade de ler documentos XPS + Adde supporto per leger documentos XPS + Aggiunge il supporto per la lettura di documenti XPS + XPS 문서 읽기 지원 추가 + Prideda palaikymą XPS dokumentų skaitymui + എക്‌സ് പി എസ് പ്രമാണങ്ങൾ വായിക്കാൻ പിന്തുണാ ചേർക്കുന്നു + Voegt ondersteuning voor lezen van XPS-documenten toe + Legg til støtte for å lesa XPS-dokument + Dodaje obsługę dokumentów XPS + Adiciona o suporte para ler documentos em XPS + Adiciona o suporte para leitura de documentos em XPS + Поддержка чтения документов XPS + Pridá podporu pre čítanie XPS dokumentov + Doda podporo za branje dokumentov XPS + Подршка за читање ИксПС докумената + Podrška za čitanje XPS dokumenata + Подршка за читање ИксПС докумената + Podrška za čitanje XPS dokumenata + Lägger till stöd för att läsa XPS-dokument + XPS belgelerini okuma desteği ekler + Додає підтримку читання документів XPS + xxAdds support for reading XPS documentsxx + 增加对 XPS 文档的阅读支持 + 加入讀取 XPS 文件的支援 + + text/plain + + https://okular.kde.org + + + + + + + diff --git a/hooks/pre-commit b/hooks/pre-commit new file mode 100755 index 0000000..6337bbb --- /dev/null +++ b/hooks/pre-commit @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +readonly output=$(git clang-format -v --diff) + +if [[ "$output" == *"no modified files to format"* ]]; then exit 0; fi +if [[ "$output" == *"clang-format did not modify any files"* ]]; then exit 0; fi + +echo "ERROR: you need to run git clang-format on your commit" +echo " git clang-format -f is potentially what you want" +exit 1 diff --git a/icons/128-apps-okular.png b/icons/128-apps-okular.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd2cda63de4b51d4721709e0bbf922a50ae8d2a GIT binary patch literal 11390 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 literal 0 HcmV?d00001 diff --git a/icons/310-apps-okular.png b/icons/310-apps-okular.png new file mode 100644 index 0000000000000000000000000000000000000000..ac4a8c83473e9cd703337583820a7afefddc7e3b GIT binary patch literal 41485 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

P@`z+ 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 literal 0 HcmV?d00001 diff --git a/icons/44-apps-okular.png b/icons/44-apps-okular.png new file mode 100644 index 0000000000000000000000000000000000000000..08b25cb1cb12353b66fce7f1ef6280c49999f4de GIT binary patch literal 3004 zcmV;t3q$mYP)6A?A6c+-CCkc_0kPb9T(->^W zv9V?2*pcP+>aNw^P9JP3vMgVcp>+Cr&YZJ5M|*zfzu))iJ2LQpX4E&m;0GUk5ac-S zTY*5}QLEK@o5^HyUcP+!Gn>t~==FNXAHPV`M=xfPlCl6HxUZgt-DoMomP42JCX>nbwE>?!dv=xCY<`I2 zxHgl?bc?}YaHy(EYnld%qCg12rDzWC_N74x0SJLf5A5Gyhfb$k5V#ClcjU;C+uGXN zF5NKji4!Mw`ThPES(d%sU@*7<(2Ak}08~{)!T+wq=d5(yT1)!Nnl<14VTOH1D0j)2jG!qnU-a__}~JhPNyrjlOrO&6y#ZTHP{#mkFBxK znX{a>V#SJwmV&JaJUu=AUirOBu!Zq^S29IcAcUZ`-U3EXFAI{Uug`Nh9Loy4c`hLc z!pAgCLsiw89hCu=j=zkn7){Koiy7ei8f_JQx7;NPLKKW;*<}UZJcak}-J1X)6<`aC zR02OWk^vzaKr|4dq1r-YeYJT(MHkxyMNzsVM~>Wf!@vL_%ko4e(9&xH3ZY1*=n5bN zyBckvZydDPW&`iWfs@JPC*=#31N2Wzn9eG5{kOqB=PfJ+2w=|j%9Sf0zA0dy=l@m- zvJ}35N}2;}&;hGG<|S1vhb(PQr*p}`tN6tckH=5ZG(G3xLyUNZ11 z0t0{~NfV2`-h`-JSC|m^tjvPymV%Z-miC3_@p!&-Q^3h&^2|a3M^O~=idtL*gurWI z7WC0lpwdTL;QZ%3>=*-OZlCc!L5?o;nU=DC+&jkKGsoZi? z!0~we)MC-@;|xW0K?riPwjk_ctpF`4DqcHz1p`xA(@g;{7I+jzA?P##AjQ9AUMYTd zDcEvl0pJhkhA}2&(K8;W-hco7+iw^c07Ow7UkLctYU><@KOavn>azvN@}3ZabAwZO zvugl^Xt)wh!QuAqzA0dy=g%$#{NOqd7@C@e2L3q`hgLzorQk=WGkEc@7oaL4ph|F? zXt>8{Pv?y!KxVqj2hP16zspvhFnr`HZ(N+*tq zzM4euwIl%Gwa@@I*4R+vxE?p9;IUW?gM)*hC<-xR#oL#XP)z~QRvqqY@?rn>dgyh4 zBuU0lD0I)kg9i`P)zvY%T<*}zFTZ>g<@A*-9*>JOO&d##?o#l{w1gkO`#JifDG;K; zZDH_>-K%j|W7Uj*1IXoa=;`T!EGy7CYw+oK79)HHvZBJlGI(%902^u?kR%D&Y!(v} z6F7J7+(m|ATAWU2qPx5MsaIcp_2Xp$PfSbB{4q{W$nex<{R zTYMZ=ax~1TF?^-jK$$owss>rr5U{hjtHFgTDh)-Jkw_$9u~?w0D$?mRy1TnSk|b&J zg%@6U9zX&BS<)qdnZV;XuD;wIN=>h$@RNHQ@WXAjIQJ!wvx6~QONbboO299s(4+Ta zdy@|qMvodh1ARJ%{=P5J`R86FlS%B^vj-N71y-vS27>|B)zy$B$@9r4pNs*p17H9M z0OTcs$H&Jzg2CWEQ4}Fb5>lyD(I<^YBPs=K54LVFsW$~pnf;+d| ziC{2@k&zMf^Ro zrq0gJXyJh-lL~=eNo<}ekL@*dcZEY=Lu^2i!I^b|PAP53z zng+u#Sg~RSa=9GB;V`qYbQC<#0{~X7T7|m0I;7L-vBt*6^Bl(=J%0T7pN<_n zmY)aw%rnn4Zr!@|sqNdh|7-2qwKPrBOfs2#on={X0anvAOiWB*XlMxi{rxy~>J&U4 z54yU#psFfpnnqn+9ky=Wist5K7z_q9Ha5cPbQaf9RTYvXL6RioaybZsfbQ;Y#9}c_ zPEH~m4nq`0=yW>xd_JsQyEfg>&`>i6_>DK-*sa&=*X-N3ug7dQdjQC)s>%Zc1MP`K zVtXVK!SL`fhKGkC2m(Y=oH>2;_v7xn?*;%o{q)n=ym@mGB%jZtr>6%1K+`nzdOc{G z1|bBQOs1I1^7%Zfs;c1idf|4vp=lZp960csD_5>0bvoS^LWp&2Z0ymZ4?p+Zb9LEl zc1L@A`zb|Hf{{qXIx#V^OOmAZ;c%Gi>+6Ht?S{wWK_C!7I-N!;m4esnMSFWYR<2x$ zmX;P6jYdSH(IS}DYQ=^P8!$LHh+Hm*R4N5g6d}tp7>0qtV1Uo(gWvCm&1M6~aYdJV z;DHB7C=~knETRE`st154o_OL`yWRe4nx=a$UcC5AmSvk5hB0WGc1=-~&K)~;gdczW z@k3|MoWaSHC&BYPnwpw$;J^X+{eCElf}x=y0D#$ShRI}_`6*yFo3Jd4b?ep@K@~*- zP1B%h8U}*_CR62#vbMH%UCE^k%w!4kwr$&v1Ofq1KA&HsD9U+F(>gRwOZff%jG`#Y zg$ox}A3Ju8^!N8uE|&`j4<1A?7(_0YgD8sl>Z`9%UtbTFWnr~i=hYFwObTQe2EhE% zvV3mAYHDf%PN&l@2tuN8PY)p5+1YvL@bECz-roMR)2B~&?b)-3qiI^pX0uc%6x!X} z+xw&-2-KD>Td;fgZm6n?WHO0-K96WLirU&*uq-<#sFq`eQnb>20Ls;?R|SfqR$%6v zt_X~yM~_|uUNbiVV>J7@Fx{HW1r9GSD3k}(57 zd+DW@9-t`dyF)`mt&vEiNtWfb*=&COjyvwC*|KHJKANUsv)K>`1W;XFjjF0D==J)F zhsweR78>hxI+92vqJ4dRT^$`Ae>r^k@Ohr+uK`dOd@JQQR*deO-)9(+x<~I9=}(Tq%of7pG_nZVE{=0N;aDn4F-b|n17U?cVyQzC6mca z#pCgCBocWqo6R0?YiqlDBXE_hn1@?iTlML5`tO1u+$%}az|_>#v#C_-0)T8`PCA{Q za5x^7UN>3_2LGVMQHUw-tcK|)eUC}RvkJ5mH~#d{K!s;;FH8|pe3NE53j zwfloV_S7mg38_V$s)AM!+E!=>RM62u2!SLdgd~KJ2YEnDg6;VIv-h2=T;#=%*qzD_ zT-}@B>we$4-#PbT75yJAAt6Df)9K>kVJej>fiGoeXS=$)yPatJDGGa<1XRh%$#F0N z7Dcyi-MWk|Teegb6&2N|q@>gsjmD~xk&)l6UAy+E)oS%p6sG>Rz$PUnsRBH!TfBI2 z>RWHURa0DCyaYsQ4F*FsykF?|`xAXWAF<(C!h0+5+Q&rnGzbLCK&@8mHf-2ndgqb4g+9kQkm4z9`VgOA*5kT1_aEwYIfyJmbMCAAu2n5Su>(;HA8#ivO%FoZQ z(;JL6pWjzik2&KDj!n6>!yPWlHLB>jMOyNDy$q1SN&+Ekj7&Ksl{7UqWr-#Z)Un85 z`SRsyyLa!dEhs3cLr1lViHVCf8cjYtsZ|t(&JMchqgylR*8imMpEhKWPAx#o5|IE1 zro8dS8zpbQ{r0Ha?T(!Q0!gjaYLgIPnVU9ks)RS{K%@>}s{yviE#HrtfC^RzgDk(sw|%h^P`&rwd&S$fZ99o}2>|KaL zLEuq~G6nCSx$9u?v&BaZ3w2bSrsexF7o=1UWG%sBCE)Mr>9IMT&OWr~1uyH*2OQ+~ z`UH5IEgQ>|14#yrSfm0OmsM9+C-I=fN`OJQ91cfkwBQxLip~z$C3sPr^zpPj&mfE&d$zu z1d%@+fihE~(7#+pI6MkjT}srlfrV^;(lUqT1U@W@35$dF9BU=J+sn%m5l@9#>AbW~4j0Jr6v42qQ@#4?s|{G6*M(eF z0%(RoLtosUd=kv}%y!!TOfK((=LIioIEhBbC+PQozeb()@|o z!uG%^?f358^TkAfSEM*~_zt#sP2pCQh3SbjH07W^NQW`Gy$Vg*T(qXlM6j@+d3$>2 z&K;VVn4lYjX8O%nBQ)YlAZHvVLYf)8DG2AE!vWlPncyWL}ZW+cXc!iwu(-LWOZ8p{C1DsJqYLA`%-Puq2^emck zV>2{vAqVuX0C=&a)?b zw6xS)w{D%q(aN$A;DdYr}Nz_5_VRc5pTkKuU}XWoU`4>SU_QNhY=hNm?p3 z=_$=;rH4cPG(0>+D^{%FK6n{HNS}n`96}7(R6(fG8DQWOg%=9ExLW)c|^KxA^9?)3K1%`;u} z;K2h1Nu{NwynrLUUN2Xqf;{AA#GzX8=;&x1t7;bf{4pSx)@HN0BR4l!3@zFWUL0s) zhUCtKr$CSk#|;e*4${ob40{r~c96$5N;o#hLeE2eH=79)Bt3liP&^A+P*qhGm6et8 zX$0X&k>$e~kiW}q@mzg<{Y!|Q&p3=`3HYNTfK5dOj#_d6j<xgEsHRe&8D8e;E@OoOul{#!`l*=L_6 z{BR*Oj+DsWmR{!j;(csog`D6p>g(%c=?FX2$@j9wKzV`2Novv5dD?> z7Xh4$7GTJJ)YR1UPn{S4}8};`G1_p$85m4-D_LArnD_2oAZ{AFJm+%et z7=z}if0CLpc_{+m;fX^tOd1B7J3^5R&LMCJRb=<_b#I|+yUb~b)pg1~F9y{5s?ZUIo<12o~G zReZ{gTZyP|qcqpl)Lh-UbLU>@Ty^^NX$B_%tY5#LR;^maoeD4@&9kil46=d2&ZIf( za5CUgWAbu_=IiWf1}xfgzL5qpDJGLCeRf3MoI7L|V$b~zT5W=ktsu}1FY-?8&j2wA z03Li$fn17_1r($}HD`{MD_0VJnc>bDumFNsVXX@g&}q<;ngK~-GRMpN^BD+fuqw?( z`qgq84P4Ce(2iWWa^)OS9eeX|5v2JB(s`LGt8#iAkLN1DFY4ub>jq0(sln{U2ZgbC$m0DJWL=bz63AT8Qk z5V+egGI7WzQ&?W71$GRN2oFMn>~)S0mO`YBOW1p|mfuF(JvKJh-_g<0cIwor*0X2N zwnIX#Q?Nh+veuy_?BBnCBlPynkt0X`l97>d5Z>K}*ihi@KkeDG#{TO*efDa zU{u)a?0s=f1~@Dd;EWaR{iPnkY`};AijS^`*DWBhXMBA863+(+ZWAVye;HwNx}SRvijG1N zkoN>w0P2DyJNoF(%`XyM*nhdu4%P+q)1EY)e%^N0`1AvDF8!G|s^e{g7 zB0N8hj$cQBUc_Y{PDQT4as4I&b*Yqq^ejed5bKjJUb$kfXnX(t_d79K)41nE@t`Pp zHQiewaU|_(Desod;epA4jOr`{g zeROm*>4qC_$a>&`2j+I~@f9IWd{%vq@a6~52tlto@HRa{yH5nNh)hQ_{Rk*G= z5D1tN0b;Y+-hq5BBA&@af%Tsmti$1`N=!^F_WS*2h^XfAcm(%o0)tfJR3c_C zz%E&`WXkH*t7}S1OKV(a$LzA))S0+0Bv>|rWmBJ34 z<=%bw-8Ivvm(=u1a`k18t*UdxQuI-`+jQojTkftjOIfZFtg$y50gp;~;)y59UwrY! zb{zWSG(h}d@3`X*4QxqCNlj{M>YSvcq$=cS;TIQNrhh-^lmU+mfeMjPO)4@I3;Dw3fMuFsw>QNGS4py(WmTvA^Q- z$oen)0X_iC8gQ*M1IrT&GR0~(8-T|e0c`pC`Ezh=!$&smuMNkhu z_+agf88hbMyK0aV!A?cknpEfx4-d=8$cO@=%O6gU?mKKT-1BY zhQ=ZB2gbnTe-w_fq{JabX*OOH?q2md;&&7h;p2}#KErCYvNDX@031AU;>3wYcwNFZ zBWPpa((jYMUmO;ZG2ki%(66XWGu$5o_>lLYkqB#W&U!5jKqdWeyz#~f7{D;CMDu*G zY;Sgp1{k7x%8V?V%*;uQc7Mzfz|Vz+g^CDGadSX_e}CZEv13kzdDIh=wgO_3q+b>`Mi~1E0#q$hRInoC3>L2e zRP(?2=9?N3#tK{kIDBbXeEvYN=k?FGOiv5t`AERo$6^Q)VYMQ{xDB9)5QR_6M8LB@ zdf6?6Js!MBUW!!;(`=FQI~)!SnoAotGRMd^F(E z4WTN+3J_s3+BGwP2Nht0LAeOR15RW#55p+epOE~YdvHWDG1#)=5zHh@lq zSP91L{nmce5jr2L3hYYe{!2(5u@f$!9Ay$3~vpB8X>1_EI1S)IBs9dz+QYtp1ikanBOoKu8V!7Ok4HBK z9N=>(B8LajiGUB+8zi{#y~8tG8w^AkmjM(JVu~RVMxDo# ztY!r~$Pm2Xnt49#^;?g3$Y)L6VolA`m&WlJz(|BfRXLbRq-~M4bupQfyL|oiuJKOvNq_j7ZN|6vO~NVp;^ZE_nSHTaH6VW%PiY zXm=WjFfIcqBE*3HSjyJ#RpkT|p+X{`HTS7&qk=Vh-5C0Ak53-kSSMXqheb;|faiIa z$16Fxc{&lsZ2(1t_~D}^mU4LIoLosuw5m+d3!?u!b}5#SW{VpBBOuj(d;h4My6BW7 z-=H|W{o?QsN>Nfk-o9^vWM^i?M1(P~n(zaO_5SbfAS1n|wxi^=S`#Qww@@Pi3T1;C0&o9oB$Cp${5{!@g z$XkL}`#(f!{A2LfpB61zl)*7BUcC65=bwLmWWo`^A4qSy>87lzs;ZSZ3>yKWe`k_K zm{lze{bu>=>0U|3eHk#I z!)}$F6uUffYq_jiFijFH<8{E)UDwdiup2u6p|-Ym2_k68nKNhpeBi)=&Iw0AdV0F` z`s=T++`fH#JvS$X_%$cwJU=kvm!EHKl)Yzrg5MG$0<7}L!VgtlAp&{-yptlFQySwdZ zezYCCckkZu_S#Y~Ufn(LQCQ1PtWE{m{n!VAFEGB4FG z)3O{=ndcD8P>-B$tdrmW^%NBnY{(EqBuSdapdW3aX$FNO858n_7;dp-B zEiEr6Y5-4PUthzNDN~k5d7l^ZoE;0L<<gkgiiG$K< zE0l){GbGDlV?;pA(%#wvJ~%2nKKV-Ue8GE4dYBs{2vQK4ic1Kb24T-gNX90PVx*Lv zvjlUc4v+9UbEC?G-gyWi9u~DA9R!1OdQv$^kMKHSqv9-|^YZdE#oOE4rlzLDFTecqugR|v z*Q7Q{z5DLFf?b)*@X*DWTCQLdRQB}g)A^9FzvR+0EMDsB>d4NTtX#QL4_P)$O9FP* zSYN$;re_J9`OGnBTncB0mX;Qtqo^@>oyvbckA|Sp`GS=7!|bhFxBg0%^b;IhJWX+s8Qwj5DX?zcIuqvlpFsh7<$q!QIXGPia6WwYV(=DPHJJDamH_EpRk|{4 znaj+5J{Ua5=%7^Nb@U_^M|d)?Ig8L3 ztnLVsp5r++HtPU-oY(U^9XNZAhsN_37~QdF&z>HPxdo>v#BGMS#~I++XP-4exqN`{ zr04N4Gdx_2aQZepQ48xP!t>3@*%RP}6ohI)QBje`?tAy{B@rK>Ruy5zioj+lkw zKp2Mj0|u$Atfbd;62hW{VXZb|QgH=TO=k)my~yuXiUd!2`gk-z(0U|N`O4y|i22TF zU^E-*0EE#`q4;`$CS#W|B60C4Jmin?dM`pdfMY+D@iXiLXfRR=t2O2!z0NSb>#n^GVgD``DT(Q6=t5(W4f0(?GZc)iN_=> zemBvkB1QERXe_*@F!1pF1oXqSOSnSFgx}S2kPe&QfB*f*usOO4^D%Gq`q2O;f8V}+ zYfzCDFuduVRjXEU4yV@%oC?y*EMw_;<}lwTsR&?r8$1|CA8E4$ozZ;??ZXd0+`n<- z#+}fw4jgthoB`+-I|Z+d9)xEL@ka>%gNiBxESiRgEd-H0jX{%;?*x1n#u|dLY88u9 z2%OU+QioF-!<}9ycp6M8PKg7s;hZAI0GPfRrF#A5&6^Kz+qUgI-|0e}kjvnxF7?M% z;S7+dUX#7>!VAAd$R};uwCT4Pd?`HmOWbT7n~y&M^Z(Z?ue@^aEw|kAW1QEx06oDH zI6X}vaFz4%fj9O9OkG?Z9UVte@Ek(fegGVH3Ey3X&Lp8Bd_T-(JW|;U(U-wtQy{2M zz3;yJ76ZVm@OCNko!+GvJ2B_~DGd$An0n)lH!j67D?PG2zo!u>40|;-DbR5lK(Rjb z=|C~I@5?X0{OqNdUOEJ4I0+Ww2H+8hm;0SjeDP)_G3^x|4eEzr&2M9{QnEbyQ2<^C z1va3>q;)MNXjm`Y&gq3-R-zc3z$e+%^hT2Hh4CAayC+e`p1|yL4Da>Y0MJcBLr;G4 z0c?PJU#q_u;dJ&49{!85KadE(>d#?z*rY7Y2Vo}gArM+2rBql+P@aa`;~VOGRq|?J zL9)SMFW?$ikY{}W96-7eu!I5}uK~Dd`41@boW|^Eh=8X7{sR%Y0wIg~h=rcVHLMp( zgDSa*ug28(1Pial3N~UWUrPgUb@mWEzZUtf!2c&mhTwZ4gAm>FXd@_p8&H!k7uAg3 zWzO~h>}e3?NlcA#dG;S}05E?IykkP|hY_9z+5Cl5h+aU92kFK7yS}=*nup4>I#_xZ zMboi&-g)Qi1{=Ep5R%V;$;(jad7=Tk4cvXZ^BQ`t#X ztt_Hw7?A&oYhODT{7I)%i#Lt^3I^kj#0sDJk{0I?Eu-+?HJsysxDO9dv}RpN;sB5V zJ>~vgtyLBXTe>HPlq`tS2j^l~%S&;3XL$Ij2@-rmP}^yfoS)z!${04ayw-E@991)*i#$G|}Go&hD;$C10

(gmBmd!ix6^kS1*8Rm^uMBi{qX$efUsn|PBU>T5c_TqB(5CB0^K%&uldo2SBiJ;gxc`Eppw^RPJ< z$KAo2;VysOKOdVNL^rRu-=q1xk5j|3tBd>Ju>a@5^6VFsgoXsih;7c^sO??i^00gL zG;o-sdO8@9|6hE3pSKd!LdV90|1-5D?!AxA@Lyos`5sZNpKk8ops1MQY9g8{s<9K~ z>Z5i6-Po(r^WtWX)imo1K>l7nzP=#!&$RL|;G-J&s`2Chd|>U$T}=aCSDWd8%&(cz z6mcCovKkI-j;{W?i&s!@z6~at+pR^Ki&v=5#IkUGJbm219v*M6UJgFw3i?@|5xtE zR=3yV`TR3S|Gmv{R*a6{$M0>BN5E^-Rm@ROqr6L?|MmTE=U__>d9uHL;@{5Tb1dY; z>Nrph6uuFwn(MeNcIh2>+rdKc`LX&iIobc0oZ$tDzZGb>vw-w8ZNqbEY;w}Ut?ldY zc@yAQig#pVS%bvz{dRbN-hnnWV9)(L3z(d|l*94!cw9ahpFVhq%^|O*nnvLs(bvz- zHQ4gQ|EwhnrP#g-;rdsVEZyRZ2|0E*R0yvp z9b!0MTJq;(uiq>m#wNZKlsYf-9iGvg`6pz;R|E_S5!)1lBW3S6+azTGFNCxXl zB2Pe@=eHj)uE_s3>s52-@CJ0SyXgCEZ6C25+7;gD$H#=G)bTATeK!X`|7Yu96&de# z_Srv=&|sD3=IiA0aPLF<>?h~@?8G_|j6EgA=XcF~z1fa#MNS?;t=FWtmQVWC(d;vz zb}WD1_y|h(oapr>at0K~OjrhnZ0BQK7yv7o2z5D|g+*n)fV&w&Jum?fN(H(49DyOZ zZU%7;EK_e_bSyH0Zia|h78M_`M}yQBLD9&e!e|0?L53mHZc|dwb&lA?uz486E4rtV zs0Iw#p;;4SWW6iGz%jvHFz<*{!89^C@ijR;0`z@Wy-uNqJ;7<|o0^)r z3Zf?xs23VOCecfP?uyt86H~=n6uxNt>J9U`ha@>>f+Ao?nCNU!Hi+SBXa$&DMmPa@ zXGUZd+4AS)`6IQ0MG&+EE+tg{rcI)L%2=9c%&L&hFyXh{?%Q!R6I^FU?oB{090x0$ROQU-{B0 z5~;TgbKgB(^m=0_-y0ZSquJAWbJg?&b0f3^Z(HHiM%^Geec_X|MYXzJLcG)6+-8%Rj!4ebFD< zfjjvU{+eGNJ|1i@1uVO z`|b=hL8>Im^_~2fJ@P6Q>mx0>9flN8qKP(>4(pd~@+T)T7OVn&b&2h{rfVu-^f@J% z`}U{sly<*w87UdPRp>r`-UHfRAV6aWj4wtEU@VJyK)=>?jun_haavH5&ah}74VF+4 zy#!>0Q$B~$+;A-Cx9VOKQ(_*>J;pi8oasx>_gYyjKL(RZf1~U0jvNR=7 zgC?NWW#zYpKskm%X^5Bi&vq?<(ti*-jLs||-A=$7gSD!b5Lwk)1??d)$W)So+KBPN zI3Xmn6;QQ4Q-I%rK`Gyip{mx(8P?T6W`P!nL=_~zczeHN3@YM5eZ>7+xLB$hoxLIW zBMOu`e$TYgSUPS2peD&XVn?tljW+DP;RLNGe1i_T?oPYlY(RvkAxyTI3B8~b zjO(9|bjCnq(;7Un8S<20BPlM}3%QZ(g3}Fydn*N6SDy$#?ffok(%33F*p-yi8?3+; z3Nw`;n|sInr+-uGS<|30tAwRENFRNOp&j|uIY=|2sW*+`w_yFV!->F9dMs0(8~ z8Rtdu7bw#wqLfiER8`TD^im+Pnf>-fzA*q4oP5JuNkMkD&mr50nf{E+G$z;dX&zbs z+rw|BLjcgqy09T_<~6+eOl3`Y@mQ!;QJ@V|Xz}`11Y#^e@d9rRjv|U*1C$PAxWy1c z+>|~+78F2v$lBE{sk6CHx!C2LGYVCVln{tvXMDZH1ie;3GS(9vhuimB zFVYWgtUU-}Bz$FVWQBCQvS||T8~`WB3(q>Bil>>TN%O@#1)2$%4AhEFAZZD$X9Dg9 zqzN9&>hwNxc4s_~mhWxnITVdfpO^xs$DBTCx3YU%M_Jo%yjXibwJ7xzIvJ$IKF0K# zh>1lE$f%tm$xn2+qOxBq+RWn6K$rGu9eDGfH}U}Q;}Z)c4`evF)R7st3X6p|@=<<$ z-zyGVN=C|tBD(UOqJ|;(?%b?_i_VLM@(5NJ@ymtw3JZmZ4UMD+>0T>G5ALc>i>-Lm z(I)m&w&$Ej9DVT!v7E&_R3Fgb%F`nYIDK!SX2gRCFO)ctLv-Y~?po}gVCffn>0C~% zQFQbssO?*XCh|71ZJsl{l?ThbG$PKF??Kb5c?~TxvEiw1=|}Tz^$~xuc581F@M&2n zV8P6rI%9-c4O4PoN`pm>ji5*@w+AH|+p&qekG$fm>Oz!dYJ`6qT^qW<0PFrp zQ*-^o*7b?fG!*7$Cj=|9+{rwJJ_#g&^n#(PMy`w*0|?37+cwjTi`Kk141>ltLTFwo z{Wmw~b4z>rr*hG~I1X zNRrYH0o_LEk7yG*j)*wwDKhHW-m=< zz2%I^o;Xrosl=-L_)X_(Br$5UOgM=|pf6Elg z-D}M%?Aifc(ys`ud!}8H*>+C4!n5xF?ugL2cioa46V!RbJa=B@Ss?mt-mEBe=e}Ew zs|eh9T%P61f7NvN9GC9r>OY0tJ@UkC#B&o(?qInb|&2t7$9i?vA=SJwr-o-b8WlNLdW)nJ$fCU(usC zYcaaDr!J0l4A*Gf{Et}R&h39Fk1F%sxu2&Q_@Czs4^gUcWESONHyG1$8|on<(K;-f zJ%cJk`381xFJerubqDPX{oRILX9fuim>FZi$J64p zSPwt5+$~lgT0E+GRU#*SNaU$$fiH9f?~uu?O!*^Zazh{AgGiH(pEklR?l%XMW#L4G zQZjxoc%v&~tqtLxyA_PPKC~#P3C#6_$dGMds}(s<)dpYIe(}?Xt2-lZ~o?|W{wOId#ES4KbE^=exS?_3voDXu>1!<>Bufw#*AnQ58d8UW%~ zE61UZ`LNah(80T9l!N@6w_+zBAus!qpIbwubqAluM2hM3U5?Vpm-|;aBhBN3G%RLc zEgjy^XNAvq6peqX_5PR5Bk4V=tPhS17dC!7p9lI)VK;;Nmk!a%seA)63aUeJxH~+a z0)~5jQqM$K;pORHkTuVB>%-O2N67s`mV;jz+P)}MtD4S3WeAHQWxh2m7{-2{)nsFq zDE95rSWQqAWYbC5k&xQmt*G`!f*9X1@t_EJ-_ChKGk{B`*>ad}i*I(@Pme)XY8cYS zMeDtC-=MH#xeqaLH(9AH1lk6%V`~FSYfv<~lanIO4GD`NTk2@xARLm>t>^oHe(+A= z?P#y>qS!F7`K*TtU%L?>r_c%rc|9>5_T-skHxHQh`|^Fdfi~dCXCAwtXY*g%H=fYC z{D%QHU*Ndnw901{5J_}EFJ8U8^^eQ=?~bnbgBooWxm(N~Tsv{t+C}FUGeLBgmJ>@I zG-MAvCn7sqm@4!6&K;YGj^XZ|unC@?ExU-W>HpI6dHbK{G990pzcPl_B~w@LVG$)x zYCP4R6sUK^4DUep7=5F8_szqjUUb1^!jB#n^8uN zExkW`iT|!x zA1S~Y@lB%VOcCb<>BZ_*ir`sl}R(R+PP z?@6{j(J{Cj?$;c>Y~`ah6HT{^*%kjZl$EPP^UZ4H(E;=Bpvxn4j=}qgKCk;l+?BTu z_6m8duJ7*_a%*nxk(!bhk?x3jGOr*1O9Avh*o%{H|8lkDcisNEpUcbhZq9$<@W!}(H|7~NR}n^VP{|?c(_6jjh^~T~YRkSd=ziYQw;wy+dL4g; zdTUNr>-?ClI^OMYRjO*+9xzo+lw!@ zwnsC@7h~Lr_WK6!9 z+p(9G8Gw16f0BbGj+)=T{v324>Fe*Pu-p^i`s|I*$5##x*fr0ras#;fzMwtaIse<`(V&D;fi1wd9Yyu+B zPI#*?1+!$V1_F08sv{B9g`v{iSf`bPk_-aqnY5)t89p9_zkA)ec`S2nBp}IXB_<%6 z#f_*0GaAzoHA_q92cxQXgB`D}rHA3tJO}<%6o7u(*ZqI=Cf5L1L;`ge=CQgeWQU!0_XM>m| zU`j9KG%3>0EW-_hWo9&+%oTA#E6F(QicAX%r|?YeGYkJIbV{0W5{)?}05Y!Q*a&U7 zT7X;EB1(fLqD5{<#}_^iG?A*}8->oydK1nZpCb~b;E-%6Jz_@jHB4j`y^5ZvtOd)F zWIGw@Ql_v%XM@1uy^#r4t-*;wQcB?mrWTc2WG~;2z=uzzdEiuD+^RIDw=)Cw4lfc9 zD=o-zqy#B!;ZSV>iw1uGHZ;PKf7+4r8L}@hJhx`_n+?MAxI&7rQVL>9R)2>X&P=K( z5a-D@S|HAB*N9k2OM6ebvQUs28r}IMEzB6Jasv`3UPXoQjO0xXP1-QR(&Q-Dz@YFb z8!``6KXIjJxl_WJTw7-s92FpvLjN{_AeXfE*{a7n2dkR2@*yV34pL9e7{#SWpe!LS z;RHv+9idY!7Ar2xQo36n&-$#yWS)vx)ZuMO1UIB81M~E<&5WP|NkefY;qQ7tB{w`> zi`xXD(f$&;G2xBxvzg|u2n}h5LD@?|w&GdCw!og0KwSjs4pW0BuTuWDTpCv-GNP69 z=25h3V-u`QM@1OQiu7JAhZM#u!%f}b8wYgbRX~FVXHBrFJ$Hyip}J||qZWBrxj1C` zHYvkWm8i*p$BdG5o6fFKz$)5q7MEkQTEzutG8CNQWlCPDi?U6_fE9}tg4zHVcn-WM zA+e2g5Rz{~nebGs4;>uVez!wS`FK8jmxLX~S1&g|FktHCe0e@!K3)H9<HpM}4+}o7{@1!0AhIHz`?Ymx&l6;_OQ*^BPI2T6 z`p&)T!T)+kKsmiT)U$l#`U{@RoB#NDyfhi&8~iH4vba--XFreFNIrVMO0{h$9^Q=X z>frqBP+VPnGqAc$mhG@Gw~c+ivfN8g6O5=tZxpF1Px3_yYYBtI3yw_2w1hPdW`{?R z?t*2e<{U$52o#|#%-hL%eQ9;?>3Uh&e0iDm3L3>v&!ubt5&x4XJK=YILkV9&jyVB= zO|M??VpZx%{Y$TWCeB!4a%pjCciR(c)KbULlE4jBVMR-3FXRYaRTfmaY_d)J&uiYX!PTENhGDuWk=LU;D)}8TTO?=$=X))mgm5v*4nei5CX+4doj&at029~@ zB;#|AV1hp;El?*!u{OjZ6#-Fx1(_NVN}y4i62@7HgcorvRTuUKr=Fo$gK&bqz0MM| z`U_4++X7LDDNaoB7yS~mP}K8>VhSvcbdxE3&BvHokhLeU093^T;EQgX07y71Bh!+y zaUCjK!iz1y)XxCXo;#vW0g3)aqNv=BF5RZ`CxKu_B0JIhu64$fQF#iV`4Gy=mvL^{ zrx~nOLwB&03Rd@bm#PWq9ZR=jeLKJ+zMHckQtl9jK2h1QBJFTM3a8LRxDD#7?O}U_ z``??@PZN>DX@4K%W4nU2yfs5U}9N= zDz*cwpi>PT2Cr~BrY5+Mh;9Il4qZY{t=>N|%a`dPf5^ERIlGx6@@CK|Wol9d2$C~v zN}}F+KJM{zb2;0Q(WOL3JHxMmo#BK1LxLHpbAq1P;!&R zov^hGRe~ba3n)>NE_v0>K{rb5KPdXsS;;Rg!Cyw$CdTxMz5DrsA*@gdR$_lFHgGM% zc>+(&*9H>6sD-laOUzj=4P*H4z{E|+vlXoPu&S>ZtA(IaA#2ZKCraU2+37VqqHW#Q zml`>F+yKxWx4~xa2itnlaldkTUgkhH^Q`T8d-%Bc_wLT!8OA2A*MHR0w}r zQDJgkxV&G~vtL5d61*=yOJ&vl*?+e3rrH>M=*ROp+-XUt+}c+Pb`zNz|59exTfBEE z4+X8l&xH|?fyoSm{i0nd4W>dFWD+DLduLt8%TCh`Ye1n{@Z?25pTbX}>kw>KE)9f) zf}oi~G2{a)UZgU~WNi(m8w~9c4D7nhC=)EZ8d%AAe{3E`7*YDn2#Dy!+yWbE9tO3a z>RSul7$p_TK(_IYEjDEmbk{~^X3(CR0sRwg)t-jRY-W5ZJX_qbySE`uaCIb<^W=sY z-kn9aZ}+80(%Gtxc#~hBSKzlZ_K@MS!i?Dt@x#f-)ua6d)$1;gCm?kRi=w3O=c!mK zuH>r{<5IN~hjzo6W)tqvc3Y_;QxrwCY9A5639{HN&%&fOmL&}IF; zHNAF(EN<)}F2KxLwbD7rt3iQ@glDzfZVE1gEsTT2lwr|ks3R4`I}Kn`>C&+DLMy~f!Wsvg9^_ygHT?GG!Db2)iKYUpoaZE z!PS0ryEka>Hiy{N;42;+Gw8+LxIW;24kE_u^-&aRAa6=|wl{?gxpMSZA2QjtX!iPAjIRw{)k{c*o57q=1`irQ6(l@1kF`IxOll~D9F z5nw}8qZHMPiyfJs+^HKEKfDR4iH+mLP+e`x#j~^J;oQ7GI<^!pRF1v5wlvwgSPW|i z7XM<4p7aYK)0dLGxPncZp|-|PS0R&62=EmUqu~s7?%@)XPE36PC?pD}E){zTh&gkh zom^f~CuJ&@{PzsWDrvNaUHQa3*?9Jk*$OkIVlo99*5H0KSjSXBjvO3bD(9x zCu!E1l@|#c3{^!4X%H$GKvQyF8e?wtVUa;W#z)A2pxo!LK zR#b5oxGlq=1qs<*dNFb)m*WqO9>?QA+YgOkVpOJ~bGvrzwIr>y{1q-0J(Ww90@5SV zz;;tpN@W28h9C&PQsmf=DQ%S{c2VTEks;&2&u~*{mkAr9;I=s$lo{){31gN%C`QR# zqjWgUM7POOA<~=#EhztPF=M2cw*k)#>e$r^!lgJVBQY`M(6j5U9~*cJlG~}ER4F*d zM1ce6MN*{0^yqG3CO| z>0d0_dQ9}N0|cZn15*EL#OTT4{ZLz-@|ABe((Nw#Hlr<H6+@ z5AnfNHQn(Yz!}eW-0~UKnb!0=@E0bMCHC3z=VLD{laCznq$m7DjUK=8qMz|jsnB5V2TT;CRN$%SHp^29mF01isPM4#;g5kpo0rX*5-{3y z&0JJ)t)6(o&++^E>3ymY3^hFhh2B2tp#8o!v9oMBncWpT)APm*RhPxERpy1-$x<$6 zwWtR-!RL5gYi&TB&FxW{@~i>V*&Eo(QtceNN)Oud&~W1J?%FZoGM z1%|4MKG&QkV;^k_KdMJZs13{_R9C*{dTBDU!kc%0C< za!@$wF+GKd<(xnxB)xE!Q{X-7&soXvX0ZDF(?6sm^#=WKXJ^%E14V7p|JlXNEIGs&+}^cw0_Wdh?G|9yjbNe)Fu1XmraQx zU(~5XSs;hDQ0)qKT9VtObrvA)7&*)B^bMKWrA>J{MN6P@6%vJ#zGj{a&fRDxP~*}> zfjKeCT_~yiJj;m{ow6AN)T;N%39jKlVwUpy{PSjH1~hvf!||JOpKpJ|`*1SgI$B@f z{uk?F;?5T5-cjN3uj}q5SEKl=2CIEHD^sPquk!<1M!9l&RX{W$uw; z7AW`P?SCqd3$_tLxi0MtF-yx4yFzI?`Q74CI8BO;b6$K5<$xOVyIOn+;9ysh8uQ49#2)Hbf0 z4aN7!c4YHFeXfPhBR7ndukR=1-{Ed6_nm%zS8OhVrrH=&T zCA%3&zsv>=RlT+ZhoQ<$vt1QvAKNui5~v0RJuBDMlagJy$#GG^yBadAX+RYQ@*NZ? zmjw2m;;Bju%eDOt)>aYpRp79s3C*+xK-rWc09+8Y#Ow&Xs|s6T7M*8V|FXXo=oA&g zt6nsn;dJGQE_i1Z{)sT!Xhz5tE424cDlDF)`N%S{j18{3rVcZwNSosuPB0oFcamZx zOX0LrU=XG5guMlX&I-O94~4yM3#TYD+bYnNu#)t?&Ir$Cgxn-)R!B!NZUN!wS;Rxgt?bmaJ!;`XK)0EE*mzreQ{6x%&Zec@bis)PU z^7m~=GQHV_s;P@lvSc%Kl#Q-CAzF(9^e*q!T;x-1D1=B<$#s5x8xyu^9Mp3aqOG$A zRVBOLN{MF| zoVUQ`S8o1OqkWxX{c)W(jwK*c!Tfkg*NxfHM?YmV@*9$&x5~d_AL~{>xoMh0rk-Se zSwCr8@9|GH?UioQC)av~B5O`Lh5Y9`x_L)5`l=tu zi1hubb|&kbUkTm-btx~$Df%92veu%)PdS20 z9CEO9W@VG90NpCd;HKt!u@b7LZEHy^G&)=I5(VzV&Pjl~YQi_$R7$jfS>#K#{#$>Y zK7jLZ_%bzLV&K+A`7*ib#9h+=JQVe)B0bT!3I2De!e6Vyo%GYbCMMP6tsPD>s?x(S zdF50!71~2$g@1_Zs?@#++Xx_|G7c~l9GEL)27Um zYBJ>p=#^<|Sn6bpT=(14sYDGSGtsVXg(ZKW5#W+>7bHQ}%v=^u>QTgoa+q}RN}`PP zWostU-B4M|lvQ=)JR6dnYoJQfKSIO^C%{j)kIqBn*2t#~LQ8y>&0i-0d)l1hGe7x} zL*mW;1(P)q+{>R~s={gWsS{u&w$~h!#8Qh&_hdqc1E3->qhU&<=EvH;1DI2+*&;ed zAxniCNmXptI0#WL17!&2M2eD}E^15`5--g36mv!`V`5eadN0O+W zaKsX`y!dQ}&jN+iYt4X(Q+oNV$NnL6i=meLmmS~7YqCaV;Ma$ zC>_Fh0)Ffpl@29V=#V8#K+0c$C1$+KFDT{>jD0G_% zABQ!nm;mvbP+E{V!$u)5ITZrbd2W%;$W+iYHBL73-o5JxP_>(QZOPALgqh(s(&<## zPz~+LWbAaiR3;XV)b3#Ipjdf`z*m$sBt+*f^kNQf%6}Bgynu#k#JJSg%1cBKQ#}rm zuMyFgs`^b-9)tvpqzg71Dq)|4UFP!{qVPbn9GN&T70l#Sr4TP)4G{*Ip?fvSLRo87 z3{aGJBtu*d$irP_Fh-V|4%JA?YL?LZ4G>SN3;bf0GL^R#T!+=+q@ZG)V_M6891S6u&&U*`nF%uKH{orDuSrFGN~sEquNYY>Utxo=BKfUCv-{9NAjP+A}xd_RfP~^ldaLcGIwFhcj)q-N40^lL2@%8o`f;3 zu%I%gb?zW&6;uvJ%d8xAg*B+K(iUfM2#u*RvL%lZueZSLg~01H$jVnEVMNc_@V9(m zZd>J$s~}~t5i>c@{Qk~53~kkEbX!(Fg40kyTdv}!>!9PBir>q$Vm29$EjnCgr~-Ck z1#I~%rzUDUYg!L$YV4dFIdurqgp@MV{(BXBVFH!2aD)@@r=jJ+fN+IzP8`Pekrsso zx=!9delWRGejY=mXziBbXQYGVR_Kr5M)_P?YJ(BT=%|nh*k*KeVMD+0)#SFGrB3_APj6HaO1=$b)U!Pz1T~UNm-I-^7de{U zTk;zO8H@|M=$E=-l(ZbHDuKzN7lCJjV>^HokN%(qLN{S_o(yFoT7?H7nnHz&)%hER zMqKbLAlcU;xs$L#g6DC1o#BYrQOO(FTdnLZq*8aH;)S%ovROnBuZE!J3~!M{Kg@Sv zZUQ1q`CsYcgtTW*I>S*q87i}s zEJ9dkEG+j-pV`Tu$=hekCBc z1_pPn9EGfP7PNIRc#H*{sK!K;4n$-0)rGjb84FrX9fM}}NA29T#RZX278M7%#mBfG zwQuTv2rn~a>i#dGglb1UY*ca9Sx=Plt0dC)YBpp+8h}Y5iHbu1f!pTTG(HrFq-7vD zWh->khAxgh-4~U|DQBwVNO`@KWM>9t>SfePe;853m{9{MkZrTW^n9Dd!m8K`e)?$a zjQE>1D5=;qo|8326}xGi0#`Pt#yQqRHF$&DEZ$SKY#s$r{M$@N{BLXtw zA`}VI^72J@0rwU@>@ehf3_CcIkBF1hN!TrC;W&lEg%3xA_qa0&%e*lPG+J2?3W3IL z6|yw}-itC`NEdsE63LtvCZ3x_)I`W?9kRB?mKsJ_44K#0X)Hioo&6V;YlQ*~&Alp! zvfWE5$lrxZ!HSut^mUjDx{8@VNVCjDCb1n~k_^q?NHub0+n(=DqR1I5V{Y6c2IeJ9 zn^VXZHCB}7u(6Ove68GK#SH~i&O(U4^x%>@M4_Rq6dnpHtQalP*y|yAun-Ps!WlJ? z&Qr!nDF1E*jn#G)H2e$Fwe`~opvTdq9?a z15Ms+y$ZPaQv*<#P^d|Cx22$LdE$xb?y>MA--F0N#7~)Zk)kJmNPuiDh0j>K}+zgi@hFsT~3Aob=RM^$x9=etAq8e?6@R}xi` z*o+hj>!sk}VnO26>oq4>xa*TVAd5ShsWNV<))5`Y4VeSGF<#q)yY``> z22~gf6TQx^QxMei7pSZ2zbF@qY;St&PjVd6l~B<$QAb@NM)4umd>cl!sa8!`qAje( z)V%5NUHulsPt{tXpv3HJ(7k15i@+%&!|)p_WN48yyl$~$lHr&|a#OLyWp$zBaOcI7 zB_?)KBQFEuHKj6IM8)ALUTpOV*Hmh-Y*Uxo1Q>Y{9Xwq>1H&MV_ zLtF(>jKO!Q?bi(i@XU$lE2>~2(5Itk?G>^+Dg>pkjK~oL5<21@;$(D`UBIp@*UHWY zWx!$11%_(s-n`c&5TE>kIl5(w@ky)8qMAzwnXjmV6c>fM9b`f_&(9A`-PsN$B!(sO>eg3S={Q920q|{oX|1DWDboy_YRo87PWp z{!YRIx8nN5`WExkqNX4@eU}eBbNB~b?{9c4|M@q3N7$sm|NScPdHax5FYx^#@?Q8o zIUfGh=pl;2dL`vfv#XBc`*xBaj8W&!;cBkdkkh1#1}2bz}E zts*H!S!ED>{OP*35}Jj539}cF^5i&_&@z@H#UaN0dnF`>IQ{A0^~Mx1eNkhDU?NhDxoIu99;?;kupk-uz4EA#WU_XYfU&))ml>HqFO Q68Ir9G~dec4Fd)Fe++e|^Z)<= literal 0 HcmV?d00001 diff --git a/icons/small/hi16-apps-okular.svgz b/icons/small/hi16-apps-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..9b4385d0063040ba0a85ec7950a93afe202d71c5 GIT binary patch literal 4116 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 N{{j5`1geI;0RR_#LeKyJ literal 0 HcmV?d00001 diff --git a/interfaces/configinterface.h b/interfaces/configinterface.h new file mode 100644 index 0000000..2131959 --- /dev/null +++ b/interfaces/configinterface.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2007 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_CONFIGINTERFACE_H_ +#define _OKULAR_CONFIGINTERFACE_H_ + +#include "../core/okularcore_export.h" + +#include + +class KConfigDialog; + +namespace Okular +{ +/** + * @short Abstract interface for configuration control + * + * This interface defines a way to configure the Generator itself. + * + * How to use it in a custom Generator: + * @code + class MyGenerator : public Okular::Generator, public Okular::ConfigInterface + { + Q_OBJECT + Q_INTERFACES( Okular::ConfigInterface ) + + ... + }; + * @endcode + * and - of course - implementing its methods. + */ +class OKULARCORE_EXPORT ConfigInterface +{ +public: + ConfigInterface() + { + } + + /** + * Destroys the config interface. + */ + virtual ~ConfigInterface() + { + } + + ConfigInterface(const ConfigInterface &) = delete; + ConfigInterface &operator=(const ConfigInterface &) = delete; + + /** + * This method is called to tell the generator to re-parse its configuration. + * + * Returns true if something has changed. + * + * @note this method can be called also when the generator is not the + * active generator, or when there was not changed in the config added + * by the generator itself. So the suggestion is to @b check whether + * something changed, and only in that case return @p true + */ + virtual bool reparseConfig() = 0; + + /** + * This method allows the generator to add custom configuration pages to the + * config @p dialog of okular. + */ + virtual void addPages(KConfigDialog *dialog) = 0; +}; + +} + +Q_DECLARE_INTERFACE(Okular::ConfigInterface, "org.kde.okular.ConfigInterface/0.1") + +#endif diff --git a/interfaces/guiinterface.h b/interfaces/guiinterface.h new file mode 100644 index 0000000..1a88a8e --- /dev/null +++ b/interfaces/guiinterface.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2007 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_GUIINTERFACE_H_ +#define _OKULAR_GUIINTERFACE_H_ + +#include "../core/okularcore_export.h" + +#include + +#include + +namespace Okular +{ +/** + * @short Abstract interface for user interface control + * + * This interface defines an way to interact with the Okular user interface, + * e.g. adding actions in the menus. + * + * How to use it in a custom Generator: + * @code + class MyGenerator : public Okular::Generator, public Okular::GuiInterface + { + Q_OBJECT + Q_INTERFACES( Okular::GuiInterface ) + + ... + }; + * @endcode + * and - of course - implementing its methods. + */ +class OKULARCORE_EXPORT GuiInterface : protected KXMLGUIClient +{ +public: + GuiInterface() + { + } + + /** + * Destroys the gui interface. + */ + ~GuiInterface() override + { + } + + GuiInterface(const GuiInterface &) = delete; + GuiInterface &operator=(const GuiInterface &) = delete; + + /** + * This method requests the XML GUI Client provided by the interface. + */ + KXMLGUIClient *guiClient() + { + return this; + } +}; + +} + +Q_DECLARE_INTERFACE(Okular::GuiInterface, "org.kde.okular.GuiInterface/0.1") + +#endif diff --git a/interfaces/printinterface.h b/interfaces/printinterface.h new file mode 100644 index 0000000..bcf361b --- /dev/null +++ b/interfaces/printinterface.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2007 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_PRINTINTERFACE_H_ +#define _OKULAR_PRINTINTERFACE_H_ + +#include "../core/okularcore_export.h" + +#include + +class QWidget; + +namespace Okular +{ +/** + * @short Abstract interface for advanced printing control + * + * This interface defines an advanced way of interfacing with the print + * process. + * + * How to use it in a custom Generator: + * @code + class MyGenerator : public Okular::Generator, public Okular::PrintInterface + { + Q_OBJECT + Q_INTERFACES( Okular::PrintInterface ) + + ... + }; + * @endcode + * and - of course - implementing its methods. + */ +class OKULARCORE_EXPORT PrintInterface +{ +public: + PrintInterface() + { + } + + /** + * Destroys the printer interface. + */ + virtual ~PrintInterface() + { + } + + PrintInterface(const PrintInterface &) = delete; + PrintInterface &operator=(const PrintInterface &) = delete; + + /** + * Builds and returns a new printing configuration widget. + * + * @note don't keep a pointer to the new constructed widget, as it + * will be handled elsewhere (in the Okular KPart) + * + * @note The returned object should be of a PrintOptionsWidget subclass + * (which is not officially enforced by the signature for binary + * compatibility reasons). + */ + virtual QWidget *printConfigurationWidget() const = 0; +}; + +} + +Q_DECLARE_INTERFACE(Okular::PrintInterface, "org.kde.okular.PrintInterface/0.1") + +#endif diff --git a/interfaces/saveinterface.h b/interfaces/saveinterface.h new file mode 100644 index 0000000..0adf3a8 --- /dev/null +++ b/interfaces/saveinterface.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * 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_SAVEINTERFACE_H_ +#define _OKULAR_SAVEINTERFACE_H_ + +#include "../core/okularcore_export.h" + +#include + +namespace Okular +{ +class AnnotationProxy; + +/** + * @short Abstract interface for saving + * + * This interface defines a way to save (or help saving) the document opened + * by the Generator. + * + * How to use it in a custom Generator: + * @code + class MyGenerator : public Okular::Generator, public Okular::SaveInterface + { + Q_OBJECT + Q_INTERFACES( Okular::SaveInterface ) + + ... + }; + * @endcode + * and - of course - implementing its methods. + */ +class OKULARCORE_EXPORT SaveInterface +{ +public: + /** + * The possible options for the saving. + */ + enum SaveOption { + NoOption = 0, + SaveChanges = 1 ///< The possibility to save with the current changes to the document. + }; + Q_DECLARE_FLAGS(SaveOptions, SaveOption) + + SaveInterface() + { + } + + /** + * Destroys the save interface. + */ + virtual ~SaveInterface() + { + } + + SaveInterface(const SaveInterface &) = delete; + SaveInterface &operator=(const SaveInterface &) = delete; + + /** + * Query for the supported saving options. + * + * @note NoOption is never queried + */ + virtual bool supportsOption(SaveOption option) const = 0; + + /** + * Save to the specified @p fileName with the specified @p options. + */ + virtual bool save(const QString &fileName, SaveOptions options, QString *errorText) = 0; + + /** + * Returns the annotation proxy. Generators can return NULL if native + * annotations are not supported. + * + * @note Returning NULL is equivalent to returning an AnnotationProxy + * that doesn't support any capability. + * @since 0.15 (KDE 4.9) + */ + virtual AnnotationProxy *annotationProxy() const = 0; +}; + +} + +Q_DECLARE_INTERFACE(Okular::SaveInterface, "org.kde.okular.SaveInterface/0.3") +Q_DECLARE_OPERATORS_FOR_FLAGS(Okular::SaveInterface::SaveOptions) + +#endif diff --git a/interfaces/viewerinterface.h b/interfaces/viewerinterface.h new file mode 100644 index 0000000..bba71ae --- /dev/null +++ b/interfaces/viewerinterface.h @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2011 by Michel Ludwig * + * * + * 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_VIEWERINTERFACE_H_ +#define _OKULAR_VIEWERINTERFACE_H_ + +#include "../core/okularcore_export.h" +#ifdef Q_OS_WIN +#define VIEWERINTERFACE_EXPORT __declspec(dllexport) +#else +#define VIEWERINTERFACE_EXPORT OKULARCORE_EXPORT +#endif + +#include +#include + +namespace Okular +{ +/** + * @short Abstract interface for controlling advanced features of a document viewer + * + * This interface can be used to control some more or less advanced features of a document + * viewer. + */ +class VIEWERINTERFACE_EXPORT ViewerInterface +{ +public: + ViewerInterface() + { + } + virtual ~ViewerInterface() + { + } + + ViewerInterface(const ViewerInterface &) = delete; + ViewerInterface &operator=(const ViewerInterface &) = delete; + + /** + * Show the specified source location centrally in the viewer. + * + * @param fileName source file name + * @param line in the source file, starts from 0 + * @param column in the source file, starts from 0 + * @param showGraphically controls whether the given source location will be + * shown graphically in the viewer (if that feature is globally activated) + */ + virtual void showSourceLocation(const QString &fileName, int line, int column, bool showGraphically = true) = 0; + + /** + * Clear the source location that was set last in the viewer. + */ + virtual void clearLastShownSourceLocation() = 0; + + /** + * Returns true iff source locations are shown graphically. + */ + virtual bool areSourceLocationsShownGraphically() const = 0; + + /** + * Allows to control whether source locations are shown graphically, or not. + */ + virtual void setShowSourceLocationsGraphically(bool b) = 0; + + /** + * Returns true iff the watch file mode is enabled. + */ + virtual bool isWatchFileModeEnabled() const = 0; + + /** + * Allows to enable or disable the watch file mode + */ + virtual void setWatchFileModeEnabled(bool b) = 0; + + /** + * Should the shell that supports tabs open new files in tabs? + */ + virtual bool openNewFilesInTabs() const = 0; + + // SIGNALS + /** + * The signal 'openSourceReference' is emitted whenever the user has triggered a source + * reference in the currently displayed document. + */ + void openSourceReference(const QString &absFileName, int line, int column); + + /** + * The signal 'viewerMenuStateChange' is emitted whenever the state of the menu + * 'menu_okular_part_viewer' defined in 'part-viewermode.rc' has changed. + */ + void viewerMenuStateChange(bool enabled); +}; + +} + +Q_DECLARE_INTERFACE(Okular::ViewerInterface, "org.kde.okular.ViewerInterface/0.1") + +#endif diff --git a/kdocumentviewer.h b/kdocumentviewer.h new file mode 100644 index 0000000..82ea1d7 --- /dev/null +++ b/kdocumentviewer.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2007 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 _KDOCUMENTVIEWER_H_ +#define _KDOCUMENTVIEWER_H_ + +#include "okularpart_export.h" + +#include + +class QUrl; + +/** + * @short Abstract interface for a document viewer + * + * This interface describes the basic functions of a document viewer. + */ +class OKULARPART_EXPORT KDocumentViewer +{ +public: + KDocumentViewer() + { + } + virtual ~KDocumentViewer() + { + } + + KDocumentViewer(const KDocumentViewer &) = delete; + KDocumentViewer &operator=(const KDocumentViewer &) = delete; + + /** + * Open the document at the specified @p url at page @p page. + */ + virtual bool openDocument(const QUrl &url, uint page) = 0; + + /** + * Change to @p page the currently shown page. + */ + virtual void goToPage(uint page) = 0; + + /** + * Start the presentation mode. + */ + virtual void startPresentation() = 0; + + /** + * Return a list with the supported mimetypes. + */ + virtual QStringList supportedMimeTypes() const = 0; +}; + +Q_DECLARE_INTERFACE(KDocumentViewer, "org.kde.kdocumentviewer/0.1") + +#endif diff --git a/metainfo.yaml b/metainfo.yaml new file mode 100644 index 0000000..b2d449f --- /dev/null +++ b/metainfo.yaml @@ -0,0 +1,16 @@ +maintainer: aacid +description: Okular, the unified document viewer +platforms: + - name: Linux + - name: Windows + - name: MacOSX +release: true + +public_lib: true +public_source_dirs: + - core + - interfaces + - Mainpage.dox +logo: icons/128-apps-okular.png +irc: okular +mailinglist: okular-devel diff --git a/mobile/CMakeLists.txt b/mobile/CMakeLists.txt new file mode 100644 index 0000000..094160d --- /dev/null +++ b/mobile/CMakeLists.txt @@ -0,0 +1,4 @@ + +add_subdirectory( app ) +add_subdirectory( components ) + diff --git a/mobile/android/AndroidManifest.xml b/mobile/android/AndroidManifest.xml new file mode 100644 index 0000000..fdd97c8 --- /dev/null +++ b/mobile/android/AndroidManifest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/android/res/drawable/icon.png b/mobile/android/res/drawable/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd2cda63de4b51d4721709e0bbf922a50ae8d2a GIT binary patch literal 11390 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 + + + https://download.qt-project.org/ministro/android/qt5/latest + + + + + + + + + + + + + + + + + + + + diff --git a/mobile/android/res/values/strings.xml b/mobile/android/res/values/strings.xml new file mode 100644 index 0000000..9c5ad89 --- /dev/null +++ b/mobile/android/res/values/strings.xml @@ -0,0 +1,3 @@ + + + diff --git a/mobile/android/src/OpenFileActivity.java b/mobile/android/src/OpenFileActivity.java new file mode 100644 index 0000000..e6b1bdf --- /dev/null +++ b/mobile/android/src/OpenFileActivity.java @@ -0,0 +1,70 @@ +package org.kde.something; + +import android.content.ContentResolver; +import android.content.Intent; +import android.util.Log; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.net.Uri; +import android.app.Activity; + +import java.io.FileNotFoundException; + +import org.qtproject.qt5.android.bindings.QtActivity; + +class FileClass +{ + public static native void openUri(String uri); +} + +public class OpenFileActivity extends QtActivity +{ + + public String contentUrlToFd(String url) + { + try { + ContentResolver resolver = getBaseContext().getContentResolver(); + ParcelFileDescriptor fdObject = resolver.openFileDescriptor(Uri.parse(url), "r"); + return "fd:///" + fdObject.detachFd(); + } catch (FileNotFoundException e) { + Log.e("Okular", "Cannot find file", e); + } + return ""; + } + + + private void displayUri(Uri uri) + { + if (uri == null) + return; + + if (!uri.getScheme().equals("file")) { + try { + ContentResolver resolver = getBaseContext().getContentResolver(); + ParcelFileDescriptor fdObject = resolver.openFileDescriptor(uri, "r"); + uri = Uri.parse("fd:///" + fdObject.detachFd()); + } catch (Exception e) { + e.printStackTrace(); + + //TODO: emit warning that couldn't be opened + Log.e("Okular", "failed to open"); + return; + } + } + + Log.e("Okular", "opening url: " + uri.toString()); + FileClass.openUri(uri.toString()); + } + + public void handleViewIntent() { + final Intent bundleIntent = getIntent(); + if (bundleIntent == null) + return; + + final String action = bundleIntent.getAction(); + Log.v("Okular", "Starting action: " + action); + if (action == "android.intent.action.VIEW") { + displayUri(bundleIntent.getData()); + } + } +} diff --git a/mobile/app/CMakeLists.txt b/mobile/app/CMakeLists.txt new file mode 100644 index 0000000..3def6ef --- /dev/null +++ b/mobile/app/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CMAKE_AUTORCC ON) +add_executable(okularkirigami main.cpp app.qrc) +target_link_libraries(okularkirigami Qt5::Widgets Qt5::Qml KF5::I18n) +if (ANDROID) + find_package(Qt5 COMPONENTS AndroidExtras) + target_sources(okularkirigami PRIVATE android.cpp) + target_link_libraries(okularkirigami Qt5::AndroidExtras) +endif() + +install(TARGETS okularkirigami ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +install(FILES package/metadata.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} RENAME org.kde.okular.kirigami.desktop) +install( FILES org.kde.okular.kirigami.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/mobile/app/Messages.sh b/mobile/app/Messages.sh new file mode 100644 index 0000000..c5fde96 --- /dev/null +++ b/mobile/app/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.qml` -L Java -o $podir/org.kde.active.documentviewer.pot diff --git a/mobile/app/android.cpp b/mobile/app/android.cpp new file mode 100644 index 0000000..242ccb1 --- /dev/null +++ b/mobile/app/android.cpp @@ -0,0 +1,63 @@ +/************************************************************************************* + * Copyright (C) 2018 by Aleix Pol * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#include "android.h" +#include +#include +#include +#include +#include + +URIHandler URIHandler::handler; +static AndroidInstance *s_instance = nullptr; + +void AndroidInstance::openFile(const QString &title, const QStringList &mimes) +{ + s_instance = this; + QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); // activity is valid + Q_ASSERT(activity.isValid()); + + QAndroidJniEnvironment _env; + QAndroidJniObject::callStaticMethod("org/kde/something/OpenFileActivity", + "openFile", + "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;)V", + activity.object(), + QAndroidJniObject::fromString(title).object(), + QAndroidJniObject::fromString(mimes.join(';')).object()); + if (_env->ExceptionCheck()) { + _env->ExceptionClear(); + qWarning() << "couldn't launch intent"; + } +} + +void AndroidInstance::handleViewIntent() +{ + QtAndroid::androidActivity().callMethod("handleViewIntent", "()V"); +} + +void Java_org_kde_something_FileClass_openUri(JNIEnv *env, jobject /*obj*/, jstring uri) +{ + jboolean isCopy = false; + const char *utf = env->GetStringUTFChars(uri, &isCopy); + const QString uriString = QString::fromUtf8(utf); + if (s_instance) + s_instance->openUri(QUrl(uriString)); + else + URIHandler::handler.openUri(uriString); + env->ReleaseStringUTFChars(uri, utf); +} diff --git a/mobile/app/android.h b/mobile/app/android.h new file mode 100644 index 0000000..76f0847 --- /dev/null +++ b/mobile/app/android.h @@ -0,0 +1,55 @@ +/************************************************************************************* + * Copyright (C) 2018 by Aleix Pol * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#ifndef ANDROID_H +#define ANDROID_H + +#include +#include +#include + +class URIHandler +{ +public: + void openUri(const QString &uri) + { + m_lastUrl = uri; + } + + QString m_lastUrl; + static URIHandler handler; +}; + +class AndroidInstance : public QObject +{ + Q_OBJECT +public: + Q_SCRIPTABLE void openFile(const QString &title, const QStringList &mimes); + + static void handleViewIntent(); + +Q_SIGNALS: + void openUri(const QUrl &uri); +}; + +extern "C" { + +JNIEXPORT void JNICALL Java_org_kde_something_FileClass_openUri(JNIEnv *env, jobject /*obj*/, jstring uri); +} + +#endif diff --git a/mobile/app/app.qrc b/mobile/app/app.qrc new file mode 100644 index 0000000..d2bf294 --- /dev/null +++ b/mobile/app/app.qrc @@ -0,0 +1,12 @@ + + +package/contents/ui/Bookmarks.qml +package/contents/ui/main.qml +package/contents/ui/MainView.qml +package/contents/ui/OkularDrawer.qml +package/contents/ui/TableOfContents.qml +package/contents/ui/Thumbnails.qml +package/contents/ui/ThumbnailsBase.qml +package/contents/ui/TreeDelegate.qml + + diff --git a/mobile/app/main.cpp b/mobile/app/main.cpp new file mode 100644 index 0000000..f1a687b --- /dev/null +++ b/mobile/app/main.cpp @@ -0,0 +1,73 @@ +/************************************************************************************* + * Copyright (C) 2010 by Aleix Pol * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * + *************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __ANDROID__ +#include "android.h" + +Q_DECL_EXPORT +#endif +int main(int argc, char *argv[]) +{ + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication app(argc, argv); + app.setApplicationName(QStringLiteral("okularkirigami")); + + QCommandLineParser parser; + parser.addVersionOption(); + parser.addHelpOption(); + // parser.setApplicationDescription(i18n("Okular mobile")); + parser.process(app); + QQmlApplicationEngine engine; + +#ifdef __ANDROID__ + AndroidInstance::handleViewIntent(); + qmlRegisterSingletonType("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine *, QJSEngine *) -> QObject * { return new AndroidInstance; }); + const QString uri = URIHandler::handler.m_lastUrl; +#else + qmlRegisterSingletonType("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine *, QJSEngine *) -> QObject * { return new QObject; }); + const QString uri = parser.positionalArguments().count() == 1 ? QUrl::fromUserInput(parser.positionalArguments().constFirst(), {}, QUrl::AssumeLocalFile).toString() : QString(); +#endif + engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); + engine.rootContext()->setContextProperty(QStringLiteral("uri"), uri); + QVariantMap paths; + paths[QStringLiteral("desktop")] = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + paths[QStringLiteral("documents")] = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + paths[QStringLiteral("music")] = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); + paths[QStringLiteral("movies")] = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); + paths[QStringLiteral("pictures")] = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + paths[QStringLiteral("home")] = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + engine.rootContext()->setContextProperty(QStringLiteral("userPaths"), paths); + + engine.setBaseUrl(QUrl(QStringLiteral("qrc:/package/contents/ui/"))); + engine.load(QUrl(QStringLiteral("qrc:/package/contents/ui/main.qml"))); + return app.exec(); +} diff --git a/mobile/app/org.kde.okular.kirigami.appdata.xml b/mobile/app/org.kde.okular.kirigami.appdata.xml new file mode 100644 index 0000000..f3312e8 --- /dev/null +++ b/mobile/app/org.kde.okular.kirigami.appdata.xml @@ -0,0 +1,282 @@ + + + org.kde.okular.kirigami.desktop + CC0-1.0 + GPL-2.0+ and GFDL-1.3 + Okular Mobile + Okular Mobil + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mobile + Okular για κινητά + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mugikorra + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mobile + Okular 모바일 + Okular mobilioji + Okular mobiel + Okular mobil + Okular Mobile + Okular Móvel + Okular móvel + Okular Mobile + Okular Mobile + Okular Mobile + Okular Mobil + Мобільний Okular + xxOkular Mobilexx + Okular Mobile + Okular 行動版 +

Document Viewer + Sənədə baxış vasitısi + Visor de documents + Visor de documents + Prohlížeč dokumentů + Dokumentenbetrachter + Πρόγραμμα προβολής εγγράφων + Document Viewer + Visor de documentos + Dokumendinäitaja + Dokumentu erakuslea + Asiakirjakatselin + Afficheur de document + Visor de documentos + Visor de documento + Penampil Dokumen + Visore di documenti + 문서 뷰어 + Dokumentų žiūryklė + Documentenviewer + Dokumentvisar + Przeglądarka dokumentów + Visualizador do Documento + Visualizador de documentos + Просмотр документов + Prehliadač dokumentov + Pregledovalnik dokumentov + Dokumentvisare + Перегляд документів + xxDocument Viewerxx + 文档查看器 + 文件檢視器 + +

+ Okular is a universal document viewer developed by KDE. Okular works on multiple platforms, including but not limited to Linux, Windows, Mac OS X, *BSD, etc. +

+

Okular KDE tərəfindən yaradılan sənədlərə universal baxış vasitəsidir. Okular Linux, Windows, Mac OS X, * BSD və s. digər bir çox platformada işləyir.

+

L'Okular és un visor universal de documents desenvolupat pel KDE. L'Okular funciona en múltiples plataformes, incloent-hi però sense limitar-se a Linux, Windows, Mac OS X, *BSD, etc.

+

L'Okular és un visor universal de documents desenvolupat pel KDE. L'Okular funciona en múltiples plataformes, incloent-hi però sense limitar-se a Linux, Windows, Mac OS X, *BSD, etc.

+

Okular ist ein universeller Dokumentenbetrachter, der von KDE entwickelt wird. Okular ist auf mehreren Plattformen verfügbar, darunter auch Linux, Windows, Mac OS X, *BSD usw.

+

Το Okular είναι ένα καθολικό πρόγραμμα προβολής εγγράφων που αναπτύχθηκε από το KDE. Το Okular λειτουργεί σε πολλές πλατφόρμες, συμπεριλαμβανομένων αλλά όχι μόνο των Linux, Windows, Mac OS X, *BSD, κλπ.

+

Okular is a universal document viewer developed by KDE. Okular works on multiple platforms, including but not limited to Linux, Windows, Mac OS X, *BSD, etc.

+

Okular es un visor universal de documentos desarrollado por KDE. Okular funciona en diversas plataformas, incluidas Linux, Windows, Mac OS X, *BSD, etc.

+

Okular on KDE loodud universaalne dokumendinäitaja. Okular töötab paljudel platvormidel, sealhulgas Linuxil, Windowsis, Mac OS X-is, *BSD-s jne.

+

Okular KDEk garatutako dokumentu erakusle unibertsal bat da. Okular hainbat plataformatan dabil, haien artean baino ez soilik haietara mugatua, Linux, windows, Mac OS X, *BSD, etab.

+

Okular on KDE:n kehittämä yleinen tiedostokatselin. Okular toimii monella alustalla kuten Linuxissa, Windowsissa, macOSissa, BSD:ssä jne.

+

Okular est un afficheur universel de documents développé par KDE. Okular fonctionne sur de multiples plate-formes, comme Linux, Windows, Mac OS X, etc.

+

Okular é un visor de documentos universal desenvolvido por KDE. Okular funciona en varias plataformas, entre elas Linux, Windows, Mac OS X, *BSD, etc.

+

Okular es un visor universal de documento disveloppate per KDE. Okular functiona sur platteformas multiple includente sed non limitate a Linux,Windows, MacOS X, *BSD, etc.

+

Okular adalah penampil dokumen universal yang dikembangkan oleh KDE. Okular bekerja pada banyak platform, termasuk tetapi tidak terbatas pada Linux, Windows, Mac OS X, *BSD, dll.

+

Okular è un lettore universale di documenti sviluppato da KDE. Okular funziona su varie piattaforme, incluse (ma non solo) Linux, Windows, Mac OS X, *BSD, ecc.

+

Okular는 KDE에서 개발한 문서 뷰어입니다. 리눅스, Windows, macOS, *BSD 등 다양한 플랫폼에서 사용할 수 있습니다.

+

Okular yra universali, KDE plėtojama dokumentų žiūryklė. Okular veikia keliose platformose, įskaitant, tačiau neapsiribojant Linux, Windows, Mac OS X, *BSD ir t.t.

+

Okular is een universele documentviewer ontwikkeld door KDE. Okular werkt op meerdere platforms, inclusief, maar niet beperkt tot Linux, Windows, Mac OS X, *BSD, etc.

+

Okular er ein dokumentvisar for mange ulike filformat, og er utvikla av KDE. Okular køyrer på fleire plattformer, blant anna Linux, Windows, Mac OS X og *BSD.

+

Okular jest wszechstronną przeglądarką dokumentów opracowaną przez KDE. Okular działa na wielu platformach takich jak Linux, Windows, Mac OS X, *BSD, itp.

+

O Okular é um visualizador universal de documentos desenvolvido pelo KDE. O Okular funciona em diversas plataformas, incluindo mas não se limitando ao Linux, Windows, Mac OS X, *BSD, etc.

+

O Okular é um visualizador de documentos universal desenvolvido pelo KDE. Ele funciona em várias plataformas, incluindo, mas não se limitando, o Linux, Windows, Mac OS X, *BSD, etc.

+

Okular — универсальная программа просмотра документов от KDE. Okular работает на многих платформах: Linux, Windows, Mac OS X, *BSD и других.

+

Okular je univerzálny zobrazovač dokumentov vyvynutý týmom KDE. Okular funguje na viacerých platformách, vrátane týchto: Linux, Windows, MAC OS X, *BSD, atď.

+

Okular je univerzalni pregledovalnik dokumentov, ki ga je razvil KDE. Okular deluje na več platformah, vključno z Linuxom, Windows, Mac OS X, * BSD itd.

+

Okular är en universell dokumentvisare utvecklad av KDE. Okular fungerar på flera plattformar, inklusive men inte begränsat till Linux, Windows, Max OS X, *BSD, etc.

+

Okular є універсальною програмою для перегляду документів, розробленою KDE. Okular може працювати на багатьох програмних платформах, зокрема Linux, Windows, Mac OS X, *BSD тощо.

+

xxOkular is a universal document viewer developed by KDE. Okular works on multiple platforms, including but not limited to Linux, Windows, Mac OS X, *BSD, etc.xx

+

Okular 是由 KDE 开发的通用文档查看器。Okular 可在多个平台上运行,包括但不是限于 Linux,Windows,Mac OS X,* BSD,等。

+

Okular 是個由 KDE 開發的一款通用文件檢視器。Okular 能在多個平台上運作,包含但不限於 Linux、Windows、Mac OS X 以及各個 BSD 等。

+

Features:

+

İmkanlar:

+

Característiques:

+

Característiques:

+

Vlastnosti:

+

Funktionen:

+

Χαρακτηριστικά:

+

Features:

+

Funciones:

+

Omadused:

+

Eginbideak:

+

Ominaisuuksia:

+

Fonctionnalités :

+

Funcionalidades:

+

Characteristicas:

+

Fitur:

+

Funzionalità:

+

기능:

+

Ypatybės:

+

Kenmerken:

+

Funksjonar:

+

Możliwości:

+

Funcionalidades:

+

Funcionalidades:

+

Возможности:

+

Funkcie:

+

Možnosti:

+

Funktioner:

+

Можливості:

+

xxFeatures:xx

+

功能:

+

功能:

+
    +
  • Supported Formats: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Dəstəklənən formatlar: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Formats acceptats: PDF, PS, Tiff, CHM, DjVu, imatges, DVI, XPS, ODT, Fiction Book, llibres de còmic, Plucker, EPub, Fax
  • +
  • Formats acceptats: PDF, PS, Tiff, CHM, DjVu, imatges, DVI, XPS, ODT, Fiction Book, llibres de còmic, Plucker, EPub, Fax
  • +
  • Podporované formáty: PDF, PS, Tiff, CHM, DjVu, obrázky, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Unterstützte Formate: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Υποστηριζόμενοι τύποι αποθήκευσης: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Supported Formats: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Formatos permitidos: PDF, PS, Tiff, CHM, DjVu, imágenes, DVI, XPS, ODT, Fiction Book, libros de cómics, Plucker, EPub, Fax
  • +
  • Toetatud vormingud: PDF, PS, Tiff, CHM, DjVu, pildid, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Onartutako formatuak: PDF, PS, Tiff, CHM, DjVu, irudiak, DVI, XPS, ODT, FictionBook, Comic Book, Plucker, EPub, Fax
  • +
  • Tuetut tiedostomuodot: PDF, Postscript, TIFF, CHM, DjVu, kuvat, DVI, XPS, OpenDocument, Fiction Book, sarjakuvakirja, Plucker, EPub, faksi
  • +
  • Formats de fichiers gérés : PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Formatos compatíbeis: PDF, PS, Tiff, CHM, DjVu, imaxes, DVI, XPS, ODT, FictionBook, banda deseñada, Plucker, EPub e fax.
  • +
  • Formatos supportate: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Format Yang Didukung: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Formati supportati: PDF, PS, Tiff, CHM, DjVu, immagini, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • 지원하는 형식: PDF, PS, Tiff, CHM, DjVu, 그림, DVI, XPS, ODT, Fiction Book, 만화책, Plucker, EPub, 팩스
  • +
  • Palaikomi formatai: PDF, PS, Tiff, CHM, DjVu, paveikslai, DVI, XPS, ODT, Fiction Book, komiksų knygos, Plucker, EPub, faksas
  • +
  • Ondersteunde formaten: PDF, PS, Tiff, CHM, DjVu, Afbeeldingen, DVI, XPS, ODT, Fictie boek, Stripboek, Plucker, EPub, Fax
  • +
  • Støtta format: PDF, PS, Tiff, CHM, DjVu, bilete, DVI, XPS, ODT, e-bøker, teikneseriar, Plucker, EPub, Fax
  • +
  • Obsługiwane formaty: PDF, PS, TIFF, CHM, DjVu, DVI, XPS, ODT, FB2, Plucker, ePub, a także różne formaty komisów, obrazów i faks.
  • +
  • Formatos Suportados: PDF, PS, Tiff, CHM, DjVu, Imagens, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Suporte aos formatos: PDF, PS, TIFF, CHM, DjVu, imagens, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Поддержка форматов PDF, PS, Tiff, CHM, DjVu, изображений, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, факсов;
  • +
  • Podporované formáty: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Podprti formati: PDF, PS, Tiff, CHM, DjVu, slike, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Format som stöds: PDF, PS, Tiff, CHM, DjVu, bilder, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Fax
  • +
  • Підтримувані формати: PDF, PS, Tiff, CHM, DjVu, зображення, DVI, XPS, ODT, Fiction Book, комікси, Plucker, EPub, факси.
  • +
  • xxSupported Formats: PDF, PS, Tiff, CHM, DjVu, Images, DVI, XPS, ODT, Fiction Book, Comic Book, Plucker, EPub, Faxxx
  • +
  • 支持的格式︰ PDF,PS,Tiff,CHM,DjVu,图片,DVI,XPS,ODT,FictionBook,漫画书,Plucker,EPub,传真
  • +
  • 支援的格式:PDF, PS, Tiff, CHM, DjVu, 影像, DVI, XPS, ODT, 小說書籍, 漫畫書, Plucker, EPub, 傳真
  • +
  • Sidebar with contents, thumbnails, reviews and bookmarks
  • +
  • Tərkibləri, miniatürləri, öncədən baxışı və əlfəcinləri ilə yan panel
  • +
  • Barra lateral amb el contingut, miniatures, revisions i punts
  • +
  • Barra lateral amb el contingut, miniatures, revisions i punts
  • +
  • Seitenleiste mit Inhalt, Vorschaubildern, Rezensionen und Lesezeichen
  • +
  • Πλευρική γραμμή με περιεχόμενα, εικόνες επισκόπησης, αναλύσεις και σελιδοδείκτες
  • +
  • Sidebar with contents, thumbnails, reviews and bookmarks
  • +
  • Barra lateral con contenido, miniaturas, revisiones y marcadores
  • +
  • Külgriba sisukorra, pisipiltide, arvustuste ja järjehoidjatega
  • +
  • Alboko-barra edukiekin, koadro-txikiekin, iritziekin eta laster-markekin
  • +
  • Sivupaneeli, jossa sisällys, pienoiskuvat, arvostelut ja kirjanmerkit
  • +
  • Barre latérale montrant les contenus, vignettes, informations de relecture et signets
  • +
  • Barra lateral con contido, miniaturas, revisións e marcadores.
  • +
  • Barra lateral con contentos, miniaturas, revisiones e marcatores de libro
  • +
  • Bilah sisi dengan konten, gambar-mini, ulasan, dan markah
  • +
  • Barra laterale con contenuti, miniature, revisioni e segnalibri
  • +
  • 목차, 축소판, 검토 및 책갈피 도구가 있는 사이드바
  • +
  • Å oninė juosta su turiniu, miniatiÅ«romis, atsiliepimais ir žymelėmis
  • +
  • Zijbalk met inhoud, miniaturen, reviews en bladwijzers
  • +
  • Sidestolpe med innhaldsliste, miniatyrbilete, omtalar og bokmerke
  • +
  • Pasek boczny z treścią, miniaturami, recenzjami i zakładkami
  • +
  • Barra lateral com o conteúdo, miniaturas, revisões e marcação de favoritos
  • +
  • Barra lateral com o conteúdo, miniaturas, revisões e favoritos
  • +
  • Боковая панель с содержанием, миниатюрами страниц, комментариями и закладками;
  • +
  • Bočný panel s obsahom, náhľadmi, hodnoteniami, a záložkami
  • +
  • Stranska vrstica z vsebino, sličicami, pregledi in zaznamki
  • +
  • Sidorad med innehÃ¥ll, miniatyrbilder, granskningar och bokmärken
  • +
  • Бічні панелі зі списками змісту, мініатюрами сторінок, можливість рецензування та додавання закладок.
  • +
  • xxSidebar with contents, thumbnails, reviews and bookmarksxx
  • +
  • 目录,缩略图,批注和书签侧边栏
  • +
  • 側邊欄包含了內容、縮圖、評論以及書籤
  • +
  • Annotations support
  • +
  • Şərh yazılmasını dəstəkləyir
  • +
  • Admet anotacions
  • +
  • Admet anotacions
  • +
  • Podpora poznámek
  • +
  • Unterstützung für Anmerkungen
  • +
  • Υποστήριξη σημειώσεων
  • +
  • Annotations support
  • +
  • Permite el uso de notas
  • +
  • Annotatsioonide toetus
  • +
  • Idatzoharrak onartzen ditu
  • +
  • Merkintöjen tuki
  • +
  • Gestion des annotations
  • +
  • Funcionalidade de anotacións.
  • +
  • Supporto de annotationes
  • +
  • Dukungan anotasi
  • +
  • Supporto per annotazioni
  • +
  • 주석 지원
  • +
  • Anotacijų palaikymas
  • +
  • Ondersteuning van annotaties
  • +
  • Støtte for merknadar
  • +
  • Obsługa przypisów
  • +
  • Suporte para anotações
  • +
  • Suporte a anotações
  • +
  • Поддержка комментариев.
  • +
  • Podpora anotácií
  • +
  • Podpora zaznamkom
  • +
  • Stöd för kommentarer
  • +
  • Підтримка анотування.
  • +
  • xxAnnotations supportxx
  • +
  • 支持批注
  • +
  • 支援註釋功能
  • +
+
+ + + Reading manual in Okular + Okular'da oxumaq təlimatı + Lectura de manuals a l'Okular + Lectura de manuals a l'Okular + Lesen eines Handbuchs in Okular + Ανάγνωση οδηγού χρήσης στο Okular + Reading manual in Okular + Lectura del manual en Okular + Käsiraamatu lugemine Okularis + Eskuliburua Okularren irakurtzea + Oppaan lukeminen Okularissa + Lecture d'un manuel dans Okular + Ler o manual en Okular + Legente manual in Okular + Membaca manual di Okular + Consultazione di un manuale in Okular + Okular로 설명서 읽기 + Vadovo skaitymas programoje Okular + Handleiding wordt gelezen in Okular + Lesing av brukarhandbok i Okular + Instrukcja czytania w Okularze + Leitura de manual no Okular + Lendo manual no Okular + Документация, открытая в Okular + Čítanie návodu v Okular + Branje priročnikov v Okularju + Läsa handbok i Okular + Читання підручника в Okular + xxReading manual in Okularxx + 在 Okular 中阅读手册 + 在 Okular 中閱讀文件 + https://cdn.kde.org/screenshots/okular/okular.png + + + https://okular.kde.org/ + https://bugs.kde.org/enter_bug.cgi?format=guided&product=okular + KDE + + okularkirigami + + + + + + + + diff --git a/mobile/app/package/contents/ui/Bookmarks.qml b/mobile/app/package/contents/ui/Bookmarks.qml new file mode 100644 index 0000000..a6063b3 --- /dev/null +++ b/mobile/app/package/contents/ui/Bookmarks.qml @@ -0,0 +1,28 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 + + +ThumbnailsBase { + model: documentItem.bookmarkedPages + onPageClicked: { + pageArea.delegate.pageItem.goToBookmark(pageArea.delegate.pageItem.bookmarks[0]) + } +} diff --git a/mobile/app/package/contents/ui/MainView.qml b/mobile/app/package/contents/ui/MainView.qml new file mode 100644 index 0000000..751a688 --- /dev/null +++ b/mobile/app/package/contents/ui/MainView.qml @@ -0,0 +1,67 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.3 as QQC2 +import org.kde.okular 2.0 as Okular +import org.kde.kirigami 2.0 as Kirigami + +Kirigami.Page { + property alias document: pageArea.document + leftPadding: 0 + topPadding: 0 + rightPadding: 0 + bottomPadding: 0 + + actions.main: Kirigami.Action { + icon.name: pageArea.page.bookmarked ? "bookmark-remove" : "bookmarks-organize" + checkable: true + onCheckedChanged: pageArea.page.bookmarked = checked + text: pageArea.page.bookmarked ? i18n("Remove bookmark") : i18n("Bookmark this page") + } + + Okular.DocumentView { + id: pageArea + anchors.fill: parent + + onPageChanged: { + bookmarkConnection.target = page + actions.main.checked = page.bookmarked + } + onClicked: fileBrowserRoot.controlsVisible = !fileBrowserRoot.controlsVisible + } + + Connections { + id: bookmarkConnection + target: pageArea.page + onBookmarkedChanged: actions.main.checked = pageArea.page.bookmarked + } + QQC2.ProgressBar { + id: bar + z: 99 + visible: applicationWindow().controlsVisible + height: Kirigami.Units.smallSpacing + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + value: documentItem.pageCount !== 0 ? ((documentItem.currentPage+1) / documentItem.pageCount) : 0 + } +} diff --git a/mobile/app/package/contents/ui/OkularDrawer.qml b/mobile/app/package/contents/ui/OkularDrawer.qml new file mode 100644 index 0000000..8860b84 --- /dev/null +++ b/mobile/app/package/contents/ui/OkularDrawer.qml @@ -0,0 +1,115 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.5 as QQC2 +import org.kde.kirigami 2.0 as Kirigami +import org.kde.okular 2.0 as Okular + + +Kirigami.OverlayDrawer { + edge: Qt.RightEdge + contentItem: Item { + id: browserFrame + implicitWidth: Kirigami.Units.gridUnit * 45 + implicitHeight: implicitWidth + state: "Hidden" + + QQC2.StackView { + id: pageStack + anchors { + left: parent.left + top: parent.top + right: parent.right + bottom: tabsToolbar.top + } + clip: true + } + + Connections { + target: documentItem + onUrlChanged: thumbnailsButton.checked = true; + } + + QQC2.ToolBar { + id: tabsToolbar + height: mainTabBar.height + position: QQC2.ToolBar.Footer + anchors { + top: undefined + bottom: browserFrame.bottom + left: parent.left + right: parent.right + } + Component.onCompleted: thumbnailsButton.checked = true; + Item { + width: parent.width + height: childrenRect.height + Row { + id: mainTabBar + spacing: 0 + anchors.horizontalCenter: parent.horizontalCenter + width: Math.min(parent.width, implicitWidth) + QQC2.ButtonGroup { id: tabPositionGroup } + QQC2.ToolButton { + id: thumbnailsButton + text: tabsToolbar.width > Kirigami.Units.gridUnit * 30 ? i18n("Thumbnails") : "" + icon.name: "view-preview" + checkable: true + flat: false + onCheckedChanged: { + if (checked) { + pageStack.replace(Qt.createComponent("Thumbnails.qml")) + } + } + QQC2.ButtonGroup.group: tabPositionGroup + } + QQC2.ToolButton { + id: tocButton + enabled: documentItem.tableOfContents.count > 0 + text: tabsToolbar.width > Kirigami.Units.gridUnit * 30 ? i18n("Table of contents") : "" + icon.name: "view-table-of-contents-ltr" + checkable: true + flat: false + onCheckedChanged: { + if (checked) { + pageStack.replace(Qt.createComponent("TableOfContents.qml")) + } + } + QQC2.ButtonGroup.group: tabPositionGroup + } + QQC2.ToolButton { + id: bookmarksButton + enabled: documentItem.bookmarkedPages.length > 0 + text: tabsToolbar.width > Kirigami.Units.gridUnit * 30 ? i18n("Bookmarks") : "" + icon.name: "bookmarks-organize" + checkable: true + flat: false + onCheckedChanged: { + if (checked) { + pageStack.replace(Qt.createComponent("Bookmarks.qml")) + } + } + QQC2.ButtonGroup.group: tabPositionGroup + } + } + } + } + } +} diff --git a/mobile/app/package/contents/ui/TableOfContents.qml b/mobile/app/package/contents/ui/TableOfContents.qml new file mode 100644 index 0000000..2132567 --- /dev/null +++ b/mobile/app/package/contents/ui/TableOfContents.qml @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.2 as QQC2 +import QtQuick.Layouts 1.2 +import org.kde.kirigami 2.0 as Kirigami + +Kirigami.ScrollablePage { + id: root + + header: QQC2.ToolBar { + id: toolBarContent + width: root.width + QQC2.TextField { + id: searchField + width: parent.width + placeholderText: i18n("Search...") + } + } + ColumnLayout { + spacing: 0 + Repeater { + model: VisualDataModel { + id: tocModel + model: documentItem.tableOfContents + delegate: TreeDelegate { + Layout.fillWidth: true + sourceModel: tocModel + } + } + } + } +} diff --git a/mobile/app/package/contents/ui/Thumbnails.qml b/mobile/app/package/contents/ui/Thumbnails.qml new file mode 100644 index 0000000..d44fb18 --- /dev/null +++ b/mobile/app/package/contents/ui/Thumbnails.qml @@ -0,0 +1,45 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.0 as QQC2 +import org.kde.kirigami 2.0 as Kirigami + +ThumbnailsBase { + id: root + model: documentItem.matchingPages + + header: QQC2.ToolBar { + id: toolBarContent + width: root.width + QQC2.TextField { + id: searchField + width: parent.width + placeholderText: i18n("Search...") + enabled: documentItem ? documentItem.supportsSearching : false + onTextChanged: { + if (text.length > 2) { + documentItem.searchText(text); + } else { + documentItem.resetSearch(); + } + } + } + } +} diff --git a/mobile/app/package/contents/ui/ThumbnailsBase.qml b/mobile/app/package/contents/ui/ThumbnailsBase.qml new file mode 100644 index 0000000..342285e --- /dev/null +++ b/mobile/app/package/contents/ui/ThumbnailsBase.qml @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.3 as QQC2 +import QtGraphicalEffects 1.0 +import org.kde.okular 2.0 as Okular +import org.kde.kirigami 2.5 as Kirigami + +Kirigami.ScrollablePage { + id: root + property alias model: resultsGrid.model + property Item view: resultsGrid + signal pageClicked(int pageNumber) + + QQC2.Label { + anchors.centerIn: parent + visible: model.length == 0 + text: i18n("No results found.") + } + Kirigami.CardsListView { + id: resultsGrid + clip: true + + leftMargin: Kirigami.Units.largeSpacing * 10 + rightMargin: Kirigami.Units.largeSpacing * 10 + + delegate: Kirigami.AbstractCard { + highlighted: delegateRecycler && delegateRecycler.GridView.isCurrentItem + showClickFeedback: true + readonly property real ratio: contentItem.implicitHeight/contentItem.implicitWidth + height: width * ratio + contentItem: Okular.ThumbnailItem { + document: documentItem + pageNumber: modelData + Rectangle { + width: childrenRect.width + height: childrenRect.height + color: Kirigami.Theme.backgroundColor + radius: width + smooth: true + anchors { + top: parent.top + right: parent.right + } + QQC2.Label { + text: modelData + 1 + } + } + } + onClicked: { + resultsGrid.currentIndex = index + documentItem.currentPage = modelData + + contextDrawer.drawerOpen = false + root.pageClicked(modelData) + } + } + } +} diff --git a/mobile/app/package/contents/ui/TreeDelegate.qml b/mobile/app/package/contents/ui/TreeDelegate.qml new file mode 100644 index 0000000..9f5de5b --- /dev/null +++ b/mobile/app/package/contents/ui/TreeDelegate.qml @@ -0,0 +1,83 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 2.0 as QQC2 +import QtQuick.Layouts 1.2 +import org.kde.kirigami 2.0 as Kirigami + +Column { + id: treeDelegate + property variant sourceModel + property int rowIndex: index + width: parent.width + + property bool matches: display.toLowerCase().indexOf(searchField.text.toLowerCase()) !== -1 + + Kirigami.BasicListItem { + id: delegateArea + height: matches ? implicitHeight : 0 + opacity: matches ? 1 : 0 + Behavior on opacity { + NumberAnimation { duration: 250 } + } + Behavior on height { + NumberAnimation { duration: 250 } + } + + onClicked: { + documentItem.currentPage = page-1 + contextDrawer.drawerOpen = false + } + + label: display + highlighted: highlight + icon: highlight || highlightedParent ? (LayoutMirroring.enabled ? "arrow-left" : "arrow-right") : "" + + QQC2.Label { + text: pageLabel ? pageLabel : page + verticalAlignment: Text.AlignBottom + Layout.rightMargin: Kirigami.Units.largeSpacing + } + } + Column { + id: col + x: 20 + width: parent.width - 20 + property variant model: childrenModel + Repeater { + id: rep + model: VisualDataModel { + id: childrenModel + model: documentItem.tableOfContents + } + } + } + onParentChanged: { + if (treeDelegate.parent && treeDelegate.parent.model) { + sourceModel = treeDelegate.parent.model + } + + childrenModel.rootIndex = sourceModel.modelIndex(index) + + if (model.hasModelChildren) { + childrenModel.delegate = Qt.createComponent("TreeDelegate.qml") + } + } +} diff --git a/mobile/app/package/contents/ui/main.qml b/mobile/app/package/contents/ui/main.qml new file mode 100644 index 0000000..b2e06b9 --- /dev/null +++ b/mobile/app/package/contents/ui/main.qml @@ -0,0 +1,80 @@ +/* + * Copyright 2012 Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.7 +import QtQuick.Dialogs 1.3 as QQD +import org.kde.okular 2.0 as Okular +import org.kde.kirigami 2.0 as Kirigami +import org.kde.okular.app 2.0 + +Kirigami.ApplicationWindow { + id: fileBrowserRoot + visible: true + + header: null + globalDrawer: Kirigami.GlobalDrawer { + title: i18n("Okular") + titleIcon: "okular" + + QQD.FileDialog { + id: fileDialog + nameFilters: Okular.Okular.nameFilters + folder: "file://" + userPaths.documents + onAccepted: { + documentItem.url = fileDialog.fileUrl + } + } + + actions: [ + Kirigami.Action { + text: i18n("Open...") + icon.name: "document-open" + onTriggered: { + fileDialog.open() + } + } + ] + } + contextDrawer: OkularDrawer {} + + title: documentItem.windowTitleForDocument + Okular.DocumentItem { + id: documentItem + onUrlChanged: { currentPage = 0 } + } + + MainView { + id: pageArea + anchors.fill: parent + document: documentItem + } + + //FIXME: this is due to global vars being binded after the parse is done, do the 2 steps parsing + Timer { + interval: 100 + running: true + onTriggered: { + if (uri) { + documentItem.url = uri + } else { + globalDrawer.open(); + } + } + } +} diff --git a/mobile/app/package/metadata.desktop b/mobile/app/package/metadata.desktop new file mode 100644 index 0000000..095cf68 --- /dev/null +++ b/mobile/app/package/metadata.desktop @@ -0,0 +1,124 @@ +[Desktop Entry] +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +GenericName=Document viewer +GenericName[ar]=عارض المستندات +GenericName[az]=Sənədə baxış vasitısi +GenericName[bg]=Преглед на документи +GenericName[bs]=Prikazivač dokumenata +GenericName[ca]=Visor de documents +GenericName[ca@valencia]=Visor de documents +GenericName[cs]=Prohlížeč dokumentů +GenericName[da]=Dokumentfremviser +GenericName[de]=Dokumentenbetrachter +GenericName[el]=Προβολέας εγγράφων +GenericName[en_GB]=Document Viewer +GenericName[es]=Visor de documentos +GenericName[et]=Dokumendinäitaja +GenericName[eu]=Dokumentu erakuslea +GenericName[fi]=Asiakirjakatselin +GenericName[fr]=Afficheur de document +GenericName[ga]=Amharcán cáipéisí +GenericName[gl]=Visor de documentos +GenericName[hu]=Dokumentummegjelenítő +GenericName[ia]=Visor de documento +GenericName[is]=Skjalaskoðari +GenericName[it]=Visore di documenti +GenericName[ja]=文書ビューア +GenericName[kk]=Құжатты қарау құралы +GenericName[ko]=문서 뷰어 +GenericName[lt]=Dokumentų žiūryklė +GenericName[mr]=दस्तऐवज प्रदर्शक +GenericName[nb]=Dokumentviser +GenericName[nds]=Dokmentkieker +GenericName[nl]=Documentenviewer +GenericName[nn]=Dokumentvisar +GenericName[pa]=ਡੌਕੂਮੈਂਟ ਦਰਸ਼ਕ +GenericName[pl]=Przeglądarka dokumentów +GenericName[pt]=Visualizador de documentos +GenericName[pt_BR]=Visualizador de documentos +GenericName[ro]=Vizualizor de documente +GenericName[ru]=Просмотр документов +GenericName[sk]=Prehliadač dokumentov +GenericName[sl]=Pregledovalnik dokumentov +GenericName[sr]=Приказивач докумената +GenericName[sr@ijekavian]=Приказивач докумената +GenericName[sr@ijekavianlatin]=Prikazivač dokumenata +GenericName[sr@latin]=Prikazivač dokumenata +GenericName[sv]=Dokumentvisare +GenericName[tr]=Belge görüntüleyici +GenericName[uk]=Переглядач документів +GenericName[x-test]=xxDocument viewerxx +GenericName[zh_CN]=文档查看器 +GenericName[zh_TW]=文件檢視器 +Type=Application +Exec=okularkirigami +Icon=okular +X-KDE-ParentApp= +X-KDE-PluginInfo-Author=Marco Martin +X-KDE-PluginInfo-Email=mart@kde.org +X-KDE-PluginInfo-Name=org.kde.mobile.okular +X-KDE-PluginInfo-Version=1.0 +X-KDE-PluginInfo-Website=https://kde.org +X-KDE-PluginInfo-Category=Office +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-Plasma-MainScript=ui/main.qml diff --git a/mobile/components/CMakeLists.txt b/mobile/components/CMakeLists.txt new file mode 100644 index 0000000..2da2f9d --- /dev/null +++ b/mobile/components/CMakeLists.txt @@ -0,0 +1,49 @@ +project(okular) + +add_definitions(${QT_DEFINITIONS}) +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + + ${QIMAGEBLITZ_INCLUDES} +) + +set(okular_SRCS + okularplugin.cpp + ${CMAKE_SOURCE_DIR}/part/guiutils.cpp + ${CMAKE_SOURCE_DIR}/part/tocmodel.cpp + ${CMAKE_SOURCE_DIR}/part/pagepainter.cpp + ${CMAKE_SOURCE_DIR}/part/debug_ui.cpp + pageitem.cpp + documentitem.cpp + thumbnailitem.cpp + okularsingleton.cpp + ) + +kconfig_add_kcfg_files(okular_SRCS GENERATE_MOC ${CMAKE_SOURCE_DIR}/conf/settings_mobile.kcfgc) + +add_library(okularplugin SHARED ${okular_SRCS}) +set_target_properties(okularplugin PROPERTIES COMPILE_DEFINITIONS "okularpart_EXPORTS") +target_link_libraries(okularplugin + Qt5::Quick + Qt5::Qml + Qt5::Core + Qt5::Xml + Qt5::Svg + KF5::Bookmarks + KF5::IconThemes + KF5::I18n + KF5::Service + okularcore + ) + +if(ANDROID) + target_link_libraries(okularplugin Qt5::AndroidExtras) +endif() + +install(TARGETS okularplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular) +install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular) +install(FILES DocumentView.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular) +install(FILES private/PageView.qml DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/okular/private) + +#add_subdirectory(test) diff --git a/mobile/components/DocumentView.qml b/mobile/components/DocumentView.qml new file mode 100644 index 0000000..d7f3daf --- /dev/null +++ b/mobile/components/DocumentView.qml @@ -0,0 +1,292 @@ +/* + * Copyright 2015 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.2 +import QtQuick.Controls 2.2 as QQC2 +import org.kde.okular 2.0 +import "./private" + +/** + * A touchscreen optimized view for a document + * + * It supports changing pages by a swipe gesture, pinch zoom + * and flicking to scroll around + */ +QQC2.ScrollView { + id: root + property DocumentItem document + property PageItem page: mouseArea.currPageDelegate.pageItem + signal clicked + + //NOTE: on some themes it tries to set the flickable to interactive + //but we need it always non interactive as we need to manage + //dragging by ourselves + Component.onCompleted: flick.interactive = false + Flickable { + id: flick + interactive: false + onWidthChanged: resizeTimer.restart() + onHeightChanged: resizeTimer.restart() + + Component.onCompleted: { + flick.contentWidth = flick.width + flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio + } + Connections { + target: root.document + onUrlChanged: resizeTimer.restart() + } + Timer { + id: resizeTimer + interval: 250 + onTriggered: { + flick.contentWidth = flick.width + flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio + } + } + + PinchArea { + width: flick.contentWidth + height: flick.contentHeight + + property real initialWidth + property real initialHeight + + onPinchStarted: { + initialWidth = mouseArea.currPageDelegate.implicitWidth * mouseArea.currPageDelegate.scaleFactor + initialHeight = mouseArea.currPageDelegate.implicitHeight * mouseArea.currPageDelegate.scaleFactor + } + + onPinchUpdated: { + // adjust content pos due to drag + flick.contentX += pinch.previousCenter.x - pinch.center.x + flick.contentY += pinch.previousCenter.y - pinch.center.y + + // resize content + //use the scale property during pinch, for speed reasons + if (initialHeight * pinch.scale > flick.height && + initialHeight * pinch.scale < flick.height * 3) { + mouseArea.scale = pinch.scale; + } + resizeTimer.stop(); + flick.returnToBounds(); + } + onPinchFinished: { + flick.resizeContent(Math.max(flick.width+1, initialWidth * mouseArea.scale), Math.max(flick.height, initialHeight * mouseArea.scale), pinch.center); + mouseArea.scale = 1; + + resizeTimer.stop() + flick.returnToBounds(); + } + MouseArea { + id: mouseArea + width: parent.width + height: parent.height + + property real oldMouseX + property real oldMouseY + property real startMouseX + property real startMouseY + property bool incrementing: true + property Item currPageDelegate: page1 + property Item prevPageDelegate: page2 + property Item nextPageDelegate: page3 + + onPressed: { + var pos = mapToItem(flick, mouse.x, mouse.y); + startMouseX = oldMouseX = pos.x; + startMouseY = oldMouseY = pos.y; + } + onPositionChanged: { + var pos = mapToItem(flick, mouse.x, mouse.y); + + flick.contentY = Math.max(0, Math.min(flick.contentHeight - flick.height, flick.contentY - (pos.y - oldMouseY))); + + if ((pos.x - oldMouseX > 0 && flick.atXBeginning) || + (pos.x - oldMouseX < 0 && flick.atXEnd)) { + currPageDelegate.x += pos.x - oldMouseX; + mouseArea.incrementing = currPageDelegate.x <= 0; + } else { + flick.contentX = Math.max(0, Math.min(flick.contentWidth - flick.width, flick.contentX - (pos.x - oldMouseX))); + } + + oldMouseX = pos.x; + oldMouseY = pos.y; + } + onReleased: { + if (root.document.currentPage > 0 && + currPageDelegate.x > width/6) { + switchAnimation.running = true; + } else if (root.document.currentPage < document.pageCount-1 && + currPageDelegate.x < -width/6) { + switchAnimation.running = true; + } else { + resetAnim.running = true; + } + } + onCanceled: { + resetAnim.running = true; + } + onDoubleClicked: { + flick.contentWidth = flick.width + flick.contentHeight = flick.width / mouseArea.currPageDelegate.pageRatio + } + onClicked: { + var pos = mapToItem(flick, mouse.x, mouse.y); + if (Math.abs(startMouseX - pos.x) < 20 && + Math.abs(startMouseY - pos.y) < 20) { + root.clicked(); + } + } + onWheel: { + if (wheel.modifiers & Qt.ControlModifier) { + //generate factors between 0.8 and 1.2 + var factor = (((wheel.angleDelta.y / 120)+1) / 5 )+ 0.8; + + var newWidth = flick.contentWidth * factor; + var newHeight = flick.contentHeight * factor; + + if (newWidth < flick.width || newHeight < flick.height || + newHeight > flick.height * 3) { + return; + } + + flick.resizeContent(newWidth, newHeight, Qt.point(wheel.x, wheel.y)); + flick.returnToBounds(); + resizeTimer.stop(); + } else { + flick.contentY = Math.min(flick.contentHeight-flick.height, Math.max(0, flick.contentY - wheel.angleDelta.y)); + } + } + + PageView { + id: page1 + document: root.document + z: 2 + } + PageView { + id: page2 + document: root.document + z: 1 + } + PageView { + id: page3 + document: root.document + z: 0 + } + + + Binding { + target: mouseArea.currPageDelegate + property: "pageNumber" + value: root.document.currentPage + } + Binding { + target: mouseArea.currPageDelegate + property: "visible" + value: true + } + + Binding { + target: mouseArea.prevPageDelegate + property: "pageNumber" + value: root.document.currentPage - 1 + } + Binding { + target: mouseArea.prevPageDelegate + property: "visible" + value: !mouseArea.incrementing && root.document.currentPage > 0 + } + + Binding { + target: mouseArea.nextPageDelegate + property: "pageNumber" + value: root.document.currentPage + 1 + } + Binding { + target: mouseArea.nextPageDelegate + property: "visible" + value: mouseArea.incrementing && root.document.currentPage < document.pageCount-1 + } + + SequentialAnimation { + id: switchAnimation + ParallelAnimation { + NumberAnimation { + target: flick + properties: "contentY" + to: 0 + easing.type: Easing.InQuad + //hardcoded number, we would need units from kirigami + //which cannot depend from here + duration: 250 + } + NumberAnimation { + target: mouseArea.currPageDelegate + properties: "x" + to: mouseArea.incrementing ? -mouseArea.currPageDelegate.width : mouseArea.currPageDelegate.width + easing.type: Easing.InQuad + //hardcoded number, we would need units from kirigami + //which cannot depend from here + duration: 250 + } + } + ScriptAction { + script: { + mouseArea.currPageDelegate.z = 0; + mouseArea.prevPageDelegate.z = 1; + mouseArea.nextPageDelegate.z = 2; + } + } + ScriptAction { + script: { + mouseArea.currPageDelegate.x = 0 + var oldCur = mouseArea.currPageDelegate; + var oldPrev = mouseArea.prevPageDelegate; + var oldNext = mouseArea.nextPageDelegate; + + if (mouseArea.incrementing) { + root.document.currentPage++; + mouseArea.currPageDelegate = oldNext; + mouseArea.prevPageDelegate = oldCur; + mouseArea. nextPageDelegate = oldPrev; + } else { + root.document.currentPage--; + mouseArea.currPageDelegate = oldPrev; + mouseArea.nextPageDelegate = oldCur; + mouseArea.prevPageDelegate = oldNext; + } + mouseArea.currPageDelegate.z = 2; + mouseArea.prevPageDelegate.z = 1; + mouseArea.nextPageDelegate.z = 0; + } + } + } + NumberAnimation { + id: resetAnim + target: mouseArea.currPageDelegate + properties: "x" + to: 0 + easing.type: Easing.InQuad + duration: 250 + } + } + } + } +} diff --git a/mobile/components/Messages.sh b/mobile/components/Messages.sh new file mode 100644 index 0000000..2a5aa96 --- /dev/null +++ b/mobile/components/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name "*.cpp" -o -name "*.h"` -o $podir/org.kde.okular.pot diff --git a/mobile/components/documentitem.cpp b/mobile/components/documentitem.cpp new file mode 100644 index 0000000..b9fc842 --- /dev/null +++ b/mobile/components/documentitem.cpp @@ -0,0 +1,274 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "documentitem.h" + +#include +#include // krazy:exclude=includes + +#ifdef Q_OS_ANDROID +#include +#include +#endif + +#include +#include +#include + +#include "part/tocmodel.h" + +DocumentItem::DocumentItem(QObject *parent) + : QObject(parent) + , m_thumbnailObserver(nullptr) + , m_pageviewObserver(nullptr) + , m_searchInProgress(false) +{ + qmlRegisterUncreatableType("org.kde.okular.private", 1, 0, "TOCModel", QStringLiteral("Do not create objects of this type.")); + Okular::Settings::instance(QStringLiteral("okularproviderrc")); + m_document = new Okular::Document(nullptr); + m_tocModel = new TOCModel(m_document, this); + + connect(m_document, &Okular::Document::searchFinished, this, &DocumentItem::searchFinished); + connect(m_document->bookmarkManager(), &Okular::BookmarkManager::bookmarksChanged, this, &DocumentItem::bookmarkedPagesChanged); + connect(m_document->bookmarkManager(), &Okular::BookmarkManager::bookmarksChanged, this, &DocumentItem::bookmarksChanged); +} + +DocumentItem::~DocumentItem() +{ + delete m_document; +} + +void DocumentItem::setUrl(const QUrl &url) +{ + m_document->closeDocument(); + // TODO: password + QMimeDatabase db; + + QUrl realUrl = url; // NOLINT(performance-unnecessary-copy-initialization) because of the ifdef below this can't be const & + +#ifdef Q_OS_ANDROID + realUrl = QUrl(QtAndroid::androidActivity().callObjectMethod("contentUrlToFd", "(Ljava/lang/String;)Ljava/lang/String;", QAndroidJniObject::fromString(url.toString()).object()).toString()); +#endif + + const QString path = realUrl.isLocalFile() ? realUrl.toLocalFile() : QStringLiteral("-"); + + m_document->openDocument(path, realUrl, db.mimeTypeForUrl(realUrl)); + + m_tocModel->clear(); + m_tocModel->fill(m_document->documentSynopsis()); + m_tocModel->setCurrentViewport(m_document->viewport()); + + m_matchingPages.clear(); + for (uint i = 0; i < m_document->pages(); ++i) { + m_matchingPages << (int)i; + } + emit matchingPagesChanged(); + emit urlChanged(); + emit pageCountChanged(); + emit openedChanged(); + emit supportsSearchingChanged(); + emit windowTitleForDocumentChanged(); + emit bookmarkedPagesChanged(); +} + +QString DocumentItem::windowTitleForDocument() const +{ + // If 'DocumentTitle' should be used, check if the document has one. If + // either case is false, use the file name. + QString title = Okular::Settings::displayDocumentNameOrPath() == Okular::Settings::EnumDisplayDocumentNameOrPath::Path ? m_document->currentDocument().toDisplayString(QUrl::PreferLocalFile) : m_document->currentDocument().fileName(); + + if (Okular::Settings::displayDocumentTitle()) { + const QString docTitle = m_document->metaData(QStringLiteral("DocumentTitle")).toString(); + + if (!docTitle.isEmpty() && !docTitle.trimmed().isEmpty()) { + title = docTitle; + } + } + + return title; +} + +QUrl DocumentItem::url() const +{ + return m_document->currentDocument(); +} + +void DocumentItem::setCurrentPage(int page) +{ + m_document->setViewportPage(page); + m_tocModel->setCurrentViewport(m_document->viewport()); + emit currentPageChanged(); +} + +int DocumentItem::currentPage() const +{ + return m_document->currentPage(); +} + +bool DocumentItem::isOpened() const +{ + return m_document->isOpened(); +} + +int DocumentItem::pageCount() const +{ + return m_document->pages(); +} + +QVariantList DocumentItem::matchingPages() const +{ + return m_matchingPages; +} + +TOCModel *DocumentItem::tableOfContents() const +{ + return m_tocModel; +} + +QVariantList DocumentItem::bookmarkedPages() const +{ + QList list; + QSet pages; + const KBookmark::List bMarks = m_document->bookmarkManager()->bookmarks(); + for (const KBookmark &bookmark : bMarks) { + Okular::DocumentViewport viewport(bookmark.url().fragment()); + pages << viewport.pageNumber; + } + list = pages.values(); + std::sort(list.begin(), list.end()); + + QVariantList variantList; + for (const int page : qAsConst(list)) { + variantList << page; + } + return variantList; +} + +QStringList DocumentItem::bookmarks() const +{ + QStringList list; + const KBookmark::List bMarks = m_document->bookmarkManager()->bookmarks(); + for (const KBookmark &bookmark : bMarks) { + list << bookmark.url().toString(); + } + return list; +} + +bool DocumentItem::supportsSearching() const +{ + return m_document->supportsSearching(); +} + +bool DocumentItem::isSearchInProgress() const +{ + return m_searchInProgress; +} + +void DocumentItem::searchText(const QString &text) +{ + if (text.isEmpty()) { + resetSearch(); + return; + } + m_document->cancelSearch(); + m_document->resetSearch(PAGEVIEW_SEARCH_ID); + m_document->searchText(PAGEVIEW_SEARCH_ID, text, true, Qt::CaseInsensitive, Okular::Document::AllDocument, true, QColor(100, 100, 200, 40)); + + if (!m_searchInProgress) { + m_searchInProgress = true; + emit searchInProgressChanged(); + } +} + +void DocumentItem::resetSearch() +{ + m_document->resetSearch(PAGEVIEW_SEARCH_ID); + m_matchingPages.clear(); + for (uint i = 0; i < m_document->pages(); ++i) { + m_matchingPages << (int)i; + } + if (m_searchInProgress) { + m_searchInProgress = false; + emit searchInProgressChanged(); + } + + emit matchingPagesChanged(); +} + +Okular::Document *DocumentItem::document() +{ + return m_document; +} + +Observer *DocumentItem::thumbnailObserver() +{ + if (!m_thumbnailObserver) + m_thumbnailObserver = new Observer(this); + + return m_thumbnailObserver; +} + +Observer *DocumentItem::pageviewObserver() +{ + if (!m_pageviewObserver) { + m_pageviewObserver = new Observer(this); + } + + return m_pageviewObserver; +} + +void DocumentItem::searchFinished(int id, Okular::Document::SearchStatus endStatus) +{ + Q_UNUSED(endStatus) + + if (id != PAGEVIEW_SEARCH_ID) { + return; + } + + m_matchingPages.clear(); + for (uint i = 0; i < m_document->pages(); ++i) { + if (m_document->page(i)->hasHighlights(id)) { + m_matchingPages << (int)i; + } + } + + if (m_searchInProgress) { + m_searchInProgress = false; + emit searchInProgressChanged(); + } + emit matchingPagesChanged(); +} + +// Observer + +Observer::Observer(DocumentItem *parent) + : QObject(parent) + , m_document(parent) +{ + parent->document()->addObserver(this); +} + +Observer::~Observer() +{ +} + +void Observer::notifyPageChanged(int page, int flags) +{ + emit pageChanged(page, flags); +} diff --git a/mobile/components/documentitem.h b/mobile/components/documentitem.h new file mode 100644 index 0000000..5efd6f3 --- /dev/null +++ b/mobile/components/documentitem.h @@ -0,0 +1,185 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef QDOCUMENTITEM_H +#define QDOCUMENTITEM_H + +#include + +#include "settings.h" + +#include +#include + +namespace Okular +{ +class Document; +} + +class Observer; +class TOCModel; + +class DocumentItem : public QObject +{ + Q_OBJECT + + /** + * Absolute URI to document file to open + */ + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + + /** + * Suggested window title if a window represents this document. may be pathname or document title, depending on Okular settings. + */ + Q_PROPERTY(QString windowTitleForDocument READ windowTitleForDocument NOTIFY windowTitleForDocumentChanged) + + /** + * Current displaying page for the document + */ + Q_PROPERTY(int currentPage READ currentPage WRITE setCurrentPage NOTIFY currentPageChanged) + + /** + * True if this DocumentItem instance has a document file opened + */ + Q_PROPERTY(bool opened READ isOpened NOTIFY openedChanged) + + /** + * How many pages there are in the document + */ + Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged) + + /** + * True if the document is able to perform full text searches in its contents + */ + Q_PROPERTY(bool supportsSearching READ supportsSearching NOTIFY supportsSearchingChanged) + + /** + * True if a search is currently in progress and results didn't arrive yet + */ + Q_PROPERTY(bool searchInProgress READ isSearchInProgress NOTIFY searchInProgressChanged) + + /** + * A list of all pages that contain a match for the search terms. If no text has been searched, all pages are returned. + */ + Q_PROPERTY(QVariantList matchingPages READ matchingPages NOTIFY matchingPagesChanged) + + /** + * Table of contents for the document, if available + */ + Q_PROPERTY(TOCModel *tableOfContents READ tableOfContents CONSTANT) + + /** + * List of pages that contain a bookmark + */ + Q_PROPERTY(QVariantList bookmarkedPages READ bookmarkedPages NOTIFY bookmarkedPagesChanged) + + /** + * list of bookmarks urls valid on this page + */ + Q_PROPERTY(QStringList bookmarks READ bookmarks NOTIFY bookmarksChanged) + +public: + explicit DocumentItem(QObject *parent = nullptr); + ~DocumentItem() override; + + void setUrl(const QUrl &url); + QUrl url() const; + + QString windowTitleForDocument() const; + + void setCurrentPage(int page); + int currentPage() const; + + bool isOpened() const; + + int pageCount() const; + + bool supportsSearching() const; + + bool isSearchInProgress() const; + + QVariantList matchingPages() const; + + TOCModel *tableOfContents() const; + + QVariantList bookmarkedPages() const; + + QStringList bookmarks() const; + + // This could be a property, but maybe we want to have parameter for searchText + /** + * Performs a search in the document + * + * @param text the string to search in the document + */ + Q_INVOKABLE void searchText(const QString &text); + + /** + * Reset the search over the document. + */ + Q_INVOKABLE void resetSearch(); + + // Internal, not binded to qml + Okular::Document *document(); + Observer *pageviewObserver(); + Observer *thumbnailObserver(); + +Q_SIGNALS: + void urlChanged(); + void pageCountChanged(); + void openedChanged(); + void searchInProgressChanged(); + void matchingPagesChanged(); + void currentPageChanged(); + void supportsSearchingChanged(); + void bookmarkedPagesChanged(); + void bookmarksChanged(); + void windowTitleForDocumentChanged(); + +private Q_SLOTS: + void searchFinished(int id, Okular::Document::SearchStatus endStatus); + +private: + Okular::Document *m_document; + TOCModel *m_tocModel; + Observer *m_thumbnailObserver; + Observer *m_pageviewObserver; + QVariantList m_matchingPages; + bool m_searchInProgress; +}; + +class Observer : public QObject, public Okular::DocumentObserver +{ + Q_OBJECT + +public: + explicit Observer(DocumentItem *parent); + ~Observer() override; + + // inherited from DocumentObserver + void notifyPageChanged(int page, int flags) override; + +Q_SIGNALS: + void pageChanged(int page, int flags); + +private: + DocumentItem *m_document; +}; + +#endif diff --git a/mobile/components/okularplugin.cpp b/mobile/components/okularplugin.cpp new file mode 100644 index 0000000..236e3e6 --- /dev/null +++ b/mobile/components/okularplugin.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "okularplugin.h" + +#include "documentitem.h" +#include "okularsingleton.h" +#include "pageitem.h" +#include "thumbnailitem.h" + +#include +#include +#include + +void OkularPlugin::registerTypes(const char *uri) +{ + if (!qobject_cast(qApp)) { + qWarning() << "The Okular QML components require a QApplication"; + return; + } + if (QString::fromLocal8Bit(uri) != QLatin1String("org.kde.okular")) { + return; + } + qmlRegisterSingletonType(uri, 2, 0, "Okular", [](QQmlEngine *, QJSEngine *) -> QObject * { return new OkularSingleton; }); + qmlRegisterType(uri, 2, 0, "DocumentItem"); + qmlRegisterType(uri, 2, 0, "PageItem"); + qmlRegisterType(uri, 2, 0, "ThumbnailItem"); +} diff --git a/mobile/components/okularplugin.h b/mobile/components/okularplugin.h new file mode 100644 index 0000000..238e650 --- /dev/null +++ b/mobile/components/okularplugin.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef OKULARPLUGIN +#define OKULARPLUGIN + +#include + +class OkularPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void registerTypes(const char *uri) override; +}; + +#endif diff --git a/mobile/components/okularsingleton.cpp b/mobile/components/okularsingleton.cpp new file mode 100644 index 0000000..f079ed3 --- /dev/null +++ b/mobile/components/okularsingleton.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Aleix Pol Gonzalez + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "okularsingleton.h" +#include +#include +#include + +OkularSingleton::OkularSingleton() +{ +} + +QStringList OkularSingleton::nameFilters() const +{ + QStringList supportedPatterns; + + QString constraint(QStringLiteral("(Library == 'okularpart')")); + QLatin1String basePartService("KParts/ReadOnlyPart"); + KService::List offers = KServiceTypeTrader::self()->query(basePartService, constraint); + KService::List::ConstIterator it = offers.constBegin(), itEnd = offers.constEnd(); + + QMimeDatabase md; + for (; it != itEnd; ++it) { + KService::Ptr service = *it; + const QStringList mimeTypes = service->mimeTypes(); + + for (const auto &mimeName : mimeTypes) { + for (const auto &suffix : md.mimeTypeForName(mimeName).suffixes()) + supportedPatterns += QStringLiteral("*.") + suffix; + } + } + + return supportedPatterns; +} diff --git a/mobile/components/okularsingleton.h b/mobile/components/okularsingleton.h new file mode 100644 index 0000000..5fb9bb9 --- /dev/null +++ b/mobile/components/okularsingleton.h @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Aleix Pol Gonzalez + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef OKULARSINGLETON_H +#define OKULARSINGLETON_H + +#include +#include + +class OkularSingleton : public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList nameFilters READ nameFilters CONSTANT) + +public: + OkularSingleton(); + + QStringList nameFilters() const; +}; + +#endif diff --git a/mobile/components/pageitem.cpp b/mobile/components/pageitem.cpp new file mode 100644 index 0000000..1018f84 --- /dev/null +++ b/mobile/components/pageitem.cpp @@ -0,0 +1,435 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "pageitem.h" +#include "documentitem.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "part/pagepainter.h" +#include "part/priorities.h" +#include "settings.h" + +#define REDRAW_TIMEOUT 250 + +PageItem::PageItem(QQuickItem *parent) + : QQuickItem(parent) + , Okular::View(QStringLiteral("PageView")) + , m_page(nullptr) + , m_smooth(false) + , m_bookmarked(false) + , m_isThumbnail(false) +{ + setFlag(QQuickItem::ItemHasContents, true); + + m_viewPort.rePos.enabled = true; + + m_redrawTimer = new QTimer(this); + m_redrawTimer->setInterval(REDRAW_TIMEOUT); + m_redrawTimer->setSingleShot(true); + connect(m_redrawTimer, &QTimer::timeout, this, &PageItem::requestPixmap); + connect(this, &QQuickItem::windowChanged, m_redrawTimer, [this]() { m_redrawTimer->start(); }); +} + +PageItem::~PageItem() +{ +} + +void PageItem::setFlickable(QQuickItem *flickable) +{ + if (m_flickable.data() == flickable) { + return; + } + + // check the object can act as a flickable + if (!flickable->property("contentX").isValid() || !flickable->property("contentY").isValid()) { + return; + } + + if (m_flickable) { + disconnect(m_flickable.data(), nullptr, this, nullptr); + } + + // check the object can act as a flickable + if (!flickable->property("contentX").isValid() || !flickable->property("contentY").isValid()) { + m_flickable.clear(); + return; + } + + m_flickable = flickable; + + if (flickable) { + connect(flickable, SIGNAL(contentXChanged()), this, SLOT(contentXChanged())); + connect(flickable, SIGNAL(contentYChanged()), this, SLOT(contentYChanged())); + } + + emit flickableChanged(); +} + +QQuickItem *PageItem::flickable() const +{ + return m_flickable.data(); +} + +DocumentItem *PageItem::document() const +{ + return m_documentItem.data(); +} + +void PageItem::setDocument(DocumentItem *doc) +{ + if (doc == m_documentItem.data() || !doc) { + return; + } + + m_page = nullptr; + disconnect(doc, nullptr, this, nullptr); + m_documentItem = doc; + Observer *observer = m_isThumbnail ? m_documentItem.data()->thumbnailObserver() : m_documentItem.data()->pageviewObserver(); + connect(observer, &Observer::pageChanged, this, &PageItem::pageHasChanged); + connect(doc->document()->bookmarkManager(), &Okular::BookmarkManager::bookmarksChanged, this, &PageItem::checkBookmarksChanged); + setPageNumber(0); + emit documentChanged(); + m_redrawTimer->start(); + + connect(doc, &DocumentItem::urlChanged, this, &PageItem::refreshPage); +} + +int PageItem::pageNumber() const +{ + return m_viewPort.pageNumber; +} + +void PageItem::setPageNumber(int number) +{ + if ((m_page && m_viewPort.pageNumber == number) || !m_documentItem || !m_documentItem.data()->isOpened() || number < 0) { + return; + } + + m_viewPort.pageNumber = number; + refreshPage(); + emit pageNumberChanged(); + checkBookmarksChanged(); +} + +void PageItem::refreshPage() +{ + if (uint(m_viewPort.pageNumber) < m_documentItem.data()->document()->pages()) { + m_page = m_documentItem.data()->document()->page(m_viewPort.pageNumber); + } else { + m_page = nullptr; + } + + emit implicitWidthChanged(); + emit implicitHeightChanged(); + + m_redrawTimer->start(); +} + +int PageItem::implicitWidth() const +{ + if (m_page) { + return m_page->width(); + } + return 0; +} + +int PageItem::implicitHeight() const +{ + if (m_page) { + return m_page->height(); + } + return 0; +} + +void PageItem::setSmooth(const bool smooth) +{ + if (smooth == m_smooth) { + return; + } + m_smooth = smooth; + update(); +} + +bool PageItem::smooth() const +{ + return m_smooth; +} + +bool PageItem::isBookmarked() +{ + return m_bookmarked; +} + +void PageItem::setBookmarked(bool bookmarked) +{ + if (!m_documentItem) { + return; + } + + if (bookmarked == m_bookmarked) { + return; + } + + if (bookmarked) { + m_documentItem.data()->document()->bookmarkManager()->addBookmark(m_viewPort); + } else { + m_documentItem.data()->document()->bookmarkManager()->removeBookmark(m_viewPort.pageNumber); + } + m_bookmarked = bookmarked; + emit bookmarkedChanged(); +} + +QStringList PageItem::bookmarks() const +{ + QStringList list; + const KBookmark::List pageMarks = m_documentItem.data()->document()->bookmarkManager()->bookmarks(m_viewPort.pageNumber); + for (const KBookmark &bookmark : pageMarks) { + list << bookmark.url().toString(); + } + return list; +} + +void PageItem::goToBookmark(const QString &bookmark) +{ + Okular::DocumentViewport viewPort(QUrl::fromUserInput(bookmark).fragment(QUrl::FullyDecoded)); + setPageNumber(viewPort.pageNumber); + + // Are we in a flickable? + if (m_flickable) { + // normalizedX is a proportion, so contentX will be the difference between document and viewport times normalizedX + m_flickable.data()->setProperty("contentX", qMax((qreal)0, width() - m_flickable.data()->width()) * viewPort.rePos.normalizedX); + + m_flickable.data()->setProperty("contentY", qMax((qreal)0, height() - m_flickable.data()->height()) * viewPort.rePos.normalizedY); + } +} + +QPointF PageItem::bookmarkPosition(const QString &bookmark) const +{ + Okular::DocumentViewport viewPort(QUrl::fromUserInput(bookmark).fragment(QUrl::FullyDecoded)); + + if (viewPort.pageNumber != m_viewPort.pageNumber) { + return QPointF(-1, -1); + } + + return QPointF(qMax((qreal)0, width() - m_flickable.data()->width()) * viewPort.rePos.normalizedX, qMax((qreal)0, height() - m_flickable.data()->height()) * viewPort.rePos.normalizedY); +} + +void PageItem::setBookmarkAtPos(qreal x, qreal y) +{ + Okular::DocumentViewport viewPort(m_viewPort); + viewPort.rePos.normalizedX = x; + viewPort.rePos.normalizedY = y; + + m_documentItem.data()->document()->bookmarkManager()->addBookmark(viewPort); + + if (!m_bookmarked) { + m_bookmarked = true; + emit bookmarkedChanged(); + } + + emit bookmarksChanged(); +} + +void PageItem::removeBookmarkAtPos(qreal x, qreal y) +{ + Okular::DocumentViewport viewPort(m_viewPort); + viewPort.rePos.enabled = true; + viewPort.rePos.normalizedX = x; + viewPort.rePos.normalizedY = y; + + m_documentItem.data()->document()->bookmarkManager()->addBookmark(viewPort); + + if (m_bookmarked && m_documentItem.data()->document()->bookmarkManager()->bookmarks(m_viewPort.pageNumber).count() == 0) { + m_bookmarked = false; + emit bookmarkedChanged(); + } + + emit bookmarksChanged(); +} + +void PageItem::removeBookmark(const QString &bookmark) +{ + m_documentItem.data()->document()->bookmarkManager()->removeBookmark(bookmark); + emit bookmarksChanged(); +} + +// Reimplemented +void PageItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + if (newGeometry.size().isEmpty()) { + return; + } + + bool changed = false; + if (newGeometry.size() != oldGeometry.size()) { + changed = true; + m_redrawTimer->start(); + } + + QQuickItem::geometryChanged(newGeometry, oldGeometry); + + if (changed) { + // Why aren't they automatically emitted? + emit widthChanged(); + emit heightChanged(); + } +} + +QSGNode *PageItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData * /*data*/) +{ + if (!window() || m_buffer.isNull()) { + delete node; + return nullptr; + } + QSGSimpleTextureNode *n = static_cast(node); + if (!n) { + n = new QSGSimpleTextureNode(); + n->setOwnsTexture(true); + } + + n->setTexture(window()->createTextureFromImage(m_buffer)); + n->setRect(boundingRect()); + return n; +} + +void PageItem::requestPixmap() +{ + if (!m_documentItem || !m_page || !window() || width() <= 0 || height() < 0) { + if (!m_buffer.isNull()) { + m_buffer = QImage(); + update(); + } + return; + } + + Observer *observer = m_isThumbnail ? m_documentItem.data()->thumbnailObserver() : m_documentItem.data()->pageviewObserver(); + const int priority = m_isThumbnail ? THUMBNAILS_PRIO : PAGEVIEW_PRIO; + + const qreal dpr = window()->devicePixelRatio(); + + // Here we want to request the pixmap for the page, but it may happen that the page + // already has the pixmap, thus requestPixmaps would not trigger pageHasChanged + // and we would not call paint. Always call paint, if we don't have a pixmap + // it's a noop. Requesting a page that already has a pixmap is also + // almost a noop. + // Ideally we would do one or the other but for now this is good enough + paint(); + { + auto request = new Okular::PixmapRequest(observer, m_viewPort.pageNumber, width() * dpr, height() * dpr, priority, Okular::PixmapRequest::Asynchronous); + request->setNormalizedRect(Okular::NormalizedRect(0, 0, 1, 1)); + const Okular::Document::PixmapRequestFlag prf = Okular::Document::NoOption; + m_documentItem.data()->document()->requestPixmaps({request}, prf); + } +} + +void PageItem::paint() +{ + Observer *observer = m_isThumbnail ? m_documentItem.data()->thumbnailObserver() : m_documentItem.data()->pageviewObserver(); + const int flags = PagePainter::Accessibility | PagePainter::Highlights | PagePainter::Annotations; + + const qreal dpr = window()->devicePixelRatio(); + const QRect limits(QPoint(0, 0), QSize(width() * dpr, height() * dpr)); + QPixmap pix(limits.size()); + pix.setDevicePixelRatio(dpr); + QPainter p(&pix); + p.setRenderHint(QPainter::Antialiasing, m_smooth); + PagePainter::paintPageOnPainter(&p, m_page, observer, flags, width(), height(), limits); + p.end(); + + m_buffer = pix.toImage(); + + update(); +} + +// Protected slots +void PageItem::pageHasChanged(int page, int flags) +{ + if (m_viewPort.pageNumber == page) { + if (flags == Okular::DocumentObserver::BoundingBox) { + // skip bounding box updates + // kDebug() << "32" << m_page->boundingBox(); + } else if (flags == Okular::DocumentObserver::Pixmap) { + // if pixmaps have updated, just repaint .. don't bother updating pixmaps AGAIN + paint(); + } else { + m_redrawTimer->start(); + } + } +} + +void PageItem::checkBookmarksChanged() +{ + if (!m_documentItem) { + return; + } + + bool newBookmarked = m_documentItem.data()->document()->bookmarkManager()->isBookmarked(m_viewPort.pageNumber); + if (m_bookmarked != newBookmarked) { + m_bookmarked = newBookmarked; + emit bookmarkedChanged(); + } + + // TODO: check the page + emit bookmarksChanged(); +} + +void PageItem::contentXChanged() +{ + if (!m_flickable || !m_flickable.data()->property("contentX").isValid()) { + return; + } + + m_viewPort.rePos.normalizedX = m_flickable.data()->property("contentX").toReal() / (width() - m_flickable.data()->width()); +} + +void PageItem::contentYChanged() +{ + if (!m_flickable || !m_flickable.data()->property("contentY").isValid()) { + return; + } + + m_viewPort.rePos.normalizedY = m_flickable.data()->property("contentY").toReal() / (height() - m_flickable.data()->height()); +} + +void PageItem::setIsThumbnail(bool thumbnail) +{ + if (thumbnail == m_isThumbnail) { + return; + } + + m_isThumbnail = thumbnail; + + if (thumbnail) { + m_smooth = false; + } + + /* + m_redrawTimer->setInterval(thumbnail ? 0 : REDRAW_TIMEOUT); + m_redrawTimer->setSingleShot(true); + */ +} diff --git a/mobile/components/pageitem.h b/mobile/components/pageitem.h new file mode 100644 index 0000000..4634585 --- /dev/null +++ b/mobile/components/pageitem.h @@ -0,0 +1,177 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef QPAGEITEM_H +#define QPAGEITEM_H + +#include +#include +#include + +#include +#include + +class QTimer; + +class DocumentItem; + +namespace Okular +{ +class Document; +class Page; +} + +class PageItem : public QQuickItem, public Okular::View +{ + Q_OBJECT + + /** + * If this page is in a Flickable, assign it in this property, to make goToBookmark work + */ + Q_PROPERTY(QQuickItem *flickable READ flickable WRITE setFlickable NOTIFY flickableChanged) + + /** + * The document this page belongs to + */ + Q_PROPERTY(DocumentItem *document READ document WRITE setDocument NOTIFY documentChanged) + + /** + * The currently displayed page + */ + Q_PROPERTY(int pageNumber READ pageNumber WRITE setPageNumber NOTIFY pageNumberChanged) + + /** + * If true, the page will be rendered with antialias + */ + Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) + + /** + * "Natural" width of the page + */ + Q_PROPERTY(int implicitWidth READ implicitWidth NOTIFY implicitWidthChanged) + + /** + * "Natural" height of the page + */ + Q_PROPERTY(int implicitHeight READ implicitHeight NOTIFY implicitHeightChanged) + + /** + * True if the page contains at least a bookmark. + * Writing true to tis property idds a bookmark at the beginning of the page (if needed). + * Writing false, all bookmarks for this page will be removed + */ + Q_PROPERTY(bool bookmarked READ isBookmarked WRITE setBookmarked NOTIFY bookmarkedChanged) + + /** + * list of bookmarks urls valid on this page + */ + Q_PROPERTY(QStringList bookmarks READ bookmarks NOTIFY bookmarksChanged) + +public: + explicit PageItem(QQuickItem *parent = nullptr); + ~PageItem() override; + + void setFlickable(QQuickItem *flickable); + QQuickItem *flickable() const; + + int implicitWidth() const; + int implicitHeight() const; + + DocumentItem *document() const; + void setDocument(DocumentItem *doc); + + int pageNumber() const; + void setPageNumber(int number); + + bool smooth() const; + void setSmooth(bool smooth); + + bool isBookmarked(); + void setBookmarked(bool bookmarked); + + QStringList bookmarks() const; + void requestPixmap(); + + /** + * loads a page bookmark and tries to ensure the bookmarked position is visible + * @param bookmark Url for the bookmark + */ + Q_INVOKABLE void goToBookmark(const QString &bookmark); + + /** + * Returns the position in the page for a bookmark + * QPointF(-1,-1) if doesn't belong to this page + * + * @param bookmark Url for the bookmark + */ + Q_INVOKABLE QPointF bookmarkPosition(const QString &bookmark) const; + + /** + * Add a new bookmark ar a given position of the current page + */ + Q_INVOKABLE void setBookmarkAtPos(qreal x, qreal y); + + /** + * Remove a bookmark ar a given position of the current page (if present) + */ + Q_INVOKABLE void removeBookmarkAtPos(qreal x, qreal y); + + /** + * Remove a bookmark at a given position, if any + */ + Q_INVOKABLE void removeBookmark(const QString &bookmark); + + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + + QSGNode *updatePaintNode(QSGNode *, QQuickItem::UpdatePaintNodeData *) override; + +Q_SIGNALS: + void flickableChanged(); + void implicitWidthChanged(); + void implicitHeightChanged(); + void documentChanged(); + void pageNumberChanged(); + void bookmarkedChanged(); + void bookmarksChanged(); + +protected: + void setIsThumbnail(bool thumbnail); + +private Q_SLOTS: + void pageHasChanged(int page, int flags); + void checkBookmarksChanged(); + void contentXChanged(); + void contentYChanged(); + +private: + void paint(); + void refreshPage(); + + const Okular::Page *m_page; + bool m_smooth; + bool m_bookmarked; + bool m_isThumbnail; + QPointer m_documentItem; + QTimer *m_redrawTimer; + QPointer m_flickable; + Okular::DocumentViewport m_viewPort; + QImage m_buffer; +}; + +#endif diff --git a/mobile/components/private/PageView.qml b/mobile/components/private/PageView.qml new file mode 100644 index 0000000..57e315d --- /dev/null +++ b/mobile/components/private/PageView.qml @@ -0,0 +1,108 @@ +/* + * Copyright 2015 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.2 +import QtGraphicalEffects 1.0 +import org.kde.okular 2.0 +import org.kde.kirigami 2.2 as Kirigami + +Item { + width: parent.width + height: parent.height + readonly property PageItem pageItem: page + property alias document: page.document + property alias pageNumber: page.pageNumber + implicitWidth: page.implicitWidth + implicitHeight: page.implicitHeight + readonly property real pageRatio: page.implicitWidth / page.implicitHeight + readonly property real scaleFactor: page.width / page.implicitWidth + + PageItem { + id: page + property bool sameOrientation: parent.width / parent.height > pageRatio + anchors.centerIn: parent + width: sameOrientation ? parent.height * pageRatio : parent.width + height: !sameOrientation ? parent.width / pageRatio : parent.height + document: null + } + + Rectangle { + id: backgroundRectangle + anchors { + top: parent.top + bottom: parent.bottom + left: page.left + right: page.right + topMargin: -Kirigami.Units.gridUnit + bottomMargin: -Kirigami.Units.gridUnit + } + z: -1 + color: "white" + + LinearGradient { + width: Kirigami.Units.gridUnit + anchors { + right: parent.left + top: parent.top + bottom: parent.bottom + } + start: Qt.point(0, 0) + end: Qt.point(Kirigami.Units.gridUnit, 0) + gradient: Gradient { + GradientStop { + position: 0.0 + color: "transparent" + } + GradientStop { + position: 0.7 + color: Qt.rgba(0, 0, 0, 0.08) + } + GradientStop { + position: 1.0 + color: Qt.rgba(0, 0, 0, 0.2) + } + } + } + + LinearGradient { + width: Kirigami.Units.gridUnit + anchors { + left: parent.right + top: parent.top + bottom: parent.bottom + } + start: Qt.point(0, 0) + end: Qt.point(Kirigami.Units.gridUnit, 0) + gradient: Gradient { + GradientStop { + position: 0.0 + color: Qt.rgba(0, 0, 0, 0.2) + } + GradientStop { + position: 0.3 + color: Qt.rgba(0, 0, 0, 0.08) + } + GradientStop { + position: 1.0 + color: "transparent" + } + } + } + } +} diff --git a/mobile/components/qmldir b/mobile/components/qmldir new file mode 100644 index 0000000..26164a8 --- /dev/null +++ b/mobile/components/qmldir @@ -0,0 +1,3 @@ +module org.kde.okular +plugin okularplugin +DocumentView 2.0 DocumentView.qml diff --git a/mobile/components/settings.h b/mobile/components/settings.h new file mode 100644 index 0000000..e81a2ea --- /dev/null +++ b/mobile/components/settings.h @@ -0,0 +1 @@ +#include "settings_mobile.h" diff --git a/mobile/components/test.qml b/mobile/components/test.qml new file mode 100644 index 0000000..4c029ca --- /dev/null +++ b/mobile/components/test.qml @@ -0,0 +1,50 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.2 +import QtQuick.Controls 1.0 +import org.kde.okular 2.0 as Okular + +Item { + width: 500 + height: 600 + Okular.DocumentItem { + id: docItem + path: "pageitem.cpp" + } + Okular.PageItem { + id: page + anchors.fill: parent + document: docItem + } + Row { + anchors { + bottom: parent.bottom + right: parent.right + } + Button { + text: "prev" + onClicked: page.pageNumber-- + } + Button { + text: "next" + onClicked: page.pageNumber++ + } + } +} diff --git a/mobile/components/testDocumentView.qml b/mobile/components/testDocumentView.qml new file mode 100644 index 0000000..d3205b9 --- /dev/null +++ b/mobile/components/testDocumentView.qml @@ -0,0 +1,35 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.2 +import QtQuick.Controls 1.0 +import org.kde.okular 2.0 as Okular + +Item { + width: 500 + height: 600 + Okular.DocumentItem { + id: docItem + path: "pageitem.cpp" + } + Okular.DocumentView { + anchors.fill: parent + document: docItem + } +} diff --git a/mobile/components/thumbnailitem.cpp b/mobile/components/thumbnailitem.cpp new file mode 100644 index 0000000..1397809 --- /dev/null +++ b/mobile/components/thumbnailitem.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "thumbnailitem.h" + +ThumbnailItem::ThumbnailItem(QQuickItem *parent) + : PageItem(parent) +{ + setIsThumbnail(true); +} + +ThumbnailItem::~ThumbnailItem() +{ +} diff --git a/mobile/components/thumbnailitem.h b/mobile/components/thumbnailitem.h new file mode 100644 index 0000000..8658be7 --- /dev/null +++ b/mobile/components/thumbnailitem.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 by Marco Martin + * + * 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, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef THUMBNAILITEM_H +#define THUMBNAILITEM_H + +#include "pageitem.h" + +class ThumbnailItem : public PageItem +{ + Q_OBJECT + +public: + explicit ThumbnailItem(QQuickItem *parent = nullptr); + ~ThumbnailItem() override; +}; + +#endif diff --git a/okular.categories b/okular.categories new file mode 100644 index 0000000..80964da --- /dev/null +++ b/okular.categories @@ -0,0 +1,16 @@ +# Okular's logging categories (for the kdebugsettings tool) +org.kde.okular.core Okular (Core) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularCoreDebug] +org.kde.okular.generators.comicbook Okular (Generator Comicbook) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularComicbookDebug] +org.kde.okular.generators.ooo Okular (Generator OOo) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularOooDebug] +org.kde.okular.generators.dvi.core Okular (Generator DVI/Core) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularDviDebug] +org.kde.okular.generators.dvi.shell Okular (Generator DVI/Shell) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularDviShellDebug] +org.kde.okular.generators.txt Okular (Generator TXT) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularTxtDebug] +org.kde.okular.generators.md Okular (Generator Markdown) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularMdDebug] +org.kde.kio.msits kioslave (kio_msits) DEFAULT_SEVERITY [WARNING] IDENTIFIER [KIO_MITS_LOG] +org.kde.okular.generators.fax Okular (Generator Fax) DEFAULT_SEVERITY [WARNING] IDENTIFIER [FAX_LOG] +org.kde.okular.generators.pdf Okular (Generator PDF) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularPdfDebug] +org.kde.okular.generators.xps Okular (Generator XPS) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularXpsDebug] +org.kde.okular.generators.tiff Okular (Generator TIFF) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularTiffDebug] +org.kde.okular.generators.epu Okular (Generator EPU) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularEpuDebug] +org.kde.okular.generators.spectre Okular (Generator Spectre) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularSpectreDebug] +org.kde.okular.ui Okular (UI) DEFAULT_SEVERITY [WARNING] IDENTIFIER [OkularUiDebug] diff --git a/okular.upd b/okular.upd new file mode 100644 index 0000000..bb0448f --- /dev/null +++ b/okular.upd @@ -0,0 +1,14 @@ +#Configuration update for Okular +Version=5 + +#Convert user-defined annotation tools to quick annotation tools +Id=annotation-toolbar +File=okularpartrc +Group=Reviews +Key=AnnotationTools,QuickAnnotationTools + +#Remove key that stored the state of the bultin annotation tools (now stored in BuiltinAnnoationTools) +Id=builtin-annotations +File=okularpartrc +Group=Reviews +RemoveKey=AnnotationTools diff --git a/okular_part.desktop b/okular_part.desktop new file mode 100644 index 0000000..25c6e57 --- /dev/null +++ b/okular_part.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Icon=okular +Name=Okular +Name[ar]=اوكلار +Name[az]=Okular +Name[bg]=Okular +Name[bs]=Okular +Name[ca]=Okular +Name[ca@valencia]=Okular +Name[cs]=Okular +Name[da]=Okular +Name[de]=Okular +Name[el]=Okular +Name[en_GB]=Okular +Name[eo]=Okular +Name[es]=Okular +Name[et]=Okular +Name[eu]=Okular +Name[fi]=Okular +Name[fr]=Okular +Name[ga]=Okular +Name[gl]=Okular +Name[hne]=ओकुलर +Name[hr]=Okular +Name[hu]=Okular +Name[ia]=Okular +Name[is]=Okular +Name[it]=Okular +Name[ja]=Okular +Name[kk]=Okular +Name[km]=Okular +Name[ko]=Okular +Name[ku]=Okular +Name[lt]=Okular +Name[lv]=Okular +Name[mr]=ओक्युलर +Name[nb]=Okular +Name[nds]=Okular +Name[nl]=Okular +Name[nn]=Okular +Name[pa]=ਓਕੁਲਾਰ +Name[pl]=Okular +Name[pt]=Okular +Name[pt_BR]=Okular +Name[ro]=Okular +Name[ru]=Okular +Name[si]=Okular +Name[sk]=Okular +Name[sl]=Okular +Name[sq]=Okular +Name[sr]=Окулар +Name[sr@ijekavian]=Окулар +Name[sr@ijekavianlatin]=Okular +Name[sr@latin]=Okular +Name[sv]=Okular +Name[th]=โอกูลาร์ +Name[tr]=Okular +Name[ug]=Okular +Name[uk]=Okular +Name[x-test]=xxOkularxx +Name[zh_CN]=Okular +Name[zh_TW]=文件檢視_Okular +X-KDE-ServiceTypes=KParts/ReadOnlyPart,KParts/ReadWritePart +X-KDE-Library=okularpart +Type=Service +MimeType=application/vnd.kde.okular-archive; diff --git a/part/CMakeLists.txt b/part/CMakeLists.txt new file mode 100644 index 0000000..b80c447 --- /dev/null +++ b/part/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory( data ) + diff --git a/part/annotationactionhandler.cpp b/part/annotationactionhandler.cpp new file mode 100644 index 0000000..e6a9229 --- /dev/null +++ b/part/annotationactionhandler.cpp @@ -0,0 +1,766 @@ +/************************************************************************** + * Copyright (C) 2019 by Simone Gaiarin * + * * + * 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. * + **************************************************************************/ + +#include "annotationactionhandler.h" + +// qt includes +#include +#include +#include +#include +#include +#include + +// kde includes +#include +#include +#include +#include +#include +#include + +// local includes +#include "annotationwidgets.h" +#include "guiutils.h" +#include "pageview.h" +#include "pageviewannotator.h" +#include "toggleactionmenu.h" + +class AnnotationActionHandlerPrivate +{ +public: + enum class AnnotationColor { Color, InnerColor }; + static const QList> defaultColors; + static const QList widthStandardValues; + static const QList opacityStandardValues; + + explicit AnnotationActionHandlerPrivate(AnnotationActionHandler *qq) + : q(qq) + , annotator(nullptr) + , agTools(nullptr) + , agLastAction(nullptr) + , aQuickTools(nullptr) + , aGeomShapes(nullptr) + , aStamp(nullptr) + , aAddToQuickTools(nullptr) + , aContinuousMode(nullptr) + , aConstrainRatioAndAngle(nullptr) + , aWidth(nullptr) + , aColor(nullptr) + , aInnerColor(nullptr) + , aOpacity(nullptr) + , aFont(nullptr) + , aAdvancedSettings(nullptr) + , aHideToolBar(nullptr) + , aShowToolBar(nullptr) + , aCustomStamp(nullptr) + , aCustomWidth(nullptr) + , aCustomOpacity(nullptr) + , currentColor(QColor()) + , currentInnerColor(QColor()) + , currentFont(QFont()) + , currentWidth(-1) + , selectedTool(-1) + , textToolsEnabled(false) + { + } + + QAction *selectActionItem(KSelectAction *aList, QAction *aCustomCurrent, double value, const QList &defaultValues, const QIcon &icon, const QString &label); + /** + * @short Adds a custom stamp annotation action to the stamp list when the stamp is not a default stamp + * + * When stampIconName cannot be found among the default stamps, this method creates a new action + * for the custom stamp annotation and adds it to the stamp action combo box. If a custom action + * is already present in the list, it is removed before adding the new custom action. If stampIconName + * matches a default stamp, any existing stamp annotation action is removed. + */ + void maybeUpdateCustomStampAction(const QString &stampIconName); + void parseTool(int toolId); + + void updateConfigActions(const QString &annotType = QLatin1String("")); + void populateQuickAnnotations(); + KSelectAction *colorPickerAction(AnnotationColor colorType); + + const QIcon widthIcon(double width); + const QIcon stampIcon(const QString &stampIconName); + + void selectTool(int toolId); + void slotStampToolSelected(const QString &stamp); + void slotQuickToolSelected(int favToolId); + void slotSetColor(AnnotationColor colorType, const QColor &color = QColor()); + void slotSelectAnnotationFont(); + void slotToolBarVisibilityChanged(bool checked); + + AnnotationActionHandler *q; + + PageViewAnnotator *annotator; + + QList textTools; + QList textQuickTools; + QActionGroup *agTools; + QAction *agLastAction; + + KSelectAction *aQuickTools; + ToggleActionMenu *aGeomShapes; + ToggleActionMenu *aStamp; + QAction *aAddToQuickTools; + KToggleAction *aContinuousMode; + KToggleAction *aConstrainRatioAndAngle; + KSelectAction *aWidth; + KSelectAction *aColor; + KSelectAction *aInnerColor; + KSelectAction *aOpacity; + QAction *aFont; + QAction *aAdvancedSettings; + QAction *aHideToolBar; + KToggleAction *aShowToolBar; + + QAction *aCustomStamp; + QAction *aCustomWidth; + QAction *aCustomOpacity; + + QColor currentColor; + QColor currentInnerColor; + QFont currentFont; + int currentWidth; + + int selectedTool; + bool textToolsEnabled; +}; + +const QList> AnnotationActionHandlerPrivate::defaultColors = {{ki18nc("@item:inlistbox Color name", "Red"), Qt::red}, + {ki18nc("@item:inlistbox Color name", "Orange"), QColor(255, 85, 0)}, + {ki18nc("@item:inlistbox Color name", "Yellow"), Qt::yellow}, + {ki18nc("@item:inlistbox Color name", "Green"), Qt::green}, + {ki18nc("@item:inlistbox Color name", "Cyan"), Qt::cyan}, + {ki18nc("@item:inlistbox Color name", "Blue"), Qt::blue}, + {ki18nc("@item:inlistbox Color name", "Magenta"), Qt::magenta}, + {ki18nc("@item:inlistbox Color name", "White"), Qt::white}, + {ki18nc("@item:inlistbox Color name", "Gray"), Qt::gray}, + {ki18nc("@item:inlistbox Color name", "Black"), Qt::black} + +}; + +const QList AnnotationActionHandlerPrivate::widthStandardValues = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5}; + +const QList AnnotationActionHandlerPrivate::opacityStandardValues = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + +QAction *AnnotationActionHandlerPrivate::selectActionItem(KSelectAction *aList, QAction *aCustomCurrent, double value, const QList &defaultValues, const QIcon &icon, const QString &label) +{ + if (aCustomCurrent) { + aList->removeAction(aCustomCurrent); + delete aCustomCurrent; + } + QAction *aCustom = nullptr; + const int defaultValueIdx = defaultValues.indexOf(value); + if (defaultValueIdx >= 0) { + aList->setCurrentItem(defaultValueIdx); + } else { + aCustom = new KToggleAction(icon, label, q); + const int aBeforeIdx = std::lower_bound(defaultValues.begin(), defaultValues.end(), value) - defaultValues.begin(); + QAction *aBefore = aBeforeIdx < defaultValues.size() ? aList->actions().at(aBeforeIdx) : nullptr; + aList->insertAction(aBefore, aCustom); + aList->setCurrentAction(aCustom); + } + return aCustom; +} + +void AnnotationActionHandlerPrivate::maybeUpdateCustomStampAction(const QString &stampIconName) +{ + auto it = std::find_if(StampAnnotationWidget::defaultStamps.begin(), StampAnnotationWidget::defaultStamps.end(), [&stampIconName](const QPair &element) { return element.second == stampIconName; }); + bool defaultStamp = it != StampAnnotationWidget::defaultStamps.end(); + + if (aCustomStamp) { + aStamp->removeAction(aCustomStamp); + agTools->removeAction(aCustomStamp); + delete aCustomStamp; + aCustomStamp = nullptr; + } + if (!defaultStamp) { + QFileInfo info(stampIconName); + QString stampActionName = info.fileName(); + aCustomStamp = new KToggleAction(stampIcon(stampIconName), stampActionName, q); + aStamp->addAction(aCustomStamp); + aStamp->setDefaultAction(aCustomStamp); + agTools->addAction(aCustomStamp); + aCustomStamp->setChecked(true); + QObject::connect(aCustomStamp, &QAction::triggered, q, [this, stampIconName]() { slotStampToolSelected(stampIconName); }); + } +} + +void AnnotationActionHandlerPrivate::parseTool(int toolId) +{ + if (toolId == -1) { + updateConfigActions(); + return; + } + + QDomElement toolElement = annotator->builtinTool(toolId); + const QString annotType = toolElement.attribute(QStringLiteral("type")); + QDomElement engineElement = toolElement.firstChildElement(QStringLiteral("engine")); + QDomElement annElement = engineElement.firstChildElement(QStringLiteral("annotation")); + + QColor color, innerColor, textColor; + if (annElement.hasAttribute(QStringLiteral("color"))) { + color = QColor(annElement.attribute(QStringLiteral("color"))); + } + if (annElement.hasAttribute(QStringLiteral("innerColor"))) { + innerColor = QColor(annElement.attribute(QStringLiteral("innerColor"))); + } + if (annElement.hasAttribute(QStringLiteral("textColor"))) { + textColor = QColor(annElement.attribute(QStringLiteral("textColor"))); + } + if (textColor.isValid()) { + currentColor = textColor; + currentInnerColor = color; + } else { + currentColor = color; + currentInnerColor = innerColor; + } + + if (annElement.hasAttribute(QStringLiteral("font"))) { + currentFont.fromString(annElement.attribute(QStringLiteral("font"))); + } + + // if the width value is not a default one, insert a new action in the width list + if (annElement.hasAttribute(QStringLiteral("width"))) { + double width = annElement.attribute(QStringLiteral("width")).toDouble(); + aCustomWidth = selectActionItem(aWidth, aCustomWidth, width, widthStandardValues, widthIcon(width), i18nc("@item:inlistbox", "Width %1", width)); + } + + // if the opacity value is not a default one, insert a new action in the opacity list + if (annElement.hasAttribute(QStringLiteral("opacity"))) { + double opacity = annElement.attribute(QStringLiteral("opacity")).toDouble(); + aCustomOpacity = selectActionItem(aOpacity, aCustomOpacity, opacity, opacityStandardValues, GuiUtils::createOpacityIcon(opacity), i18nc("@item:inlistbox", "%1\%", opacity * 100)); + } else { + aOpacity->setCurrentItem(opacityStandardValues.size() - 1); // 100 % + } + + // if the tool is a custom stamp, insert a new action in the stamp list + if (annotType == QStringLiteral("stamp")) { + QString stampIconName = annElement.attribute(QStringLiteral("icon")); + maybeUpdateCustomStampAction(stampIconName); + } + + updateConfigActions(annotType); +} + +void AnnotationActionHandlerPrivate::updateConfigActions(const QString &annotType) +{ + const bool isAnnotationSelected = !annotType.isEmpty(); + const bool isTypewriter = annotType == QStringLiteral("typewriter"); + const bool isInlineNote = annotType == QStringLiteral("note-inline"); + const bool isText = isInlineNote || isTypewriter; + const bool isPolygon = annotType == QStringLiteral("polygon"); + const bool isShape = annotType == QStringLiteral("rectangle") || annotType == QStringLiteral("ellipse") || isPolygon; + const bool isStraightLine = annotType == QStringLiteral("straight-line"); + const bool isLine = annotType == QStringLiteral("ink") || isStraightLine; + const bool isStamp = annotType == QStringLiteral("stamp"); + + if (isTypewriter) { + aColor->setIcon(GuiUtils::createColorIcon({currentColor}, QIcon::fromTheme(QStringLiteral("format-text-color")))); + } else { + aColor->setIcon(GuiUtils::createColorIcon({currentColor}, QIcon::fromTheme(QStringLiteral("format-stroke-color")))); + } + aInnerColor->setIcon(GuiUtils::createColorIcon({currentInnerColor}, QIcon::fromTheme(QStringLiteral("format-fill-color")))); + + aAddToQuickTools->setEnabled(isAnnotationSelected); + aWidth->setEnabled(isLine || isShape); + aColor->setEnabled(isAnnotationSelected && !isStamp); + aInnerColor->setEnabled(isShape); + aOpacity->setEnabled(isAnnotationSelected); + aFont->setEnabled(isText); + aConstrainRatioAndAngle->setEnabled(isStraightLine || isShape); + aAdvancedSettings->setEnabled(isAnnotationSelected); + + // set tooltips + if (!isAnnotationSelected) { + aWidth->setToolTip(i18nc("@info:tooltip", "Annotation line width (No annotation selected)")); + aColor->setToolTip(i18nc("@info:tooltip", "Annotation color (No annotation selected)")); + aInnerColor->setToolTip(i18nc("@info:tooltip", "Annotation fill color (No annotation selected)")); + aOpacity->setToolTip(i18nc("@info:tooltip", "Annotation opacity (No annotation selected)")); + aFont->setToolTip(i18nc("@info:tooltip", "Annotation font (No annotation selected)")); + aAddToQuickTools->setToolTip(i18nc("@info:tooltip", "Add the current annotation to the quick annotations menu (No annotation selected)")); + aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation selected)")); + aAdvancedSettings->setToolTip(i18nc("@info:tooltip", "Advanced settings for the current annotation tool (No annotation selected)")); + return; + } + + if (isLine || isShape) { + aWidth->setToolTip(i18nc("@info:tooltip", "Annotation line width")); + } else { + aWidth->setToolTip(i18nc("@info:tooltip", "Annotation line width (Current annotation has no line width)")); + } + + if (isTypewriter) { + aColor->setToolTip(i18nc("@info:tooltip", "Annotation text color")); + } else if (isShape) { + aColor->setToolTip(i18nc("@info:tooltip", "Annotation border color")); + } else { + aColor->setToolTip(i18nc("@info:tooltip", "Annotation color")); + } + + if (isShape) { + aInnerColor->setToolTip(i18nc("@info:tooltip", "Annotation fill color")); + } else { + aInnerColor->setToolTip(i18nc("@info:tooltip", "Annotation fill color (Current annotation has no fill color)")); + } + + if (isText) { + aFont->setToolTip(i18nc("@info:tooltip", "Annotation font")); + } else { + aFont->setToolTip(i18nc("@info:tooltip", "Annotation font (Current annotation has no font)")); + } + + if (isStraightLine || isPolygon) { + aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain line angle to 15° steps")); + } else if (isShape) { + aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1")); + } else { + aConstrainRatioAndAngle->setToolTip(i18nc("@info:tooltip", "Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by current annotation)")); + } + + aOpacity->setToolTip(i18nc("@info:tooltip", "Annotation opacity")); + aAddToQuickTools->setToolTip(i18nc("@info:tooltip", "Add the current annotation to the quick annotations menu")); + aAdvancedSettings->setToolTip(i18nc("@info:tooltip", "Advanced settings for the current annotation tool")); +} + +void AnnotationActionHandlerPrivate::populateQuickAnnotations() +{ + if (!aQuickTools->isEnabled()) { + return; + } + + const QList numberKeys = {Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_0}; + + textQuickTools.clear(); + aQuickTools->removeAllActions(); + + int favToolId = 1; + QList::const_iterator shortcutNumber = numberKeys.begin(); + QDomElement favToolElement = annotator->quickTool(favToolId); + while (!favToolElement.isNull()) { + QString itemText = favToolElement.attribute(QStringLiteral("name")); + if (itemText.isEmpty()) { + itemText = PageViewAnnotator::defaultToolName(favToolElement); + } + QIcon toolIcon = QIcon(PageViewAnnotator::makeToolPixmap(favToolElement)); + QAction *annFav = new QAction(toolIcon, itemText, q); + aQuickTools->addAction(annFav); + if (shortcutNumber != numberKeys.end()) + annFav->setShortcut(QKeySequence(*(shortcutNumber++))); + QObject::connect(annFav, &QAction::triggered, q, [this, favToolId]() { slotQuickToolSelected(favToolId); }); + + QDomElement engineElement = favToolElement.firstChildElement(QStringLiteral("engine")); + if (engineElement.attribute(QStringLiteral("type")) == QStringLiteral("TextSelector")) { + textQuickTools.append(annFav); + annFav->setEnabled(textToolsEnabled); + } + + favToolElement = annotator->quickTool(++favToolId); + } + QAction *separator = new QAction(); + separator->setSeparator(true); + aQuickTools->addAction(separator); + // add action to open "Configure Annotation" settings dialog + KActionCollection *ac = qobject_cast(q->parent()->parent())->actionCollection(); + QAction *aConfigAnnotation = ac->action(QStringLiteral("options_configure_annotations")); + if (aConfigAnnotation) { + aQuickTools->addAction(aConfigAnnotation); + } +} + +KSelectAction *AnnotationActionHandlerPrivate::colorPickerAction(AnnotationColor colorType) +{ + auto colorList = defaultColors; + QString aText(i18nc("@action:intoolbar Current annotation config option", "Color")); + if (colorType == AnnotationColor::InnerColor) { + aText = i18nc("@action:intoolbar Current annotation config option", "Fill Color"); + colorList.append(QPair(ki18nc("@item:inlistbox Color name", "Transparent"), Qt::transparent)); + } + KSelectAction *aColorPicker = new KSelectAction(QIcon(), aText, q); + aColorPicker->setToolBarMode(KSelectAction::MenuMode); + for (const auto &colorNameValue : colorList) { + QColor color(colorNameValue.second); + QAction *aColor = new QAction(GuiUtils::createColorIcon({color}, QIcon(), GuiUtils::VisualizeTransparent), colorNameValue.first.toString(), q); + aColorPicker->addAction(aColor); + QObject::connect(aColor, &QAction::triggered, q, [this, colorType, color]() { slotSetColor(colorType, color); }); + } + QAction *aCustomColor = new QAction(QIcon::fromTheme(QStringLiteral("color-picker")), i18nc("@item:inlistbox", "Custom Color..."), q); + aColorPicker->addAction(aCustomColor); + QObject::connect(aCustomColor, &QAction::triggered, q, [this, colorType]() { slotSetColor(colorType); }); + return aColorPicker; +} + +const QIcon AnnotationActionHandlerPrivate::widthIcon(double width) +{ + QPixmap pm(32, 32); + pm.fill(Qt::transparent); + QPainter p(&pm); + p.setRenderHint(QPainter::Antialiasing); + p.setPen(QPen(Qt::black, 2 * width, Qt::SolidLine, Qt::RoundCap)); + p.drawLine(0, pm.height() / 2, pm.width(), pm.height() / 2); + p.end(); + return QIcon(pm); +} + +const QIcon AnnotationActionHandlerPrivate::stampIcon(const QString &stampIconName) +{ + QPixmap stampPix = GuiUtils::loadStamp(stampIconName, 32); + if (stampPix.width() == stampPix.height()) + return QIcon(stampPix); + else + return QIcon::fromTheme(QStringLiteral("tag")); +} + +void AnnotationActionHandlerPrivate::selectTool(int toolId) +{ + selectedTool = toolId; + annotator->selectTool(toolId, PageViewAnnotator::ShowTip::Yes); + parseTool(toolId); +} + +void AnnotationActionHandlerPrivate::slotStampToolSelected(const QString &stamp) +{ + KMessageBox::information(nullptr, i18nc("@info", "Stamps inserted in PDF documents are not visible in PDF readers other than Okular"), i18nc("@title:window", "Experimental feature"), QStringLiteral("stampAnnotationWarning")); + selectedTool = PageViewAnnotator::STAMP_TOOL_ID; + annotator->selectStampTool(stamp); // triggers a reparsing thus calling parseTool +} + +void AnnotationActionHandlerPrivate::slotQuickToolSelected(int favToolId) +{ + int toolId = annotator->setQuickTool(favToolId); // always triggers an unuseful reparsing + if (toolId == -1) { + qWarning("Corrupted configuration for quick annotation tool with id: %d", favToolId); + return; + } + int indexOfActionInGroup = toolId - 1; + if (toolId == PageViewAnnotator::STAMP_TOOL_ID) { + // if the quick tool is a stamp we need to find its corresponding built-in tool action and select it + QDomElement favToolElement = annotator->quickTool(favToolId); + QDomElement engineElement = favToolElement.firstChildElement(QStringLiteral("engine")); + QDomElement annotationElement = engineElement.firstChildElement(QStringLiteral("annotation")); + QString stampIconName = annotationElement.attribute(QStringLiteral("icon")); + + auto it = std::find_if(StampAnnotationWidget::defaultStamps.begin(), StampAnnotationWidget::defaultStamps.end(), [&stampIconName](const QPair &element) { return element.second == stampIconName; }); + if (it != StampAnnotationWidget::defaultStamps.end()) { + int stampActionIndex = std::distance(StampAnnotationWidget::defaultStamps.begin(), it); + indexOfActionInGroup = PageViewAnnotator::STAMP_TOOL_ID + stampActionIndex - 1; + } else { + maybeUpdateCustomStampAction(stampIconName); + indexOfActionInGroup = agTools->actions().size() - 1; + } + } + QAction *favToolAction = agTools->actions().at(indexOfActionInGroup); + if (!favToolAction->isChecked()) { + // action group workaround: activates the action slot calling selectTool + // when new tool if different from the selected one + favToolAction->trigger(); + } else { + selectTool(toolId); + } + aShowToolBar->setChecked(true); +} + +void AnnotationActionHandlerPrivate::slotSetColor(AnnotationColor colorType, const QColor &color) +{ + QColor selectedColor(color); + if (!selectedColor.isValid()) { + selectedColor = QColorDialog::getColor(currentColor, nullptr, i18nc("@title:window", "Select color")); + if (!selectedColor.isValid()) { + return; + } + } + if (colorType == AnnotationColor::Color) { + currentColor = selectedColor; + annotator->setAnnotationColor(selectedColor); + } else if (colorType == AnnotationColor::InnerColor) { + currentInnerColor = selectedColor; + annotator->setAnnotationInnerColor(selectedColor); + } +} + +void AnnotationActionHandlerPrivate::slotSelectAnnotationFont() +{ + bool ok; + QFont selectedFont = QFontDialog::getFont(&ok, currentFont); + if (ok) { + currentFont = selectedFont; + annotator->setAnnotationFont(currentFont); + } +} + +void AnnotationActionHandlerPrivate::slotToolBarVisibilityChanged(bool checked) +{ + if (!checked) { + q->deselectAllAnnotationActions(); + } +} + +AnnotationActionHandler::AnnotationActionHandler(PageViewAnnotator *parent, KActionCollection *ac) + : QObject(parent) + , d(new AnnotationActionHandlerPrivate(this)) +{ + d->annotator = parent; + + // toolbar visibility actions + d->aShowToolBar = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-freehand")), i18n("&Annotations"), this); + d->aHideToolBar = new QAction(QIcon::fromTheme(QStringLiteral("dialog-close")), i18nc("@action:intoolbar Hide the toolbar", "Hide"), this); + connect(d->aHideToolBar, &QAction::triggered, this, [this]() { d->aShowToolBar->setChecked(false); }); + + // Text markup actions + KToggleAction *aHighlighter = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-highlight")), i18nc("@action:intoolbar Annotation tool", "Highlighter"), this); + KToggleAction *aUnderline = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-underline")), i18nc("@action:intoolbar Annotation tool", "Underline"), this); + KToggleAction *aSquiggle = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-underline-squiggle")), i18nc("@action:intoolbar Annotation tool", "Squiggle"), this); + KToggleAction *aStrikeout = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-strikethrough")), i18nc("@action:intoolbar Annotation tool", "Strike Out"), this); + // Notes actions + KToggleAction *aTypewriter = new KToggleAction(QIcon::fromTheme(QStringLiteral("tool-text")), i18nc("@action:intoolbar Annotation tool", "Typewriter"), this); + KToggleAction *aInlineNote = new KToggleAction(QIcon::fromTheme(QStringLiteral("note")), i18nc("@action:intoolbar Annotation tool", "Inline Note"), this); + KToggleAction *aPopupNote = new KToggleAction(QIcon::fromTheme(QStringLiteral("edit-comment")), i18nc("@action:intoolbar Annotation tool", "Popup Note"), this); + KToggleAction *aFreehandLine = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-freehand")), i18nc("@action:intoolbar Annotation tool", "Freehand Line"), this); + // Geometrical shapes actions + KToggleAction *aStraightLine = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-line")), i18nc("@action:intoolbar Annotation tool", "Straight line"), this); + KToggleAction *aArrow = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-arrow")), i18nc("@action:intoolbar Annotation tool", "Arrow"), this); + KToggleAction *aRectangle = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-rectangle")), i18nc("@action:intoolbar Annotation tool", "Rectangle"), this); + KToggleAction *aEllipse = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-ellipse")), i18nc("@action:intoolbar Annotation tool", "Ellipse"), this); + KToggleAction *aPolygon = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-polyline")), i18nc("@action:intoolbar Annotation tool", "Polygon"), this); + d->aGeomShapes = new ToggleActionMenu(QIcon(), QString(), this, ToggleActionMenu::MenuButtonPopup, ToggleActionMenu::ImplicitDefaultAction); + d->aGeomShapes->setText(i18nc("@action", "Geometrical shapes")); + d->aGeomShapes->setEnabled(true); // Need to explicitly set this once, or refreshActions() in part.cpp will disable this action + d->aGeomShapes->addAction(aArrow); + d->aGeomShapes->addAction(aStraightLine); + d->aGeomShapes->addAction(aRectangle); + d->aGeomShapes->addAction(aEllipse); + d->aGeomShapes->addAction(aPolygon); + d->aGeomShapes->setDefaultAction(aArrow); + + // The order in which the actions are added is relevant to connect + // them to the correct toolId defined in tools.xml + d->agTools = new QActionGroup(this); + d->agTools->addAction(aHighlighter); + d->agTools->addAction(aUnderline); + d->agTools->addAction(aSquiggle); + d->agTools->addAction(aStrikeout); + d->agTools->addAction(aTypewriter); + d->agTools->addAction(aInlineNote); + d->agTools->addAction(aPopupNote); + d->agTools->addAction(aFreehandLine); + d->agTools->addAction(aArrow); + d->agTools->addAction(aStraightLine); + d->agTools->addAction(aRectangle); + d->agTools->addAction(aEllipse); + d->agTools->addAction(aPolygon); + + d->textTools.append(aHighlighter); + d->textTools.append(aUnderline); + d->textTools.append(aSquiggle); + d->textTools.append(aStrikeout); + + int toolId = 1; + const QList tools = d->agTools->actions(); + for (const auto &ann : tools) { + // action group workaround: connecting to toggled instead of triggered + connect(ann, &QAction::toggled, this, [this, toolId](bool checked) { + if (checked) + d->selectTool(toolId); + }); + toolId++; + } + + // Stamp action + d->aStamp = new ToggleActionMenu(QIcon::fromTheme(QStringLiteral("tag")), QString(), this, ToggleActionMenu::MenuButtonPopup, ToggleActionMenu::ImplicitDefaultAction); + d->aStamp->setText(i18nc("@action", "Stamp")); + + for (const auto &stamp : StampAnnotationWidget::defaultStamps) { + KToggleAction *ann = new KToggleAction(d->stampIcon(stamp.second), stamp.first, this); + if (!d->aStamp->defaultAction()) + d->aStamp->setDefaultAction(ann); + d->aStamp->addAction(ann); + d->agTools->addAction(ann); + // action group workaround: connecting to toggled instead of triggered + // (because deselectAllAnnotationActions has to call triggered) + connect(ann, &QAction::toggled, this, [this, stamp](bool checked) { + if (checked) + d->slotStampToolSelected(stamp.second); + }); + } + + // Quick annotations action + d->aQuickTools = new KSelectAction(QIcon::fromTheme(QStringLiteral("draw-freehand")), i18nc("@action:intoolbar Show list of quick annotation tools", "Quick Annotations"), this); + d->aQuickTools->setToolTip(i18nc("@info:tooltip", "Choose an annotation tool from the quick annotations")); + d->aQuickTools->setToolBarMode(KSelectAction::MenuMode); + d->aQuickTools->setEnabled(true); // required to ensure that populateQuickAnnotations is executed the first time + d->populateQuickAnnotations(); + + // Add to quick annotation action + d->aAddToQuickTools = new QAction(QIcon::fromTheme(QStringLiteral("favorite")), i18nc("@action:intoolbar Add current annotation tool to the quick annotations list", "Add to Quick Annotations"), this); + + // Pin action + d->aContinuousMode = new KToggleAction(QIcon::fromTheme(QStringLiteral("pin")), i18nc("@action:intoolbar When checked keep the current annotation tool active after use", "Keep Active"), this); + d->aContinuousMode->setToolTip(i18nc("@info:tooltip", "Keep the annotation tool active after use")); + d->aContinuousMode->setChecked(d->annotator->continuousMode()); + + // Constrain angle action + d->aConstrainRatioAndAngle = + new KToggleAction(QIcon::fromTheme(QStringLiteral("snap-angle")), i18nc("@action When checked, line annotations are constrained to 15° steps, shape annotations to 1:1 ratio", "Constrain Ratio and Angle of Annotation Tools"), this); + d->aConstrainRatioAndAngle->setChecked(d->annotator->constrainRatioAndAngleActive()); + + // Annotation settings actions + d->aColor = d->colorPickerAction(AnnotationActionHandlerPrivate::AnnotationColor::Color); + d->aInnerColor = d->colorPickerAction(AnnotationActionHandlerPrivate::AnnotationColor::InnerColor); + d->aFont = new QAction(QIcon::fromTheme(QStringLiteral("font-face")), i18nc("@action:intoolbar Current annotation config option", "Font"), this); + d->aAdvancedSettings = new QAction(QIcon::fromTheme(QStringLiteral("settings-configure")), i18nc("@action:intoolbar Current annotation advanced settings", "Annotation Settings"), this); + + // Width list + d->aWidth = new KSelectAction(QIcon::fromTheme(QStringLiteral("edit-line-width")), i18nc("@action:intoolbar Current annotation config option", "Line width"), this); + d->aWidth->setToolBarMode(KSelectAction::MenuMode); + for (auto width : d->widthStandardValues) { + KToggleAction *ann = new KToggleAction(d->widthIcon(width), i18nc("@item:inlistbox", "Width %1", width), this); + d->aWidth->addAction(ann); + connect(ann, &QAction::triggered, this, [this, width]() { d->annotator->setAnnotationWidth(width); }); + } + + // Opacity list + d->aOpacity = new KSelectAction(QIcon::fromTheme(QStringLiteral("edit-opacity")), i18nc("@action:intoolbar Current annotation config option", "Opacity"), this); + d->aOpacity->setToolBarMode(KSelectAction::MenuMode); + for (double opacity : d->opacityStandardValues) { + KToggleAction *ann = new KToggleAction(GuiUtils::createOpacityIcon(opacity), QStringLiteral("%1\%").arg(opacity * 100), this); + d->aOpacity->addAction(ann); + connect(ann, &QAction::triggered, this, [this, opacity]() { d->annotator->setAnnotationOpacity(opacity); }); + } + + connect(d->aAddToQuickTools, &QAction::triggered, d->annotator, &PageViewAnnotator::addToQuickAnnotations); + connect(d->aContinuousMode, &QAction::toggled, d->annotator, &PageViewAnnotator::setContinuousMode); + connect(d->aConstrainRatioAndAngle, &QAction::toggled, d->annotator, &PageViewAnnotator::setConstrainRatioAndAngle); + connect(d->aAdvancedSettings, &QAction::triggered, d->annotator, &PageViewAnnotator::slotAdvancedSettings); + connect(d->aFont, &QAction::triggered, std::bind(&AnnotationActionHandlerPrivate::slotSelectAnnotationFont, d)); + + // action group workaround: allows unchecking the currently selected annotation action. + // Other parts of code dependent to this workaround are marked with "action group workaround". + connect(d->agTools, &QActionGroup::triggered, this, [this](QAction *action) { + if (action == d->agLastAction) { + d->agLastAction = nullptr; + d->agTools->checkedAction()->setChecked(false); + d->selectTool(-1); + } else { + d->agLastAction = action; + // Show the annotation toolbar whenever actions are triggered (e.g using shortcuts) + d->aShowToolBar->setChecked(true); + } + }); + + ac->addAction(QStringLiteral("mouse_toggle_annotate"), d->aShowToolBar); + ac->addAction(QStringLiteral("hide_annotation_toolbar"), d->aHideToolBar); + ac->addAction(QStringLiteral("annotation_highlighter"), aHighlighter); + ac->addAction(QStringLiteral("annotation_underline"), aUnderline); + ac->addAction(QStringLiteral("annotation_squiggle"), aSquiggle); + ac->addAction(QStringLiteral("annotation_strike_out"), aStrikeout); + ac->addAction(QStringLiteral("annotation_typewriter"), aTypewriter); + ac->addAction(QStringLiteral("annotation_inline_note"), aInlineNote); + ac->addAction(QStringLiteral("annotation_popup_note"), aPopupNote); + ac->addAction(QStringLiteral("annotation_freehand_line"), aFreehandLine); + ac->addAction(QStringLiteral("annotation_arrow"), aArrow); + ac->addAction(QStringLiteral("annotation_straight_line"), aStraightLine); + ac->addAction(QStringLiteral("annotation_rectangle"), aRectangle); + ac->addAction(QStringLiteral("annotation_ellipse"), aEllipse); + ac->addAction(QStringLiteral("annotation_polygon"), aPolygon); + ac->addAction(QStringLiteral("annotation_geometrical_shape"), d->aGeomShapes); + ac->addAction(QStringLiteral("annotation_stamp"), d->aStamp); + ac->addAction(QStringLiteral("annotation_favorites"), d->aQuickTools); + ac->addAction(QStringLiteral("annotation_bookmark"), d->aAddToQuickTools); + ac->addAction(QStringLiteral("annotation_settings_pin"), d->aContinuousMode); + ac->addAction(QStringLiteral("annotation_constrain_ratio_angle"), d->aConstrainRatioAndAngle); + ac->addAction(QStringLiteral("annotation_settings_width"), d->aWidth); + ac->addAction(QStringLiteral("annotation_settings_color"), d->aColor); + ac->addAction(QStringLiteral("annotation_settings_inner_color"), d->aInnerColor); + ac->addAction(QStringLiteral("annotation_settings_opacity"), d->aOpacity); + ac->addAction(QStringLiteral("annotation_settings_font"), d->aFont); + ac->addAction(QStringLiteral("annotation_settings_advanced"), d->aAdvancedSettings); + + ac->setDefaultShortcut(d->aShowToolBar, Qt::Key_F6); + ac->setDefaultShortcut(aHighlighter, Qt::ALT + Qt::Key_1); + ac->setDefaultShortcut(aUnderline, Qt::ALT + Qt::Key_2); + ac->setDefaultShortcut(aSquiggle, Qt::ALT + Qt::Key_3); + ac->setDefaultShortcut(aStrikeout, Qt::ALT + Qt::Key_4); + ac->setDefaultShortcut(aTypewriter, Qt::ALT + Qt::Key_5); + ac->setDefaultShortcut(aInlineNote, Qt::ALT + Qt::Key_6); + ac->setDefaultShortcut(aPopupNote, Qt::ALT + Qt::Key_7); + ac->setDefaultShortcut(aFreehandLine, Qt::ALT + Qt::Key_8); + ac->setDefaultShortcut(aArrow, Qt::ALT + Qt::Key_9); + ac->setDefaultShortcut(aRectangle, Qt::ALT + Qt::Key_0); + ac->setDefaultShortcut(d->aAddToQuickTools, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B)); + d->updateConfigActions(); +} + +AnnotationActionHandler::~AnnotationActionHandler() +{ + // delete the private data storage structure + delete d; +} + +void AnnotationActionHandler::setupAnnotationToolBarVisibilityAction() +{ + // find the main window associated to the toggle toolbar action + QList widgets = d->aShowToolBar->associatedWidgets(); + auto itMainWindow = std::find_if(widgets.begin(), widgets.end(), [](const QWidget *widget) { return qobject_cast(widget) != nullptr; }); + Q_ASSERT(itMainWindow != widgets.end()); + KParts::MainWindow *mw = qobject_cast(*itMainWindow); + // ensure that the annotation toolbar has been created and retrieve it + QList toolbars = mw->toolBars(); + auto itToolBar = std::find_if(toolbars.begin(), toolbars.end(), [](const KToolBar *toolBar) { return toolBar->objectName() == QStringLiteral("annotationToolBar"); }); + Q_ASSERT(itToolBar != toolbars.end()); + KToolBar *annotationToolBar = mw->toolBar(QStringLiteral("annotationToolBar")); + d->aShowToolBar->setChecked(annotationToolBar->isVisible()); + connect(annotationToolBar, &QToolBar::visibilityChanged, d->aShowToolBar, &QAction::setChecked, Qt::UniqueConnection); + connect(d->aShowToolBar, &QAction::toggled, annotationToolBar, &KToolBar::setVisible, Qt::UniqueConnection); + connect(d->aShowToolBar, &QAction::toggled, this, [this](bool checked) { d->slotToolBarVisibilityChanged(checked); }); +} + +void AnnotationActionHandler::reparseBuiltinToolsConfig() +{ + d->parseTool(d->selectedTool); +} + +void AnnotationActionHandler::reparseQuickToolsConfig() +{ + d->populateQuickAnnotations(); +} + +void AnnotationActionHandler::setToolsEnabled(bool on) +{ + const QList tools = d->agTools->actions(); + for (QAction *ann : tools) { + ann->setEnabled(on); + } + d->aQuickTools->setEnabled(on); + d->aGeomShapes->setEnabled(on); + d->aStamp->setEnabled(on); + d->aContinuousMode->setEnabled(on); +} + +void AnnotationActionHandler::setTextToolsEnabled(bool on) +{ + d->textToolsEnabled = on; + for (QAction *ann : qAsConst(d->textTools)) { + ann->setEnabled(on); + } + for (QAction *ann : qAsConst(d->textQuickTools)) { + ann->setEnabled(on); + } +} + +void AnnotationActionHandler::deselectAllAnnotationActions() +{ + QAction *checkedAction = d->agTools->checkedAction(); + if (checkedAction) { + checkedAction->trigger(); // action group workaround: using trigger instead of setChecked + } +} + +#include "moc_annotationactionhandler.cpp" diff --git a/part/annotationactionhandler.h b/part/annotationactionhandler.h new file mode 100644 index 0000000..3e7338e --- /dev/null +++ b/part/annotationactionhandler.h @@ -0,0 +1,52 @@ +/************************************************************************** + * Copyright (C) 2019 by Simone Gaiarin * + * * + * 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 _ANNOTATIONACTIONHANDLER_H_ +#define _ANNOTATIONACTIONHANDLER_H_ + +#include + +class QAction; +class QColor; +class QFont; +class KActionCollection; +class PageViewAnnotator; +class AnnotationActionHandlerPrivate; + +/** + * @short Handles all the actions of the annotation toolbar + */ +class AnnotationActionHandler : public QObject +{ + Q_OBJECT + +public: + AnnotationActionHandler(PageViewAnnotator *parent, KActionCollection *ac); + ~AnnotationActionHandler() override; + + /** + * @short Reads the settings for the current annotation and rebuild the quick annotations menu + * + * This method is called each time okularpartrc is modified. This happens in the following + * situations (among others): the quick annotations are modified from the KCM settings + * page, a tool is modified using the "advanced settings" action, a quick annotation is + * selected, an annotation property (line width, colors, opacity, font) is modified. + */ + void setupAnnotationToolBarVisibilityAction(); + void reparseBuiltinToolsConfig(); + void reparseQuickToolsConfig(); + void setToolsEnabled(bool on); + void setTextToolsEnabled(bool on); + void deselectAllAnnotationActions(); + +private: + class AnnotationActionHandlerPrivate *d; +}; + +#endif // _ANNOTATIONACTIONHANDLER_H_ diff --git a/part/annotationmodel.cpp b/part/annotationmodel.cpp new file mode 100644 index 0000000..b587bf3 --- /dev/null +++ b/part/annotationmodel.cpp @@ -0,0 +1,407 @@ +/*************************************************************************** + * Copyright (C) 2006 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "annotationmodel.h" + +#include +#include +#include + +#include +#include + +#include "core/annotations.h" +#include "core/document.h" +#include "core/observer.h" +#include "core/page.h" +#include "guiutils.h" + +struct AnnItem { + AnnItem(); + AnnItem(AnnItem *parent, Okular::Annotation *ann); + AnnItem(AnnItem *parent, int page); + ~AnnItem(); + + AnnItem(const AnnItem &) = delete; + AnnItem &operator=(const AnnItem &) = delete; + + AnnItem *parent; + QList children; + + Okular::Annotation *annotation; + int page; +}; + +static QLinkedList filterOutWidgetAnnotations(const QLinkedList &annotations) +{ + QLinkedList result; + + for (Okular::Annotation *annotation : annotations) { + if (annotation->subType() == Okular::Annotation::AWidget) + continue; + + result.append(annotation); + } + + return result; +} + +class AnnotationModelPrivate : public Okular::DocumentObserver +{ +public: + AnnotationModelPrivate(AnnotationModel *qq); + ~AnnotationModelPrivate() override; + + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyPageChanged(int page, int flags) override; + + QModelIndex indexForItem(AnnItem *item) const; + void rebuildTree(const QVector &pages); + AnnItem *findItem(int page, int *index) const; + + AnnotationModel *q; + AnnItem *root; + QPointer document; +}; + +AnnItem::AnnItem() + : parent(nullptr) + , annotation(nullptr) + , page(-1) +{ +} + +AnnItem::AnnItem(AnnItem *_parent, Okular::Annotation *ann) + : parent(_parent) + , annotation(ann) + , page(_parent->page) +{ + Q_ASSERT(!parent->annotation); + parent->children.append(this); +} + +AnnItem::AnnItem(AnnItem *_parent, int _page) + : parent(_parent) + , annotation(nullptr) + , page(_page) +{ + Q_ASSERT(!parent->parent); + parent->children.append(this); +} + +AnnItem::~AnnItem() +{ + qDeleteAll(children); +} + +AnnotationModelPrivate::AnnotationModelPrivate(AnnotationModel *qq) + : q(qq) + , root(new AnnItem) +{ +} + +AnnotationModelPrivate::~AnnotationModelPrivate() +{ + delete root; +} + +static void updateAnnotationPointer(AnnItem *item, const QVector &pages) +{ + if (item->annotation) { + item->annotation = pages[item->page]->annotation(item->annotation->uniqueName()); + if (!item->annotation) + qWarning() << "Lost annotation on document save, something went wrong"; + } + + for (AnnItem *child : qAsConst(item->children)) { + updateAnnotationPointer(child, pages); + } +} + +void AnnotationModelPrivate::notifySetup(const QVector &pages, int setupFlags) +{ + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) { + if (setupFlags & Okular::DocumentObserver::UrlChanged) { + // Here with UrlChanged and no document changed it means we + // need to update all the Annotation* otherwise + // they still point to the old document ones, luckily the old ones are still + // around so we can look for the new ones using unique ids, etc + updateAnnotationPointer(root, pages); + } + return; + } + + q->beginResetModel(); + qDeleteAll(root->children); + root->children.clear(); + + rebuildTree(pages); + q->endResetModel(); +} + +void AnnotationModelPrivate::notifyPageChanged(int page, int flags) +{ + // we are strictly interested in annotations + if (!(flags & Okular::DocumentObserver::Annotations)) + return; + + const QLinkedList annots = filterOutWidgetAnnotations(document->page(page)->annotations()); + int annItemIndex = -1; + AnnItem *annItem = findItem(page, &annItemIndex); + // case 1: the page has no more annotations + // => remove the branch, if any + if (annots.isEmpty()) { + if (annItem) { + q->beginRemoveRows(indexForItem(root), annItemIndex, annItemIndex); + delete root->children.at(annItemIndex); + root->children.removeAt(annItemIndex); + q->endRemoveRows(); + } + return; + } + // case 2: no existing branch + // => add a new branch, and add the annotations for the page + if (!annItem) { + int i = 0; + while (i < root->children.count() && root->children.at(i)->page < page) + ++i; + + AnnItem *annItem = new AnnItem(); + annItem->page = page; + annItem->parent = root; + q->beginInsertRows(indexForItem(root), i, i); + annItem->parent->children.insert(i, annItem); + q->endInsertRows(); + QLinkedList::ConstIterator it = annots.begin(), itEnd = annots.end(); + int newid = 0; + for (; it != itEnd; ++it, ++newid) { + q->beginInsertRows(indexForItem(annItem), newid, newid); + new AnnItem(annItem, *it); + q->endInsertRows(); + } + return; + } + // case 3: existing branch, less annotations than items + // => lookup and remove the annotations + if (annItem->children.count() > annots.count()) { + for (int i = annItem->children.count(); i > 0; --i) { + Okular::Annotation *ref = annItem->children.at(i - 1)->annotation; + bool found = false; + QLinkedList::ConstIterator it = annots.begin(), itEnd = annots.end(); + for (; !found && it != itEnd; ++it) { + if ((*it) == ref) + found = true; + } + if (!found) { + q->beginRemoveRows(indexForItem(annItem), i - 1, i - 1); + delete annItem->children.at(i - 1); + annItem->children.removeAt(i - 1); + q->endRemoveRows(); + } + } + return; + } + // case 4: existing branch, less items than annotations + // => lookup and add annotations if not in the branch + if (annots.count() > annItem->children.count()) { + QLinkedList::ConstIterator it = annots.begin(), itEnd = annots.end(); + for (; it != itEnd; ++it) { + Okular::Annotation *ref = *it; + bool found = false; + int count = annItem->children.count(); + for (int i = 0; !found && i < count; ++i) { + if (ref == annItem->children.at(i)->annotation) + found = true; + } + if (!found) { + q->beginInsertRows(indexForItem(annItem), count, count); + new AnnItem(annItem, ref); + q->endInsertRows(); + } + } + return; + } + // case 5: the data of some annotation changed + // TODO: what do we do in this case? + // FIXME: for now, update ALL the annotations for that page + for (int i = 0; i < annItem->children.count(); ++i) { + QModelIndex index = indexForItem(annItem->children.at(i)); + emit q->dataChanged(index, index); + } +} + +QModelIndex AnnotationModelPrivate::indexForItem(AnnItem *item) const +{ + if (item->parent) { + int id = item->parent->children.indexOf(item); + if (id >= 0 && id < item->parent->children.count()) + return q->createIndex(id, 0, item); + } + return QModelIndex(); +} + +void AnnotationModelPrivate::rebuildTree(const QVector &pages) +{ + if (pages.isEmpty()) + return; + + emit q->layoutAboutToBeChanged(); + for (int i = 0; i < pages.count(); ++i) { + const QLinkedList annots = filterOutWidgetAnnotations(pages.at(i)->annotations()); + if (annots.isEmpty()) + continue; + + AnnItem *annItem = new AnnItem(root, i); + QLinkedList::ConstIterator it = annots.begin(), itEnd = annots.end(); + for (; it != itEnd; ++it) { + new AnnItem(annItem, *it); + } + } + emit q->layoutChanged(); +} + +AnnItem *AnnotationModelPrivate::findItem(int page, int *index) const +{ + for (int i = 0; i < root->children.count(); ++i) { + AnnItem *tmp = root->children.at(i); + if (tmp->page == page) { + if (index) + *index = i; + return tmp; + } + } + if (index) + *index = -1; + return nullptr; +} + +AnnotationModel::AnnotationModel(Okular::Document *document, QObject *parent) + : QAbstractItemModel(parent) + , d(new AnnotationModelPrivate(this)) +{ + d->document = document; + + d->document->addObserver(d); +} + +AnnotationModel::~AnnotationModel() +{ + if (d->document) + d->document->removeObserver(d); + + delete d; +} + +int AnnotationModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant AnnotationModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + AnnItem *item = static_cast(index.internalPointer()); + if (!item->annotation) { + if (role == Qt::DisplayRole) + return i18n("Page %1", item->page + 1); + else if (role == Qt::DecorationRole) + return QIcon::fromTheme(QStringLiteral("text-plain")); + else if (role == PageRole) + return item->page; + + return QVariant(); + } + switch (role) { + case Qt::DisplayRole: + return GuiUtils::captionForAnnotation(item->annotation); + break; + case Qt::DecorationRole: + return QIcon::fromTheme(QStringLiteral("okular")); + break; + case Qt::ToolTipRole: + return GuiUtils::prettyToolTip(item->annotation); + break; + case AuthorRole: + return item->annotation->author(); + break; + case PageRole: + return item->page; + break; + } + return QVariant(); +} + +bool AnnotationModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return true; + + AnnItem *item = static_cast(parent.internalPointer()); + return !item->children.isEmpty(); +} + +QVariant AnnotationModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal) + return QVariant(); + + if (section == 0 && role == Qt::DisplayRole) + return QString::fromLocal8Bit("Annotations"); + + return QVariant(); +} + +QModelIndex AnnotationModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 || column != 0) + return QModelIndex(); + + AnnItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + if (row < item->children.count()) + return createIndex(row, column, item->children.at(row)); + + return QModelIndex(); +} + +QModelIndex AnnotationModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + AnnItem *item = static_cast(index.internalPointer()); + return d->indexForItem(item->parent); +} + +int AnnotationModel::rowCount(const QModelIndex &parent) const +{ + AnnItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + return item->children.count(); +} + +bool AnnotationModel::isAnnotation(const QModelIndex &index) const +{ + return annotationForIndex(index); +} + +Okular::Annotation *AnnotationModel::annotationForIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return nullptr; + + AnnItem *item = static_cast(index.internalPointer()); + return item->annotation; +} + +#include "moc_annotationmodel.cpp" diff --git a/part/annotationmodel.h b/part/annotationmodel.h new file mode 100644 index 0000000..f98a0ee --- /dev/null +++ b/part/annotationmodel.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2006 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 ANNOTATIONMODEL_H +#define ANNOTATIONMODEL_H + +#include + +namespace Okular +{ +class Annotation; +class Document; +} + +class AnnotationModelPrivate; + +class AnnotationModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + enum { AuthorRole = Qt::UserRole + 1000, PageRole }; + + explicit AnnotationModel(Okular::Document *document, QObject *parent = nullptr); + ~AnnotationModel() override; + + // reimplementations from QAbstractItemModel + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + bool isAnnotation(const QModelIndex &index) const; + Okular::Annotation *annotationForIndex(const QModelIndex &index) const; + +private: + // storage + friend class AnnotationModelPrivate; + AnnotationModelPrivate *const d; +}; + +#endif diff --git a/part/annotationpopup.cpp b/part/annotationpopup.cpp new file mode 100644 index 0000000..ec5bdc4 --- /dev/null +++ b/part/annotationpopup.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (C) 2006 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "annotationpopup.h" + +#include +#include +#include + +#include "annotationpropertiesdialog.h" + +#include "core/annotations.h" +#include "core/document.h" +#include "guiutils.h" +#include "okmenutitle.h" + +Q_DECLARE_METATYPE(AnnotationPopup::AnnotPagePair) + +namespace +{ +bool annotationHasFileAttachment(Okular::Annotation *annotation) +{ + return (annotation->subType() == Okular::Annotation::AFileAttachment || annotation->subType() == Okular::Annotation::ARichMedia); +} + +Okular::EmbeddedFile *embeddedFileFromAnnotation(Okular::Annotation *annotation) +{ + if (annotation->subType() == Okular::Annotation::AFileAttachment) { + const Okular::FileAttachmentAnnotation *fileAttachAnnot = static_cast(annotation); + return fileAttachAnnot->embeddedFile(); + } else if (annotation->subType() == Okular::Annotation::ARichMedia) { + const Okular::RichMediaAnnotation *richMediaAnnot = static_cast(annotation); + return richMediaAnnot->embeddedFile(); + } else { + return nullptr; + } +} + +} + +AnnotationPopup::AnnotationPopup(Okular::Document *document, MenuMode mode, QWidget *parent) + : mParent(parent) + , mDocument(document) + , mMenuMode(mode) +{ +} + +void AnnotationPopup::addAnnotation(Okular::Annotation *annotation, int pageNumber) +{ + AnnotPagePair pair(annotation, pageNumber); + if (!mAnnotations.contains(pair)) + mAnnotations.append(pair); +} + +void AnnotationPopup::exec(const QPoint point) +{ + if (mAnnotations.isEmpty()) + return; + + QMenu menu(mParent); + + addActionsToMenu(&menu); + + menu.exec(point.isNull() ? QCursor::pos() : point); +} + +void AnnotationPopup::addActionsToMenu(QMenu *menu) +{ + QAction *action = nullptr; + + if (mMenuMode == SingleAnnotationMode) { + const bool onlyOne = (mAnnotations.count() == 1); + + const AnnotPagePair &pair = mAnnotations.at(0); + + menu->addAction(new OKMenuTitle(menu, i18np("Annotation", "%1 Annotations", mAnnotations.count()))); + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("comment")), i18n("&Open Pop-up Note")); + action->setEnabled(onlyOne); + connect(action, &QAction::triggered, menu, [this, pair] { doOpenAnnotationWindow(pair); }); + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("&Delete")); + action->setEnabled(mDocument->isAllowed(Okular::AllowNotes)); + connect(action, &QAction::triggered, menu, [this] { + for (const AnnotPagePair &pair : qAsConst(mAnnotations)) { + doRemovePageAnnotation(pair); + } + }); + + for (const AnnotPagePair &pair : qAsConst(mAnnotations)) { + if (!mDocument->canRemovePageAnnotation(pair.annotation)) + action->setEnabled(false); + } + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("&Properties")); + action->setEnabled(onlyOne); + connect(action, &QAction::triggered, menu, [this, pair] { doOpenPropertiesDialog(pair); }); + + if (onlyOne && annotationHasFileAttachment(pair.annotation)) { + const Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation(pair.annotation); + if (embeddedFile) { + const QString saveText = i18nc("%1 is the name of the file to save", "&Save '%1'...", embeddedFile->name()); + + menu->addSeparator(); + action = menu->addAction(QIcon::fromTheme(QStringLiteral("document-save")), saveText); + connect(action, &QAction::triggered, menu, [this, pair] { doSaveEmbeddedFile(pair); }); + } + } + } else { + for (const AnnotPagePair &pair : qAsConst(mAnnotations)) { + menu->addAction(new OKMenuTitle(menu, GuiUtils::captionForAnnotation(pair.annotation))); + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("comment")), i18n("&Open Pop-up Note")); + connect(action, &QAction::triggered, menu, [this, pair] { doOpenAnnotationWindow(pair); }); + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("&Delete")); + action->setEnabled(mDocument->isAllowed(Okular::AllowNotes) && mDocument->canRemovePageAnnotation(pair.annotation)); + connect(action, &QAction::triggered, menu, [this, pair] { doRemovePageAnnotation(pair); }); + + action = menu->addAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("&Properties")); + connect(action, &QAction::triggered, menu, [this, pair] { doOpenPropertiesDialog(pair); }); + + if (annotationHasFileAttachment(pair.annotation)) { + const Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation(pair.annotation); + if (embeddedFile) { + const QString saveText = i18nc("%1 is the name of the file to save", "&Save '%1'...", embeddedFile->name()); + + menu->addSeparator(); + action = menu->addAction(QIcon::fromTheme(QStringLiteral("document-save")), saveText); + connect(action, &QAction::triggered, menu, [this, pair] { doSaveEmbeddedFile(pair); }); + } + } + } + } +} + +void AnnotationPopup::doRemovePageAnnotation(AnnotPagePair pair) +{ + if (pair.pageNumber != -1) { + mDocument->removePageAnnotation(pair.pageNumber, pair.annotation); + } +} + +void AnnotationPopup::doOpenAnnotationWindow(AnnotPagePair pair) +{ + emit openAnnotationWindow(pair.annotation, pair.pageNumber); +} + +void AnnotationPopup::doOpenPropertiesDialog(AnnotPagePair pair) +{ + if (pair.pageNumber != -1) { + AnnotsPropertiesDialog propdialog(mParent, mDocument, pair.pageNumber, pair.annotation); + propdialog.exec(); + } +} + +void AnnotationPopup::doSaveEmbeddedFile(AnnotPagePair pair) +{ + Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation(pair.annotation); + GuiUtils::saveEmbeddedFile(embeddedFile, mParent); +} diff --git a/part/annotationpopup.h b/part/annotationpopup.h new file mode 100644 index 0000000..d37a1cc --- /dev/null +++ b/part/annotationpopup.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * Copyright (C) 2006 by Tobias Koenig * + * * + * 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 ANNOTATIONPOPUP_H +#define ANNOTATIONPOPUP_H + +#include +#include +#include +#include + +class QMenu; + +namespace Okular +{ +class Annotation; +class Document; +} + +class AnnotationPopup : public QObject +{ + Q_OBJECT + +public: + /** + * Describes the structure of the popup menu. + */ + enum MenuMode { + SingleAnnotationMode, ///< The menu shows only entries to manipulate a single annotation, or multiple annotations as a group. + MultiAnnotationMode ///< The menu shows entries to manipulate multiple annotations. + }; + + AnnotationPopup(Okular::Document *document, MenuMode mode, QWidget *parent = nullptr); + + void addAnnotation(Okular::Annotation *annotation, int pageNumber); + + /* You only need to use this if you don't plan on using exec() */ + void addActionsToMenu(QMenu *menu); + + void exec(const QPoint point = QPoint()); + +Q_SIGNALS: + void openAnnotationWindow(Okular::Annotation *annotation, int pageNumber); + +public: + struct AnnotPagePair { + AnnotPagePair() + : annotation(nullptr) + , pageNumber(-1) + { + } + + AnnotPagePair(Okular::Annotation *a, int pn) + : annotation(a) + , pageNumber(pn) + { + } + + bool operator==(const AnnotPagePair pair) const + { + return annotation == pair.annotation && pageNumber == pair.pageNumber; + } + + Okular::Annotation *annotation; + int pageNumber; + }; + +private: + void doRemovePageAnnotation(AnnotPagePair pair); + void doOpenAnnotationWindow(AnnotPagePair pair); + void doOpenPropertiesDialog(AnnotPagePair pair); + void doSaveEmbeddedFile(AnnotPagePair pair); + + QWidget *mParent; + + QList mAnnotations; + Okular::Document *mDocument; + MenuMode mMenuMode; +}; + +#endif diff --git a/part/annotationpropertiesdialog.cpp b/part/annotationpropertiesdialog.cpp new file mode 100644 index 0000000..4bae8cd --- /dev/null +++ b/part/annotationpropertiesdialog.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * Copyright (C) 2006 by Chu Xiaodong * + * * + * 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. * + ***************************************************************************/ + +#include "annotationpropertiesdialog.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "annotationwidgets.h" +#include "core/annotations.h" +#include "core/document.h" +#include "core/page.h" + +AnnotsPropertiesDialog::AnnotsPropertiesDialog(QWidget *parent, Okular::Document *document, int docpage, Okular::Annotation *ann) + : KPageDialog(parent) + , m_document(document) + , m_page(docpage) + , modified(false) +{ + setFaceType(Tabbed); + m_annot = ann; + const bool canEditAnnotations = m_document->canModifyPageAnnotation(ann); + setCaptionTextbyAnnotType(); + if (canEditAnnotations) { + setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel); + button(QDialogButtonBox::Apply)->setEnabled(false); + connect(button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &AnnotsPropertiesDialog::slotapply); + connect(button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &AnnotsPropertiesDialog::slotapply); + } else { + setStandardButtons(QDialogButtonBox::Close); + button(QDialogButtonBox::Close)->setDefault(true); + } + + m_annotWidget = AnnotationWidgetFactory::widgetFor(ann); + + QLabel *tmplabel; + // 1. Appearance + // BEGIN tab1 + QWidget *appearanceWidget = m_annotWidget->appearanceWidget(); + appearanceWidget->setEnabled(canEditAnnotations); + addPage(appearanceWidget, i18n("&Appearance")); + // END tab1 + + // BEGIN tab 2 + QFrame *page = new QFrame(this); + addPage(page, i18n("&General")); + // m_tabitem[1]->setIcon( QIcon::fromTheme( "fonts" ) ); + QFormLayout *gridlayout = new QFormLayout(page); + AuthorEdit = new KLineEdit(ann->author(), page); + AuthorEdit->setEnabled(canEditAnnotations); + gridlayout->addRow(i18n("&Author:"), AuthorEdit); + + tmplabel = new QLabel(page); + tmplabel->setText(QLocale().toString(ann->creationDate(), QLocale::LongFormat)); + tmplabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + gridlayout->addRow(i18n("Created:"), tmplabel); + + m_modifyDateLabel = new QLabel(page); + m_modifyDateLabel->setText(QLocale().toString(ann->modificationDate(), QLocale::LongFormat)); + m_modifyDateLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + gridlayout->addRow(i18n("Modified:"), m_modifyDateLabel); + + // END tab 2 + + QWidget *extraWidget = m_annotWidget->extraWidget(); + if (extraWidget) { + addPage(extraWidget, extraWidget->windowTitle()); + } + + // BEGIN connections + connect(AuthorEdit, &QLineEdit::textChanged, this, &AnnotsPropertiesDialog::setModified); + connect(m_annotWidget, &AnnotationWidget::dataChanged, this, &AnnotsPropertiesDialog::setModified); + // END + +#if 0 + qCDebug(OkularUiDebug) << "Annotation details:"; + qCDebug(OkularUiDebug).nospace() << " => unique name: '" << ann->uniqueName() << "'"; + qCDebug(OkularUiDebug) << " => flags:" << QString::number( m_annot->flags(), 2 ); +#endif + + resize(sizeHint()); +} +AnnotsPropertiesDialog::~AnnotsPropertiesDialog() +{ + delete m_annotWidget; +} + +void AnnotsPropertiesDialog::setCaptionTextbyAnnotType() +{ + Okular::Annotation::SubType type = m_annot->subType(); + QString captiontext; + switch (type) { + case Okular::Annotation::AText: + if (((Okular::TextAnnotation *)m_annot)->textType() == Okular::TextAnnotation::Linked) + captiontext = i18n("Pop-up Note Properties"); + else { + if (((Okular::TextAnnotation *)m_annot)->inplaceIntent() == Okular::TextAnnotation::TypeWriter) + captiontext = i18n("Typewriter Properties"); + else + captiontext = i18n("Inline Note Properties"); + } + break; + case Okular::Annotation::ALine: + if (((Okular::LineAnnotation *)m_annot)->linePoints().count() == 2) + captiontext = i18n("Straight Line Properties"); + else + captiontext = i18n("Polygon Properties"); + break; + case Okular::Annotation::AGeom: + captiontext = i18n("Geometry Properties"); + break; + case Okular::Annotation::AHighlight: + captiontext = i18n("Text Markup Properties"); + break; + case Okular::Annotation::AStamp: + captiontext = i18n("Stamp Properties"); + break; + case Okular::Annotation::AInk: + captiontext = i18n("Freehand Line Properties"); + break; + case Okular::Annotation::ACaret: + captiontext = i18n("Caret Properties"); + break; + case Okular::Annotation::AFileAttachment: + captiontext = i18n("File Attachment Properties"); + break; + case Okular::Annotation::ASound: + captiontext = i18n("Sound Properties"); + break; + case Okular::Annotation::AMovie: + captiontext = i18n("Movie Properties"); + break; + default: + captiontext = i18n("Annotation Properties"); + break; + } + setWindowTitle(captiontext); +} + +void AnnotsPropertiesDialog::setModified() +{ + modified = true; + button(QDialogButtonBox::Apply)->setEnabled(true); +} + +void AnnotsPropertiesDialog::slotapply() +{ + if (!modified) + return; + + m_document->prepareToModifyAnnotationProperties(m_annot); + m_annot->setAuthor(AuthorEdit->text()); + m_annot->setModificationDate(QDateTime::currentDateTime()); + + m_annotWidget->applyChanges(); + + m_document->modifyPageAnnotationProperties(m_page, m_annot); + + m_modifyDateLabel->setText(i18n("Modified: %1", QLocale().toString(m_annot->modificationDate(), QLocale::LongFormat))); + + modified = false; + button(QDialogButtonBox::Apply)->setEnabled(false); +} + +#include "moc_annotationpropertiesdialog.cpp" diff --git a/part/annotationpropertiesdialog.h b/part/annotationpropertiesdialog.h new file mode 100644 index 0000000..831c8f0 --- /dev/null +++ b/part/annotationpropertiesdialog.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2006 by Chu Xiaodong * + * * + * 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 _ANNOTATIONPROPERTIESDIALOG_H_ +#define _ANNOTATIONPROPERTIESDIALOG_H_ + +#include + +class QLabel; +class QLineEdit; +class AnnotationWidget; + +namespace Okular +{ +class Annotation; +class Document; +} + +class AnnotsPropertiesDialog : public KPageDialog +{ + Q_OBJECT +public: + AnnotsPropertiesDialog(QWidget *parent, Okular::Document *document, int docpage, Okular::Annotation *ann); + ~AnnotsPropertiesDialog() override; + +private: + Okular::Document *m_document; + int m_page; + bool modified; + Okular::Annotation *m_annot; // source annotation + // dialog widgets: + QLineEdit *AuthorEdit; + AnnotationWidget *m_annotWidget; + QLabel *m_modifyDateLabel; + + void setCaptionTextbyAnnotType(); + +private Q_SLOTS: + void setModified(); + void slotapply(); +}; + +#endif diff --git a/part/annotationproxymodels.cpp b/part/annotationproxymodels.cpp new file mode 100644 index 0000000..f22eb39 --- /dev/null +++ b/part/annotationproxymodels.cpp @@ -0,0 +1,640 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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. * + ***************************************************************************/ + +#include "annotationproxymodels.h" + +#include +#include + +#include + +#include "annotationmodel.h" +#include "debug_ui.h" + +static quint32 mixIndex(int row, int column) +{ + return (row << 4) | column; +} + +PageFilterProxyModel::PageFilterProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) + , mGroupByCurrentPage(false) + , mCurrentPage(-1) +{ + setDynamicSortFilter(true); +} + +void PageFilterProxyModel::groupByCurrentPage(bool value) +{ + if (mGroupByCurrentPage == value) + return; + + mGroupByCurrentPage = value; + + invalidateFilter(); +} + +void PageFilterProxyModel::setCurrentPage(int page) +{ + if (mCurrentPage == page) + return; + + mCurrentPage = page; + + // no need to invalidate when we're not showing the current page only + if (!mGroupByCurrentPage) + return; + + invalidateFilter(); +} + +bool PageFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &sourceParent) const +{ + if (!mGroupByCurrentPage) + return true; + + const QModelIndex pageIndex = sourceModel()->index(row, 0, sourceParent); + int page = sourceModel()->data(pageIndex, AnnotationModel::PageRole).toInt(); + + return (page == mCurrentPage); +} + +PageGroupProxyModel::PageGroupProxyModel(QObject *parent) + : QAbstractProxyModel(parent) + , mGroupByPage(false) +{ +} + +int PageGroupProxyModel::columnCount(const QModelIndex &parentIndex) const +{ + // For top-level and second level we have always only one column + if (mGroupByPage) { + if (parentIndex.isValid()) { + if (parentIndex.parent().isValid()) + return 0; + else { + return 1; // second-level + } + } else { + return 1; // top-level + } + } else { + if (!parentIndex.isValid()) // top-level + return 1; + else + return 0; + } + return 1; +} + +int PageGroupProxyModel::rowCount(const QModelIndex &parentIndex) const +{ + if (mGroupByPage) { + if (parentIndex.isValid()) { + if (parentIndex.parent().isValid()) + return 0; + else { + return mTreeIndexes[parentIndex.row()].second.count(); // second-level + } + } else { + return mTreeIndexes.count(); // top-level + } + } else { + if (!parentIndex.isValid()) // top-level + return mIndexes.count(); + else + return 0; + } +} + +QModelIndex PageGroupProxyModel::index(int row, int column, const QModelIndex &parentIndex) const +{ + if (row < 0 || column != 0) + return QModelIndex(); + + if (mGroupByPage) { + if (parentIndex.isValid()) { + if (parentIndex.row() >= 0 && parentIndex.row() < mTreeIndexes.count() && row < mTreeIndexes[parentIndex.row()].second.count()) + return createIndex(row, column, qint32(parentIndex.row() + 1)); + else + return QModelIndex(); + } else { + if (row < mTreeIndexes.count()) + return createIndex(row, column); + else + return QModelIndex(); + } + } else { + if (row < mIndexes.count()) + return createIndex(row, column, mixIndex(parentIndex.row(), parentIndex.column())); + else + return QModelIndex(); + } +} + +QModelIndex PageGroupProxyModel::parent(const QModelIndex &idx) const +{ + if (mGroupByPage) { + if (idx.internalId() == 0) // top-level + return QModelIndex(); + else + return index(idx.internalId() - 1, idx.column()); + } else { + // We have only top-level items + return QModelIndex(); + } +} + +QModelIndex PageGroupProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + if (mGroupByPage) { + if (sourceIndex.parent().isValid()) { + return index(sourceIndex.row(), sourceIndex.column(), sourceIndex.parent()); + } else { + return index(sourceIndex.row(), sourceIndex.column()); + } + } else { + for (int i = 0; i < mIndexes.count(); ++i) { + if (mIndexes[i] == sourceIndex) + return index(i, 0); + } + + return QModelIndex(); + } +} + +QModelIndex PageGroupProxyModel::mapToSource(const QModelIndex &proxyIndex) const +{ + if (!proxyIndex.isValid()) + return QModelIndex(); + + if (mGroupByPage) { + if (proxyIndex.internalId() == 0) { + if (proxyIndex.row() >= mTreeIndexes.count() || proxyIndex.row() < 0) + return QModelIndex(); + + return mTreeIndexes[proxyIndex.row()].first; + } else { + if (qint32(proxyIndex.internalId()) - 1 >= mTreeIndexes.count() || proxyIndex.row() >= mTreeIndexes[proxyIndex.internalId() - 1].second.count()) + return QModelIndex(); + + return mTreeIndexes[proxyIndex.internalId() - 1].second[proxyIndex.row()]; + } + } else { + if (proxyIndex.column() > 0 || proxyIndex.row() >= mIndexes.count()) + return QModelIndex(); + else { + return mIndexes[proxyIndex.row()]; + } + } +} + +void PageGroupProxyModel::setSourceModel(QAbstractItemModel *model) +{ + if (sourceModel()) { + disconnect(sourceModel(), &QAbstractItemModel::layoutChanged, this, &PageGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::modelReset, this, &PageGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &PageGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, &PageGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::dataChanged, this, &PageGroupProxyModel::sourceDataChanged); + } + + QAbstractProxyModel::setSourceModel(model); + + connect(sourceModel(), &QAbstractItemModel::layoutChanged, this, &PageGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::modelReset, this, &PageGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &PageGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, &PageGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::dataChanged, this, &PageGroupProxyModel::sourceDataChanged); + + rebuildIndexes(); +} + +void PageGroupProxyModel::rebuildIndexes() +{ + beginResetModel(); + + if (mGroupByPage) { + mTreeIndexes.clear(); + + for (int row = 0; row < sourceModel()->rowCount(); ++row) { + const QModelIndex pageIndex = sourceModel()->index(row, 0); + + QList itemIndexes; + for (int subRow = 0; subRow < sourceModel()->rowCount(pageIndex); ++subRow) { + itemIndexes.append(sourceModel()->index(subRow, 0, pageIndex)); + } + + mTreeIndexes.append(QPair>(pageIndex, itemIndexes)); + } + } else { + mIndexes.clear(); + + for (int row = 0; row < sourceModel()->rowCount(); ++row) { + const QModelIndex pageIndex = sourceModel()->index(row, 0); + for (int subRow = 0; subRow < sourceModel()->rowCount(pageIndex); ++subRow) { + mIndexes.append(sourceModel()->index(subRow, 0, pageIndex)); + } + } + } + + endResetModel(); +} + +void PageGroupProxyModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles); +} + +void PageGroupProxyModel::groupByPage(bool value) +{ + if (mGroupByPage == value) + return; + + mGroupByPage = value; + + rebuildIndexes(); +} + +class AuthorGroupItem +{ +public: + enum Type { Page, Author, Annotation }; + + AuthorGroupItem(AuthorGroupItem *parent, Type type = Page, const QModelIndex &index = QModelIndex()) + : mParent(parent) + , mType(type) + , mIndex(index) + { + } + + ~AuthorGroupItem() + { + qDeleteAll(mChilds); + } + + AuthorGroupItem(const AuthorGroupItem &) = delete; + AuthorGroupItem &operator=(const AuthorGroupItem &) = delete; + + void appendChild(AuthorGroupItem *child) + { + mChilds.append(child); + } + AuthorGroupItem *parent() const + { + return mParent; + } + AuthorGroupItem *child(int row) const + { + return mChilds.value(row); + } + int childCount() const + { + return mChilds.count(); + } + + void dump(int level = 0) + { + QString prefix; + for (int i = 0; i < level; ++i) + prefix += QLatin1Char(' '); + + qCDebug(OkularUiDebug, "%s%s", qPrintable(prefix), (mType == Page ? "Page" : (mType == Author ? "Author" : "Annotation"))); + + for (int i = 0; i < mChilds.count(); ++i) + mChilds[i]->dump(level + 2); + } + + const AuthorGroupItem *findIndex(const QModelIndex &index) const + { + if (index == mIndex) + return this; + + for (int i = 0; i < mChilds.count(); ++i) { + const AuthorGroupItem *item = mChilds[i]->findIndex(index); + if (item) + return item; + } + + return nullptr; + } + + int row() const + { + return (mParent ? mParent->mChilds.indexOf(const_cast(this)) : 0); + } + + Type type() const + { + return mType; + } + QModelIndex index() const + { + return mIndex; + } + + void setAuthor(const QString &author) + { + mAuthor = author; + } + QString author() const + { + return mAuthor; + } + +private: + AuthorGroupItem *mParent; + Type mType; + QModelIndex mIndex; + QList mChilds; + QString mAuthor; +}; + +class AuthorGroupProxyModel::Private +{ +public: + Private(AuthorGroupProxyModel *parent) + : mParent(parent) + , mRoot(nullptr) + , mGroupByAuthor(false) + { + } + ~Private() + { + delete mRoot; + } + + AuthorGroupProxyModel *mParent; + AuthorGroupItem *mRoot; + bool mGroupByAuthor; +}; + +AuthorGroupProxyModel::AuthorGroupProxyModel(QObject *parent) + : QAbstractProxyModel(parent) + , d(new Private(this)) +{ +} + +AuthorGroupProxyModel::~AuthorGroupProxyModel() +{ + delete d; +} + +int AuthorGroupProxyModel::columnCount(const QModelIndex &) const +{ + return 1; +} + +int AuthorGroupProxyModel::rowCount(const QModelIndex &parentIndex) const +{ + AuthorGroupItem *item = nullptr; + if (!parentIndex.isValid()) + item = d->mRoot; + else + item = static_cast(parentIndex.internalPointer()); + + return item ? item->childCount() : 0; +} + +QModelIndex AuthorGroupProxyModel::index(int row, int column, const QModelIndex &parentIndex) const +{ + if (!hasIndex(row, column, parentIndex)) + return QModelIndex(); + + AuthorGroupItem *parentItem = nullptr; + if (!parentIndex.isValid()) + parentItem = d->mRoot; + else + parentItem = static_cast(parentIndex.internalPointer()); + + AuthorGroupItem *child = parentItem->child(row); + if (child) + return createIndex(row, column, child); + else + return QModelIndex(); +} + +QModelIndex AuthorGroupProxyModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + AuthorGroupItem *childItem = static_cast(index.internalPointer()); + AuthorGroupItem *parentItem = childItem->parent(); + + if (parentItem == d->mRoot) + return QModelIndex(); + else + return createIndex(parentItem->row(), 0, parentItem); +} + +QModelIndex AuthorGroupProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + if (!sourceIndex.isValid()) + return QModelIndex(); + + const AuthorGroupItem *item = d->mRoot->findIndex(sourceIndex); + if (!item) + return QModelIndex(); + + return createIndex(item->row(), 0, const_cast(item)); +} + +QModelIndex AuthorGroupProxyModel::mapToSource(const QModelIndex &proxyIndex) const +{ + if (!proxyIndex.isValid()) + return QModelIndex(); + + AuthorGroupItem *item = static_cast(proxyIndex.internalPointer()); + + return item->index(); +} + +void AuthorGroupProxyModel::setSourceModel(QAbstractItemModel *model) +{ + if (sourceModel()) { + disconnect(sourceModel(), &QAbstractItemModel::layoutChanged, this, &AuthorGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::modelReset, this, &AuthorGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &AuthorGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, &AuthorGroupProxyModel::rebuildIndexes); + disconnect(sourceModel(), &QAbstractItemModel::dataChanged, this, &AuthorGroupProxyModel::sourceDataChanged); + } + + QAbstractProxyModel::setSourceModel(model); + + connect(sourceModel(), &QAbstractItemModel::layoutChanged, this, &AuthorGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::modelReset, this, &AuthorGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &AuthorGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, &AuthorGroupProxyModel::rebuildIndexes); + connect(sourceModel(), &QAbstractItemModel::dataChanged, this, &AuthorGroupProxyModel::sourceDataChanged); + + rebuildIndexes(); +} + +static bool isAuthorItem(const QModelIndex &index) +{ + if (!index.isValid()) { + return false; + } + + AuthorGroupItem *item = static_cast(index.internalPointer()); + return (item->type() == AuthorGroupItem::Author); +} + +QItemSelection AuthorGroupProxyModel::mapSelectionToSource(const QItemSelection &selection) const +{ + const QModelIndexList proxyIndexes = selection.indexes(); + QItemSelection sourceSelection; + for (const QModelIndex &proxyIndex : proxyIndexes) { + if (!isAuthorItem(proxyIndex)) { + sourceSelection << QItemSelectionRange(mapToSource(proxyIndex)); + } + } + + return sourceSelection; +} + +QItemSelection AuthorGroupProxyModel::mapSelectionFromSource(const QItemSelection &selection) const +{ + return QAbstractProxyModel::mapSelectionFromSource(selection); +} + +QVariant AuthorGroupProxyModel::data(const QModelIndex &proxyIndex, int role) const +{ + if (isAuthorItem(proxyIndex)) { + AuthorGroupItem *item = static_cast(proxyIndex.internalPointer()); + if (role == Qt::DisplayRole) + return item->author(); + else if (role == Qt::DecorationRole) + return QIcon::fromTheme(item->author().isEmpty() ? QStringLiteral("user-away") : QStringLiteral("user-identity")); + else + return QVariant(); + } else { + return QAbstractProxyModel::data(proxyIndex, role); + } +} + +QMap AuthorGroupProxyModel::itemData(const QModelIndex &index) const +{ + if (isAuthorItem(index)) { + return QMap(); + } else { + return QAbstractProxyModel::itemData(index); + } +} + +Qt::ItemFlags AuthorGroupProxyModel::flags(const QModelIndex &index) const +{ + if (isAuthorItem(index)) { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } else { + return QAbstractProxyModel::flags(index); + } +} + +void AuthorGroupProxyModel::groupByAuthor(bool value) +{ + if (d->mGroupByAuthor == value) + return; + + d->mGroupByAuthor = value; + + rebuildIndexes(); +} + +void AuthorGroupProxyModel::rebuildIndexes() +{ + beginResetModel(); + delete d->mRoot; + d->mRoot = new AuthorGroupItem(nullptr); + + if (d->mGroupByAuthor) { + QMap authorMap; + + for (int row = 0; row < sourceModel()->rowCount(); ++row) { + const QModelIndex idx = sourceModel()->index(row, 0); + const QString author = sourceModel()->data(idx, AnnotationModel::AuthorRole).toString(); + if (!author.isEmpty()) { + // We have the annotations as top-level, so introduce authors as new + // top-levels and append the annotations + AuthorGroupItem *authorItem = authorMap.value(author, nullptr); + if (!authorItem) { + authorItem = new AuthorGroupItem(d->mRoot, AuthorGroupItem::Author); + authorItem->setAuthor(author); + + // Add item to tree + d->mRoot->appendChild(authorItem); + + // Insert to lookup list + authorMap.insert(author, authorItem); + } + + AuthorGroupItem *item = new AuthorGroupItem(authorItem, AuthorGroupItem::Annotation, idx); + authorItem->appendChild(item); + } else { + // We have the pages as top-level, so we use them as top-level, append the + // authors for all annotations of the page, and then the annotations themself + AuthorGroupItem *pageItem = new AuthorGroupItem(d->mRoot, AuthorGroupItem::Page, idx); + d->mRoot->appendChild(pageItem); + + // First collect all authors... + QMap pageAuthorMap; + for (int subRow = 0; subRow < sourceModel()->rowCount(idx); ++subRow) { + const QModelIndex annIdx = sourceModel()->index(subRow, 0, idx); + const QString author = sourceModel()->data(annIdx, AnnotationModel::AuthorRole).toString(); + + AuthorGroupItem *authorItem = pageAuthorMap.value(author, nullptr); + if (!authorItem) { + authorItem = new AuthorGroupItem(pageItem, AuthorGroupItem::Author); + authorItem->setAuthor(author); + + // Add item to tree + pageItem->appendChild(authorItem); + + // Insert to lookup list + pageAuthorMap.insert(author, authorItem); + } + + AuthorGroupItem *item = new AuthorGroupItem(authorItem, AuthorGroupItem::Annotation, annIdx); + authorItem->appendChild(item); + } + } + } + } else { + for (int row = 0; row < sourceModel()->rowCount(); ++row) { + const QModelIndex idx = sourceModel()->index(row, 0); + const QString author = sourceModel()->data(idx, AnnotationModel::AuthorRole).toString(); + if (!author.isEmpty()) { + // We have the annotations as top-level items + AuthorGroupItem *item = new AuthorGroupItem(d->mRoot, AuthorGroupItem::Annotation, idx); + d->mRoot->appendChild(item); + } else { + // We have the pages as top-level items + AuthorGroupItem *pageItem = new AuthorGroupItem(d->mRoot, AuthorGroupItem::Page, idx); + d->mRoot->appendChild(pageItem); + + // Append all annotations as second-level + for (int subRow = 0; subRow < sourceModel()->rowCount(idx); ++subRow) { + const QModelIndex subIdx = sourceModel()->index(subRow, 0, idx); + AuthorGroupItem *item = new AuthorGroupItem(pageItem, AuthorGroupItem::Annotation, subIdx); + pageItem->appendChild(item); + } + } + } + } + + endResetModel(); +} + +void AuthorGroupProxyModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles); +} + +#include "moc_annotationproxymodels.cpp" diff --git a/part/annotationproxymodels.h b/part/annotationproxymodels.h new file mode 100644 index 0000000..5a763e8 --- /dev/null +++ b/part/annotationproxymodels.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2007 by Tobias Koenig * + * * + * 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 ANNOTATIONPROXYMODEL_H +#define ANNOTATIONPROXYMODEL_H + +#include +#include + +/** + * A proxy model, which filters out all pages except the + * current one. + */ +class PageFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + /** + * Creates a new page filter proxy model. + * + * @param parent The parent object. + */ + explicit PageFilterProxyModel(QObject *parent = nullptr); + + /** + * Reimplemented from QSortFilterProxy. + */ + bool filterAcceptsRow(int, const QModelIndex &) const override; + +public Q_SLOTS: + /** + * Sets whether the proxy model shall filter + * by current page. + */ + void groupByCurrentPage(bool value); + + /** + * Sets the current page. + */ + void setCurrentPage(int page); + +private: + bool mGroupByCurrentPage; + int mCurrentPage; +}; + +/** + * A proxy model which either groups the annotations by + * pages or shows them all as list. + */ +class PageGroupProxyModel : public QAbstractProxyModel +{ + Q_OBJECT + +public: + /** + * Creates a new page group proxy model. + * + * @param parent The parent object. + */ + explicit PageGroupProxyModel(QObject *parent = nullptr); + + int columnCount(const QModelIndex &parentIndex) const override; + int rowCount(const QModelIndex &parentIndex) const override; + + QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &idx) const override; + + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + + void setSourceModel(QAbstractItemModel *model) override; + +public Q_SLOTS: + /** + * Sets whether the proxy model shall group + * the annotations by page. + */ + void groupByPage(bool value); + +private Q_SLOTS: + void rebuildIndexes(); + void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); + +private: + bool mGroupByPage; + QList mIndexes; + QList>> mTreeIndexes; +}; + +/** + * A proxy model which groups the annotations by author. + */ +class AuthorGroupProxyModel : public QAbstractProxyModel +{ + Q_OBJECT + +public: + /** + * Creates a new author group proxy model. + * + * @param parent The parent object. + */ + explicit AuthorGroupProxyModel(QObject *parent = nullptr); + ~AuthorGroupProxyModel() override; + + int columnCount(const QModelIndex &parentIndex) const override; + int rowCount(const QModelIndex &parentIndex) const override; + + QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + + void setSourceModel(QAbstractItemModel *model) override; + + QItemSelection mapSelectionToSource(const QItemSelection &selection) const override; + QItemSelection mapSelectionFromSource(const QItemSelection &selection) const override; + QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override; + QMap itemData(const QModelIndex &index) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + +public Q_SLOTS: + /** + * Sets whether the proxy model shall group + * the annotations by author. + */ + void groupByAuthor(bool value); + +private Q_SLOTS: + void rebuildIndexes(); + void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/part/annotationtools.cpp b/part/annotationtools.cpp new file mode 100644 index 0000000..f66128c --- /dev/null +++ b/part/annotationtools.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "annotationtools.h" + +// qt / kde includes +#include +#include +#include +#include + +// local includes +#include "core/annotations.h" + +AnnotatorEngine::AnnotatorEngine(const QDomElement &engineElement) + : m_engineElement(engineElement) + , m_creationCompleted(false) + , m_item(nullptr) +{ + // parse common engine attributes + if (engineElement.hasAttribute(QStringLiteral("color"))) + m_engineColor = QColor(engineElement.attribute(QStringLiteral("color"))); + + // get the annotation element + QDomElement annElement = m_engineElement.firstChild().toElement(); + if (!annElement.isNull() && annElement.tagName() == QLatin1String("annotation")) + m_annotElement = annElement; +} + +void AnnotatorEngine::decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button) +{ + *eventType = AnnotatorEngine::Press; + if (mouseEvent->type() == QEvent::MouseMove) + *eventType = AnnotatorEngine::Move; + else if (mouseEvent->type() == QEvent::MouseButtonRelease) + *eventType = AnnotatorEngine::Release; + + *button = AnnotatorEngine::None; + const Qt::MouseButtons buttonState = (*eventType == AnnotatorEngine::Move) ? mouseEvent->buttons() : mouseEvent->button(); + if (buttonState == Qt::LeftButton) + *button = AnnotatorEngine::Left; + else if (buttonState == Qt::RightButton) + *button = AnnotatorEngine::Right; +} + +void AnnotatorEngine::decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button) +{ + switch (tabletEvent->type()) { + case QEvent::TabletPress: + // Tablet press event is equivalent to pressing the left mouse button + *button = AnnotatorEngine::Left; + *eventType = AnnotatorEngine::Press; + break; + case QEvent::TabletRelease: + // Tablet release event is equivalent to releasing the left mouse button + *button = AnnotatorEngine::Left; + *eventType = AnnotatorEngine::Release; + break; + case QEvent::TabletMove: + // Tablet events are only routed if the pen is down so + // this is equivalent to the left mouse button being pressed + *button = AnnotatorEngine::Left; + *eventType = AnnotatorEngine::Move; + break; + default: + Q_ASSERT(false); + break; + } +} + +AnnotatorEngine::~AnnotatorEngine() +{ +} + +QCursor AnnotatorEngine::cursor() const +{ + return Qt::CrossCursor; +} + +SmoothPath::SmoothPath(const QLinkedList &points, const QPen &pen, qreal opacity, QPainter::CompositionMode compositionMode) + : points(points) + , pen(pen) + , opacity(opacity) + , compositionMode(compositionMode) +{ +} + +/** SmoothPathEngine */ +SmoothPathEngine::SmoothPathEngine(const QDomElement &engineElement) + : AnnotatorEngine(engineElement) + , compositionMode(QPainter::CompositionMode_SourceOver) +{ + // parse engine specific attributes + if (engineElement.attribute(QStringLiteral("compositionMode"), QStringLiteral("sourceOver")) == QLatin1String("clear")) + compositionMode = QPainter::CompositionMode_Clear; +} + +QRect SmoothPathEngine::event(EventType type, Button button, Modifiers /*modifiers*/, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/) +{ + // only proceed if pressing left button + if (button != Left) + return QRect(); + + // start operation + if (type == Press && points.isEmpty()) { + lastPoint.x = nX; + lastPoint.y = nY; + totalRect.left = totalRect.right = lastPoint.x; + totalRect.top = totalRect.bottom = lastPoint.y; + points.append(lastPoint); + } + // add a point to the path + else if (type == Move && points.count() > 0) { + // double dist = hypot( nX - points.last().x, nY - points.last().y ); + // if ( dist > 0.0001 ) + //{ + // append mouse position (as normalized point) to the list + Okular::NormalizedPoint nextPoint = Okular::NormalizedPoint(nX, nY); + points.append(nextPoint); + // update total rect + double dX = 2.0 / (double)xScale; + double dY = 2.0 / (double)yScale; + totalRect.left = qMin(totalRect.left, nX - dX); + totalRect.top = qMin(totalRect.top, nY - dY); + totalRect.right = qMax(nX + dX, totalRect.right); + totalRect.bottom = qMax(nY + dY, totalRect.bottom); + // paint the difference to previous full rect + Okular::NormalizedRect incrementalRect; + incrementalRect.left = qMin(nextPoint.x, lastPoint.x) - dX; + incrementalRect.right = qMax(nextPoint.x, lastPoint.x) + dX; + incrementalRect.top = qMin(nextPoint.y, lastPoint.y) - dY; + incrementalRect.bottom = qMax(nextPoint.y, lastPoint.y) + dY; + lastPoint = nextPoint; + return incrementalRect.geometry((int)xScale, (int)yScale); + //} + } + // terminate process + else if (type == Release && points.count() > 0) { + if (points.count() < 2) + points.clear(); + else + m_creationCompleted = true; + return totalRect.geometry((int)xScale, (int)yScale); + } + return QRect(); +} + +void SmoothPathEngine::paint(QPainter *painter, double xScale, double yScale, const QRect & /*clipRect*/) +{ + const double penWidth = m_annotElement.attribute(QStringLiteral("width"), QStringLiteral("1")).toInt(); + const qreal opacity = m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble(); + + // use engine's color for painting + const SmoothPath path(points, QPen(m_engineColor, penWidth), opacity, compositionMode); + + // draw the path + path.paint(painter, xScale, yScale); +} + +void SmoothPath::paint(QPainter *painter, double xScale, double yScale) const +{ + // draw SmoothPaths with at least 2 points + if (points.count() > 1) { + painter->setCompositionMode(compositionMode); + painter->setPen(pen); + painter->setOpacity(opacity); + + QPainterPath path; + QLinkedList::const_iterator pIt = points.begin(), pEnd = points.end(); + path.moveTo(QPointF(pIt->x * xScale, pIt->y * yScale)); + ++pIt; + for (; pIt != pEnd; ++pIt) { + path.lineTo(QPointF(pIt->x * xScale, pIt->y * yScale)); + } + painter->drawPath(path); + } +} + +QList SmoothPathEngine::end() +{ + m_creationCompleted = false; + + // find out annotation's description node + if (m_annotElement.isNull()) + return QList(); + + // find out annotation's type + Okular::Annotation *ann = nullptr; + QString typeString = m_annotElement.attribute(QStringLiteral("type")); + + // create InkAnnotation from path + if (typeString == QLatin1String("Ink")) { + Okular::InkAnnotation *ia = new Okular::InkAnnotation(); + ann = ia; + if (m_annotElement.hasAttribute(QStringLiteral("width"))) + ann->style().setWidth(m_annotElement.attribute(QStringLiteral("width")).toDouble()); + // fill points + QList> list = ia->inkPaths(); + list.append(points); + ia->setInkPaths(list); + // set boundaries + ia->setBoundingRectangle(totalRect); + } + + // safety check + if (!ann) + return QList(); + + // set common attributes + ann->style().setColor(m_annotElement.hasAttribute(QStringLiteral("color")) ? m_annotElement.attribute(QStringLiteral("color")) : m_engineColor); + if (m_annotElement.hasAttribute(QStringLiteral("opacity"))) + ann->style().setOpacity(m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble()); + + // return annotation + return QList() << ann; +} + +SmoothPath SmoothPathEngine::endSmoothPath() +{ + m_creationCompleted = false; + + QColor color(m_annotElement.hasAttribute(QStringLiteral("color")) ? m_annotElement.attribute(QStringLiteral("color")) : m_engineColor); + + const int width = m_annotElement.attribute(QStringLiteral("width"), QStringLiteral("2")).toInt(); + const qreal opacity = m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble(); + + return SmoothPath(points, QPen(color, width), opacity, compositionMode); +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/annotationtools.h b/part/annotationtools.h new file mode 100644 index 0000000..54e0c3b --- /dev/null +++ b/part/annotationtools.h @@ -0,0 +1,126 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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_ANNOTATIONTOOLS_H_ +#define _OKULAR_ANNOTATIONTOOLS_H_ + +#include +#include +#include +#include +#include + +#include "core/area.h" + +class QMouseEvent; +class QTabletEvent; +class PageViewItem; +namespace Okular +{ +class Annotation; +class Page; +} + +/** + * @short Engine: filter events to distill Annotations. + */ +class AnnotatorEngine +{ +public: + explicit AnnotatorEngine(const QDomElement &engineElement); + virtual ~AnnotatorEngine(); + + AnnotatorEngine(const AnnotatorEngine &) = delete; + AnnotatorEngine &operator=(const AnnotatorEngine &) = delete; + + // enum definitions + enum EventType { Press, Move, Release }; + enum Button { None, Left, Right }; + /** To tell the annotator engine about modifier keys and other special wishes */ + struct Modifiers { + bool constrainRatioAndAngle; ///< Whether the engine shall snap to certain angles, if supported. + }; + + // perform operations + virtual QRect event(EventType type, Button button, Modifiers modifiers, double nX, double nY, double xScale, double yScale, const Okular::Page *page) = 0; + virtual void paint(QPainter *painter, double xScale, double yScale, const QRect &clipRect) = 0; + virtual QList end() = 0; + + // query creation state + // PageViewItem * editingItem() const { return m_lockedItem; } + bool creationCompleted() const + { + return m_creationCompleted; + } + + void setItem(PageViewItem *item) + { + m_item = item; + } + + static void decodeEvent(const QMouseEvent *mouseEvent, EventType *eventType, Button *button); + static void decodeEvent(const QTabletEvent *tabletEvent, EventType *eventType, Button *button); + + virtual QCursor cursor() const; + +protected: + PageViewItem *item() + { + return m_item; + } + + // common engine attributes (the element includes annotation desc) + QDomElement m_engineElement; + QDomElement m_annotElement; + QColor m_engineColor; + // other vars (remove this!) + bool m_creationCompleted; + +private: + PageViewItem *m_item; +}; + +class SmoothPath +{ +public: + SmoothPath(const QLinkedList &points, const QPen &pen, qreal opacity = 1.0, QPainter::CompositionMode compositionMode = QPainter::CompositionMode_SourceOver); + void paint(QPainter *painter, double xScale, double yScale) const; + +private: + const QLinkedList points; + const QPen pen; + const qreal opacity; + const QPainter::CompositionMode compositionMode; +}; + +/** @short SmoothPathEngine */ +class SmoothPathEngine : public AnnotatorEngine +{ +public: + explicit SmoothPathEngine(const QDomElement &engineElement); + + QRect event(EventType type, Button button, Modifiers modifiers, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/) override; + + void paint(QPainter *painter, double xScale, double yScale, const QRect & /*clipRect*/) override; + + // These are two alternative ways to get the resulting path. Don't call them both! + QList end() override; + SmoothPath endSmoothPath(); + +private: + // data + QLinkedList points; + Okular::NormalizedRect totalRect; + Okular::NormalizedPoint lastPoint; + QPainter::CompositionMode compositionMode; +}; + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/annotationwidgets.cpp b/part/annotationwidgets.cpp new file mode 100644 index 0000000..4ebb21a --- /dev/null +++ b/part/annotationwidgets.cpp @@ -0,0 +1,855 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "annotationwidgets.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/document.h" +#include "guiutils.h" +#include "pagepainter.h" + +#define FILEATTACH_ICONSIZE 48 + +PixmapPreviewSelector::PixmapPreviewSelector(QWidget *parent, PreviewPosition position) + : QWidget(parent) + , m_previewPosition(position) +{ + QVBoxLayout *mainlay = new QVBoxLayout(this); + mainlay->setContentsMargins(0, 0, 0, 0); + QHBoxLayout *toplay = new QHBoxLayout(this); + toplay->setContentsMargins(0, 0, 0, 0); + mainlay->addLayout(toplay); + m_comboItems = new KComboBox(this); + toplay->addWidget(m_comboItems); + m_stampPushButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-open")), QString(), this); + m_stampPushButton->setVisible(false); + m_stampPushButton->setToolTip(i18nc("@info:tooltip", "Select a custom stamp symbol from file")); + toplay->addWidget(m_stampPushButton); + m_iconLabel = new QLabel(this); + switch (m_previewPosition) { + case Side: + toplay->addWidget(m_iconLabel); + break; + case Below: + mainlay->addWidget(m_iconLabel); + mainlay->setAlignment(m_iconLabel, Qt::AlignHCenter); + break; + } + m_iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_iconLabel->setAlignment(Qt::AlignCenter); + m_iconLabel->setFrameStyle(QFrame::StyledPanel); + setPreviewSize(32); + + setFocusPolicy(Qt::TabFocus); + setFocusProxy(m_comboItems); + + connect(m_comboItems, QOverload::of(&QComboBox::currentIndexChanged), this, &PixmapPreviewSelector::iconComboChanged); + connect(m_comboItems, &QComboBox::editTextChanged, this, &PixmapPreviewSelector::iconComboChanged); + connect(m_stampPushButton, &QPushButton::clicked, this, &PixmapPreviewSelector::selectCustomStamp); +} + +PixmapPreviewSelector::~PixmapPreviewSelector() +{ +} + +void PixmapPreviewSelector::setIcon(const QString &icon) +{ + int id = m_comboItems->findData(QVariant(icon), Qt::UserRole, Qt::MatchFixedString); + if (id == -1) + id = m_comboItems->findText(icon, Qt::MatchFixedString); + if (id > -1) { + m_comboItems->setCurrentIndex(id); + } else if (m_comboItems->isEditable()) { + m_comboItems->addItem(icon, QVariant(icon)); + m_comboItems->setCurrentIndex(m_comboItems->findText(icon, Qt::MatchFixedString)); + } +} + +QString PixmapPreviewSelector::icon() const +{ + return m_icon; +} + +void PixmapPreviewSelector::addItem(const QString &item, const QString &id) +{ + m_comboItems->addItem(item, QVariant(id)); + setIcon(m_icon); +} + +void PixmapPreviewSelector::setPreviewSize(int size) +{ + m_previewSize = size; + switch (m_previewPosition) { + case Side: + m_iconLabel->setFixedSize(m_previewSize + 8, m_previewSize + 8); + break; + case Below: + m_iconLabel->setFixedSize(3 * m_previewSize + 8, m_previewSize + 8); + break; + } + iconComboChanged(m_icon); +} + +int PixmapPreviewSelector::previewSize() const +{ + return m_previewSize; +} + +void PixmapPreviewSelector::setEditable(bool editable) +{ + m_comboItems->setEditable(editable); + m_stampPushButton->setVisible(editable); +} + +void PixmapPreviewSelector::iconComboChanged(const QString &icon) +{ + int id = m_comboItems->findText(icon, Qt::MatchFixedString); + if (id >= 0) { + m_icon = m_comboItems->itemData(id).toString(); + } else { + m_icon = icon; + } + + QPixmap pixmap = GuiUtils::loadStamp(m_icon, m_previewSize); + const QRect cr = m_iconLabel->contentsRect(); + if (pixmap.width() > cr.width() || pixmap.height() > cr.height()) + pixmap = pixmap.scaled(cr.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + m_iconLabel->setPixmap(pixmap); + + emit iconChanged(m_icon); +} + +void PixmapPreviewSelector::selectCustomStamp() +{ + const QString customStampFile = QFileDialog::getOpenFileName(this, i18nc("@title:window file chooser", "Select custom stamp symbol"), QString(), i18n("*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)")); + if (!customStampFile.isEmpty()) { + QPixmap pixmap = GuiUtils::loadStamp(customStampFile, m_previewSize); + if (pixmap.isNull()) { + KMessageBox::sorry(this, xi18nc("@info", "Could not load the file %1", customStampFile), i18nc("@title:window", "Invalid file")); + } else { + m_comboItems->setEditText(customStampFile); + } + } +} + +AnnotationWidget *AnnotationWidgetFactory::widgetFor(Okular::Annotation *ann) +{ + switch (ann->subType()) { + case Okular::Annotation::AStamp: + return new StampAnnotationWidget(ann); + break; + case Okular::Annotation::AText: + return new TextAnnotationWidget(ann); + break; + case Okular::Annotation::ALine: + return new LineAnnotationWidget(ann); + break; + case Okular::Annotation::AHighlight: + return new HighlightAnnotationWidget(ann); + break; + case Okular::Annotation::AInk: + return new InkAnnotationWidget(ann); + break; + case Okular::Annotation::AGeom: + return new GeomAnnotationWidget(ann); + break; + case Okular::Annotation::AFileAttachment: + return new FileAttachmentAnnotationWidget(ann); + break; + case Okular::Annotation::ACaret: + return new CaretAnnotationWidget(ann); + break; + // shut up gcc + default:; + } + // cases not covered yet: return a generic widget + return new AnnotationWidget(ann); +} + +AnnotationWidget::AnnotationWidget(Okular::Annotation *ann) + : m_typeEditable(true) + , m_ann(ann) +{ +} + +AnnotationWidget::~AnnotationWidget() +{ +} + +Okular::Annotation::SubType AnnotationWidget::annotationType() const +{ + return m_ann->subType(); +} + +QWidget *AnnotationWidget::appearanceWidget() +{ + if (m_appearanceWidget) + return m_appearanceWidget; + + m_appearanceWidget = createAppearanceWidget(); + return m_appearanceWidget; +} + +QWidget *AnnotationWidget::extraWidget() +{ + if (m_extraWidget) + return m_extraWidget; + + m_extraWidget = createExtraWidget(); + return m_extraWidget; +} + +void AnnotationWidget::applyChanges() +{ + if (m_colorBn) + m_ann->style().setColor(m_colorBn->color()); + if (m_opacity) + m_ann->style().setOpacity((double)m_opacity->value() / 100.0); +} + +QWidget *AnnotationWidget::createAppearanceWidget() +{ + QWidget *widget = new QWidget(); + QFormLayout *formlayout = new QFormLayout(widget); + formlayout->setLabelAlignment(Qt::AlignRight); + formlayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + + createStyleWidget(formlayout); + + return widget; +} + +void AnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + Q_UNUSED(formlayout); +} + +void AnnotationWidget::addColorButton(QWidget *widget, QFormLayout *formlayout) +{ + m_colorBn = new KColorButton(widget); + m_colorBn->setColor(m_ann->style().color()); + formlayout->addRow(i18n("&Color:"), m_colorBn); + connect(m_colorBn, &KColorButton::changed, this, &AnnotationWidget::dataChanged); +} + +void AnnotationWidget::addOpacitySpinBox(QWidget *widget, QFormLayout *formlayout) +{ + m_opacity = new QSpinBox(widget); + m_opacity->setRange(0, 100); + m_opacity->setValue((int)(m_ann->style().opacity() * 100)); + m_opacity->setSuffix(i18nc("Suffix for the opacity level, eg '80%'", "%")); + formlayout->addRow(i18n("&Opacity:"), m_opacity); + connect(m_opacity, QOverload::of(&QSpinBox::valueChanged), this, &AnnotationWidget::dataChanged); +} + +void AnnotationWidget::addVerticalSpacer(QFormLayout *formlayout) +{ + formlayout->addItem(new QSpacerItem(0, 5, QSizePolicy::Fixed, QSizePolicy::Fixed)); +} + +QWidget *AnnotationWidget::createExtraWidget() +{ + return nullptr; +} + +TextAnnotationWidget::TextAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) +{ + m_textAnn = static_cast(ann); +} + +void TextAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + if (m_textAnn->textType() == Okular::TextAnnotation::Linked) { + createPopupNoteStyleUi(widget, formlayout); + } else if (m_textAnn->textType() == Okular::TextAnnotation::InPlace) { + if (isTypewriter()) + createTypewriterStyleUi(widget, formlayout); + else + createInlineNoteStyleUi(widget, formlayout); + } +} + +void TextAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + if (m_textAnn->textType() == Okular::TextAnnotation::Linked) { + Q_ASSERT(m_pixmapSelector); + m_textAnn->setTextIcon(m_pixmapSelector->icon()); + } else if (m_textAnn->textType() == Okular::TextAnnotation::InPlace) { + Q_ASSERT(m_fontReq); + m_textAnn->setTextFont(m_fontReq->font()); + if (!isTypewriter()) { + Q_ASSERT(m_textAlign && m_spinWidth); + m_textAnn->setInplaceAlignment(m_textAlign->currentIndex()); + m_textAnn->style().setWidth(m_spinWidth->value()); + } else { + Q_ASSERT(m_textColorBn); + m_textAnn->setTextColor(m_textColorBn->color()); + } + } +} + +void AnnotationWidget::setAnnotTypeEditable(bool editable) +{ + m_typeEditable = editable; +} + +void TextAnnotationWidget::createPopupNoteStyleUi(QWidget *widget, QFormLayout *formlayout) +{ + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + addVerticalSpacer(formlayout); + addPixmapSelector(widget, formlayout); +} + +void TextAnnotationWidget::createInlineNoteStyleUi(QWidget *widget, QFormLayout *formlayout) +{ + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + addVerticalSpacer(formlayout); + addFontRequester(widget, formlayout); + addTextAlignComboBox(widget, formlayout); + addVerticalSpacer(formlayout); + addWidthSpinBox(widget, formlayout); +} + +void TextAnnotationWidget::createTypewriterStyleUi(QWidget *widget, QFormLayout *formlayout) +{ + addFontRequester(widget, formlayout); + addTextColorButton(widget, formlayout); +} + +void TextAnnotationWidget::addPixmapSelector(QWidget *widget, QFormLayout *formlayout) +{ + m_pixmapSelector = new PixmapPreviewSelector(widget); + formlayout->addRow(i18n("Icon:"), m_pixmapSelector); + m_pixmapSelector->addItem(i18n("Comment"), QStringLiteral("Comment")); + m_pixmapSelector->addItem(i18n("Help"), QStringLiteral("Help")); + m_pixmapSelector->addItem(i18n("Insert"), QStringLiteral("Insert")); + m_pixmapSelector->addItem(i18n("Key"), QStringLiteral("Key")); + m_pixmapSelector->addItem(i18n("New paragraph"), QStringLiteral("NewParagraph")); + m_pixmapSelector->addItem(i18n("Note"), QStringLiteral("Note")); + m_pixmapSelector->addItem(i18n("Paragraph"), QStringLiteral("Paragraph")); + m_pixmapSelector->setIcon(m_textAnn->textIcon()); + connect(m_pixmapSelector, &PixmapPreviewSelector::iconChanged, this, &AnnotationWidget::dataChanged); +} + +void TextAnnotationWidget::addFontRequester(QWidget *widget, QFormLayout *formlayout) +{ + m_fontReq = new KFontRequester(widget); + formlayout->addRow(i18n("Font:"), m_fontReq); + m_fontReq->setFont(m_textAnn->textFont()); + connect(m_fontReq, &KFontRequester::fontSelected, this, &AnnotationWidget::dataChanged); +} + +void TextAnnotationWidget::addTextColorButton(QWidget *widget, QFormLayout *formlayout) +{ + m_textColorBn = new KColorButton(widget); + m_textColorBn->setColor(m_textAnn->textColor()); + formlayout->addRow(i18n("Text &color:"), m_textColorBn); + connect(m_textColorBn, &KColorButton::changed, this, &AnnotationWidget::dataChanged); +} + +void TextAnnotationWidget::addTextAlignComboBox(QWidget *widget, QFormLayout *formlayout) +{ + m_textAlign = new KComboBox(widget); + formlayout->addRow(i18n("&Align:"), m_textAlign); + m_textAlign->addItem(i18n("Left")); + m_textAlign->addItem(i18n("Center")); + m_textAlign->addItem(i18n("Right")); + m_textAlign->setCurrentIndex(m_textAnn->inplaceAlignment()); + connect(m_textAlign, QOverload::of(&KComboBox::currentIndexChanged), this, &AnnotationWidget::dataChanged); +} + +void TextAnnotationWidget::addWidthSpinBox(QWidget *widget, QFormLayout *formlayout) +{ + m_spinWidth = new QDoubleSpinBox(widget); + formlayout->addRow(i18n("Border &width:"), m_spinWidth); + m_spinWidth->setRange(0, 100); + m_spinWidth->setValue(m_textAnn->style().width()); + m_spinWidth->setSingleStep(0.1); + connect(m_spinWidth, QOverload::of(&QDoubleSpinBox::valueChanged), this, &AnnotationWidget::dataChanged); +} + +const QList> StampAnnotationWidget::defaultStamps = {{i18n("Approved"), QStringLiteral("Approved")}, + {i18n("As Is"), QStringLiteral("AsIs")}, + {i18n("Confidential"), QStringLiteral("Confidential")}, + {i18n("Departmental"), QStringLiteral("Departmental")}, + {i18n("Draft"), QStringLiteral("Draft")}, + {i18n("Experimental"), QStringLiteral("Experimental")}, + {i18n("Final"), QStringLiteral("Expired")}, + {i18n("For Comment"), QStringLiteral("ForComment")}, + {i18n("For Public Release"), QStringLiteral("ForPublicRelease")}, + {i18n("Not Approved"), QStringLiteral("NotApproved")}, + {i18n("Not For Public Release"), QStringLiteral("NotForPublicRelease")}, + {i18n("Sold"), QStringLiteral("Sold")}, + {i18n("Top Secret"), QStringLiteral("TopSecret")}, + {i18n("Bookmark"), QStringLiteral("bookmark-new")}, + {i18n("Information"), QStringLiteral("help-about")}, + {i18n("KDE"), QStringLiteral("kde")}, + {i18n("Okular"), QStringLiteral("okular")}}; + +StampAnnotationWidget::StampAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) + , m_pixmapSelector(nullptr) +{ + m_stampAnn = static_cast(ann); +} + +void StampAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + KMessageWidget *brokenStampSupportWarning = new KMessageWidget(widget); + brokenStampSupportWarning->setText(xi18nc("@info", + "experimental feature." + "Stamps inserted in PDF documents are not visible in PDF readers other than Okular.")); + brokenStampSupportWarning->setMessageType(KMessageWidget::Warning); + brokenStampSupportWarning->setWordWrap(true); + brokenStampSupportWarning->setCloseButtonVisible(false); + formlayout->insertRow(0, brokenStampSupportWarning); + + addOpacitySpinBox(widget, formlayout); + addVerticalSpacer(formlayout); + + m_pixmapSelector = new PixmapPreviewSelector(widget, PixmapPreviewSelector::Below); + formlayout->addRow(i18n("Stamp symbol:"), m_pixmapSelector); + m_pixmapSelector->setEditable(true); + + QPair pair; + foreach (pair, defaultStamps) { + m_pixmapSelector->addItem(pair.first, pair.second); + } + + m_pixmapSelector->setIcon(m_stampAnn->stampIconName()); + m_pixmapSelector->setPreviewSize(64); + + connect(m_pixmapSelector, &PixmapPreviewSelector::iconChanged, this, &AnnotationWidget::dataChanged); +} + +void StampAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_stampAnn->setStampIconName(m_pixmapSelector->icon()); +} + +LineAnnotationWidget::LineAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) +{ + m_lineAnn = static_cast(ann); + if (m_lineAnn->linePoints().count() == 2) + m_lineType = 0; // line + else if (m_lineAnn->lineClosed()) + m_lineType = 1; // polygon + else + m_lineType = 2; // polyline +} + +void LineAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + + m_spinSize = new QDoubleSpinBox(widget); + m_spinSize->setRange(1, 100); + m_spinSize->setValue(m_lineAnn->style().width()); + + connect(m_spinSize, QOverload::of(&QDoubleSpinBox::valueChanged), this, &LineAnnotationWidget::dataChanged); + + // Straight line + if (m_lineType == 0) { + addVerticalSpacer(formlayout); + formlayout->addRow(i18n("&Width:"), m_spinSize); + + // Line Term Styles + addVerticalSpacer(formlayout); + m_startStyleCombo = new QComboBox(widget); + formlayout->addRow(i18n("Line start:"), m_startStyleCombo); + m_endStyleCombo = new QComboBox(widget); + formlayout->addRow(i18n("Line end:"), m_endStyleCombo); + // FIXME: Where does the tooltip goes?? + + const QList> termStyles {{Okular::LineAnnotation::Square, i18n("Square")}, + {Okular::LineAnnotation::Circle, i18n("Circle")}, + {Okular::LineAnnotation::Diamond, i18n("Diamond")}, + {Okular::LineAnnotation::OpenArrow, i18n("Open Arrow")}, + {Okular::LineAnnotation::ClosedArrow, i18n("Closed Arrow")}, + {Okular::LineAnnotation::None, i18n("None")}, + {Okular::LineAnnotation::Butt, i18n("Butt")}, + {Okular::LineAnnotation::ROpenArrow, i18n("Right Open Arrow")}, + {Okular::LineAnnotation::RClosedArrow, i18n("Right Closed Arrow")}, + {Okular::LineAnnotation::Slash, i18n("Slash")}}; + for (const auto &item : termStyles) { + const QIcon icon = endStyleIcon(item.first, QGuiApplication::palette().color(QPalette::WindowText)); + m_startStyleCombo->addItem(icon, item.second); + m_endStyleCombo->addItem(icon, item.second); + } + + m_startStyleCombo->setCurrentIndex(m_lineAnn->lineStartStyle()); + m_endStyleCombo->setCurrentIndex(m_lineAnn->lineEndStyle()); + + // Leaders lengths + addVerticalSpacer(formlayout); + m_spinLL = new QDoubleSpinBox(widget); + formlayout->addRow(i18n("Leader line length:"), m_spinLL); + m_spinLLE = new QDoubleSpinBox(widget); + formlayout->addRow(i18n("Leader line extensions length:"), m_spinLLE); + + m_spinLL->setRange(-500, 500); + m_spinLL->setValue(m_lineAnn->lineLeadingForwardPoint()); + m_spinLLE->setRange(0, 500); + m_spinLLE->setValue(m_lineAnn->lineLeadingBackwardPoint()); + + connect(m_startStyleCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &LineAnnotationWidget::dataChanged); + connect(m_endStyleCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &LineAnnotationWidget::dataChanged); + connect(m_spinLL, QOverload::of(&QDoubleSpinBox::valueChanged), this, &LineAnnotationWidget::dataChanged); + connect(m_spinLLE, QOverload::of(&QDoubleSpinBox::valueChanged), this, &LineAnnotationWidget::dataChanged); + } else if (m_lineType == 1) // Polygon + { + QHBoxLayout *colorlay = new QHBoxLayout(); + m_useColor = new QCheckBox(i18n("Enabled"), widget); + colorlay->addWidget(m_useColor); + m_innerColor = new KColorButton(widget); + colorlay->addWidget(m_innerColor); + formlayout->addRow(i18n("Shape fill:"), colorlay); + + m_innerColor->setColor(m_lineAnn->lineInnerColor()); + if (m_lineAnn->lineInnerColor().isValid()) { + m_useColor->setChecked(true); + } else { + m_innerColor->setEnabled(false); + } + + addVerticalSpacer(formlayout); + formlayout->addRow(i18n("&Width:"), m_spinSize); + + connect(m_innerColor, &KColorButton::changed, this, &AnnotationWidget::dataChanged); + connect(m_useColor, &QAbstractButton::toggled, this, &AnnotationWidget::dataChanged); + connect(m_useColor, &QCheckBox::toggled, m_innerColor, &KColorButton::setEnabled); + } +} + +void LineAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + if (m_lineType == 0) { + Q_ASSERT(m_spinLL && m_spinLLE && m_startStyleCombo && m_endStyleCombo); + m_lineAnn->setLineLeadingForwardPoint(m_spinLL->value()); + m_lineAnn->setLineLeadingBackwardPoint(m_spinLLE->value()); + m_lineAnn->setLineStartStyle((Okular::LineAnnotation::TermStyle)m_startStyleCombo->currentIndex()); + m_lineAnn->setLineEndStyle((Okular::LineAnnotation::TermStyle)m_endStyleCombo->currentIndex()); + } else if (m_lineType == 1) { + Q_ASSERT(m_useColor && m_innerColor); + if (!m_useColor->isChecked()) { + m_lineAnn->setLineInnerColor(QColor()); + } else { + m_lineAnn->setLineInnerColor(m_innerColor->color()); + } + } + Q_ASSERT(m_spinSize); + m_lineAnn->style().setWidth(m_spinSize->value()); +} + +QIcon LineAnnotationWidget::endStyleIcon(Okular::LineAnnotation::TermStyle endStyle, const QColor &lineColor) +{ + const int iconSize {48}; + QImage image {iconSize, iconSize, QImage::Format_ARGB32}; + image.fill(qRgba(0, 0, 0, 0)); + Okular::LineAnnotation prototype; + prototype.setLinePoints({{0, 0.5}, {0.65, 0.5}}); + prototype.setLineStartStyle(Okular::LineAnnotation::TermStyle::None); + prototype.setLineEndStyle(endStyle); + prototype.style().setWidth(4); + prototype.style().setColor(lineColor); + prototype.style().setLineStyle(Okular::Annotation::LineStyle::Solid); + prototype.setBoundingRectangle({0, 0, 1, 1}); + LineAnnotPainter linepainter {&prototype, QSize {iconSize, iconSize}, 1, QTransform()}; + linepainter.draw(image); + return QIcon(QPixmap::fromImage(image)); +} + +InkAnnotationWidget::InkAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) +{ + m_inkAnn = static_cast(ann); +} + +void InkAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + + addVerticalSpacer(formlayout); + + m_spinSize = new QDoubleSpinBox(widget); + formlayout->addRow(i18n("&Width:"), m_spinSize); + + m_spinSize->setRange(1, 100); + m_spinSize->setValue(m_inkAnn->style().width()); + + connect(m_spinSize, QOverload::of(&QDoubleSpinBox::valueChanged), this, &AnnotationWidget::dataChanged); +} + +void InkAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_inkAnn->style().setWidth(m_spinSize->value()); +} + +HighlightAnnotationWidget::HighlightAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) +{ + m_hlAnn = static_cast(ann); +} + +void HighlightAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + m_typeCombo = new KComboBox(widget); + m_typeCombo->setVisible(m_typeEditable); + if (m_typeEditable) { + formlayout->addRow(i18n("Type:"), m_typeCombo); + } + m_typeCombo->addItem(i18n("Highlight")); + m_typeCombo->addItem(i18n("Squiggle")); + m_typeCombo->addItem(i18n("Underline")); + m_typeCombo->addItem(i18n("Strike out")); + m_typeCombo->setCurrentIndex(m_hlAnn->highlightType()); + + addVerticalSpacer(formlayout); + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + + connect(m_typeCombo, QOverload::of(&KComboBox::currentIndexChanged), this, &AnnotationWidget::dataChanged); +} + +void HighlightAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_hlAnn->setHighlightType((Okular::HighlightAnnotation::HighlightType)m_typeCombo->currentIndex()); +} + +GeomAnnotationWidget::GeomAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) +{ + m_geomAnn = static_cast(ann); +} + +void GeomAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + m_typeCombo = new KComboBox(widget); + m_typeCombo->setVisible(m_typeEditable); + if (m_typeEditable) { + formlayout->addRow(i18n("Type:"), m_typeCombo); + } + addVerticalSpacer(formlayout); + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + QHBoxLayout *colorlay = new QHBoxLayout(); + m_useColor = new QCheckBox(i18n("Enabled"), widget); + colorlay->addWidget(m_useColor); + m_innerColor = new KColorButton(widget); + colorlay->addWidget(m_innerColor); + formlayout->addRow(i18n("Shape fill:"), colorlay); + addVerticalSpacer(formlayout); + m_spinSize = new QDoubleSpinBox(widget); + formlayout->addRow(i18n("&Width:"), m_spinSize); + + m_typeCombo->addItem(i18n("Rectangle")); + m_typeCombo->addItem(i18n("Ellipse")); + m_typeCombo->setCurrentIndex(m_geomAnn->geometricalType()); + m_innerColor->setColor(m_geomAnn->geometricalInnerColor()); + if (m_geomAnn->geometricalInnerColor().isValid()) { + m_useColor->setChecked(true); + } else { + m_innerColor->setEnabled(false); + } + m_spinSize->setRange(0, 100); + m_spinSize->setValue(m_geomAnn->style().width()); + + connect(m_typeCombo, QOverload::of(&KComboBox::currentIndexChanged), this, &AnnotationWidget::dataChanged); + connect(m_innerColor, &KColorButton::changed, this, &AnnotationWidget::dataChanged); + connect(m_useColor, &QAbstractButton::toggled, this, &AnnotationWidget::dataChanged); + connect(m_useColor, &QCheckBox::toggled, m_innerColor, &KColorButton::setEnabled); + connect(m_spinSize, QOverload::of(&QDoubleSpinBox::valueChanged), this, &AnnotationWidget::dataChanged); +} + +void GeomAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_geomAnn->setGeometricalType((Okular::GeomAnnotation::GeomType)m_typeCombo->currentIndex()); + if (!m_useColor->isChecked()) { + m_geomAnn->setGeometricalInnerColor(QColor()); + } else { + m_geomAnn->setGeometricalInnerColor(m_innerColor->color()); + } + m_geomAnn->style().setWidth(m_spinSize->value()); +} + +FileAttachmentAnnotationWidget::FileAttachmentAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) + , m_pixmapSelector(nullptr) +{ + m_attachAnn = static_cast(ann); +} + +void FileAttachmentAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + addOpacitySpinBox(widget, formlayout); + + m_pixmapSelector = new PixmapPreviewSelector(widget); + formlayout->addRow(i18n("File attachment symbol:"), m_pixmapSelector); + m_pixmapSelector->setEditable(true); + + m_pixmapSelector->addItem(i18nc("Symbol for file attachment annotations", "Graph"), QStringLiteral("graph")); + m_pixmapSelector->addItem(i18nc("Symbol for file attachment annotations", "Push Pin"), QStringLiteral("pushpin")); + m_pixmapSelector->addItem(i18nc("Symbol for file attachment annotations", "Paperclip"), QStringLiteral("paperclip")); + m_pixmapSelector->addItem(i18nc("Symbol for file attachment annotations", "Tag"), QStringLiteral("tag")); + m_pixmapSelector->setIcon(m_attachAnn->fileIconName()); + + connect(m_pixmapSelector, &PixmapPreviewSelector::iconChanged, this, &AnnotationWidget::dataChanged); +} + +QWidget *FileAttachmentAnnotationWidget::createExtraWidget() +{ + QWidget *widget = new QWidget(); + widget->setWindowTitle(i18nc("'File' as normal file, that can be opened, saved, etc..", "File")); + + Okular::EmbeddedFile *ef = m_attachAnn->embeddedFile(); + const int size = ef->size(); + const QString sizeString = size <= 0 ? i18nc("Not available size", "N/A") : KFormat().formatByteSize(size); + const QString descString = ef->description().isEmpty() ? i18n("No description available.") : ef->description(); + + QHBoxLayout *mainLay = new QHBoxLayout(widget); + QFormLayout *lay = new QFormLayout(); + mainLay->addLayout(lay); + + QLabel *tmplabel = new QLabel(ef->name(), widget); + tmplabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + lay->addRow(i18n("Name:"), tmplabel); + + tmplabel = new QLabel(sizeString, widget); + tmplabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + lay->addRow(i18n("&Width:"), tmplabel); + + tmplabel = new QLabel(widget); + tmplabel->setTextFormat(Qt::PlainText); + tmplabel->setWordWrap(true); + tmplabel->setText(descString); + tmplabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + lay->addRow(i18n("Description:"), tmplabel); + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(ef->name(), QMimeDatabase::MatchExtension); + if (mime.isValid()) { + tmplabel = new QLabel(widget); + tmplabel->setPixmap(QIcon::fromTheme(mime.iconName()).pixmap(FILEATTACH_ICONSIZE, FILEATTACH_ICONSIZE)); + tmplabel->setFixedSize(FILEATTACH_ICONSIZE, FILEATTACH_ICONSIZE); + QVBoxLayout *tmpLayout = new QVBoxLayout(widget); + tmpLayout->setAlignment(Qt::AlignTop); + mainLay->addLayout(tmpLayout); + tmpLayout->addWidget(tmplabel); + } + + return widget; +} + +void FileAttachmentAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_attachAnn->setFileIconName(m_pixmapSelector->icon()); +} + +static QString caretSymbolToIcon(Okular::CaretAnnotation::CaretSymbol symbol) +{ + switch (symbol) { + case Okular::CaretAnnotation::None: + return QStringLiteral("caret-none"); + case Okular::CaretAnnotation::P: + return QStringLiteral("caret-p"); + } + return QString(); +} + +static Okular::CaretAnnotation::CaretSymbol caretSymbolFromIcon(const QString &icon) +{ + if (icon == QLatin1String("caret-none")) + return Okular::CaretAnnotation::None; + else if (icon == QLatin1String("caret-p")) + return Okular::CaretAnnotation::P; + return Okular::CaretAnnotation::None; +} + +CaretAnnotationWidget::CaretAnnotationWidget(Okular::Annotation *ann) + : AnnotationWidget(ann) + , m_pixmapSelector(nullptr) +{ + m_caretAnn = static_cast(ann); +} + +void CaretAnnotationWidget::createStyleWidget(QFormLayout *formlayout) +{ + QWidget *widget = qobject_cast(formlayout->parent()); + + addColorButton(widget, formlayout); + addOpacitySpinBox(widget, formlayout); + + m_pixmapSelector = new PixmapPreviewSelector(widget); + formlayout->addRow(i18n("Caret symbol:"), m_pixmapSelector); + + m_pixmapSelector->addItem(i18nc("Symbol for caret annotations", "None"), QStringLiteral("caret-none")); + m_pixmapSelector->addItem(i18nc("Symbol for caret annotations", "P"), QStringLiteral("caret-p")); + m_pixmapSelector->setIcon(caretSymbolToIcon(m_caretAnn->caretSymbol())); + + connect(m_pixmapSelector, &PixmapPreviewSelector::iconChanged, this, &AnnotationWidget::dataChanged); +} + +void CaretAnnotationWidget::applyChanges() +{ + AnnotationWidget::applyChanges(); + m_caretAnn->setCaretSymbol(caretSymbolFromIcon(m_pixmapSelector->icon())); +} + +#include "moc_annotationwidgets.cpp" diff --git a/part/annotationwidgets.h b/part/annotationwidgets.h new file mode 100644 index 0000000..0fc3f25 --- /dev/null +++ b/part/annotationwidgets.h @@ -0,0 +1,286 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _ANNOTATIONWIDGETS_H_ +#define _ANNOTATIONWIDGETS_H_ + +#include + +#include "core/annotations.h" + +class QCheckBox; +class QComboBox; +class QDoubleSpinBox; +class QFormLayout; +class QLabel; +class QPushButton; +class QWidget; +class KColorButton; +class QSpinBox; +class KFontRequester; +class AnnotationWidget; + +class PixmapPreviewSelector : public QWidget +{ + Q_OBJECT + +public: + enum PreviewPosition { Side, Below }; + + explicit PixmapPreviewSelector(QWidget *parent = nullptr, PreviewPosition position = Side); + ~PixmapPreviewSelector() override; + + void setIcon(const QString &icon); + QString icon() const; + + void addItem(const QString &item, const QString &id); + + void setPreviewSize(int size); + int previewSize() const; + + void setEditable(bool editable); + +Q_SIGNALS: + void iconChanged(const QString &); + +private Q_SLOTS: + void iconComboChanged(const QString &icon); + void selectCustomStamp(); + +private: + QString m_icon; + QPushButton *m_stampPushButton; + QLabel *m_iconLabel; + QComboBox *m_comboItems; + int m_previewSize; + PreviewPosition m_previewPosition; +}; + +/** + * A factory to create AnnotationWidget's. + */ +class AnnotationWidgetFactory +{ +public: + static AnnotationWidget *widgetFor(Okular::Annotation *ann); +}; + +class AnnotationWidget : public QObject +{ + Q_OBJECT + +public: + explicit AnnotationWidget(Okular::Annotation *ann); + ~AnnotationWidget() override; + + virtual Okular::Annotation::SubType annotationType() const; + + QWidget *appearanceWidget(); + QWidget *extraWidget(); + + virtual void applyChanges(); + + void setAnnotTypeEditable(bool); + +Q_SIGNALS: + void dataChanged(); + +protected: + QWidget *createAppearanceWidget(); + + virtual void createStyleWidget(QFormLayout *formLayout); + virtual QWidget *createExtraWidget(); + + void addColorButton(QWidget *widget, QFormLayout *formlayout); + void addOpacitySpinBox(QWidget *widget, QFormLayout *formlayout); + void addVerticalSpacer(QFormLayout *formlayout); + + bool m_typeEditable; + +private: + Okular::Annotation *m_ann; + QWidget *m_appearanceWidget {nullptr}; + QWidget *m_extraWidget {nullptr}; + KColorButton *m_colorBn {nullptr}; + QSpinBox *m_opacity {nullptr}; +}; + +class QVBoxLayout; +class QFormLayout; + +class TextAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit TextAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + void createPopupNoteStyleUi(QWidget *widget, QFormLayout *formlayout); + void createInlineNoteStyleUi(QWidget *widget, QFormLayout *formlayout); + void createTypewriterStyleUi(QWidget *widget, QFormLayout *formlayout); + void addPixmapSelector(QWidget *widget, QFormLayout *formlayout); + void addFontRequester(QWidget *widget, QFormLayout *formlayout); + void addTextColorButton(QWidget *widget, QFormLayout *formlayout); + void addTextAlignComboBox(QWidget *widget, QFormLayout *formlayout); + void addWidthSpinBox(QWidget *widget, QFormLayout *formlayout); + + inline bool isTypewriter() const + { + return (m_textAnn->inplaceIntent() == Okular::TextAnnotation::TypeWriter); + } + + Okular::TextAnnotation *m_textAnn; + PixmapPreviewSelector *m_pixmapSelector {nullptr}; + KFontRequester *m_fontReq {nullptr}; + KColorButton *m_textColorBn {nullptr}; + QComboBox *m_textAlign {nullptr}; + QDoubleSpinBox *m_spinWidth {nullptr}; +}; + +class StampAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + static const QList> defaultStamps; + + explicit StampAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + Okular::StampAnnotation *m_stampAnn; + PixmapPreviewSelector *m_pixmapSelector; +}; + +class LineAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit LineAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + static QIcon endStyleIcon(Okular::LineAnnotation::TermStyle endStyle, const QColor &lineColor); + + Okular::LineAnnotation *m_lineAnn; + int m_lineType; + QDoubleSpinBox *m_spinLL {nullptr}; + QDoubleSpinBox *m_spinLLE {nullptr}; + QCheckBox *m_useColor {nullptr}; + KColorButton *m_innerColor {nullptr}; + QDoubleSpinBox *m_spinSize {nullptr}; + QComboBox *m_startStyleCombo {nullptr}; + QComboBox *m_endStyleCombo {nullptr}; +}; + +class HighlightAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit HighlightAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + Okular::HighlightAnnotation *m_hlAnn; + QComboBox *m_typeCombo; +}; + +class GeomAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit GeomAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + Okular::GeomAnnotation *m_geomAnn; + QComboBox *m_typeCombo; + QCheckBox *m_useColor; + KColorButton *m_innerColor; + QDoubleSpinBox *m_spinSize; +}; + +class FileAttachmentAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit FileAttachmentAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + QWidget *createExtraWidget() override; + +private: + Okular::FileAttachmentAnnotation *m_attachAnn; + PixmapPreviewSelector *m_pixmapSelector; +}; + +class CaretAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit CaretAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + Okular::CaretAnnotation *m_caretAnn; + PixmapPreviewSelector *m_pixmapSelector; +}; + +class InkAnnotationWidget : public AnnotationWidget +{ + Q_OBJECT + +public: + explicit InkAnnotationWidget(Okular::Annotation *ann); + + void applyChanges() override; + +protected: + void createStyleWidget(QFormLayout *formlayout) override; + +private: + Okular::InkAnnotation *m_inkAnn; + QDoubleSpinBox *m_spinSize; +}; + +#endif diff --git a/part/annotwindow.cpp b/part/annotwindow.cpp new file mode 100644 index 0000000..e8e3ca2 --- /dev/null +++ b/part/annotwindow.cpp @@ -0,0 +1,425 @@ +/*************************************************************************** + * Copyright (C) 2006 by Chu Xiaodong * + * Copyright (C) 2006 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "annotwindow.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "core/annotations.h" +#include "core/document.h" +#include "latexrenderer.h" +#include +#include + +class CloseButton : public QPushButton +{ + Q_OBJECT + +public: + CloseButton(QWidget *parent = Q_NULLPTR) + : QPushButton(parent) + { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QSize size = QSize(14, 14).expandedTo(QApplication::globalStrut()); + setFixedSize(size); + setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton)); + setIconSize(size); + setToolTip(i18n("Close this note")); + setCursor(Qt::ArrowCursor); + } +}; + +class MovableTitle : public QWidget +{ + Q_OBJECT + +public: + MovableTitle(AnnotWindow *parent) + : QWidget(parent) + { + QVBoxLayout *mainlay = new QVBoxLayout(this); + mainlay->setContentsMargins(0, 0, 0, 0); + mainlay->setSpacing(0); + // close button row + QHBoxLayout *buttonlay = new QHBoxLayout(); + mainlay->addLayout(buttonlay); + titleLabel = new QLabel(this); + QFont f = titleLabel->font(); + f.setBold(true); + titleLabel->setFont(f); + titleLabel->setCursor(Qt::SizeAllCursor); + buttonlay->addWidget(titleLabel); + dateLabel = new QLabel(this); + dateLabel->setAlignment(Qt::AlignTop | Qt::AlignRight); + f = dateLabel->font(); + f.setPointSize(QFontInfo(f).pointSize() - 2); + dateLabel->setFont(f); + dateLabel->setCursor(Qt::SizeAllCursor); + buttonlay->addWidget(dateLabel); + CloseButton *close = new CloseButton(this); + connect(close, &QAbstractButton::clicked, parent, &QWidget::close); + buttonlay->addWidget(close); + // option button row + QHBoxLayout *optionlay = new QHBoxLayout(); + mainlay->addLayout(optionlay); + authorLabel = new QLabel(this); + authorLabel->setCursor(Qt::SizeAllCursor); + authorLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + optionlay->addWidget(authorLabel); + optionButton = new QToolButton(this); + QString opttext = i18n("Options"); + optionButton->setText(opttext); + optionButton->setAutoRaise(true); + QSize s = QFontMetrics(optionButton->font()).boundingRect(opttext).size() + QSize(8, 8); + optionButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + optionButton->setFixedSize(s); + optionlay->addWidget(optionButton); + // ### disabled for now + optionButton->hide(); + latexButton = new QToolButton(this); + QHBoxLayout *latexlay = new QHBoxLayout(); + QString latextext = i18n("This annotation may contain LaTeX code.\nClick here to render."); + latexButton->setText(latextext); + latexButton->setAutoRaise(true); + s = QFontMetrics(latexButton->font()).boundingRect(0, 0, this->width(), this->height(), 0, latextext).size() + QSize(8, 8); + latexButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + latexButton->setFixedSize(s); + latexButton->setCheckable(true); + latexButton->setVisible(false); + latexlay->addSpacing(1); + latexlay->addWidget(latexButton); + latexlay->addSpacing(1); + mainlay->addLayout(latexlay); + connect(latexButton, &QToolButton::clicked, parent, &AnnotWindow::renderLatex); + connect(parent, &AnnotWindow::containsLatex, latexButton, &QWidget::setVisible); + + titleLabel->installEventFilter(this); + dateLabel->installEventFilter(this); + authorLabel->installEventFilter(this); + } + + bool eventFilter(QObject *obj, QEvent *e) override + { + if (obj != titleLabel && obj != authorLabel && obj != dateLabel) + return false; + + QMouseEvent *me = nullptr; + switch (e->type()) { + case QEvent::MouseButtonPress: + me = (QMouseEvent *)e; + mousePressPos = me->pos(); + parentWidget()->raise(); + break; + case QEvent::MouseButtonRelease: + mousePressPos = QPoint(); + break; + case QEvent::MouseMove: + me = (QMouseEvent *)e; + parentWidget()->move(me->pos() - mousePressPos + parentWidget()->pos()); + break; + default: + return false; + } + return true; + } + + void setTitle(const QString &title) + { + titleLabel->setText(QStringLiteral(" ") + title); + } + + void setDate(const QDateTime &dt) + { + dateLabel->setText(QLocale().toString(dt.toTimeSpec(Qt::LocalTime), QLocale::ShortFormat) + QLatin1Char(' ')); + } + + void setAuthor(const QString &author) + { + authorLabel->setText(QStringLiteral(" ") + author); + } + + void connectOptionButton(QObject *recv, const char *method) + { + connect(optionButton, SIGNAL(clicked()), recv, method); + } + + void uncheckLatexButton() + { + latexButton->setChecked(false); + } + +private: + QLabel *titleLabel; + QLabel *dateLabel; + QLabel *authorLabel; + QPoint mousePressPos; + QToolButton *optionButton; + QToolButton *latexButton; +}; + +// Qt::SubWindow is needed to make QSizeGrip work +AnnotWindow::AnnotWindow(QWidget *parent, Okular::Annotation *annot, Okular::Document *document, int page) + : QFrame(parent, Qt::SubWindow) + , m_annot(annot) + , m_document(document) + , m_page(page) +{ + setAutoFillBackground(true); + setFrameStyle(Panel | Raised); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName(QStringLiteral("AnnotWindow")); + + const bool canEditAnnotation = m_document->canModifyPageAnnotation(annot); + + textEdit = new KTextEdit(this); + textEdit->setAcceptRichText(false); + textEdit->setPlainText(m_annot->contents()); + textEdit->installEventFilter(this); + textEdit->setUndoRedoEnabled(false); + + m_prevCursorPos = textEdit->textCursor().position(); + m_prevAnchorPos = textEdit->textCursor().anchor(); + + connect(textEdit, &KTextEdit::textChanged, this, &AnnotWindow::slotsaveWindowText); + connect(textEdit, &KTextEdit::cursorPositionChanged, this, &AnnotWindow::slotsaveWindowText); + connect(textEdit, &KTextEdit::aboutToShowContextMenu, this, &AnnotWindow::slotUpdateUndoAndRedoInContextMenu); + connect(m_document, &Okular::Document::annotationContentsChangedByUndoRedo, this, &AnnotWindow::slotHandleContentsChangedByUndoRedo); + + if (!canEditAnnotation) + textEdit->setReadOnly(true); + + QVBoxLayout *mainlay = new QVBoxLayout(this); + mainlay->setContentsMargins(2, 2, 2, 2); + mainlay->setSpacing(0); + m_title = new MovableTitle(this); + mainlay->addWidget(m_title); + mainlay->addWidget(textEdit); + QHBoxLayout *lowerlay = new QHBoxLayout(); + mainlay->addLayout(lowerlay); + lowerlay->addItem(new QSpacerItem(5, 5, QSizePolicy::Expanding, QSizePolicy::Fixed)); + QSizeGrip *sb = new QSizeGrip(this); + lowerlay->addWidget(sb); + + m_latexRenderer = new GuiUtils::LatexRenderer(); + // The emit below is not wrong even if emitting signals from the constructor it's usually wrong + // in this case the signal it's connected to inside MovableTitle constructor a few lines above + emit containsLatex(GuiUtils::LatexRenderer::mightContainLatex(m_annot->contents())); // clazy:exclude=incorrect-emit + + m_title->setTitle(m_annot->window().summary()); + m_title->connectOptionButton(this, SLOT(slotOptionBtn())); + + setGeometry(10, 10, 300, 300); + + reloadInfo(); +} + +AnnotWindow::~AnnotWindow() +{ + delete m_latexRenderer; +} + +Okular::Annotation *AnnotWindow::annotation() const +{ + return m_annot; +} + +void AnnotWindow::updateAnnotation(Okular::Annotation *a) +{ + m_annot = a; +} + +void AnnotWindow::reloadInfo() +{ + QColor newcolor; + if (m_annot->subType() == Okular::Annotation::AText) { + Okular::TextAnnotation *textAnn = static_cast(m_annot); + if (textAnn->textType() == Okular::TextAnnotation::InPlace && textAnn->inplaceIntent() == Okular::TextAnnotation::TypeWriter) + newcolor = QColor(0xfd, 0xfd, 0x96); + } + if (!newcolor.isValid()) + newcolor = m_annot->style().color().isValid() ? QColor(m_annot->style().color().red(), m_annot->style().color().green(), m_annot->style().color().blue(), 255) : Qt::yellow; + if (newcolor != m_color) { + m_color = newcolor; + setPalette(QPalette(m_color)); + QPalette pl = textEdit->palette(); + pl.setColor(QPalette::Base, m_color); + textEdit->setPalette(pl); + } + m_title->setAuthor(m_annot->author()); + m_title->setDate(m_annot->modificationDate()); +} + +int AnnotWindow::pageNumber() const +{ + return m_page; +} + +void AnnotWindow::showEvent(QShowEvent *event) +{ + QFrame::showEvent(event); + + // focus the content area by default + textEdit->setFocus(); +} + +bool AnnotWindow::eventFilter(QObject *o, QEvent *e) +{ + if (e->type() == QEvent::ShortcutOverride) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent->key() == Qt::Key_Escape) { + close(); + return true; + } + } else if (e->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent == QKeySequence::Undo) { + m_document->undo(); + return true; + } else if (keyEvent == QKeySequence::Redo) { + m_document->redo(); + return true; + } + } else if (e->type() == QEvent::FocusIn) { + raise(); + } + return QFrame::eventFilter(o, e); +} + +void AnnotWindow::slotUpdateUndoAndRedoInContextMenu(QMenu *menu) +{ + if (!menu) + return; + + QList actionList = menu->actions(); + enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, ClearAct, SelectAllAct, NCountActs }; + + QAction *kundo = KStandardAction::create(KStandardAction::Undo, m_document, SLOT(undo()), menu); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, m_document, SLOT(redo()), menu); + connect(m_document, &Okular::Document::canUndoChanged, kundo, &QAction::setEnabled); + connect(m_document, &Okular::Document::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(m_document->canUndo()); + kredo->setEnabled(m_document->canRedo()); + + QAction *oldUndo, *oldRedo; + oldUndo = actionList[UndoAct]; + oldRedo = actionList[RedoAct]; + + menu->insertAction(oldUndo, kundo); + menu->insertAction(oldRedo, kredo); + + menu->removeAction(oldUndo); + menu->removeAction(oldRedo); +} + +void AnnotWindow::slotOptionBtn() +{ + // TODO: call context menu in pageview + // emit sig... +} + +void AnnotWindow::slotsaveWindowText() +{ + const QString contents = textEdit->toPlainText(); + const int cursorPos = textEdit->textCursor().position(); + if (contents != m_annot->contents()) { + m_document->editPageAnnotationContents(m_page, m_annot, contents, cursorPos, m_prevCursorPos, m_prevAnchorPos); + emit containsLatex(GuiUtils::LatexRenderer::mightContainLatex(textEdit->toPlainText())); + } + m_prevCursorPos = cursorPos; + m_prevAnchorPos = textEdit->textCursor().anchor(); +} + +void AnnotWindow::renderLatex(bool render) +{ + if (render) { + textEdit->setReadOnly(true); + disconnect(textEdit, &KTextEdit::textChanged, this, &AnnotWindow::slotsaveWindowText); + disconnect(textEdit, &KTextEdit::cursorPositionChanged, this, &AnnotWindow::slotsaveWindowText); + textEdit->setAcceptRichText(true); + QString contents = m_annot->contents(); + contents = Qt::convertFromPlainText(contents); + QColor fontColor = textEdit->textColor(); + int fontSize = textEdit->fontPointSize(); + QString latexOutput; + GuiUtils::LatexRenderer::Error errorCode = m_latexRenderer->renderLatexInHtml(contents, fontColor, fontSize, Okular::Utils::realDpi(nullptr).width(), latexOutput); + switch (errorCode) { + case GuiUtils::LatexRenderer::LatexNotFound: + KMessageBox::sorry(this, i18n("Cannot find latex executable."), i18n("LaTeX rendering failed")); + m_title->uncheckLatexButton(); + renderLatex(false); + break; + case GuiUtils::LatexRenderer::DvipngNotFound: + KMessageBox::sorry(this, i18n("Cannot find dvipng executable."), i18n("LaTeX rendering failed")); + m_title->uncheckLatexButton(); + renderLatex(false); + break; + case GuiUtils::LatexRenderer::LatexFailed: + KMessageBox::detailedSorry(this, i18n("A problem occurred during the execution of the 'latex' command."), latexOutput, i18n("LaTeX rendering failed")); + m_title->uncheckLatexButton(); + renderLatex(false); + break; + case GuiUtils::LatexRenderer::DvipngFailed: + KMessageBox::sorry(this, i18n("A problem occurred during the execution of the 'dvipng' command."), i18n("LaTeX rendering failed")); + m_title->uncheckLatexButton(); + renderLatex(false); + break; + case GuiUtils::LatexRenderer::NoError: + default: + textEdit->setHtml(contents); + break; + } + } else { + textEdit->setAcceptRichText(false); + textEdit->setPlainText(m_annot->contents()); + connect(textEdit, &KTextEdit::textChanged, this, &AnnotWindow::slotsaveWindowText); + connect(textEdit, &KTextEdit::cursorPositionChanged, this, &AnnotWindow::slotsaveWindowText); + textEdit->setReadOnly(false); + } +} + +void AnnotWindow::slotHandleContentsChangedByUndoRedo(Okular::Annotation *annot, const QString &contents, int cursorPos, int anchorPos) +{ + if (annot != m_annot) { + return; + } + + textEdit->setPlainText(contents); + QTextCursor c = textEdit->textCursor(); + c.setPosition(anchorPos); + c.setPosition(cursorPos, QTextCursor::KeepAnchor); + m_prevCursorPos = cursorPos; + m_prevAnchorPos = anchorPos; + textEdit->setTextCursor(c); + textEdit->setFocus(); + emit containsLatex(GuiUtils::LatexRenderer::mightContainLatex(m_annot->contents())); +} + +#include "annotwindow.moc" diff --git a/part/annotwindow.h b/part/annotwindow.h new file mode 100644 index 0000000..4469a05 --- /dev/null +++ b/part/annotwindow.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2006 by Chu Xiaodong * + * Copyright (C) 2006 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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 _ANNOTWINDOW_H_ +#define _ANNOTWINDOW_H_ + +#include +#include + +namespace Okular +{ +class Annotation; +class Document; +} + +namespace GuiUtils +{ +class LatexRenderer; +} + +class KTextEdit; +class MovableTitle; +class QMenu; + +class AnnotWindow : public QFrame +{ + Q_OBJECT +public: + AnnotWindow(QWidget *parent, Okular::Annotation *annot, Okular::Document *document, int page); + ~AnnotWindow() override; + + void reloadInfo(); + + Okular::Annotation *annotation() const; + int pageNumber() const; + + void updateAnnotation(Okular::Annotation *a); + +private: + MovableTitle *m_title; + KTextEdit *textEdit; + QColor m_color; + GuiUtils::LatexRenderer *m_latexRenderer; + Okular::Annotation *m_annot; + Okular::Document *m_document; + int m_page; + int m_prevCursorPos; + int m_prevAnchorPos; + +public Q_SLOTS: + void renderLatex(bool render); + +protected: + void showEvent(QShowEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + +private Q_SLOTS: + void slotUpdateUndoAndRedoInContextMenu(QMenu *menu); + void slotOptionBtn(); + void slotsaveWindowText(); + void slotHandleContentsChangedByUndoRedo(Okular::Annotation *annot, const QString &contents, int cursorPos, int anchorPos); + +Q_SIGNALS: + void containsLatex(bool); +}; + +#endif diff --git a/part/bookmarklist.cpp b/part/bookmarklist.cpp new file mode 100644 index 0000000..87e00bb --- /dev/null +++ b/part/bookmarklist.cpp @@ -0,0 +1,440 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "bookmarklist.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "core/action.h" +#include "core/bookmarkmanager.h" +#include "core/document.h" +#include "pageitemdelegate.h" + +static const int BookmarkItemType = QTreeWidgetItem::UserType + 1; +static const int FileItemType = QTreeWidgetItem::UserType + 2; +static const int UrlRole = Qt::UserRole + 1; + +class BookmarkItem : public QTreeWidgetItem +{ +public: + BookmarkItem(const KBookmark &bm) + : QTreeWidgetItem(BookmarkItemType) + , m_bookmark(bm) + { + setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + m_url = m_bookmark.url(); + m_viewport = Okular::DocumentViewport(m_url.fragment(QUrl::FullyDecoded)); + m_url.setFragment(QString()); + setText(0, m_bookmark.fullText()); + if (m_viewport.isValid()) + setData(0, PageItemDelegate::PageRole, QString::number(m_viewport.pageNumber + 1)); + } + + BookmarkItem(const BookmarkItem &) = delete; + BookmarkItem &operator=(const BookmarkItem &) = delete; + + QVariant data(int column, int role) const override + { + switch (role) { + case Qt::ToolTipRole: + return m_bookmark.fullText(); + } + return QTreeWidgetItem::data(column, role); + } + + bool operator<(const QTreeWidgetItem &other) const override + { + if (other.type() == BookmarkItemType) { + const BookmarkItem *cmp = static_cast(&other); + return m_viewport < cmp->m_viewport; + } + return QTreeWidgetItem::operator<(other); + } + + KBookmark &bookmark() + { + return m_bookmark; + } + + const Okular::DocumentViewport &viewport() const + { + return m_viewport; + } + + QUrl url() const + { + return m_url; + } + +private: + KBookmark m_bookmark; + QUrl m_url; + Okular::DocumentViewport m_viewport; +}; + +class FileItem : public QTreeWidgetItem +{ +public: + FileItem(const QUrl &url, QTreeWidget *tree, Okular::Document *document) + : QTreeWidgetItem(tree, FileItemType) + { + setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); + const QString fileString = document->bookmarkManager()->titleForUrl(url); + setText(0, fileString); + setData(0, UrlRole, QVariant::fromValue(url)); + } + + FileItem(const FileItem &) = delete; + FileItem &operator=(const FileItem &) = delete; + + QVariant data(int column, int role) const override + { + switch (role) { + case Qt::ToolTipRole: + return i18ncp("%1 is the file name", "%1\n\nOne bookmark", "%1\n\n%2 bookmarks", text(0), childCount()); + } + return QTreeWidgetItem::data(column, role); + } +}; + +BookmarkList::BookmarkList(Okular::Document *document, QWidget *parent) + : QWidget(parent) + , m_document(document) + , m_currentDocumentItem(nullptr) +{ + QVBoxLayout *mainlay = new QVBoxLayout(this); + mainlay->setSpacing(6); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Bookmarks")); + mainlay->addWidget(titleWidget); + mainlay->setAlignment(titleWidget, Qt::AlignHCenter); + m_searchLine = new KTreeWidgetSearchLine(this); + mainlay->addWidget(m_searchLine); + m_searchLine->setPlaceholderText(i18n("Search...")); + + m_tree = new QTreeWidget(this); + mainlay->addWidget(m_tree); + QStringList cols; + cols.append(QStringLiteral("Bookmarks")); + m_tree->setContextMenuPolicy(Qt::CustomContextMenu); + m_tree->setHeaderLabels(cols); + m_tree->setSortingEnabled(false); + m_tree->setRootIsDecorated(true); + m_tree->setAlternatingRowColors(true); + m_tree->setItemDelegate(new PageItemDelegate(m_tree)); + m_tree->header()->hide(); + m_tree->setSelectionBehavior(QAbstractItemView::SelectRows); + m_tree->setEditTriggers(QAbstractItemView::EditKeyPressed); + connect(m_tree, &QTreeWidget::itemActivated, this, &BookmarkList::slotExecuted); + connect(m_tree, &QTreeWidget::customContextMenuRequested, this, &BookmarkList::slotContextMenu); + m_searchLine->addTreeWidget(m_tree); + + QToolBar *bookmarkController = new QToolBar(this); + mainlay->addWidget(bookmarkController); + bookmarkController->setObjectName(QStringLiteral("BookmarkControlBar")); + // change toolbar appearance + bookmarkController->setIconSize(QSize(16, 16)); + bookmarkController->setMovable(false); + QSizePolicy sp = bookmarkController->sizePolicy(); + sp.setVerticalPolicy(QSizePolicy::Minimum); + bookmarkController->setSizePolicy(sp); + // insert a togglebutton [show only bookmarks in the current document] + m_showBoomarkOnlyAction = bookmarkController->addAction(QIcon::fromTheme(QStringLiteral("bookmarks")), i18n("Current document only")); + m_showBoomarkOnlyAction->setCheckable(true); + connect(m_showBoomarkOnlyAction, &QAction::toggled, this, &BookmarkList::slotFilterBookmarks); + + connect(m_document->bookmarkManager(), &Okular::BookmarkManager::bookmarksChanged, this, &BookmarkList::slotBookmarksChanged); + + rebuildTree(m_showBoomarkOnlyAction->isChecked()); +} + +BookmarkList::~BookmarkList() +{ + m_document->removeObserver(this); +} + +void BookmarkList::notifySetup(const QVector &pages, int setupFlags) +{ + Q_UNUSED(pages); + if (!(setupFlags & Okular::DocumentObserver::UrlChanged)) + return; + + // clear contents + m_searchLine->clear(); + + if (m_showBoomarkOnlyAction->isChecked()) { + rebuildTree(m_showBoomarkOnlyAction->isChecked()); + } else { + disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); + if (m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem()) { + m_currentDocumentItem->setIcon(0, QIcon()); + } + m_currentDocumentItem = itemForUrl(m_document->currentDocument()); + if (m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem()) { + m_currentDocumentItem->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks"))); + m_currentDocumentItem->setExpanded(true); + } + connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); + } +} + +void BookmarkList::slotFilterBookmarks(bool on) +{ + rebuildTree(on); +} + +void BookmarkList::slotExecuted(QTreeWidgetItem *item) +{ + BookmarkItem *bmItem = dynamic_cast(item); + if (!bmItem || !bmItem->viewport().isValid()) + return; + + goTo(bmItem); +} + +void BookmarkList::slotChanged(QTreeWidgetItem *item) +{ + BookmarkItem *bmItem = dynamic_cast(item); + if (bmItem && bmItem->viewport().isValid()) { + bmItem->bookmark().setFullText(bmItem->text(0)); + m_document->bookmarkManager()->save(); + } + + FileItem *fItem = dynamic_cast(item); + if (fItem) { + const QUrl url = fItem->data(0, UrlRole).value(); + m_document->bookmarkManager()->renameBookmark(url, fItem->text(0)); + m_document->bookmarkManager()->save(); + } +} + +void BookmarkList::slotContextMenu(const QPoint p) +{ + QTreeWidgetItem *item = m_tree->itemAt(p); + BookmarkItem *bmItem = item ? dynamic_cast(item) : nullptr; + if (bmItem) + contextMenuForBookmarkItem(p, bmItem); + else if (FileItem *fItem = dynamic_cast(item)) + contextMenuForFileItem(p, fItem); +} + +void BookmarkList::contextMenuForBookmarkItem(const QPoint p, BookmarkItem *bmItem) +{ + Q_UNUSED(p); + if (!bmItem || !bmItem->viewport().isValid()) + return; + + QMenu menu(this); + QAction *gotobm = menu.addAction(i18n("Go to This Bookmark")); + QAction *editbm = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename Bookmark")); + QAction *removebm = menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove Bookmark")); + QAction *res = menu.exec(QCursor::pos()); + if (!res) + return; + + if (res == gotobm) + goTo(bmItem); + else if (res == editbm) + m_tree->editItem(bmItem, 0); + else if (res == removebm) + m_document->bookmarkManager()->removeBookmark(bmItem->url(), bmItem->bookmark()); +} + +void BookmarkList::contextMenuForFileItem(const QPoint p, FileItem *fItem) +{ + Q_UNUSED(p); + if (!fItem) + return; + + const QUrl itemurl = fItem->data(0, UrlRole).value(); + const bool thisdoc = itemurl == m_document->currentDocument(); + + QMenu menu(this); + QAction *open = nullptr; + if (!thisdoc) + open = menu.addAction(i18nc("Opens the selected document", "Open Document")); + QAction *editbm = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename Bookmark")); + QAction *removebm = menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove Bookmarks")); + QAction *res = menu.exec(QCursor::pos()); + if (!res) + return; + + if (res == open) { + Okular::GotoAction action(itemurl.toDisplayString(QUrl::PreferLocalFile), Okular::DocumentViewport()); + m_document->processAction(&action); + } else if (res == editbm) + m_tree->editItem(fItem, 0); + else if (res == removebm) { + KBookmark::List list; + for (int i = 0; i < fItem->childCount(); ++i) { + list.append(static_cast(fItem->child(i))->bookmark()); + } + m_document->bookmarkManager()->removeBookmarks(itemurl, list); + } +} + +void BookmarkList::slotBookmarksChanged(const QUrl &url) +{ + // special case here, as m_currentDocumentItem could represent + // the invisible root item + if (url == m_document->currentDocument()) { + selectiveUrlUpdate(m_document->currentDocument(), m_currentDocumentItem); + return; + } + + // we are showing the bookmarks for the current document only + if (m_showBoomarkOnlyAction->isChecked()) + return; + + QTreeWidgetItem *item = itemForUrl(url); + selectiveUrlUpdate(url, item); +} + +QList createItems(const QUrl &baseurl, const KBookmark::List &bmlist) +{ + Q_UNUSED(baseurl) + QList ret; + for (const KBookmark &bm : bmlist) { + // qCDebug(OkularUiDebug).nospace() << "checking '" << tmp << "'"; + // qCDebug(OkularUiDebug).nospace() << " vs '" << baseurl << "'"; + // TODO check that bm and baseurl are the same (#ref excluded) + QTreeWidgetItem *item = new BookmarkItem(bm); + ret.append(item); + } + return ret; +} + +void BookmarkList::rebuildTree(bool filter) +{ + // disconnect and reconnect later, otherwise we'll get many itemChanged() + // signals for all the current items + disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); + + m_currentDocumentItem = nullptr; + m_tree->clear(); + + const QList urls = m_document->bookmarkManager()->files(); + if (filter) { + if (m_document->isOpened()) { + for (const QUrl &url : urls) { + if (url == m_document->currentDocument()) { + m_tree->addTopLevelItems(createItems(url, m_document->bookmarkManager()->bookmarks(url))); + m_currentDocumentItem = m_tree->invisibleRootItem(); + break; + } + } + } + } else { + QTreeWidgetItem *currenturlitem = nullptr; + for (const QUrl &url : urls) { + QList subitems = createItems(url, m_document->bookmarkManager()->bookmarks(url)); + if (!subitems.isEmpty()) { + FileItem *item = new FileItem(url, m_tree, m_document); + item->addChildren(subitems); + if (!currenturlitem && url == m_document->currentDocument()) { + currenturlitem = item; + } + } + } + if (currenturlitem) { + currenturlitem->setExpanded(true); + currenturlitem->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks"))); + m_tree->scrollToItem(currenturlitem, QAbstractItemView::PositionAtTop); + m_currentDocumentItem = currenturlitem; + } + } + + m_tree->sortItems(0, Qt::AscendingOrder); + + connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); +} + +void BookmarkList::goTo(BookmarkItem *item) +{ + if (item->url() == m_document->currentDocument()) { + m_document->setViewport(item->viewport(), nullptr, true); + } else { + Okular::GotoAction action(item->url().toDisplayString(QUrl::PreferLocalFile), item->viewport()); + m_document->processAction(&action); + } +} + +void BookmarkList::selectiveUrlUpdate(const QUrl &url, QTreeWidgetItem *&item) +{ + disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); + + const KBookmark::List urlbookmarks = m_document->bookmarkManager()->bookmarks(url); + if (urlbookmarks.isEmpty()) { + if (item != m_tree->invisibleRootItem()) { + m_tree->invisibleRootItem()->removeChild(item); + item = nullptr; + } else if (item) { + for (int i = item->childCount(); i >= 0; --i) { + item->removeChild(item->child(i)); + } + } + } else { + bool fileitem_created = false; + + if (item) { + for (int i = item->childCount() - 1; i >= 0; --i) { + item->removeChild(item->child(i)); + } + } else { + item = new FileItem(url, m_tree, m_document); + fileitem_created = true; + } + if (m_document->isOpened() && url == m_document->currentDocument()) { + item->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks"))); + item->setExpanded(true); + } + item->addChildren(createItems(url, urlbookmarks)); + + if (fileitem_created) { + // we need to sort also the parent of the new file item, + // so it can be properly shown in the correct place + m_tree->invisibleRootItem()->sortChildren(0, Qt::AscendingOrder); + } + item->sortChildren(0, Qt::AscendingOrder); + } + + connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged); +} + +QTreeWidgetItem *BookmarkList::itemForUrl(const QUrl &url) const +{ + const int count = m_tree->topLevelItemCount(); + for (int i = 0; i < count; ++i) { + QTreeWidgetItem *item = m_tree->topLevelItem(i); + const QUrl itemurl = item->data(0, UrlRole).value(); + if (itemurl.isValid() && itemurl == url) { + return item; + } + } + return nullptr; +} + +#include "moc_bookmarklist.cpp" diff --git a/part/bookmarklist.h b/part/bookmarklist.h new file mode 100644 index 0000000..17bc6aa --- /dev/null +++ b/part/bookmarklist.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2006 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 BOOKMARKLIST_H +#define BOOKMARKLIST_H + +#include + +#include "core/observer.h" + +class QAction; +class QTreeWidget; +class QTreeWidgetItem; +class KTreeWidgetSearchLine; +class QUrl; +class BookmarkItem; +class FileItem; + +namespace Okular +{ +class Document; +} + +class BookmarkList : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT + +public: + explicit BookmarkList(Okular::Document *document, QWidget *parent = nullptr); + ~BookmarkList() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + +private Q_SLOTS: + void slotFilterBookmarks(bool); + void slotExecuted(QTreeWidgetItem *item); + void slotChanged(QTreeWidgetItem *item); + void slotContextMenu(const QPoint p); + void slotBookmarksChanged(const QUrl &url); + +private: + void rebuildTree(bool filter); + void goTo(BookmarkItem *item); + void selectiveUrlUpdate(const QUrl &url, QTreeWidgetItem *&item); + QTreeWidgetItem *itemForUrl(const QUrl &url) const; + void contextMenuForBookmarkItem(const QPoint p, BookmarkItem *bmItem); + void contextMenuForFileItem(const QPoint p, FileItem *fItem); + + Okular::Document *m_document; + QTreeWidget *m_tree; + KTreeWidgetSearchLine *m_searchLine; + QAction *m_showBoomarkOnlyAction; + QTreeWidgetItem *m_currentDocumentItem; +}; + +#endif diff --git a/part/certificateviewer.cpp b/part/certificateviewer.cpp new file mode 100644 index 0000000..7f74ea6 --- /dev/null +++ b/part/certificateviewer.cpp @@ -0,0 +1,325 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "certificateviewer.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "signatureguiutils.h" + +// DN (DistinguishedName) attributes can be +// C Country +// CN Common name +// DC Domain component +// E E-mail address +// EMAIL E-mail address (preferred) +// EMAILADDRESS E-mail address +// L Locality +// O Organization name +// OU Organizational unit name +// PC Postal code +// S State or province +// SN Family name +// SP State or province +// ST State or province (preferred) +// STREET Street +// T Title + +// CN=James Hacker, +// L=Basingstoke, +// O=Widget Inc, +// C=GB +// CN=L. Eagle, O="Sue, Grabbit and Runn", C=GB +// CN=L. Eagle, O=Sue\, Grabbit and Runn, C=GB + +// This is a poor man's attempt at parsing DN, if it fails it is not a problem since it's only for display in a list +static QString splitDNAttributes(const QStringList &text) +{ + const QStringList attributes = {"C", "CN", "DC", "E", "EMAIL", "EMAILADDRESS", "L", "O", "OU", "PC", "S", "SN", "SP", "ST", "STREET", "T"}; + + for (const QString &t : text) { + for (const QString &attribute : attributes) { + const QRegularExpression re(QStringLiteral("(.*),\\s*(%1=.*)").arg(attribute), QRegularExpression::DotMatchesEverythingOption); + const QRegularExpressionMatch match = re.match(t); + if (match.hasMatch()) { + QStringList results = text; + const int index = results.indexOf(t); + results.removeAt(index); + results.insert(index, match.captured(2)); + results.insert(index, match.captured(1)); + return splitDNAttributes(results); + } + } + } + + // Clean escaped commas + QStringList result = text; + for (QString &t : result) { + t.replace(QLatin1String("\\,"), QLatin1String(",")); + } + + // Clean up quoted attributes + for (QString &t : result) { + for (const QString &attribute : attributes) { + const QRegularExpression re(QStringLiteral("%1=\"(.*)\"").arg(attribute)); + const QRegularExpressionMatch match = re.match(t); + if (match.hasMatch()) { + t = attribute + '=' + match.captured(1); + } + } + } + + return result.join(QStringLiteral("\n")); +} + +static QString splitDNAttributes(const QString &text) +{ + return splitDNAttributes(QStringList {text}); +} + +CertificateModel::CertificateModel(const Okular::CertificateInfo &certInfo, QObject *parent) + : QAbstractTableModel(parent) + , m_certificateInfo(certInfo) +{ + m_certificateProperties = {Version, SerialNumber, Issuer, IssuedOn, ExpiresOn, Subject, PublicKey, KeyUsage}; +} + +int CertificateModel::columnCount(const QModelIndex &) const +{ + return 2; +} + +int CertificateModel::rowCount(const QModelIndex &) const +{ + return m_certificateProperties.size(); +} + +static QString propertyVisibleName(CertificateModel::Property p) +{ + switch (p) { + case CertificateModel::Version: + return i18n("Version"); + case CertificateModel::SerialNumber: + return i18n("Serial Number"); + case CertificateModel::Issuer: + return i18n("Issuer"); + case CertificateModel::IssuedOn: + return i18n("Issued On"); + case CertificateModel::ExpiresOn: + return i18n("Expires On"); + case CertificateModel::Subject: + return i18nc("The person/company that made the signature", "Subject"); + case CertificateModel::PublicKey: + return i18n("Public Key"); + case CertificateModel::KeyUsage: + return i18n("Key Usage"); + } + return QString(); +} + +static QString propertyVisibleValue(CertificateModel::Property p, const Okular::CertificateInfo &certInfo) +{ + switch (p) { + case CertificateModel::Version: + return i18n("V%1", QString::number(certInfo.version())); + case CertificateModel::SerialNumber: + return certInfo.serialNumber().toHex(' '); + case CertificateModel::Issuer: + return certInfo.issuerInfo(Okular::CertificateInfo::DistinguishedName); + case CertificateModel::IssuedOn: + return certInfo.validityStart().toString(Qt::DefaultLocaleLongDate); + case CertificateModel::ExpiresOn: + return certInfo.validityEnd().toString(Qt::DefaultLocaleLongDate); + case CertificateModel::Subject: + return certInfo.subjectInfo(Okular::CertificateInfo::DistinguishedName); + case CertificateModel::PublicKey: + return i18n("%1 (%2 bits)", SignatureGuiUtils::getReadablePublicKeyType(certInfo.publicKeyType()), certInfo.publicKeyStrength()); + case CertificateModel::KeyUsage: + return SignatureGuiUtils::getReadableKeyUsageCommaSeparated(certInfo.keyUsageExtensions()); + } + return QString(); +} + +QVariant CertificateModel::data(const QModelIndex &index, int role) const +{ + const int row = index.row(); + if (!index.isValid() || row < 0 || row >= m_certificateProperties.count()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + case Qt::ToolTipRole: + switch (index.column()) { + case 0: + return propertyVisibleName(m_certificateProperties[row]); + case 1: + return propertyVisibleValue(m_certificateProperties[row], m_certificateInfo); + default: + return QString(); + } + case PropertyKeyRole: + return m_certificateProperties[row]; + case PropertyVisibleValueRole: + return propertyVisibleValue(m_certificateProperties[row], m_certificateInfo); + } + + return QVariant(); +} + +QVariant CertificateModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::TextAlignmentRole) + return QVariant(Qt::AlignLeft); + + if (orientation != Qt::Horizontal || role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return i18n("Property"); + case 1: + return i18n("Value"); + default: + return QVariant(); + } +} + +CertificateViewer::CertificateViewer(const Okular::CertificateInfo &certInfo, QWidget *parent) + : KPageDialog(parent) + , m_certificateInfo(certInfo) +{ + setModal(true); + setMinimumSize(QSize(500, 500)); + setFaceType(Tabbed); + setWindowTitle(i18n("Certificate Viewer")); + setStandardButtons(QDialogButtonBox::Close); + + auto exportBtn = new QPushButton(i18n("Export...")); + connect(exportBtn, &QPushButton::clicked, this, &CertificateViewer::exportCertificate); + addActionButton(exportBtn); + + // General tab + auto generalPage = new QFrame(this); + addPage(generalPage, i18n("General")); + + auto issuerBox = new QGroupBox(i18n("Issued By"), generalPage); + auto issuerFormLayout = new QFormLayout(issuerBox); + issuerFormLayout->setLabelAlignment(Qt::AlignLeft); + issuerFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::CommonName))); + issuerFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::EmailAddress))); + issuerFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.issuerInfo(Okular::CertificateInfo::Organization))); + + auto subjectBox = new QGroupBox(i18n("Issued To"), generalPage); + auto subjectFormLayout = new QFormLayout(subjectBox); + subjectFormLayout->setLabelAlignment(Qt::AlignLeft); + subjectFormLayout->addRow(i18n("Common Name(CN)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::CommonName))); + subjectFormLayout->addRow(i18n("EMail"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::EmailAddress))); + subjectFormLayout->addRow(i18n("Organization(O)"), new QLabel(m_certificateInfo.subjectInfo(Okular::CertificateInfo::Organization))); + + auto validityBox = new QGroupBox(i18n("Validity"), generalPage); + auto validityFormLayout = new QFormLayout(validityBox); + validityFormLayout->setLabelAlignment(Qt::AlignLeft); + validityFormLayout->addRow(i18n("Issued On"), new QLabel(m_certificateInfo.validityStart().toString(Qt::DefaultLocaleLongDate))); + validityFormLayout->addRow(i18n("Expires On"), new QLabel(m_certificateInfo.validityEnd().toString(Qt::DefaultLocaleLongDate))); + + auto fingerprintBox = new QGroupBox(i18n("Fingerprints"), generalPage); + auto fingerprintFormLayout = new QFormLayout(fingerprintBox); + fingerprintFormLayout->setLabelAlignment(Qt::AlignLeft); + QByteArray certData = m_certificateInfo.certificateData(); + auto sha1Label = new QLabel(QString(QCryptographicHash::hash(certData, QCryptographicHash::Sha1).toHex(' '))); + sha1Label->setWordWrap(true); + auto sha256Label = new QLabel(QString(QCryptographicHash::hash(certData, QCryptographicHash::Sha256).toHex(' '))); + sha256Label->setWordWrap(true); + fingerprintFormLayout->addRow(i18n("SHA-1 Fingerprint"), sha1Label); + fingerprintFormLayout->addRow(i18n("SHA-256 Fingerprint"), sha256Label); + + auto generalPageLayout = new QVBoxLayout(generalPage); + generalPageLayout->addWidget(issuerBox); + generalPageLayout->addWidget(subjectBox); + generalPageLayout->addWidget(validityBox); + generalPageLayout->addWidget(fingerprintBox); + generalPageLayout->addStretch(); + + // force column 1 to have same width + auto resizer = new KColumnResizer(this); + resizer->addWidgetsFromLayout(issuerBox->layout(), 0); + resizer->addWidgetsFromLayout(subjectBox->layout(), 0); + resizer->addWidgetsFromLayout(validityBox->layout(), 0); + resizer->addWidgetsFromLayout(fingerprintBox->layout(), 0); + + // Details tab + auto detailsFrame = new QFrame(this); + addPage(detailsFrame, i18n("Details")); + auto certDataLabel = new QLabel(i18n("Certificate Data:")); + auto certTree = new QTreeView(this); + certTree->setIndentation(0); + m_certificateModel = new CertificateModel(m_certificateInfo, this); + certTree->setModel(m_certificateModel); + connect(certTree->selectionModel(), &QItemSelectionModel::currentChanged, this, &CertificateViewer::updateText); + m_propertyText = new QTextEdit(this); + m_propertyText->setReadOnly(true); + + auto detailsPageLayout = new QVBoxLayout(detailsFrame); + detailsPageLayout->addWidget(certDataLabel); + detailsPageLayout->addWidget(certTree); + detailsPageLayout->addWidget(m_propertyText); +} + +void CertificateViewer::updateText(const QModelIndex &index) +{ + QString text; + const CertificateModel::Property key = m_certificateModel->data(index, CertificateModel::PropertyKeyRole).value(); + switch (key) { + case CertificateModel::SerialNumber: + case CertificateModel::Version: + case CertificateModel::IssuedOn: + case CertificateModel::ExpiresOn: + text = m_certificateModel->data(index, CertificateModel::PropertyVisibleValueRole).toString(); + break; + case CertificateModel::Issuer: + case CertificateModel::Subject: + text = splitDNAttributes(m_certificateModel->data(index, CertificateModel::PropertyVisibleValueRole).toString()); + break; + case CertificateModel::PublicKey: + text = m_certificateInfo.publicKey().toHex(' '); + break; + case CertificateModel::KeyUsage: + text = SignatureGuiUtils::getReadableKeyUsageNewLineSeparated(m_certificateInfo.keyUsageExtensions()); + break; + } + m_propertyText->setText(text); +} + +void CertificateViewer::exportCertificate() +{ + const QString caption = i18n("Where do you want to save this certificate?"); + const QString path = QFileDialog::getSaveFileName(this, caption, QStringLiteral("Certificate.cer"), i18n("Certificate File (*.cer)")); + if (!path.isEmpty()) { + QFile targetFile(path); + targetFile.open(QIODevice::WriteOnly); + if (targetFile.write(m_certificateInfo.certificateData()) == -1) { + KMessageBox::error(this, i18n("Could not export the certificate")); + } + targetFile.close(); + } +} diff --git a/part/certificateviewer.h b/part/certificateviewer.h new file mode 100644 index 0000000..42fe956 --- /dev/null +++ b/part/certificateviewer.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_CERTIFICATEVIEWER_H +#define OKULAR_CERTIFICATEVIEWER_H + +#include +#include +#include + +#include "core/signatureutils.h" + +class QTextEdit; + +namespace Okular +{ +class CertificateInfo; +} + +class CertificateModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CertificateModel(const Okular::CertificateInfo &certInfo, QObject *parent = nullptr); + + enum { PropertyKeyRole = Qt::UserRole, PropertyVisibleValueRole }; + + enum Property { Version, SerialNumber, Issuer, IssuedOn, ExpiresOn, Subject, PublicKey, KeyUsage }; + Q_ENUM(Property) + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + +private: + QVector m_certificateProperties; + const Okular::CertificateInfo &m_certificateInfo; +}; + +class CertificateViewer : public KPageDialog +{ + Q_OBJECT + +public: + CertificateViewer(const Okular::CertificateInfo &certInfo, QWidget *parent); + +private Q_SLOTS: + void updateText(const QModelIndex &index); + void exportCertificate(); + +private: + QTextEdit *m_propertyText; + CertificateModel *m_certificateModel; + const Okular::CertificateInfo &m_certificateInfo; +}; + +#endif diff --git a/part/data/CMakeLists.txt b/part/data/CMakeLists.txt new file mode 100644 index 0000000..17c0926 --- /dev/null +++ b/part/data/CMakeLists.txt @@ -0,0 +1,57 @@ +# install annotator xml tools description +install(FILES + tools.xml + toolsQuick.xml + drawingtools.xml + DESTINATION ${KDE_INSTALL_DATADIR}/okular) + +# install annotation tool images +install(FILES + tool-base-okular.png + tool-base-okular@2x.png + tool-highlighter-okular-colorizable.png + tool-highlighter-okular-colorizable@2x.png + tool-ink-okular-colorizable.png + tool-ink-okular-colorizable@2x.png + tool-note.png + tool-note-okular-colorizable.png + tool-note-okular-colorizable@2x.png + tool-note-inline.png + tool-note-inline-okular-colorizable.png + tool-note-inline-okular-colorizable@2x.png + tool-typewriter-okular-colorizable.png + tool-typewriter-okular-colorizable@2x.png + DESTINATION ${KDE_INSTALL_DATADIR}/okular/pics) +# install annotation page images +install(FILES + checkmark.png + circle.png + comment.png + cross.png + help.png + insert.png + key.png + newparagraph.png + note.png + paperclip.png + paragraph.png + pushpin.png + rightarrow.png + rightpointer.png + star.png + uparrow.png + upleftarrow.png + DESTINATION ${KDE_INSTALL_DATADIR}/okular/pics) +# install annotation stamps +install(FILES + stamps.svg + DESTINATION ${KDE_INSTALL_DATADIR}/okular/pics) +# install misc images + +# newstuff +if (FALSE) +install(FILES + okular.knsrc + DESTINATION ${KDE_INSTALL_CONFDIR}) +endif (FALSE) + diff --git a/part/data/README.Icons b/part/data/README.Icons new file mode 100644 index 0000000..140411c --- /dev/null +++ b/part/data/README.Icons @@ -0,0 +1,13 @@ +The icons contained in this directory are divided into: + +>> Annotations TOOLBAR Icons: +These icons are displayed only on the annotation toolbar that popups up +then entering the review mode: + tool_eraser, tool_hl_orange, tool_hl_pink, tool_hl_yellow, tool_ink_green, + tool_note + +>> Annotations PAGE Icons +The following icons are mandated in the PDF1.6 spec or adopted de facto by +some programs. The following are used by Text notes (Stamps not yet ready): + checkmark, circle, comment, cross, help, insert, key, newparagraph, + note, paragraph, rightarrow, rightpointer, star, uparrow, upleftarrow diff --git a/part/data/checkmark.png b/part/data/checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..33409fd0e6a61831d09adac7d0822021c2eda4fb GIT binary patch literal 1303 zcmV+y1?c*TP)ZDG}^$OC#93BDp%cP!F)(Md% zxGcd#IlaV%5C$ebytr6Vk=JpBc7pf`5pY*P8H2>QP747cL=eNh7WilrwNKt_F$suV z?%kt5LqDY$d_@(0%fCsETl5~P=^_t9KPyG-7YxyR-J)-%5uXSLC`a@f2HB#=9r~Np zVhDqjVp{N#?N;Y==%B`0ZgIIc5Zt6U>86@6`Fu@{`}794`G^QnT4{8j-a}mOPYEqt z!*rV-ZqUq|6w;*lMW5=-_wWWr8uYbv@)pHv!5{(5RO!z$#2$73`9@JeKkxE3?=wow zrq4;1zF6cNOmL5R0@h`z);qfP0_Q2=E~WO3C&{~Bj1jh(VMG{aTMi^4#S{YEr-Bkm zh|_@If-l)D|B~xT#+k6Nz!-U$WTiCs`>5wVF4Dvu0*F492W}rLO!1IujVT`R8$|?D zS~{Q7%LkNG!!$wrnU})#QGR8P1&vut!V_A_#YlP{6f?mk;j-w9Z2FXDk%uleS(Jo% zW|$JTi4aIK!hq;M5qTxwQ%iuL)BWVDfL#^^rNFcV?C=?3d`bP2IIUDs%{7L|MGbJe zpGpSpY_ViXP#YxTF%kSpOvEzAsNrMkSU@vJu)CjXh2(l!64VAu!j57M9l02T%ur9Q z@*0+eP&#kB9!0p#k}YAH1sz3?T#P+*inxI`#tEhSwrjAT#4HD2sI~}ZYo;=5Y`jsu(1dfDVn*NnR zE^FKpIvJ&#JR#`#Pd|eT3Vu}rtTqTc#PGi|z3$O3@-C4-Ax1u7%;Vhcd70uTRs~65 zo=v`a<+*T?RguT((fJ0^%fFM*@nlfMK0k`aYJ>2MbN^&u=*+kD(#Ll?iXi{i@;lb@ zGQiI`5)zD%XLtD)licPG1B$( z&BXqug+10R3CciYU1UL#j)?pRhS-v%DEYSk3{;R!9!rAV2FYpWDhcii!^~n@Q3IV8ft?iJY|DRoTA|1 z-YK&gG{|v6SYwkH^iU-F*umwO=?r}Gy(Qm&GD{h!ZTHUp*#!xOykv(O3Pm3yLI~3x z_f8uOa*4@%RKNWP_xx^UkcCND2p;^%?6!m)A=~lpx&#|1byEMw`Wq6w;BH~xFiije N002ovPDHLkV1nuaWX1ph literal 0 HcmV?d00001 diff --git a/part/data/circle.png b/part/data/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..767fb6ac6d3e3774b3beb3f6ec20027c63407898 GIT binary patch literal 2036 zcmVr95*redI!@d)j$0ZM1rb1|Py#9{jgTrXkhq|NqFz)$FA$(| z#h<_>H&6tDN(g9CMJcoiQY)afQ0laC$rrH`$8{XralGE$v*+;W)yx^KT_nyp3ZMvx6H~ z^|XmCyiXKfrb2pq1S0nE1syYIIwwwQHWpw8T(z;aLEKCqd-)4*k*=M23b-U$r0fpKnKXlD7ntBx;PV0;A;y41Z>M~b zpIcC;??s@4A99y7eWcC5vB>S4loDUzK|Rf}L<;6(RU3I9imDr@t`-Epi4p!r8#|b^kVVzEu@o9N z2i6l1*b#%@AhSeMmiXm zmVHbpUoLy=xTL+T*5L z&ocs`UHe4jN1CxU3sS2Fa*QKPIQ_j9Y{gMZ^EN!ra}*5zY1*im&zt3nXPFIApHc87 zvRdVsjUdgkBY8lAx1nuz>HEvqFTNqcL1`F&Y+*H`o{UK5tE(bW}ZENsbxkNd;H;llY%fh27 zn-m@6#!DYp2+5aYA0t?{1q&4Xa>lcphsaABC(uSaDdGIxj5Fgy&=Xh+7I038d6aDw z$Tdvi6O56|tlPyNj@y|DAqJRo8+?n}JYS<-Z4-@@76zF@1e`TK%g;!?1H!A>J=zAT z)impSi8x8zKsH1irp&DSrEKK^!OuJRIs!Ew3GmsEZY)~UoNeGX*dYgu5*cJS`}sA~ zgr98!fmt4A12_snY8>P;=Wmlj7hmOdQX|mIE{<9@=v05f2LfdhhU*BBQ8+|_(c7TV z!MAyXiUs!$x_O4h3_e*-0M5x+cV@u&Eo!Umtu1Wg@NCNzF z0%gwfDOwh&D&;= zG*e?6_p+02F1wE!UG(uhqXud(vL1dl0@%;+qkIR#2Pjq7h8Ij*El3isv0z8GlVhG~ zu2V6X76v%U?^!f(cfzfFCCgD@n5XGl@d_SZ#H;>o-&)OuRnxqgt(@VvMorItKEU7j zBUQ=;UZIEWE21F8g{K{5(&T<WrnB<+0-Ol=(B7C;<&;h&= z0)PvyoJ6go5O$~a@Qy-=6B;MLvPf4O_OF&D|E+&mM62%fd9hyB%X<0$E&m35(Q0&T S`m7580000YM}^Gq$2tQ zr6452OZ+JL0is1Jg0@tUl+aYBgcRH~Z*1W@Zeq8!OJn?qA8YSxb{>~cqv?+Aefkyn z!9Bj-**j;?_uX^OJ;&qq;=erp2MGvpQr3P*3V-J%p!(#EqC?y)Hi?Qgr66TYj>SuM;f-b09#s)bh{}AnOS-FJcI#Aoyi@D49@8&DhY7iaKwuXR zRJFEMe%5mns-Zd`%sC6MX5Y67%y|E)9uD>0J-bajnm)+|1C~pGyB7y)+dd!unurtv zapy9%0*IgyyOm#te!t_&cddtv3rIqTbO@+Ee510pGyJgdL9QGy|ElvE!h;ZjXPT$J zYCa+@Sau+65A5)NqOI~P!V7Cv;Ie4oyto(r<)=Sp>@;4sgWwS8sEFL<3Bf82Y*jQW z&>{N6$y<$cb{P$o9 zbtT1iB4Va^LEn0Ca@6@0SX+r&)BoE?gdZ-F<67pdywo{`LWz?VLwF)ao;C!^DR6wB! z3f}=jLORMGnz$RAz(ERI@f&QWsq4{50-gnCKFR=`$BPV=O6_gbt${yNel~I9?eQQgl zcn-iNux#@hUT0~(4o#&|%zp|f%S<@HKtB%S1jf*UpP)7;SQ^uqL=aoDJWwD9+>tjy zIVTAoV=uS~KR_S$<1=VL2;~saDKSjoGTvnO7{?H*N$|P?bs%%Y{Y%t&b$L@vibI7) zALFj>Lz&$veudNM;kD`z@S%cNjd&kAczpo9Y;SjA1|LE&w+E!9c$5sRhQHxF!LDIh zZgtiazQ*wyoj%VyY4p?BUIb{)gMGLe6Eq)%hH^>-8&E+y9;Zm(kB3PihA)wzmFpD9 zMSC5`qZq^t;VkmqgF9$$mMdp4z%_vYR~zwl?%$1PJ?e5LtP|E|{1!n12}nosg}@%& zbliiOr;`tJ$IqdQ9}d$SJ8&oJcpac{chI46S|#Ov#HEwJ623D&?exiZ?*1$;!jC34 z+Xlie8g^edpi!*lR0&&K$v%cI1yANy4LT@=9zMJj6>(@8of1ou$QgnHqrhDc!bl^= zSy~&*J_W@=ic<5T3aM-ox#$$=h6N#tj{y9bCka`&jW3@->68S*BryxUv~D0=0!2Ye zr{qBpQ%J)H1+uhuoUcn+NZHQ=Blgq47JLd#H1B9TrP-iPoQ}VO2~1L(^^hKjQ?C&_ z(S{oMau9HkWPuQ9=*AhAq03MZMx3Vqg2UK@W(d3F&Ji@qnRK2oD^Q6lY`|88sPQ)X zaS4y(Nj9Kn(ypghREiCivl$tdTe=+)Yr&HVdKexZ8Q@I7+6@wHW22aG3a%3)cME?_#NFfa?QwQ_}_Q&TgcK)!w zDX>%U=%ER1pkv`ILSdDI_S||KeUCVQ9xar>*O?FRFL6mAB;GdlaW| zOkUFG=aU0Q4@_7kxnRN?G>2sh8aNmHuXIt!O*7^h5*tI|eM01n?<9_+8^ftsR6B1R zG0#~%;xLL*a2tpLozqxY`Mryk#4dH$_CWUjB`)K6oRSmC*o@X~9x?}HjNlrlZLVYr zmaCmj0BS(_LZo`H;#<<123gV1n6Y^5ZT%(lIdj;CPTAmgXWuT=GdI!$vrNI(($=epMKOlVO?>- z9cQlXHzuM@-Tj{6E_+iGco8S$Xli~=J82#o>VpCN2>&o*@%XU*SM#Vjg0!=9JuBjCOTh0D zouT?U{4^b#Prhb!8ONromuTVn=Kk(| zZ_bZL@hJX}BHU1r`110h^HAh^*b!ze8d|#R@0AyBbnAryS9CnQhzOqY+_n=RSA8og z#qQGvf7)Te<$hJL5QEYtsf~Ry=a%mI`dsw|@um1yT(TF;B#c0;xHgu-#2|KaoNRQh zL&STI8@uA*{u|}utT-P}J6Kr0^=Z}fHfbyG#3zSqk6N**a0eVs> z<-c6!B42QxbCOWbNtWP?Ys)sG@F$1tbpfaCKi)tZ2}EGSsQp+gWb$iV;Vb#`0-y5< zXZeT^`GCplZZ(^b)p`9Fe-KW6Hf3a z`d~s&v!a9P`CSL9oq!YesoPB1BoRXpo(V{cNUl69j$!B-4^0LN+ozvCS?k>2oKA;N1!X>rvi;Q*|w$Xle#AelHiU~B5hr)@?HkISTI zwG~hSzhw*E>t8M+u;^fM^#*YVuw5*^82vOUBoRv(KA4=ho#qgZ@=-m&9(J;gP4u~U zmOI5w`s=HrMBD+Ci5Jg=7T)dqb{L)Mn@7l!Nl$6EU=O?4!CSmZzO$tgdrUq3iYQhA zZ&pwLXFxtF>Ju+e)A!9LB+G;+kQLAXwz5$Y#$Z9G*JX~GS+P{CQ~_(N#~n82l1zf8 z?^{fWVLit+fZy;oo7liwX1N4p&3f+ULg4_cy8Xj<+`5xYJQ13{Z!y74C`%duY~~G0 zD6t)R=EgkX04%%Rugs8BGj@K?zHcqTgpC;-kxL7B-F7O&o-L-UfcaH9zg9Ak>D93_ zwLGg90ESdWEGMPrjvt6W16a2i*!1?1n3s=ecf zW5WXrR^ph+Vl6->E?^M-=t+NuNNh{OMe!LGf3=IK1q`r9zOHnsdEoeB!bL7O-0`J1 z3wfa)V6aS{$KzztM^b!fUg&h*6Ju|tiCRE^(fNRqNy^>ydK47(9%;f#m`wc=GqeCn z>p?cMYV!ANJeyH`ud$JpiNXm;|F>%%Da6we+da=arKS$vJi%YaWGpv#8=zYA728p_Wv}@)fb@w~q-Ne^y1w97L zco0q@Pt^l-Bvb_ilPh0(boCI5!Lr8BelH;KEz(FL5`WB^^bOa+McoWf5-4Jj1`t9J zkCBZDSGio!Y4cBLSLHA20%9(@$nGbO;0Hb{QqZfLVZn=DjO2+rfH-;+t|m7$a9pcv zZ$9rWoPaoc#3x>J)RV1__~52Z-{fYPun@`+2C0A;de9wDTx*y111YYnJcI)fW)HsN zx7R#Xm!pe>VMG=|w83 z>iEPGidSRZ-}Gjv2rFIi#E6@^47k*9K#T5OW0mQoafv>kBvRx`B7s;U2*%raO4bU5 z38PAIZLt3tsjSoWRe}g4h6K6dh$NfH-=E81cjl4@}NNJ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/part/data/help.png b/part/data/help.png new file mode 100644 index 0000000000000000000000000000000000000000..5d60fd5758642593e7a25f0b87d922238cccb427 GIT binary patch literal 1717 zcmV;m21@yfP)+8@ha00002VoOIv0RM-N%)bBt21ZFlK~#9! z?U-9^6jdC?e`jWPdoQJT%1z~Bfr{KLpkOpngBXxYj4_xPF~%2PeDO(q;zbi<)WioP zj~EgWd{7~X3L*gk5wRfQR;eJDZE5Lccc(iu$IZ!7c5=$;tSO0!d?%BpoipeA{@?lj zlQZQm?&5zB!4SL(*6^HskVfeMNbS=98gZV-75})u_0qP*y~tq&NZ~EzJr_{T>?t-9|4`?7}C_wsq z*R0<|3Z>csxn^W~kZPP_C#OkpmTUM(0>Y3SVH>Yt8{#VMX)E}d41P{P@VGurzo3_G z?BfdU+#o;#0!zuthtC&0OOr7N6^kh*tsGFbPmWUk5jJs&izEmDi*hCq=LUb`5%%G4 zF4G8x_Kh_W&yF;p9H<#7bc1Z>Gy1tg1}LG0i8L~n5+rBXN?%AqnjQj#VNGic4l!&5 z$^pyVaxNdUo$K5Hh1s;SkV(|zkf4%2wub~b#E}H1HLdKhu@EQ+j2qywi7oVy#8*$0 zGLB_5=kC_hLXrbq%u7NI4M?Op)789^hprGm)Z@MC~dx1HHUMD*yrEJ1GwFJEz%C8iz+&rRXh!yn06=17m3&c6++m z!Fhh=ECCKHc$8^0Ak3|2$UuRozAJ3wEQjdDM=+T=%%T^iiY?h!Cj>KD`Ve^Bj|8@U-+7mVwChkix|sdhgp* zvygkS3BY8xIRgfA?T&+uliQFgW;2r}nyD`|f_fK3MVz=2FotHPGmQn*GZ;Ms!#gl? z_2I)-IW64BR32dpaiEwaDZQ2Ni~~?c6BBuonZy8@J0BO(OQtY--GOLACNY~ugl&^J zRFkA1Pa_;f2P6Q?5rm)cl>jJJUkRxwF6a(KcR`SkLAvm%q6`3=u{iW1M=JwnSuW>D zs18`1C$9pBE&?O9`8^OxOdrQNMTRyGvX(`m6-ua6!V1WM4wIR5XdApqD5i+3mzl;Xv@-$P470|v#G*Ux1 z*YR+VY&k}Nk5c2ndUw}b4Rfrfk(+Q3J4^lovk@9ul;cbtHFPGnyno46N%jGRx}0y< z)_r8xj?{!M=b46Mq%k9Nec#46_K=~U9@PIgZ4`E#n|ESNi&Jl|##Vc7f>~Db*4FN}gz1ziRyQvguB(u!#s6ZI++uN}fKm`@`>kPm-mlpFWa!w*-Ji zj8e+8R~#FGVDur8_zaSyU)3J~IC(9eB*3FsNx12>7!~3ihoVoDB(3N*0t<&2MZ|Hi zM%@Fc${WNT`j$bjP+(!J`tOJUsRSFPkHRI?@^mQyjbBu^Sb z8{!bB=%t_2^egvCpk@!@B@Z#j7~QaxY{*k0J&>110235*kX>|h8`A)ZLz=AeJU#>D z5Y*%0hZH0Uq%m)@jTFg{CmzTtm96w|Y$YIr)QQ~4BT@U8yg-39ER2m3#++^g36i)t zp#s9Iq|O~y@Q@)%y-88I20eR730%~LL#RLn>357z5TubblSGuKY70k!E7#j_!rQBh z4;Tr>m$c)U{k02(MNNnikP}>hJX;tDqnFe%6)_IlXOv;x*D`0!JPfww)Y!=}4KHaU zQv%}i7XfKpJyzI5(q_*AeJ`+MY#Y&0GOEBS1X*fH8Vcw>HU;eE=PSBN>E~veVlfUV zcocXeY4iwVPKyF|_}zTMB6nl0ZSD;$U53t$%kRD zY_tF)90}91g_*>1>6~()EL*`IHgFSnD;oWzf!VqO^s=8(Ceg;lMj@&`2lPG9M+)X) z79rUSq0J8?{FNg>BlD=o+)2VxQEfS(yZy`oE@1_efIbE3BAKQ@^ZdXGQVRT1l2NoV zE$t_&U4eiuCGBb)E$BXc(qa6)Y$K=IuA|Y2ePRkwUIB0b7f8?!QA!2u)kJnGC9*8$ zW-{hVM|aD?ZW3^CG&qT0K%&OAqfVs5H>X<{?7Oyb3 zp}iEBj~+I&ixeQ${dxfEqDgB3ml~4f7%c%5<_0}C1%6_Ev^B4!sbrlYp`Vh}Gt7{V z+VVnD$u1b=Ek;S{I&m|E)(6`95fQx_(wrfWu)LI3pn&8MIQs| zsfQerPXS+7gR5z=QA43vY185@kn#Om5Bo-|=>KkPWjrWs&OAeg5}Q&1kj*?Analuv6p;Yp&=-2m zBzVyI^PG>p2djax_xEU~fz#n~6t-_V66R^36?mYy?fIr9?kp@;Eg6>v>gnxT^LkI7 zQRRVF0J;3=H%~RZ93?0|9kNR3?2CFwU>UR zz=(1m0TBU$Rofq4b^m=Wt1|PvW+!oeij1P%_`e`VAyCZ;<&N_6 zYf^a-y7`YuWHM|n#=xEP6TNXV#R-^9FZ^$Kfx!QYz(0G1&MWmz_(LXeQ_=h4` z1W`e&f(kw`w6<7XP_Y`QHnv6swj`@Hq*a^8W^dATH~Y%nz3-VjWEUdE9$hPRr^4KB>eU#kEbImc_ z1X?0`{4GY0eBrKp=U@8UOacMrPyQpu_sM#|QYAhc>EhN#KKS4DVjrSRU5>?VuZ8Tb~UxZ5=rA1OeCbJ%zhC@hT( zy>u_!hqZMdBiNlzumIefRdP)G&r$x!gLHG6XLub@0x-1ZVdG%F zGj-kE>mb13!k%pMD}KQivbe0|qaABk)25A0O>l-0&U1tk2kA=;PP4bKaK^;Ijkq9K z{V{QPn&+^&RkvDAZ;G4V$(;=IBByzQhmz~$GZqFa7KE-!4xBc}_%#kDw3Lr)x z+59X&B*zZXZ`XAk4)bxoL>X7`bI}WIh_&0vATBRsC-&*5lo<%nWSH~Z!xSbr;| zpJ$%66mdDuQ#{IJfE!)y+ytECt)yWIP)RcoAoTuGe$QUkaDf2^u{lPGjllJI91-)M z<^Wk;H%fmGMasN}8_Cz^S)vPG=NUG$g9?-E)@%K3e3mLO!4u5#Mc#+<>qhBsU<)26 zWBGyv3Rco_GRKc;unU7x;08Q04DnYcf$e;l-qbU|U?-=z#1wt;Z7rFA8|mT<=NQsv zO5}LEU;Y~^z_Vm{fZnuA2wTWe=3;c$NDaacDbZ##iWYCNm98*=M4#pB9N>BCDaTGf zt8tQ+q9Az&BIm#~c~**6XOcUD$vy!*j-k(k&#;$Iavf&;nkMLBy-`{%UBHh z+>cUc7pp|e@Bx0r$3%OU{i02V3ohtoGdZe^MfaEVWe5rblR8yak`Zl|F4mJHEBbG7 zc^8)7QJzomO(~n^+uX+&I2l=zy{y6GjYT5>41B{DCWb&!74!f$Wj3G$CR1$WN%rIU za7AvD(Z3tT0C^^8;DykeG@Pdym`;rW%_1nQ&?KkVK$$&$?mE8VpZ+bHLCo~?HD=^# z5D(>d@CsEfvB`hOCy*Qi9n&*|Nfs#6WK~e6KtFR7$pzh6tVL$=~6_Ex_4X`jZ3=R3z#_Bk}i8h{yt5IN|vzez6|15?0S?j!3Hi&F^SZGl4z8xcX1I%Vc)`gv{Yzy%zP za0a|20$%8uY4Y4fh6$9PsaLt6NmWqu(V(u)gmCaWmZpFlUF2zzO}`UTrHD^1&pn*u zIfRpjr_Bq3{Xk(5E<#I?MGOhL1ziXOWpfBI$n;?)_^NU51+9h+ID zW63!&e9}L&q67}km%r@U|K8}AUNbKwwz9hU+IL4Qv~X}^F2H;EsoK+?bG4&hysp)r ze&SmvXlerS-w9!!vwyg~klRg$v=lMC)SB+xt6w?rvsP7aA5LcssNmBg|GnF;d!+cD z%pkd?n@LY@t@Y;Rqdy(~Nr?tRApT3K3Z0>sbzYDWO$n||@^JNj-4MjggNj{kG6M6O z6L8|;7bk!=t1mg%l0f7qlK1n4nZc3;`Pw?O=oP z51J@L9hwA)0h*|`iirZ!1k=`Z8?4hdpwLMhTf1)SLPnD{Bz2r7ac$qPgLP!xD_g#~ z!M5OcrT8l6`29WSecyAg;~4y(RRNIbW;eT7CAtwbPf}*&KN;qDaS9mksEPcqXKdu7;=Z=wfysk%#(D&WKmd@q zirc#S_qN}KQ5~>B>mWuKx8s;62By9qd)Xev!t(**f_*J(hdRE6jtsYn0E>pwxs~&Y z{MxyF9LB>&mI1U*u_vAWf|d@kZyr#J&xpI*bG!7T?gd;tqyk_|tbcXOwo3bG%eo4) ziL2u?E8MN_BsLbH05&HQ@6tLKm;MH!QVjBXBDaxY3OKkZfDLA11K>5X>O~i6h~sf> zh&VCTh|&PjYZ!faHK#Wps25!q-53~Xq-vI-z$mY>nn8p= zYLnv<6F8(eu(1L}AmjJ-v6yM|?TC3JD&+qvo=ea}=ckn?h#(9mG7-fQ4 z=ExIgJNsFy;2g5N!8y(_LJ`=;tt3!BQ2>2p7^Z{o5+|@f%}>ek0Y1+CoGXnDGsX-F zu3;+!EWze4{D#L$Kew`+Io>2gKSS(fFIUL14HFp#Ao0qB0x%fl9LH$qATb}of5N9OFeU;;^1QtRexG)ei&E^xz}}FxkKh{E`$mqm=^;`9YR) z7>ziR>I1Bcui)TfAVS(Oau)W>^xibJHi z9@*?8Dr6g0A*{yW1m7mf7HIJNSFhpQP*#)x^(xTVfW~9o!B2PxUUN>wupR)=l&P}! zA>ND2Fn4l{6fQPieU?!G($mlhtb^1E*6;)q6cHHc3c_wE4_-|GDUsCDTO2`h3*F^$ z9i2D@1yNrf!b{-yKrkiCubJm&_M;IC#CNudy}NT~OAr41grKEAaP{)lTljgt9L4C!XeIirmOe#L;<+HyCAv zF)lKT&Jdqwo&Ve`GRX+9GKEbmyIG6!5TX`<1cDN{CHpb1$D9oA?}SNUQWqU@w2*1W%Pvds)YI>?e&5LG>4I!T?~5aaM8`#E~Ko3|sWtpw|<-jzV-G8U3nk`c#r zNC^VX)57=JNTnnTD@G?-3enp!`W%SyJ+_A$h68CVQQ2GY6o_iVYgo#c*d1aOB|#@J zAN7!4=p5L?cDffZjRs5Mk_$_JbQ8wtiLi>2MkgK$A@pG+YkVH4!wO^wLYG2V?B@ZW zHN>J0BtZ|7`3P$t0LznZqiYZ3BM4?|tlz;yIF%WgDac%%X5n)M-I!d$sY1x(c+6D- zOuFtQK-06(p&n6%3V`VnfSe8j7{CkGwzF*?LWEf~fMs$uSuzB97{RvOSAvNK@VDYk zugDpZuFonm4@+ocs@xB=yop_qXZ*hg6~HO`!oRwoPwb2^s~;`KRdkSHo^xDsi{tJ; z@YIC@aHfq%=il~QbCXEbZ55q|Hj-TAX$m>#q<0w?$N#e0mHN^Aheuj})_MSgFf|V5 z@(@#2?sex89Bdpv14wJ!ym#i%$yJ8=d6p2O27#t|kY}9fapwVV3I_|@&j8?A$K!pO z1CK8|-?Bpt($>^=l&bd6GHPWfibw3{lzlPCfRePWhho{x!Q9G`WGrUtqNxZ)&vEis zu3T__VV_d=c?CcKAn|108rIKxAIZN@TR|rvXqF^1a@>8+eb&q3D*HSZ9x?y`i9^A? z;Qoq-iK8PBG*=Q?wx6efgRK5Q;$b22a7dI9Ks3!9WpAt17pnhl7a-Uw6GdVeXaG%s zkbZOr8_VB-0YD{!;?&gDTzTqpQMC^P0I8-lGyT8Bm00002VoOIv0RM-N%)bBt1M5jdK~#9! z)tOC;97Pz%f7QF27n5}jDtIy%J^KX&Z+-_o`3V#+F{pU)99NWpL=Qp~Jm^6|L_7q7 zUd&~Khlol@bd#O9vm1M+UuLGKs@!zh6iL}zJXCwI9{QP{dg=ea{?GGF4YZ=a^^aL( zO#<@lx7*Jv4$R*3xX%L*3hY03w)O66?^|zip6jH zk^#r4$WYir31rzY`wqu(Nrgax#C>}oiOWt?r zMG7c`iKLd8o=gFYfq~(TBnj={A+X35h*!K!9Z3#YZ2InlGL$Kh3Y;8*w5X?*q4H(u zeQHvQb6{9_c^R4n*?Z=S%Pk@hz}#*;shd(++dxOf_X{^tN>cm5SHf#4K*bVhQ)uYz!qN} zGEZYEu%$==D~f$X!)aD~XK(RGRlnsA(kKBVjQmNSR;Dz@C^o%L*RisZ!v_c=6uNI-|xOWxlTz=;dd_%f&Z>h9=f~!l|aRLuKcq9O0nI- zmmXfIKnU&$bY{?i!LOR~9zR{(J5%1KXyF@d(pjJ&0CvzF0gGRiv&pp|_g=5=MBqhL z(DTB^S%X(#pLh7}``tHZV;uZ4c$_o|6^1U^JhV5>l8(SG=eT)k^hT4n@KpdW4S@m= z8$!32W`Ucv&Aay2*E?_Pf+;z5053laI#>_v!M!a2&2`>4qtAEF=_yktRA>(`%mG(c zq2${62W-h4_?b`5_~PiiE|?rx?cv1)cGRy9x<`6Xqa#x?=8~CS7=2{QR{WWV7r!|@ z{Q)n!qK~gtomVVp7e=4hnu&u?cy-Gv>zv{k3R$x(D406<6apDXInEk#0u40_G^7!L gtTlNvt^MEH-&E4gZ*8x(kN^Mx07*qoM6N<$f}4Z+@Bjb+ literal 0 HcmV?d00001 diff --git a/part/data/okular.knsrc b/part/data/okular.knsrc new file mode 100644 index 0000000..bcd1213 --- /dev/null +++ b/part/data/okular.knsrc @@ -0,0 +1,2 @@ +[KNewStuff2] +ProvidersUrl=http://okular.kde.org/newstuff/providers.xml diff --git a/part/data/paperclip.png b/part/data/paperclip.png new file mode 100644 index 0000000000000000000000000000000000000000..b2bb3d170efb9d8f037db1ef89a08d3c8cf59bdb GIT binary patch literal 1741 zcmV;;1~U1HP)#y~xmUfIKnlo*p+T-dO4ktOOGVTIb1cU+HCNcJ9ffU8#aw5%+|5d3 z*N>d7MAOF7FcM)fT|w71Ao(&uU_u8F`6dMkyNCkUd*3~tVaghrwF|$QXP!IfJm){p z{O`PX&gDUwcMu{h=s+VdIb8XuEm^lfN@bNfOy^dowk-KGEv=iCyfD`(2rbsZQcX3_O%CI}*C0AzMGJj-2HawD=iQjfY!#-1qxC6OYFKZA_YP z?lQCYyNAenWGXX;OhdPM5|&hFC@$gG6A%DWLd05_c7t7L*qM$59lm{bnUqIN1rP77 zOSf$=1T6xd(XV{e#YwdeQNqMtjuo+-+JX@px3&DH(QDEaI@RpDA@P;$6 zvNG)R+!@w4{+YbYBqgY&p1!H^$QUjU9y08S^x`#?BQB&DL2NeapFEgXKlwYOj_;2DrcpD6Uf zq)D2jhXJO~mEMnC1-odE4yL!%OZh{aluT-il(|ujWZ(S^JPKg(uMd%HUC*H*&j8az zstpB-iy_bn=L3geb&K6a0O73|MJL&y(F_clxt?JMm&2ODcC`SylZ+u){24TE0tzM@ zj-iwQ$_TJt?~w`1G6IJ$xfO19)$I_kunGV((7yhVmbq!}Oo-0BHT-v-Gt5uuQpG-= z0>A=5j}05>WiG&w)y@;_gnP0aMTQu~9e%?4W2VR1e`u)tL21uN!Vf3Vko_&7*FwcI zotf5HWhtlFg(E*9f6Po%GcQ}?l=++%$=Gu*cWf`9(?UzcHL*~5D*1Ga6Nvj|bUEUh z@}`=}Q!^#M$SAfK&`_ph6%JUHcBJ?cao?sHY9>t0)Fb(3fD7nCL5u*U70B#k&}k4e zRllzK1sK>3Oa?Jb^$OK9`Y3q!Vv z`1BSy4;<|yqh1%YR8^>|8t4M!K=i1(pz2s38&I!{8K6|EUN_KR!DtXIs+Xvqg5|yi zGO>u+pp*f11HFOa2vLhwIZQJr@B|In>q5)q;-!SrqLkAkS_kYH_71;ErDzm>N~uf{ zv1Ecq2QUb@0ifGNjTpyvWiXG6Z>hcad9b~JMH?PYqezfxtg;4*M7~BtgaA3JTLJVf z;&Z;X#tTJm6Ya9--sds&^QYMQfqC`dIQ^{p)XUz(qQ;g-hKw{Wagf=k4(TGmau#4@ zk+G;fsk+;cj=eNl&Vz;*V3vDqd?RZAO!>fMg{1E`7FTaK>(+=h;eMAk&ySboh)44_2p5TxJ8tG&6A>dCo6abi220`n%f`;qle|LQK$L6%ItSiaumdCGr zWIhaA7rEcfv8*bls^5S0KPJbU5^bLR^fgNuCj2HooJdYR~ zO8=1(MHTZGkyEa)JdhHrNJO5L3!r00000NkvXXu0mjf^I|!6 literal 0 HcmV?d00001 diff --git a/part/data/paragraph.png b/part/data/paragraph.png new file mode 100644 index 0000000000000000000000000000000000000000..58d050fb99a21b5c3457d542d48cfa302e59059c GIT binary patch literal 2384 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 AHvj+t literal 0 HcmV?d00001 diff --git a/part/data/rightarrow.png b/part/data/rightarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..321857ab9bed81f29603e4c517292ff8f3aa7513 GIT binary patch literal 1553 zcmV+s2JZQZP)990;{e{?YaVHqFHvYZF^bX|WfzwWydEOF>aVL_rXIsV_b%BItwQgCJfI zQ3UZ#Tac;+Q7LM*qE^$UHMO?UG-*pNCh0a!Hk-}P%yBr(G9)L%$#w(2d!$UmAZK4%h0Hp>(Z4s7;9!HG2r`&^=KHD>mh!9ZRZM-ga zYn*6$bb_2;uRgc+Cp?5Apm@Ldkamp|tth=9cXZ^LU0>qh5x@c{ba6m*ROVW5mA0DX zT|2%zG%5cq2`Jd&ZE^R)p(6OEv6d-U07hM7>(Ot6WhYa*O-`)ub)5@jvNSO;-pSU6yUXb!R#nNu&)Iz*k{-e4l^QL90z3bO%=7$yd?2yL}o z6iZ-JttQ)u^Dg~(%FL)|3JVjfBtUf(S^Yv0B!Hbf$XX84gBwcJJX1O^tpYDH(|W4_ z;@n9iNBN#C_hM?F5FivFG*fgIFxf&QKX8hx>?MKzMM9Y9GOe+ca0C13#^rM+(brT6 zB?9H1aUtrshk8zOgk7|QCWR7V4TN0>$l)ddSgP+MYBL z?8RLJyv8-+BuG+4(r1P>G}A9xX(M2%A~bh z!eW?}!aP~}nIRdq3`4`p3lPjO%2`ZmAu<9AGFU5;0*^@s>6bgEfaOOZO%+qjk|GKP za?DE3V6bh;kq(zR$0gcG=?)_m8K${H>9G!zl3A_>oAG>5S~+G|LoHibj64IJCd5Xkmo6uo;&J(hMfHWQ>H*I7#Y*lkp5=6qU?pIm-zwy08%X!w5xH2fy$hacX4# zGBnZbGZUPFwIne?BFmVP`Ahu4DVkXi5$?4Sc$)Rp(d@TcYN*Ci>pS8;;K+AB&j#9c z_aU_g!mc)+Ko5bM`5t~_m>o1mxR2b5^=|Z-;AeUoCNK{o~y z!72d5oO#o>vcCpnxv{nF0%mj|TRh zNNu*-D>)VP<8!AEzw**?3e1wDfD2#|;FHU_!>t$XDkEtmF)MMSLb%TOwUd1xy!g(i zgUrjDTpkCp@COT%7)eroi(wH;FsKZnLJyZBd1iwID33R>iA&m8itEZ{xH!y9I(SRJ zpMi-bY4}`O2%oN``isdz5t2&(iX=fuu3{CdSb+Zk;Gfn>f%rYW00000NkvXXu0mjf DAS$;8 literal 0 HcmV?d00001 diff --git a/part/data/rightpointer.png b/part/data/rightpointer.png new file mode 100644 index 0000000000000000000000000000000000000000..af75fca3dafa7de6b5d509ac2ca6ffbaf16c86e7 GIT binary patch literal 1573 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/comment.svgz b/part/data/sources/comment.svgz new file mode 100644 index 0000000000000000000000000000000000000000..8ed0aeaaa4b232f32bf78b5342d1e4969d351b19 GIT binary patch literal 3922 zcmV-Y53TSYiwFq!MqNSx17mM(ZDnqBE^~Hg0PS2|Z(B!_eb2ApDlZeP)T-~UQsS8h z2eSy^*#&kI?7j_Xk+QXsNr9qcE5Clb?j?PBC0ZY2ITHk?9EkUHRaf_^Q`MKwrN8^j z`!^SpU*@Z;^X1~%0Twuz%onH2+4|`#cX=9T+E*xES3j<`SVxb z{oB#es5_>9d24{pH)$MQ1lVJ)U38-^>^5t79y9d@z`w4(9LXFUx9vwS2oe z?WaFI-L+iJ&YJ14l6Tx0VMH7Q9TOcji=(US#d`YwXmR!Rj%!=sK34*O<2E)}KFsRm z{Y9hUql@WAccVAzFWY|~96oT^@Aa&C&dXxHKK}m4?~k|EM^I+#+0HauubgIoIu_G6 z^Q+70>HO+Lh|Yg|aWa2@xm>M}u4k8RF%nurBVw=3`v=&ZonOpb%(kNA)pEH${`qot zcKo07cR!pi7gxup%Qu+0A}mgo9jO};JexU>?#L(-@M{( zpbfQj&!?;ZSWRc=Z8sgZyRg&c#l`%zO+LMNH@&{f=|9Xfb|uk%(r((T_40CS+cvYl zzG#Fbc+_TGu1>zj)BO3igO)Ar=j-be{Ptk*S)QF;&0AndY$s}Zkfzry~DY2Yt1P^V8yd-A?kiSM$~1^ECXg#ZOoBQQQ6B zzrFb3`+v|s?#mojzMG!EwwLWKf%_AKRqmVo`SZP#Z7iBGEMkFJ~tT>CA@>pYBg25_3j4=S`WDEhY-ox1E z*Vylgi%-7uK&Q{IvENa>Jqcs-*%|x&oPke5n0_hB$1x`Hr6?cAn8KH$d>mo;r6?cA zn14AbAIsR6lk$;-=^v4>H`Dd%{QWLt(7lE?TMiGkh=mgz9%&(V^Ozs`6EMsA$1C1} z+M#-HQ@gF_&q%HP@lKL4wE)h0RjcG)W1tp_2!-I2&>CN8{S37Fmqzfp8o`&->$5Ri z|Io~$5VG%K_Na{+arhw>h)Ruq_7YJYKAl#=Di5KR(CgFm0=1$_ZZhIku#hr|jd*Qa zcNeIk;~wk9Nr2!%cc{o@jYTNo7AQ}`ng7O|VKGs09cvK_Wrf|~jJ=SBqK!F|Vru*_ z&PX-Fld~FzHJ*Yq$A@vo^jrQteje=t2KDBFkE*P7#Oyxf2G{He0Kg9`b9R>4+d#d# zm>wQc!yGCddLak|_~uSx0Ukswg#3oY3Kc*!A6GfnB3#j7#4B-$N-U!yPunWW8V@^{ zK+SbOtsy~v$fX7YwoV|$2vqoPS`i*yPPsscJ9L$NTD-8lNPH?SMxh>OAY zLHYZa5@vWmVN?vAzz#F>7;=L!DOC}v@=d~AL;OaIz+!HoJ|=9i{rwZh4^fzjBSb2! z3ZmXpn2@oK3G*mWgSd_e^Fk?7u@PZ|?PCc0?l_+d@7{fQ_B@|-pZ#(^fA`gxx_9S` z+49}dbsmcc`^Vn5#Q8_YwhyeE>qjg$Pq0VIX0wCy*>ZLM>U{Bj=XtEl^{wISj}2et zGf|6I%^mL=zuq%GEH4d@UcOwmS
xAG+(+>*c!~8ql%Q-mX@S{iBQN^?cPtlfUqm zQAUOmq7`lrwt!TG9aQVh!C#llH`#3h9RzO;Urt}muU=0Zt!<8dgZAa`p50A-Y8DV8C*g>C5HYCbg|+`p!;IvL2_|5=Q<#+8&8Mf7AAo zUz_>&_U)Bc7+Z(&B_k_wqF6-_cfyS=goOK9shlOesS?b206I7h8&OGX9bTp zTTLJ@H`MecyCtr>dUZ>z%eR+rmb3XrayN5-F?~6|cy{n2$0j%=Yb(%A#LMaW^;hHP z4$s>1Puj-*bnC8#{F`rcboUX&9$3A-n4iplnJ<>JS$j%xwfuR0vRE$WoA-UmpA5D4 zemjsM+Iml3zFn_(vHx41FHRbv^VJp|V%~gWvTf>b6OOD78ifIb7SkU^~`DiEZUUg4&-z4H?4A~C^QINdvMP4~__3M)h9lpC^A z#Duu05eQ5Oi+c^j32C49hRGl>ss%v=B*&qKc=L`zUP+pdwNXN_31i`|f)aBiP47f& z6*Wtg6xm@AUCyX%!L)|ihUWNojwu|_;Zw6keDURSH> zb+54dq}(a^;=KJjkzs5s-l`+~hn%-?( zc*7d0sC$33P(?}%sz+^DEnr^5JG&~unDuN$K!dG|!)_)yr{+w-eI&seHRB*!L~n^z z9CJkgWCGpF6$CiFsUTB`CQ2Frkb6XB#7In>1w9#JXCUe_5m4Rw<1@?zI8lviP!m(G z)UQV(m^m>(G3(W$fe?Kjt-5of$v=Wl(25W{b*n@I2@Yy#f^M>Q)eLnlqi!bab|*1RWva`GN!}=f)zWAy|VPmP(VcM zEv=d+7A%OA7*W;gUB?Lyjl@)4+|%0%20L-0E0e}=;)r(5hj6DL;zUl&8+6l+l!fS zcozjZP}4hSswN$3&dQV+88~O0j7T7fS$Op8sj3Fhdqo=G_kkL2qf4eKRo) zQ=kq*afw!q=}ivaX8_dRh9HsGpK!^22$;~5OL<{6<9T- zdZGsI7OC_gH;LX72q7_aW#i5+MA7=%;VL41HEVUMS!IgQBIf64?v&H@?ofA048Rzn zuUit0O5L1QO`+@FD8`zY1fp?b#KH)PDJf|5J%b`dut$Zere(N*bH}f9t(F*u6ZJDz z!zz;(`})uyxuf&bb#%pBpQH@Qqwy<685yk4t%Nc{qNFC&^oiBT9<>*63GNvanFnW)E(njH{T z(LJL$R(9`e8B75rQ6sKg6LY3;>b%uJBJbHMs#i^nRiR?vN2F39_H2L$bbV12tg|!_ zQ_Ri==q}M=3gOy!HW627d(;93Xxh(dMh3M*kwQ45dv&NCzahY)i6LmHC047uTE8D+ zLghX>s(S8RsQK5#khLb3>m}&-Lk!V&7G zKbQiC^e8#i#4-=kc?(*tn948@jM`x&%(d506=C*7m57|W{y<^EeQb+LS<68jgdIPO gUX#l`x*RI}yW>~wpS)^+v)z9EKYQwWk84W+0K#Os$p8QV literal 0 HcmV?d00001 diff --git a/part/data/sources/cross.svgz b/part/data/sources/cross.svgz new file mode 100644 index 0000000000000000000000000000000000000000..7935c870d91dcc980cbec4e7a32f9bb65772e029 GIT binary patch literal 1918 zcmV-^2Z8t>iwFoZL|sAv17mV;b8{|pc4q*^SzT}2MizbVuiz>#36>hp_lIJq4-Hxb zXm^2afy zeATrHBP^K=@N9su{S9e+Td$gIJA9TMBb$5<=upX8^dRP(ODIn`p8_#$H&vJ3PpkIT zQ78&L7s@H6348FK)6BPr6d@kn%)7hm31@V%=nZ$ixV`IOab{;J^6Lra$ordp3A2NU zC=pxNe%xc1WaFs3&Ti5cbtX++cgg2vK2QGR*B`RFYLj_UrDgHe=O;0!9x+){w=F>_ z<8=OhSvTEuUX&iVN5;;ICM!KzR_BB7^JNiOAXZXbXEB=xn0EkO<$m7cb4OFS6TJg2 zwA!c5FHM>kP&aG`*x19lP`emJwOzf$_ak($0AnVDxt`Bk-+|yGTib0)zeP{8x~!Yo zE81UgdsB_(7u{yY-cF+A`E2e?Hb%AsK9hCcU*oKY&>{O(GN$31S>p#rhE}13(r2hO zE!XL$eV$hCUX)gLj@EC__8ndlav;TKal!lkg{VBNqfttN_bsRt~-o+xUFK~gth`4~H{ zg9gfT`(gpE_ct)C)nk#-ByJxCFnXr`DQtQ%OJAdG50baj3fJ3otUpiLnO7o6FPxgLr0Z{_-- zo4X6eNsZhR>nIzGQ(8iu)6|W`skI>9Y2{|5iNvO7f6;9C9I?RjAR*cPDw4HRAq_g)W%ce3=!6V z?WYvxp_feg_DFTro@O>O(n6^YCGcf3>H?VHKAHkeHpLHY01v& zm0D=e#Zwm=MV&qPo~Bi@%V-tqQd+N)aAfSi9nQPq5SxD~{CYT7-lPXEm+7tV_Z!GN z@2{QXrfzcI>|MIQMy}nKq(8^OF{&<%dhpZp{`M}->or!5ht98cy$Dfa%i&3I__cEV zxmgNv;zU9&DB;E#`Ot}@|7rnBr>m{HmiH&&tELHnGTnI0yZ>MhLF=MI<4Y1~FPV7fZ>AWRls4>#(<#O2&#h zB8<{H;tV!H6_0fo+fl&~&6y;UTg_t4Sg4IF*ckkr3D^{IQb-YTYKb=70mmsZ+Bp;b z8aYd-u*#TNYfdcFOk+$&Q88CxOl1k=OC@ZAFb61XBII!#Hcc>)*0GkBIBiTHt+x9I z8!H*2jgnzLh_Q~x(t-mN=prEvp$HPOaKI_ka|s>@?iG!NbVO@rTqF&0Qzv;WP#HJ} zL(-uW+6B&qCQca3F`sk&`5KLu@6c1uxqxwWW}8ESGidYmtJ4Mk&D-ETeQ&ijH>=Xm zs=E4$)fDHvrvB`QV_$!}U1Vk)DxnYo+nYlsC~|hQ>bhgw|LdZf;nDET-rC=k1wLky z(9z(hW#JimOu)==A|0+6^CC`3DT9c(f+UO~e0Q&FfFCMjZRG@%lwA{GORVqLPUlUs|DAn=p0AqMWiklkr3ZYMEkgx5z$q0i~q2}4+1{^1aqeXNhult E0E39C7XSbN literal 0 HcmV?d00001 diff --git a/part/data/sources/ghns.svg b/part/data/sources/ghns.svg new file mode 100644 index 0000000..d611f6b --- /dev/null +++ b/part/data/sources/ghns.svg @@ -0,0 +1,3106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + New + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + New + Get + Get + Exciting + Exciting + Stuff + Stuff + + + + + + + + + + + + + + + diff --git a/part/data/sources/help.svgz b/part/data/sources/help.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3d327df2904040373dc4b18c3fee538220b07d02 GIT binary patch literal 3098 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/key.svgz b/part/data/sources/key.svgz new file mode 100644 index 0000000000000000000000000000000000000000..2e3c749ab725f9d421a7b523d4239c005ff2a66d GIT binary patch literal 4252 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 Wy8d5U)AdjF$NvKq6d-xTO8@{OW=Jgn literal 0 HcmV?d00001 diff --git a/part/data/sources/note.svgz b/part/data/sources/note.svgz new file mode 100644 index 0000000000000000000000000000000000000000..825210ae2d2ac66df68f1286983b97a694ee4d15 GIT binary patch literal 2424 zcmV-;35WI{iwFoLKwUxr18Ht+UuAf7UtwBQdRcJ*?VH_m+DH<>-}6^+MnhD`k-ssJmx+^y`nI!sP7N z+v{oPOOh9pEIsdnkljv_jV9ef+IY-A++PX&g63+i%~R7Iy&UWibE&gYL$Bv@xG27a~uJ>?R*Aryq^BE%SKHrkj<_Rb>R; z`+>v(VxKMg#Ud@E+kRTS+#1RYY#WMF$^q*(md9BQZ>Nmmn~SNm+uj-djQ`dHYKF^a z9rMUUq)9n=_wn6eZQYk5F5|6f)}z8S?cqqH>!g@Pqok-^RO8n-!{m0BmqJ5hx^0!h<*4|)%WlD;uI{gr$>mkakBYOh63i!Y zd9}L#g#~AEGA{UiH8$L-O2I0QbQ0yi=TSW2^w`2I9KR&#F_ZR+kD01M`-FSZE%eI!l;lO~?hbDjfwsms2FZVX+ zEy&w=pG3R8Vw|hh)%HHT$`k%N^0JP~!M4;HoLHvdJRT0VSNAE?16}*Dcik51`|nr} z*X+PKeVC#%|G#F(-tV#VlBbJy@268dtxQ5`YJtju^4P3SFO)*1Ort(YXq4bcH%b&y zNR3GQMfx$1(qf$D*ZjbvXqvnNA<*124TM!lj+#Bq2(O%$coZ;Wh-?6+opg9NFi%eqSf42NsLjk_yCtnYjbR9zVyP5{r9(^8muf&#|XfZ}%srAD!5f+5_(o%sdz6X~eXD zF3Qu08Tnk4rvZcKqCAZlJ@1sK5_{e$PXuOuMqt-bnNM!FiOK4!Khz9+Mri8^Wv_1p zDzfC0K0N?gWq!iqt;X$zaXRMEa zm7W{HV>N>3-RsfFx}TaXXaq$qWc#eMs66#}KJSq6D-zy2lK01o;Pf$A5y(AEFECaZ zgJgAss|JBap|%aK{OCklI=}OiBMCw+Q6BXT6%<;gD1|5MK|csH`oYXVSZy?!W-cdF6bZE6fNe6M7y8lE9rn3yacdbvIU!C)fDnV+Bb9 zl+@6~NPq9yYUi`AJ$?|AwZw@IAklgmkZyLFIZ zR_>`6-%=MGWj-;?!{ILdqD@~fFBtYOE;62F98K$lDXy}4P}R~M;5T{B(dbX3MUrzY z!yD`wv1cok_Gq=+Q{FCrRL8Kd?kc}#8K)7VP~KRnch$4#GAXVi#>z%*%GEK83fxM6 zk>zoc*9zECRA)6f+iZ2MRAH*MVq9G-Mc@+7z^)VRIw_+#Dx-~dEz#?9sChgd{_EXu z+ZDjKW^?dmG#dUp%Re_yp9IPF(UUMsbdlX~s?{TTY&;r<%8N=CHO4Qce3o!>&Ce3f zNdKLWDxVGN0nJIu#Vlb#!`=G4ciWk9{&PJEg9d+=lj-z*aMImfL(u!}LpFoeqprvd zR%n(by9QU?UG61ob~C%q;$)R_yRn}}7s>Rz`yuE$PzS3{(3QtoR9>xDx#t^!$f07J7nmu_Ijbyuipf1%ekUToZn27Ve%#6XN&m&Ql5QI_&L*L^?BKp zhEkwew}-VRcw(f(i<`0``)@W$haB@HUrF~}bEq4fn-~$mHZeM(4JhSw54`Z;(K$v_ zO9LA3JbDVi!tU#ogq|XS3W)3yxh67B^^gQ0DMw8yipo^76twUXtusCTq%5isw6-;z z6bPifK%5kUO@qFD^aub+y%z!NoYl=lZclI2!a3#8_RtCkhLEGxHp5B$2=@3rxfE`1 z6~*Wq-NNs53uT01n&_*(K+ap$dD~H180D08A$6tH%(KIv&}h;=AO;@dd~Qj<2_2w9`%_waPxQ)T8vQ=t-fyGGL`#Rvog9vn;j}2#wV&Zh89CIvqXr1Zi#+ za%Zd13>b}Cb~6cHbJc956%;^Fx|PVwk&PiSC%5{Smcnb7gy-lG5T4GVx|vS+ZK!Ma z-^O=)<*_Nvj2k- qLK$AWDeSaG=fE5lq6?mLdY=%T4KDfrQ1Z8De)}JF<8ijUIRF68r@s&Y literal 0 HcmV?d00001 diff --git a/part/data/sources/paragraph.svgz b/part/data/sources/paragraph.svgz new file mode 100644 index 0000000000000000000000000000000000000000..f0668a5f87674944ae621a6a19a44bb8dbc388c4 GIT binary patch literal 4731 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 J1c(q<004WDGT8tC literal 0 HcmV?d00001 diff --git a/part/data/sources/rightarrow.svgz b/part/data/sources/rightarrow.svgz new file mode 100644 index 0000000000000000000000000000000000000000..e36c0b65869e82bcba0015a8a61a25f5d67936c4 GIT binary patch literal 2989 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/rightpointer.svgz b/part/data/sources/rightpointer.svgz new file mode 100644 index 0000000000000000000000000000000000000000..d8ee504b972ec134366913142c6389090ef6fafe GIT binary patch literal 3299 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 M0Xnv6R?k2H0FKcw0{{R3 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-base-okular.svgz b/part/data/sources/tool-base-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..c761eff1780815edb5c80a0c21d83f092210482b GIT binary patch literal 10758 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 E0G{x^8UO$Q literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-ellipse-okular.svgz b/part/data/sources/tool-ellipse-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..a880e3ab6e28a4c0e5f6ec8a1edf31c855d47ddc GIT binary patch literal 18082 zcmV)FK)=5qiwFq7`qWPV19We1Y%OJMY-ws0l9k#ZzpgdmZTSm$>2 zyZY3l+i(8zaJ!j&YW9cqZhL)UXXawkY?r&$dV6zy@zX!PpXQ6n;kekY7MtC+xxU!$ zF8=cEAKv`ibUJyvZx+X9HTk?gew_Sm`}1MBxN9bV{CGUxUCrm8KYyOB>&Mw{e>4Bn zWIE-VhfgO&`u!F={2WJ@V?y4+#VMX({WWE<5N|gF=ozXz2wWJ zt`5AOcl=)`-hP-JcK7>b^MUI%vu$&nfA^2?y27cMt&XcfGwpJYdL6Ctc5&Mr?iS1D zFmJz0{m<*w@gr}q%K|?(>zj|q9XswYJjhb2Q zmKfRfMYGwg?+(p$`MB85+BNE$+}$7V?vMX$9*)gcTjDtlCMdU)%=J3?xr~&*Ssg&`R?KIrrFN9@@DaV)68$zx6SeKt~rcH(mdSl_Q&am z^`_B*&p+;NoB8@UJx;3d zR}Gtt_V(_d54^FHs|f}EpM6r|Q6(&^JO5>#l=&h$_6zOQAxwAs_05_$T;zhA5q{FR z4$pcpIhXClWG*W+$70BD-Au7-t556ZbH8FxjoR29Z`pFU+3l|{zWE?Owc!13ziRev zkqm-HMLRxR>*Hguq0NZ`Vg=thi7FS1U8GuhUYDRwd>w9M^|sa9^JRY z$KB_fJ(l^yV$-d2*8_^Ccf0i#132#Qn_;#4^{P31ts)Ai@89npM)kV#&+9F(=d>GT zI$QNB(GEHV`xOaj{8x&wpJxXRa~kUAUm1VD-`)POZ%m*cK{?x-L#Mua_LzQHtox{H zkDj}gY(GAZKZ4b{Jr)h;UmwR`Tm9veX*$)OOq$!fuape5)(yo6-^1{G?G|d>9>MdI zC*PS}7pui_(I3P1iz92>HDyD5_21up|84E!&2oA5zq|dOeA|6~ zvszxU>AYPWzg>fcVRiqVO(hdTS1=OB9`ucBv&`XQgP(LnR?FKpD$Rd9t~VQ@`Z{B2 za$W~or!gPQm=74?es_s?v!H@pJd zMt+;NMfT5!<9_#Zb0x}eOod7vSD}TQ^|tvxCaNpmfbFXN%39FuH*5Z@ms~BF%=i1n zqjpxmcHMP)GTtH`uZ*#po|9po>!wjFP32pD2cR6K00>Bc!o5rZjWe8=Eh?<|qF#>Ds#Ns!hzq;!m6vUv z%0Jb9uT{tWVtW9svk_Sw_v?p0T8IY3L%Tz%_lYBVt?uI5-LQDPz!QoiC1w!Fe{F1A0viyvs z^rXQ5>h10?cjL`--TbHgJlTyMnfLKryYEAuI-&HZw|BgPsLrQ)I7~TRtn-x1r6XuH z(>bsWz|mx&=pqm$2NawGV$M=o)&k(1MAi^MA)2t-P~c|L%!B|@Hj*v_TQ^~CNJV~U zv&z7`)S|Z&pV?yfrJ3!3wrU3;Sg)cLyW|BW8LP1(>m!df&X@_t z1rwk_RR%mbwk|&OAjc{vC?y%VL8FX}bWutKA|F(gX#_ZmXtW+6kaR%awMax$ii6V3 zbb^W@3{WzpvMpxL0;*$Gl)T3@I7ZW1THq*HM~}LZ#fl&!`)5YTnRZ1Kha%(mHp$NW z2vkC8k!)wQuEp5-A}HE?qETOly8Vkp6S;OMCqzR$lgxfVIi(sdFswJHM8mCE^48eb zA{y^sNHjkFIz*FxA4HSRh=$E_W+e%tBySaG!F&RNij7&BsD=7N?L znItIGGj*$=qR8i31RYRt1K>lcl8T)#TCV^xhv>=$AmhEt7U|HWB8#2`d7cF}L?l_g zAxT(HnPMOyAwo1Bfn<#pu`DmW?zEJqSrC=5SwNCjj0sF_3=3J2EVX7Vsy|GGjGQCU z80;NyeuyoS5yh%cSY&uoL3PcZ=;fD*XsR>PGMg;bJ|hBFmb12OWD_V8CSGFDC5pN# z#ap1D%Tlb!`jQkSm1Q&4mGah+bjd^tB&*8}_^PHR$$(R)PEDEVvRCBQ&Sh1-T3Vu& znpTw9Veq`OMHHM}I&Ie{uPiRIqy{{B0#XtOs5%uC%c&xxPC}50!gXb2V?C`FQ67$I zlGQAvCMhaPG8HN+E2X@0Sy+IrvrOE$lYMx(A#reB^2h{;Dd9yZ_SBBBGMF4r&4?IO zn_tU_1oJ{865Ow1L_+vo7?IJws1Zr(3$a^il>-Q*#4tNy1fq`3nM;x%a6L0b7!+FP zwH@jZvxcqBRtygei1gHisLjYJF_Ni3H&%?1Z3!(puck}-iHVf7!T_08G*L?lKwjuQ z8$khPg3W?jOD01jhJm~cshG}f(^0junR?0$3w~rzcTT$pp&8mq3mHh zPD;ACJ=L*m))Sx1%*C#dD=4>kS#~0I+GA14?2D3_Zi9A_nc7+eqY_lM;y_MXQtvkN zx<@#Gve4FN-E2}?3LKg+vOctGGgcz_#nGy1V-m}%D)M`jc?MIYT_;;4M3|G+@t9)O z+x9YNlJR(*bVa6$I-Pc68;!wwK`}|IS$%6D8G0l;D0Lb)C9i6sA%{tIPf}EWnnMXp zBg+D1lTRk~ViLvbxH!&BfJ8I=0A~uFktm$*OydgG)#M#|wR}YkFC@`OzYd8$n}7Xn zkZ3+5QDn)~-w|Jf`6r56Tij(O#4Fv|g~JsF2RqL~85EKe6gYC~QI?!xi#5t+6g3P) zjseXCaUx2Fs~Nj=r*XE{^<5x{rx-!g3^=`o=>#VWa_qLKKNy&|iQSu=+tD#1H~TSM0=FQ{pxYaQflN>c|PW7hGZ}x?RUVL#N+WPX*XHvpZNzU3ELKC+X_I$ zRwWf8(ICwvO-@_sky;?b2_<)hOlBmML>L?*=<3s9DM=C+YK~+)Ow^h*LI}$(Np@4s zh>RfgMuxFB!&0L|%60&(c;YQa`U=2Woiph+7@=ZhUuA_{(HP&?sy>n$8QCVU$uh+8 zJ+hJ?=&=dXve!VO6xj*aBUOgtTFfX`X5`_sLKQ2+4ONZ3x|=>qp+p%xQ5pcK=GzXl zCu*vwB>NFo0Fflwj2bh>UcFX|I7vk>13<)$&jecu1d|Q3Az-elV~-gYz|&pI&oIYPvHtsCDiM*>gd#z>FM4rE;h?;nXQ5!mN^JJTx~(HB@U8XN+U< zgHoTB&EX*Mq4iGNsj^1xC=M~P=b{!li9@0 z?tnCnhdEb-%MV@X3cZzvN|J%Y)&LoeluFcTsv8u^X)j4Hk#cr2A}Xz4)FaytzG7Xz zl)C_*#8~wKK4V|6Znac0s7kbiRA*F+Cb9|7HpC%-EE{gUammb&jAGE(jgTK4t0UsY zb{q~DyE?z@NpT%?Y0E_i;XiUD=|v+0yde(jbbd&H6<`}=m{q<-iOuFWW=p9kvim%yKA>jaLS^S z$x9~`?8&OUJm6&4HS4c1fr+#e=#s;tL=`G|-{!ipo~ZKAhHMRHP+oSCExx z07n{8MqvX`aB`rTc*a6vK&SqT`t@F=WPvXDiP!zUD$^gWZS z*Y*(2!ZH-aW^$Y>huF#hYz{4wky1V4C@p%=>f|X9qfogl2{jhbme`9TL*l4QXBH4E zb3|6>$&p_&xZG&bTi|3uS87{Z)42AFOPm3 zHlm!`h!pho2D~URPzvhKiiZj0^$iC5aUJmD<#dozl4kTeyRd%yHk5bbJ0(0WlH69% zQoS-K$MsmfVhi2^lCy)tprUYW6CPPgt3jR_F}9j9V@hCPw4%*vcR0j)ixGiRu9s^(#HjB&^<;He7RBqOqP{X7&+6sm%%;zp zbar24nQfy#zb*=r89%*o#{n|&6&-l);bp9upM5d(D&(A>y_EV*kh7yRa?YAy33!bM z6-s!cAqSM*t(5dlJK+ji{=tc@&!r&>cSs2to*1d`tl1VEK=rjW7n6{A=n5n5Nn6(o zCs}zt$Ec!mCyV#10ABMnxajSXmHW{a^Vwxz78Uhs*G4(0?fD*+^YTCO01|`DLpQoPyRhsnpvM04E^9rgo^5IwYev4Bkt_R&(n@ zeDao}zqU%GD_TpFzUxKW7eL+;{C{;1OdFrnk6h#3VUe#qDyFM67y@6W*tFH0XrP}iV z1PUuDdEOeoP_Iudc@?iCXAy^mPIG7x&#$+z2(=fg@ zSeMLVAcjFJa2)WJ%Q&``cB$|x$OQ2|LWu`jNohH4qWe_YQ}#HvReGUtrx6jx2*-h~ z@c>MrZ4~lxb< zz=&l67Xd?F2*8NZlo@tl1a2D221X1*>KzyXOGz3aBiwRm#I}Kr;GGs6Vl?*;T4hGp zG`CjZhlhhB2J&=mgCoY_Mnm4}=Z>2qsr!?6)=IW}V3z((McTCcFJ=Y7(~MvUwg zdtf6t@v~ziV3o145qKsIsjv}ven&>&Z&% zWN$#h;uGB`|B*pmgwYOf zm9e@yuNyb5er(zB!e&zM4}anoJK=a+Pp#NfW?(4_xZ0?(Wnm8fMZW($u07^C z<0vrvkChg7OY3SCG06I^Zt;6ilk?WVq8u!JD>g4VvjnbzIX1l+J3zLU!A~9@pMn$o zV2pk#uLScqFh2>SlXi}hoLQ1CI6_2kO)SabKA`6ap?+8h1NcLaKm#4xxwXa*#|U>& z4r%2AtG05oM)hkmM>v6EdE5y<6ky#BYqa4O>6qbgT;2+W8@_-?00*XKoq9QWDd|zL z;#q&93KkLEkPT_!!Y9NsU%#f8{=(<|O&G$GAoQn#lMPFGuD}I3hm{ zNJd6vPIZWxrdxdRu`AxKY8wulYz>5=*1AJ_?F@KI#iNhODR_~@GK^t3PPT&zW zpp7~RoK3RiCW@N{_}&xV{+w+;;aov7o%DjcL^2lUhj_qWyrA(l&x54rdl z#xL^71=!Je*;`|EYq|9|EnzL(lu39jEPika`&-B)v~rb6=tO$t<}wMLJ7(Be!a8%5 z^a|;0NlU=&E|~;uIp|*~lfaTX7aqwZG=HxtlTf*b_qkpuY_dH;AvJZkM$Hz=BxEuj zF@+?Pkcpw-_s|y=O&7`}nAKe-VcC>Pz!ryIjXDY3_H%+Xe?jcXC*l^Iq^C&PpimQA6A;}g6mbrNvv3d?j7uubM& zDU{H-9l(tml?Ucvn<*t6BSnWnp@dF=85~3x{kB!N$RI5mYim6gXnqn(2>=k#GO2{g zZ5threHQdF^lTyfw6xB*M(oodr)5$J9R)nuVl0=U_booXn{?&KwhuWqlYU70LH!?O z*7Fwxj>AkGu<05BLw!%Fgv#nBtjKFy?y|bBP3ln-Qb6tkx1Ch9XpukNq!O@QC|cK> zURAzeluCfb>0wd{tCdm-g?k??0@8UXTH{SBp|I?S*Id#Lz8E67!HeLAy;ceUGiTP& z44_m(BV`5=fV!bk6#@%LV~=qK?vhGqWJ2SoNGicvo1_wu$zdy{5+26k{&EtLFUwad zFr+KmFL2^HVUvGR-H8KH&)XK0cvCLn5lHvB#U%bM%EoT2Tms6_XSZY;$5irqK<= zYP}mLZD8AqN?vdoa0AOy<;QJ`HglW;!+m6Z@d%^3#cKg>GaKWb6(AJyp}AiIS8M2P zfYc4XHIXz6))5wN_=~F1e<)3y-``qMz)g{B6++FUT8IZ^k9ey

~x_q)c(F{B~!j4=2}*5l43?c0IP#gL3$^QjV)lD7>j+{RP1l6;YOG}kG3!)~{}IF#Qs3B7Oabu49mQPK5yjlJM=`4s9Cj3wxAbv_ zF&m-D9mTZKrf@i$z!A$w)Y89f_Ty@je`JL*1>2R+Fs2~C#tvi(kSgv#=1F-VbJHHk z1cJ(gDg-il=cs2O6I8O$cOVnWbx4HCNqHc1(;modE1=<_$`)0Ua0D`2RK?4_s>sU@ zWU@@|+V)6h3xWb)kxVVy*rCi#?O5hX6U;O!)v|+`h(Zt6crcTta920MOvd0FfZ&bB z*UwN6^O6o4>^L_e2xd0)_jUv`@3->bq8%2~sxQn<A~X2`^<#*<8ZG-DgG)rT)z}Y3WG@;t!=QOn4}tzNh_41`i6=*j1 z0GA<@EDy6U;FYR8329$~vKwt~-=1UV9ge>y;G>(1!7VcZuXqzL9_zp>m{B?_+Wza{ z2zbS*br`)l3a1R~K;Mbd75PuXu4CY%472KUX&v5=ZtZoYP?7c~}xyk>swm zzJXW36m;h4?@1mz6YxqV!&An2Ti=qM`3QI=tHPXkU{5~YO=y7BY~Ir3G?(4oQir`k zgX&?^>o-TIs7)ny=*TPHd4*7C7hF?lP6aJuK8SA}>#W>dWCp1(*J`IlEYPt`9Je{} ziUXa|QbpK^v)_!osS)6!g+3Edl-Fl_EdW#&*cF*)rL81dFx_133xa#2K+@f=!ol*G zuP4!hn&m##>;O0+9P7&vO1)X_B2=4mxs7%a<`|5_{jW}R*E;)}^qF=5mL;jK6{lNj z;jTE%(OE0xB0$J0Wg99BccrSu&AwVSB?`1S7+sS-;Ayl#)y=sz0v*ZQ<9l<|AC>^5 zK*wJ1vO*kpg*Z;U)S)RCs9y2EBaXoIR_QD~KUjx$pTO~c65w^L#$Sa57?(OUj!L=l z4lH_k2RL*2@D4O$lQ-T05Ua*P3*zbU4gj|lPwxPTK;iHXbZXHK?|`6>ZoC7aFNGWL zK=;1B?i~P3sBiCpy~N+|-T_8X4)1_ax(@pvoU3%>9cYega$W^GYIz3)3V7ok0Fo~r z-T|ZPb`I#@hi||scMZT+;&u%*H3&Lg15E2!t^pvnw(T!W!5hy2SWe;a41k)Iw`V|* zSvQ^m5Uu9n833$lY|p?VwrAiV@eBw9?eGkM2UTu7159B(JOe@;J3IsT8%KbLT}2~@ zX8@qFdUyu-&bB=RO+^8xX8`E1a(D)sw-j2Qfs>MFV3Y0{;19>)3ji`L-FOBBSXOSX zhIDua7+t&Z3`o2jo&n@Z*`9&>4||+-vM=)$f;QqpEmz+F7>wiM8lbiOoAs6K<-r=X z`-FveZuZ%a>oI6QKb&KAUT9AcKFU`4U)fFwxxeH0;P@KCr z5?P8fSaV0(A82wpo{Dp)0&Uz}O|B@QIFniL!6#Ro`;q8Tg_}1#pBBw|QHSPy(rC^- z2ncp*&fWV~9hx&Q^;|L6rG(8GPhF}jG`8s;cAnXi33S0ZbZ4%PtvVw<#@MPek69^w zZGDZW9tKB%?4fQIQsa%M!pS71d{56C)wz2ew5!g{u-_b=8vWFqh5OgH=G+Mj_N^TE zB(Zs@&d{yiT!j%zb>`o*ovJf;lAYtKGpnETQk{EpC;BmT>d*SAI}2m!uo8qb*0=85 z3Bl!4cZQBDGN@b2R-FNSa&>rN7NV+d%^6ImeylG8aC>I0b`HouxR2hJ#SO-FwT8BpXHHt4r}Er| zSHE;;9m?ASd~?_z7XVaw*K2Gof;C>RC1?OX=Q=NCE)g{+jkn8ss1KH*-N*UgPYS#a zkNB&Q0`pRa)|(rPW3>wef-K0>SGzF!VqIkm#bFHR;eRPdv{?8BiPAx>pm`Q8v?EX_6FP|>02oEEFs$@h>sfN@35whnJ6T)_Fo zO!MRkxNZ-ksh!J7t{cNSTh+fc$#L^edjJSF25RguE=e?U8KCi(Q zHyvE}Eh(RRjeL0aZ5v{B!@agNdt?Bfe30uJPuAiEhdwOAp+);`Vv<7yuK1Ih4i;Iq zC4?832ZglL3HYpBH{}Z-+i?|>-ScF!@cvdhChlPVi+agnC- zccpxIZifH~gD2T%LC=G)SX{O?$A8?Zrus{&kr$F!k_U7A<8ccwLc*Yd}78Fiwy*2!;;?y8F#P3udAU*EL~o=6FSN}fI1 z^_R^{F>+pDmDSU2m!w$UB`gw+y}0YdU%H4|7usWSpCkb2{NZr3H#Gm~wkaV{W=}-b zRdo&6PofO6`tWOCFhMJ=Mrl#tRR;Iwr0P#pUe9nbH{HtKPNGFGCz0T-`gQ|>U*_2p3#=$A0e4@G0)JUfBCrtMzc3dR zqO?MH5{>N9M0XO6rR{Df5jcGALUJe3$bwCCC(*#uzI;UB-_08*5hECBJBdbAv(M!Q zqDHUP(@6wCSUqT<#B$tDB7nwbKAl9IR!@#84q!(3ZMlgSbvTMP?XIHkXx{EB68c&` zT}5Dt#U(U-ZtM03jVQRv!&@X!xp{MSEFZYA{DP;7l#Sk(oHsW|>|4@ZkVT8y{-To> zWKr5Brot?WUwdG4K^B=x;vOPF7Lh%k_O7|#LjtUw!ml{|MI(3w#QjCW!5hn8G?t;c z{YAn?+wLO1+m)5<-@T}??ri?$0xiOJh}$8=)@-M@2x!p5c{G&Lxt&F943`cIvj|qb zeMLeJZrfRO|5cCkP{DJwOSw->RF0+ROf(}5p4$nOzQz#WF3#E>EE>Jfop?tE`VUbw zYP;Y$107yAhsqwESy8VDIT93V)6(u?WaXx|)995SvaS+@(}UVUh2^U`>F!*xtXL78 zj_0_2t4^B&4b^E|P?vdE=h16(ctR@db(R|{tXoGpiU6TjMM@Awsh-Z;SfA=S$IX#y zWA^|WKyF@tx2T1d+HS6{vIs1TliFCR%XyppPR|FS+a^!-K%95m6nv|Ucki}2=z!x& zb`d&m@CpaoZBlf%iXD}1JE~_kceUIEi#GLx!8T9fKG?4y%WketcT>}H6RbP8SiI$? zu(ZhL{$5g2xOf4sBT?KwgeeHUssAOa&+AUkJlG_p^7exYPzsz_FRKIQ*7sY=yKdec ziHF%Fd382(&rva9-Pw$Yi%(r?_Aj*~PVC|IW}LD=S{B(qrY!Px2)VzPQ~v)7GqkeS zUg{bhb59q57u;bXzpzR~jq`jnzgK^>+Gl)Bwa@D)Pw%=)lnjS{tuR(&-*#Cgxsoq9 z6$xbTH|&oH;NpX`_c4k8uVekZ^CFEAu6iNhf31x0JP9vSr*g@_OQamWS@OkvG{Ja& zOoH+2kR|WALNSn@8ZHGi7<=J)`v`&c^4fE}K({ZXFn!I~!|J~MTybcHO zzH6jRyo-Y>z`fGt4AJEFrQT7-3*L&&*_nQHfj%UIX}n(G`o0S!{B9Nvt} zjr3q3bEFRmWRBM>YTk8)B9Z)f?PNq|(FHPwOqJ{UjB<( zeQbX3Gg5b_so45++clCC*Pm;0-by#VS)J|35Bm5<{tzGEcs*hFeU}KduW>2o12wIT z=h|FUb>wraH7n2StzhFRzjW6q0#_LHt?=FPm1^&_m(ATElJ!f)>q_&IS2aJVM-fV&DgC2!ZKg6Rj zUJp0F?*frVQ=hL7FkSaPg1@>(kV<&oR)`|_8QxHjYY%!9M*9$t!gxKN^{y+FD5z?e zP@s?z(s=HdOZn?^uRdsv6l-`Z2lr@?`V;!c_!D0DqrdA4(Hvp6=V}6t3wntcryLC~ z#)wz{HsI{&+i%s8dh|!V3jJfe3a>lT-*uV5-fWlBwLm>jyM)w12^!@JG7q{@ctg;! zF&_0RjF0gvyzWSU??p=EilBifdtQ%{a_8!0l?ZRXS>nT(kNOqn$M_Xqccj1f3iU9r zD?}sA`CMfXbni3eK+ZXq`EEV`z9o9pwJ<-#wJ=}zqrdMGRq{H1+_54-~G{b|Ag&97?u`plvqrd9{3Hj~5=wtWuyl8ZkAI;RR8L}jX_qU4U&G?{a zVa5;fEX>#4=sxOdsN1n6G=% z-KbFE!h$&8~`->UL?<_BF2Gk=JSVZQE8e_wGV_rTS~K;db)lqLd@n#*(0Ph3Vh zv^O)1W`5AgFw2KH8RqLA_4i&Q+l?1jH*j(}KUcfKzs;rqUi?6605{&uS2xRpE{0h? z#KkaQ_o~0|B2g+iuX+1`v$Yg2+>Sc9J}((s%>Vr;(SwF+`V!tEbd1soWKH%!x-?LkMwy|3~8R_S&B`una@A`|_ZrllIP=dmMz z6w3=LI2|{hX9xX#i}awYVYZKPHN5U(f7e9A0t3zYq(0J2pCm=t2Bl=9(6X1k8w7T8%E<7;@`yZ*jwL|w|bu2KIw+$T6_ zkpLJl74G>W(Q&l*`gYQ2KI&|kALDFz-M{{>iv%1{?iZDT;_n!kk9iw#^M1%0 zz3ydyZ>7Ox%r!t!D`+(3xgjf9n{tg&pdIEs-tH*H$NUX;<45=#Y*+rz`Wpn@5U$!c z>k;N9(%03lr(fJcAfB26GT-bprN{gYcH>9*8|*dzv;Kw==`vZa%LJzN$d}Uu#9PSo zd8VB)&eZ1{E>nKY;b1p@gu}sJ^S%y;fBEM>u7BJjJFK@HC=S1Igooe#A=NtX5gtJ4 zvQuR$hX4NMKYsZ9&5u9*_}`zu{PdfjfBEv$zlr?3{{7WozW>87fBL3vk}>`MyMO=Y z%TNFD;~#E+{C|J?{>S@Y|NQ+gpTGR@z5VB#vVZ%-cR&B>yDwk9`|I61_|>Q2o3MX7 zzvU0#|NQSi*k64ABk%dm=O4fO-4CC?`rUWG|F=Ktec$}}`7g(8{$cewX{pobDYmb% z)XHi=o=OCLKZ1e~W-6Z&xC>y*C-4%|X!TPBGb*<#NS*wh~LAo;ixiVfG}eQkZF3Y zKM9UJCIJ@AN+MSq_BlaaMSK24&Q~>6BRx$}7Gta96Xh7A$59y%`IhREdj1OFW)8IZ zJAbRR)h#CAZhj+~B9Er_fD{^zlzM#=XnVJ+jRTtOdX%3bc%;d!tX<02LomXPf|*6>tb`hud#}IoKpT z(Qc%Zm+*-SJmXlQKM5_rr|f@C&v5{g5E!G+nDmYOaeHcXdm44}ZtzI}J>@ssD?-$X zfgUQoJOR@jY#nXV105YfKLKz#RY1rXxXnc>{5J8sPW`d%u@U^&T6)Yr@R3`XJh4n$ zN8MIyoB2tWKvt(iJ~||TlfWyoi?M5np@KmH)=n6?luw}B+fYY*n)Z}5vhZXlU4#P= zd6R52lOU>r*_G$RNHm>LZsy<^-MN%gx+hsy0l1>H=BxY+$6BN%hpw2W>y4jo?x*4=K?mWej8ao!;KnR`XLLC^>CVPvDqkd%)ngnnyA*AUMS0 z4Nr|-W@BykL4Bwrr7f6owh-(i?LF*(F^t6~kP1_2cHBW;o?TF#_N#Gf&_#vgh`?cb zn?0ot{bp-q0>j>IlA%|PJhohg9hU%9P4tD6oyxcI+X#&oPn{EDjG?{w-2yTrL#Tq> zk9-Wpfmj=5U62IE9>kfr&ve*8{d%Eqy+=L5m=cQ+U zgKLciPi}I8&rw^1F$Kxru)P_#9iawT=?h;i8CFU2FkZ@ck5XDu>oTC71JFQeQt-V8aHyN{W=)PQ{oe9>8pKE#fLHYa8kFM8k4nX%r$8$DNoEaU9gQy?|J=Z z+T~nb0PLBjIV5m-?OdqS!ic~mFvw|KrjHi~u8xNqy77&KEX-AKS@aGzmdrzen$<3D zKnr#{ecJ~W6M{CK^z5<|9rZybheBLkzUz=9GTZOx!m0;uTgP&`;XJCJ4I!dU=zM3y{2#j?YP5(@S2>JHiCQ zNxG$Nzbv?3Goeh;$PM`!XLMxSg1CpH*;yJ6soTj!kuqdFp61ZNwVM?3gHeoAI2egVx33GDEb z11wo)Gf@t+;Ob@{Q*&$*3e^H&M;gE!4IHok0UkbXXW!Edm4rYHQ1zdNMOgQ1D$*T%La#(41YzjpoQx>URG%KjZMZl{l4_WO9X*-SrHZcd z-xN%7#6Fp{B+oRtvQ0brZQ9W`nQCX;#yzL>!66OCrW4VCKe6+Y7SSMhqD`eK?)-H& z4mh;UO?T_kp@F|MgEfffni6bhUcZ?%Em`k2#g$=CY&8rf`^^-vC@5tzdrhg2+Wn@9 z4BP7h{!F!qNwA6&`XWN}_5H>xwh=9!l1!&UJRA{QrFhKOz9G6~l(#PO@ z%K!?RO>FHtJLt{Go{%sgJZoiqZK1c30umX19YN?og6IHxiLF zV?k$DAeUf3u{M=*(JZ7v(;d)DXgO++PA|-tHYC?G0E_S-<5mLA$JR9^HHw9qUSe7Y zd%zU_NzV^=D1iW8-wG{=wf#ak#wa(1Ctdu`G ztd1#vE}dOX4R2;AO^lvUja9Aoi{zP?>W0)T(WlZ*zkRlRAUp>X*Cd)Ly-%2{jL+?Q zSd*<3RgAKOlDt~|G+qi>F)eyimNFpFMadc=V`H6>JN>NNZ#4!nsz_6f9-p~ zQswwh9)KNd;q^?WPNHVH@@z3KYsZP@S= zTa;IuHj}D8sTf0-HJ0g3H0|8+*8_)PVep*SE+%N(3?$N*2F?df@dNvA4c+!(Up^gE zR_M6FKnp%ajz%-1!@CY;Q{Id#PxwmFm@0iBv>X#*CRWCec92b%v~@RioQ@ua<6u_B zv)32OtmbYpz*7xP0+BJg3LxJp!u6R z+dj>P%LWG%D`Gsr47ry+dQHY0Ss!hCCJTLh0;wHyk)y!o&)BK%GcAWk0q95x!*pT- z&kEYB<2K2?#azrOmOwYDhA))Au2sDl1U)?JeBsT@I5a5=aC?Nuq`Vq!*of7G9v7YQ zpouKBZ!JMRm5le5DEwV~h;)Y~>9)Iwn?cjj2d-vQtdc-#G0trF(vZdET2}LuZ0bnH zcF!fPzEP&+BlJ4`tST_c##ReVdCEIsgPQfmFvQTP)cSo=w`k*_I5x!2D_sn2U%PVv z1tWhFlzD|?n1)t@X(GuFcekx(zrr9f-itKFY4UsWX`JIZyxX_!HUZGv!4KYCHIr|w z)>B$(T5Z$!&IaG$+!HrQQENm~AV8TG&~7NpCsA=&sZE$^k+n^4d4;v}ROy~%nqp_N zZ0ZO2yb1fYt|lk;uK}bq?mAo=bfpO7)vAAaG?uEaH=}gmjpb9C*;|>g@UTw=U~k5n zi+8Xx4&9z;RcbqtH)9XmR%6EOn7OpV)sqShUge;%kMG`BfVvU6f=$Jl0;iAmz@P`3 z?NRm702;foZ5Am$!7Me#woi9lWBVJm%u2|F;w`jH5P3)B!x>U&w1d$oWxoz@D`qBB zu)|xZKMslzD7F#Y(H1cyVNq%wpN;>bahT>hi#8K8651y-vd@2Vbr#WOlUOT_;)X+;ni48W1Os?tqnZUEQ2x9e zg8iww;zWBxR4p%mKZq?h%xfNqSnn+7g*yN@inmqg@ zA6=}g^PnA%gcsOWqebr;8cUUXN6rq+K{ZX1qahO#Ni7K&zapfD+{GpW^J*axx?+hK zA11kq_lUDYWU>j5it#ybeA>+{#IejwnziRh>tlBL+V~aUf?D#K*1@U4v22^F2_xOq zM*I7hK3d8ZmTFjSkoH_KA~Vf*Zxd`F>CtudUNs9D28W(#rjp~rXJejHt#Gop)#=IP znXL}L5vFXb6^OBi_|l6R56fs;R?+;j2yzw?`LHkQ-tyL_cQkE+f)_}f-4-0Z7L^*w ze005RJL&k6DkT zyV~lIZMtv{JFIB}-rKU825R&8$>CgcSq;xjk?1dev399V6|z~cHe;p4fRFISTiK%Z^T z^5S1h`6P-J>FGw9V`a-P4`0Kh#;=7RCmudKZ#Z2VaXpkZe#??b#G~z%QBAs7n2z6% zu&>FKC|`UtoxnB+u4RhDs+z?&1+&$*)hw9Rm)LSr?=rZL~4$eL;M#%$ER z-ae{(EYystXvzeA>WdO0o{+LsV)F}L9Qyzgf%LO=k53otc;@p40kw)1Yj|z%$F<6)~}2 zsb)YehS%7M!$Y3Q8+oGtZ^SIsj3s`epExG;lG5O+dX@_QL8LTI69HT2H)DUstX}%! zbrMV+!1z^1dsAui76H6eqh_;(E(8>f>H?U~WhThYS)QXak&6 z(PvZlhd;4Flr^tPRoZ3HZ?19w|#h;$&--m z)&cV~7CeHhnN*BvJZ2B(CH&>+(H1hEMFfT$&7v5C*O-xmckiWFFNJ%OGhMY|$lXt_ zj!dErN(A6=H2+Lg&&-f;>16-S)-lNRuZWGf^$|18iqbCxM8IYSNxty zCX&r>o&G`U4L$umCV*1b=*h3C{8n%_xyZ63-kMvpy((73bbwZ&Bm|Ql^mdgJmS`PK z(@@)DHlCNhTdJlS>vT_8IMXWRA*9zE;Rc(KBCWz~lI}?v05ybLDNfwczPGLn6+3{i zZ?i0I3e2+B0mMTld#qOUDfF49Son~WN{ye0E!b|v03|$_Y0j!7l)8RPlx~+7$Gr_I zQfoTDo2u@)3Dahbkd(V@#=z)6EzJ#E;0~0Bjd=HH^oydwUn6etNdeYmY9aRfume=$(v(|P zf@d)48y0h>2lmvfOpX*WLgE=+f1E*c6SFsd$vfyXGqEt2Mm_O6C=}IbK~LDz40V&u zTC<9imADXL+QLeh@!-KCxoM_NI~{FsP9^yW>_$(pvah4H*h?R+9cT=UP^V@XkeB8D z#EQt;2R5Lxj;SfQJV5S76R|8sms!fo1KB6OiAX@p_(6lWhH<8N& z&CW6bMc@U~KjG7E$owehjR`36wJD9&js}kmcz+txVCo#LZf8buB zQ9Ya^M-tol<358N%N_KwNVZ?lhD|zkwqMch?bW8OPXA+=mT}w0Tp0iBV%-WeSIti+ z%&X%*Cn;ylqA6oRIt9)VQ=fwvgDEa%duRy=#8(z|kYAZzT4)^xj=Tvq#p05EwtRZ> zGU0GxGVsz5jBVqlk#)ss$^5ga>|IF-~I6ZyM@T5J#60w{*aNogLGF;PJh#=vo7 zb1?X=lP0A}FD+q}zx36b4LGKfXV@hZXRiAr%#72}kqNvTELtVH5^T$446v(AJyTSY zc!MN$vA-;noSmr%ckm3&gw)q7Yz=#S@wIC>$wbZcciR@yDZx8M8sXrfg#2tDWC`Bs zDdsk-wJR?&fneOo7|pocvQLrmZrt?~A4De`m@s3+fxvrAAF$bc@!g7RqE6W{)ADva zl)KkzCc}%TX590Uz$Vrpr-D#E@oz=Z$+5_qrU?4PC*|UhTStZ|ZE?v{qamPDHMk;Uq>Vv2L{k|@oJbNDm7)iGg>Ng7HBtej=71)a(2xj!nW-dMi!|+$WkiA^ zAHi>#jETy};3b>+#n0Asbh(0~l4EVCDeTUJjD=r^QZjq& z8c)n555F|>XA9hLz;^jdheMLuddS^t{6mc-P4}S#r1GXUqx9o6B`GScIFeqy8e|5t zNTxECm4l%snsQ)jdjwR07vH@ycW`U#=MI2}GGItYGWA`Hj9f5Pl=2KSFqL@?!&CYL zd&-or{^Y6pEB~cYywRCrTPRZbai|vlgts)JJMpC#Ydj=OC7P3?GQse9CPIRaZCW-{ zcarjX>Lf+$$?Xu6)#P#*gUg&>6#3x3J|cj|`>Q6-L@L^fy}cwK5yr7e(Dc%)SD#^` z`$0cX99hj{O3{vDQp&mZv~mmW^`26nGoBZ;Bm98TbK=98E6L5|zNwG8vr`wKT*X0h zneHU0s$Rexhd6ZKFl%r(AjL59y%B=v;SKxiAs&@&o}&8KlY|#A_P3iWcPijXclhl;bBuD-h7+9i-=U?MhRkl1CbCG)cKF0`?<* zOT>ZFp12&q8>@xM6F~Yu* zK^fr8K13T?Qs~mujN#uWr{_!arR+t{`V7TqEGSszxzCyM5FcoUm3j3C%90l;*?ImX zCpd8c-Pef4`q_!SB;N*;*b6^3oP@p#!L*DQ-@KBROsgJuC!DY|6-(I#NKt|}NZF}t zG_eu;1i)&tg)~99z_UlaO&Z(b@H&sC40a{mqDt!BgP(}iHNAnra8{h3i1{?8=*1+s zb0#-Z<1(t=Z2EM?VL42d>qA?@tj@6qZN_11KAb`R3oa^?6>Hcgkf&ndp_{DowPvpt z4}52Q*;#iEFxr)3k9p^(c;YtGZzPUQFIh3`c>T4p>pXoDD>-UZOOu?ER;7(eEq=36 zo35chrmXFgvd_)vYQ@=Z#i7Kvn5Cbz_^@JSa2xA0eWm$%F)K;wr^KZlB~K zO(^s74`g`Kb(#PBsPWs4sUzCsQ8D>1|N6sEfBAoY`spZK{jWd&@XgQEk=or~KL7mr z%YS~pd&IuqHt1QXe%m4YcRzgh`+s|>Ci1LJyepE7|NdW>ibxefJ};j9-GBV@%d@`Q zzxmgne*ERDfBo*y-~aH}Z~o7h@4x%Of6;jCu z`metK@!x*7SA71;FZ}!G-+%wF-~ax*U%vn8$NR^A`TWc8|8)11|NPFb|9Cw4m(Tz8 z%U9q1`1?Qo^yQnMfBEjqFYA{dzW?Ko>xaL5`Tm#hfBfTDfBxwYpTGIx%WwF;um0rY zvt|3g{^@`FqI~|Nz5c$A_x#z}@&DxtB@@2>n+&}n3H_R5a>mw!G7=pXTafA{6P>nHFl4DO%SUqJ6a cwypKQSHbST{PWNMY5)2E01>96Z(&ve0Caj*TmS$7 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-typewriter-okular-colorizable.svgz b/part/data/sources/tool-typewriter-okular-colorizable.svgz new file mode 100644 index 0000000000000000000000000000000000000000..8bb05eba3a075fd148a425ee5ffe712fce00a292 GIT binary patch literal 2611 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 V;r8m9{`d3t>ff{AnG???005_~{v!YY literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-underline-okular.svgz b/part/data/sources/tool-underline-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..3aa9201d0fdad013c65884d4009183c26baf160f GIT binary patch literal 18176 zcmV)8K*qlxiwFqn`_xYW19We1Y%O(eWMy(}X>MgLZ)(@}-+xy+s>Vwo<%{HsU{ICD~YhO4uv*lqqYNlJxqh62Jc(b@& z?e7*>tNpzDuJu2ymxqtCy{;(yxLRL-JPdffyf~8)yJV8$ZUpDOVwjnC6m89pivnvM zY0*(L%k33Lc5!yI-mIqYZx&ZS&AJup8{FO>?(Pr&T0I{@a z!`*gwn0{E_tT^oX$L;NEzCKL%^M9&5*0_0{2iC#(GT+r_o~`tQ}%VY{1ef4aX} z?B=6c-fga*ZTn$)C)(iLEIwQOI23;?$PmR z$^|z|_{qn0WY(j}xf0GMb6uG^7DNB)XNo;r{=8m&8deO7(Hgsx4ZGUjYa5Utq+fbevjuOt@h>S`SSh8#d7;ew)M2|^LBeHpJyf;Z(Tes zzLNczx;XRMl~SIRN{6w|O!UTt(?U5D_h8cL{bqd-wz_+GQvH6ngTT$=aV7KCU){P7 ztkKsSF-QMx|8e{2dWU8Hu(;{hx$gl*)4T0@g8>|N_p5QW`}K0Q|58O1PT#-ZJ{;BS z%Rj9*vYyj^l=;c3H;Hc0IoK~qK;yqqg#CPS&@iX5ZvIX1cf0NF_q&w|=?4(b=6c_& zFVCKkkBIdjsrKl(U&-#{gnYELGs+q*B6jI`E`#Yf-6 z_UNDv z^B)fDn;RwiHe+pa-UiyHF(1w2?Yx_)qU#gI65F%7xj1_#M0RttojlRW>)rPL?smIe zwc~g;EMPmHtS~=_KL0s}S+XX_{FQI-Cf0_T^C8qXHb_IMx_I>U*%6GsejX0M;qgY+ zs442X=NpP_gx&sMA*yrPfX%Y|Dq67G z-K^!;Ah}!!neTRsM|Re}_TBY*a=b+xua2>qo|9po>`Jn2_GMOVC_ZGYN%vKj-@;}j zW3emGeU7f*fnWTF^>^K_h(L(W<)g39j$ril^Aj!e18e+(ZuSdx-E-w`vDxDQ3tcP@ zyY<5#-OLwPOR;Z^{6mzzeKVE5WdbqcPf-w4bF_at8pw5x$$v>-g)V6%#J!A^MPN8H=O9*IDv4);cP< zZvFj8!+kFE`$m%XB_V>MP~eU!1rS#n;Ev~**f zeIo&f6VLlnaRM}`DnJG&hu(()l-T4H<*WlYXjG8VE^3WH$p?yhV}YZJM(Y7W(hib$ z9a7PpbA+7fR)jcI z9ly6(ciu;!8fu4hJEL_S#?Dto(Uud9`aIU{UnH6+wL?82nj|wRLeKS-YNWu3-kcJR zv|^LD#=aKOc>hA8@$uIon*949n*4-lqL@@slAua*Nn8}m2?VNInw%S>6q;<+!|Yj_ zQvoV90(p{>*8>}Zuu&o@MIax&vWcye;Ac684qXC^q3uiEtU9H>iV->JwyJo6`ytqe z!hTfN8Lvml3`kTsc*-_xgziwY>O`Y9o0A8!oSK&tE8WP*asY~1k#L`k-H1y-pc4~D z9Lii^S=C8`LcLHo1&N}ZYZY`r!Hs|qwMh~?UsASFUH9)Wa?i9}YGo;$6jc@|V9Y*CQ46^Z(V+62~QRkF64u~L78 z2n9KpRAaDrviTu)NJkW#K4FpJNd@YfJ<-e06V+5_v}G|_)IOsER+qE2Y;+S+Ntk$z zflCy*D%D${z-6gcWqr*=nX+Q0`cm1tq+JS;0_o~X1HP%L$vWU%Qm>}Mbj1^S+POm2 zYo#?>t!Y(>9R@EuTUEiurDMB3d$PF7CK~YU6A(!ppy^Z~)>D-XorIthh3hKF#&%jQ zoNpY{tgBfQO;RMvI+au@tEIAXMOi?svrgQ&lYMx(A#reB%8?0BQzDB{?Wr9RWiTb2 znh`aqw!D@R3Fd`HB)DJ2h=lOFFd|3$LL-vt3yE84$pHzZB(OMTgp_(V7cR+u#Pz}u zVN__HXFI7!!Wy>5vonHlFb|?y$;Vu zMb;?^fz`>sPHk{upipR8BRou?Tv)dXs&ZsKiO@k-++Uq&NM#a@3^&o}B%nYZbV@XW z#m5x$*+NSfY*duF491O6(#0Nd7K??Jba+|&P(!B{m6DBwj22oB z0E>rQO>BU(s&OduF4B-yEJxu^mm0WOYOI9Oa^})S#xF+(f%%2^2nws zOGXJRX>yanG4F6v?Td(I)sanBlVzUzmX!Mh7w`L0cnEZ^MgIiVq!dt96dtX@AjdIA z7*bVvvDSiOq(hV7y$LR%*>W5R!NF)<95U3g>M%qAYc%k56$b)Cs3d2hUm0GujpGZD z$vx7ErZkjVnVJq>PA!n7&yt;Mgpim_h*=3CXs@Qm9?1gwOj*UDBaBKHUibo?R1yT) z!}gq%xwr$>iEB0xpU%w1zECQVTf8oNN_5&|rDXAyWX5e^7e%P8Loh0VvJHpiv?Y4C zMbX(>o(BFOsCsm-wx!7q-MrcFq!P*wErsPhb_YP(LiNQtmy%kh|M z>1}(RbJFp6PP!q}L>;G{#YSVWUQx{2YN2lpq(hI%j!GTlrtGN}3^`10dy*slX$d7T zjiL)wOgWj zv85y-5)Il+W^&qUkEsJXoKQ<&C}ftDk`e}o2)g-nSjwb{3z{Pxj}SGJMhIc0CCzTq zjOYl$U}OY)GcGk8Qn4do)f4Y9(pLc1a?Xj{V3dlHebp6ml`+0=Reek}GP+Hk$uh+8 z1G1VQ7_bT2vS%PstL}sw5S5|24hxEn8D;pQP}S;iLsMf0Awsc7uG1nXIf}1v{PjJZ4jguxwrg?p2nrY z)h@j25Vj~#w&5JLU5&IvZA3M+9YwHfY&WV>A(y4cK6JsKphT-z^xhX^qFc{UP{&Wp zCrX96S>0f9N=C@})=$Hx=%SS7J()Jw)FF;(RA!l6455Ie5>qXWvTWg8z%8PLA=3Xz zBg6n@z!js5^l-4f>dRH$$Qa*b3nOa~4V*S!?1*LxN?p1&H#e_y*R)iVKMBWS0J&?m z!$!SHZi5#K4nQ|0H(xU3)MZz-W@LgcN9`n9W|W*8AM0E z-c+wkX5C`$q_Wlah-*FIhTdOS+%lYEA1Ib&GDkJGMeE5Amv~ zx_8GBn|!b0AIBVyzB3C3Zz}nx-id*?j0dH!mJ3Vvg$~N-TKfy0!>c$b>8tlPzXb;+ znRx1;q#`~&b4xVc1sc>j_X*i^MXk?;zWA&p_ zU&!Wg5aiH$$99^mp&i8`PU5-HB8L)2$m#9vfJN^UbL>%XH37(D+2Ozowt?3_p|BSh zJw5oSBccft;T||W?maYF1zk(eC!L6`p0^g6qIB8{XPKCq%S9{Z=sKjLm5z^=;tq&u zJj}TvTz+t&8}wEis#ymPTLWYmDb>hn(hZ8qv6swCq*9!YDAmp{8j$S<-!PXimp;Hx zYOIC;U$Adiw=C5RDv35B)fs8gR5s(;hB^e06~oONmm>TqCaUNthn8EWWqT39ALytl15VwQ(VXZV9b*oHFJ#xt1bz7%67uCt^wUZR= z$*R0O;1t)lB=eNg;fh;NQg3GOY zhRd7VS)Aixa=20}>JBQmYeHQp9@JG3UjQXU13fCPQnq37;aF2p)t0nfMOLE$9BD)u zRSZDI$$@6#8B0W(94DC)>Pt^w_#ki1a_|ClE=D@w6lRCfc9$~v_uSp+?NN@1DrnOwWJhiFlj zNl|U4#JPHitq#DJ&>@jW`v~ADBCcc zenBk|^G^3BRX%JmO_mk`))E`%o0H&yG~qy`qs@H00gS1%2q3At7~eVxJQSlvdAWsv zQs?7L7A%A{Rt|=LY9lgYqNk5FEz&AS?&kl?M&$TX8}ZebO|N4kzIu7|+prP!)JEjM z*BkJnz(6_BomCGL$ny<`_;Ee(>gDt><*d!{I=hN~`!1As>N{mTF4EjqU@5Q6laqR) zUa>opE6#UG52dSP-SA+qn92<4cG>ptJ9j6IUlbzeeVGo{)24f+gTJ9#kmfjfNgjakp~j zoA!h&Xdq|Xb7_de9U>va6HD}+nQg%Vq_4$XOh)FRFO0Y+?OZRMWb%56k)nDhi}$Ml zo_QKv^bW}C{b+~f?20doioDvjQBORtC2VN}X#7?kN6?rt#Sx;1Ho{Fd^Ex*MMeSBh zbGjMfKkuk=TNHZCfVn*(m8zkR5Z}iS7(P8Jwq!Y&5XlZETxf|BZ6+RW7Dar_sV-Zh z3n}F0V?wYDJ{-Y|Ht4O`~cmH6~6#c*wv6IZmAX1?o1 z+803I65wTpj=muHqN8YmVrVai(+JTZ4A4YHp3ik-Rm70OYa&i?;?rK2wAs?#UTV#n zdnB^rk`Gu=i(KG>cOXzzdni#K08?-He+z(Ozn>Ik%!5auK#s}tl(a*}G+Cd6DCTZE zm9@!ssdXSeJU065S1>~!ST6uR>rxuW|H;AI7_SDkwl}`fv?ZybJz^+|jP3)v?16-p zO_c9dkO|Uu_)6R;a!kuHh|ZPQp2S7MDk>CODi&@G-*F%`E_kMp{;#^P+nFUdl6w`w zz8#(A|Ic{u=2kBu>pd0WO_V_7xt>RU!O(o@c=hU8F>lzRZ zqhC^05h=NzuMk{htW&-Pq+ufhAmZzg5o12N*3E~wua~TK^I?7Cn^@~|zF+GG0Az6? zBSumVN63hgMaK|;U;rAwa1zJ0c$*hA;;?cX4vpBBpb>5h8Uf4j1&1#j#fxTwM&Nsl z`^9YpuI|~P5u+&ODrm$&{2K+07^qhkheixbmD|%bmA}`sVJff2BjqyaL*Er&*I8`ucmX~7{zbN`@KW^_$+YXyFI zI5=V;PuDg$VjONXArHi8pB zJ2nDV85A@oFfu2w(>hhrlK zSXgs`BMv7vQ*v;`0B5l{IAU7@M{FD52)MtH92@~Fj}4B%wZaa;)kGyu1%DWTilz;Y zIBcdjS8Fh)>pU6V@9OpupTM%P;)srM8?E4sq!CBNy3rA^OLTMuEWy}-j@Xva5!*)c z7M5cp@Rf5zBk)t?H<2Yps8SsJfDWh|7%}3PQBQ4Cxq09swk2G|$yOH_Qw+EW+@^0> z#LW`)Yc}CCjda~=gk9p2G3Jm{a zrG?$nx>`jHvc9WZ{2tWgyfv^W2TR|I%}dTKfoounO>f2ykga9#lZVHr-~>MyqhHD^ z!Tb%(Pr~S=ouedYmZS@g5Ybx`OLDjm=s7~D9~Qy@{?H@PK!e;{o2eCPM}yGcft<^ShvF(ZMa1`W;h&|w?cS?FW?ctfvH)iUQS+0dKBzRjD0R58hg0L1Kn)2aOF>+=+f`Qx^aDqcTc^@pU_!hozVti6t1m-x_IXvtfdX1-k zR&$F#GxTM%>p5M}x624VMzl#%qt)48xzD>fNq+4yZjrwxGQPyik@*si$WH^3krA0w z9b%^G7GHeqig&9TN9)o$V5czf;soRXA6sqApJP?x@WzwXyXi>K##WdUctj0oqYeUR zlPtN3;${K9H}gh?Z|=miA?MVs0|S32>UgjU2kF=W-SxrqTWf+4%caJLTzm}UD|zGs z>}b5~t+Beb-1>`_uoj+_Nw_U6zHtfrO~@p)a+OKwM0(`rG6|hKX4qK5I&+lt3h8V~ zOTg?dnFMS(=wB$4z>+!_9?2v$f3GQ%P`QWqxn3x2vOPf|HFdW}%@)ceWHKEwg(Q=Z ziJ{>4&=(a=7s@1<)mOM}2j*a#DJ2{uMTbG5gie4N97GrWwpF*tAT1heYdscdeiBLv01(hJsf5XG8y$~* z7W6UnY$5x!w9dCi?9(8pWl{+p1w7eeESIA9E#AGGbmhpl4>>iHen|R3{dZ*6^A`k; z!%Q5o=^6n;eNU-`%IYSp$ZK2fvbwHK>QNI?K<)y!om8}Fkw4v}60lt;TGyLiRlZ=9 zN`S@bVNwaJl~M_Xdmk(U(s?La<4r1|u3smakM`NLRG4 z;KXynCjX+k69=N6mn|moNx6huAl>^GllYsEOE{vv3y1B9K8u`2B~v0&pak=wkO&+U zD2_r}e$%U&s}b>|UR*%L50}!@ULYpPNqd37ZfUMot|{6N$yM>TS{^VDv|NNNSH$l? zoorhn*tJFT6S*l^dRmDS)Yd&*m&YsGw`g^nlpujUrydW+2-GI9eZgQ&hWE{@6)|As z#$?o!6$?bfwjG+&`a|)}34S7P1mg030@0WcyM}mbMIi`QOj1O!&58Y(MmG?v^=_QB zfo&@)dBJ7C4J=EQAGZeuz%WjM;Xbmyc!W{i;j(?C@yWF}A!Fs{oqOID5t2GDt_X?Ya=cvq64?T>_?4>B@0BLbFH6s~_@pku zEoSR|?kN2xbP0~_^~D`Q^=F5+G@FOEu)0UK+u%GiQ*kY12ejElTno8?9o2&FUW-Sy zWROR9OJIz9(uO=lhzG1Fw<@b^Q7!1*w%iY6kjK``qMz)g{B6++FUT8IZ^k9ey

O2tD??pTE!xWPs1{bTpmzPOn0A>6 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 literal 0 HcmV?d00001 diff --git a/part/data/stamps.svg b/part/data/stamps.svg new file mode 100644 index 0000000..16a430c --- /dev/null +++ b/part/data/stamps.svg @@ -0,0 +1,538 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Okular stamps + + + Eugene Trounev [it-s] + + + + + + + + + + + + + + + + + + + + + + + Confidential + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sold + + + + + + + + + + + + + + + + + + + diff --git a/part/data/star.png b/part/data/star.png new file mode 100644 index 0000000000000000000000000000000000000000..27d5d948b887c6262504cbf808c6c02aab41dca1 GIT binary patch literal 2725 zcmV;W3R?AvP)IXXH@!@|OT+`fIguxHO6*0*op zV=|e{5+61Dzc7NOrKQV^88gaLQc@UU#flYGFv{2X=#PM*-W#E1%a-3CK75#o1~_^0 zBnt`(`UxL705ZTpZ9Xg{nKSJ5>(@+Ng@uJGFX-B} zYYM*N3N+`0s9($4+S+6G?AiI3FJD%jyttG~CA)U*8k;+JZkdUR$(Q)54Pc~qVc_B6 zF@4{@eZu3%kJ*Ro>C>kS#3Y z7Z+0q)QO^^B6juaRW@(lydqOm(}>TyCP35E9R2<&EcWEd6EZ-(K%ugC?_L27(iQ^) z1J}mVAQ{N8e0_aw+qZA;8WIxX9UL4S2qD}1`1pjmxw(a-i0Ou}L>LnLK*j!qL%m;dPKRqyAKEq3=BXf zlGfKyR#5cmi4!N-*|TTa`Sa(gQK4F$x;7O{-@SWR<)#lGK4jV1*^EkCDrHI0+}vE2 zmzSr?_pe^PQW4+Vw{IJaH*emMC(v)w@6$fCr)uvzckVDMsEAj{yU0)^D;b>Xh~(sC zcJSaq3L`oU#r*m6i{L@u^OS0!&JgYk7Az>BALSs$NfC16Mh%jYKzwuQ(j`%T)d7wj zJGPY96*6^3kofueZQ8wiccu6Pw{PEO`T6;LgT@b%mC9;Sevq&dWc&;9GGGlD*Hv3c z0CP`I&ox-T!g@qVYyWRV-e z2t+(Yctm!M3eTQBqfn)jrC^DHd{18a}*BBpZLU*LT11yg%2UnozC(u&sgSiN5D0h!uAKNx)hVxz6J&rLnwteEO5Ty1 z!3e~*M35AFS_f(YG2VrB>(-T^=t+Q#Vcg|C0cSp0GFG4e)f>Tpx286zs>Yya&pv(n zv=T8#?nlK5orYFGd(ocQn+hNS)nP6UWhd4M3r?sP z*5RgC0l`R6y7Kxcpzok2N>utcK=W0OJ=b9GkZLK;5il2BUIWV4$qV+~yLZ3By?}&Q z53V2wJx3q~>jaoyi8(_Y#e0nu$8VOkJ3iw^K<{9RE3ahC^+^ehA}%gYiTOY@ojh0G zrbfK$VqxMd8#iv;OYQ+01=5{z{P^+nc#e0d(cS54?ccvYcl{6WMpI_ zWdWVvB6sT4X)e4#sITx)mK3ki)S#=RYOg`{1E#|FK!jd8CqlaR0x{KFc{DP$c6MlT z8f1iN)26-m_V#YC(|3yC{w-o-WAnIjbpjfq!!!JO8uTmKvp5s{vlm{>+F zH9(<3-&c!`8#gLZef~|S*XYPZ{V*V@QYS1L8d8qBMPbpRMFkcX7OVNFDiH9)z;gWP z(W5g_NGahBA}`bl@;VG||Apt>bjAa{di7d^3lyO)K}nf=_wEU(;mdH^zd+d`TyY=3 zoin*J&;~a++ib*j7E(bl?L~(wWEV8Q@m64ro_PF z5xTd9{M7xp&@O;AcV9E!$vMC~M#sd&WMH9L6{i@^TUIX~=Qdn1v1ga4 zn=^2wJh9?2a48ipUq#SJ9GzhneMj3oV2JkjKh^K!&H0k!O736LHB+dIF)7ujVP|3B#qRBnqDtS4K%H$ f)wG&c1K0lmgxr`r6D)#r00000NkvXXu0mjfo+Ko8 literal 0 HcmV?d00001 diff --git a/part/data/tool-base-okular.png b/part/data/tool-base-okular.png new file mode 100644 index 0000000000000000000000000000000000000000..cf6eb01338bf5a2d8bef652eae588d926226106a GIT binary patch literal 870 zcmV-s1DX7ZP)ZMv(@Y_7R;hk?N{qZ{AVDX6OVsZ;fqAtHRH z4B)p9_Vj=g`El}~*82NLx@WW5ZwChlCZGUZCG>Jqa_`Z)}7`U#>#Kgq=0a~pVhGF3QK6iI_ zBoYYvFj) zT5C~Cy-pFO)Gy=zqP4ZPKY)OUAR<5CKp+qxolXzy#l=Mc48!=@E_3v6_Lm)FvDnBB z-URR&GCj`&pjxeReSOX5<|gOo=KzQZN-4C~!v(K*2cVQdCAq)6{%DT%d&7BhieaM<6#$G|B#!T zn>PbsS(a$6#kOrxN=c{F5fKrswK$F=T5Ayz>G%86@ApMS#C2U!N=duj77-EKw&m&R zNiHrf-W)^zZNaGZcYx1N!KVW#rP$foq0{N0lmehwEYfH+cz%BV-vNTvYL!N#K{A=7 zR4Ne)g*ZJuWqo}e%d&{YVrZ>tx7*mZO*Wh5?CgwSFi0+!dq2S8;UUx0)70yAJkKK< zjS`7Oh(@E_-`~^g_3%88TCK+F>MG@Od1U4QD5d1+=tx}Gl~SoBzVAz=QjvbYFDEA_ w!#LJzHMzaL72CGOb={Gr;46k-0G|%* zq{jNfpGj5xps^c_{gU$ez1)oZVu#}*cOtJuzI)qrziJ^ee@?~>r(E^b~q@#*B^^8PwDcE%7s3Aqn# z3eSpRHo@Sg|DO&23PEU9!Oq-9AAcJe9epzPmzcV`KnEpl_`9f#%pDq!&IO{RV`mf% z7cZ}(rsj}Pc+d;%5wvnT7ts-P3D{jb@NF@G&d-{}lbuh1ce4OhhF~hkx70lBP3sZmC zdNJi@wDf?vrRC!Od$LJ1(!L$_2-#@d=FlRAP&4%QQ@bK{9OSyRxfs~PviHVJ^ zx4 z3f>e1F>Y=70=4@3`xl3iXQd<(U+ZitG-{&SYROks-^gh7YndUCxtd=cGQGb(by<=& z`UxJ-^M!yMo^JB;Yq7Jgv6SXv!eX&~jf07tlGZK$;^13+%(U-XTdzGnx;pdrz9j=W`IEA(V1v z`*Wtbj;oKZ3(0-<3Tr|fg$f8T;btF5Dk^f;{5`9~&d>k(O2>)9`UM{c0-HP^GXcIE zaoqgDO|kRG4|g7EYv^s6sx7q09=@@$(Q(Zr#YCp~Eu@Ko|J)w-ox^2|!E7I&LJE+P zMUuuv)Ov$;9sj6R=Q7f&A*hE5NJ(*V8r-j64@}L>{L~7ss;HP@FoxFFeC_S+g9Ic2 zz>3b3Mse8JA~&o3#>ecxrLrS{H?4fS}Rn{+?>9 zy2ahYko`68l#~>>Mo4;04E53Rv4@Y3TX!4_TrH43>$9%5Hr1_ExD#-go14oiC`6IH zUlteRFwGAdf;a8=LN#ZaecZ-g-f_PQ1BtOa5luI;7N~~5;$S2UEq?nJzq;x=e`j)P ze7vU-JCKl+l+S%KKQHX;?414VSw>C{UGeh%RP9~oz`*S1Dn5-t>y};J-RC>lT^%xT zvaqrFjF-WHy@R|H5fLFhK30~?>uvr!i>UUb1?<&~85+}z4Ve($Ud0Jh~+RrS$m_UPznW;Ql6G`e$ZORloA za&K>MYi;84(a}*tax$@`B_N?g0@?Y(OD+b8h8;5?S8X25+|?Ug(aOho$uN^rWY!U-$P{P=21$ z)ujUh0TK1435`um=$V>kX1Wrt1;l~u;pFCyo$y@wNq$YTlT8)Wguz9D{f|+hnz)8w z+E!@$;?e$k*McuSA|~W;r;PM)BR@AkKi|UXj*k^E5Rzsk2iX z5d*z{|Gq()s+^oKz*0{b3ccd+p3Ab@A}}cE(y6GZXvzEc_N3VdU?LqWJl7&IqQ(>2 zK{<1vEF11_E!-F#8{5^Z-OpL6pT?LHL{wB%+z%MBQJzdD&(o>?Ykk;UY(Cvtt)=(&_eVjoa&QpJ%F5~&Mo{0laRZKwfTJ?&$=(`|kIa=u z9XJYsmh$o$04cPsZU2uSQcg}z1~}IE=$##ZHFb4x_C4$S3TkTo%gbW0lsJIGIi(&R z=(mFcFc^^X#S6s4&AA~^l!3qn1#lyR7R!g)yRG9%k9ej}PQn2~alK0~N=su(N<=gS z*<^E)gVrbI<>WrJJ=*0H5O7}Uf5yeljW##$`S1a^^KN`DW${ZXV=~#YnGyK^SP+3)VZ@5Skfau&jvwax8yt;3y<}OGrw_&&}Bv7)b(_L5?vpGWHD)mbSF;=L~!V3xE=$5we8?9NKq8 z4E6L-gY$l6-<}WN5kyAZ2FzWyd?l=+lA|8{OHNt&rnk2=ZS=zP6Jl&_X{jzbuBxhP z@jD?>LQ}JFZOwCam@u5L{3!+pKh2V+u+>GDuya)Xvk>t zni4^AeE(9o)EP~8venJT#lvHY!3-E9PfH)ZBCIB7+fn2qEm-0>5KS}{clsdz(++h& YerDyY#?tw`2LCh=l%A1pt&U^VzvDMpX8-^I literal 0 HcmV?d00001 diff --git a/part/data/tool-highlighter-okular-colorizable.png b/part/data/tool-highlighter-okular-colorizable.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7db875f501a72e52c2a0a7eef047a93e01c9ac GIT binary patch literal 2148 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 literal 0 HcmV?d00001 diff --git a/part/data/tool-ink-okular-colorizable.png b/part/data/tool-ink-okular-colorizable.png new file mode 100644 index 0000000000000000000000000000000000000000..a79c37f0af326900a99e35efba43f5187271d913 GIT binary patch literal 1770 zcmVRzgP4WI_FMgWSF z!SxQts=$|lEx^_lKJNiP1m^8dsz@nc2et!Wv3MKM3Ty&4n%+=io}UB10LC2z^cm$V+Z z2D}Fh16hnJuD8Ja2M~5AbZXWmc!sft{{Z5^KP{eK4}enk*aVpXJ_cgI-!ZbYE&#DPcM$FoQ&qf*KRS-EATl)scxdZm=ub;V3TBk-!}oj`}hJI&*EEere_7y_nO z8(aV=Wp3b`z;`U(ZUbZn_&#vAQh;K%)dI5*_!h-)Y;(Xt;P#3$Ia#j~zD-K`Qz@lh zq&8Ag%GXyqw^{%NZ;(>HDW&{)3B+GkE5d49GcW>tqmXEfJL|IB^jbWS)R|&muzaVO z5X;QY14$e317I&kM1^w%khAy(jLUXwk$FD_{#_2hc8pYh$p&aCdyf?|uv$??id3}| z6H>~bmC{(P1|F0d@dEGx@EXuxYM`B~;8o!B7=>i@0=)GpSYrGF-o>bkRc);M~ZviNZQl}`&iv43Jy<#V#E3BFj_ec zrdUB(F%K7Qh*b<=M!Ufj7rZFEbcyp-15gyjjnTrl3NPI~6(Y_{DT{Vn9RnzevH_z3 zQE1;=h3iaF1tZ$bO2Uo-OyL%mH?yq~=P)*=i^bNvEC5qj#c0>9WDCGkDP`7SSt7F-vA zzP>*9#fuj|Y;0_txOC~#p9cpAzxe!Mh3)xO{ltkA?h6+#T$`Mn6i=Q!krNXW^77@& z$`1jZAvnkLL9G)5`;pb#@)MjU){TR z?;EYHt;*EY6uDdum&?Wc{Cu6NsvTwF&C1No4B2cJm&-*e zl_HTy+)S61Uq;GMOZiNZh}5>(;?YBr*k6 zz8M7qfzIyk?khWX?D)E>s@%SPo3^$#+-^7NbeecPe)s0hn+MOHJ^TE9V$}cwfk02j=a&7mqT(Vn#jpDP{#_oAhh#EICX+!*iOc0e(==^# zbo58X#G%3>92gkzc6WCV`+UBg9*+lI*U4mz2c>*I&+P217L7*V3WvjgT4|250fNDx z@9^QnSA9O;&Zed&W@l%~WHJaLP!t7C)3jJD_SWgsr#~n)PgwxLV9?jo(=+V#dcSHd zxPob#rjLw_yd4gQONv7oMOcX3@AvOqT5v*$LfYRBhr@rcGoPa(3Z7Bh@7NUw2N~$^@85Rp*s)=+*ZWFSQxkJ@b1W<@Af+Ui%c1MKcH_p4 zcS51i@0|o?s|Nb}`?noEdi1K->wTrUxfxBOA z?d`qR(b3^+X=!;uTnK@tX}T%?JE!8d0QT?S|9*RWyH8bBW@cty5TBl&)}qnq@iS-6 zlqC)}ickpAAf+UkOp?uJDb$RnX-QN3x8;hj3UL1X`M&n{c5gf$CzVQ(&*#bIa!gH4 z=_4Z}?^Y^a65!OSQ`@_`x_+`{%a&G;$HSvXk9hX%nbb6GJ{F4|9~v6^O{L;c;xb%Z zT>No79*+ni^180)#>dD1mdoY-nog(Rk3=HzYKTLLA{0WrCWNR^u zEm2zl`F#FUAw;aczWz`!7<{r8;y}rLf$PqlJI!moZ>TjWUOK>k0p4U55d?p@>i_@% M07*qoM6N<$g0po^L;wH) literal 0 HcmV?d00001 diff --git a/part/data/tool-ink-okular-colorizable@2x.png b/part/data/tool-ink-okular-colorizable@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7e02a79424193e16a3a6e6e615e79a7a5a2e0231 GIT binary patch literal 3744 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 Z=ms&IC*HC)pZS{vObyL3#RjN)T zKo0Of02sHE@p$}oFc^G!?+_{Fuf<~V?XIb{zSe9u`>sDg^ZESeZO&~yyn^+54L}q{ zTrL-qBq2!>f*>G{V*q^LCk#UXf*`ot^GwETrj!yXC51u(Aq2Kx(A*G~PEHa%=F-`Mr0O#|WG)<{itJt>9;c&ol9J<{uN~!D4>-9QH zDUQb@uImzpA-!JjdU9_DFbsocv&rdnqS0v3Znue|2+OjF;~2+ra9x+pW`pN>Y`0rV zr4p@H3)3`7(-h0HUJbtoApQ=9!{O7#mSy329_4bGe!u^)Pirk6dE)jr9F0bwJDtwU z)8v1Y@B6=(%jJ)!09h#WmoNv&0djyGAP2|+a)8VM{s8RH1Wsl>r&9m`002ovPDHLk FV1htkzFmw>vSEe0(&A zLZKz#&sxR&eP?G!H9m=KHk$+fc<&%hwW`)<_3i?M!{M5Ae0_b*(a}*&VpXH+6%dQX zC>Dzpi$(75?v#XPN`Jl=H}+Lo!jlEx3?Ef(}=}l7>0pi7+hRj z@cjIYrfC?4fu?DcN+q72p18feC7;iePN%C)`&CsZd^8#*olc{wDnmm&*b#)Ps$4Mj-M59ssem|$DrznbouIn5e98h0h zPcRr{Z*Pym!9mv6)^IwVG&eVsOeP71LYU3ff1s*b0f|I{g@py0nwlsS3XF}7Q7V<_ z>FFU52yk+8g2&@wX=#bJwl;#n;8(Nf^?I3`n?qGqbX~{i^D#9w^;KW}{r!xNj?&%T zO&}0JRn=-ze^pfhOs1FScDtQYsf5Gfpin4~OeVRzyTjx0V7J?`SS&O)Hd0qtN2OBv zM+}F<0f3??OioU6c6LT25VGD zCX=CDE~D!@i9~{ih6dneZ+ko*yk0N5uA?Y#-?gr;uE^zbl*?sycXyecoyBUkVzb#u zrBYm8UjEp~{-t+sB1KWy+SpD%AIW?7r!( zGeF(g*myiVJk0-KLLVxZ%T<8Hug*gVA%qY@2qAy{D4^00lTnL_t(|+O1d1j$1_#t?I|U_RM%* z5P=8_*nk8JSg?r1o)6(0_yv~y4NGm}AGD9>* z!Q_yW<(T!x_8N zV;63n#%eaJJi9=|p2#_3cJP_>mGM@qpp9kNoHIGkbbhh_LwIynee~5A55D~Ho#qx{ zle*$i*Hwu1#D}U5u{wmE!eSij;H#QonDcNM z@813P^UyZS_~|FN-}~VGgEzXBOYEG}4QpawZ#E~6;Q~28ZAT|NB10P*<*h`}~0Se6m;4E_5 zkTb~h4df%WrC!O?Kp6Jv=Tx+D5j$onf~ zB2gGST}zNhe%ngtEb3jzw|d{A??BjsctyFp0+wBFNj?t z4*V(ttloA)Fy129$Wzw{c>?*+ydbC`7qv~oD-ds|+yq$ULVhJtYvkud!&UYb@!*)A z&*Lh*60wo0P1^0bU|5qc5d9pH|3$gf9g+J;+$Tzpp4H26^WP46t3k(kCEQB8-tRON z@y&q7Ibn9p=A(l0plsir%1cwAyNAAmxIMO-=AFl{L>6I zidh!A-o1Idp?BYE9{vqFUV!h{Go8)=001I-R9JLVZ)S9NVRB^v0C?IfFE7{2%*!rL gPAo{(%P&d?05;eLSP)anTmS$707*qoM6N<$f(QW5w*UYD literal 0 HcmV?d00001 diff --git a/part/data/tool-note-okular-colorizable.png b/part/data/tool-note-okular-colorizable.png new file mode 100644 index 0000000000000000000000000000000000000000..01ade5e6c9072a5aade5f5068bd81db49fe75b8e GIT binary patch literal 670 zcmV;P0%84$P)0Dh zVRxaR5El_OE>slc-aGeex=Kn&3*}D0E;)`(CKvOcDtVgAf?2zEKJkn?(U8t2nd3JWHQP5`8l5FQLon# zLg2bC?RJ||sq{`m382+#vET1Wr_*e=TXMPFTkdc;aC>|E!O-(OT-W9G5i0>aK0Y#^ z&$+p|VX;_{N~Ne)t2{kDkT%>t0g zWY9E?QmKS(+Xx}Jyu1V;pU+dT*Lit)A(zXcX}{mT5EQj$)mv2B}+iwpMqJ+A9gsZE~$^ZZW literal 0 HcmV?d00001 diff --git a/part/data/tool-note-okular-colorizable@2x.png b/part/data/tool-note-okular-colorizable@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dbdd3d95505f9e5a4815affdbd15991fa1da9507 GIT binary patch literal 1524 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 LNkvXXu0mjfh1hRS literal 0 HcmV?d00001 diff --git a/part/data/tool-typewriter-okular-colorizable.png b/part/data/tool-typewriter-okular-colorizable.png new file mode 100644 index 0000000000000000000000000000000000000000..89da4aca3149e27c96c195eee9569a4062fa2faa GIT binary patch literal 397 zcmV;80doF{P)Wti6hXZE%w*73;Z-V<*DYpp5E@;6D6IaiaW>7uS{b*YpjBHKbl+dR*| z0Sw!`WdI-nAdcg&s;UYu?=7IUUIG~X&z}-#$+B!_j9H%}uqle-hs*m4G>o;@OCs9& z3ZNML_}ICXdQ rX}lND!;gU5crIkm-l}JPAn+LW(6Ri0&vE#)00000NkvXXu0mjf-{q-z literal 0 HcmV?d00001 diff --git a/part/data/tool-typewriter-okular-colorizable@2x.png b/part/data/tool-typewriter-okular-colorizable@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c3961615e75462e92f89936ebae14f8912c14470 GIT binary patch literal 727 zcmV;|0x127P)No2g~i4uO(5kJ7W)|j`2?bk zbvj9vDv*#=!4HrWNf}cHY;99Xsvr`*TLjmQ$+CL0DQ*P|b2qcMGk?SVe_$i?o^Rg{ zyEBXc!!QiPFw8B*QW*PGTM9jVk{NVI(#)Msr*CVu+JhSeGKTN_L8Vgh01U4iD_a1n z)oLY|%Sn%?q*N;1mmQna8RUO}3!n}_4Hux%Tg>Nkuib8cuq^APs@S&eH~oJ9YZOJl zb%ayJ-EOyGEWv8E@>{LedjL-Wob2>6+I;}HiMG*bG+s<5lb=EeDXkFVVoz_TfZ1$z z<~YuC0F^`f8x*i3Z`*cfJRbizssf@Y`qOMSUjevxl|F+4cG!;NJo9~jNnXHUF!%=G zp^RR3`breAqt@&7zK8?HCJGRpPUj1pokw#bPH2g1}?}7pJGEuT}MN94j@T zcma<_qtSP*1$dr!9){tvUa!A{+Ab2%UjP6&-EQ~uX0urbLExv*Uw;wFC!a=Zpa9_V zwY$qHh05-3sFsC<5Q;f@DNG%J8ZLl305wNhz~xK83`bdjNsJYsa#t-&b)A(So&nSW zsNn*r15m>SnED};Pj(e}22cl}h6|t$Kn)i_9e^4xfI0v*I{x$H9{BEY3ZH*zhAF&^ z;f7(jPR;-h9os3Bc!)TTh39!^$oRk`^BIuO=TDHF9A&ZmO*||BD3{Auoj|98p8;7L zuGi~dg+d|oI|TrX#bTMYr;aU}tHE=hp=N)EVHk#C7>2nG`~_<1fUDAqA143+002ov JPDHLkV1flrFp~fP literal 0 HcmV?d00001 diff --git a/part/data/tool_hl_orange.png b/part/data/tool_hl_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..b4d4591c9770a530a8f191f229087898620dd301 GIT binary patch literal 1527 zcmV_}|&@xm4T8)v^+7NrBj2^rxgpSNglSZkE*E z;efG{!_3X^iRM&IobQ zwBq$kxKUrhp^vTX*mZ)6Z?3Q+<1j1N?B%1GDfIC4-X_V<=_l}}Zy6nGlri^b(bI96uhCOAFe-w%;Vcpgf z982<{a;)fU(GmNIXytG~jP$$4ND=vq7C>!2*{gHeZ~$_PU{5K0dICP2HigRxBF;}& zB)xAu(5yKyUiwWDQpfrK=>LD}iaEOb16E|$u;n0Z{u1)aVEKkh4n%k6K#;gk+AC?O z;nu8xiP9~-WkkAJ=9TBJ!B(}3wA4*x>;&sx*kS^*jg*-2)Jzb;KB|(GVE8tB6vs)o zG*;@D{>n?&smxym`dN$-Wv;@7(NH-Ta{Ex1?n1<{ zFkW~yo7kY|`6ga8#fYf(x-4mq(NXqw+mB#^)OBe03!}YcT5+&niz&oB^sg*fXp)>+=d?8cV(gZ7w|A@L|aekx-^wL@T zq4^lPt$+mSCoxh$R$$*I%A+CIA2J0QqG^SwPZ3wAiEB|Jv%7A1NvkD2YUs8DCP<1h zBBh|^Jv}Lz-Hqx@4{TP!D$%$|T$?3oCyR;~#M3QRCTW!6?UaBwCB1HhOC!Dr8$d(h z2C5Q!Ql8w3i|MX3EEHEJ8>7XX_Nui=DU$wf$SDC~l1zkqN@tIPx`K50BpDLjs2}A^ z<;eRef7hMbIB_UI_)GbcUNkID3wYz^*nPcZdLW$2gZDebL_u&%ZajG}rH^;ulff+* z_g7tzlw|zPkkbN2NM5PE+kDn^d>d>W1Brq#VH@nh<%jNKV{1?TC6}|UrT^OJy{l6L z!lh?Q-+dL1Sz+$|Fj3fsyV3NRH^n}l{8KLFl9KIjy@w&E225|OsaH3RfeoV}K@e^X z@u22GZ<5_wT((FHZZ+$j_YU|EE!-df9Ot6iL8M@W8<^eiZ0$}bX{V$?hT9zr7&PqT z!b7KPSv>Ot@`iMz;R*3ohgLi#l}HLV?lyGC0v_tMbjil!Ha1^??IjmTdvY)@NncBf zHy$u_M+5%SCO#x^N;RSLPcv-dmLJ-67+NGL!GU4poB*j^+ZG7X|-^l;~002ovPDHLkV1n#5@Bjb+ literal 0 HcmV?d00001 diff --git a/part/data/tool_hl_pink.png b/part/data/tool_hl_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..e063b193b4b4ec9433c90c6db73370460c5d0e80 GIT binary patch literal 1552 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 b`d{ErXY>@S_zN`?00000NkvXXu0mjfOX#^$ literal 0 HcmV?d00001 diff --git a/part/data/tool_note.png b/part/data/tool_note.png new file mode 100644 index 0000000000000000000000000000000000000000..06c37ce1b7e7ca35db99fcde5fd46d77125b46b5 GIT binary patch literal 1592 zcmV-82FLk{P)g{0*G5or;X)b7LJ?O9x>c8o1hVn5 zGYfTP!k`2c2a<(Cf|?-sVkRWrn(4mXxBI^9{W{0W+?pbhI;(b0$X3w%fByhh5DgiytKt^k=p{w5h@fKnj-lL@@v zG{63EtA#AWg|3q(38OfsXBa#IA9p`-k34R7 zJ`~t3Mtzt-GK6R!f_rRvZ;*`+h!4kMGM>1-N#G_UM*Rc!ya7Xd!l4YAkTX�~CJ+ zMwP(j%d#6qq`r>>I9po`OcQ%NCIsZ*2zQjwIdcx^0XdkmAc3wAcr-3eX)tzL962yN z3w!THO(2*fXA9DiiyZqn)12Ra*Zn!KWM4fN82kRK&8t_h&0LpgbCW@qp>E$slad7> z&Y#6>>OcU*Kt_cGEZ_{V30ztVl7J{^#b_-b>-++6!GD(Edw;kLTs{`~#cQws^r4A& z?IBxZ9t3n}Gg76P0Q(g6d88RG*YKphMG-jqMP zb9#K!-^s3ZGf4)_fg?aX@fAM!#m^v!%RkQ7NTlneDlrv-jDZm>JZ1|#AUYPf(Z~Dj zm#@rsuRqTAGp`Wd+eY+H^UhCxgso3~jIM1^b)VM)()uK7HH5rCCZM~-yAiVx7l@Aq zp1gt+(db^heuInGA0uUshD0v_9|+fXzMd*vMa%F!SPEz!(O$+hsR@KRcC+a?-~khi zdRO(%%k#Gn_d$jw%j} z8s*^&ajMZo2W@?L{aII(omWB2T7@si9{?eYG7cxX2e>OQB82D(O8~0YVZA1Gk=j

frtfYP+nn4;{Q`U|EWy!y!8+Y2@!~}AOiJ3KqnY!?51*hLO@w;V5?eqT2Yf&2LAg(t92X& z;Jcvt&`7}aK=hf;P-7UK5YSqxD;!m=fjaBMYZE9aYASvF*L^nb%@NW5@^@Q7p7GBY zW$2b$a8;l!do-&FoE&>rg_m1x?P5~_S>z-A9D#sLLY~5(;nuCg`L_nVFor(@;fjFK zqmM8Ft-LJ(Rgy1J1u`p03Sv-i5`hdWRESCgjNAcR1F13n4Lo^^ou@*ci{TdVCm>xB zuu|;|!xw;Uuq|*LFbgQa0vaGhQ50wr@(j`xh(VR_c>=&Ak3t$w4-Tfh_;eV4`z2m} zei>Y-@G8|-T2MIA>p`~- ztuC~if@Z6M(=2cdVK+_PYT6CE)iNzh)18-h7NcjQ{I-PWfWJH#`CAFB+<#C@G(ayg qYBbhdn}7t~00!mx+T;IU$NvI>gaK34+DdQ$0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/part/data/toolsQuick.xml b/part/data/toolsQuick.xml new file mode 100644 index 0000000..67f02ea --- /dev/null +++ b/part/data/toolsQuick.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/part/data/uparrow.png b/part/data/uparrow.png new file mode 100644 index 0000000000000000000000000000000000000000..c29414d107955ee5af238063cf2c084165bb4aa7 GIT binary patch literal 1744 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 Ef|U_w(EtDd literal 0 HcmV?d00001 diff --git a/part/debug_ui.cpp b/part/debug_ui.cpp new file mode 100644 index 0000000..77ee180 --- /dev/null +++ b/part/debug_ui.cpp @@ -0,0 +1,12 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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. * + ***************************************************************************/ + +#include "debug_ui.h" + +Q_LOGGING_CATEGORY(OkularUiDebug, "org.kde.okular.ui", QtWarningMsg) diff --git a/part/debug_ui.h b/part/debug_ui.h new file mode 100644 index 0000000..a66df68 --- /dev/null +++ b/part/debug_ui.h @@ -0,0 +1,18 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2014 by Frederik Gladhorn * + * * + * 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_DEBUG_UI_P_H +#define OKULAR_DEBUG_UI_P_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(OkularUiDebug) + +#endif diff --git a/part/dlgaccessibility.cpp b/part/dlgaccessibility.cpp new file mode 100644 index 0000000..fbd1e14 --- /dev/null +++ b/part/dlgaccessibility.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "dlgaccessibility.h" + +#include "ui_dlgaccessibilitybase.h" + +#include "settings.h" + +#ifdef HAVE_SPEECH +#include +#endif + +DlgAccessibility::DlgAccessibility(QWidget *parent) + : QWidget(parent) + , m_selected(0) +{ + m_dlg = new Ui_DlgAccessibilityBase(); + m_dlg->setupUi(this); + + // ### not working yet, hide for now + m_dlg->kcfg_HighlightImages->hide(); + + m_color_pages.append(m_dlg->page_invert); + m_color_pages.append(m_dlg->page_paperColor); + m_color_pages.append(m_dlg->page_darkLight); + m_color_pages.append(m_dlg->page_bw); + m_color_pages.append(m_dlg->page_invertLightness); + m_color_pages.append(m_dlg->page_invertLuma); + m_color_pages.append(m_dlg->page_invertLumaSymmetric); + m_color_pages.append(m_dlg->page_hueShiftPositive); + m_color_pages.append(m_dlg->page_hueShiftNegative); + for (QWidget *page : qAsConst(m_color_pages)) { + page->hide(); + } + m_color_pages[m_selected]->show(); + +#ifdef HAVE_SPEECH + // Populate tts engines + const QStringList engines = QTextToSpeech::availableEngines(); + for (const QString &engine : engines) { + m_dlg->kcfg_ttsEngine->addItem(engine); + } + m_dlg->kcfg_ttsEngine->setProperty("kcfg_property", QByteArray("currentText")); +#else + m_dlg->speechBox->hide(); +#endif + + connect(m_dlg->kcfg_RenderMode, static_cast(&KComboBox::currentIndexChanged), this, &DlgAccessibility::slotColorMode); +} + +DlgAccessibility::~DlgAccessibility() +{ + delete m_dlg; +} + +void DlgAccessibility::slotColorMode(int mode) +{ + m_color_pages[m_selected]->hide(); + m_color_pages[mode]->show(); + + m_selected = mode; +} + +#include "moc_dlgaccessibility.cpp" diff --git a/part/dlgaccessibility.h b/part/dlgaccessibility.h new file mode 100644 index 0000000..66c3b8a --- /dev/null +++ b/part/dlgaccessibility.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _DLGACCESSIBILITY_H +#define _DLGACCESSIBILITY_H + +#include +#include + +class Ui_DlgAccessibilityBase; + +class DlgAccessibility : public QWidget +{ + Q_OBJECT + +public: + explicit DlgAccessibility(QWidget *parent = nullptr); + ~DlgAccessibility() override; + +private Q_SLOTS: + void slotColorMode(int mode); + +private: + Ui_DlgAccessibilityBase *m_dlg; + QList m_color_pages; + int m_selected; +}; + +#endif diff --git a/part/dlgaccessibilitybase.ui b/part/dlgaccessibilitybase.ui new file mode 100644 index 0000000..d5dd107 --- /dev/null +++ b/part/dlgaccessibilitybase.ui @@ -0,0 +1,466 @@ + + DlgAccessibilityBase + + + + 0 + 0 + 374 + 479 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Draw border around &Images + + + + + + + Draw border around &Links + + + + + + + true + + + Change &colors + + + true + + + false + + + + + + + 0 + 0 + + + + Warning: these options can badly affect drawing speed. + + + Qt::PlainText + + + true + + + + + + + + + Color mode: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_RenderMode + + + + + + + + Invert Colors + + + + + Change Paper Color + + + + + Change Dark & Light Colors + + + + + Convert to Black & White + + + + + Invert Lightness + + + + + Invert Luma (sRGB Linear) + + + + + Invert Luma (Symmetric) + + + + + Shift Hue Positive + + + + + Shift Hue Negative + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Paper color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_PaperColor + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Dark color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_RecolorForeground + + + + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Light color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_RecolorBackground + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + Threshold: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_BWThreshold + + + + + + + + 0 + 0 + + + + 16 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Contrast: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_BWContrast + + + + + + + + 0 + 0 + + + + 1 + + + Qt::Horizontal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Speech + + + + + + Engine + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ttsEngine + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 20 + + + + + + + + + KColorButton + QPushButton +

kcolorbutton.h
+ + + KComboBox + QComboBox +
kcombobox.h
+
+ + + + diff --git a/part/dlgannotations.cpp b/part/dlgannotations.cpp new file mode 100644 index 0000000..87a7279 --- /dev/null +++ b/part/dlgannotations.cpp @@ -0,0 +1,26 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "dlgannotations.h" + +#include + +#include "ui_dlgannotationsbase.h" +#include "widgetannottools.h" + +DlgAnnotations::DlgAnnotations(QWidget *parent) + : QWidget(parent) +{ + Ui_DlgAnnotationsBase dlg; + dlg.setupUi(this); + + WidgetAnnotTools *kcfg_QuickAnnotationTools = new WidgetAnnotTools(dlg.annotToolsGroup); + dlg.annotToolsPlaceholder->addWidget(kcfg_QuickAnnotationTools); + kcfg_QuickAnnotationTools->setObjectName(QStringLiteral("kcfg_QuickAnnotationTools")); +} diff --git a/part/dlgannotations.h b/part/dlgannotations.h new file mode 100644 index 0000000..341127b --- /dev/null +++ b/part/dlgannotations.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _DLGANNOTATIONS_H_ +#define _DLGANNOTATIONS_H_ + +#include + +class DlgAnnotations : public QWidget +{ + Q_OBJECT + +public: + explicit DlgAnnotations(QWidget *parent = nullptr); +}; + +#endif diff --git a/part/dlgannotationsbase.ui b/part/dlgannotationsbase.ui new file mode 100644 index 0000000..d2a7bf4 --- /dev/null +++ b/part/dlgannotationsbase.ui @@ -0,0 +1,109 @@ + + DlgAnnotationsBase + + + + 0 + 0 + 381 + 155 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Identity + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + 6 + + + + + Au&thor: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_IdentityAuthor + + + + + + + + + + <b>Note</b>: the information here is used only for annotations. The information is saved in annotated documents, and so will be transmitted together with the document. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + + Quick annotation tools + + + + + + + + Qt::Vertical + + + + 20 + 4 + + + + + + + + + diff --git a/part/dlgdebug.cpp b/part/dlgdebug.cpp new file mode 100644 index 0000000..323c541 --- /dev/null +++ b/part/dlgdebug.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "dlgdebug.h" + +#include +#include + +#define DEBUG_SIMPLE_BOOL(cfgname, layout) \ + { \ + QCheckBox *foo = new QCheckBox(QStringLiteral(cfgname), this); \ + foo->setObjectName(QStringLiteral("kcfg_" cfgname)); \ + layout->addWidget(foo); \ + } + +DlgDebug::DlgDebug(QWidget *parent) + : QWidget(parent) +{ + QVBoxLayout *lay = new QVBoxLayout(this); + lay->setContentsMargins(0, 0, 0, 0); + + DEBUG_SIMPLE_BOOL("DebugDrawBoundaries", lay); + DEBUG_SIMPLE_BOOL("DebugDrawAnnotationRect", lay); + DEBUG_SIMPLE_BOOL("TocPageColumn", lay); + + lay->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding)); +} diff --git a/part/dlgdebug.h b/part/dlgdebug.h new file mode 100644 index 0000000..1f2abad --- /dev/null +++ b/part/dlgdebug.h @@ -0,0 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _DLGDEBUG_H +#define _DLGDEBUG_H + +#include + +class DlgDebug : public QWidget +{ + Q_OBJECT + +public: + explicit DlgDebug(QWidget *parent = nullptr); +}; + +#endif diff --git a/part/dlgeditor.cpp b/part/dlgeditor.cpp new file mode 100644 index 0000000..2a61c2c --- /dev/null +++ b/part/dlgeditor.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "dlgeditor.h" + +#include "core/texteditors_p.h" + +#include + +#include "ui_dlgeditorbase.h" + +DlgEditor::DlgEditor(QWidget *parent) + : QWidget(parent) +{ + m_dlg = new Ui_DlgEditorBase(); + m_dlg->setupUi(this); + + m_editors = Okular::buildEditorsMap(); + + connect(m_dlg->kcfg_ExternalEditor, static_cast(&QComboBox::currentIndexChanged), this, &DlgEditor::editorChanged); + + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "Custom Text Editor")); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "Kate"), 1); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "Kile"), 2); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "SciTE"), 3); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "Emacs client"), 4); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "Lyx client"), 5); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "TeXstudio"), 6); + m_dlg->kcfg_ExternalEditor->addItem(i18nc("Text editor", "TeXiFy IDEA"), 7); + + m_dlg->kcfg_ExternalEditorCommand->setWhatsThis(i18nc("@info:whatsthis", + "Set the command of a custom text editor to be launched.
\n" + "You can also put few placeholders:\n" + "
    \n" + "
  • %f - the file name
  • \n" + "
  • %l - the line of the file to be reached
  • \n" + "
  • %c - the column of the file to be reached
  • \n" + "
\n" + "If %f is not specified, then the file name is appended to the specified " + "command.")); +} + +DlgEditor::~DlgEditor() +{ + delete m_dlg; +} + +void DlgEditor::editorChanged(int which) +{ + const int whichEditor = m_dlg->kcfg_ExternalEditor->itemData(which).toInt(); + const QHash::const_iterator it = m_editors.constFind(whichEditor); + QString editor; + if (it != m_editors.constEnd()) + editor = it.value(); + + if (!editor.isEmpty()) { + m_dlg->stackCommands->setCurrentIndex(1); + m_dlg->leReadOnlyCommand->setText(editor); + } else { + m_dlg->stackCommands->setCurrentIndex(0); + } +} + +#include "moc_dlgeditor.cpp" diff --git a/part/dlgeditor.h b/part/dlgeditor.h new file mode 100644 index 0000000..0db8e23 --- /dev/null +++ b/part/dlgeditor.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * 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 DLGEDITOR_H +#define DLGEDITOR_H + +#include +#include + +class Ui_DlgEditorBase; + +class DlgEditor : public QWidget +{ + Q_OBJECT + +public: + explicit DlgEditor(QWidget *parent = nullptr); + ~DlgEditor() override; + +private Q_SLOTS: + void editorChanged(int which); + +private: + Ui_DlgEditorBase *m_dlg; + QHash m_editors; +}; + +#endif diff --git a/part/dlgeditorbase.ui b/part/dlgeditorbase.ui new file mode 100644 index 0000000..a16146e --- /dev/null +++ b/part/dlgeditorbase.ui @@ -0,0 +1,103 @@ + + DlgEditorBase + + + + 0 + 0 + 375 + 108 + + + + + 0 + + + + + Editor + + + + + + Editor: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ExternalEditor + + + + + + + Choose the editor you want to launch when Okular wants to open a source file. + + + + + + + 1 + + + + + 0 + + + + + + + + + + 0 + + + + + true + + + + + + + + + + + Command: + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 4 + + + + + + + + + diff --git a/part/dlggeneral.cpp b/part/dlggeneral.cpp new file mode 100644 index 0000000..feef557 --- /dev/null +++ b/part/dlggeneral.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "dlggeneral.h" + +#include + +#include + +#include "settings.h" +#include "ui_dlggeneralbase.h" + +DlgGeneral::DlgGeneral(QWidget *parent, Okular::EmbedMode embedMode) + : QWidget(parent) +{ + m_dlg = new Ui_DlgGeneralBase(); + m_dlg->setupUi(this); + + if (embedMode == Okular::ViewerWidgetMode) { + 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_BackgroundColor->setEnabled(Okular::Settings::useCustomBackgroundColor()); + m_dlg->kcfg_ShellOpenFileInTabs->setVisible(embedMode == Okular::NativeShellMode); + m_dlg->kcfg_SwitchToTabIfOpen->setEnabled(Okular::Settings::shellOpenFileInTabs()); + + connect(m_dlg->kcfg_UseCustomBackgroundColor, &QCheckBox::toggled, m_dlg->kcfg_BackgroundColor, &QCheckBox::setEnabled); + connect(m_dlg->kcfg_ShellOpenFileInTabs, &QCheckBox::toggled, m_dlg->kcfg_SwitchToTabIfOpen, &QCheckBox::setEnabled); +} + +DlgGeneral::~DlgGeneral() +{ + delete m_dlg; +} + +void DlgGeneral::showEvent(QShowEvent *) +{ +#if OKULAR_FORCE_DRM + m_dlg->kcfg_ObeyDRM->hide(); +#else + if (KAuthorized::authorize(QStringLiteral("skip_drm"))) + m_dlg->kcfg_ObeyDRM->show(); + else + m_dlg->kcfg_ObeyDRM->hide(); +#endif +} diff --git a/part/dlggeneral.h b/part/dlggeneral.h new file mode 100644 index 0000000..af20e33 --- /dev/null +++ b/part/dlggeneral.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _DLGGENERAL_H +#define _DLGGENERAL_H + +#include + +#include "part.h" + +class Ui_DlgGeneralBase; + +class DlgGeneral : public QWidget +{ + Q_OBJECT + +public: + explicit DlgGeneral(QWidget *parent, Okular::EmbedMode embedMode); + ~DlgGeneral() override; + +protected: + void showEvent(QShowEvent *) override; + + Ui_DlgGeneralBase *m_dlg; +}; + +#endif diff --git a/part/dlggeneralbase.ui b/part/dlggeneralbase.ui new file mode 100644 index 0000000..e7ea4a4 --- /dev/null +++ b/part/dlggeneralbase.ui @@ -0,0 +1,488 @@ + + + DlgGeneralBase + + + true + + + + 0 + 0 + 558 + 635 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Appearance + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Use smooth scrolling + + + + + + + Show scroll&bars + + + + + + + true + + + Link the &thumbnails with the page + + + + + + + Show &hints and info messages + + + + + + + Display document title in titlebar if available + + + + + + + When not displaying document title: + + + + + + + QGroupBox {border:0; } + + + true + + + + 8 + + + 0 + + + 0 + + + + + Display file name only + + + true + + + + + + + Display full file path + + + false + + + + + + + + + + 6 + + + 0 + + + + + false + + + + + + + Use custom background color + + + + + + + + + 4 + + + 0 + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 1 + + + + + + + + + + + + + Program Features + + + + + + + + Open new files in &tabs + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 25 + 20 + + + + + + + + Switch to existing tab if file is already open + + + + + + + + + &Obey DRM limitations + + + + + + + &Reload document on file change + + + + + + + Show backend selection dialog + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Right to left reading direction + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + + + + + + View Options + + + + + + Overview &columns: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ViewColumns + + + + + + + 3 + + + 10 + + + + + + + Defines how much of the current viewing area will still be visible when pressing the Page Up/Down keys. + + + &Page Up/Down overlap: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ScrollOverlap + + + + + + + % + + + 50 + + + 5 + + + + + + + Defines the default zoom mode for files which were never opened before. +For files which were opened before the previous zoom is applied. + + + Defines the default zoom mode for files which were never opened before. +For files which were opened before the previous zoom is applied. + + + &Default Zoom: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ZoomMode + + + + + + + Defines the default zoom mode for files which were never opened before. +For files which were opened before the previous zoom is applied. + + + Defines the default zoom mode for files which were never opened before. +For files which were opened before the previous zoom is applied. + + + + 100% + + + + + Fit Width + + + + + Fit Page + + + + + Auto Fit + + + + + + + + + + + Qt::Vertical + + + + 20 + 4 + + + + + + + + + KColorButton + QPushButton +
kcolorbutton.h
+ + useDefaultBackgroundColor() + +
+
+ + kiconloader.h + + + +
diff --git a/part/dlgperformance.cpp b/part/dlgperformance.cpp new file mode 100644 index 0000000..b6efdf5 --- /dev/null +++ b/part/dlgperformance.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "dlgperformance.h" + +#include +#include + +#include + +#include "settings_core.h" +#include "ui_dlgperformancebase.h" + +DlgPerformance::DlgPerformance(QWidget *parent) + : QWidget(parent) +{ + m_dlg = new Ui_DlgPerformanceBase(); + m_dlg->setupUi(this); + + QFont labelFont = m_dlg->descLabel->font(); + labelFont.setBold(true); + m_dlg->descLabel->setFont(labelFont); + + m_dlg->cpuLabel->setPixmap(QIcon::fromTheme(QStringLiteral("cpu")).pixmap(32)); + // m_dlg->memoryLabel->setPixmap( QIcon::fromTheme( "kcmmemory" ).pixmap( 32 ) ); // TODO: enable again when proper icon is available + + m_dlg->memoryLevelGroup->setId(m_dlg->lowRadio, 0); + m_dlg->memoryLevelGroup->setId(m_dlg->normalRadio, 1); + m_dlg->memoryLevelGroup->setId(m_dlg->aggressiveRadio, 2); + m_dlg->memoryLevelGroup->setId(m_dlg->greedyRadio, 3); + + connect(m_dlg->memoryLevelGroup, static_cast(&QButtonGroup::buttonClicked), this, &DlgPerformance::radioGroup_changed); +} + +DlgPerformance::~DlgPerformance() +{ + delete m_dlg; +} + +void DlgPerformance::radioGroup_changed(int which) +{ + switch (which) { + case 0: + m_dlg->descLabel->setText(i18n("Keeps used memory as low as possible. Do not reuse anything. (For systems with low memory.)")); + break; + case 1: + m_dlg->descLabel->setText(i18n("A good compromise between memory usage and speed gain. Preload next page and boost searches. (For systems with 2GB of memory, typically.)")); + break; + case 2: + m_dlg->descLabel->setText(i18n("Keeps everything in memory. Preload next pages. Boost searches. (For systems with more than 4GB of memory.)")); + break; + case 3: + // xgettext: no-c-format + m_dlg->descLabel->setText(i18n("Loads and keeps everything in memory. Preload all pages. (Will use at maximum 50% of your total memory or your free memory, whatever is bigger.)")); + break; + } +} + +#include "moc_dlgperformance.cpp" diff --git a/part/dlgperformance.h b/part/dlgperformance.h new file mode 100644 index 0000000..2f1ad38 --- /dev/null +++ b/part/dlgperformance.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2006 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 _DLGPERFORMANCE_H +#define _DLGPERFORMANCE_H + +#include + +class Ui_DlgPerformanceBase; + +class DlgPerformance : public QWidget +{ + Q_OBJECT + +public: + explicit DlgPerformance(QWidget *parent = nullptr); + ~DlgPerformance() override; + +protected Q_SLOTS: + void radioGroup_changed(int which); + +protected: + Ui_DlgPerformanceBase *m_dlg; +}; + +#endif diff --git a/part/dlgperformancebase.ui b/part/dlgperformancebase.ui new file mode 100644 index 0000000..75b7530 --- /dev/null +++ b/part/dlgperformancebase.ui @@ -0,0 +1,355 @@ + + + DlgPerformanceBase + + + + 0 + 0 + 316 + 397 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + CPU Usage + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Enable &transparency effects + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 21 + 1 + + + + + + + + + + + + + + + Memory Usage + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + true + + + + + + &Low + + + memoryLevelGroup + + + + + + + Nor&mal (default) + + + memoryLevelGroup + + + + + + + Aggr&essive + + + memoryLevelGroup + + + + + + + G&reedy + + + memoryLevelGroup + + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 21 + 1 + + + + + + + + + + + + + + + Qt::PlainText + + + Qt::AlignVCenter + + + true + + + + + + + + + + Rendering + + + + + + Enable Text Antialias + + + + + + + Enable Graphics Antialias + + + + + + + Enable Text Hinting + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 4 + + + + + + + + kiconloader.h + + + + + + + diff --git a/part/dlgpresentation.cpp b/part/dlgpresentation.cpp new file mode 100644 index 0000000..25ed347 --- /dev/null +++ b/part/dlgpresentation.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2006,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. * + ***************************************************************************/ + +#include "dlgpresentation.h" + +#include "ui_dlgpresentationbase.h" +#include "widgetdrawingtools.h" + +#include +#include +#include +#include + +#include "settings.h" + +DlgPresentation::DlgPresentation(QWidget *parent) + : QWidget(parent) +{ + m_dlg = new Ui_DlgPresentationBase(); + m_dlg->setupUi(this); + + WidgetDrawingTools *kcfg_DrawingTools = new WidgetDrawingTools(m_dlg->annotationToolsGroupBox); + m_dlg->verticalLayout_4->addWidget(kcfg_DrawingTools); + kcfg_DrawingTools->setObjectName(QStringLiteral("kcfg_DrawingTools")); + + QStringList choices; + choices.append(i18nc("@label:listbox The current screen, for the presentation mode", "Current Screen")); + choices.append(i18nc("@label:listbox The default screen for the presentation mode", "Default Screen")); + const int screenCount = QGuiApplication::screens().count(); + for (int i = 0; i < screenCount; ++i) { + choices.append(i18nc("@label:listbox %1 is the screen number (0, 1, ...)", "Screen %1", i)); + } + m_dlg->screenCombo->addItems(choices); + + const int screen = Okular::Settings::slidesScreen(); + if (screen >= -2 && screen < screenCount) { + m_dlg->screenCombo->setCurrentIndex(screen + 2); + } else { + m_dlg->screenCombo->setCurrentIndex(0); + Okular::Settings::setSlidesScreen(-2); + } + + m_dlg->kcfg_SlidesAdvanceTime->setSuffix(ki18ncp("Advance every %1 seconds", " second", " seconds")); + + connect(m_dlg->screenCombo, static_cast(&QComboBox::activated), this, &DlgPresentation::screenComboChanged); + connect(m_dlg->kcfg_SlidesAdvance, &QAbstractButton::toggled, m_dlg->kcfg_SlidesAdvanceTime, &QWidget::setEnabled); +} + +DlgPresentation::~DlgPresentation() +{ + delete m_dlg; +} + +void DlgPresentation::screenComboChanged(int which) +{ + Okular::Settings::setSlidesScreen(which - 2); +} + +#include "moc_dlgpresentation.cpp" diff --git a/part/dlgpresentation.h b/part/dlgpresentation.h new file mode 100644 index 0000000..cc4e5b9 --- /dev/null +++ b/part/dlgpresentation.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2006,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 _DLGPRESENTATION_H +#define _DLGPRESENTATION_H + +#include + +class Ui_DlgPresentationBase; + +class DlgPresentation : public QWidget +{ + Q_OBJECT + +public: + explicit DlgPresentation(QWidget *parent = nullptr); + ~DlgPresentation() override; + +protected Q_SLOTS: + void screenComboChanged(int which); + +protected: + Ui_DlgPresentationBase *m_dlg; +}; + +#endif diff --git a/part/dlgpresentationbase.ui b/part/dlgpresentationbase.ui new file mode 100644 index 0000000..e1dcb9d --- /dev/null +++ b/part/dlgpresentationbase.ui @@ -0,0 +1,379 @@ + + + DlgPresentationBase + + + + 0 + 0 + 400 + 525 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Navigation + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Advance every: + + + + + + + false + + + 5 + + + + + + + + + Loop after last page + + + + + + + + + Touch navigation: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_SlidesTapNavigation + + + + + + + + Tap left/right side to go back/forward + + + + + Tap anywhere to go forward + + + + + Disabled + + + + + + + + + + + + + Appearance + + + + + + + + Background color: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_SlidesBackgroundColor + + + + + + + + + + Mouse cursor: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_SlidesCursor + + + + + + + + Hidden After Delay + + + + + Always Visible + + + + + Always Hidden + + + + + + + + + + Show &progress indicator + + + + + + + Show s&ummary page + + + + + + + + + + Enable transitions + + + true + + + true + + + + + + Default transition: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_SlidesTransition + + + + + + + + Blinds Vertical + + + + + Blinds Horizontal + + + + + Box In + + + + + Box Out + + + + + Dissolve + + + + + Fade + + + + + Glitter Down + + + + + Glitter Right + + + + + Glitter Right-Down + + + + + Random Transition + + + + + Replace + + + + + Split Horizontal In + + + + + Split Horizontal Out + + + + + Split Vertical In + + + + + Split Vertical Out + + + + + Wipe Down + + + + + Wipe Right + + + + + Wipe Left + + + + + Wipe Up + + + + + + + + + + + Placement + + + + + + Screen: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + screenCombo + + + + + + + + + + + + + Drawing Tool Configuration + + + + + + + + + KColorButton + QPushButton +
kcolorbutton.h
+
+ + KPluralHandlingSpinBox + QSpinBox +
KPluralHandlingSpinBox
+
+
+ +
diff --git a/part/drawingtoolactions.cpp b/part/drawingtoolactions.cpp new file mode 100644 index 0000000..ab132af --- /dev/null +++ b/part/drawingtoolactions.cpp @@ -0,0 +1,249 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * Copyright (C) 2015 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "drawingtoolactions.h" + +#include "debug_ui.h" +#include "settings.h" + +#include +#include + +#include +#include +#include + +class ColorAction : public QAction +{ + Q_OBJECT + +public: + explicit ColorAction(KActionCollection *parent) + : QAction(parent) + { + } + + void setColor(const QColor &color) + { + setIcon(QIcon(new ColorActionIconEngine(color))); + } + +protected: + class ColorActionIconEngine : public QIconEngine + { + public: + explicit ColorActionIconEngine(const QColor &color) + : m_color(color) + { + } + + ColorActionIconEngine(const ColorActionIconEngine &) = delete; + ColorActionIconEngine &operator=(const ColorActionIconEngine &) = delete; + + // No one needs clone(), but it’s pure virtual + QIconEngine *clone() const override + { + return nullptr; + } + + QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) override + { + QPixmap pixmap(size); + pixmap.fill(Qt::transparent); + Q_ASSERT(pixmap.hasAlphaChannel()); + + QPainter painter(&pixmap); + paint(&painter, QRect(QPoint(0, 0), size), mode, state); + return pixmap; + } + + void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override + { + Q_UNUSED(mode) + + // Assume that rect is square and at position (0, 0) + int squareSize = rect.height() * 0.8; + int squareOffset = (rect.height() - squareSize) / 2; + + painter->fillRect(squareOffset, squareOffset, squareSize, squareSize, m_color); + + if (state == QIcon::On) { + QFont checkmarkFont = painter->font(); + checkmarkFont.setPixelSize(squareSize * 0.9); + painter->setFont(checkmarkFont); + + const int lightness = ((m_color.red() * 299) + (m_color.green() * 587) + (m_color.blue() * 114)) / 1000; + painter->setPen(lightness < 128 ? Qt::white : Qt::black); + + painter->drawText(QRect(squareOffset, squareOffset, squareSize, squareSize), Qt::AlignCenter, QStringLiteral("\u2713")); + } + } + + protected: + QColor m_color; + }; +}; + +DrawingToolActions::DrawingToolActions(KActionCollection *parent) + : QObject(parent) +{ + loadTools(); +} + +DrawingToolActions::~DrawingToolActions() +{ +} + +QList DrawingToolActions::actions() const +{ + return m_actions; +} + +void DrawingToolActions::reparseConfig() +{ + qDeleteAll(m_actions); + m_actions.clear(); + loadTools(); +} + +void DrawingToolActions::actionTriggered() +{ + QAction *action = qobject_cast(sender()); + + if (action) { + if (action->isChecked()) { + for (QAction *btn : qAsConst(m_actions)) { + if (action != btn) { + btn->setChecked(false); + } + } + + emit changeEngine(action->property("__document").value()); + } else { + emit changeEngine(QDomElement()); + } + } +} + +void DrawingToolActions::loadTools() +{ + const QStringList drawingTools = Okular::Settings::drawingTools(); + + QDomDocument doc; + QDomElement drawingDefinition = doc.createElement(QStringLiteral("drawingTools")); + for (const QString &drawingXml : drawingTools) { + QDomDocument entryParser; + if (entryParser.setContent(drawingXml)) + drawingDefinition.appendChild(doc.importNode(entryParser.documentElement(), true)); + else + qCWarning(OkularUiDebug) << "Skipping malformed quick selection XML in QuickSelectionTools setting"; + } + + // Create the AnnotationToolItems from the XML dom tree + QDomNode drawingDescription = drawingDefinition.firstChild(); + while (drawingDescription.isElement()) { + const QDomElement toolElement = drawingDescription.toElement(); + if (toolElement.tagName() == QLatin1String("tool")) { + QString tooltip; + QString width; + QString colorStr; + QString opacity; + + const QString name = toolElement.attribute(QStringLiteral("name")); + if (toolElement.attribute(QStringLiteral("default"), QStringLiteral("false")) == QLatin1String("true")) { + tooltip = i18n(name.toLatin1().constData()); + } else { + tooltip = name; + } + + const QDomNodeList engineNodeList = toolElement.elementsByTagName(QStringLiteral("engine")); + if (engineNodeList.size() > 0) { + const QDomElement engineEl = engineNodeList.item(0).toElement(); + if (engineEl.hasAttribute(QStringLiteral("color"))) { + colorStr = engineEl.attribute(QStringLiteral("color")); + } + + const QDomNodeList annotationList = engineEl.elementsByTagName(QStringLiteral("annotation")); + if (annotationList.size() > 0) { + const QDomElement annotationEl = annotationList.item(0).toElement(); + if (annotationEl.hasAttribute(QStringLiteral("width"))) { + width = annotationEl.attribute(QStringLiteral("width")); + opacity = annotationEl.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")); + } + } + } + + QDomDocument doc(QStringLiteral("engine")); + QDomElement root = doc.createElement(QStringLiteral("engine")); + root.setAttribute(QStringLiteral("color"), colorStr); + doc.appendChild(root); + QDomElement annElem = doc.createElement(QStringLiteral("annotation")); + root.appendChild(annElem); + annElem.setAttribute(QStringLiteral("type"), QStringLiteral("Ink")); + annElem.setAttribute(QStringLiteral("color"), colorStr); + annElem.setAttribute(QStringLiteral("width"), width); + annElem.setAttribute(QStringLiteral("opacity"), opacity); + + const QString text = i18n("Drawing Tool: %1", tooltip); + createToolAction(text, tooltip, colorStr, root); + } + + drawingDescription = drawingDescription.nextSibling(); + } + + // add erasure action + { + QDomDocument doc(QStringLiteral("engine")); + QDomElement root = doc.createElement(QStringLiteral("engine")); + root.setAttribute(QStringLiteral("color"), QStringLiteral("transparent")); + root.setAttribute(QStringLiteral("compositionMode"), QStringLiteral("clear")); + doc.appendChild(root); + QDomElement annElem = doc.createElement(QStringLiteral("annotation")); + root.appendChild(annElem); + annElem.setAttribute(QStringLiteral("type"), QStringLiteral("Ink")); + annElem.setAttribute(QStringLiteral("color"), QStringLiteral("transparent")); + annElem.setAttribute(QStringLiteral("width"), 20); + + KActionCollection *ac = static_cast(parent()); + QAction *action = new QAction(ac); + action->setText(i18n("Eraser")); + action->setToolTip(i18n("Eraser")); + action->setCheckable(true); + action->setIcon(QIcon::fromTheme(QStringLiteral("draw-eraser"))); + action->setProperty("__document", QVariant::fromValue(root)); + + m_actions.append(action); + + ac->addAction(QStringLiteral("presentation_drawing_eraser"), action); + + connect(action, &QAction::triggered, this, &DrawingToolActions::actionTriggered); + } +} + +void DrawingToolActions::createToolAction(const QString &text, const QString &toolName, const QString &colorName, const QDomElement &root) +{ + KActionCollection *ac = static_cast(parent()); + ColorAction *action = new ColorAction(ac); + action->setText(text); + action->setToolTip(toolName); + action->setCheckable(true); + action->setColor(QColor(colorName)); + action->setEnabled(false); + + action->setProperty("__document", QVariant::fromValue(root)); + + m_actions.append(action); + + ac->addAction(QStringLiteral("presentation_drawing_%1").arg(toolName), action); + + connect(action, &QAction::triggered, this, &DrawingToolActions::actionTriggered); +} + +#include "drawingtoolactions.moc" diff --git a/part/drawingtoolactions.h b/part/drawingtoolactions.h new file mode 100644 index 0000000..6f63210 --- /dev/null +++ b/part/drawingtoolactions.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * Copyright (C) 2015 by Albert Astals Cid * + * * + * 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 DRAWINGTOOLACTIONS_H +#define DRAWINGTOOLACTIONS_H + +#include +#include + +class QAction; +class KActionCollection; + +class DrawingToolActions : public QObject +{ + Q_OBJECT +public: + explicit DrawingToolActions(KActionCollection *parent); + ~DrawingToolActions() override; + + QList actions() const; + + void reparseConfig(); + +Q_SIGNALS: + void changeEngine(const QDomElement &doc); + void actionsRecreated(); + +private Q_SLOTS: + void actionTriggered(); + +private: + void loadTools(); + void createToolAction(const QString &text, const QString &toolName, const QString &colorName, const QDomElement &root); + + QList m_actions; +}; + +Q_DECLARE_METATYPE(QDomElement) + +#endif // DRAWINGTOOLACTIONS_H diff --git a/part/editannottooldialog.cpp b/part/editannottooldialog.cpp new file mode 100644 index 0000000..1ef262d --- /dev/null +++ b/part/editannottooldialog.cpp @@ -0,0 +1,473 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * Copyright (C) 2015 by Laurent Montel * + * * + * 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. * + ***************************************************************************/ + +#include "editannottooldialog.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "annotationwidgets.h" +#include "core/annotations.h" +#include "pageviewannotator.h" + +EditAnnotToolDialog::EditAnnotToolDialog(QWidget *parent, const QDomElement &initialState, bool builtinTool) + : QDialog(parent) + , m_stubann(nullptr) + , m_annotationWidget(nullptr) +{ + m_builtinTool = builtinTool; + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); // NOLINT(bugprone-suspicious-enum-usage) + connect(buttonBox, &QDialogButtonBox::accepted, this, &EditAnnotToolDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &EditAnnotToolDialog::reject); + okButton->setDefault(true); + + QLabel *tmplabel; + QWidget *widget = new QWidget(this); + QGridLayout *widgetLayout = new QGridLayout(widget); + + mainLayout->addWidget(widget); + mainLayout->addWidget(buttonBox); + + m_name = new KLineEdit(widget); + m_name->setReadOnly(m_builtinTool); + mainLayout->addWidget(m_name); + tmplabel = new QLabel(i18n("&Name:"), widget); + mainLayout->addWidget(tmplabel); + tmplabel->setBuddy(m_name); + widgetLayout->addWidget(tmplabel, 0, 0, Qt::AlignRight); + widgetLayout->addWidget(m_name, 0, 1); + + m_type = new KComboBox(false, widget); + m_type->setVisible(!m_builtinTool); + mainLayout->addWidget(m_type); + connect(m_type, static_cast(&KComboBox::currentIndexChanged), this, &EditAnnotToolDialog::slotTypeChanged); + tmplabel = new QLabel(i18n("&Type:"), widget); + mainLayout->addWidget(tmplabel); + tmplabel->setBuddy(m_type); + tmplabel->setVisible(!m_builtinTool); + widgetLayout->addWidget(tmplabel, 1, 0, Qt::AlignRight); + widgetLayout->addWidget(m_type, 1, 1); + + m_toolIcon = new QLabel(widget); + mainLayout->addWidget(m_toolIcon); + m_toolIcon->setAlignment(Qt::AlignRight | Qt::AlignTop); + m_toolIcon->setMinimumSize(40, 32); + widgetLayout->addWidget(m_toolIcon, 0, 2, 2, 1); + + m_appearanceBox = new QGroupBox(i18n("Appearance"), widget); + mainLayout->addWidget(m_appearanceBox); + m_appearanceBox->setLayout(new QVBoxLayout(m_appearanceBox)); + widgetLayout->addWidget(m_appearanceBox, 2, 0, 1, 3); + + // Populate combobox with annotation types + m_type->addItem(i18n("Pop-up Note"), QVariant::fromValue(ToolNoteLinked)); + m_type->addItem(i18n("Inline Note"), QVariant::fromValue(ToolNoteInline)); + m_type->addItem(i18n("Freehand Line"), QVariant::fromValue(ToolInk)); + m_type->addItem(i18n("Straight Line"), QVariant::fromValue(ToolStraightLine)); + m_type->addItem(i18n("Polygon"), QVariant::fromValue(ToolPolygon)); + m_type->addItem(i18n("Text markup"), QVariant::fromValue(ToolTextMarkup)); + m_type->addItem(i18n("Geometrical shape"), QVariant::fromValue(ToolGeometricalShape)); + m_type->addItem(i18n("Stamp"), QVariant::fromValue(ToolStamp)); + m_type->addItem(i18n("Typewriter"), QVariant::fromValue(ToolTypewriter)); + + createStubAnnotation(); + + if (initialState.isNull()) { + setWindowTitle(i18n("Create annotation tool")); + } else { + setWindowTitle(i18n("Edit annotation tool")); + loadTool(initialState); + } + + rebuildAppearanceBox(); + updateDefaultNameAndIcon(); +} + +EditAnnotToolDialog::~EditAnnotToolDialog() +{ + delete m_stubann; + delete m_annotationWidget; +} + +QString EditAnnotToolDialog::name() const +{ + return m_name->text(); +} + +QDomDocument EditAnnotToolDialog::toolXml() const +{ + const ToolType toolType = m_type->itemData(m_type->currentIndex()).value(); + + QDomDocument doc; + QDomElement toolElement = doc.createElement(QStringLiteral("tool")); + QDomElement engineElement = doc.createElement(QStringLiteral("engine")); + QDomElement annotationElement = doc.createElement(QStringLiteral("annotation")); + doc.appendChild(toolElement); + toolElement.appendChild(engineElement); + engineElement.appendChild(annotationElement); + + const QString color = m_stubann->style().color().name(QColor::HexArgb); + const QString opacity = QString::number(m_stubann->style().opacity()); + const QString width = QString::number(m_stubann->style().width()); + + if (toolType == ToolNoteLinked) { + Okular::TextAnnotation *ta = static_cast(m_stubann); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("note-linked")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PickPoint")); + engineElement.setAttribute(QStringLiteral("color"), color); + engineElement.setAttribute(QStringLiteral("hoverIcon"), QStringLiteral("tool-note")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Text")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("icon"), ta->textIcon()); + } else if (toolType == ToolNoteInline) { + Okular::TextAnnotation *ta = static_cast(m_stubann); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("note-inline")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PickPoint")); + engineElement.setAttribute(QStringLiteral("color"), color); + engineElement.setAttribute(QStringLiteral("hoverIcon"), QStringLiteral("tool-note-inline")); + engineElement.setAttribute(QStringLiteral("block"), QStringLiteral("true")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("FreeText")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), width); + if (ta->inplaceAlignment() != 0) + annotationElement.setAttribute(QStringLiteral("align"), ta->inplaceAlignment()); + if (ta->textFont() != QApplication::font()) + annotationElement.setAttribute(QStringLiteral("font"), ta->textFont().toString()); + } else if (toolType == ToolInk) { + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("ink")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("SmoothLine")); + engineElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Ink")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), width); + } else if (toolType == ToolStraightLine) { + Okular::LineAnnotation *la = static_cast(m_stubann); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("straight-line")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PolyLine")); + engineElement.setAttribute(QStringLiteral("color"), color); + engineElement.setAttribute(QStringLiteral("points"), QStringLiteral("2")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Line")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), width); + if (la->lineLeadingForwardPoint() != 0 || la->lineLeadingBackwardPoint() != 0) { + annotationElement.setAttribute(QStringLiteral("leadFwd"), QString::number(la->lineLeadingForwardPoint())); + annotationElement.setAttribute(QStringLiteral("leadBack"), QString::number(la->lineLeadingBackwardPoint())); + } + annotationElement.setAttribute(QStringLiteral("startStyle"), QString::number(la->lineStartStyle())); + annotationElement.setAttribute(QStringLiteral("endStyle"), QString::number(la->lineEndStyle())); + } else if (toolType == ToolPolygon) { + Okular::LineAnnotation *la = static_cast(m_stubann); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("polygon")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PolyLine")); + engineElement.setAttribute(QStringLiteral("color"), color); + engineElement.setAttribute(QStringLiteral("points"), QStringLiteral("-1")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Line")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), width); + if (la->lineInnerColor().isValid()) { + annotationElement.setAttribute(QStringLiteral("innerColor"), la->lineInnerColor().name()); + } + } else if (toolType == ToolTextMarkup) { + Okular::HighlightAnnotation *ha = static_cast(m_stubann); + + switch (ha->highlightType()) { + case Okular::HighlightAnnotation::Highlight: + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("highlight")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Highlight")); + break; + case Okular::HighlightAnnotation::Squiggly: + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("squiggly")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Squiggly")); + break; + case Okular::HighlightAnnotation::Underline: + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("underline")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Underline")); + break; + case Okular::HighlightAnnotation::StrikeOut: + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("strikeout")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("StrikeOut")); + break; + } + + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("TextSelector")); + engineElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("color"), color); + } else if (toolType == ToolGeometricalShape) { + Okular::GeomAnnotation *ga = static_cast(m_stubann); + + if (ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle) { + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("ellipse")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("GeomCircle")); + } else { + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("rectangle")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("GeomSquare")); + } + + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PickPoint")); + engineElement.setAttribute(QStringLiteral("color"), color); + engineElement.setAttribute(QStringLiteral("block"), QStringLiteral("true")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), width); + + if (ga->geometricalInnerColor().isValid()) + annotationElement.setAttribute(QStringLiteral("innerColor"), ga->geometricalInnerColor().name()); + } else if (toolType == ToolStamp) { + Okular::StampAnnotation *sa = static_cast(m_stubann); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("stamp")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PickPoint")); + engineElement.setAttribute(QStringLiteral("hoverIcon"), sa->stampIconName()); + engineElement.setAttribute(QStringLiteral("size"), QStringLiteral("64")); + engineElement.setAttribute(QStringLiteral("block"), QStringLiteral("true")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Stamp")); + annotationElement.setAttribute(QStringLiteral("icon"), sa->stampIconName()); + } else if (toolType == ToolTypewriter) { + Okular::TextAnnotation *ta = static_cast(m_stubann); + const QString textColor = ta->textColor().name(); + toolElement.setAttribute(QStringLiteral("type"), QStringLiteral("typewriter")); + engineElement.setAttribute(QStringLiteral("type"), QStringLiteral("PickPoint")); + engineElement.setAttribute(QStringLiteral("block"), QStringLiteral("true")); + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Typewriter")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("textColor"), textColor); + annotationElement.setAttribute(QStringLiteral("width"), width); + if (ta->textFont() != QApplication::font()) + annotationElement.setAttribute(QStringLiteral("font"), ta->textFont().toString()); + } + + if (opacity != QStringLiteral("1")) + annotationElement.setAttribute(QStringLiteral("opacity"), opacity); + + return doc; +} + +void EditAnnotToolDialog::createStubAnnotation() +{ + const ToolType toolType = m_type->itemData(m_type->currentIndex()).value(); + + // Delete previous stub annotation, if any + delete m_stubann; + + // Create stub annotation + if (toolType == ToolNoteLinked) { + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + ta->setTextType(Okular::TextAnnotation::Linked); + ta->setTextIcon(QStringLiteral("Note")); + ta->style().setColor(Qt::yellow); + m_stubann = ta; + } else if (toolType == ToolNoteInline) { + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + ta->setTextType(Okular::TextAnnotation::InPlace); + ta->style().setWidth(1.0); + ta->style().setColor(Qt::yellow); + m_stubann = ta; + } else if (toolType == ToolInk) { + m_stubann = new Okular::InkAnnotation(); + m_stubann->style().setWidth(2.0); + m_stubann->style().setColor(Qt::green); + } else if (toolType == ToolStraightLine) { + Okular::LineAnnotation *la = new Okular::LineAnnotation(); + la->setLinePoints(QLinkedList() << Okular::NormalizedPoint(0, 0) << Okular::NormalizedPoint(1, 0)); + la->style().setColor(QColor(0xff, 0xe0, 0x00)); + m_stubann = la; + } else if (toolType == ToolPolygon) { + Okular::LineAnnotation *la = new Okular::LineAnnotation(); + la->setLinePoints(QLinkedList() << Okular::NormalizedPoint(0, 0) << Okular::NormalizedPoint(1, 0) << Okular::NormalizedPoint(1, 1)); + la->setLineClosed(true); + la->style().setColor(QColor(0x00, 0x7e, 0xee)); + m_stubann = la; + } else if (toolType == ToolTextMarkup) { + m_stubann = new Okular::HighlightAnnotation(); + m_stubann->style().setColor(Qt::yellow); + } else if (toolType == ToolGeometricalShape) { + Okular::GeomAnnotation *ga = new Okular::GeomAnnotation(); + ga->setGeometricalType(Okular::GeomAnnotation::InscribedCircle); + ga->style().setWidth(5.0); + ga->style().setColor(Qt::cyan); + m_stubann = ga; + } else if (toolType == ToolStamp) { + Okular::StampAnnotation *sa = new Okular::StampAnnotation(); + sa->setStampIconName(QStringLiteral("okular")); + m_stubann = sa; + } else if (toolType == ToolTypewriter) { + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + ta->setTextType(Okular::TextAnnotation::InPlace); + ta->setInplaceIntent(Okular::TextAnnotation::TypeWriter); + ta->style().setWidth(0.0); + ta->style().setColor(QColor(255, 255, 255, 0)); + ta->setTextColor(Qt::black); + m_stubann = ta; + } +} + +void EditAnnotToolDialog::rebuildAppearanceBox() +{ + // Remove previous widget (if any) + if (m_annotationWidget) { + delete m_annotationWidget->appearanceWidget(); + delete m_annotationWidget; + } + + m_annotationWidget = AnnotationWidgetFactory::widgetFor(m_stubann); + m_annotationWidget->setAnnotTypeEditable(!m_builtinTool); + m_appearanceBox->layout()->addWidget(m_annotationWidget->appearanceWidget()); + + connect(m_annotationWidget, &AnnotationWidget::dataChanged, this, &EditAnnotToolDialog::slotDataChanged); +} + +void EditAnnotToolDialog::updateDefaultNameAndIcon() +{ + QDomDocument doc = toolXml(); + QDomElement toolElement = doc.documentElement(); + m_name->setPlaceholderText(PageViewAnnotator::defaultToolName(toolElement)); + m_toolIcon->setPixmap(PageViewAnnotator::makeToolPixmap(toolElement)); +} + +void EditAnnotToolDialog::setToolType(ToolType newType) +{ + int idx = -1; + + for (int i = 0; idx == -1 && i < m_type->count(); ++i) { + if (m_type->itemData(i).value() == newType) + idx = i; + } + + // The following call also results in createStubAnnotation being called + m_type->setCurrentIndex(idx); +} + +void EditAnnotToolDialog::loadTool(const QDomElement &toolElement) +{ + const QDomElement engineElement = toolElement.elementsByTagName(QStringLiteral("engine")).item(0).toElement(); + const QDomElement annotationElement = engineElement.elementsByTagName(QStringLiteral("annotation")).item(0).toElement(); + const QString annotType = toolElement.attribute(QStringLiteral("type")); + + if (annotType == QLatin1String("ellipse")) { + setToolType(ToolGeometricalShape); + Okular::GeomAnnotation *ga = static_cast(m_stubann); + ga->setGeometricalType(Okular::GeomAnnotation::InscribedCircle); + if (annotationElement.hasAttribute(QStringLiteral("innerColor"))) + ga->setGeometricalInnerColor(QColor(annotationElement.attribute(QStringLiteral("innerColor")))); + } else if (annotType == QLatin1String("highlight")) { + setToolType(ToolTextMarkup); + Okular::HighlightAnnotation *ha = static_cast(m_stubann); + ha->setHighlightType(Okular::HighlightAnnotation::Highlight); + } else if (annotType == QLatin1String("ink")) { + setToolType(ToolInk); + } else if (annotType == QLatin1String("note-inline")) { + setToolType(ToolNoteInline); + Okular::TextAnnotation *ta = static_cast(m_stubann); + if (annotationElement.hasAttribute(QStringLiteral("align"))) + ta->setInplaceAlignment(annotationElement.attribute(QStringLiteral("align")).toInt()); + if (annotationElement.hasAttribute(QStringLiteral("font"))) { + QFont f; + f.fromString(annotationElement.attribute(QStringLiteral("font"))); + ta->setTextFont(f); + } + } else if (annotType == QLatin1String("note-linked")) { + setToolType(ToolNoteLinked); + Okular::TextAnnotation *ta = static_cast(m_stubann); + ta->setTextIcon(annotationElement.attribute(QStringLiteral("icon"))); + } else if (annotType == QLatin1String("polygon")) { + setToolType(ToolPolygon); + Okular::LineAnnotation *la = static_cast(m_stubann); + if (annotationElement.hasAttribute(QStringLiteral("innerColor"))) + la->setLineInnerColor(QColor(annotationElement.attribute(QStringLiteral("innerColor")))); + } else if (annotType == QLatin1String("rectangle")) { + setToolType(ToolGeometricalShape); + Okular::GeomAnnotation *ga = static_cast(m_stubann); + ga->setGeometricalType(Okular::GeomAnnotation::InscribedSquare); + if (annotationElement.hasAttribute(QStringLiteral("innerColor"))) + ga->setGeometricalInnerColor(QColor(annotationElement.attribute(QStringLiteral("innerColor")))); + } else if (annotType == QLatin1String("squiggly")) { + setToolType(ToolTextMarkup); + Okular::HighlightAnnotation *ha = static_cast(m_stubann); + ha->setHighlightType(Okular::HighlightAnnotation::Squiggly); + } else if (annotType == QLatin1String("stamp")) { + setToolType(ToolStamp); + Okular::StampAnnotation *sa = static_cast(m_stubann); + sa->setStampIconName(annotationElement.attribute(QStringLiteral("icon"))); + } else if (annotType == QLatin1String("straight-line")) { + setToolType(ToolStraightLine); + Okular::LineAnnotation *la = static_cast(m_stubann); + if (annotationElement.hasAttribute(QStringLiteral("leadFwd"))) + la->setLineLeadingForwardPoint(annotationElement.attribute(QStringLiteral("leadFwd")).toDouble()); + if (annotationElement.hasAttribute(QStringLiteral("leadBack"))) + la->setLineLeadingBackwardPoint(annotationElement.attribute(QStringLiteral("leadBack")).toDouble()); + if (annotationElement.hasAttribute(QStringLiteral("startStyle"))) + la->setLineStartStyle((Okular::LineAnnotation::TermStyle)annotationElement.attribute(QStringLiteral("startStyle")).toInt()); + if (annotationElement.hasAttribute(QStringLiteral("endStyle"))) + la->setLineEndStyle((Okular::LineAnnotation::TermStyle)annotationElement.attribute(QStringLiteral("endStyle")).toInt()); + } else if (annotType == QLatin1String("strikeout")) { + setToolType(ToolTextMarkup); + Okular::HighlightAnnotation *ha = static_cast(m_stubann); + ha->setHighlightType(Okular::HighlightAnnotation::StrikeOut); + } else if (annotType == QLatin1String("underline")) { + setToolType(ToolTextMarkup); + Okular::HighlightAnnotation *ha = static_cast(m_stubann); + ha->setHighlightType(Okular::HighlightAnnotation::Underline); + } else if (annotType == QLatin1String("typewriter")) { + setToolType(ToolTypewriter); + Okular::TextAnnotation *ta = static_cast(m_stubann); + if (annotationElement.hasAttribute(QStringLiteral("font"))) { + QFont f; + f.fromString(annotationElement.attribute(QStringLiteral("font"))); + ta->setTextFont(f); + } + if (annotationElement.hasAttribute(QStringLiteral("textColor"))) + ta->setTextColor(QColor(annotationElement.attribute(QStringLiteral("textColor")))); + } + + // Common properties + if (annotationElement.hasAttribute(QStringLiteral("color"))) + m_stubann->style().setColor(QColor(annotationElement.attribute(QStringLiteral("color")))); + if (annotationElement.hasAttribute(QStringLiteral("opacity"))) + m_stubann->style().setOpacity(annotationElement.attribute(QStringLiteral("opacity")).toDouble()); + if (annotationElement.hasAttribute(QStringLiteral("width"))) + m_stubann->style().setWidth(annotationElement.attribute(QStringLiteral("width")).toDouble()); + + if (toolElement.hasAttribute(QStringLiteral("name"))) + m_name->setText(toolElement.attribute(QStringLiteral("name"))); +} + +void EditAnnotToolDialog::slotTypeChanged() +{ + createStubAnnotation(); + rebuildAppearanceBox(); + updateDefaultNameAndIcon(); +} + +void EditAnnotToolDialog::slotDataChanged() +{ + // Mirror changes back in the stub annotation + m_annotationWidget->applyChanges(); + + updateDefaultNameAndIcon(); +} diff --git a/part/editannottooldialog.h b/part/editannottooldialog.h new file mode 100644 index 0000000..1cf385a --- /dev/null +++ b/part/editannottooldialog.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * * + * 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 EDITANNOTTOOLDIALOG_H +#define EDITANNOTTOOLDIALOG_H + +#include +#include +class KLineEdit; +class KComboBox; +class QLabel; +class QListWidget; +class QGroupBox; +class AnnotationWidget; + +namespace Okular +{ +class Annotation; +} + +class EditAnnotToolDialog : public QDialog +{ + Q_OBJECT + +public: + enum ToolType { ToolNoteLinked, ToolNoteInline, ToolInk, ToolStraightLine, ToolPolygon, ToolTextMarkup, ToolGeometricalShape, ToolStamp, ToolTypewriter }; + + explicit EditAnnotToolDialog(QWidget *parent = nullptr, const QDomElement &initialState = QDomElement(), bool builtinTool = false); + ~EditAnnotToolDialog() override; + QString name() const; + QDomDocument toolXml() const; + +private: + void createStubAnnotation(); + void rebuildAppearanceBox(); + void updateDefaultNameAndIcon(); + void setToolType(ToolType newType); + void loadTool(const QDomElement &toolElement); + + KLineEdit *m_name; + KComboBox *m_type; + QLabel *m_toolIcon; + QGroupBox *m_appearanceBox; + + Okular::Annotation *m_stubann; + AnnotationWidget *m_annotationWidget; + + bool m_builtinTool; + +private Q_SLOTS: + void slotTypeChanged(); + void slotDataChanged(); +}; + +Q_DECLARE_METATYPE(EditAnnotToolDialog::ToolType) + +#endif // EDITANNOTTOOLDIALOG_H diff --git a/part/editdrawingtooldialog.cpp b/part/editdrawingtooldialog.cpp new file mode 100644 index 0000000..a3da9b9 --- /dev/null +++ b/part/editdrawingtooldialog.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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. * + ***************************************************************************/ + +#include "editdrawingtooldialog.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +EditDrawingToolDialog::EditDrawingToolDialog(const QDomElement &initialState, QWidget *parent) + : QDialog(parent) +{ + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttonBox->setObjectName(QStringLiteral("buttonbox")); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); // NOLINT(bugprone-suspicious-enum-usage) + connect(buttonBox, &QDialogButtonBox::accepted, this, &EditDrawingToolDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &EditDrawingToolDialog::reject); + okButton->setDefault(true); + + QWidget *widget = new QWidget(this); + QGridLayout *widgetLayout = new QGridLayout(widget); + + mainLayout->addWidget(widget); + mainLayout->addWidget(buttonBox); + + m_name = new KLineEdit(widget); + m_name->setObjectName(QStringLiteral("name")); + mainLayout->addWidget(m_name); + + QLabel *tmplabel = new QLabel(i18n("&Name:"), widget); + mainLayout->addWidget(tmplabel); + tmplabel->setBuddy(m_name); + + widgetLayout->addWidget(tmplabel, 0, 0, Qt::AlignRight); + widgetLayout->addWidget(m_name, 0, 1); + + tmplabel = new QLabel(i18n("Color:"), widget); + widgetLayout->addWidget(tmplabel, 1, 0, Qt::AlignRight); + + m_colorBn = new KColorButton(this); + m_colorBn->setObjectName(QStringLiteral("colorbutton")); + widgetLayout->addWidget(m_colorBn, 1, 1, Qt::AlignRight); + + tmplabel = new QLabel(i18n("&Pen Width:"), widget); + widgetLayout->addWidget(tmplabel, 2, 0, Qt::AlignRight); + + m_penWidth = new QSpinBox(widget); + m_penWidth->setObjectName(QStringLiteral("penWidth")); + m_penWidth->setRange(0, 50); + m_penWidth->setSuffix(i18nc("Suffix for the pen width, eg '10 px'", " px")); + tmplabel->setBuddy(m_penWidth); + widgetLayout->addWidget(m_penWidth, 2, 1); + + tmplabel = new QLabel(i18n("&Opacity:"), widget); + widgetLayout->addWidget(tmplabel, 3, 0, Qt::AlignRight); + + m_opacity = new QSpinBox(widget); + m_opacity->setObjectName(QStringLiteral("opacity")); + m_opacity->setRange(0, 100); + m_opacity->setSuffix(i18nc("Suffix for the opacity level, eg '80 %'", " %")); + tmplabel->setBuddy(m_opacity); + widgetLayout->addWidget(m_opacity, 3, 1); + + if (initialState.isNull()) { + setWindowTitle(i18n("Create drawing tool")); + m_colorBn->setColor(Qt::black); + m_penWidth->setValue(2); + m_opacity->setValue(100); + } else { + setWindowTitle(i18n("Edit drawing tool")); + loadTool(initialState); + } + + m_name->setFocus(); +} + +EditDrawingToolDialog::~EditDrawingToolDialog() +{ +} + +QString EditDrawingToolDialog::name() const +{ + return m_name->text(); +} + +QDomDocument EditDrawingToolDialog::toolXml() const +{ + QDomDocument doc; + QDomElement toolElement = doc.createElement(QStringLiteral("tool")); + QDomElement engineElement = doc.createElement(QStringLiteral("engine")); + QDomElement annotationElement = doc.createElement(QStringLiteral("annotation")); + doc.appendChild(toolElement); + toolElement.appendChild(engineElement); + engineElement.appendChild(annotationElement); + + const QString color = m_colorBn->color().name(); + const double opacity = m_opacity->value() / 100.0; + + engineElement.setAttribute(QStringLiteral("color"), color); + + annotationElement.setAttribute(QStringLiteral("type"), QStringLiteral("Ink")); + annotationElement.setAttribute(QStringLiteral("color"), color); + annotationElement.setAttribute(QStringLiteral("width"), QString::number(m_penWidth->value())); + + if (opacity != 1.0) + annotationElement.setAttribute(QStringLiteral("opacity"), QString::number(opacity)); + + return doc; +} + +void EditDrawingToolDialog::loadTool(const QDomElement &toolElement) +{ + const QDomElement engineElement = toolElement.elementsByTagName(QStringLiteral("engine")).item(0).toElement(); + const QDomElement annotationElement = engineElement.elementsByTagName(QStringLiteral("annotation")).item(0).toElement(); + + if (annotationElement.hasAttribute(QStringLiteral("color"))) + m_colorBn->setColor(QColor(annotationElement.attribute(QStringLiteral("color")))); + + m_penWidth->setValue(annotationElement.attribute(QStringLiteral("width"), QStringLiteral("2")).toInt()); + m_opacity->setValue(annotationElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble() * 100); + + if (toolElement.attribute(QStringLiteral("default"), QStringLiteral("false")) == QLatin1String("true")) + m_name->setText(i18n(toolElement.attribute(QStringLiteral("name")).toLatin1().constData())); + else + m_name->setText(toolElement.attribute(QStringLiteral("name"))); +} diff --git a/part/editdrawingtooldialog.h b/part/editdrawingtooldialog.h new file mode 100644 index 0000000..12554c3 --- /dev/null +++ b/part/editdrawingtooldialog.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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 EDITDRAWINGTOOLDIALOG_H +#define EDITDRAWINGTOOLDIALOG_H + +#include +#include + +class KColorButton; +class KLineEdit; + +class QSpinBox; + +class EditDrawingToolDialog : public QDialog +{ + Q_OBJECT +public: + explicit EditDrawingToolDialog(const QDomElement &initialState = QDomElement(), QWidget *parent = nullptr); + ~EditDrawingToolDialog() override; + + QDomDocument toolXml() const; + + QString name() const; + +private: + void loadTool(const QDomElement &toolElement); + + KLineEdit *m_name; + KColorButton *m_colorBn; + QSpinBox *m_penWidth; + QSpinBox *m_opacity; +}; + +#endif // EDITDRAWINGTOOLDIALOG_H diff --git a/part/embeddedfilesdialog.cpp b/part/embeddedfilesdialog.cpp new file mode 100644 index 0000000..be8d255 --- /dev/null +++ b/part/embeddedfilesdialog.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "embeddedfilesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/document.h" +#include "guiutils.h" + +Q_DECLARE_METATYPE(Okular::EmbeddedFile *) + +static const int EmbeddedFileRole = Qt::UserRole + 100; + +static QString dateToString(const QDateTime &date) +{ + return date.isValid() ? QLocale().toString(date, QLocale::LongFormat) : i18nc("Unknown date", "Unknown"); +} + +EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document *document) + : QDialog(parent) +{ + setWindowTitle(i18nc("@title:window", "Embedded Files")); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mUser1Button = new QPushButton; + buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + buttonBox->button(QDialogButtonBox::Close)->setDefault(true); + KGuiItem::assign(mUser1Button, KStandardGuiItem::save()); + mUser1Button->setEnabled(false); + + mUser2Button = new QPushButton; + buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole); + KGuiItem::assign(mUser2Button, KGuiItem(i18nc("@action:button", "View"), QStringLiteral("document-open"))); + mUser2Button->setEnabled(false); + + m_tw = new QTreeWidget(this); + mainLayout->addWidget(m_tw); + mainLayout->addWidget(buttonBox); + + QStringList header; + header.append(i18nc("@title:column", "Name")); + header.append(i18nc("@title:column", "Description")); + header.append(i18nc("@title:column", "Size")); + header.append(i18nc("@title:column", "Created")); + header.append(i18nc("@title:column", "Modified")); + m_tw->setHeaderLabels(header); + m_tw->setRootIsDecorated(false); + m_tw->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_tw->setContextMenuPolicy(Qt::CustomContextMenu); + + // embeddedFiles() returns a const QList + for (Okular::EmbeddedFile *ef : *document->embeddedFiles()) { + QTreeWidgetItem *twi = new QTreeWidgetItem(); + twi->setText(0, ef->name()); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(ef->name(), QMimeDatabase::MatchExtension); + if (mime.isValid()) { + 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())); + twi->setText(3, dateToString(ef->creationDate())); + twi->setText(4, dateToString(ef->modificationDate())); + twi->setData(0, EmbeddedFileRole, QVariant::fromValue(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(); + + connect(mUser1Button, &QPushButton::clicked, this, &EmbeddedFilesDialog::saveFileFromButton); + connect(mUser2Button, &QPushButton::clicked, this, &EmbeddedFilesDialog::viewFileFromButton); + connect(m_tw, &QWidget::customContextMenuRequested, this, &EmbeddedFilesDialog::attachViewContextMenu); + connect(m_tw, &QTreeWidget::itemSelectionChanged, this, &EmbeddedFilesDialog::updateSaveButton); + connect(m_tw, &QTreeWidget::itemDoubleClicked, this, &EmbeddedFilesDialog::viewFileItem); +} + +void EmbeddedFilesDialog::updateSaveButton() +{ + bool enable = (m_tw->selectedItems().count() > 0); + mUser1Button->setEnabled(enable); + mUser2Button->setEnabled(enable); +} + +void EmbeddedFilesDialog::saveFileFromButton() +{ + const QList selected = m_tw->selectedItems(); + for (const QTreeWidgetItem *twi : selected) { + Okular::EmbeddedFile *ef = qvariant_cast(twi->data(0, EmbeddedFileRole)); + saveFile(ef); + } +} + +void EmbeddedFilesDialog::viewFileFromButton() +{ + const QList selected = m_tw->selectedItems(); + for (QTreeWidgetItem *twi : selected) { + Okular::EmbeddedFile *ef = qvariant_cast(twi->data(0, EmbeddedFileRole)); + viewFile(ef); + } +} + +void EmbeddedFilesDialog::viewFileItem(QTreeWidgetItem *item, int /*column*/) +{ + Okular::EmbeddedFile *ef = qvariant_cast(item->data(0, EmbeddedFileRole)); + viewFile(ef); +} + +void EmbeddedFilesDialog::attachViewContextMenu() +{ + QList selected = m_tw->selectedItems(); + if (selected.isEmpty()) + return; + + if (selected.size() > 1) + return; + + 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(selected.at(0)->data(0, EmbeddedFileRole)); + if (act == saveAsAct) { + 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() + '/' + fileInfo.baseName() + ".XXXXXX" + (fileInfo.completeSuffix().isEmpty() ? QLatin1String("") : 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(tmpFile)); + + // view the temporary file with the default application + new KRun(QUrl("file://" + tmpFile->fileName()), this); +} + +void EmbeddedFilesDialog::saveFile(Okular::EmbeddedFile *ef) +{ + GuiUtils::saveEmbeddedFile(ef, this); +} + +#include "moc_embeddedfilesdialog.cpp" diff --git a/part/embeddedfilesdialog.h b/part/embeddedfilesdialog.h new file mode 100644 index 0000000..2af0638 --- /dev/null +++ b/part/embeddedfilesdialog.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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 _EMBEDDEDFILESDIALOG_H_ +#define _EMBEDDEDFILESDIALOG_H_ + +#include + +class QTreeWidget; +class QPushButton; +class QTemporaryFile; +class QTreeWidgetItem; + +namespace Okular +{ +class Document; +class EmbeddedFile; +} + +class EmbeddedFilesDialog : public QDialog +{ + Q_OBJECT +public: + EmbeddedFilesDialog(QWidget *parent, const Okular::Document *document); + +private Q_SLOTS: + void saveFileFromButton(); + void attachViewContextMenu(); + void updateSaveButton(); + void viewFileFromButton(); + void viewFileItem(QTreeWidgetItem *item, int column); + +private: + void saveFile(Okular::EmbeddedFile *); + void viewFile(Okular::EmbeddedFile *); + + QTreeWidget *m_tw; + + QPushButton *mUser1Button; + QPushButton *mUser2Button; + QList> m_openedFiles; +}; + +#endif diff --git a/part/extensions.cpp b/part/extensions.cpp new file mode 100644 index 0000000..3656c02 --- /dev/null +++ b/part/extensions.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2002 by Wilco Greven * + * 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. * + ***************************************************************************/ + +#include "extensions.h" + +// local includes +#include "part.h" + +namespace Okular +{ +/* + * BrowserExtension class + */ +BrowserExtension::BrowserExtension(Part *parent) + : KParts::BrowserExtension(parent) + , m_part(parent) +{ + emit enableAction("print", true); + setURLDropHandlingEnabled(true); +} + +void BrowserExtension::print() +{ + m_part->slotPrint(); +} + +/* + * OkularLiveConnectExtension class + */ +#define OKULAR_EVAL_RES_OBJ_NAME "__okular_object" +#define OKULAR_EVAL_RES_OBJ "this." OKULAR_EVAL_RES_OBJ_NAME + +OkularLiveConnectExtension::OkularLiveConnectExtension(Part *parent) + : KParts::LiveConnectExtension(parent) + , m_inEval(false) +{ +} + +bool OkularLiveConnectExtension::get(const unsigned long objid, const QString &field, KParts::LiveConnectExtension::Type &type, unsigned long &retobjid, QString &value) +{ + Q_UNUSED(value) + retobjid = objid; + bool result = false; + if (field == QLatin1String("postMessage")) { + type = KParts::LiveConnectExtension::TypeFunction; + result = true; + } + return result; +} + +bool OkularLiveConnectExtension::put(const unsigned long objid, const QString &field, const QString &value) +{ + Q_UNUSED(objid) + if (m_inEval) { + if (field == QLatin1String(OKULAR_EVAL_RES_OBJ_NAME)) + m_evalRes = value; + return true; + } + + return false; +} + +bool OkularLiveConnectExtension::call(const unsigned long objid, const QString &func, const QStringList &args, KParts::LiveConnectExtension::Type &type, unsigned long &retobjid, QString &value) +{ + retobjid = objid; + bool result = false; + if (func == QLatin1String("postMessage")) { + type = KParts::LiveConnectExtension::TypeVoid; + postMessage(args); + value = QString(); + result = true; + } + return result; +} + +QString OkularLiveConnectExtension::eval(const QString &script) +{ + KParts::LiveConnectExtension::ArgList args; + args.append(qMakePair(KParts::LiveConnectExtension::TypeString, script)); + m_evalRes.clear(); + m_inEval = true; + emit partEvent(0, QStringLiteral("eval"), args); + m_inEval = false; + return m_evalRes; +} + +void OkularLiveConnectExtension::postMessage(const QStringList &args) +{ + QStringList arrayargs; + for (const QString &arg : args) { + QString newarg = arg; + newarg.replace(QLatin1Char('\''), QLatin1String("\\'")); + arrayargs.append(QLatin1Char('"') + newarg + QLatin1Char('"')); + } + const QString arrayarg = QLatin1Char('[') + arrayargs.join(QStringLiteral(", ")) + QLatin1Char(']'); + eval(QStringLiteral("if (this.messageHandler && typeof this.messageHandler.onMessage == 'function') " + "{ this.messageHandler.onMessage(") + + arrayarg + QStringLiteral(") }")); +} + +} + +#include "moc_extensions.cpp" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/extensions.h b/part/extensions.h new file mode 100644 index 0000000..87a72df --- /dev/null +++ b/part/extensions.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2002 by Wilco Greven * + * 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 _EXTENSIONS_H_ +#define _EXTENSIONS_H_ + +#include +#include + +namespace Okular +{ +class Part; + +class BrowserExtension : public KParts::BrowserExtension +{ + Q_OBJECT + +public: + explicit BrowserExtension(Part *); + +public Q_SLOTS: + // Automatically detected by the host. + void print(); + +private: + Part *m_part; +}; + +class OkularLiveConnectExtension : public KParts::LiveConnectExtension +{ + Q_OBJECT + +public: + explicit OkularLiveConnectExtension(Part *parent); + + // from LiveConnectExtension + bool get(const unsigned long objid, const QString &field, Type &type, unsigned long &retobjid, QString &value) override; + bool put(const unsigned long objid, const QString &field, const QString &value) override; + bool call(const unsigned long objid, const QString &func, const QStringList &args, Type &type, unsigned long &retobjid, QString &value) override; + +private: + QString eval(const QString &script); + void postMessage(const QStringList &args); + + bool m_inEval; + QString m_evalRes; +}; + +} + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/fileprinterpreview.cpp b/part/fileprinterpreview.cpp new file mode 100644 index 0000000..6bac0cc --- /dev/null +++ b/part/fileprinterpreview.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** + * Copyright (C) 2007 by John Layt * + * * + * FilePrinterPreview based on KPrintPreview (originally LGPL) * + * Copyright (c) 2007 Alex Merry * + * * + * 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. * + ***************************************************************************/ + +#include "fileprinterpreview.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug_ui.h" + +using namespace Okular; + +// This code copied from KPrintPreview by Alex Merry, adapted to do PS files instead of PDF + +class Okular::FilePrinterPreviewPrivate +{ +public: + FilePrinterPreviewPrivate(FilePrinterPreview *host, const QString &_filename) + : q(host) + , mainWidget(new QWidget(host)) + , previewPart(nullptr) + , failMessage(nullptr) + , config(KSharedConfig::openConfig(QStringLiteral("okularrc"))) + + { + mainlayout = new QVBoxLayout(q); + buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, q); + mainlayout->addWidget(buttonBox); + filename = _filename; + } + + void getPart(); + bool doPreview(); + void fail(); + + FilePrinterPreview *q; + + QWidget *mainWidget; + + QDialogButtonBox *buttonBox; + + QVBoxLayout *mainlayout; + + QString filename; + + KParts::ReadOnlyPart *previewPart; + QWidget *failMessage; + + KSharedConfig::Ptr config; +}; + +void FilePrinterPreviewPrivate::getPart() +{ + if (previewPart) { + qCDebug(OkularUiDebug) << "already got a part"; + return; + } + qCDebug(OkularUiDebug) << "querying trader for application/ps service"; + + KPluginFactory *factory(nullptr); + KService::List offers; + if (filename.endsWith(QStringLiteral(".ps"))) { + /* Explicitly look for the Okular/Ghostview part: no other PostScript + parts are available now; other parts which handles text are not + suitable here (PostScript source code) */ + offers = KMimeTypeTrader::self()->query(QStringLiteral("application/postscript"), QStringLiteral("KParts/ReadOnlyPart"), QStringLiteral("[DesktopEntryName] == 'okularghostview'")); + } else { + offers = KMimeTypeTrader::self()->query(QStringLiteral("application/pdf"), QStringLiteral("KParts/ReadOnlyPart")); + } + + KService::List::ConstIterator it = offers.constBegin(); + while (!factory && it != offers.constEnd()) { + KPluginLoader loader(**it); + factory = loader.factory(); + if (!factory) { + qCDebug(OkularUiDebug) << "Loading failed:" << loader.errorString(); + } + ++it; + } + if (factory) { + qCDebug(OkularUiDebug) << "Trying to create a part"; + previewPart = factory->create(q, (QVariantList() << QStringLiteral("Print/Preview"))); + if (!previewPart) { + qCDebug(OkularUiDebug) << "Part creation failed"; + } + } +} + +bool FilePrinterPreviewPrivate::doPreview() +{ + if (!QFile::exists(filename)) { + qCWarning(OkularUiDebug) << "Nothing was produced to be previewed"; + return false; + } + + getPart(); + if (!previewPart) { + // TODO: error dialog + qCWarning(OkularUiDebug) << "Could not find a PS viewer for the preview dialog"; + fail(); + return false; + } else { + mainlayout->insertWidget(0, previewPart->widget()); + return previewPart->openUrl(QUrl::fromLocalFile(filename)); + } +} + +void FilePrinterPreviewPrivate::fail() +{ + if (!failMessage) { + failMessage = new QLabel(i18n("Could not load print preview part"), q); + } + mainlayout->insertWidget(0, failMessage); +} + +FilePrinterPreview::FilePrinterPreview(const QString &filename, QWidget *parent) + : QDialog(parent) + , d(new FilePrinterPreviewPrivate(this, filename)) +{ + qCDebug(OkularUiDebug) << "kdeprint: creating preview dialog"; + + // Set up the dialog + setWindowTitle(i18n("Print Preview")); + + connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + KWindowConfig::restoreWindowSize(windowHandle(), d->config->group("Print Preview")); +} + +FilePrinterPreview::~FilePrinterPreview() +{ + KConfigGroup group(d->config->group("Print Preview")); + KWindowConfig::saveWindowSize(windowHandle(), group); + + delete d; +} + +QSize FilePrinterPreview::sizeHint() const +{ + // return a more or less useful window size, if not saved already + return QSize(600, 500); +} + +void FilePrinterPreview::showEvent(QShowEvent *event) +{ + if (!event->spontaneous()) { + // being shown for the first time + if (!d->doPreview()) { + event->accept(); + return; + } + } + QDialog::showEvent(event); +} + +#include "moc_fileprinterpreview.cpp" diff --git a/part/fileprinterpreview.h b/part/fileprinterpreview.h new file mode 100644 index 0000000..f963c55 --- /dev/null +++ b/part/fileprinterpreview.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2007 by John Layt * + * * + * FilePrinterPreview based on KPrintPreview (originally LGPL) * + * Copyright (c) 2007 Alex Merry * + * * + * 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 FILEPRINTERPREVIEW_H +#define FILEPRINTERPREVIEW_H + +#include + +namespace Okular +{ +// This code copied from KPrintPreview by Alex Merry, adapted to do PS files instead of PDF + +class FilePrinterPreviewPrivate; + +class FilePrinterPreview : public QDialog +{ + Q_OBJECT + +public: + /** + * Create a Print Preview dialog for a given file. + * + * @param filename file to print preview + * @param parent pointer to the parent widget for the dialog + */ + explicit FilePrinterPreview(const QString &filename, QWidget *parent = nullptr); + ~FilePrinterPreview() override; + + QSize sizeHint() const override; + +protected: + void showEvent(QShowEvent *event) override; + +private: + FilePrinterPreviewPrivate *const d; +}; + +} + +#endif // FILEPRINTER_H diff --git a/part/findbar.cpp b/part/findbar.cpp new file mode 100644 index 0000000..973314d --- /dev/null +++ b/part/findbar.cpp @@ -0,0 +1,201 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "findbar.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "core/document.h" +#include "searchlineedit.h" +#include "settings.h" + +FindBar::FindBar(Okular::Document *document, QWidget *parent) + : QWidget(parent) + , m_active(false) +{ + QHBoxLayout *lay = new QHBoxLayout(this); + lay->setContentsMargins(2, 2, 2, 2); + + QToolButton *closeBtn = new QToolButton(this); + closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); + closeBtn->setToolTip(i18n("Close")); + closeBtn->setAutoRaise(true); + lay->addWidget(closeBtn); + + QLabel *label = new QLabel(i18nc("Find text", "F&ind:"), this); + lay->addWidget(label); + + m_search = new SearchLineWidget(this, document); + m_search->lineEdit()->setSearchCaseSensitivity(Qt::CaseInsensitive); + m_search->lineEdit()->setSearchMinimumLength(0); + m_search->lineEdit()->setSearchType(Okular::Document::NextMatch); + m_search->lineEdit()->setSearchId(PART_SEARCH_ID); + m_search->lineEdit()->setSearchColor(qRgb(255, 255, 64)); + m_search->lineEdit()->setSearchMoveViewport(true); + m_search->lineEdit()->setFindAsYouType(false); + m_search->lineEdit()->setToolTip(i18n("Text to search for")); + m_search->installEventFilter(this); + label->setBuddy(m_search->lineEdit()); + lay->addWidget(m_search); + + QPushButton *findNextBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18nc("Find and go to the next search match", "Next"), this); + findNextBtn->setToolTip(i18n("Jump to next match")); + lay->addWidget(findNextBtn); + + QPushButton *findPrevBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-up-search")), i18nc("Find and go to the previous search match", "Previous"), this); + findPrevBtn->setToolTip(i18n("Jump to previous match")); + lay->addWidget(findPrevBtn); + + QPushButton *optionsBtn = new QPushButton(this); + optionsBtn->setText(i18n("Options")); + optionsBtn->setToolTip(i18n("Modify search behavior")); + QMenu *optionsMenu = new QMenu(optionsBtn); + m_caseSensitiveAct = optionsMenu->addAction(i18n("Case sensitive")); + m_caseSensitiveAct->setCheckable(true); + m_fromCurrentPageAct = optionsMenu->addAction(i18n("From current page")); + m_fromCurrentPageAct->setCheckable(true); + m_findAsYouTypeAct = optionsMenu->addAction(i18n("Find as you type")); + m_findAsYouTypeAct->setCheckable(true); + optionsBtn->setMenu(optionsMenu); + lay->addWidget(optionsBtn); + + connect(closeBtn, &QAbstractButton::clicked, this, &FindBar::closeAndStopSearch); + connect(findNextBtn, &QAbstractButton::clicked, this, &FindBar::findNext); + connect(findPrevBtn, &QAbstractButton::clicked, this, &FindBar::findPrev); + connect(m_caseSensitiveAct, &QAction::toggled, this, &FindBar::caseSensitivityChanged); + connect(m_fromCurrentPageAct, &QAction::toggled, this, &FindBar::fromCurrentPageChanged); + connect(m_findAsYouTypeAct, &QAction::toggled, this, &FindBar::findAsYouTypeChanged); + + m_caseSensitiveAct->setChecked(Okular::Settings::searchCaseSensitive()); + m_fromCurrentPageAct->setChecked(Okular::Settings::searchFromCurrentPage()); + m_findAsYouTypeAct->setChecked(Okular::Settings::findAsYouType()); + + hide(); + + // "activate" it only at th very end + m_active = true; +} + +FindBar::~FindBar() +{ +} + +bool FindBar::eventFilter(QObject *target, QEvent *event) +{ + if (target == m_search) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_PageUp || keyEvent->key() == Qt::Key_PageDown) { + emit forwardKeyPressEvent(keyEvent); + return true; + } + } + } + return false; +} + +QString FindBar::text() const +{ + return m_search->lineEdit()->text(); +} + +Qt::CaseSensitivity FindBar::caseSensitivity() const +{ + return m_caseSensitiveAct->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive; +} + +void FindBar::focusAndSetCursor() +{ + setFocus(); + m_search->lineEdit()->selectAll(); + m_search->lineEdit()->setFocus(); +} + +bool FindBar::maybeHide() +{ + if (m_search->lineEdit()->isSearchRunning()) { + m_search->lineEdit()->stopSearch(); + return false; + } else { + hide(); + return true; + } +} + +void FindBar::findNext() +{ + m_search->lineEdit()->setSearchType(Okular::Document::NextMatch); + m_search->lineEdit()->findNext(); +} + +void FindBar::findPrev() +{ + m_search->lineEdit()->setSearchType(Okular::Document::PreviousMatch); + m_search->lineEdit()->findPrev(); +} + +void FindBar::resetSearch() +{ + m_search->lineEdit()->resetSearch(); +} + +void FindBar::caseSensitivityChanged() +{ + m_search->lineEdit()->setSearchCaseSensitivity(m_caseSensitiveAct->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive); + if (!m_active) + return; + Okular::Settings::setSearchCaseSensitive(m_caseSensitiveAct->isChecked()); + Okular::Settings::self()->save(); + m_search->lineEdit()->restartSearch(); +} + +void FindBar::fromCurrentPageChanged() +{ + m_search->lineEdit()->setSearchFromStart(!m_fromCurrentPageAct->isChecked()); + if (!m_active) + return; + Okular::Settings::setSearchFromCurrentPage(m_fromCurrentPageAct->isChecked()); + Okular::Settings::self()->save(); +} + +void FindBar::findAsYouTypeChanged() +{ + m_search->lineEdit()->setFindAsYouType(m_findAsYouTypeAct->isChecked()); + if (!m_active) + return; + Okular::Settings::setFindAsYouType(m_findAsYouTypeAct->isChecked()); + Okular::Settings::self()->save(); +} + +void FindBar::closeAndStopSearch() +{ + if (m_search->lineEdit()->isSearchRunning()) { + m_search->lineEdit()->stopSearch(); + } + emit onCloseButtonPressed(); + close(); +} + +void FindBar::startSearch(const QString &findText) +{ + m_search->lineEdit()->setText(findText); + show(); +} + +#include "moc_findbar.cpp" diff --git a/part/findbar.h b/part/findbar.h new file mode 100644 index 0000000..54cd93d --- /dev/null +++ b/part/findbar.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2007 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 _FINDBAR_H_ +#define _FINDBAR_H_ + +#include + +class QAction; +class SearchLineWidget; + +namespace Okular +{ +class Document; +} + +class FindBar : public QWidget +{ + Q_OBJECT + +public: + explicit FindBar(Okular::Document *document, QWidget *parent = nullptr); + ~FindBar() override; + + QString text() const; + Qt::CaseSensitivity caseSensitivity() const; + + void focusAndSetCursor(); + bool maybeHide(); + void startSearch(const QString &findText); + +Q_SIGNALS: + void forwardKeyPressEvent(QKeyEvent *); + void onCloseButtonPressed(); + +public Q_SLOTS: + void findNext(); + void findPrev(); + void resetSearch(); + +private Q_SLOTS: + void caseSensitivityChanged(); + void fromCurrentPageChanged(); + void findAsYouTypeChanged(); + void closeAndStopSearch(); + +private: + SearchLineWidget *m_search; + QAction *m_caseSensitiveAct; + QAction *m_fromCurrentPageAct; + QAction *m_findAsYouTypeAct; + bool eventFilter(QObject *target, QEvent *event) override; + bool m_active; +}; + +#endif diff --git a/part/formwidgets.cpp b/part/formwidgets.cpp new file mode 100644 index 0000000..8e6e627 --- /dev/null +++ b/part/formwidgets.cpp @@ -0,0 +1,1218 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * Copyright (C) 2018 Intevation GmbH * + * * + * 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. * + ***************************************************************************/ + +#include "formwidgets.h" +#include "pageviewutils.h" +#include "revisionviewer.h" +#include "signaturepropertiesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "core/action.h" +#include "core/document.h" +#include "debug_ui.h" + +FormWidgetsController::FormWidgetsController(Okular::Document *doc) + : QObject(doc) + , m_doc(doc) +{ + // emit changed signal when a form has changed + connect(this, &FormWidgetsController::formTextChangedByUndoRedo, this, &FormWidgetsController::changed); + connect(this, &FormWidgetsController::formListChangedByUndoRedo, this, &FormWidgetsController::changed); + connect(this, &FormWidgetsController::formComboChangedByUndoRedo, this, &FormWidgetsController::changed); + + // connect form modification signals to and from document + connect(this, &FormWidgetsController::formTextChangedByWidget, doc, &Okular::Document::editFormText); + connect(doc, &Okular::Document::formTextChangedByUndoRedo, this, &FormWidgetsController::formTextChangedByUndoRedo); + + connect(this, &FormWidgetsController::formListChangedByWidget, doc, &Okular::Document::editFormList); + connect(doc, &Okular::Document::formListChangedByUndoRedo, this, &FormWidgetsController::formListChangedByUndoRedo); + + connect(this, &FormWidgetsController::formComboChangedByWidget, doc, &Okular::Document::editFormCombo); + connect(doc, &Okular::Document::formComboChangedByUndoRedo, this, &FormWidgetsController::formComboChangedByUndoRedo); + + connect(this, &FormWidgetsController::formButtonsChangedByWidget, doc, &Okular::Document::editFormButtons); + connect(doc, &Okular::Document::formButtonsChangedByUndoRedo, this, &FormWidgetsController::slotFormButtonsChangedByUndoRedo); + + // Connect undo/redo signals + connect(this, &FormWidgetsController::requestUndo, doc, &Okular::Document::undo); + connect(this, &FormWidgetsController::requestRedo, doc, &Okular::Document::redo); + + connect(doc, &Okular::Document::canUndoChanged, this, &FormWidgetsController::canUndoChanged); + connect(doc, &Okular::Document::canRedoChanged, this, &FormWidgetsController::canRedoChanged); + + // Connect the generic formWidget refresh signal + connect(doc, &Okular::Document::refreshFormWidget, this, &FormWidgetsController::refreshFormWidget); +} + +FormWidgetsController::~FormWidgetsController() +{ +} + +void FormWidgetsController::signalAction(Okular::Action *a) +{ + emit action(a); +} + +void FormWidgetsController::processScriptAction(Okular::Action *a, Okular::FormField *field, Okular::Annotation::AdditionalActionType type) +{ + // If it's not a Action Script or if the field is not a FormText, handle it normally + if (a->actionType() != Okular::Action::Script || field->type() != Okular::FormField::FormText) { + emit action(a); + return; + } + switch (type) { + // These cases are to be handled by the FormField text, so we let it happen. + case Okular::Annotation::FocusIn: + case Okular::Annotation::FocusOut: + return; + case Okular::Annotation::PageOpening: + case Okular::Annotation::PageClosing: + case Okular::Annotation::CursorEntering: + case Okular::Annotation::CursorLeaving: + case Okular::Annotation::MousePressed: + case Okular::Annotation::MouseReleased: + emit action(a); + } +} + +void FormWidgetsController::registerRadioButton(FormWidgetIface *fwButton, Okular::FormFieldButton *formButton) +{ + if (!fwButton) + return; + + QAbstractButton *button = dynamic_cast(fwButton); + if (!button) { + qWarning() << "fwButton is not a QAbstractButton" << fwButton; + return; + } + + QList::iterator it = m_radios.begin(), itEnd = m_radios.end(); + const int id = formButton->id(); + m_buttons.insert(id, button); + for (; it != itEnd; ++it) { + const RadioData &rd = *it; + const QList::const_iterator idsIt = std::find(rd.ids.begin(), rd.ids.end(), id); + if (idsIt != rd.ids.constEnd()) { + qCDebug(OkularUiDebug) << "Adding id" << id << "To group including" << rd.ids; + rd.group->addButton(button); + rd.group->setId(button, id); + return; + } + } + + const QList siblings = formButton->siblings(); + + RadioData newdata; + newdata.ids = siblings; + newdata.ids.append(id); + newdata.group = new QButtonGroup(); + newdata.group->addButton(button); + newdata.group->setId(button, id); + + // Groups of 1 (like checkboxes) can't be exclusive + if (siblings.isEmpty()) + newdata.group->setExclusive(false); + + connect(newdata.group, QOverload::of(&QButtonGroup::buttonClicked), this, &FormWidgetsController::slotButtonClicked); + m_radios.append(newdata); +} + +void FormWidgetsController::dropRadioButtons() +{ + QList::iterator it = m_radios.begin(), itEnd = m_radios.end(); + for (; it != itEnd; ++it) { + delete (*it).group; + } + m_radios.clear(); + m_buttons.clear(); +} + +bool FormWidgetsController::canUndo() +{ + return m_doc->canUndo(); +} + +bool FormWidgetsController::canRedo() +{ + return m_doc->canRedo(); +} + +bool FormWidgetsController::shouldFormWidgetBeShown(Okular::FormField *form) +{ + return !form->isReadOnly() || form->type() == Okular::FormField::FormSignature; +} + +void FormWidgetsController::slotButtonClicked(QAbstractButton *button) +{ + int pageNumber = -1; + CheckBoxEdit *check = qobject_cast(button); + if (check) { + // Checkboxes need to be uncheckable so if clicking a checked one + // disable the exclusive status temporarily and uncheck it + Okular::FormFieldButton *formButton = static_cast(check->formField()); + if (formButton->state()) { + const bool wasExclusive = button->group()->exclusive(); + button->group()->setExclusive(false); + check->setChecked(false); + button->group()->setExclusive(wasExclusive); + } + pageNumber = check->pageItem()->pageNumber(); + } else if (RadioButtonEdit *radio = qobject_cast(button)) { + pageNumber = radio->pageItem()->pageNumber(); + } + + const QList buttons = button->group()->buttons(); + QList checked; + QList prevChecked; + QList formButtons; + + for (QAbstractButton *button : buttons) { + checked.append(button->isChecked()); + Okular::FormFieldButton *formButton = static_cast(dynamic_cast(button)->formField()); + formButtons.append(formButton); + prevChecked.append(formButton->state()); + } + if (checked != prevChecked) + emit formButtonsChangedByWidget(pageNumber, formButtons, checked); + if (check) { + // The formButtonsChangedByWidget signal changes the value of the underlying + // Okular::FormField of the checkbox. We need to execute the activation + // action after this. + check->doActivateAction(); + } +} + +void FormWidgetsController::slotFormButtonsChangedByUndoRedo(int pageNumber, const QList &formButtons) +{ + for (const Okular::FormFieldButton *formButton : formButtons) { + int id = formButton->id(); + QAbstractButton *button = m_buttons[id]; + CheckBoxEdit *check = qobject_cast(button); + if (check) { + emit refreshFormWidget(check->formField()); + } + // temporarily disable exclusiveness of the button group + // since it breaks doing/redoing steps into which all the checkboxes + // are unchecked + const bool wasExclusive = button->group()->exclusive(); + button->group()->setExclusive(false); + bool checked = formButton->state(); + button->setChecked(checked); + button->group()->setExclusive(wasExclusive); + button->setFocus(); + } + emit changed(pageNumber); +} + +FormWidgetIface *FormWidgetFactory::createWidget(Okular::FormField *ff, QWidget *parent) +{ + FormWidgetIface *widget = nullptr; + + switch (ff->type()) { + case Okular::FormField::FormButton: { + Okular::FormFieldButton *ffb = static_cast(ff); + switch (ffb->buttonType()) { + case Okular::FormFieldButton::Push: + widget = new PushButtonEdit(ffb, parent); + break; + case Okular::FormFieldButton::CheckBox: + widget = new CheckBoxEdit(ffb, parent); + break; + case Okular::FormFieldButton::Radio: + widget = new RadioButtonEdit(ffb, parent); + break; + default:; + } + break; + } + case Okular::FormField::FormText: { + Okular::FormFieldText *fft = static_cast(ff); + switch (fft->textType()) { + case Okular::FormFieldText::Multiline: + widget = new TextAreaEdit(fft, parent); + break; + case Okular::FormFieldText::Normal: + widget = new FormLineEdit(fft, parent); + break; + case Okular::FormFieldText::FileSelect: + widget = new FileEdit(fft, parent); + break; + } + break; + } + case Okular::FormField::FormChoice: { + Okular::FormFieldChoice *ffc = static_cast(ff); + switch (ffc->choiceType()) { + case Okular::FormFieldChoice::ListBox: + widget = new ListEdit(ffc, parent); + break; + case Okular::FormFieldChoice::ComboBox: + widget = new ComboEdit(ffc, parent); + break; + } + break; + } + case Okular::FormField::FormSignature: { + Okular::FormFieldSignature *ffs = static_cast(ff); + if (ffs->isVisible() && ffs->signatureType() != Okular::FormFieldSignature::UnknownType) + widget = new SignatureEdit(ffs, parent); + break; + } + default:; + } + + if (!FormWidgetsController::shouldFormWidgetBeShown(ff)) + widget->setVisibility(false); + + return widget; +} + +FormWidgetIface::FormWidgetIface(QWidget *w, Okular::FormField *ff) + : m_controller(nullptr) + , m_ff(ff) + , m_widget(w) + , m_pageItem(nullptr) +{ +} + +FormWidgetIface::~FormWidgetIface() +{ +} + +Okular::NormalizedRect FormWidgetIface::rect() const +{ + return m_ff->rect(); +} + +void FormWidgetIface::setWidthHeight(int w, int h) +{ + m_widget->resize(w, h); +} + +void FormWidgetIface::moveTo(int x, int y) +{ + m_widget->move(x, y); +} + +bool FormWidgetIface::setVisibility(bool visible) +{ + bool hadfocus = m_widget->hasFocus(); + if (hadfocus) + m_widget->clearFocus(); + m_widget->setVisible(visible); + return hadfocus; +} + +void FormWidgetIface::setCanBeFilled(bool fill) +{ + m_widget->setEnabled(fill); +} + +void FormWidgetIface::setPageItem(PageViewItem *pageItem) +{ + m_pageItem = pageItem; +} + +void FormWidgetIface::setFormField(Okular::FormField *field) +{ + m_ff = field; +} + +Okular::FormField *FormWidgetIface::formField() const +{ + return m_ff; +} + +PageViewItem *FormWidgetIface::pageItem() const +{ + return m_pageItem; +} + +void FormWidgetIface::setFormWidgetsController(FormWidgetsController *controller) +{ + m_controller = controller; + QObject *obj = dynamic_cast(this); + QObject::connect(m_controller, &FormWidgetsController::refreshFormWidget, obj, [this](Okular::FormField *form) { slotRefresh(form); }); +} + +void FormWidgetIface::slotRefresh(Okular::FormField *form) +{ + if (m_ff != form) { + return; + } + setVisibility(form->isVisible() && m_controller->shouldFormWidgetBeShown(form)); + + m_widget->setEnabled(!form->isReadOnly()); +} + +PushButtonEdit::PushButtonEdit(Okular::FormFieldButton *button, QWidget *parent) + : QPushButton(parent) + , FormWidgetIface(this, button) +{ + setText(button->caption()); + + if (button->caption().isEmpty()) { + setFlat(true); + } + + setVisible(button->isVisible()); + setCursor(Qt::ArrowCursor); +} + +CheckBoxEdit::CheckBoxEdit(Okular::FormFieldButton *button, QWidget *parent) + : QCheckBox(parent) + , FormWidgetIface(this, button) +{ + setText(button->caption()); + + setVisible(button->isVisible()); + setCursor(Qt::ArrowCursor); +} + +void CheckBoxEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + Okular::FormFieldButton *form = static_cast(m_ff); + FormWidgetIface::setFormWidgetsController(controller); + m_controller->registerRadioButton(this, form); + setChecked(form->state()); +} + +void CheckBoxEdit::doActivateAction() +{ + Okular::FormFieldButton *form = static_cast(m_ff); + if (form->activationAction()) + m_controller->signalAction(form->activationAction()); +} + +void CheckBoxEdit::slotRefresh(Okular::FormField *form) +{ + if (form != m_ff) { + return; + } + FormWidgetIface::slotRefresh(form); + + Okular::FormFieldButton *button = static_cast(m_ff); + bool oldState = isChecked(); + bool newState = button->state(); + if (oldState != newState) { + setChecked(button->state()); + doActivateAction(); + } +} + +RadioButtonEdit::RadioButtonEdit(Okular::FormFieldButton *button, QWidget *parent) + : QRadioButton(parent) + , FormWidgetIface(this, button) +{ + setText(button->caption()); + + setVisible(button->isVisible()); + setCursor(Qt::ArrowCursor); +} + +void RadioButtonEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + Okular::FormFieldButton *form = static_cast(m_ff); + FormWidgetIface::setFormWidgetsController(controller); + m_controller->registerRadioButton(this, form); + setChecked(form->state()); +} + +FormLineEdit::FormLineEdit(Okular::FormFieldText *text, QWidget *parent) + : QLineEdit(parent) + , FormWidgetIface(this, text) +{ + int maxlen = text->maximumLength(); + if (maxlen >= 0) + setMaxLength(maxlen); + setAlignment(text->textAlignment()); + setText(text->text()); + if (text->isPassword()) + setEchoMode(QLineEdit::Password); + + m_prevCursorPos = cursorPosition(); + m_prevAnchorPos = cursorPosition(); + m_editing = false; + + connect(this, &QLineEdit::textEdited, this, &FormLineEdit::slotChanged); + connect(this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged); + + setVisible(text->isVisible()); +} + +void FormLineEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + FormWidgetIface::setFormWidgetsController(controller); + connect(m_controller, &FormWidgetsController::formTextChangedByUndoRedo, this, &FormLineEdit::slotHandleTextChangedByUndoRedo); +} + +bool FormLineEdit::event(QEvent *e) +{ + if (e->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent == QKeySequence::Undo) { + emit m_controller->requestUndo(); + return true; + } else if (keyEvent == QKeySequence::Redo) { + emit m_controller->requestRedo(); + return true; + } + } else if (e->type() == QEvent::FocusIn) { + const auto fft = static_cast(m_ff); + if (text() != fft->text()) + setText(fft->text()); + m_editing = true; + if (const Okular::Action *action = m_ff->additionalAction(Okular::Annotation::FocusIn)) + emit m_controller->focusAction(action, fft); + setFocus(); + } else if (e->type() == QEvent::FocusOut) { + // Don't worry about focus events from other sources than the user FocusEvent to edit the field + QFocusEvent *focusEvent = static_cast(e); + if (focusEvent->reason() == Qt::OtherFocusReason) + return true; + m_editing = false; + + if (const Okular::Action *action = m_ff->additionalAction(Okular::Annotation::FocusOut)) { + bool ok = false; + emit m_controller->validateAction(action, static_cast(m_ff), ok); + } + if (const Okular::Action *action = m_ff->additionalAction(Okular::FormField::FormatField)) { + emit m_controller->formatAction(action, static_cast(m_ff)); + } + } + return QLineEdit::event(e); +} + +void FormLineEdit::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = createStandardContextMenu(); + + QList actionList = menu->actions(); + enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct }; + + QAction *kundo = KStandardAction::create(KStandardAction::Undo, m_controller, SIGNAL(requestUndo()), menu); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, m_controller, SIGNAL(requestRedo()), menu); + connect(m_controller, &FormWidgetsController::canUndoChanged, kundo, &QAction::setEnabled); + connect(m_controller, &FormWidgetsController::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(m_controller->canUndo()); + kredo->setEnabled(m_controller->canRedo()); + + QAction *oldUndo, *oldRedo; + oldUndo = actionList[UndoAct]; + oldRedo = actionList[RedoAct]; + + menu->insertAction(oldUndo, kundo); + menu->insertAction(oldRedo, kredo); + + menu->removeAction(oldUndo); + menu->removeAction(oldRedo); + + menu->exec(event->globalPos()); + delete menu; +} + +void FormLineEdit::slotChanged() +{ + Okular::FormFieldText *form = static_cast(m_ff); + QString contents = text(); + int cursorPos = cursorPosition(); + + if (form->additionalAction(Okular::FormField::FieldModified) && m_editing && !form->isReadOnly()) { + bool ok = false; + QString oldInputText = form->text(); + form->setText(text()); + emit m_controller->keystrokeAction(form->additionalAction(Okular::FormField::FieldModified), form, ok); + form->setText(oldInputText); + if (!ok) { + setText(oldInputText); + return; + } + } + + if (contents != form->text()) { + emit m_controller->formTextChangedByWidget(pageItem()->pageNumber(), form, contents, cursorPos, m_prevCursorPos, m_prevAnchorPos); + } + + m_prevCursorPos = cursorPos; + m_prevAnchorPos = cursorPos; + if (hasSelectedText()) { + if (cursorPos == selectionStart()) { + m_prevAnchorPos = selectionStart() + selectedText().size(); + } else { + m_prevAnchorPos = selectionStart(); + } + } +} + +void FormLineEdit::slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos) +{ + Q_UNUSED(pageNumber); + if (textForm != m_ff || contents == text()) { + return; + } + disconnect(this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged); + setText(contents); + setCursorPosition(anchorPos); + cursorForward(true, cursorPos - anchorPos); + connect(this, &QLineEdit::cursorPositionChanged, this, &FormLineEdit::slotChanged); + m_prevCursorPos = cursorPos; + m_prevAnchorPos = anchorPos; + setFocus(); +} + +void FormLineEdit::slotRefresh(Okular::FormField *form) +{ + if (form != m_ff) { + return; + } + FormWidgetIface::slotRefresh(form); + + Okular::FormFieldText *text = static_cast(form); + setText(text->text()); +} + +TextAreaEdit::TextAreaEdit(Okular::FormFieldText *text, QWidget *parent) + : KTextEdit(parent) + , FormWidgetIface(this, text) +{ + setAcceptRichText(text->isRichText()); + setCheckSpellingEnabled(text->canBeSpellChecked()); + setAlignment(text->textAlignment()); + setPlainText(text->text()); + setUndoRedoEnabled(false); + + connect(this, &QTextEdit::textChanged, this, &TextAreaEdit::slotChanged); + connect(this, &QTextEdit::cursorPositionChanged, this, &TextAreaEdit::slotChanged); + connect(this, &KTextEdit::aboutToShowContextMenu, this, &TextAreaEdit::slotUpdateUndoAndRedoInContextMenu); + m_prevCursorPos = textCursor().position(); + m_prevAnchorPos = textCursor().anchor(); + m_editing = false; + setVisible(text->isVisible()); +} + +TextAreaEdit::~TextAreaEdit() +{ + // We need this because otherwise on destruction we destruct the syntax highlighter + // that ends up calling text changed but then we go to slotChanged and we're already + // half destructed and all is bad + disconnect(this, &QTextEdit::textChanged, this, &TextAreaEdit::slotChanged); +} + +bool TextAreaEdit::event(QEvent *e) +{ + if (e->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent == QKeySequence::Undo) { + emit m_controller->requestUndo(); + return true; + } else if (keyEvent == QKeySequence::Redo) { + emit m_controller->requestRedo(); + return true; + } + } else if (e->type() == QEvent::FocusIn) { + const auto fft = static_cast(m_ff); + if (toPlainText() != fft->text()) + setText(fft->text()); + m_editing = true; + } else if (e->type() == QEvent::FocusOut) { + m_editing = false; + if (const Okular::Action *action = m_ff->additionalAction(Okular::FormField::FormatField)) { + emit m_controller->formatAction(action, static_cast(m_ff)); + } + } + return KTextEdit::event(e); +} + +void TextAreaEdit::slotUpdateUndoAndRedoInContextMenu(QMenu *menu) +{ + if (!menu) + return; + + QList actionList = menu->actions(); + enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, ClearAct, SelectAllAct, NCountActs }; + + QAction *kundo = KStandardAction::create(KStandardAction::Undo, m_controller, SIGNAL(requestUndo()), menu); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, m_controller, SIGNAL(requestRedo()), menu); + connect(m_controller, &FormWidgetsController::canUndoChanged, kundo, &QAction::setEnabled); + connect(m_controller, &FormWidgetsController::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(m_controller->canUndo()); + kredo->setEnabled(m_controller->canRedo()); + + QAction *oldUndo, *oldRedo; + oldUndo = actionList[UndoAct]; + oldRedo = actionList[RedoAct]; + + menu->insertAction(oldUndo, kundo); + menu->insertAction(oldRedo, kredo); + + menu->removeAction(oldUndo); + menu->removeAction(oldRedo); +} + +void TextAreaEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + FormWidgetIface::setFormWidgetsController(controller); + connect(m_controller, &FormWidgetsController::formTextChangedByUndoRedo, this, &TextAreaEdit::slotHandleTextChangedByUndoRedo); +} + +void TextAreaEdit::slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos) +{ + Q_UNUSED(pageNumber); + if (textForm != m_ff) { + return; + } + setPlainText(contents); + QTextCursor c = textCursor(); + c.setPosition(anchorPos); + c.setPosition(cursorPos, QTextCursor::KeepAnchor); + m_prevCursorPos = cursorPos; + m_prevAnchorPos = anchorPos; + setTextCursor(c); + setFocus(); +} + +void TextAreaEdit::slotChanged() +{ + Okular::FormFieldText *form = static_cast(m_ff); + QString contents = toPlainText(); + int cursorPos = textCursor().position(); + + if (form->additionalAction(Okular::FormField::FieldModified) && m_editing && !form->isReadOnly()) { + bool ok = false; + QString oldInputText = form->text(); + form->setText(toPlainText()); + emit m_controller->keystrokeAction(form->additionalAction(Okular::FormField::FieldModified), form, ok); + form->setText(oldInputText); + if (!ok) { + setText(oldInputText); + return; + } + } + + if (contents != form->text()) { + emit m_controller->formTextChangedByWidget(pageItem()->pageNumber(), form, contents, cursorPos, m_prevCursorPos, m_prevAnchorPos); + } + m_prevCursorPos = cursorPos; + m_prevAnchorPos = textCursor().anchor(); +} + +void TextAreaEdit::slotRefresh(Okular::FormField *form) +{ + if (form != m_ff) { + return; + } + FormWidgetIface::slotRefresh(form); + + Okular::FormFieldText *text = static_cast(form); + setPlainText(text->text()); +} + +FileEdit::FileEdit(Okular::FormFieldText *text, QWidget *parent) + : KUrlRequester(parent) + , FormWidgetIface(this, text) +{ + setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly); + setFilter(i18n("*|All Files")); + setUrl(QUrl::fromUserInput(text->text())); + lineEdit()->setAlignment(text->textAlignment()); + + m_prevCursorPos = lineEdit()->cursorPosition(); + m_prevAnchorPos = lineEdit()->cursorPosition(); + + connect(this, &KUrlRequester::textChanged, this, &FileEdit::slotChanged); + connect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &FileEdit::slotChanged); + setVisible(text->isVisible()); +} + +void FileEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + FormWidgetIface::setFormWidgetsController(controller); + connect(m_controller, &FormWidgetsController::formTextChangedByUndoRedo, this, &FileEdit::slotHandleFileChangedByUndoRedo); +} + +bool FileEdit::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == lineEdit()) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent == QKeySequence::Undo) { + emit m_controller->requestUndo(); + return true; + } else if (keyEvent == QKeySequence::Redo) { + emit m_controller->requestRedo(); + return true; + } + } else if (event->type() == QEvent::ContextMenu) { + QContextMenuEvent *contextMenuEvent = static_cast(event); + + QMenu *menu = ((QLineEdit *)lineEdit())->createStandardContextMenu(); + + QList actionList = menu->actions(); + enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct }; + + QAction *kundo = KStandardAction::create(KStandardAction::Undo, m_controller, SIGNAL(requestUndo()), menu); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, m_controller, SIGNAL(requestRedo()), menu); + connect(m_controller, &FormWidgetsController::canUndoChanged, kundo, &QAction::setEnabled); + connect(m_controller, &FormWidgetsController::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(m_controller->canUndo()); + kredo->setEnabled(m_controller->canRedo()); + + QAction *oldUndo, *oldRedo; + oldUndo = actionList[UndoAct]; + oldRedo = actionList[RedoAct]; + + menu->insertAction(oldUndo, kundo); + menu->insertAction(oldRedo, kredo); + + menu->removeAction(oldUndo); + menu->removeAction(oldRedo); + + menu->exec(contextMenuEvent->globalPos()); + delete menu; + return true; + } + } + return KUrlRequester::eventFilter(obj, event); +} + +void FileEdit::slotChanged() +{ + // Make sure line edit's text matches url expansion + if (text() != url().toLocalFile()) + this->setText(url().toLocalFile()); + + Okular::FormFieldText *form = static_cast(m_ff); + + QString contents = text(); + int cursorPos = lineEdit()->cursorPosition(); + if (contents != form->text()) { + emit m_controller->formTextChangedByWidget(pageItem()->pageNumber(), form, contents, cursorPos, m_prevCursorPos, m_prevAnchorPos); + } + + m_prevCursorPos = cursorPos; + m_prevAnchorPos = cursorPos; + if (lineEdit()->hasSelectedText()) { + if (cursorPos == lineEdit()->selectionStart()) { + m_prevAnchorPos = lineEdit()->selectionStart() + lineEdit()->selectedText().size(); + } else { + m_prevAnchorPos = lineEdit()->selectionStart(); + } + } +} + +void FileEdit::slotHandleFileChangedByUndoRedo(int pageNumber, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos) +{ + Q_UNUSED(pageNumber); + if (form != m_ff || contents == text()) { + return; + } + disconnect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &FileEdit::slotChanged); + setText(contents); + lineEdit()->setCursorPosition(anchorPos); + lineEdit()->cursorForward(true, cursorPos - anchorPos); + connect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &FileEdit::slotChanged); + m_prevCursorPos = cursorPos; + m_prevAnchorPos = anchorPos; + setFocus(); +} + +ListEdit::ListEdit(Okular::FormFieldChoice *choice, QWidget *parent) + : QListWidget(parent) + , FormWidgetIface(this, choice) +{ + addItems(choice->choices()); + setSelectionMode(choice->multiSelect() ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection); + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + const QList selectedItems = choice->currentChoices(); + if (choice->multiSelect()) { + for (const int index : selectedItems) + if (index >= 0 && index < count()) + item(index)->setSelected(true); + } else { + if (selectedItems.count() == 1 && selectedItems.at(0) >= 0 && selectedItems.at(0) < count()) { + setCurrentRow(selectedItems.at(0)); + scrollToItem(item(selectedItems.at(0))); + } + } + + connect(this, &QListWidget::itemSelectionChanged, this, &ListEdit::slotSelectionChanged); + + setVisible(choice->isVisible()); + setCursor(Qt::ArrowCursor); +} + +void ListEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + FormWidgetIface::setFormWidgetsController(controller); + connect(m_controller, &FormWidgetsController::formListChangedByUndoRedo, this, &ListEdit::slotHandleFormListChangedByUndoRedo); +} + +void ListEdit::slotSelectionChanged() +{ + const QList selection = selectedItems(); + QList rows; + for (const QListWidgetItem *item : selection) { + rows.append(row(item)); + } + Okular::FormFieldChoice *form = static_cast(m_ff); + if (rows != form->currentChoices()) { + emit m_controller->formListChangedByWidget(pageItem()->pageNumber(), form, rows); + } +} + +void ListEdit::slotHandleFormListChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *listForm, const QList &choices) +{ + Q_UNUSED(pageNumber); + + if (m_ff != listForm) { + return; + } + + disconnect(this, &QListWidget::itemSelectionChanged, this, &ListEdit::slotSelectionChanged); + for (int i = 0; i < count(); i++) { + item(i)->setSelected(choices.contains(i)); + } + connect(this, &QListWidget::itemSelectionChanged, this, &ListEdit::slotSelectionChanged); + + setFocus(); +} + +ComboEdit::ComboEdit(Okular::FormFieldChoice *choice, QWidget *parent) + : QComboBox(parent) + , FormWidgetIface(this, choice) +{ + addItems(choice->choices()); + setEditable(true); + setInsertPolicy(NoInsert); + lineEdit()->setReadOnly(!choice->isEditable()); + QList selectedItems = choice->currentChoices(); + if (selectedItems.count() == 1 && selectedItems.at(0) >= 0 && selectedItems.at(0) < count()) + setCurrentIndex(selectedItems.at(0)); + + if (choice->isEditable() && !choice->editChoice().isEmpty()) + lineEdit()->setText(choice->editChoice()); + + connect(this, QOverload::of(&QComboBox::currentIndexChanged), this, &ComboEdit::slotValueChanged); + connect(this, &QComboBox::editTextChanged, this, &ComboEdit::slotValueChanged); + connect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &ComboEdit::slotValueChanged); + + setVisible(choice->isVisible()); + setCursor(Qt::ArrowCursor); + m_prevCursorPos = lineEdit()->cursorPosition(); + m_prevAnchorPos = lineEdit()->cursorPosition(); +} + +void ComboEdit::setFormWidgetsController(FormWidgetsController *controller) +{ + FormWidgetIface::setFormWidgetsController(controller); + connect(m_controller, &FormWidgetsController::formComboChangedByUndoRedo, this, &ComboEdit::slotHandleFormComboChangedByUndoRedo); +} + +void ComboEdit::slotValueChanged() +{ + const QString text = lineEdit()->text(); + + Okular::FormFieldChoice *form = static_cast(m_ff); + + QString prevText; + if (form->currentChoices().isEmpty()) { + prevText = form->editChoice(); + } else { + prevText = form->choices().at(form->currentChoices().constFirst()); + } + + int cursorPos = lineEdit()->cursorPosition(); + if (text != prevText) { + emit m_controller->formComboChangedByWidget(pageItem()->pageNumber(), form, currentText(), cursorPos, m_prevCursorPos, m_prevAnchorPos); + } + prevText = text; + m_prevCursorPos = cursorPos; + m_prevAnchorPos = cursorPos; + if (lineEdit()->hasSelectedText()) { + if (cursorPos == lineEdit()->selectionStart()) { + m_prevAnchorPos = lineEdit()->selectionStart() + lineEdit()->selectedText().size(); + } else { + m_prevAnchorPos = lineEdit()->selectionStart(); + } + } +} + +void ComboEdit::slotHandleFormComboChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *form, const QString &text, int cursorPos, int anchorPos) +{ + Q_UNUSED(pageNumber); + + if (m_ff != form) { + return; + } + + // Determine if text corrisponds to an index choices + int index = -1; + for (int i = 0; i < count(); i++) { + if (itemText(i) == text) { + index = i; + } + } + + m_prevCursorPos = cursorPos; + m_prevAnchorPos = anchorPos; + + disconnect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &ComboEdit::slotValueChanged); + const bool isCustomValue = index == -1; + if (isCustomValue) { + setEditText(text); + } else { + setCurrentIndex(index); + } + lineEdit()->setCursorPosition(anchorPos); + lineEdit()->cursorForward(true, cursorPos - anchorPos); + connect(lineEdit(), &QLineEdit::cursorPositionChanged, this, &ComboEdit::slotValueChanged); + setFocus(); +} + +void ComboEdit::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = lineEdit()->createStandardContextMenu(); + + QList actionList = menu->actions(); + enum { UndoAct, RedoAct, CutAct, CopyAct, PasteAct, DeleteAct, SelectAllAct }; + + QAction *kundo = KStandardAction::create(KStandardAction::Undo, m_controller, SIGNAL(requestUndo()), menu); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, m_controller, SIGNAL(requestRedo()), menu); + connect(m_controller, &FormWidgetsController::canUndoChanged, kundo, &QAction::setEnabled); + connect(m_controller, &FormWidgetsController::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(m_controller->canUndo()); + kredo->setEnabled(m_controller->canRedo()); + + QAction *oldUndo, *oldRedo; + oldUndo = actionList[UndoAct]; + oldRedo = actionList[RedoAct]; + + menu->insertAction(oldUndo, kundo); + menu->insertAction(oldRedo, kredo); + + menu->removeAction(oldUndo); + menu->removeAction(oldRedo); + + menu->exec(event->globalPos()); + delete menu; +} + +bool ComboEdit::event(QEvent *e) +{ + if (e->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent == QKeySequence::Undo) { + emit m_controller->requestUndo(); + return true; + } else if (keyEvent == QKeySequence::Redo) { + emit m_controller->requestRedo(); + return true; + } + } + return QComboBox::event(e); +} + +SignatureEdit::SignatureEdit(Okular::FormFieldSignature *signature, QWidget *parent) + : QAbstractButton(parent) + , FormWidgetIface(this, signature) + , m_widgetPressed(false) + , m_dummyMode(false) + , m_wasVisible(false) +{ + setCursor(Qt::PointingHandCursor); + connect(this, &SignatureEdit::clicked, this, &SignatureEdit::slotViewProperties); +} + +void SignatureEdit::setDummyMode(bool set) +{ + m_dummyMode = set; + if (m_dummyMode) { + m_wasVisible = isVisible(); + // if widget was hidden then show it. + // even if it wasn't hidden calling this will still update the background. + setVisibility(true); + } else { + // forms were not visible before this call so hide this widget. + if (!m_wasVisible) + setVisibility(false); + // forms were visible even before this call so only update the background color. + else + update(); + } +} + +bool SignatureEdit::event(QEvent *e) +{ + if (m_dummyMode && e->type() != QEvent::Paint) { + e->accept(); + return true; + } + + switch (e->type()) { + case QEvent::MouseButtonPress: { + QMouseEvent *ev = static_cast(e); + if (ev->button() == Qt::LeftButton) { + m_widgetPressed = true; + update(); + } + break; + } + case QEvent::MouseButtonRelease: { + QMouseEvent *ev = static_cast(e); + if (ev->button() == Qt::LeftButton) { + m_widgetPressed = false; + update(); + } + break; + } + case QEvent::Leave: { + m_widgetPressed = false; + update(); + } + default: + break; + } + + return QAbstractButton::event(e); +} + +void SignatureEdit::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = new QMenu(this); + QAction *signatureProperties = new QAction(i18n("Signature Properties"), menu); + connect(signatureProperties, &QAction::triggered, this, &SignatureEdit::slotViewProperties); + menu->addAction(signatureProperties); + menu->exec(event->globalPos()); + delete menu; +} + +void SignatureEdit::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + // no borders when user hasn't allowed the forms to be shown + if (m_dummyMode && !m_wasVisible) { + painter.setPen(Qt::transparent); + } else { + painter.setPen(Qt::black); + } + + if (m_widgetPressed || m_dummyMode) { + QColor col = palette().color(QPalette::Active, QPalette::Highlight); + col.setAlpha(50); + painter.setBrush(col); + } else { + painter.setBrush(Qt::transparent); + } + painter.drawRect(0, 0, width() - 2, height() - 2); +} + +void SignatureEdit::slotViewProperties() +{ + if (m_dummyMode) + return; + + Okular::FormFieldSignature *formSignature = static_cast(formField()); + SignaturePropertiesDialog propDlg(m_controller->m_doc, formSignature, this); + propDlg.exec(); +} + +// Code for additional action handling. +// Challenge: Change preprocessor magic to C++ magic! +// +// The mouseRelease event is special because the PDF spec +// says that the activation action takes precedence over this. +// So the mouse release action is only signaled if no activation +// action exists. +// +// For checkboxes the activation action is not triggered as +// they are still triggered from the clicked signal and additionally +// when the checked state changes. + +#define DEFINE_ADDITIONAL_ACTIONS(FormClass, BaseClass) \ + void FormClass::mousePressEvent(QMouseEvent *event) \ + { \ + Okular::Action *act = m_ff->additionalAction(Okular::Annotation::MousePressed); \ + if (act) { \ + m_controller->signalAction(act); \ + } \ + BaseClass::mousePressEvent(event); \ + } \ + void FormClass::mouseReleaseEvent(QMouseEvent *event) \ + { \ + if (!QWidget::rect().contains(event->localPos().toPoint())) { \ + BaseClass::mouseReleaseEvent(event); \ + return; \ + } \ + Okular::Action *act = m_ff->activationAction(); \ + if (act && !qobject_cast(this)) { \ + m_controller->signalAction(act); \ + } else if ((act = m_ff->additionalAction(Okular::Annotation::MouseReleased))) { \ + m_controller->signalAction(act); \ + } \ + BaseClass::mouseReleaseEvent(event); \ + } \ + void FormClass::focusInEvent(QFocusEvent *event) \ + { \ + Okular::Action *act = m_ff->additionalAction(Okular::Annotation::FocusIn); \ + if (act) { \ + m_controller->processScriptAction(act, m_ff, Okular::Annotation::FocusIn); \ + } \ + BaseClass::focusInEvent(event); \ + } \ + void FormClass::focusOutEvent(QFocusEvent *event) \ + { \ + Okular::Action *act = m_ff->additionalAction(Okular::Annotation::FocusOut); \ + if (act) { \ + m_controller->processScriptAction(act, m_ff, Okular::Annotation::FocusOut); \ + } \ + BaseClass::focusOutEvent(event); \ + } \ + void FormClass::leaveEvent(QEvent *event) \ + { \ + Okular::Action *act = m_ff->additionalAction(Okular::Annotation::CursorLeaving); \ + if (act) { \ + m_controller->signalAction(act); \ + } \ + BaseClass::leaveEvent(event); \ + } \ + void FormClass::enterEvent(QEvent *event) \ + { \ + Okular::Action *act = m_ff->additionalAction(Okular::Annotation::CursorEntering); \ + if (act) { \ + m_controller->signalAction(act); \ + } \ + BaseClass::enterEvent(event); \ + } + +DEFINE_ADDITIONAL_ACTIONS(PushButtonEdit, QPushButton) +DEFINE_ADDITIONAL_ACTIONS(CheckBoxEdit, QCheckBox) +DEFINE_ADDITIONAL_ACTIONS(RadioButtonEdit, QRadioButton) +DEFINE_ADDITIONAL_ACTIONS(FormLineEdit, QLineEdit) +DEFINE_ADDITIONAL_ACTIONS(TextAreaEdit, KTextEdit) +DEFINE_ADDITIONAL_ACTIONS(FileEdit, KUrlRequester) +DEFINE_ADDITIONAL_ACTIONS(ListEdit, QListWidget) +DEFINE_ADDITIONAL_ACTIONS(ComboEdit, QComboBox) +DEFINE_ADDITIONAL_ACTIONS(SignatureEdit, QAbstractButton) + +#undef DEFINE_ADDITIONAL_ACTIONS diff --git a/part/formwidgets.h b/part/formwidgets.h new file mode 100644 index 0000000..299add6 --- /dev/null +++ b/part/formwidgets.h @@ -0,0 +1,349 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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_FORMWIDGETS_H_ +#define _OKULAR_FORMWIDGETS_H_ + +#include "core/area.h" +#include "core/form.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +class ComboEdit; +class QMenu; +class QButtonGroup; +class FormWidgetIface; +class PageViewItem; +class RadioButtonEdit; +class QEvent; + +namespace Okular +{ +class Action; +class FormField; +class FormFieldButton; +class FormFieldChoice; +class FormFieldText; +class FormFieldSignature; +class Document; +} + +struct RadioData { + RadioData() + { + } + + QList ids; + QButtonGroup *group; +}; + +class FormWidgetsController : public QObject +{ + Q_OBJECT + +public: + explicit FormWidgetsController(Okular::Document *doc); + ~FormWidgetsController() override; + + void signalAction(Okular::Action *action); + + void processScriptAction(Okular::Action *a, Okular::FormField *field, Okular::Annotation::AdditionalActionType type); + + void registerRadioButton(FormWidgetIface *fwButton, Okular::FormFieldButton *formButton); + void dropRadioButtons(); + bool canUndo(); + bool canRedo(); + + static bool shouldFormWidgetBeShown(Okular::FormField *form); + +Q_SIGNALS: + void changed(int pageNumber); + void requestUndo(); + void requestRedo(); + void canUndoChanged(bool undoAvailable); + void canRedoChanged(bool redoAvailable); + void formTextChangedByWidget(int pageNumber, Okular::FormFieldText *form, const QString &newContents, int newCursorPos, int prevCursorPos, int prevAnchorPos); + + void formTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos); + + void formListChangedByWidget(int pageNumber, Okular::FormFieldChoice *form, const QList &newChoices); + + void formListChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *form, const QList &choices); + + void formComboChangedByWidget(int pageNumber, Okular::FormFieldChoice *form, const QString &newText, int newCursorPos, int prevCursorPos, int prevAnchorPos); + + void formComboChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *form, const QString &text, int cursorPos, int anchorPos); + + void formButtonsChangedByWidget(int pageNumber, const QList &formButtons, const QList &newButtonStates); + + void action(Okular::Action *action); + + void focusAction(const Okular::Action *action, Okular::FormFieldText *ff); + + void formatAction(const Okular::Action *action, Okular::FormFieldText *ff); + + void keystrokeAction(const Okular::Action *action, Okular::FormFieldText *ff, bool &ok); + + void validateAction(const Okular::Action *action, Okular::FormFieldText *ff, bool &ok); + + void refreshFormWidget(Okular::FormField *form); + +private Q_SLOTS: + void slotButtonClicked(QAbstractButton *button); + void slotFormButtonsChangedByUndoRedo(int pageNumber, const QList &formButtons); + +private: + friend class TextAreaEdit; + friend class FormLineEdit; + friend class FileEdit; + friend class ListEdit; + friend class ComboEdit; + friend class SignatureEdit; + + QList m_radios; + QHash m_buttons; + Okular::Document *m_doc; +}; + +class FormWidgetFactory +{ +public: + static FormWidgetIface *createWidget(Okular::FormField *ff, QWidget *parent = nullptr); +}; + +class FormWidgetIface +{ +public: + FormWidgetIface(QWidget *w, Okular::FormField *ff); + virtual ~FormWidgetIface(); + + FormWidgetIface(const FormWidgetIface &) = delete; + FormWidgetIface &operator=(const FormWidgetIface &) = delete; + + Okular::NormalizedRect rect() const; + void setWidthHeight(int w, int h); + void moveTo(int x, int y); + bool setVisibility(bool visible); + void setCanBeFilled(bool fill); + + void setPageItem(PageViewItem *pageItem); + PageViewItem *pageItem() const; + void setFormField(Okular::FormField *field); + Okular::FormField *formField() const; + + virtual void setFormWidgetsController(FormWidgetsController *controller); + +protected: + virtual void slotRefresh(Okular::FormField *form); + + FormWidgetsController *m_controller; + Okular::FormField *m_ff; + +private: + QWidget *m_widget; + PageViewItem *m_pageItem; +}; + +#define DECLARE_ADDITIONAL_ACTIONS \ +protected: \ + virtual void mousePressEvent(QMouseEvent *event) override; \ + virtual void mouseReleaseEvent(QMouseEvent *event) override; \ + virtual void focusInEvent(QFocusEvent *event) override; \ + virtual void focusOutEvent(QFocusEvent *event) override; \ + virtual void leaveEvent(QEvent *event) override; \ + virtual void enterEvent(QEvent *event) override; + +class PushButtonEdit : public QPushButton, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit PushButtonEdit(Okular::FormFieldButton *button, QWidget *parent = nullptr); + + DECLARE_ADDITIONAL_ACTIONS +}; + +class CheckBoxEdit : public QCheckBox, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit CheckBoxEdit(Okular::FormFieldButton *button, QWidget *parent = nullptr); + + // reimplemented from FormWidgetIface + void setFormWidgetsController(FormWidgetsController *controller) override; + + void doActivateAction(); + +protected: + void slotRefresh(Okular::FormField *form) override; + DECLARE_ADDITIONAL_ACTIONS +}; + +class RadioButtonEdit : public QRadioButton, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit RadioButtonEdit(Okular::FormFieldButton *button, QWidget *parent = nullptr); + + // reimplemented from FormWidgetIface + void setFormWidgetsController(FormWidgetsController *controller) override; + DECLARE_ADDITIONAL_ACTIONS +}; + +class FormLineEdit : public QLineEdit, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit FormLineEdit(Okular::FormFieldText *text, QWidget *parent = nullptr); + void setFormWidgetsController(FormWidgetsController *controller) override; + bool event(QEvent *e) override; + void contextMenuEvent(QContextMenuEvent *event) override; + +public Q_SLOTS: + void slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos); +private Q_SLOTS: + void slotChanged(); + +protected: + void slotRefresh(Okular::FormField *form) override; + +private: + int m_prevCursorPos; + int m_prevAnchorPos; + bool m_editing; + DECLARE_ADDITIONAL_ACTIONS +}; + +class TextAreaEdit : public KTextEdit, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit TextAreaEdit(Okular::FormFieldText *text, QWidget *parent = nullptr); + ~TextAreaEdit() override; + void setFormWidgetsController(FormWidgetsController *controller) override; + bool event(QEvent *e) override; + +public Q_SLOTS: + void slotHandleTextChangedByUndoRedo(int pageNumber, Okular::FormFieldText *textForm, const QString &contents, int cursorPos, int anchorPos); + void slotUpdateUndoAndRedoInContextMenu(QMenu *menu); + +private Q_SLOTS: + void slotChanged(); + +protected: + void slotRefresh(Okular::FormField *form) override; + +private: + int m_prevCursorPos; + int m_prevAnchorPos; + bool m_editing; + DECLARE_ADDITIONAL_ACTIONS +}; + +class FileEdit : public KUrlRequester, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit FileEdit(Okular::FormFieldText *text, QWidget *parent = nullptr); + void setFormWidgetsController(FormWidgetsController *controller) override; + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +private Q_SLOTS: + void slotChanged(); + void slotHandleFileChangedByUndoRedo(int pageNumber, Okular::FormFieldText *form, const QString &contents, int cursorPos, int anchorPos); + +private: + int m_prevCursorPos; + int m_prevAnchorPos; + DECLARE_ADDITIONAL_ACTIONS +}; + +class ListEdit : public QListWidget, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit ListEdit(Okular::FormFieldChoice *choice, QWidget *parent = nullptr); + void setFormWidgetsController(FormWidgetsController *controller) override; + +private Q_SLOTS: + void slotSelectionChanged(); + void slotHandleFormListChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *listForm, const QList &choices); + DECLARE_ADDITIONAL_ACTIONS +}; + +class ComboEdit : public QComboBox, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit ComboEdit(Okular::FormFieldChoice *choice, QWidget *parent = nullptr); + void setFormWidgetsController(FormWidgetsController *controller) override; + bool event(QEvent *e) override; + void contextMenuEvent(QContextMenuEvent *event) override; + +private Q_SLOTS: + void slotValueChanged(); + void slotHandleFormComboChangedByUndoRedo(int pageNumber, Okular::FormFieldChoice *comboForm, const QString &text, int cursorPos, int anchorPos); + +private: + int m_prevCursorPos; + int m_prevAnchorPos; + DECLARE_ADDITIONAL_ACTIONS +}; + +class SignatureEdit : public QAbstractButton, public FormWidgetIface +{ + Q_OBJECT + +public: + explicit SignatureEdit(Okular::FormFieldSignature *signature, QWidget *parent = nullptr); + + // This will be called when an item in signature panel is clicked. Calling it changes the + // widget state. If this widget was visible prior to calling this then background + // color will change and borders will remain otherwise visibility of this widget will change. + // During the change all interactions will be disabled. + void setDummyMode(bool set); + +protected: + bool event(QEvent *e) override; + void contextMenuEvent(QContextMenuEvent *event) override; + void paintEvent(QPaintEvent *event) override; + +private Q_SLOTS: + void slotViewProperties(); + +private: + bool m_widgetPressed; + bool m_dummyMode; + bool m_wasVisible; // this will help in deciding whether or not to paint border for this widget + + DECLARE_ADDITIONAL_ACTIONS +}; + +#undef DECLARE_ADDITIONAL_ACTIONS + +#endif diff --git a/part/guiutils.cpp b/part/guiutils.cpp new file mode 100644 index 0000000..ade0f3f --- /dev/null +++ b/part/guiutils.cpp @@ -0,0 +1,371 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 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. * + ***************************************************************************/ + +#include "guiutils.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "core/action.h" +#include "core/annotations.h" +#include "core/document.h" + +#include + +struct GuiUtilsHelper { + GuiUtilsHelper() + { + } + + QSvgRenderer *svgStamps(); + + QList il; + std::unique_ptr svgStampFile; +}; + +QSvgRenderer *GuiUtilsHelper::svgStamps() +{ + if (!svgStampFile.get()) { + const QString stampFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("okular/pics/stamps.svg")); + if (!stampFile.isEmpty()) { + svgStampFile = std::make_unique(stampFile); + if (!svgStampFile->isValid()) { + svgStampFile.reset(); + } + } + } + return svgStampFile.get(); +} + +Q_GLOBAL_STATIC(GuiUtilsHelper, s_data) + +namespace GuiUtils +{ +QString captionForAnnotation(const Okular::Annotation *ann) +{ + Q_ASSERT(ann); + + const bool hasComment = !ann->contents().isEmpty(); + + QString ret; + switch (ann->subType()) { + case Okular::Annotation::AText: + if (((Okular::TextAnnotation *)ann)->textType() == Okular::TextAnnotation::Linked) + ret = i18n("Pop-up Note"); + else { + if (((Okular::TextAnnotation *)ann)->inplaceIntent() == Okular::TextAnnotation::TypeWriter) + ret = i18n("Typewriter"); + else + ret = i18n("Inline Note"); + } + break; + case Okular::Annotation::ALine: + if (((Okular::LineAnnotation *)ann)->linePoints().count() == 2) + ret = hasComment ? i18n("Straight Line with Comment") : i18n("Straight Line"); + else + ret = hasComment ? i18n("Polygon with Comment") : i18n("Polygon"); + break; + case Okular::Annotation::AGeom: + ret = hasComment ? i18n("Geometry with Comment") : i18n("Geometry"); + break; + case Okular::Annotation::AHighlight: + switch (((Okular::HighlightAnnotation *)ann)->highlightType()) { + case Okular::HighlightAnnotation::Highlight: + ret = hasComment ? i18n("Highlight with Comment") : i18n("Highlight"); + break; + case Okular::HighlightAnnotation::Squiggly: + ret = hasComment ? i18n("Squiggle with Comment") : i18n("Squiggle"); + break; + case Okular::HighlightAnnotation::Underline: + ret = hasComment ? i18n("Underline with Comment") : i18n("Underline"); + break; + case Okular::HighlightAnnotation::StrikeOut: + ret = hasComment ? i18n("Strike Out with Comment") : i18n("Strike Out"); + break; + } + break; + case Okular::Annotation::AStamp: + ret = hasComment ? i18n("Stamp with Comment") : i18n("Stamp"); + break; + case Okular::Annotation::AInk: + ret = hasComment ? i18n("Freehand Line with Comment") : i18n("Freehand Line"); + break; + case Okular::Annotation::ACaret: + ret = i18n("Caret"); + break; + case Okular::Annotation::AFileAttachment: + ret = i18n("File Attachment"); + break; + case Okular::Annotation::ASound: + ret = i18n("Sound"); + break; + case Okular::Annotation::AMovie: + ret = i18n("Movie"); + break; + case Okular::Annotation::AScreen: + ret = i18nc("Caption for a screen annotation", "Screen"); + break; + case Okular::Annotation::AWidget: + ret = i18nc("Caption for a widget annotation", "Widget"); + break; + case Okular::Annotation::ARichMedia: + ret = i18nc("Caption for a rich media annotation", "Rich Media"); + break; + case Okular::Annotation::A_BASE: + break; + } + return ret; +} + +QString authorForAnnotation(const Okular::Annotation *ann) +{ + Q_ASSERT(ann); + + return !ann->author().isEmpty() ? ann->author() : i18nc("Unknown author", "Unknown"); +} + +QString contentsHtml(const Okular::Annotation *ann) +{ + QString text = ann->contents().toHtmlEscaped(); + text.replace(QLatin1Char('\n'), QLatin1String("
")); + return text; +} + +QString prettyToolTip(const Okular::Annotation *ann) +{ + Q_ASSERT(ann); + + QString author = authorForAnnotation(ann); + QString contents = contentsHtml(ann); + + QString tooltip = QStringLiteral("") + i18n("Author: %1", author) + QStringLiteral(""); + if (!contents.isEmpty()) + tooltip += QStringLiteral("

") + contents; + + tooltip += QLatin1String("
"); + + return tooltip; +} + +QPixmap loadStamp(const QString &nameOrPath, int size, bool keepAspectRatio) +{ + const QString name = nameOrPath.toLower(); + + // _name is the name of an Okular stamp symbols ( multiple symbols in a single *.svg file) + QSvgRenderer *r = nullptr; + if ((r = s_data->svgStamps()) && r->elementExists(name)) { + const QSize stampSize = r->boundsOnElement(name).size().toSize(); + const QSize pixmapSize = stampSize.scaled(size, size, keepAspectRatio ? Qt::KeepAspectRatioByExpanding : Qt::IgnoreAspectRatio); + QPixmap pixmap(pixmapSize); + pixmap.fill(Qt::transparent); + QPainter p(&pixmap); + r->render(&p, name); + p.end(); + return pixmap; + } + + // _name is a path (do this before loading as icon name to avoid some rare weirdness ) + QPixmap pixmap; + pixmap.load(nameOrPath); + if (!pixmap.isNull()) { + pixmap = pixmap.scaled(size, size, keepAspectRatio ? Qt::KeepAspectRatioByExpanding : Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + return pixmap; + } + + // _name is an icon name + const KIconLoader *il = iconLoader(); + QString path; + pixmap = il->loadIcon(name, KIconLoader::User, size, KIconLoader::DefaultState, QStringList(), &path, true); + if (path.isEmpty()) + pixmap = il->loadIcon(name, KIconLoader::NoGroup, size); + + return pixmap; // can be a null pixmap +} + +void addIconLoader(KIconLoader *loader) +{ + s_data->il.append(loader); +} + +void removeIconLoader(KIconLoader *loader) +{ + s_data->il.removeAll(loader); +} + +KIconLoader *iconLoader() +{ + return s_data->il.isEmpty() ? KIconLoader::global() : s_data->il.back(); +} + +void saveEmbeddedFile(Okular::EmbeddedFile *ef, QWidget *parent) +{ + const QString caption = i18n("Where do you want to save %1?", ef->name()); + const QString path = QFileDialog::getSaveFileName(parent, caption, ef->name()); + if (path.isEmpty()) + return; + QFile targetFile(path); + writeEmbeddedFile(ef, parent, targetFile); +} + +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.", target.fileName())); + return; + } + target.write(ef->data()); + target.close(); +} + +Okular::Movie *renditionMovieFromScreenAnnotation(const Okular::ScreenAnnotation *annotation) +{ + if (!annotation) + return nullptr; + + if (annotation->action() && annotation->action()->actionType() == Okular::Action::Rendition) { + Okular::RenditionAction *renditionAction = static_cast(annotation->action()); + return renditionAction->movie(); + } + + return nullptr; +} + +// from Arthur - qt4 +static inline int qt_div_255(int x) +{ + return (x + (x >> 8) + 0x80) >> 8; +} + +void colorizeImage(QImage &grayImage, const QColor &color, unsigned int destAlpha) +{ + // Make sure that the image is Format_ARGB32_Premultiplied + if (grayImage.format() != QImage::Format_ARGB32_Premultiplied) + grayImage = grayImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); + + // iterate over all pixels changing the alpha component value + unsigned int *data = reinterpret_cast(grayImage.bits()); + unsigned int pixels = grayImage.width() * grayImage.height(); + int red = color.red(), green = color.green(), blue = color.blue(); + + int source, sourceSat, sourceAlpha; + for (unsigned int i = 0; i < pixels; ++i) { // optimize this loop keeping byte order into account + source = data[i]; + sourceSat = qRed(source); + int newR = qt_div_255(sourceSat * red), newG = qt_div_255(sourceSat * green), newB = qt_div_255(sourceSat * blue); + if ((sourceAlpha = qAlpha(source)) == 255) { + // use destAlpha + data[i] = qRgba(newR, newG, newB, destAlpha); + } else { + // use destAlpha * sourceAlpha product + if (destAlpha < 255) + sourceAlpha = qt_div_255(destAlpha * sourceAlpha); + data[i] = qRgba(newR, newG, newB, sourceAlpha); + } + } +} + +QIcon createColorIcon(const QList &colors, const QIcon &background, ColorIconFlags flags) +{ + QIcon colorIcon; + + // Create a pixmap for each common icon size. + for (int size : {16, 22, 24, 32, 48}) { + QPixmap pixmap(QSize(size, size) * qApp->devicePixelRatio()); + pixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + // Configure hairlines for visualization of outline or transparency (visualizeTransparent): + painter.setPen(QPen(qApp->palette().color(QPalette::Active, QPalette::WindowText), 0)); + painter.setBrush(Qt::NoBrush); + + if (background.isNull()) { + // Full-size color rectangles. + // Draw rectangles left to right: + for (int i = 0; i < colors.count(); ++i) { + if (!colors.at(i).isValid()) { + continue; + } + QRect rect(QPoint(size * i / colors.count(), 0), QPoint(size * (i + 1) / colors.count(), size)); + if ((flags & VisualizeTransparent) && (colors.at(i) == Qt::transparent)) { + painter.drawLine(rect.topLeft(), rect.bottomRight()); + painter.drawLine(rect.bottomLeft(), rect.topRight()); + } else { + painter.fillRect(rect, colors.at(i)); + } + } + + // Draw hairline outline: + // To get the hairline on the outermost pixels, we shrink the rectangle by a half pixel on each edge. + const qreal halfPixelWidth = 0.5 / pixmap.devicePixelRatio(); + painter.drawRect(QRectF(QPointF(halfPixelWidth, halfPixelWidth), QPointF(qreal(size) - halfPixelWidth, qreal(size) - halfPixelWidth))); + } else { + // Lower 25% color rectangles. + // Draw background icon: + background.paint(&painter, QRect(QPoint(0, 0), QSize(size, size))); + + // Draw rectangles left to right: + for (int i = 0; i < colors.count(); ++i) { + if (!colors.at(i).isValid()) { + continue; + } + QRect rect(QPoint(size * i / colors.count(), size * 3 / 4), QPoint(size * (i + 1) / colors.count(), size)); + if ((flags & VisualizeTransparent) && (colors.at(i) == Qt::transparent)) { + painter.drawLine(rect.topLeft(), rect.bottomRight()); + painter.drawLine(rect.bottomLeft(), rect.topRight()); + } else { + painter.fillRect(rect, colors.at(i)); + } + } + } + + painter.end(); + colorIcon.addPixmap(pixmap); + } + + return colorIcon; +} + +QIcon createOpacityIcon(qreal opacity) +{ + QIcon opacityIcon; + + // Create a pixmap for each common icon size. + for (int size : {16, 22, 24, 32, 48}) { + QPixmap pixmap(QSize(size, size) * qApp->devicePixelRatio()); + pixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setPen(Qt::NoPen); + painter.setBrush(qApp->palette().color(QPalette::Active, QPalette::WindowText)); + + // Checkerboard pattern + painter.drawRect(QRectF(QPoint(0, 0), QPoint(size, size) / 2)); + painter.drawRect(QRectF(QPoint(size, size) / 2, QPoint(size, size))); + + // Opacity + painter.setOpacity(opacity); + painter.drawRect(QRect(QPoint(0, 0), QPoint(size, size))); + + painter.end(); + opacityIcon.addPixmap(pixmap); + } + + return opacityIcon; +} + +} diff --git a/part/guiutils.h b/part/guiutils.h new file mode 100644 index 0000000..c20b9be --- /dev/null +++ b/part/guiutils.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 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_GUIUTILS_H +#define OKULAR_GUIUTILS_H + +#include +#include +#include + +class QImage; +class QPixmap; +class QSize; +class QWidget; +class QFile; +class KIconLoader; + +namespace Okular +{ +class Annotation; +class EmbeddedFile; +class Movie; +class ScreenAnnotation; +} + +namespace GuiUtils +{ +/** + * Returns the translated string with the type of the given @p annotation. + */ +QString captionForAnnotation(const Okular::Annotation *annotation); +QString authorForAnnotation(const Okular::Annotation *annotation); + +QString contentsHtml(const Okular::Annotation *annotation); + +QString prettyToolTip(const Okular::Annotation *annotation); + +/** + * Returns a pixmap for a stamp symbol + * + * @p name Name of a Okular stamp symbol, icon or path to an image + * @p size Size of the pixmap (ignore aspect ratio). Takes precedence over @p iconSize + * @p iconSize Maximum size of the pixmap (keep aspect ratio) + */ +QPixmap loadStamp(const QString &nameOrPath, int size, bool keepAspectRatio = true); + +void addIconLoader(KIconLoader *loader); +void removeIconLoader(KIconLoader *loader); +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 + * or @c 0 if the screen annotation has no rendition action set or the rendition action does not contain + * a media rendition. + */ +Okular::Movie *renditionMovieFromScreenAnnotation(const Okular::ScreenAnnotation *annotation); + +// colorize a gray image to the given color +void colorizeImage(QImage &image, const QColor &color, unsigned int alpha = 255); + +enum ColorIconFlags { + NoFlags = 0x0, + VisualizeTransparent = 0x1 ///< Visualizes Qt::transparent with a cross. +}; + +/** + * Paints color rectangles on the lower 25% of an icon. + * + * If no icon is given, the whole icon square is filled, and a 1px border is added. + * + * Examples: + * * Different icons for different kinds of color selection, like fill and outline. + * * Selection of a color scheme preset, where each scheme has a different icon and ~1..3 specific colors. + * + * @param colors Which color rectangles to paint, from left to right (even on RTL). Colors may be transparent. Invalid colors are skipped. + * @param background Which icon to use as background. + * @param flags Special wishes. + * + * @returns A newly created QIcon. + */ +QIcon createColorIcon(const QList &colors, const QIcon &background = QIcon(), ColorIconFlags flags = NoFlags); + +/** + * Creates an opacity icon, using QPalette foreground color + * painted on top of a checkerboard pattern using @p opacity. + * + * @param opacity 0 = invisible, 1 = opaque. + */ +QIcon createOpacityIcon(qreal opacity); + +} + +#endif diff --git a/part/ktreeviewsearchline.cpp b/part/ktreeviewsearchline.cpp new file mode 100644 index 0000000..bbf9cfb --- /dev/null +++ b/part/ktreeviewsearchline.cpp @@ -0,0 +1,411 @@ +/* + Copyright (c) 2003 Scott Wheeler + Copyright (c) 2005 Rafal Rzepecki + Copyright (c) 2006 Hamish Rodda + Copyright 2007 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ktreeviewsearchline.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class KTreeViewSearchLine::Private +{ +public: + Private(KTreeViewSearchLine *_parent) + : parent(_parent) + , treeView(nullptr) + , caseSensitive(Qt::CaseInsensitive) + , regularExpression(false) + , activeSearch(false) + , queuedSearches(0) + { + } + + KTreeViewSearchLine *parent; + QTreeView *treeView; + Qt::CaseSensitivity caseSensitive; + bool regularExpression; + bool activeSearch; + QString search; + int queuedSearches; + + void rowsInserted(const QModelIndex &parent, int start, int end) const; + void treeViewDeleted(QObject *object); + void slotCaseSensitive(); + void slotRegularExpression(); + + void checkItemParentsNotVisible(QTreeView *treeView); + bool filterItems(QTreeView *treeView, const QModelIndex &index); +}; + +//////////////////////////////////////////////////////////////////////////////// +// private slots +//////////////////////////////////////////////////////////////////////////////// + +void KTreeViewSearchLine::Private::rowsInserted(const QModelIndex &parentIndex, int start, int end) const +{ + QAbstractItemModel *model = qobject_cast(parent->sender()); + if (!model) + return; + + QTreeView *widget = nullptr; + if (treeView->model() == model) { + widget = treeView; + } + + if (!widget) + return; + + for (int i = start; i <= end; ++i) { + widget->setRowHidden(i, parentIndex, !parent->itemMatches(parentIndex, i, parent->text())); + } +} + +void KTreeViewSearchLine::Private::treeViewDeleted(QObject *object) +{ + if (object == treeView) { + treeView = nullptr; + parent->setEnabled(false); + } +} + +void KTreeViewSearchLine::Private::slotCaseSensitive() +{ + if (caseSensitive == Qt::CaseSensitive) + parent->setCaseSensitivity(Qt::CaseInsensitive); + else + parent->setCaseSensitivity(Qt::CaseSensitive); + + parent->updateSearch(); +} + +void KTreeViewSearchLine::Private::slotRegularExpression() +{ + if (regularExpression) + parent->setRegularExpression(false); + else + parent->setRegularExpression(true); + + parent->updateSearch(); +} + +//////////////////////////////////////////////////////////////////////////////// +// private methods +//////////////////////////////////////////////////////////////////////////////// + +/** Check whether \p item, its siblings and their descendants should be shown. Show or hide the items as necessary. + * + * \p item The list view item to start showing / hiding items at. Typically, this is the first child of another item, or the + * the first child of the list view. + * \return \c true if an item which should be visible is found, \c false if all items found should be hidden. If this function + * returns true and \p highestHiddenParent was not 0, highestHiddenParent will have been shown. + */ +bool KTreeViewSearchLine::Private::filterItems(QTreeView *treeView, const QModelIndex &index) +{ + bool childMatch = false; + const int rowcount = treeView->model()->rowCount(index); + for (int i = 0; i < rowcount; ++i) + childMatch |= filterItems(treeView, treeView->model()->index(i, 0, index)); + + // Should this item be shown? It should if any children should be, or if it matches. + const QModelIndex parentindex = index.parent(); + if (childMatch || parent->itemMatches(parentindex, index.row(), search)) { + treeView->setRowHidden(index.row(), parentindex, false); + return true; + } + + treeView->setRowHidden(index.row(), parentindex, true); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// public methods +//////////////////////////////////////////////////////////////////////////////// + +KTreeViewSearchLine::KTreeViewSearchLine(QWidget *parent, QTreeView *treeView) + : KLineEdit(parent) + , d(new Private(this)) +{ + connect(this, &KTreeViewSearchLine::textChanged, this, &KTreeViewSearchLine::queueSearch); + + setClearButtonEnabled(true); + setTreeView(treeView); + + if (!treeView) { + setEnabled(false); + } +} + +KTreeViewSearchLine::~KTreeViewSearchLine() +{ + delete d; +} + +Qt::CaseSensitivity KTreeViewSearchLine::caseSensitivity() const +{ + return d->caseSensitive; +} + +bool KTreeViewSearchLine::regularExpression() const +{ + return d->regularExpression; +} + +QTreeView *KTreeViewSearchLine::treeView() const +{ + return d->treeView; +} + +//////////////////////////////////////////////////////////////////////////////// +// public slots +//////////////////////////////////////////////////////////////////////////////// + +void KTreeViewSearchLine::updateSearch(const QString &pattern) +{ + d->search = pattern.isNull() ? text() : pattern; + + updateSearch(d->treeView); +} + +void KTreeViewSearchLine::updateSearch(QTreeView *treeView) +{ + if (!treeView || !treeView->model()->rowCount()) + return; + + // If there's a selected item that is visible, make sure that it's visible + // when the search changes too (assuming that it still matches). + + QModelIndex currentIndex = treeView->currentIndex(); + + bool wasUpdateEnabled = treeView->updatesEnabled(); + treeView->setUpdatesEnabled(false); + d->filterItems(treeView, treeView->rootIndex()); + treeView->setUpdatesEnabled(wasUpdateEnabled); + + if (currentIndex.isValid()) + treeView->scrollTo(currentIndex); +} + +void KTreeViewSearchLine::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) +{ + if (d->caseSensitive != caseSensitivity) { + d->caseSensitive = caseSensitivity; + updateSearch(); + emit searchOptionsChanged(); + } +} + +void KTreeViewSearchLine::setRegularExpression(bool value) +{ + if (d->regularExpression != value) { + d->regularExpression = value; + updateSearch(); + emit searchOptionsChanged(); + } +} + +void KTreeViewSearchLine::setTreeView(QTreeView *treeView) +{ + disconnectTreeView(d->treeView); + d->treeView = treeView; + connectTreeView(treeView); + + setEnabled(treeView != nullptr); +} + +//////////////////////////////////////////////////////////////////////////////// +// protected members +//////////////////////////////////////////////////////////////////////////////// + +bool KTreeViewSearchLine::itemMatches(const QModelIndex &parentIndex, int row, const QString &pattern) const +{ + if (pattern.isEmpty()) + return true; + + if (!parentIndex.isValid() && parentIndex != d->treeView->rootIndex()) + return false; + + // Construct a regular expression object with the right options. + QRegularExpression re; + if (d->regularExpression) { + re.setPattern(pattern); + re.setPatternOptions(d->caseSensitive ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption); + } + + // If the search column list is populated, search just the columns + // specified. If it is empty default to searching all of the columns. + QAbstractItemModel *model = d->treeView->model(); + const int columncount = model->columnCount(parentIndex); + for (int i = 0; i < columncount; ++i) { + const QString str = model->data(model->index(row, i, parentIndex), Qt::DisplayRole).toString(); + if (d->regularExpression) { + return str.contains(re); + } else { + return str.contains(pattern, d->caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive); + } + } + + return false; +} + +void KTreeViewSearchLine::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *popup = KLineEdit::createStandardContextMenu(); + + popup->addSeparator(); + QMenu *optionsSubMenu = popup->addMenu(i18n("Search Options")); + QAction *caseSensitiveAction = optionsSubMenu->addAction(i18nc("Enable case sensitive search in the side navigation panels", "Case Sensitive"), this, [this] { d->slotCaseSensitive(); }); + caseSensitiveAction->setCheckable(true); + caseSensitiveAction->setChecked(d->caseSensitive); + QAction *regularExpressionAction = optionsSubMenu->addAction(i18nc("Enable regular expression search in the side navigation panels", "Regular Expression"), this, [this] { d->slotRegularExpression(); }); + regularExpressionAction->setCheckable(true); + regularExpressionAction->setChecked(d->regularExpression); + + popup->exec(event->globalPos()); + delete popup; +} + +void KTreeViewSearchLine::connectTreeView(QTreeView *treeView) +{ + if (treeView) { + connect(treeView, &QTreeView::destroyed, this, &KTreeViewSearchLine::treeViewDeleted); + + connect(treeView->model(), &QAbstractItemModel::rowsInserted, this, &KTreeViewSearchLine::rowsInserted); + } +} + +void KTreeViewSearchLine::disconnectTreeView(QTreeView *treeView) +{ + if (treeView) { + disconnect(treeView, &QTreeView::destroyed, this, &KTreeViewSearchLine::treeViewDeleted); + + disconnect(treeView->model(), &QAbstractItemModel::rowsInserted, this, &KTreeViewSearchLine::rowsInserted); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// protected slots +//////////////////////////////////////////////////////////////////////////////// + +void KTreeViewSearchLine::queueSearch(const QString &search) +{ + d->queuedSearches++; + d->search = search; + + QTimer::singleShot(200, this, &KTreeViewSearchLine::activateSearch); +} + +void KTreeViewSearchLine::activateSearch() +{ + --(d->queuedSearches); + + if (d->queuedSearches == 0) + updateSearch(d->search); +} + +//////////////////////////////////////////////////////////////////////////////// +// private functions +//////////////////////////////////////////////////////////////////////////////// + +void KTreeViewSearchLine::rowsInserted(const QModelIndex &parent, int start, int end) const +{ + d->rowsInserted(parent, start, end); +} + +void KTreeViewSearchLine::treeViewDeleted(QObject *treeView) +{ + d->treeViewDeleted(treeView); +} + +//////////////////////////////////////////////////////////////////////////////// +// KTreeViewSearchLineWidget +//////////////////////////////////////////////////////////////////////////////// + +class KTreeViewSearchLineWidget::Private +{ +public: + Private() + : treeView(nullptr) + , searchLine(nullptr) + { + } + + QTreeView *treeView; + KTreeViewSearchLine *searchLine; +}; + +KTreeViewSearchLineWidget::KTreeViewSearchLineWidget(QWidget *parent, QTreeView *treeView) + : QWidget(parent) + , d(new Private) +{ + d->treeView = treeView; + + QTimer::singleShot(0, this, &KTreeViewSearchLineWidget::createWidgets); +} + +KTreeViewSearchLineWidget::~KTreeViewSearchLineWidget() +{ + delete d; +} + +KTreeViewSearchLine *KTreeViewSearchLineWidget::createSearchLine(QTreeView *treeView) const +{ + return new KTreeViewSearchLine(const_cast(this), treeView); +} + +void KTreeViewSearchLineWidget::createWidgets() +{ + QLabel *label = new QLabel(i18n("S&earch:"), this); + label->setObjectName(QStringLiteral("kde toolbar widget")); + + searchLine()->show(); + + label->setBuddy(d->searchLine); + label->show(); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setSpacing(5); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(label); + layout->addWidget(d->searchLine); +} + +KTreeViewSearchLine *KTreeViewSearchLineWidget::searchLine() const +{ + if (!d->searchLine) + d->searchLine = createSearchLine(d->treeView); + + return d->searchLine; +} + +#include "moc_ktreeviewsearchline.cpp" diff --git a/part/ktreeviewsearchline.h b/part/ktreeviewsearchline.h new file mode 100644 index 0000000..937c456 --- /dev/null +++ b/part/ktreeviewsearchline.h @@ -0,0 +1,230 @@ +/* + Copyright (c) 2003 Scott Wheeler + Copyright (c) 2005 Rafal Rzepecki + Copyright (c) 2006 Hamish Rodda + Copyright 2007 Pino Toscano + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KTREEVIEWSEARCHLINE_H +#define KTREEVIEWSEARCHLINE_H + +#include + +class QModelIndex; +class QTreeView; + +/** + * This class makes it easy to add a search line for filtering the items in + * listviews based on a simple text search. + * + * No changes to the application other than instantiating this class with + * appropriate QTreeViews should be needed. + */ + +class KTreeViewSearchLine : public KLineEdit +{ + Q_OBJECT + + Q_PROPERTY(Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity NOTIFY searchOptionsChanged) + +public: + /** + * Constructs a KTreeViewSearchLine with \a treeView being the QTreeView to + * be filtered. + * + * If \a treeView is null then the widget will be disabled until listview + * are set with setTreeView(). + */ + explicit KTreeViewSearchLine(QWidget *parent = nullptr, QTreeView *treeView = nullptr); + + /** + * Destroys the KTreeViewSearchLine. + */ + ~KTreeViewSearchLine() override; + + /** + * Returns true if the search is case sensitive. This defaults to false. + * + * @see setCaseSensitive() + */ + Qt::CaseSensitivity caseSensitivity() const; + + /** + * Returns true if the search is a regular expression search. This defaults to false. + * + * @see setRegularExpression() + */ + bool regularExpression() const; + + /** + * Returns the listview that is currently filtered by the search. + * + * @see setTreeView() + */ + QTreeView *treeView() const; + +public Q_SLOTS: + /** + * Updates search to only make visible the items that match \a pattern. If + * \a s is null then the line edit's text will be used. + */ + virtual void updateSearch(const QString &pattern = QString()); + + /** + * Make the search case sensitive or case insensitive. + * + * @see caseSenstivity() + */ + void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); + + /** + * Make the search a regular expression search or not. + * + * @see regularExpression() + */ + void setRegularExpression(bool value); + + /** + * Sets the QTreeView that is filtered by this search line, replacing any + * previously filtered listviews. If \a treeView is null then the widget will be + * disabled. + * + * @see treeView() + */ + void setTreeView(QTreeView *treeView); + +Q_SIGNALS: + /** + * This signal is emitted when search options have been changed. It is emitted so + * that users of this class can choose to save the search options to the settings. + */ + void searchOptionsChanged(); + +protected: + /** + * Returns true if \a parentIndex matches the search \a pattern. This will be evaluated + * based on the value of caseSensitive(). This can be overridden in + * subclasses to implement more complicated matching schemes. + */ + virtual bool itemMatches(const QModelIndex &parentIndex, int row, const QString &pattern) const; + + /** + * Re-implemented for internal reasons. API not affected. + */ + void contextMenuEvent(QContextMenuEvent *) override; + + /** + * Updates search to only make visible appropriate items in \a treeView. If + * \a treeView is null then nothing is done. + */ + virtual void updateSearch(QTreeView *treeView); + + /** + * Connects signals of this listview to the appropriate slots of the search + * line. + */ + virtual void connectTreeView(QTreeView *); + + /** + * Disconnects signals of a listviews from the search line. + */ + virtual void disconnectTreeView(QTreeView *); + +protected Q_SLOTS: + /** + * When keys are pressed a new search string is created and a timer is + * activated. The most recent search is activated when this timer runs out + * if another key has not yet been pressed. + * + * This method makes @param search the most recent search and starts the + * timer. + * + * Together with activateSearch() this makes it such that searches are not + * started until there is a short break in the users typing. + * + * @see activateSearch() + */ + void queueSearch(const QString &search); + + /** + * When the timer started with queueSearch() expires this slot is called. + * If there has been another timer started then this slot does nothing. + * However if there are no other pending searches this starts the list view + * search. + * + * @see queueSearch() + */ + void activateSearch(); + +private: + class Private; + Private *const d; + + void rowsInserted(const QModelIndex &, int, int) const; + void treeViewDeleted(QObject *); +}; + +/** + * Creates a widget featuring a KTreeViewSearchLine, a label with the text + * "Search" and a button to clear the search. + */ +class KTreeViewSearchLineWidget : public QWidget +{ + Q_OBJECT + +public: + /** + * Creates a KTreeViewSearchLineWidget for \a treeView with \a parent as the + * parent. + */ + explicit KTreeViewSearchLineWidget(QWidget *parent = nullptr, QTreeView *treeView = nullptr); + + /** + * Destroys the KTreeViewSearchLineWidget + */ + ~KTreeViewSearchLineWidget() override; + + /** + * Returns a pointer to the search line. + */ + KTreeViewSearchLine *searchLine() const; + +protected Q_SLOTS: + /** + * Creates the widgets inside of the widget. This is called from the + * constructor via a single shot timer so that it is guaranteed to run + * after construction is complete. This makes it suitable for overriding in + * subclasses. + */ + virtual void createWidgets(); + +protected: + /** + * Creates the search line. This can be useful to reimplement in cases where + * a KTreeViewSearchLine subclass is used. + * + * It is const because it is be called from searchLine(), which to the user + * doesn't conceptually alter the widget. + */ + virtual KTreeViewSearchLine *createSearchLine(QTreeView *treeView) const; + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/part/latexrenderer.cpp b/part/latexrenderer.cpp new file mode 100644 index 0000000..02ba244 --- /dev/null +++ b/part/latexrenderer.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * Copyright (C) 2004 by Duncan Mac-Vicar Prett * + * Copyright (C) 2004-2005 by Olivier Goffart * + * Copyright (C) 2011 by Niels Ole Salscheider * + * * + * * + * 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. * + ***************************************************************************/ + +#include "latexrenderer.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug_ui.h" + +namespace GuiUtils +{ +LatexRenderer::LatexRenderer() +{ +} + +LatexRenderer::~LatexRenderer() +{ + for (const QString &file : qAsConst(m_fileList)) { + QFile::remove(file); + } +} + +LatexRenderer::Error LatexRenderer::renderLatexInHtml(QString &html, const QColor &textColor, int fontSize, int resolution, QString &latexOutput) +{ + if (!html.contains(QStringLiteral("$$"))) + return NoError; + + // this searches for $$formula$$ + QRegularExpression rg(QStringLiteral("\\$\\$.+?\\$\\$")); + QRegularExpressionMatchIterator it = rg.globalMatch(html); + + QMap replaceMap; + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + const QString matchedString = match.captured(0); + + QString formul = matchedString; + // first remove the $$ delimiters on start and end + formul.remove(QStringLiteral("$$")); + // then trim the result, so we can skip totally empty/whitespace-only formulas + formul = formul.trimmed(); + if (formul.isEmpty() || !securityCheck(formul)) { + continue; + } + + // unescape formula + formul.replace(QLatin1String(">"), QLatin1String(">")); + formul.replace(QLatin1String("<"), QLatin1String("<")); + formul.replace(QLatin1String("&"), QLatin1String("&")); + formul.replace(QLatin1String("""), QLatin1String("\"")); + formul.replace(QLatin1String("'"), QLatin1String("\'")); + formul.replace(QLatin1String("
"), QLatin1String(" ")); + + QString fileName; + Error returnCode = handleLatex(fileName, formul, textColor, fontSize, resolution, latexOutput); + if (returnCode != NoError) { + return returnCode; + } + + replaceMap[matchedString] = fileName; + } + + if (replaceMap.isEmpty()) // we haven't found any LaTeX strings + return NoError; + + int imagePxWidth, imagePxHeight; + for (QMap::ConstIterator it = replaceMap.constBegin(); it != replaceMap.constEnd(); ++it) { + QImage theImage(*it); + if (theImage.isNull()) + continue; + imagePxWidth = theImage.width(); + imagePxHeight = theImage.height(); + QString escapedLATEX = it.key().toHtmlEscaped().replace(QLatin1Char('"'), QLatin1String(""")); // we need the escape quotes because that string will be in a title="" argument, but not the \n + html.replace(it.key(), + QStringLiteral(" \"") ")); + } + return NoError; +} + +bool LatexRenderer::mightContainLatex(const QString &text) +{ + if (!text.contains(QStringLiteral("$$"))) + return false; + + // this searches for $$formula$$ + QRegularExpression rg(QStringLiteral("\\$\\$.+?\\$\\$")); + if (!rg.match(text).hasMatch()) + return false; + + return true; +} + +LatexRenderer::Error LatexRenderer::handleLatex(QString &fileName, const QString &latexFormula, const QColor &textColor, int fontSize, int resolution, QString &latexOutput) +{ + KProcess latexProc; + KProcess dvipngProc; + + QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/okular_kdelatex-XXXXXX.tex")); + tempFile->open(); + QString tempFileName = tempFile->fileName(); + QFileInfo *tempFileInfo = new QFileInfo(tempFileName); + QString tempFileNameNS = tempFileInfo->absolutePath() + '/' + tempFileInfo->baseName(); + QString tempFilePath = tempFileInfo->absolutePath(); + delete tempFileInfo; + QTextStream tempStream(tempFile); + + tempStream << "\ +\\documentclass[" + << fontSize << "pt]{article} \ +\\usepackage{color} \ +\\usepackage{amsmath,latexsym,amsfonts,amssymb,ulem} \ +\\pagestyle{empty} \ +\\begin{document} \ +{\\color[rgb]{" << textColor.redF() + << "," << textColor.greenF() << "," << textColor.blueF() << "} \ +\\begin{eqnarray*} \ +" << latexFormula + << " \ +\\end{eqnarray*}} \ +\\end{document}"; + + tempFile->close(); + QString latexExecutable = QStandardPaths::findExecutable(QStringLiteral("latex")); + if (latexExecutable.isEmpty()) { + qCDebug(OkularUiDebug) << "Could not find latex!"; + delete tempFile; + fileName = QString(); + return LatexNotFound; + } + latexProc << latexExecutable << QStringLiteral("-interaction=nonstopmode") << QStringLiteral("-halt-on-error") << QStringLiteral("-output-directory=%1").arg(tempFilePath) << tempFile->fileName(); + latexProc.setOutputChannelMode(KProcess::MergedChannels); + latexProc.execute(); + latexOutput = QString::fromLocal8Bit(latexProc.readAll()); + tempFile->remove(); + + QFile::remove(tempFileNameNS + QStringLiteral(".log")); + QFile::remove(tempFileNameNS + QStringLiteral(".aux")); + delete tempFile; + + if (!QFile::exists(tempFileNameNS + QStringLiteral(".dvi"))) { + fileName = QString(); + return LatexFailed; + } + + QString dvipngExecutable = QStandardPaths::findExecutable(QStringLiteral("dvipng")); + if (dvipngExecutable.isEmpty()) { + qCDebug(OkularUiDebug) << "Could not find dvipng!"; + fileName = QString(); + return DvipngNotFound; + } + + dvipngProc << dvipngExecutable << QStringLiteral("-o%1").arg(tempFileNameNS + QStringLiteral(".png")) << QStringLiteral("-Ttight") << QStringLiteral("-bgTransparent") << QStringLiteral("-D %1").arg(resolution) + << QStringLiteral("%1").arg(tempFileNameNS + QStringLiteral(".dvi")); + dvipngProc.setOutputChannelMode(KProcess::MergedChannels); + dvipngProc.execute(); + + QFile::remove(tempFileNameNS + QStringLiteral(".dvi")); + + if (!QFile::exists(tempFileNameNS + QStringLiteral(".png"))) { + fileName = QString(); + return DvipngFailed; + } + + fileName = tempFileNameNS + QStringLiteral(".png"); + m_fileList << fileName; + return NoError; +} + +bool LatexRenderer::securityCheck(const QString &latexFormula) +{ + return !latexFormula.contains( + QRegularExpression(QString::fromLatin1("\\\\(def|let|futurelet|newcommand|renewcommand|else|fi|write|input|include" + "|chardef|catcode|makeatletter|noexpand|toksdef|every|errhelp|errorstopmode|scrollmode|nonstopmode|batchmode" + "|read|csname|newhelp|relax|afterground|afterassignment|expandafter|noexpand|special|command|loop|repeat|toks" + "|output|line|mathcode|name|item|section|mbox|DeclareRobustCommand)[^a-zA-Z]"))); +} + +} diff --git a/part/latexrenderer.h b/part/latexrenderer.h new file mode 100644 index 0000000..c3f981d --- /dev/null +++ b/part/latexrenderer.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2004 by Duncan Mac-Vicar Prett * + * Copyright (C) 2004-2005 by Olivier Goffart * + * Copyright (C) 2011 by Niels Ole Salscheider * + * * + * * + * 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 LATEXRENDERER_H +#define LATEXRENDERER_H + +#include + +class QString; +class QColor; + +namespace GuiUtils +{ +class LatexRenderer +{ +public: + enum Error { NoError, LatexNotFound, DvipngNotFound, LatexFailed, DvipngFailed }; + + LatexRenderer(); + ~LatexRenderer(); + + LatexRenderer(const LatexRenderer &) = delete; + LatexRenderer &operator=(const LatexRenderer &) = delete; + + Error renderLatexInHtml(QString &html, const QColor &textColor, int fontSize, int resolution, QString &latexOutput); + static bool mightContainLatex(const QString &text); + +private: + Error handleLatex(QString &fileName, const QString &latexFormula, const QColor &textColor, int fontSize, int resolution, QString &latexOutput); + static bool securityCheck(const QString &latexFormula); + + QStringList m_fileList; +}; + +} + +#endif // LATEXRENDERER_H diff --git a/part/layers.cpp b/part/layers.cpp new file mode 100644 index 0000000..e58d7a0 --- /dev/null +++ b/part/layers.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2015 by Saheb Preet Singh * + * * + * 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. * + ***************************************************************************/ + +#include "layers.h" +#include "settings.h" + +// qt/kde includes +#include +#include +#include +#include +#include + +#include + +// local includes +#include "core/document.h" +#include "ktreeviewsearchline.h" +#include "pageview.h" + +Layers::Layers(QWidget *parent, Okular::Document *document) + : QWidget(parent) + , m_document(document) +{ + QVBoxLayout *const mainlay = new QVBoxLayout(this); + mainlay->setSpacing(6); + + m_document->addObserver(this); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Layers")); + mainlay->addWidget(titleWidget); + mainlay->setAlignment(titleWidget, Qt::AlignHCenter); + m_searchLine = new KTreeViewSearchLine(this); + mainlay->addWidget(m_searchLine); + m_searchLine->setCaseSensitivity(Okular::Settings::self()->layersSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive); + m_searchLine->setRegularExpression(Okular::Settings::self()->layersSearchRegularExpression()); + connect(m_searchLine, &KTreeViewSearchLine::searchOptionsChanged, this, &Layers::saveSearchOptions); + + m_treeView = new QTreeView(this); + mainlay->addWidget(m_treeView); + + m_treeView->setSortingEnabled(false); + m_treeView->setRootIsDecorated(true); + m_treeView->setAlternatingRowColors(true); + m_treeView->header()->hide(); +} + +Layers::~Layers() +{ + m_document->removeObserver(this); +} + +void Layers::notifySetup(const QVector & /*pages*/, int /*setupFlags*/) +{ + QAbstractItemModel *layersModel = m_document->layersModel(); + + if (layersModel) { + m_treeView->setModel(layersModel); + m_searchLine->setTreeView(m_treeView); + emit hasLayers(true); + connect(layersModel, &QAbstractItemModel::dataChanged, m_document, &Okular::Document::reloadDocument); + connect(layersModel, &QAbstractItemModel::dataChanged, m_pageView, &PageView::reloadForms); + } else { + emit hasLayers(false); + } +} + +void Layers::setPageView(PageView *pageView) +{ + m_pageView = pageView; +} + +void Layers::saveSearchOptions() +{ + Okular::Settings::setLayersSearchRegularExpression(m_searchLine->regularExpression()); + Okular::Settings::setLayersSearchCaseSensitive(m_searchLine->caseSensitivity() == Qt::CaseSensitive ? true : false); + Okular::Settings::self()->save(); +} diff --git a/part/layers.h b/part/layers.h new file mode 100644 index 0000000..e3eedc4 --- /dev/null +++ b/part/layers.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2015 by Saheb Preet Singh * + * * + * 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_LAYERS_H_ +#define _OKULAR_LAYERS_H_ + +#include "core/observer.h" +#include + +#include "okularpart_export.h" + +class PageView; +class QTreeView; +class KTreeViewSearchLine; + +namespace Okular +{ +class Document; +class PartTest; +} + +class OKULARPART_EXPORT Layers : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT + friend class Okular::PartTest; + +public: + Layers(QWidget *parent, Okular::Document *document); + ~Layers() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + + void setPageView(PageView *pageView); + +Q_SIGNALS: + void hasLayers(bool has); + +private Q_SLOTS: + void saveSearchOptions(); + +private: + Okular::Document *m_document; + QTreeView *m_treeView; + KTreeViewSearchLine *m_searchLine; + PageView *m_pageView; +}; + +#endif diff --git a/part/magnifierview.cpp b/part/magnifierview.cpp new file mode 100644 index 0000000..02d81fd --- /dev/null +++ b/part/magnifierview.cpp @@ -0,0 +1,189 @@ +/* + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "magnifierview.h" + +#include + +#include "core/document.h" +#include "core/generator.h" +#include "pagepainter.h" +#include "priorities.h" + +static const int SCALE = 10; + +MagnifierView::MagnifierView(Okular::Document *document, QWidget *parent) + : QWidget(parent) + , m_document(document) + , m_page(nullptr) +{ + document->addObserver(this); +} + +MagnifierView::~MagnifierView() +{ + m_document->removeObserver(this); +} + +void MagnifierView::notifySetup(const QVector &pages, int setupFlags) +{ + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) { + return; + } + + m_pages = pages; + m_page = nullptr; + m_current = -1; +} + +void MagnifierView::notifyPageChanged(int page, int flags) +{ + Q_UNUSED(page); + Q_UNUSED(flags); + + if (isVisible()) { + update(); + } +} + +bool MagnifierView::canUnloadPixmap(int page) const +{ + return (page != m_current); +} + +void MagnifierView::notifyCurrentPageChanged(int previous, int current) +{ + Q_UNUSED(previous); + + if (current != m_current) { + m_current = current; + m_page = m_pages[current]; + + if (isVisible()) { + requestPixmap(); + update(); + } + } +} + +void MagnifierView::updateView(const Okular::NormalizedPoint &p, const Okular::Page *page) +{ + m_viewpoint = p; + + if (page != m_page) // ok, we are screwed + { + m_page = page; + m_current = page->number(); + } + + if (isVisible()) { + requestPixmap(); + update(); + } +} + +void MagnifierView::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e); + + QPainter p(this); + + if (m_page) { + QRect where = QRect(0, 0, width(), height()); + PagePainter::paintCroppedPageOnPainter(&p, m_page, this, 0, m_page->width() * SCALE, m_page->height() * SCALE, where, normalizedView(), nullptr); + } + + drawTicks(&p); +} + +void MagnifierView::move(int x, int y) +{ + QWidget::move(x, y); + requestPixmap(); +} + +void MagnifierView::requestPixmap() +{ + const int full_width = m_page->width() * SCALE; + const int full_height = m_page->height() * SCALE; + + Okular::NormalizedRect nrect = normalizedView(); + + if (m_page && !m_page->hasPixmap(this, full_width, full_height, nrect)) { + QLinkedList requestedPixmaps; + + Okular::PixmapRequest *p = new Okular::PixmapRequest(this, m_current, full_width, full_height, PAGEVIEW_PRIO, Okular::PixmapRequest::Asynchronous); + + if (m_page->hasTilesManager(this)) { + p->setTile(true); + } + + // request a little bit bigger rectangle then currently viewed, but not the full scale page + const double rect_width = (nrect.right - nrect.left) * 0.5, rect_height = (nrect.bottom - nrect.top) * 0.5; + + const double top = qMax(nrect.top - rect_height, 0.0); + const double bottom = qMin(nrect.bottom + rect_height, 1.0); + const double left = qMax(nrect.left - rect_width, 0.0); + const double right = qMin(nrect.right + rect_width, 1.0); + + p->setNormalizedRect(Okular::NormalizedRect(left, top, right, bottom)); + requestedPixmaps.push_back(p); + + m_document->requestPixmaps(requestedPixmaps); + } +} + +Okular::NormalizedRect MagnifierView::normalizedView() const +{ + double h = (double)height() / (SCALE * m_page->height() * 2); + double w = (double)width() / (SCALE * m_page->width() * 2); + return Okular::NormalizedRect(m_viewpoint.x - w, m_viewpoint.y - h, m_viewpoint.x + w, m_viewpoint.y + h); +} + +void MagnifierView::drawTicks(QPainter *p) +{ + p->save(); + + p->setPen(QPen(Qt::black, 0)); + // the cross + p->drawLine(width() / 2, 0, width() / 2, height() - 1); + p->drawLine(0, height() / 2, width() - 1, height() / 2); + + // the borders + p->drawLine(0, 0, width() - 1, 0); + p->drawLine(width() - 1, 0, width() - 1, height() - 1); + p->drawLine(0, height() - 1, width() - 1, height() - 1); + p->drawLine(0, height() - 1, 0, 0); + + // ticks + // TODO possibility to switch units (pt, mm, cc, in, printing dots) + float ps = (float)SCALE * 5; // how much pixels in widget is one pixel in document * how often + int tw = 10; // tick size in pixels + + for (float x = 0; x < width(); x += ps) { + p->drawLine(x, 1, x, tw); + p->drawLine(x, height() - 1, x, height() - tw - 1); + p->drawLine(1, x, tw, x); + p->drawLine(width() - 1, x, width() - tw - 1, x); + } + + p->restore(); +} + +#include "moc_magnifierview.cpp" diff --git a/part/magnifierview.h b/part/magnifierview.h new file mode 100644 index 0000000..4a423ad --- /dev/null +++ b/part/magnifierview.h @@ -0,0 +1,59 @@ +/* + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef MAGNIFIERVIEW_H +#define MAGNIFIERVIEW_H + +#include "core/observer.h" +#include "core/page.h" +#include + +class MagnifierView : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT + +public: + explicit MagnifierView(Okular::Document *document, QWidget *parent = nullptr); + ~MagnifierView() override; + + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyPageChanged(int page, int flags) override; + void notifyCurrentPageChanged(int previous, int current) override; + bool canUnloadPixmap(int page) const override; + + void updateView(const Okular::NormalizedPoint &p, const Okular::Page *page); + void move(int x, int y); + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + Okular::NormalizedRect normalizedView() const; + void requestPixmap(); + void drawTicks(QPainter *p); + +private: + Okular::Document *m_document; + Okular::NormalizedPoint m_viewpoint; + const Okular::Page *m_page; + int m_current; + QVector m_pages; +}; + +#endif // MAGNIFIERVIEW_H diff --git a/part/minibar.cpp b/part/minibar.cpp new file mode 100644 index 0000000..4c511e8 --- /dev/null +++ b/part/minibar.cpp @@ -0,0 +1,561 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "minibar.h" + +// qt / kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "core/document.h" +#include "core/page.h" + +// [private widget] a flat qpushbutton that enlights on hover +class HoverButton : public QToolButton +{ + Q_OBJECT +public: + HoverButton(QWidget *parent); +}; + +MiniBarLogic::MiniBarLogic(QObject *parent, Okular::Document *document) + : QObject(parent) + , m_document(document) +{ +} + +MiniBarLogic::~MiniBarLogic() +{ + m_document->removeObserver(this); +} + +void MiniBarLogic::addMiniBar(MiniBar *miniBar) +{ + m_miniBars.insert(miniBar); +} + +void MiniBarLogic::removeMiniBar(MiniBar *miniBar) +{ + m_miniBars.remove(miniBar); +} + +Okular::Document *MiniBarLogic::document() const +{ + return m_document; +} + +int MiniBarLogic::currentPage() const +{ + return m_document->currentPage(); +} + +void MiniBarLogic::notifySetup(const QVector &pageVector, int setupFlags) +{ + // only process data when document changes + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) + return; + + // if document is closed or has no pages, hide widget + const int pages = pageVector.count(); + if (pages < 1) { + for (MiniBar *miniBar : qAsConst(m_miniBars)) { + miniBar->setEnabled(false); + } + return; + } + + bool labelsDiffer = false; + for (const Okular::Page *page : pageVector) { + if (!page->label().isEmpty()) { + if (page->label().toInt() != (page->number() + 1)) { + labelsDiffer = true; + } + } + } + + const QString pagesString = QString::number(pages); + + for (MiniBar *miniBar : qAsConst(m_miniBars)) { + // resize width of widgets + miniBar->resizeForPage(pages); + + // update child widgets + miniBar->m_pageLabelEdit->setPageLabels(pageVector); + miniBar->m_pageNumberEdit->setPagesNumber(pages); + miniBar->m_pagesButton->setText(pagesString); + miniBar->m_prevButton->setEnabled(false); + miniBar->m_nextButton->setEnabled(false); + miniBar->m_pageLabelEdit->setVisible(labelsDiffer); + miniBar->m_pageNumberLabel->setVisible(labelsDiffer); + miniBar->m_pageNumberEdit->setVisible(!labelsDiffer); + + miniBar->adjustSize(); + + miniBar->setEnabled(true); + } +} + +void MiniBarLogic::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + Q_UNUSED(previousPage) + + // get current page number + const int pages = m_document->pages(); + + // if the document is opened and page is changed + if (pages > 0) { + const QString pageNumber = QString::number(currentPage + 1); + const QString pageLabel = m_document->page(currentPage)->label(); + + for (MiniBar *miniBar : qAsConst(m_miniBars)) { + // update prev/next button state + miniBar->m_prevButton->setEnabled(currentPage > 0); + miniBar->m_nextButton->setEnabled(currentPage < (pages - 1)); + // update text on widgets + miniBar->m_pageNumberEdit->setText(pageNumber); + miniBar->m_pageNumberLabel->setText(pageNumber); + miniBar->m_pageLabelEdit->setText(pageLabel); + } + } +} + +/** MiniBar **/ + +MiniBar::MiniBar(QWidget *parent, MiniBarLogic *miniBarLogic) + : QWidget(parent) + , m_miniBarLogic(miniBarLogic) + , m_oldToobarParent(nullptr) +{ + setObjectName(QStringLiteral("miniBar")); + + m_miniBarLogic->addMiniBar(this); + + QHBoxLayout *horLayout = new QHBoxLayout(this); + + horLayout->setContentsMargins(0, 0, 0, 0); + horLayout->setSpacing(3); + + QSize buttonSize(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium); + // bottom: left prev_page button + m_prevButton = new HoverButton(this); + m_prevButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up"))); + m_prevButton->setIconSize(buttonSize); + horLayout->addWidget(m_prevButton); + // bottom: left lineEdit (current page box) + m_pageNumberEdit = new PageNumberEdit(this); + horLayout->addWidget(m_pageNumberEdit); + m_pageNumberEdit->installEventFilter(this); + // bottom: left labelWidget (current page label) + m_pageLabelEdit = new PageLabelEdit(this); + horLayout->addWidget(m_pageLabelEdit); + m_pageLabelEdit->installEventFilter(this); + // bottom: left labelWidget (current page label) + m_pageNumberLabel = new QLabel(this); + m_pageNumberLabel->setAlignment(Qt::AlignCenter); + horLayout->addWidget(m_pageNumberLabel); + // bottom: central 'of' label + horLayout->addSpacing(5); + horLayout->addWidget(new QLabel(i18nc("Layouted like: '5 [pages] of 10'", "of"), this)); + // bottom: right button + m_pagesButton = new HoverButton(this); + horLayout->addWidget(m_pagesButton); + // bottom: right next_page button + m_nextButton = new HoverButton(this); + m_nextButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down"))); + m_nextButton->setIconSize(buttonSize); + horLayout->addWidget(m_nextButton); + + QSizePolicy sp = sizePolicy(); + sp.setHorizontalPolicy(QSizePolicy::Fixed); + sp.setVerticalPolicy(QSizePolicy::Fixed); + setSizePolicy(sp); + + // resize width of widgets + resizeForPage(0); + + // connect signals from child widgets to internal handlers / signals bouncers + connect(m_pageNumberEdit, &PageNumberEdit::returnPressed, this, &MiniBar::slotChangePageFromReturn); + connect(m_pageLabelEdit, &PageLabelEdit::pageNumberChosen, this, &MiniBar::slotChangePage); + connect(m_pagesButton, &QAbstractButton::clicked, this, &MiniBar::gotoPage); + connect(m_prevButton, &QAbstractButton::clicked, this, &MiniBar::prevPage); + connect(m_nextButton, &QAbstractButton::clicked, this, &MiniBar::nextPage); + + adjustSize(); + + // widget starts disabled (will be enabled after opening a document) + setEnabled(false); +} + +MiniBar::~MiniBar() +{ + m_miniBarLogic->removeMiniBar(this); +} + +void MiniBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::ParentChange) { + QToolBar *tb = dynamic_cast(parent()); + if (tb != m_oldToobarParent) { + if (m_oldToobarParent) { + disconnect(m_oldToobarParent, &QToolBar::iconSizeChanged, this, &MiniBar::slotToolBarIconSizeChanged); + } + m_oldToobarParent = tb; + if (tb) { + connect(tb, &QToolBar::iconSizeChanged, this, &MiniBar::slotToolBarIconSizeChanged); + slotToolBarIconSizeChanged(); + } + } + } +} + +bool MiniBar::eventFilter(QObject *target, QEvent *event) +{ + if (target == m_pageNumberEdit || target == m_pageLabelEdit) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + int key = keyEvent->key(); + if (key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Up || key == Qt::Key_Down) { + emit forwardKeyPressEvent(keyEvent); + return true; + } + } + } + return false; +} + +void MiniBar::slotChangePageFromReturn() +{ + // get text from the lineEdit + const QString pageNumber = m_pageNumberEdit->text(); + + // convert it to page number and go to that page + bool ok; + int number = pageNumber.toInt(&ok) - 1; + if (ok && number >= 0 && number < (int)m_miniBarLogic->document()->pages() && number != m_miniBarLogic->currentPage()) { + slotChangePage(number); + } +} + +void MiniBar::slotChangePage(int pageNumber) +{ + m_miniBarLogic->document()->setViewportPage(pageNumber); + m_pageNumberEdit->clearFocus(); + m_pageLabelEdit->clearFocus(); +} + +void MiniBar::slotEmitNextPage() +{ + // emit signal + emit nextPage(); +} + +void MiniBar::slotEmitPrevPage() +{ + // emit signal + emit prevPage(); +} + +void MiniBar::slotToolBarIconSizeChanged() +{ + const QSize buttonSize = m_oldToobarParent->iconSize(); + m_prevButton->setIconSize(buttonSize); + m_nextButton->setIconSize(buttonSize); +} + +void MiniBar::resizeForPage(int pages) +{ + const int numberWidth = 10 + fontMetrics().horizontalAdvance(QString::number(pages)); + m_pageNumberEdit->setMinimumWidth(numberWidth); + m_pageNumberEdit->setMaximumWidth(2 * numberWidth); + m_pageLabelEdit->setMinimumWidth(numberWidth); + m_pageLabelEdit->setMaximumWidth(2 * numberWidth); + m_pageNumberLabel->setMinimumWidth(numberWidth); + m_pageNumberLabel->setMaximumWidth(2 * numberWidth); + m_pagesButton->setMinimumWidth(numberWidth); + m_pagesButton->setMaximumWidth(2 * numberWidth); +} + +/** ProgressWidget **/ + +ProgressWidget::ProgressWidget(QWidget *parent, Okular::Document *document) + : QWidget(parent) + , m_document(document) + , m_progressPercentage(-1) +{ + setObjectName(QStringLiteral("progress")); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setFixedHeight(4); + setMouseTracking(true); +} + +ProgressWidget::~ProgressWidget() +{ + m_document->removeObserver(this); +} + +void ProgressWidget::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + Q_UNUSED(previousPage) + + // get current page number + int pages = m_document->pages(); + + // if the document is opened and page is changed + if (pages > 0) { + // update percentage + const float percentage = pages < 2 ? 1.0 : (float)currentPage / (float)(pages - 1); + setProgress(percentage); + } +} + +void ProgressWidget::setProgress(float percentage) +{ + m_progressPercentage = percentage; + update(); +} + +void ProgressWidget::slotGotoNormalizedPage(float index) +{ + // figure out page number and go to that page + int number = (int)(index * (float)m_document->pages()); + if (number >= 0 && number < (int)m_document->pages() && number != (int)m_document->currentPage()) + m_document->setViewportPage(number); +} + +void ProgressWidget::mouseMoveEvent(QMouseEvent *e) +{ + if ((QApplication::mouseButtons() & Qt::LeftButton) && width() > 0) + slotGotoNormalizedPage((float)(QApplication::isRightToLeft() ? width() - e->x() : e->x()) / (float)width()); +} + +void ProgressWidget::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton && width() > 0) + slotGotoNormalizedPage((float)(QApplication::isRightToLeft() ? width() - e->x() : e->x()) / (float)width()); +} + +void ProgressWidget::wheelEvent(QWheelEvent *e) +{ + if (e->angleDelta().y() > 0) + emit nextPage(); + else + emit prevPage(); +} + +void ProgressWidget::paintEvent(QPaintEvent *e) +{ + QPainter p(this); + + if (m_progressPercentage < 0.0) { + p.fillRect(rect(), palette().color(QPalette::Active, QPalette::HighlightedText)); + return; + } + + // find out the 'fill' and the 'clear' rectangles + int w = width(), h = height(), l = (int)((float)w * m_progressPercentage); + QRect cRect = (QApplication::isRightToLeft() ? QRect(0, 0, w - l, h) : QRect(l, 0, w - l, h)).intersected(e->rect()); + QRect fRect = (QApplication::isRightToLeft() ? QRect(w - l, 0, l, h) : QRect(0, 0, l, h)).intersected(e->rect()); + + QPalette pal = palette(); + // paint clear rect + if (cRect.isValid()) + p.fillRect(cRect, pal.color(QPalette::Active, QPalette::HighlightedText)); + // draw a frame-like outline + // p.setPen( palette().active().mid() ); + // p.drawRect( 0,0, w, h ); + // paint fill rect + if (fRect.isValid()) + p.fillRect(fRect, pal.color(QPalette::Active, QPalette::Highlight)); + if (l && l != w) { + p.setPen(pal.color(QPalette::Active, QPalette::Highlight).darker(120)); + int delta = QApplication::isRightToLeft() ? w - l : l; + p.drawLine(delta, 0, delta, h); + } +} + +/** PageLabelEdit **/ + +PageLabelEdit::PageLabelEdit(MiniBar *parent) + : PagesEdit(parent) +{ + setVisible(false); + connect(this, &PageLabelEdit::returnPressed, this, &PageLabelEdit::pageChosen); +} + +void PageLabelEdit::setText(const QString &newText) +{ + m_lastLabel = newText; + PagesEdit::setText(newText); +} + +void PageLabelEdit::setPageLabels(const QVector &pageVector) +{ + m_labelPageMap.clear(); + completionObject()->clear(); + for (const Okular::Page *page : pageVector) { + if (!page->label().isEmpty()) { + m_labelPageMap.insert(page->label(), page->number()); + bool ok; + page->label().toInt(&ok); + if (!ok) { + // Only add to the completion objects labels that are not numbers + completionObject()->addItem(page->label()); + } + } + } +} + +void PageLabelEdit::pageChosen() +{ + const QString newInput = text(); + const int pageNumber = m_labelPageMap.value(newInput, -1); + if (pageNumber != -1) { + emit pageNumberChosen(pageNumber); + } else { + setText(m_lastLabel); + } +} + +/** PageNumberEdit **/ + +PageNumberEdit::PageNumberEdit(MiniBar *miniBar) + : PagesEdit(miniBar) +{ + // use an integer validator + m_validator = new QIntValidator(1, 1, this); + setValidator(m_validator); +} + +void PageNumberEdit::setPagesNumber(int pages) +{ + m_validator->setTop(pages); +} + +/** PagesEdit **/ + +PagesEdit::PagesEdit(MiniBar *parent) + : KLineEdit(parent) + , m_miniBar(parent) + , m_eatClick(false) +{ + // customize text properties + setAlignment(Qt::AlignCenter); + + // send a focus out event + QFocusEvent fe(QEvent::FocusOut); + QApplication::sendEvent(this, &fe); + + connect(qApp, &QGuiApplication::paletteChanged, this, &PagesEdit::updatePalette); +} + +void PagesEdit::setText(const QString &newText) +{ + // call default handler if hasn't focus + if (!hasFocus()) { + KLineEdit::setText(newText); + } + // else preserve existing selection + else { + // save selection and adapt it to the new text length + int selectionLength = selectedText().length(); + const bool allSelected = (selectionLength == text().length()); + if (allSelected) { + KLineEdit::setText(newText); + selectAll(); + } else { + int newSelectionStart = newText.length() - text().length() + selectionStart(); + if (newSelectionStart < 0) { + // the new text is shorter than the old one, and the front part, which is "cut off", is selected + // shorten the selection accordingly + selectionLength += newSelectionStart; + newSelectionStart = 0; + } + KLineEdit::setText(newText); + setSelection(newSelectionStart, selectionLength); + } + } +} + +void PagesEdit::updatePalette() +{ + QPalette pal; + + if (hasFocus()) + pal.setColor(QPalette::Active, QPalette::Base, QApplication::palette().color(QPalette::Active, QPalette::Base)); + else + pal.setColor(QPalette::Base, QApplication::palette().color(QPalette::Base).darker(102)); + + setPalette(pal); +} + +void PagesEdit::focusInEvent(QFocusEvent *e) +{ + // select all text + selectAll(); + if (e->reason() == Qt::MouseFocusReason) + m_eatClick = true; + // change background color to the default 'edit' color + updatePalette(); + // call default handler + KLineEdit::focusInEvent(e); +} + +void PagesEdit::focusOutEvent(QFocusEvent *e) +{ + // change background color to a dark tone + updatePalette(); + // call default handler + KLineEdit::focusOutEvent(e); +} + +void PagesEdit::mousePressEvent(QMouseEvent *e) +{ + // if this click got the focus in, don't process the event + if (!m_eatClick) + KLineEdit::mousePressEvent(e); + m_eatClick = false; +} + +void PagesEdit::wheelEvent(QWheelEvent *e) +{ + if (e->angleDelta().y() > 0) + m_miniBar->slotEmitNextPage(); + else + m_miniBar->slotEmitPrevPage(); +} + +/** HoverButton **/ + +HoverButton::HoverButton(QWidget *parent) + : QToolButton(parent) +{ + setAutoRaise(true); + setFocusPolicy(Qt::NoFocus); + setToolButtonStyle(Qt::ToolButtonIconOnly); + KAcceleratorManager::setNoAccel(this); +} + +#include "minibar.moc" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/minibar.h b/part/minibar.h new file mode 100644 index 0000000..c98f0af --- /dev/null +++ b/part/minibar.h @@ -0,0 +1,183 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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_MINIBAR_H_ +#define _OKULAR_MINIBAR_H_ + +#include "core/observer.h" +#include +#include +#include + +namespace Okular +{ +class Document; +} + +class MiniBar; +class HoverButton; +class QIntValidator; +class QLabel; +class QToolBar; + +// [private widget] lineEdit for entering/validating page numbers +class PagesEdit : public KLineEdit +{ + Q_OBJECT + +public: + explicit PagesEdit(MiniBar *parent); + void setText(const QString &) override; + +protected: + void focusInEvent(QFocusEvent *e) override; + void focusOutEvent(QFocusEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + +private Q_SLOTS: + void updatePalette(); + +private: + MiniBar *m_miniBar; + bool m_eatClick; +}; + +class PageNumberEdit : public PagesEdit +{ + Q_OBJECT + +public: + explicit PageNumberEdit(MiniBar *miniBar); + void setPagesNumber(int pages); + +private: + QIntValidator *m_validator; +}; + +class PageLabelEdit : public PagesEdit +{ + Q_OBJECT +public: + explicit PageLabelEdit(MiniBar *parent); + void setText(const QString &newText) override; + void setPageLabels(const QVector &pageVector); + +Q_SIGNALS: + void pageNumberChosen(int page); + +private Q_SLOTS: + void pageChosen(); + +private: + QString m_lastLabel; + QMap m_labelPageMap; +}; + +/** + * @short The object that observes the document and feeds the minibars + */ +class MiniBarLogic : public QObject, public Okular::DocumentObserver +{ + Q_OBJECT + +public: + MiniBarLogic(QObject *parent, Okular::Document *m_document); + ~MiniBarLogic() override; + + void addMiniBar(MiniBar *miniBar); + void removeMiniBar(MiniBar *miniBar); + + Okular::Document *document() const; + int currentPage() const; + + // [INHERITED] from DocumentObserver + void notifySetup(const QVector &pageVector, int setupFlags) override; + void notifyCurrentPageChanged(int previous, int current) override; + +private: + QSet m_miniBars; + Okular::Document *m_document; +}; + +/** + * @short A widget to display page number and change current page. + */ +class MiniBar : public QWidget +{ + Q_OBJECT + friend class MiniBarLogic; + +public: + MiniBar(QWidget *parent, MiniBarLogic *miniBarLogic); + ~MiniBar() override; + + void changeEvent(QEvent *event) override; + +Q_SIGNALS: + void gotoPage(); + void prevPage(); + void nextPage(); + void forwardKeyPressEvent(QKeyEvent *e); + +public Q_SLOTS: + void slotChangePageFromReturn(); + void slotChangePage(int page); + void slotEmitNextPage(); + void slotEmitPrevPage(); + void slotToolBarIconSizeChanged(); + +private: + void resizeForPage(int pages); + bool eventFilter(QObject *target, QEvent *event) override; + + MiniBarLogic *m_miniBarLogic; + PageNumberEdit *m_pageNumberEdit; + PageLabelEdit *m_pageLabelEdit; + QLabel *m_pageNumberLabel; + HoverButton *m_prevButton; + HoverButton *m_pagesButton; + HoverButton *m_nextButton; + QToolBar *m_oldToobarParent; +}; + +/** + * @short A small progress bar. + */ +class ProgressWidget : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT +public: + ProgressWidget(QWidget *parent, Okular::Document *document); + ~ProgressWidget() override; + + // [INHERITED] from DocumentObserver + void notifyCurrentPageChanged(int previous, int current) override; + + void slotGotoNormalizedPage(float index); + +Q_SIGNALS: + void prevPage(); + void nextPage(); + +protected: + void setProgress(float percentage); + + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private: + Okular::Document *m_document; + float m_progressPercentage; +}; + +#endif diff --git a/part/okmenutitle.cpp b/part/okmenutitle.cpp new file mode 100644 index 0000000..4051166 --- /dev/null +++ b/part/okmenutitle.cpp @@ -0,0 +1,64 @@ +/* This file was part of the KDE libraries (copied partially from kmenu.cpp) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "okmenutitle.h" + +#include +#include +#include +#include +#include + +OKMenuTitle::OKMenuTitle(QMenu *menu, const QString &text, const QIcon &icon) + : QWidgetAction(menu) +{ + QAction *buttonAction = new QAction(menu); + QFont font = buttonAction->font(); + font.setBold(true); + buttonAction->setFont(font); + buttonAction->setText(text); + buttonAction->setIcon(icon); + + QToolButton *titleButton = new QToolButton(menu); + titleButton->installEventFilter(this); // prevent clicks on the title of the menu + titleButton->setDefaultAction(buttonAction); + titleButton->setDown(true); // prevent hover style changes in some styles + titleButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + setDefaultWidget(titleButton); +} + +bool OKMenuTitle::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object); + + if (event->type() == QEvent::Paint) { + return QWidgetAction::eventFilter(object, event); + } else if (event->type() == QEvent::KeyRelease) { + // If we're receiving the key release event is because we just gained + // focus though a key event, use the same key to move it to the next action + if (static_cast(parentWidget())->activeAction() == this) { + QKeyEvent *ke = static_cast(event); + QKeyEvent newKe(QEvent::KeyPress, ke->key(), ke->modifiers(), ke->text(), ke->isAutoRepeat(), ke->count()); + QApplication::sendEvent(parentWidget(), &newKe); + } + + // TODO What happens when there's multiple OKMenuTitle or only OKMenuTitle in a menu + } + + event->accept(); + return true; +} diff --git a/part/okmenutitle.h b/part/okmenutitle.h new file mode 100644 index 0000000..db17035 --- /dev/null +++ b/part/okmenutitle.h @@ -0,0 +1,32 @@ +/* This file was part of the KDE libraries (copied partially from kmenu.cpp) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef OKMENUTITLE_H +#define OKMENUTITLE_H + +#include + +class OKMenuTitle : public QWidgetAction +{ + Q_OBJECT +public: + OKMenuTitle(QMenu *menu, const QString &text, const QIcon &icon = QIcon()); + + bool eventFilter(QObject *object, QEvent *event) override; +}; + +#endif diff --git a/part/pageitemdelegate.cpp b/part/pageitemdelegate.cpp new file mode 100644 index 0000000..93a7f7f --- /dev/null +++ b/part/pageitemdelegate.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2006 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. * + ***************************************************************************/ + +#include "pageitemdelegate.h" + +// qt/kde includes +#include +#include +#include +#include + +// local includes +#include "settings.h" + +#define PAGEITEMDELEGATE_INTERNALMARGIN 3 + +class PageItemDelegate::Private +{ +public: + Private() + { + } + + QModelIndex index; +}; + +PageItemDelegate::PageItemDelegate(QObject *parent) + : QItemDelegate(parent) + , d(new Private) +{ +} + +PageItemDelegate::~PageItemDelegate() +{ + delete d; +} + +void PageItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + d->index = index; + QItemDelegate::paint(painter, option, index); +} + +void PageItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const +{ + QVariant pageVariant = d->index.data(PageRole); + QVariant labelVariant = d->index.data(PageLabelRole); + if ((labelVariant.type() != QVariant::String && !pageVariant.canConvert(QVariant::String)) || !Okular::Settings::tocPageColumn()) { + QItemDelegate::drawDisplay(painter, option, rect, text); + return; + } + QString label = labelVariant.toString(); + QString page = label.isEmpty() ? pageVariant.toString() : label; + QTextDocument document; + document.setPlainText(page); + document.setDefaultFont(option.font); + int margindelta = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + int pageRectWidth = (int)document.size().width(); + QRect newRect(rect); + QRect pageRect(rect); + pageRect.setWidth(pageRectWidth + 2 * margindelta); + newRect.setWidth(newRect.width() - pageRectWidth - PAGEITEMDELEGATE_INTERNALMARGIN); + if (option.direction == Qt::RightToLeft) + newRect.translate(pageRectWidth + PAGEITEMDELEGATE_INTERNALMARGIN, 0); + else + pageRect.translate(newRect.width() + PAGEITEMDELEGATE_INTERNALMARGIN - 2 * margindelta, 0); + QItemDelegate::drawDisplay(painter, option, newRect, text); + QStyleOptionViewItem newoption(option); + newoption.displayAlignment = (option.displayAlignment & ~Qt::AlignHorizontal_Mask) | Qt::AlignRight; + QItemDelegate::drawDisplay(painter, newoption, pageRect, page); +} + +#include "moc_pageitemdelegate.cpp" diff --git a/part/pageitemdelegate.h b/part/pageitemdelegate.h new file mode 100644 index 0000000..d10d510 --- /dev/null +++ b/part/pageitemdelegate.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2006 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 PAGEITEMDELEGATE_H +#define PAGEITEMDELEGATE_H + +#include + +class PageItemDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + explicit PageItemDelegate(QObject *parent = nullptr); + ~PageItemDelegate() override; + + static const int PageRole = 0x000f0001; + static const int PageLabelRole = 0x000f0002; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +protected: + void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const override; + +private: + class Private; + Private *const d; +}; + +#endif diff --git a/part/pagepainter.cpp b/part/pagepainter.cpp new file mode 100644 index 0000000..499d917 --- /dev/null +++ b/part/pagepainter.cpp @@ -0,0 +1,1226 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "pagepainter.h" + +// qt / kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// system includes +#include + +// local includes +#include "core/observer.h" +#include "core/page.h" +#include "core/page_p.h" +#include "core/tile.h" +#include "core/utils.h" +#include "debug_ui.h" +#include "guiutils.h" +#include "settings.h" +#include "settings_core.h" + +Q_GLOBAL_STATIC_WITH_ARGS(QPixmap, busyPixmap, (KIconLoader::global()->loadIcon(QLatin1String("okular"), KIconLoader::NoGroup, KIconLoader::SizeLarge, KIconLoader::DefaultState, QStringList(), nullptr, true))) + +#define TEXTANNOTATION_ICONSIZE 24 + +inline QPen buildPen(const Okular::Annotation *ann, double width, const QColor &color) +{ + QColor c = color; + c.setAlphaF(ann->style().opacity()); + QPen p(QBrush(c), width, ann->style().lineStyle() == Okular::Annotation::Dashed ? Qt::DashLine : Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin); + return p; +} + +void PagePainter::paintPageOnPainter(QPainter *destPainter, const Okular::Page *page, Okular::DocumentObserver *observer, int flags, int scaledWidth, int scaledHeight, const QRect limits) +{ + paintCroppedPageOnPainter(destPainter, page, observer, flags, scaledWidth, scaledHeight, limits, Okular::NormalizedRect(0, 0, 1, 1), nullptr); +} + +void PagePainter::paintCroppedPageOnPainter(QPainter *destPainter, + const Okular::Page *page, + Okular::DocumentObserver *observer, + int flags, + int scaledWidth, + int scaledHeight, + const QRect limits, + const Okular::NormalizedRect &crop, + Okular::NormalizedPoint *viewPortPoint) +{ + qreal dpr = destPainter->device()->devicePixelRatioF(); + + /* Calculate the cropped geometry of the page */ + QRect scaledCrop = crop.geometry(scaledWidth, scaledHeight); + + /* variables prefixed with d are in the device pixels coordinate system, which translates to the rendered output - that means, + * multiplied with the device pixel ratio of the target PaintDevice */ + const QRect dScaledCrop(QRectF(scaledCrop.x() * dpr, scaledCrop.y() * dpr, scaledCrop.width() * dpr, scaledCrop.height() * dpr).toAlignedRect()); + + int croppedWidth = scaledCrop.width(); + int croppedHeight = scaledCrop.height(); + + int dScaledWidth = ceil(scaledWidth * dpr); + int dScaledHeight = ceil(scaledHeight * dpr); + const QRect dLimits(QRectF(limits.x() * dpr, limits.y() * dpr, limits.width() * dpr, limits.height() * dpr).toAlignedRect()); + + QColor paperColor = Qt::white; + QColor backgroundColor = paperColor; + if (Okular::SettingsCore::changeColors()) { + switch (Okular::SettingsCore::renderMode()) { + case Okular::SettingsCore::EnumRenderMode::Inverted: + backgroundColor = Qt::black; + break; + case Okular::SettingsCore::EnumRenderMode::Paper: + paperColor = Okular::SettingsCore::paperColor(); + backgroundColor = paperColor; + break; + case Okular::SettingsCore::EnumRenderMode::Recolor: + backgroundColor = Okular::Settings::recolorBackground(); + break; + default:; + } + } + destPainter->fillRect(limits, backgroundColor); + + const bool hasTilesManager = page->hasTilesManager(observer); + QPixmap pixmap; + + if (!hasTilesManager) { + /** 1 - RETRIEVE THE 'PAGE+ID' PIXMAP OR A SIMILAR 'PAGE' ONE **/ + const QPixmap *p = page->_o_nearestPixmap(observer, dScaledWidth, dScaledHeight); + + if (p != nullptr) { + pixmap = *p; + pixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + } + + /** 1B - IF NO PIXMAP, DRAW EMPTY PAGE **/ + double pixmapRescaleRatio = !pixmap.isNull() ? dScaledWidth / (double)pixmap.width() : -1; + long pixmapPixels = !pixmap.isNull() ? (long)pixmap.width() * (long)pixmap.height() : 0; + if (pixmap.isNull() || pixmapRescaleRatio > 20.0 || pixmapRescaleRatio < 0.25 || (dScaledWidth > pixmap.width() && pixmapPixels > 60000000L)) { + // draw something on the blank page: the okular icon or a cross (as a fallback) + if (!busyPixmap()->isNull()) { + busyPixmap->setDevicePixelRatio(dpr); + destPainter->drawPixmap(QPoint(10, 10), *busyPixmap()); + } else { + destPainter->setPen(Qt::gray); + destPainter->drawLine(0, 0, croppedWidth - 1, croppedHeight - 1); + destPainter->drawLine(0, croppedHeight - 1, croppedWidth - 1, 0); + } + return; + } + } + + /** 2 - FIND OUT WHAT TO PAINT (Flags + Configuration + Presence) **/ + bool canDrawHighlights = (flags & Highlights) && !page->m_highlights.isEmpty(); + bool canDrawTextSelection = (flags & TextSelection) && page->textSelection(); + bool canDrawAnnotations = (flags & Annotations) && !page->m_annotations.isEmpty(); + bool enhanceLinks = (flags & EnhanceLinks) && Okular::Settings::highlightLinks(); + bool enhanceImages = (flags & EnhanceImages) && Okular::Settings::highlightImages(); + + // vectors containing objects to draw + // make this a qcolor, rect map, since we don't need + // to know s_id here! we are only drawing this right? + QList> *bufferedHighlights = nullptr; + QList *bufferedAnnotations = nullptr; + QList *unbufferedAnnotations = nullptr; + Okular::Annotation *boundingRectOnlyAnn = nullptr; // Paint the bounding rect of this annotation + // fill up lists with visible annotation/highlight objects/text selections + if (canDrawHighlights || canDrawTextSelection || canDrawAnnotations) { + // precalc normalized 'limits rect' for intersection + double nXMin = ((double)limits.left() / scaledWidth) + crop.left, nXMax = ((double)limits.right() / scaledWidth) + crop.left, nYMin = ((double)limits.top() / scaledHeight) + crop.top, + nYMax = ((double)limits.bottom() / scaledHeight) + crop.top; + // append all highlights inside limits to their list + if (canDrawHighlights) { + if (!bufferedHighlights) + bufferedHighlights = new QList>(); + /* else + {*/ + + Okular::NormalizedRect *limitRect = new Okular::NormalizedRect(nXMin, nYMin, nXMax, nYMax); + QLinkedList::const_iterator h2It = page->m_highlights.constBegin(), hEnd = page->m_highlights.constEnd(); + Okular::HighlightAreaRect::const_iterator hIt; + for (; h2It != hEnd; ++h2It) + for (hIt = (*h2It)->constBegin(); hIt != (*h2It)->constEnd(); ++hIt) { + if ((*hIt).intersects(limitRect)) + bufferedHighlights->append(qMakePair((*h2It)->color, *hIt)); + } + delete limitRect; + //} + } + if (canDrawTextSelection) { + if (!bufferedHighlights) + bufferedHighlights = new QList>(); + /* else + {*/ + Okular::NormalizedRect *limitRect = new Okular::NormalizedRect(nXMin, nYMin, nXMax, nYMax); + const Okular::RegularAreaRect *textSelection = page->textSelection(); + Okular::HighlightAreaRect::const_iterator hIt = textSelection->constBegin(), hEnd = textSelection->constEnd(); + for (; hIt != hEnd; ++hIt) { + if ((*hIt).intersects(limitRect)) + bufferedHighlights->append(qMakePair(page->textSelectionColor(), *hIt)); + } + delete limitRect; + //} + } + // append annotations inside limits to the un/buffered list + if (canDrawAnnotations) { + QLinkedList::const_iterator aIt = page->m_annotations.constBegin(), aEnd = page->m_annotations.constEnd(); + for (; aIt != aEnd; ++aIt) { + Okular::Annotation *ann = *aIt; + int flags = ann->flags(); + + if (flags & Okular::Annotation::Hidden) + continue; + + if (flags & Okular::Annotation::ExternallyDrawn) { + // ExternallyDrawn annots are never rendered by PagePainter. + // Just paint the boundingRect if the annot is moved or resized. + if (flags & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)) { + boundingRectOnlyAnn = ann; + } + continue; + } + + bool intersects = ann->transformedBoundingRectangle().intersects(nXMin, nYMin, nXMax, nYMax); + if (ann->subType() == Okular::Annotation::AText) { + Okular::TextAnnotation *ta = static_cast(ann); + if (ta->textType() == Okular::TextAnnotation::Linked) { + Okular::NormalizedRect iconrect(ann->transformedBoundingRectangle().left, + ann->transformedBoundingRectangle().top, + ann->transformedBoundingRectangle().left + TEXTANNOTATION_ICONSIZE / page->width(), + ann->transformedBoundingRectangle().top + TEXTANNOTATION_ICONSIZE / page->height()); + intersects = iconrect.intersects(nXMin, nYMin, nXMax, nYMax); + } + } + if (intersects) { + Okular::Annotation::SubType type = ann->subType(); + if (type == Okular::Annotation::ALine || type == Okular::Annotation::AHighlight || type == Okular::Annotation::AInk /*|| (type == Annotation::AGeom && ann->style().opacity() < 0.99)*/) { + if (!bufferedAnnotations) + bufferedAnnotations = new QList(); + bufferedAnnotations->append(ann); + } else { + if (!unbufferedAnnotations) + unbufferedAnnotations = new QList(); + unbufferedAnnotations->append(ann); + } + } + } + } + // end of intersections checking + } + + /** 3 - ENABLE BACKBUFFERING IF DIRECT IMAGE MANIPULATION IS NEEDED **/ + bool bufferAccessibility = (flags & Accessibility) && Okular::SettingsCore::changeColors() && (Okular::SettingsCore::renderMode() != Okular::SettingsCore::EnumRenderMode::Paper); + bool useBackBuffer = bufferAccessibility || bufferedHighlights || bufferedAnnotations || viewPortPoint; + QPixmap *backPixmap = nullptr; + QPainter *mixedPainter = nullptr; + QRect limitsInPixmap = limits.translated(scaledCrop.topLeft()); + QRect dLimitsInPixmap = dLimits.translated(dScaledCrop.topLeft()); + + // limits within full (scaled but uncropped) pixmap + + /** 4A -- REGULAR FLOW. PAINT PIXMAP NORMAL OR RESCALED USING GIVEN QPAINTER **/ + if (!useBackBuffer) { + if (hasTilesManager) { + const Okular::NormalizedRect normalizedLimits(limitsInPixmap, scaledWidth, scaledHeight); + const QList tiles = page->tilesAt(observer, normalizedLimits); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + while (tIt != tEnd) { + const Okular::Tile &tile = *tIt; + QRect tileRect = tile.rect().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()); + QRect dTileRect = QRectF(tileRect.x() * dpr, tileRect.y() * dpr, tileRect.width() * dpr, tileRect.height() * dpr).toAlignedRect(); + QRect limitsInTile = limits & tileRect; + QRectF dLimitsInTile = dLimits & dTileRect; + + if (!limitsInTile.isEmpty()) { + QPixmap *tilePixmap = tile.pixmap(); + tilePixmap->setDevicePixelRatio(qApp->devicePixelRatio()); + + if (tilePixmap->width() == dTileRect.width() && tilePixmap->height() == dTileRect.height()) { + destPainter->drawPixmap(limitsInTile.topLeft(), *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft())); + } else { + destPainter->drawPixmap(tileRect, *tilePixmap); + } + } + tIt++; + } + } else { + QPixmap scaledCroppedPixmap = pixmap.scaled(dScaledWidth, dScaledHeight).copy(dLimitsInPixmap); + scaledCroppedPixmap.setDevicePixelRatio(dpr); + destPainter->drawPixmap(limits.topLeft(), scaledCroppedPixmap, QRectF(0, 0, dLimits.width(), dLimits.height())); + } + + // 4A.2. active painter is the one passed to this method + mixedPainter = destPainter; + } + /** 4B -- BUFFERED FLOW. IMAGE PAINTING + OPERATIONS. QPAINTER OVER PIXMAP **/ + else { + // the image over which we are going to draw + QImage backImage = QImage(dLimits.width(), dLimits.height(), QImage::Format_ARGB32_Premultiplied); + backImage.setDevicePixelRatio(dpr); + backImage.fill(paperColor); + QPainter p(&backImage); + + if (hasTilesManager) { + const Okular::NormalizedRect normalizedLimits(limitsInPixmap, scaledWidth, scaledHeight); + const QList tiles = page->tilesAt(observer, normalizedLimits); + QList::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd(); + while (tIt != tEnd) { + const Okular::Tile &tile = *tIt; + QRect tileRect = tile.rect().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()); + QRect dTileRect(QRectF(tileRect.x() * dpr, tileRect.y() * dpr, tileRect.width() * dpr, tileRect.height() * dpr).toAlignedRect()); + QRect limitsInTile = limits & tileRect; + QRect dLimitsInTile = dLimits & dTileRect; + + if (!limitsInTile.isEmpty()) { + QPixmap *tilePixmap = tile.pixmap(); + tilePixmap->setDevicePixelRatio(qApp->devicePixelRatio()); + + if (tilePixmap->width() == dTileRect.width() && tilePixmap->height() == dTileRect.height()) { + p.drawPixmap(limitsInTile.translated(-limits.topLeft()).topLeft(), *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft())); + } else { + double xScale = tilePixmap->width() / (double)dTileRect.width(); + double yScale = tilePixmap->height() / (double)dTileRect.height(); + QTransform transform(xScale, 0, 0, yScale, 0, 0); + p.drawPixmap(limitsInTile.translated(-limits.topLeft()), *tilePixmap, transform.mapRect(dLimitsInTile).translated(-transform.mapRect(dTileRect).topLeft())); + } + } + ++tIt; + } + } else { + // 4B.1. draw the page pixmap: normal or scaled + QPixmap scaledCroppedPixmap = pixmap.scaled(dScaledWidth, dScaledHeight).copy(dLimitsInPixmap); + scaledCroppedPixmap.setDevicePixelRatio(dpr); + p.drawPixmap(0, 0, scaledCroppedPixmap); + } + + p.end(); + + // 4B.2. modify pixmap following accessibility settings + if (bufferAccessibility) { + switch (Okular::SettingsCore::renderMode()) { + case Okular::SettingsCore::EnumRenderMode::Inverted: + // Invert image pixels using QImage internal function + backImage.invertPixels(QImage::InvertRgb); + break; + case Okular::SettingsCore::EnumRenderMode::Recolor: + recolor(&backImage, Okular::Settings::recolorForeground(), Okular::Settings::recolorBackground()); + break; + case Okular::SettingsCore::EnumRenderMode::BlackWhite: + blackWhite(&backImage, Okular::Settings::bWContrast(), Okular::Settings::bWThreshold()); + break; + case Okular::SettingsCore::EnumRenderMode::InvertLightness: + invertLightness(&backImage); + break; + case Okular::SettingsCore::EnumRenderMode::InvertLuma: + invertLuma(&backImage, 0.2126, 0.7152, 0.0722); // sRGB / Rec. 709 luma coefficients + break; + case Okular::SettingsCore::EnumRenderMode::InvertLumaSymmetric: + invertLuma(&backImage, 0.3333, 0.3334, 0.3333); // Symmetric coefficients, to keep colors saturated. + break; + case Okular::SettingsCore::EnumRenderMode::HueShiftPositive: + hueShiftPositive(&backImage); + break; + case Okular::SettingsCore::EnumRenderMode::HueShiftNegative: + hueShiftNegative(&backImage); + break; + } + } + + // 4B.3. highlight rects in page + if (bufferedHighlights) { + // draw highlights that are inside the 'limits' paint region + for (const auto &highlight : qAsConst(*bufferedHighlights)) { + const Okular::NormalizedRect &r = highlight.second; + // find out the rect to highlight on pixmap + QRect highlightRect = r.geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()).intersected(limits); + highlightRect.translate(-limits.left(), -limits.top()); + + const QColor highlightColor = highlight.first; + QPainter painter(&backImage); + painter.setCompositionMode(QPainter::CompositionMode_Multiply); + painter.fillRect(highlightRect, highlightColor); + + auto frameColor = highlightColor.darker(150); + const QRect frameRect = r.geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()).translated(-limits.left(), -limits.top()); + painter.setPen(frameColor); + painter.drawRect(frameRect); + } + } + + // 4B.4. paint annotations [COMPOSITED ONES] + if (bufferedAnnotations) { + // Albert: This is quite "heavy" but all the backImage that reach here are QImage::Format_ARGB32_Premultiplied + // and have to be so that the QPainter::CompositionMode_Multiply works + // we could also put a + // backImage = backImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) + // that would be almost a noop, but we'll leave the assert for now + Q_ASSERT(backImage.format() == QImage::Format_ARGB32_Premultiplied); + // precalc constants for normalizing [0,1] page coordinates into normalized [0,1] limit rect coordinates + double pageScale = (double)croppedWidth / page->width(); + double xOffset = (double)limits.left() / (double)scaledWidth + crop.left, xScale = (double)scaledWidth / (double)limits.width(), yOffset = (double)limits.top() / (double)scaledHeight + crop.top, + yScale = (double)scaledHeight / (double)limits.height(); + + // paint all buffered annotations in the page + QList::const_iterator aIt = bufferedAnnotations->constBegin(), aEnd = bufferedAnnotations->constEnd(); + for (; aIt != aEnd; ++aIt) { + Okular::Annotation *a = *aIt; + Okular::Annotation::SubType type = a->subType(); + QColor acolor = a->style().color(); + if (!acolor.isValid()) + acolor = Qt::yellow; + acolor.setAlphaF(a->style().opacity()); + + // draw LineAnnotation MISSING: caption, dash pattern, endings for multipoint lines + if (type == Okular::Annotation::ALine) { + LineAnnotPainter linepainter {(Okular::LineAnnotation *)a, {page->width(), page->height()}, pageScale, {xScale, 0., 0., yScale, -xOffset * xScale, -yOffset * yScale}}; + linepainter.draw(backImage); + } + // draw HighlightAnnotation MISSING: under/strike width, feather, capping + else if (type == Okular::Annotation::AHighlight) { + // get the annotation + Okular::HighlightAnnotation *ha = (Okular::HighlightAnnotation *)a; + Okular::HighlightAnnotation::HighlightType type = ha->highlightType(); + + // draw each quad of the annotation + int quads = ha->highlightQuads().size(); + for (int q = 0; q < quads; q++) { + NormalizedPath path; + const Okular::HighlightAnnotation::Quad &quad = ha->highlightQuads()[q]; + // normalize page point to image + for (int i = 0; i < 4; i++) { + Okular::NormalizedPoint point; + point.x = (quad.transformedPoint(i).x - xOffset) * xScale; + point.y = (quad.transformedPoint(i).y - yOffset) * yScale; + path.append(point); + } + // draw the normalized path into image + switch (type) { + // highlight the whole rect + case Okular::HighlightAnnotation::Highlight: + drawShapeOnImage(backImage, path, true, Qt::NoPen, acolor, pageScale, Multiply); + break; + // highlight the bottom part of the rect + case Okular::HighlightAnnotation::Squiggly: + path[3].x = (path[0].x + path[3].x) / 2.0; + path[3].y = (path[0].y + path[3].y) / 2.0; + path[2].x = (path[1].x + path[2].x) / 2.0; + path[2].y = (path[1].y + path[2].y) / 2.0; + drawShapeOnImage(backImage, path, true, Qt::NoPen, acolor, pageScale, Multiply); + break; + // make a line at 3/4 of the height + case Okular::HighlightAnnotation::Underline: + path[0].x = (3 * path[0].x + path[3].x) / 4.0; + path[0].y = (3 * path[0].y + path[3].y) / 4.0; + path[1].x = (3 * path[1].x + path[2].x) / 4.0; + path[1].y = (3 * path[1].y + path[2].y) / 4.0; + path.pop_back(); + path.pop_back(); + drawShapeOnImage(backImage, path, false, QPen(acolor, 2), QBrush(), pageScale); + break; + // make a line at 1/2 of the height + case Okular::HighlightAnnotation::StrikeOut: + path[0].x = (path[0].x + path[3].x) / 2.0; + path[0].y = (path[0].y + path[3].y) / 2.0; + path[1].x = (path[1].x + path[2].x) / 2.0; + path[1].y = (path[1].y + path[2].y) / 2.0; + path.pop_back(); + path.pop_back(); + drawShapeOnImage(backImage, path, false, QPen(acolor, 2), QBrush(), pageScale); + break; + } + } + } + // draw InkAnnotation MISSING:invar width, PENTRACER + else if (type == Okular::Annotation::AInk) { + // get the annotation + Okular::InkAnnotation *ia = (Okular::InkAnnotation *)a; + + // draw each ink path + const QList> transformedInkPaths = ia->transformedInkPaths(); + + const QPen inkPen = buildPen(a, a->style().width(), acolor); + + int paths = transformedInkPaths.size(); + for (int p = 0; p < paths; p++) { + NormalizedPath path; + const QLinkedList &inkPath = transformedInkPaths[p]; + + // normalize page point to image + QLinkedList::const_iterator pIt = inkPath.constBegin(), pEnd = inkPath.constEnd(); + for (; pIt != pEnd; ++pIt) { + const Okular::NormalizedPoint &inkPoint = *pIt; + Okular::NormalizedPoint point; + point.x = (inkPoint.x - xOffset) * xScale; + point.y = (inkPoint.y - yOffset) * yScale; + path.append(point); + } + // draw the normalized path into image + drawShapeOnImage(backImage, path, false, inkPen, QBrush(), pageScale); + } + } + } // end current annotation drawing + } + if (viewPortPoint) { + QPainter painter(&backImage); + painter.translate(-limits.left(), -limits.top()); + painter.setPen(QApplication::palette().color(QPalette::Active, QPalette::Highlight)); + painter.drawLine(0, viewPortPoint->y * scaledHeight + 1, scaledWidth - 1, viewPortPoint->y * scaledHeight + 1); + // ROTATION CURRENTLY NOT IMPLEMENTED + /* + if( page->rotation() == Okular::Rotation0) + { + + } + else if(page->rotation() == Okular::Rotation270) + { + painter.drawLine( viewPortPoint->y * scaledHeight + 1, 0, viewPortPoint->y * scaledHeight + 1, scaledWidth - 1); + } + else if(page->rotation() == Okular::Rotation180) + { + painter.drawLine( 0, (1.0 - viewPortPoint->y) * scaledHeight - 1, scaledWidth - 1, (1.0 - viewPortPoint->y) * scaledHeight - 1 ); + } + else if(page->rotation() == Okular::Rotation90) // not right, rotation clock-wise + { + painter.drawLine( scaledWidth - (viewPortPoint->y * scaledHeight + 1), 0, scaledWidth - (viewPortPoint->y * scaledHeight + 1), scaledWidth - 1); + } + */ + } + + // 4B.5. create the back pixmap converting from the local image + backPixmap = new QPixmap(QPixmap::fromImage(backImage)); + backPixmap->setDevicePixelRatio(dpr); + + // 4B.6. create a painter over the pixmap and set it as the active one + mixedPainter = new QPainter(backPixmap); + mixedPainter->translate(-limits.left(), -limits.top()); + } + + /** 5 -- MIXED FLOW. Draw ANNOTATIONS [OPAQUE ONES] on ACTIVE PAINTER **/ + if (unbufferedAnnotations) { + // iterate over annotations and paint AText, AGeom, AStamp + QList::const_iterator aIt = unbufferedAnnotations->constBegin(), aEnd = unbufferedAnnotations->constEnd(); + for (; aIt != aEnd; ++aIt) { + Okular::Annotation *a = *aIt; + + // honor opacity settings on supported types + unsigned int opacity = (unsigned int)(a->style().color().alpha() * a->style().opacity()); + // skip the annotation drawing if all the annotation is fully + // transparent, but not with text annotations + if (opacity <= 0 && a->subType() != Okular::Annotation::AText) + continue; + + QColor acolor = a->style().color(); + if (!acolor.isValid()) + acolor = Qt::yellow; + acolor.setAlpha(opacity); + + // Annotation boundary in destPainter coordinates: + QRect annotBoundary = a->transformedBoundingRectangle().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()); + QRect annotRect = annotBoundary.intersected(limits); + // Visible portion of the annotation at annotBoundary size: + QRect innerRect = annotRect.translated(-annotBoundary.topLeft()); + QRectF dInnerRect(innerRect.x() * dpr, innerRect.y() * dpr, innerRect.width() * dpr, innerRect.height() * dpr); + + Okular::Annotation::SubType type = a->subType(); + + // draw TextAnnotation + if (type == Okular::Annotation::AText) { + Okular::TextAnnotation *text = (Okular::TextAnnotation *)a; + if (text->textType() == Okular::TextAnnotation::InPlace) { + QImage image(annotBoundary.size(), QImage::Format_ARGB32); + image.fill(acolor.rgba()); + QPainter painter(&image); + painter.setFont(text->textFont()); + painter.setPen(text->textColor()); + Qt::AlignmentFlag halign = (text->inplaceAlignment() == 1 ? Qt::AlignHCenter : (text->inplaceAlignment() == 2 ? Qt::AlignRight : Qt::AlignLeft)); + const double invXScale = (double)page->width() / scaledWidth; + const double invYScale = (double)page->height() / scaledHeight; + const double borderWidth = text->style().width(); + painter.scale(1 / invXScale, 1 / invYScale); + painter.drawText( + borderWidth * invXScale, borderWidth * invYScale, (image.width() - 2 * borderWidth) * invXScale, (image.height() - 2 * borderWidth) * invYScale, Qt::AlignTop | halign | Qt::TextWordWrap, text->contents()); + painter.resetTransform(); + // Required as asking for a zero width pen results + // in a default width pen (1.0) being created + if (borderWidth != 0) { + QPen pen(Qt::black, borderWidth); + painter.setPen(pen); + painter.drawRect(0, 0, image.width() - 1, image.height() - 1); + } + painter.end(); + + mixedPainter->drawImage(annotBoundary.topLeft(), image); + } else if (text->textType() == Okular::TextAnnotation::Linked) { + // get pixmap, colorize and alpha-blend it + QString path; + QPixmap pixmap = GuiUtils::iconLoader()->loadIcon(text->textIcon().toLower(), KIconLoader::User, 32, KIconLoader::DefaultState, QStringList(), &path, true); + if (path.isEmpty()) + pixmap = GuiUtils::iconLoader()->loadIcon(text->textIcon().toLower(), KIconLoader::NoGroup, 32); + + QPixmap scaledCroppedPixmap = pixmap.scaled(TEXTANNOTATION_ICONSIZE * dpr, TEXTANNOTATION_ICONSIZE * dpr).copy(dInnerRect.toAlignedRect()); + scaledCroppedPixmap.setDevicePixelRatio(dpr); + QImage scaledCroppedImage = scaledCroppedPixmap.toImage(); + + // if the annotation color is valid (ie it was set), then + // use it to colorize the icon, otherwise the icon will be + // "gray" + if (a->style().color().isValid()) + GuiUtils::colorizeImage(scaledCroppedImage, a->style().color(), opacity); + pixmap = QPixmap::fromImage(scaledCroppedImage); + + // draw the mangled image to painter + mixedPainter->drawPixmap(annotRect.topLeft(), pixmap); + } + + } + // draw StampAnnotation + else if (type == Okular::Annotation::AStamp) { + Okular::StampAnnotation *stamp = (Okular::StampAnnotation *)a; + + // get pixmap and alpha blend it if needed + QPixmap pixmap = GuiUtils::loadStamp(stamp->stampIconName(), qMax(annotBoundary.width(), annotBoundary.height()) * dpr); + if (!pixmap.isNull()) // should never happen but can happen on huge sizes + { + QPixmap scaledCroppedPixmap = pixmap.scaled(annotBoundary.width() * dpr, annotBoundary.height() * dpr).copy(dInnerRect.toAlignedRect()); + scaledCroppedPixmap.setDevicePixelRatio(dpr); + + // Draw pixmap with opacity: + mixedPainter->save(); + mixedPainter->setOpacity(mixedPainter->opacity() * opacity / 255.0); + mixedPainter->drawPixmap(annotRect.topLeft(), scaledCroppedPixmap); + mixedPainter->restore(); + } + } + // draw GeomAnnotation + else if (type == Okular::Annotation::AGeom) { + Okular::GeomAnnotation *geom = (Okular::GeomAnnotation *)a; + // check whether there's anything to draw + if (geom->style().width() || geom->geometricalInnerColor().isValid()) { + mixedPainter->save(); + const double width = geom->style().width() * Okular::Utils::realDpi(nullptr).width() / (72.0 * 2.0) * scaledWidth / page->width(); + QRectF r(.0, .0, annotBoundary.width(), annotBoundary.height()); + r.adjust(width, width, -width, -width); + r.translate(annotBoundary.topLeft()); + if (geom->geometricalInnerColor().isValid()) { + r.adjust(width, width, -width, -width); + const QColor color = geom->geometricalInnerColor(); + mixedPainter->setPen(Qt::NoPen); + mixedPainter->setBrush(QColor(color.red(), color.green(), color.blue(), opacity)); + if (geom->geometricalType() == Okular::GeomAnnotation::InscribedSquare) + mixedPainter->drawRect(r); + else + mixedPainter->drawEllipse(r); + r.adjust(-width, -width, width, width); + } + if (geom->style().width()) // need to check the original size here.. + { + mixedPainter->setPen(buildPen(a, width * 2, acolor)); + mixedPainter->setBrush(Qt::NoBrush); + if (geom->geometricalType() == Okular::GeomAnnotation::InscribedSquare) + mixedPainter->drawRect(r); + else + mixedPainter->drawEllipse(r); + } + mixedPainter->restore(); + } + } + + // draw extents rectangle + if (Okular::Settings::debugDrawAnnotationRect()) { + mixedPainter->setPen(a->style().color()); + mixedPainter->drawRect(annotBoundary); + } + } + } + + if (boundingRectOnlyAnn) { + QRect annotBoundary = boundingRectOnlyAnn->transformedBoundingRectangle().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()); + mixedPainter->setPen(Qt::DashLine); + mixedPainter->drawRect(annotBoundary); + } + + /** 6 -- MIXED FLOW. Draw LINKS+IMAGES BORDER on ACTIVE PAINTER **/ + if (enhanceLinks || enhanceImages) { + mixedPainter->save(); + mixedPainter->scale(scaledWidth, scaledHeight); + mixedPainter->translate(-crop.left, -crop.top); + + QColor normalColor = QApplication::palette().color(QPalette::Active, QPalette::Highlight); + // enlarging limits for intersection is like growing the 'rectGeometry' below + QRect limitsEnlarged = limits; + limitsEnlarged.adjust(-2, -2, 2, 2); + // draw rects that are inside the 'limits' paint region as opaque rects + QLinkedList::const_iterator lIt = page->m_rects.constBegin(), lEnd = page->m_rects.constEnd(); + for (; lIt != lEnd; ++lIt) { + Okular::ObjectRect *rect = *lIt; + if ((enhanceLinks && rect->objectType() == Okular::ObjectRect::Action) || (enhanceImages && rect->objectType() == Okular::ObjectRect::Image)) { + if (limitsEnlarged.intersects(rect->boundingRect(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft()))) { + mixedPainter->strokePath(rect->region(), QPen(normalColor, 0)); + } + } + } + mixedPainter->restore(); + } + + /** 7 -- BUFFERED FLOW. Copy BACKPIXMAP on DESTINATION PAINTER **/ + if (useBackBuffer) { + delete mixedPainter; + destPainter->drawPixmap(limits.left(), limits.top(), *backPixmap); + delete backPixmap; + } + + // delete object containers + delete bufferedHighlights; + delete bufferedAnnotations; + delete unbufferedAnnotations; +} + +void PagePainter::recolor(QImage *image, const QColor &foreground, const QColor &background) +{ + if (image->format() != QImage::Format_ARGB32_Premultiplied) { + qCWarning(OkularUiDebug) << "Wrong image format! Converting..."; + *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); + + const float scaleRed = background.redF() - foreground.redF(); + const float scaleGreen = background.greenF() - foreground.greenF(); + const float scaleBlue = background.blueF() - foreground.blueF(); + + for (int y = 0; y < image->height(); y++) { + QRgb *pixels = reinterpret_cast(image->scanLine(y)); + + for (int x = 0; x < image->width(); x++) { + const int lightness = qGray(pixels[x]); + pixels[x] = qRgba(scaleRed * lightness + foreground.red(), scaleGreen * lightness + foreground.green(), scaleBlue * lightness + foreground.blue(), qAlpha(pixels[x])); + } + } +} + +void PagePainter::blackWhite(QImage *image, int contrast, int threshold) +{ + unsigned int *data = reinterpret_cast(image->bits()); + int con = contrast; + int thr = 255 - threshold; + + int pixels = image->width() * image->height(); + for (int i = 0; i < pixels; ++i) { + // Piecewise linear function of val, through (0, 0), (thr, 128), (255, 255) + int val = qGray(data[i]); + if (val > thr) + val = 128 + (127 * (val - thr)) / (255 - thr); + else if (val < thr) + val = (128 * val) / thr; + + // Linear contrast stretching through (thr, thr) + if (con > 2) { + val = thr + (val - thr) * con / 2; + val = qBound(0, val, 255); + } + data[i] = qRgba(val, val, val, 255); + } +} + +void PagePainter::invertLightness(QImage *image) +{ + if (image->format() != QImage::Format_ARGB32_Premultiplied) { + qCWarning(OkularUiDebug) << "Wrong image format! Converting..."; + *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); + + QRgb *data = reinterpret_cast(image->bits()); + int pixels = image->width() * image->height(); + for (int i = 0; i < pixels; ++i) { + // Invert lightness of the pixel using the cylindric HSL color model. + // Algorithm is based on https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB (2019-03-17). + // Important simplifications are that inverting lightness does not change chroma and hue. + // This means the sector (of the chroma/hue plane) is not changed, + // so we can use a linear calculation after determining the sector using qMin() and qMax(). + uchar R = qRed(data[i]); + uchar G = qGreen(data[i]); + uchar B = qBlue(data[i]); + + // Get only the needed HSL components. These are chroma C and the common component m. + // Get common component m + uchar m = qMin(R, qMin(G, B)); + // Remove m from color components + R -= m; + G -= m; + B -= m; + // Get chroma C + uchar C = qMax(R, qMax(G, B)); + + // Get common component m' after inverting lightness L. + // Hint: Lightness L = m + C / 2; L' = 255 - L = 255 - (m + C / 2) => m' = 255 - C - m + uchar m_ = 255 - C - m; + + // Add m' to color compontents + R += m_; + G += m_; + B += m_; + + // Save new color + data[i] = qRgba(R, G, B, 255); + } +} + +void PagePainter::invertLuma(QImage *image, float Y_R, float Y_G, float Y_B) +{ + if (image->format() != QImage::Format_ARGB32_Premultiplied) { + qCWarning(OkularUiDebug) << "Wrong image format! Converting..."; + *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); + + QRgb *data = reinterpret_cast(image->bits()); + int pixels = image->width() * image->height(); + for (int i = 0; i < pixels; ++i) { + uchar R = qRed(data[i]); + uchar G = qGreen(data[i]); + uchar B = qBlue(data[i]); + + invertLumaPixel(R, G, B, Y_R, Y_G, Y_B); + + // Save new color + data[i] = qRgba(R, G, B, 255); + } +} + +void PagePainter::invertLumaPixel(uchar &R, uchar &G, uchar &B, float Y_R, float Y_G, float Y_B) +{ + // Invert luma of the pixel using the bicone HCY color model, stretched to cylindric HSY. + // Algorithm is based on https://en.wikipedia.org/wiki/HSL_and_HSV#Luma,_chroma_and_hue_to_RGB (2019-03-19). + // For an illustration see https://experilous.com/1/product/make-it-colorful/ (2019-03-19). + + // Special case: The algorithm does not work when hue is undefined. + if (R == G && G == B) { + R = 255 - R; + G = 255 - G; + B = 255 - B; + return; + } + + // Get input and output luma Y, Y_inv in range 0..255 + float Y = R * Y_R + G * Y_G + B * Y_B; + float Y_inv = 255 - Y; + + // Get common component m and remove from color components. + // This moves us to the bottom faces of the HCY bicone, i. e. we get C and X in R, G, B. + uint_fast8_t m = qMin(R, qMin(G, B)); + R -= m; + G -= m; + B -= m; + + // We operate in a hue plane of the luma/chroma/hue bicone. + // The hue plane is a triangle. + // This bicone is distorted, so we can not simply mirror the triangle. + // We need to stretch it to a luma/saturation rectangle, so we need to stretch chroma C and the proportional X. + + // First, we need to calculate luma Y_full_C for the outer corner of the triangle. + // Then we can interpolate the max chroma C_max, C_inv_max for our luma Y, Y_inv. + // Then we calculate C_inv and X_inv by scaling them by the ratio of C_max and C_inv_max. + + // Calculate luma Y_full_C (in range equivalent to gray 0..255) for chroma = 1 at this hue. + // Piecewise linear, with the corners of the bicone at the sum of one or two luma coefficients. + float Y_full_C; + if (R >= B && B >= G) { + Y_full_C = 255 * Y_R + 255 * Y_B * B / R; + } else if (R >= G && G >= B) { + Y_full_C = 255 * Y_R + 255 * Y_G * G / R; + } else if (G >= R && R >= B) { + Y_full_C = 255 * Y_G + 255 * Y_R * R / G; + } else if (G >= B && B >= R) { + Y_full_C = 255 * Y_G + 255 * Y_B * B / G; + } else if (B >= G && G >= R) { + Y_full_C = 255 * Y_B + 255 * Y_G * G / B; + } else { + Y_full_C = 255 * Y_B + 255 * Y_R * R / B; + } + + // Calculate C_max, C_inv_max, to scale C and X. + float C_max, C_inv_max; + if (Y >= Y_full_C) { + C_max = Y_inv / (255 - Y_full_C); + } else { + C_max = Y / Y_full_C; + } + if (Y_inv >= Y_full_C) { + C_inv_max = Y / (255 - Y_full_C); + } else { + C_inv_max = Y_inv / Y_full_C; + } + + // Scale C and X. C and X already lie in R, G, B. + float C_scale = C_inv_max / C_max; + float R_ = R * C_scale; + float G_ = G * C_scale; + float B_ = B * C_scale; + + // Calculate missing luma (in range 0..255), to get common component m_inv + float m_inv = Y_inv - (Y_R * R_ + Y_G * G_ + Y_B * B_); + + // Add m_inv to color compontents + R_ += m_inv; + G_ += m_inv; + B_ += m_inv; + + // Return colors rounded + R = R_ + 0.5; + G = G_ + 0.5; + B = B_ + 0.5; +} + +void PagePainter::hueShiftPositive(QImage *image) +{ + if (image->format() != QImage::Format_ARGB32_Premultiplied) { + qCWarning(OkularUiDebug) << "Wrong image format! Converting..."; + *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); + + QRgb *data = reinterpret_cast(image->bits()); + int pixels = image->width() * image->height(); + for (int i = 0; i < pixels; ++i) { + uchar R = qRed(data[i]); + uchar G = qGreen(data[i]); + uchar B = qBlue(data[i]); + + // Save new color + data[i] = qRgba(B, R, G, 255); + } +} + +void PagePainter::hueShiftNegative(QImage *image) +{ + if (image->format() != QImage::Format_ARGB32_Premultiplied) { + qCWarning(OkularUiDebug) << "Wrong image format! Converting..."; + *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); + } + + Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); + + QRgb *data = reinterpret_cast(image->bits()); + int pixels = image->width() * image->height(); + for (int i = 0; i < pixels; ++i) { + uchar R = qRed(data[i]); + uchar G = qGreen(data[i]); + uchar B = qBlue(data[i]); + + // Save new color + data[i] = qRgba(G, B, R, 255); + } +} + +void PagePainter::drawShapeOnImage(QImage &image, const NormalizedPath &normPath, bool closeShape, const QPen &pen, const QBrush &brush, double penWidthMultiplier, RasterOperation op + // float antiAliasRadius +) +{ + // safety checks + int pointsNumber = normPath.size(); + if (pointsNumber < 2) + return; + + const double dpr = image.devicePixelRatio(); + const double fImageWidth = image.width() / dpr; + const double fImageHeight = image.height() / dpr; + + // stroke outline + double penWidth = (double)pen.width() * penWidthMultiplier; + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing); + QPen pen2 = pen; + pen2.setWidthF(penWidth); + painter.setPen(pen2); + painter.setBrush(brush); + + if (op == Multiply) { + painter.setCompositionMode(QPainter::CompositionMode_Multiply); + } + + if (brush.style() == Qt::NoBrush) { + // create a polygon + QPolygonF poly(closeShape ? pointsNumber + 1 : pointsNumber); + for (int i = 0; i < pointsNumber; ++i) { + poly[i] = QPointF(normPath[i].x * fImageWidth, normPath[i].y * fImageHeight); + } + if (closeShape) + poly[pointsNumber] = poly[0]; + + painter.drawPolyline(poly); + } else { + // create a 'path' + QPainterPath path; + path.setFillRule(Qt::WindingFill); + + path.moveTo(normPath[0].x * fImageWidth, normPath[0].y * fImageHeight); + for (int i = 1; i < pointsNumber; i++) { + path.lineTo(normPath[i].x * fImageWidth, normPath[i].y * fImageHeight); + } + if (closeShape) + path.closeSubpath(); + + painter.drawPath(path); + } +} + +void PagePainter::drawEllipseOnImage(QImage &image, const NormalizedPath &rect, const QPen &pen, const QBrush &brush, double penWidthMultiplier, RasterOperation op) +{ + const double dpr = image.devicePixelRatio(); + const double fImageWidth = image.width() / dpr; + const double fImageHeight = image.height() / dpr; + + // stroke outline + const double penWidth = (double)pen.width() * penWidthMultiplier; + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing); + QPen pen2 = pen; + pen2.setWidthF(penWidth); + painter.setPen(pen2); + painter.setBrush(brush); + + if (op == Multiply) { + painter.setCompositionMode(QPainter::CompositionMode_Multiply); + } + + const QPointF &topLeft {rect[0].x * fImageWidth, rect[0].y * fImageHeight}; + const QSizeF &size {(rect[1].x - rect[0].x) * fImageWidth, (rect[1].y - rect[0].y) * fImageHeight}; + const QRectF imgRect {topLeft, size}; + if (brush.style() == Qt::NoBrush) { + painter.drawArc(imgRect, 0, 16 * 360); + } else { + painter.drawEllipse(imgRect); + } +} + +LineAnnotPainter::LineAnnotPainter(const Okular::LineAnnotation *a, QSizeF pageSize, double pageScale, const QTransform &toNormalizedImage) + : la {a} + , pageSize {pageSize} + , pageScale {pageScale} + , toNormalizedImage {toNormalizedImage} + , aspectRatio {pageSize.height() / pageSize.width()} + , linePen {buildPen(a, a->style().width(), a->style().color())} +{ + if ((la->lineClosed() || la->transformedLinePoints().count() == 2) && la->lineInnerColor().isValid()) { + fillBrush = QBrush(la->lineInnerColor()); + } +} + +void LineAnnotPainter::draw(QImage &image) const +{ + const QLinkedList transformedLinePoints = la->transformedLinePoints(); + if (transformedLinePoints.count() == 2) { + const Okular::NormalizedPoint delta {transformedLinePoints.last().x - transformedLinePoints.first().x, transformedLinePoints.first().y - transformedLinePoints.last().y}; + const double angle {atan2(delta.y * aspectRatio, delta.x)}; + const double cosA {cos(-angle)}; + const double sinA {sin(-angle)}; + const QTransform tmpMatrix = QTransform {cosA, sinA / aspectRatio, -sinA, cosA / aspectRatio, transformedLinePoints.first().x, transformedLinePoints.first().y}; + const double deaspectedY {delta.y * aspectRatio}; + const double mainSegmentLength {sqrt(delta.x * delta.x + deaspectedY * deaspectedY)}; + const double lineendSize {std::min(6. * la->style().width() / pageSize.width(), mainSegmentLength / 2.)}; + + drawShortenedLine(mainSegmentLength, lineendSize, image, tmpMatrix); + drawLineEnds(mainSegmentLength, lineendSize, image, tmpMatrix); + drawLeaderLine(0., image, tmpMatrix); + drawLeaderLine(mainSegmentLength, image, tmpMatrix); + } else if (transformedLinePoints.count() > 2) { + drawMainLine(image); + } +} + +void LineAnnotPainter::drawMainLine(QImage &image) const +{ + // draw the line as normalized path into image + PagePainter::drawShapeOnImage(image, transformPath(la->transformedLinePoints(), toNormalizedImage), la->lineClosed(), linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawShortenedLine(double mainSegmentLength, double size, QImage &image, const QTransform &toNormalizedPage) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const QList path {{shortenForArrow(size, la->lineStartStyle()), 0}, {mainSegmentLength - shortenForArrow(size, la->lineEndStyle()), 0}}; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), la->lineClosed(), linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEnds(double mainSegmentLength, double size, QImage &image, const QTransform &transform) const +{ + switch (la->lineStartStyle()) { + case Okular::LineAnnotation::Square: + drawLineEndSquare(0, -size, transform, image); + break; + case Okular::LineAnnotation::Circle: + drawLineEndCircle(0, -size, transform, image); + break; + case Okular::LineAnnotation::Diamond: + drawLineEndDiamond(0, -size, transform, image); + break; + case Okular::LineAnnotation::OpenArrow: + drawLineEndArrow(0, -size, 1., false, transform, image); + break; + case Okular::LineAnnotation::ClosedArrow: + drawLineEndArrow(0, -size, 1., true, transform, image); + break; + case Okular::LineAnnotation::None: + break; + case Okular::LineAnnotation::Butt: + drawLineEndButt(0, size, transform, image); + break; + case Okular::LineAnnotation::ROpenArrow: + drawLineEndArrow(0, size, 1., false, transform, image); + break; + case Okular::LineAnnotation::RClosedArrow: + drawLineEndArrow(0, size, 1., true, transform, image); + break; + case Okular::LineAnnotation::Slash: + drawLineEndSlash(0, -size, transform, image); + break; + } + switch (la->lineEndStyle()) { + case Okular::LineAnnotation::Square: + drawLineEndSquare(mainSegmentLength, size, transform, image); + break; + case Okular::LineAnnotation::Circle: + drawLineEndCircle(mainSegmentLength, size, transform, image); + break; + case Okular::LineAnnotation::Diamond: + drawLineEndDiamond(mainSegmentLength, size, transform, image); + break; + case Okular::LineAnnotation::OpenArrow: + drawLineEndArrow(mainSegmentLength, size, 1., false, transform, image); + break; + case Okular::LineAnnotation::ClosedArrow: + drawLineEndArrow(mainSegmentLength, size, 1., true, transform, image); + break; + case Okular::LineAnnotation::None: + break; + case Okular::LineAnnotation::Butt: + drawLineEndButt(mainSegmentLength, size, transform, image); + break; + case Okular::LineAnnotation::ROpenArrow: + drawLineEndArrow(mainSegmentLength, size, -1., false, transform, image); + break; + case Okular::LineAnnotation::RClosedArrow: + drawLineEndArrow(mainSegmentLength, size, -1., true, transform, image); + break; + case Okular::LineAnnotation::Slash: + drawLineEndSlash(mainSegmentLength, size, transform, image); + break; + } +} + +void LineAnnotPainter::drawLineEndArrow(double xEndPos, double size, double flipX, bool close, const QTransform &toNormalizedPage, QImage &image) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const QList path { + {xEndPos - size * flipX, size / 2.}, + {xEndPos, 0}, + {xEndPos - size * flipX, -size / 2.}, + }; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), close, linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEndButt(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const double halfSize {size / 2.}; + const QList path { + {xEndPos, halfSize}, + {xEndPos, -halfSize}, + }; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), true, linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEndCircle(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const +{ + /* transform the circle midpoint to intermediate normalized coordinates + * where it's easy to construct the bounding rect of the circle */ + Okular::NormalizedPoint center; + toNormalizedPage.map(xEndPos - size / 2., 0, ¢er.x, ¢er.y); + const double halfSize {size / 2.}; + const QList path { + {center.x - halfSize, center.y - halfSize / aspectRatio}, + {center.x + halfSize, center.y + halfSize / aspectRatio}, + }; + + /* then transform bounding rect with toNormalizedImage */ + PagePainter::drawEllipseOnImage(image, transformPath(path, toNormalizedImage), linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEndSquare(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const QList path {{xEndPos, size / 2.}, {xEndPos - size, size / 2.}, {xEndPos - size, -size / 2.}, {xEndPos, -size / 2.}}; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), true, linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEndDiamond(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const QList path {{xEndPos, 0}, {xEndPos - size / 2., size / 2.}, {xEndPos - size, 0}, {xEndPos - size / 2., -size / 2.}}; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), true, linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLineEndSlash(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const +{ + const QTransform combinedTransform {toNormalizedPage * toNormalizedImage}; + const double halfSize {size / 2.}; + const double xOffset {cos(M_PI / 3.) * halfSize}; + const QList path { + {xEndPos - xOffset, halfSize}, + {xEndPos + xOffset, -halfSize}, + }; + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), true, linePen, fillBrush, pageScale); +} + +void LineAnnotPainter::drawLeaderLine(double xEndPos, QImage &image, const QTransform &toNormalizedPage) const +{ + const QTransform combinedTransform = toNormalizedPage * toNormalizedImage; + const double ll = aspectRatio * la->lineLeadingForwardPoint() / pageSize.height(); + const double lle = aspectRatio * la->lineLeadingBackwardPoint() / pageSize.height(); + const int sign {ll > 0 ? -1 : 1}; + QList path; + + if (fabs(ll) > 0) { + path.append({xEndPos, ll}); + // do we have the extension on the "back"? + if (fabs(lle) > 0) { + path.append({xEndPos, sign * lle}); + } else { + path.append({xEndPos, 0}); + } + } + PagePainter::drawShapeOnImage(image, transformPath(path, combinedTransform), false, linePen, fillBrush, pageScale); +} + +double LineAnnotPainter::shortenForArrow(double size, Okular::LineAnnotation::TermStyle endStyle) +{ + double shortenBy {0}; + + if (endStyle == Okular::LineAnnotation::Square || endStyle == Okular::LineAnnotation::Circle || endStyle == Okular::LineAnnotation::Diamond || endStyle == Okular::LineAnnotation::ClosedArrow) { + shortenBy = size; + } + + return shortenBy; +} + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/pagepainter.h b/part/pagepainter.h new file mode 100644 index 0000000..8f98be6 --- /dev/null +++ b/part/pagepainter.h @@ -0,0 +1,184 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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_PAGEPAINTER_H_ +#define _OKULAR_PAGEPAINTER_H_ + +#include +#include +#include + +#include "core/annotations.h" +#include "core/area.h" // for NormalizedPoint + +class QPainter; +class QRect; +namespace Okular +{ +class DocumentObserver; +class Page; +} + +/** + * @short Paints a Okular::Page to an open painter using given flags. + */ +class Q_DECL_EXPORT PagePainter +{ +public: + // list of flags passed to the painting function. by OR-ing those flags + // you can decide whether or not to permit drawing of a certain feature. + enum PagePainterFlags { Accessibility = 1, EnhanceLinks = 2, EnhanceImages = 4, Highlights = 8, TextSelection = 16, Annotations = 32 }; + + /** + * Draw @p page on @p destPainter. + * + * @param destPainter Page will be drawn on this painter. + * @param page Which page do draw. + * @param observer Request pixmaps generated for this DocumentObserver. + * @param flags PagePainterFlags, which features to draw. + * @param scaledWidth The requested width of uncropped page in @p destPainter coordinates. + * @param scaledHeight The requested height of uncropped page in @p destPainter coordinates. + * @param pageLimits Where to paint in @p destPainter coordinates. (I. e. painter crop.) Should begin at (0, 0). + */ + static void paintPageOnPainter(QPainter *destPainter, const Okular::Page *page, Okular::DocumentObserver *observer, int flags, int scaledWidth, int scaledHeight, const QRect pageLimits); + + /** + * Draw @p page on @p destPainter. + * + * @param destPainter Page will be drawn on this painter. + * @param page Which page do draw. + * @param observer Request pixmaps generated for this DocumentObserver. + * @param flags PagePainterFlags, which features to draw. + * @param scaledWidth The requested width of uncropped page in @p destPainter coordinates. + * @param scaledHeight The requested height of uncropped page in @p destPainter coordinates. + * @param pageLimits Where to paint in @p destPainter coordinates. (I. e. painter crop.) Should begin at (0, 0). + * @param crop Which area of the page to paint in @p pageLimits. + * @param viewPortPoint Which point of the page to highlight, e. g. a source location. @c nullptr to disable. + */ + static void paintCroppedPageOnPainter(QPainter *destPainter, + const Okular::Page *page, + Okular::DocumentObserver *observer, + int flags, + int scaledWidth, + int scaledHeight, + const QRect pageLimits, + const Okular::NormalizedRect &crop, + Okular::NormalizedPoint *viewPortPoint); + +private: + // BEGIN Change Colors feature + /** + * Collapse color space (from white to black) to a line from @p foreground to @p background. + */ + static void recolor(QImage *image, const QColor &foreground, const QColor &background); + /** + * Collapse color space to a line from white to black, + * then move from @p threshold to 128 and stretch the line by @p contrast. + */ + static void blackWhite(QImage *image, int contrast, int threshold); + /** + * Invert the lightness axis of the HSL color cone. + */ + static void invertLightness(QImage *image); + /** + * Inverts luma of @p image using the luma coefficients @p Y_R, @p Y_G, @p Y_B (should sum up to 1), + * and assuming linear 8bit RGB color space. + */ + static void invertLuma(QImage *image, float Y_R, float Y_G, float Y_B); + /** + * Inverts luma of a pixel given in @p R, @p G, @p B, + * using the luma coefficients @p Y_R, @p Y_G, @p Y_B (should sum up to 1), + * and assuming linear 8bit RGB color space. + */ + static void invertLumaPixel(uchar &R, uchar &G, uchar &B, float Y_R, float Y_G, float Y_B); + /** + * Shifts hue of each pixel by 120 degrees, by simply swapping channels. + */ + static void hueShiftPositive(QImage *image); + /** + * Shifts hue of each pixel by 240 degrees, by simply swapping channels. + */ + static void hueShiftNegative(QImage *image); + // END Change Colors feature + + // my pretty dear raster function + typedef QList NormalizedPath; + enum RasterOperation { Normal, Multiply }; + + /** + * Draw @p normPath on @p image. + * + * @note @p normPath needs to be normalized in respect to @p image, not to the actual page. + */ + static void drawShapeOnImage(QImage &image, const NormalizedPath &normPath, bool closeShape, const QPen &pen, const QBrush &brush = QBrush(), double penWidthMultiplier = 1.0, RasterOperation op = Normal); + + /** + * Draw an ellipse described by @p rect on @p image. + * + * @param rect Two NormalizedPoints describing the bounding rect. Need to be normalized in respect to @p image, not to the actual page. + */ + static void drawEllipseOnImage(QImage &image, const NormalizedPath &rect, const QPen &pen, const QBrush &brush, double penWidthMultiplier, RasterOperation op = Normal); + + friend class LineAnnotPainter; +}; + +/** + * @short Painting helper for a single Okular::LineAnnotation. + */ +class LineAnnotPainter +{ +public: + /** + * @param a The annotation to paint. Accessed by draw(). + * @param pageSizeA The full size of the page on which to paint. + * @param pageScale The scale of the page when you call draw(). + * @param toNormalizedImage How to transform normalized coordinates of @p a to normalized coordinates of your paint device. (If your paint device represents the whole page, use the unit matrix QTransform().) + */ + LineAnnotPainter(const Okular::LineAnnotation *a, QSizeF pageSizeA, double pageScale, const QTransform &toNormalizedImage); + + /** + * Draw the annotation on @p image. + */ + void draw(QImage &image) const; + +private: + void drawMainLine(QImage &image) const; + void drawShortenedLine(double mainSegmentLength, double size, QImage &image, const QTransform &toNormalizedPage) const; + void drawLineEnds(double mainSegmentLength, double size, QImage &image, const QTransform &transform) const; + void drawLineEndArrow(double xEndPos, double size, double flipX, bool close, const QTransform &toNormalizedPage, QImage &image) const; + void drawLineEndButt(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const; + void drawLineEndCircle(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const; + void drawLineEndSquare(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const; + void drawLineEndDiamond(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const; + void drawLineEndSlash(double xEndPos, double size, const QTransform &toNormalizedPage, QImage &image) const; + void drawLeaderLine(double xEndPos, QImage &image, const QTransform &toNormalizedPage) const; + template QList transformPath(const T &path, const QTransform &transform) const + { + QList transformedPath; + for (const Okular::NormalizedPoint &item : path) { + Okular::NormalizedPoint p; + transform.map(item.x, item.y, &p.x, &p.y); + transformedPath.append(p); + } + return transformedPath; + } + + static double shortenForArrow(double size, Okular::LineAnnotation::TermStyle endStyle); + +private: + const Okular::LineAnnotation *la; + QSizeF pageSize; + double pageScale; + QTransform toNormalizedImage; + double aspectRatio; + const QPen linePen; + QBrush fillBrush; +}; + +#endif diff --git a/part/pagesizelabel.cpp b/part/pagesizelabel.cpp new file mode 100644 index 0000000..fe3c3ef --- /dev/null +++ b/part/pagesizelabel.cpp @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "pagesizelabel.h" + +#include "core/document.h" + +PageSizeLabel::PageSizeLabel(QWidget *parent, Okular::Document *document) + : KSqueezedTextLabel(parent) + , m_document(document) +{ + setAlignment(Qt::AlignRight); +} + +PageSizeLabel::~PageSizeLabel() +{ + m_document->removeObserver(this); +} + +void PageSizeLabel::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + Q_UNUSED(previousPage) + + // if the document is opened + if (m_document->pages() > 0 && !m_document->allPagesSize().isValid()) { + setText(m_document->pageSizeString(currentPage)); + } +} + +#include "moc_pagesizelabel.cpp" diff --git a/part/pagesizelabel.h b/part/pagesizelabel.h new file mode 100644 index 0000000..1e2c83b --- /dev/null +++ b/part/pagesizelabel.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * 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_PAGESIZELABEL_H_ +#define _OKULAR_PAGESIZELABEL_H_ + +#include + +#include "core/observer.h" + +namespace Okular +{ +class Document; +} + +/** + * @short A widget to display page size. + */ +class PageSizeLabel : public KSqueezedTextLabel, public Okular::DocumentObserver +{ + Q_OBJECT + +public: + PageSizeLabel(QWidget *parent, Okular::Document *document); + ~PageSizeLabel() override; + + // [INHERITED] from DocumentObserver + void notifyCurrentPageChanged(int previous, int current) override; + +private: + Okular::Document *m_document; +}; + +#endif diff --git a/part/pageview.cpp b/part/pageview.cpp new file mode 100644 index 0000000..a33ef47 --- /dev/null +++ b/part/pageview.cpp @@ -0,0 +1,5163 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2006 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * With portions of code from kpdf/kpdf_pagewidget.cc by: * + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2003 by Christophe Devriese * + * * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2003 by Dirk Mueller * + * Copyright (C) 2004 by James Ots * + * Copyright (C) 2011 by Jiri Baum - NICTA * + * * + * 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. * + ***************************************************************************/ + +#include "pageview.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// system includes +#include +#include +#include + +// local includes +#include "annotationpopup.h" +#include "annotwindow.h" +#include "core/annotations.h" +#include "debug_ui.h" +#include "formwidgets.h" +#include "guiutils.h" +#include "okmenutitle.h" +#include "pagepainter.h" +#include "pageviewannotator.h" +#include "pageviewmouseannotation.h" +#include "pageviewutils.h" +#include "priorities.h" +#include "toggleactionmenu.h" +#ifdef HAVE_SPEECH +#include "tts.h" +#endif +#include "core/action.h" +#include "core/audioplayer.h" +#include "core/document_p.h" +#include "core/form.h" +#include "core/generator.h" +#include "core/misc.h" +#include "core/movie.h" +#include "core/page.h" +#include "core/page_p.h" +#include "core/sourcereference.h" +#include "core/tile.h" +#include "magnifierview.h" +#include "settings.h" +#include "settings_core.h" +#include "url_utils.h" +#include "videowidget.h" + +static const int pageflags = PagePainter::Accessibility | PagePainter::EnhanceLinks | PagePainter::EnhanceImages | PagePainter::Highlights | PagePainter::TextSelection | PagePainter::Annotations; + +static const std::array kZoomValues {0.12, 0.25, 0.33, 0.50, 0.66, 0.75, 1.00, 1.25, 1.50, 2.00, 4.00, 8.00, 16.00, 25.00, 50.00, 100.00}; + +// This is the length of the text that will be shown when the user is searching for a specific piece of text. +static const int searchTextPreviewLength = 21; + +// When following a link, only a preview of this length will be used to set the text of the action. +static const int linkTextPreviewLength = 30; + +static inline double normClamp(double value, double def) +{ + return (value < 0.0 || value > 1.0) ? def : value; +} + +struct TableSelectionPart { + PageViewItem *item; + Okular::NormalizedRect rectInItem; + Okular::NormalizedRect rectInSelection; + + TableSelectionPart(PageViewItem *item_p, const Okular::NormalizedRect &rectInItem_p, const Okular::NormalizedRect &rectInSelection_p); +}; + +TableSelectionPart::TableSelectionPart(PageViewItem *item_p, const Okular::NormalizedRect &rectInItem_p, const Okular::NormalizedRect &rectInSelection_p) + : item(item_p) + , rectInItem(rectInItem_p) + , rectInSelection(rectInSelection_p) +{ +} + +// structure used internally by PageView for data storage +class PageViewPrivate +{ +public: + PageViewPrivate(PageView *qq); + + FormWidgetsController *formWidgetsController(); +#ifdef HAVE_SPEECH + OkularTTS *tts(); +#endif + QString selectedText() const; + + // the document, pageviewItems and the 'visible cache' + PageView *q; + Okular::Document *document; + QVector items; + QLinkedList visibleItems; + MagnifierView *magnifierView; + + // view layout (columns and continuous in Settings), zoom and mouse + PageView::ZoomMode zoomMode; + float zoomFactor; + QPoint mouseGrabOffset; + QPoint mousePressPos; + QPoint mouseSelectPos; + QPoint previousMouseMovePos; + int mouseMidLastY; + bool mouseSelecting; + QRect mouseSelectionRect; + QColor mouseSelectionColor; + bool mouseTextSelecting; + QSet pagesWithTextSelection; + bool mouseOnRect; + int mouseMode; + MouseAnnotation *mouseAnnotation; + + // table selection + QList tableSelectionCols; + QList tableSelectionRows; + QList tableSelectionParts; + bool tableDividersGuessed; + + int lastSourceLocationViewportPageNumber; + double lastSourceLocationViewportNormalizedX; + double lastSourceLocationViewportNormalizedY; + int controlWheelAccumulatedDelta; + + // for everything except PgUp/PgDn and scroll to arbitrary locations + const int baseShortScrollDuration = 100; + int currentShortScrollDuration; + // for PgUp/PgDn and scroll to arbitrary locations + const int baseLongScrollDuration = baseShortScrollDuration * 2; + int currentLongScrollDuration; + + // auto scroll + int scrollIncrement; + QTimer *autoScrollTimer; + // annotations + PageViewAnnotator *annotator; + // text annotation dialogs list + QSet m_annowindows; + // other stuff + QTimer *delayResizeEventTimer; + bool dirtyLayout; + bool blockViewport; // prevents changes to viewport + bool blockPixmapsRequest; // prevent pixmap requests + PageViewMessage *messageWindow; // in pageviewutils.h + bool m_formsVisible; + FormWidgetsController *formsWidgetController; +#ifdef HAVE_SPEECH + OkularTTS *m_tts; +#endif + QTimer *refreshTimer; + QSet refreshPages; + + // bbox state for Trim to Selection mode + Okular::NormalizedRect trimBoundingBox; + + // infinite resizing loop prevention + bool verticalScrollBarVisible; + bool horizontalScrollBarVisible; + + // drag scroll + QPoint dragScrollVector; + QTimer dragScrollTimer; + + // left click depress + QTimer leftClickTimer; + + // actions + QAction *aRotateClockwise; + QAction *aRotateCounterClockwise; + QAction *aRotateOriginal; + KActionMenu *aTrimMode; + KToggleAction *aTrimMargins; + KToggleAction *aReadingDirection; + QAction *aMouseNormal; + QAction *aMouseSelect; + QAction *aMouseTextSelect; + QAction *aMouseTableSelect; + QAction *aMouseMagnifier; + KToggleAction *aTrimToSelection; + KSelectAction *aZoom; + QAction *aZoomIn; + QAction *aZoomOut; + QAction *aZoomActual; + KToggleAction *aZoomFitWidth; + KToggleAction *aZoomFitPage; + KToggleAction *aZoomAutoFit; + KActionMenu *aViewModeMenu; + QActionGroup *viewModeActionGroup; + KToggleAction *aViewContinuous; + QAction *aPrevAction; + KToggleAction *aToggleForms; + QAction *aSpeakDoc; + QAction *aSpeakPage; + QAction *aSpeakStop; + QAction *aSpeakPauseResume; + KActionCollection *actionCollection; + QActionGroup *mouseModeActionGroup; + ToggleActionMenu *aMouseModeMenu; + QAction *aFitWindowToPage; + + int setting_viewCols; + bool rtl_Mode; + // Keep track of whether tablet pen is currently pressed down + bool penDown; + + // Keep track of mouse over link object + const Okular::ObjectRect *mouseOverLinkObject; + + QScroller *scroller; +}; + +PageViewPrivate::PageViewPrivate(PageView *qq) + : q(qq) +#ifdef HAVE_SPEECH + , m_tts(nullptr) +#endif +{ +} + +FormWidgetsController *PageViewPrivate::formWidgetsController() +{ + if (!formsWidgetController) { + formsWidgetController = new FormWidgetsController(document); + QObject::connect(formsWidgetController, &FormWidgetsController::changed, q, &PageView::slotFormChanged); + QObject::connect(formsWidgetController, &FormWidgetsController::action, q, &PageView::slotAction); + QObject::connect(formsWidgetController, &FormWidgetsController::formatAction, q, [this](const Okular::Action *action, Okular::FormFieldText *fft) { document->processFormatAction(action, fft); }); + QObject::connect(formsWidgetController, &FormWidgetsController::keystrokeAction, q, [this](const Okular::Action *action, Okular::FormFieldText *fft, bool &ok) { document->processKeystrokeAction(action, fft, ok); }); + QObject::connect(formsWidgetController, &FormWidgetsController::focusAction, q, [this](const Okular::Action *action, Okular::FormFieldText *fft) { document->processFocusAction(action, fft); }); + QObject::connect(formsWidgetController, &FormWidgetsController::validateAction, q, [this](const Okular::Action *action, Okular::FormFieldText *fft, bool &ok) { document->processValidateAction(action, fft, ok); }); + } + + return formsWidgetController; +} + +#ifdef HAVE_SPEECH +OkularTTS *PageViewPrivate::tts() +{ + if (!m_tts) { + m_tts = new OkularTTS(q); + if (aSpeakStop) { + QObject::connect(m_tts, &OkularTTS::canPauseOrResume, aSpeakStop, &QAction::setEnabled); + } + + if (aSpeakPauseResume) { + QObject::connect(m_tts, &OkularTTS::canPauseOrResume, aSpeakPauseResume, &QAction::setEnabled); + } + } + + return m_tts; +} +#endif + +/* PageView. What's in this file? -> quick overview. + * Code weight (in rows) and meaning: + * 160 - constructor and creating actions plus their connected slots (empty stuff) + * 70 - DocumentObserver inherited methodes (important) + * 550 - events: mouse, keyboard, drag + * 170 - slotRelayoutPages: set contents of the scrollview on continuous/single modes + * 100 - zoom: zooming pages in different ways, keeping update the toolbar actions, etc.. + * other misc functions: only slotRequestVisiblePixmaps and pickItemOnPoint noticeable, + * and many insignificant stuff like this comment :-) + */ +PageView::PageView(QWidget *parent, Okular::Document *document) + : QAbstractScrollArea(parent) + , Okular::View(QStringLiteral("PageView")) +{ + // create and initialize private storage structure + d = new PageViewPrivate(this); + d->document = document; + d->aRotateClockwise = nullptr; + d->aRotateCounterClockwise = nullptr; + d->aRotateOriginal = nullptr; + d->aViewModeMenu = nullptr; + d->zoomMode = PageView::ZoomFitWidth; + d->zoomFactor = 1.0; + d->mouseSelecting = false; + d->mouseTextSelecting = false; + d->mouseOnRect = false; + d->mouseMode = Okular::Settings::mouseMode(); + d->mouseAnnotation = new MouseAnnotation(this, document); + d->tableDividersGuessed = false; + d->lastSourceLocationViewportPageNumber = -1; + d->lastSourceLocationViewportNormalizedX = 0.0; + d->lastSourceLocationViewportNormalizedY = 0.0; + d->controlWheelAccumulatedDelta = 0; + d->currentShortScrollDuration = d->baseShortScrollDuration; + d->currentLongScrollDuration = d->baseLongScrollDuration; + d->scrollIncrement = 0; + d->autoScrollTimer = nullptr; + d->annotator = nullptr; + d->dirtyLayout = false; + d->blockViewport = false; + d->blockPixmapsRequest = false; + d->messageWindow = new PageViewMessage(this); + d->m_formsVisible = false; + d->formsWidgetController = nullptr; +#ifdef HAVE_SPEECH + d->m_tts = nullptr; +#endif + d->refreshTimer = nullptr; + d->aRotateClockwise = nullptr; + d->aRotateCounterClockwise = nullptr; + d->aRotateOriginal = nullptr; + d->aTrimMode = nullptr; + d->aTrimMargins = nullptr; + d->aTrimToSelection = nullptr; + d->aReadingDirection = nullptr; + d->aMouseNormal = nullptr; + d->aMouseSelect = nullptr; + d->aMouseTextSelect = nullptr; + d->aZoomFitWidth = nullptr; + d->aZoomFitPage = nullptr; + d->aZoomAutoFit = nullptr; + d->aViewModeMenu = nullptr; + d->aViewContinuous = nullptr; + d->viewModeActionGroup = nullptr; + d->aPrevAction = nullptr; + d->aToggleForms = nullptr; + d->aSpeakDoc = nullptr; + d->aSpeakPage = nullptr; + d->aSpeakStop = nullptr; + d->aSpeakPauseResume = nullptr; + d->actionCollection = nullptr; + d->setting_viewCols = Okular::Settings::viewColumns(); + d->rtl_Mode = Okular::Settings::rtlReadingDirection(); + d->mouseModeActionGroup = nullptr; + d->aMouseModeMenu = nullptr; + d->penDown = false; + d->aMouseMagnifier = nullptr; + d->aFitWindowToPage = nullptr; + d->trimBoundingBox = Okular::NormalizedRect(); // Null box + + switch (Okular::Settings::zoomMode()) { + case 0: { + d->zoomFactor = 1; + d->zoomMode = PageView::ZoomFixed; + break; + } + case 1: { + d->zoomMode = PageView::ZoomFitWidth; + break; + } + case 2: { + d->zoomMode = PageView::ZoomFitPage; + break; + } + case 3: { + d->zoomMode = PageView::ZoomFitAuto; + break; + } + } + + d->delayResizeEventTimer = new QTimer(this); + d->delayResizeEventTimer->setSingleShot(true); + d->delayResizeEventTimer->setObjectName(QStringLiteral("delayResizeEventTimer")); + connect(d->delayResizeEventTimer, &QTimer::timeout, this, &PageView::delayedResizeEvent); + + setFrameStyle(QFrame::NoFrame); + + setAttribute(Qt::WA_StaticContents); + + setObjectName(QStringLiteral("okular::pageView")); + + // viewport setup: setup focus, and track mouse + viewport()->setFocusProxy(this); + viewport()->setFocusPolicy(Qt::StrongFocus); + viewport()->setAttribute(Qt::WA_OpaquePaintEvent); + viewport()->setAttribute(Qt::WA_NoSystemBackground); + viewport()->setMouseTracking(true); + viewport()->setAutoFillBackground(false); + + d->scroller = QScroller::scroller(viewport()); + + QScrollerProperties prop; + prop.setScrollMetric(QScrollerProperties::DecelerationFactor, 0.3); + prop.setScrollMetric(QScrollerProperties::MaximumVelocity, 1); + prop.setScrollMetric(QScrollerProperties::AcceleratingFlickMaximumTime, 0.2); // Workaround for QTBUG-88249 (non-flick gestures recognized as accelerating flick) + prop.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + prop.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff); + prop.setScrollMetric(QScrollerProperties::DragStartDistance, 0.0); + d->scroller->setScrollerProperties(prop); + + connect(d->scroller, &QScroller::stateChanged, this, &PageView::slotRequestVisiblePixmaps); + + // the apparently "magic" value of 20 is the same used internally in QScrollArea + verticalScrollBar()->setCursor(Qt::ArrowCursor); + verticalScrollBar()->setSingleStep(20); + horizontalScrollBar()->setCursor(Qt::ArrowCursor); + horizontalScrollBar()->setSingleStep(20); + + // make the smooth scroll animation durations respect the global animation + // scale + KConfigWatcher::Ptr animationSpeedWatcher = KConfigWatcher::create(KSharedConfig::openConfig()); + connect(animationSpeedWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) { + if (group.name() == QLatin1String("KDE") && names.contains(QByteArrayLiteral("AnimationDurationFactor"))) { + PageView::updateSmoothScrollAnimationSpeed(); + } + }); + + // connect the padding of the viewport to pixmaps requests + connect(horizontalScrollBar(), &QAbstractSlider::valueChanged, this, &PageView::slotRequestVisiblePixmaps); + connect(verticalScrollBar(), &QAbstractSlider::valueChanged, this, &PageView::slotRequestVisiblePixmaps); + + // Keep the scroller in sync with user input on the scrollbars. + // QAbstractSlider::sliderMoved() and sliderReleased are the intuitive signals, + // but are only emitted when the “slider is down”, i. e. not when the user scrolls on the scrollbar. + // QAbstractSlider::actionTriggered() is emitted in all user input cases, + // but before the value() changes, so we need queued connection here. + auto update_scroller = [=]() { + d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar + }; + connect(verticalScrollBar(), &QAbstractSlider::actionTriggered, this, update_scroller, Qt::QueuedConnection); + connect(horizontalScrollBar(), &QAbstractSlider::actionTriggered, this, update_scroller, Qt::QueuedConnection); + + connect(&d->dragScrollTimer, &QTimer::timeout, this, &PageView::slotDragScroll); + + d->leftClickTimer.setSingleShot(true); + connect(&d->leftClickTimer, &QTimer::timeout, this, &PageView::slotShowSizeAllCursor); + + // set a corner button to resize the view to the page size + // QPushButton * resizeButton = new QPushButton( viewport() ); + // resizeButton->setPixmap( SmallIcon("crop") ); + // setCornerWidget( resizeButton ); + // resizeButton->setEnabled( false ); + // connect(...); + setAttribute(Qt::WA_InputMethodEnabled, true); + + // Grab pinch gestures to zoom and rotate the view + grabGesture(Qt::PinchGesture); + + d->magnifierView = new MagnifierView(document, this); + d->magnifierView->hide(); + d->magnifierView->setGeometry(0, 0, 351, 201); // TODO: more dynamic? + + connect(document, &Okular::Document::processMovieAction, this, &PageView::slotProcessMovieAction); + connect(document, &Okular::Document::processRenditionAction, this, &PageView::slotProcessRenditionAction); + + // schedule the welcome message + QMetaObject::invokeMethod(this, "slotShowWelcome", Qt::QueuedConnection); +} + +PageView::~PageView() +{ +#ifdef HAVE_SPEECH + if (d->m_tts) + d->m_tts->stopAllSpeechs(); +#endif + + delete d->mouseAnnotation; + + // delete the local storage structure + + // We need to assign it to a different list otherwise slotAnnotationWindowDestroyed + // will bite us and clear d->m_annowindows + QSet annowindows = d->m_annowindows; + d->m_annowindows.clear(); + qDeleteAll(annowindows); + + // delete all widgets + qDeleteAll(d->items); + delete d->formsWidgetController; + d->document->removeObserver(this); + delete d; +} + +void PageView::setupBaseActions(KActionCollection *ac) +{ + d->actionCollection = ac; + + // Zoom actions ( higher scales takes lots of memory! ) + d->aZoom = new KSelectAction(QIcon::fromTheme(QStringLiteral("page-zoom")), i18n("Zoom"), this); + ac->addAction(QStringLiteral("zoom_to"), d->aZoom); + d->aZoom->setEditable(true); + d->aZoom->setMaxComboViewCount(kZoomValues.size() + 3); + connect(d->aZoom, QOverload::of(&KSelectAction::triggered), this, &PageView::slotZoom); + updateZoomText(); + + d->aZoomIn = KStandardAction::zoomIn(this, SLOT(slotZoomIn()), ac); + + d->aZoomOut = KStandardAction::zoomOut(this, SLOT(slotZoomOut()), ac); + + d->aZoomActual = KStandardAction::actualSize(this, &PageView::slotZoomActual, ac); + d->aZoomActual->setText(i18n("Zoom to 100%")); +} + +void PageView::setupViewerActions(KActionCollection *ac) +{ + d->actionCollection = ac; + + ac->setDefaultShortcut(d->aZoomIn, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Plus)); + ac->setDefaultShortcut(d->aZoomOut, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Minus)); + + // orientation menu actions + d->aRotateClockwise = new QAction(QIcon::fromTheme(QStringLiteral("object-rotate-right")), i18n("Rotate &Right"), this); + d->aRotateClockwise->setIconText(i18nc("Rotate right", "Right")); + ac->addAction(QStringLiteral("view_orientation_rotate_cw"), d->aRotateClockwise); + d->aRotateClockwise->setEnabled(false); + connect(d->aRotateClockwise, &QAction::triggered, this, &PageView::slotRotateClockwise); + d->aRotateCounterClockwise = new QAction(QIcon::fromTheme(QStringLiteral("object-rotate-left")), i18n("Rotate &Left"), this); + d->aRotateCounterClockwise->setIconText(i18nc("Rotate left", "Left")); + ac->addAction(QStringLiteral("view_orientation_rotate_ccw"), d->aRotateCounterClockwise); + d->aRotateCounterClockwise->setEnabled(false); + connect(d->aRotateCounterClockwise, &QAction::triggered, this, &PageView::slotRotateCounterClockwise); + d->aRotateOriginal = new QAction(i18n("Original Orientation"), this); + ac->addAction(QStringLiteral("view_orientation_original"), d->aRotateOriginal); + d->aRotateOriginal->setEnabled(false); + connect(d->aRotateOriginal, &QAction::triggered, this, &PageView::slotRotateOriginal); + + // Trim View actions + d->aTrimMode = new KActionMenu(i18n("&Trim View"), this); + d->aTrimMode->setDelayed(false); + ac->addAction(QStringLiteral("view_trim_mode"), d->aTrimMode); + + d->aTrimMargins = new KToggleAction(QIcon::fromTheme(QStringLiteral("trim-margins")), i18n("&Trim Margins"), d->aTrimMode->menu()); + d->aTrimMode->addAction(d->aTrimMargins); + ac->addAction(QStringLiteral("view_trim_margins"), d->aTrimMargins); + d->aTrimMargins->setData(QVariant::fromValue((int)Okular::Settings::EnumTrimMode::Margins)); + connect(d->aTrimMargins, &QAction::toggled, this, &PageView::slotTrimMarginsToggled); + d->aTrimMargins->setChecked(Okular::Settings::trimMargins()); + + d->aTrimToSelection = new KToggleAction(QIcon::fromTheme(QStringLiteral("trim-to-selection")), i18n("Trim To &Selection"), d->aTrimMode->menu()); + d->aTrimMode->addAction(d->aTrimToSelection); + ac->addAction(QStringLiteral("view_trim_selection"), d->aTrimToSelection); + d->aTrimToSelection->setData(QVariant::fromValue((int)Okular::Settings::EnumTrimMode::Selection)); + connect(d->aTrimToSelection, &QAction::toggled, this, &PageView::slotTrimToSelectionToggled); + + d->aZoomFitWidth = new KToggleAction(QIcon::fromTheme(QStringLiteral("zoom-fit-width")), i18n("Fit &Width"), this); + ac->addAction(QStringLiteral("view_fit_to_width"), d->aZoomFitWidth); + connect(d->aZoomFitWidth, &QAction::toggled, this, &PageView::slotFitToWidthToggled); + + d->aZoomFitPage = new KToggleAction(QIcon::fromTheme(QStringLiteral("zoom-fit-best")), i18n("Fit &Page"), this); + ac->addAction(QStringLiteral("view_fit_to_page"), d->aZoomFitPage); + connect(d->aZoomFitPage, &QAction::toggled, this, &PageView::slotFitToPageToggled); + + d->aZoomAutoFit = new KToggleAction(QIcon::fromTheme(QStringLiteral("zoom-fit-best")), i18n("&Auto Fit"), this); + ac->addAction(QStringLiteral("view_auto_fit"), d->aZoomAutoFit); + connect(d->aZoomAutoFit, &QAction::toggled, this, &PageView::slotAutoFitToggled); + + d->aFitWindowToPage = new QAction(QIcon::fromTheme(QStringLiteral("zoom-fit-width")), i18n("Fit Wi&ndow to Page"), this); + d->aFitWindowToPage->setEnabled(Okular::Settings::viewMode() == (int)Okular::Settings::EnumViewMode::Single); + ac->setDefaultShortcut(d->aFitWindowToPage, QKeySequence(Qt::CTRL + Qt::Key_J)); + ac->addAction(QStringLiteral("fit_window_to_page"), d->aFitWindowToPage); + connect(d->aFitWindowToPage, &QAction::triggered, this, &PageView::slotFitWindowToPage); + + // View Mode action menu (Single Page, Facing Pages,...(choose), and Continuous (on/off)) + d->aViewModeMenu = new KActionMenu(QIcon::fromTheme(QStringLiteral("view-split-left-right")), i18n("&View Mode"), this); + d->aViewModeMenu->setDelayed(false); + ac->addAction(QStringLiteral("view_render_mode"), d->aViewModeMenu); + + d->viewModeActionGroup = new QActionGroup(this); + auto addViewMode = [=](QAction *a, const QString &name, Okular::Settings::EnumViewMode::type id) { + a->setCheckable(true); + a->setData(int(id)); + d->aViewModeMenu->addAction(a); + ac->addAction(name, a); + d->viewModeActionGroup->addAction(a); + }; + addViewMode(new QAction(QIcon::fromTheme(QStringLiteral("view-pages-single")), i18nc("@item:inmenu", "&Single Page"), this), QStringLiteral("view_render_mode_single"), Okular::Settings::EnumViewMode::Single); + addViewMode(new QAction(QIcon::fromTheme(QStringLiteral("view-pages-facing")), i18nc("@item:inmenu", "&Facing Pages"), this), QStringLiteral("view_render_mode_facing"), Okular::Settings::EnumViewMode::Facing); + addViewMode(new QAction(QIcon::fromTheme(QStringLiteral("view-pages-facing-first-centered")), i18nc("@item:inmenu", "Facing Pages (&Center First Page)"), this), + QStringLiteral("view_render_mode_facing_center_first"), + Okular::Settings::EnumViewMode::FacingFirstCentered); + addViewMode(new QAction(QIcon::fromTheme(QStringLiteral("view-pages-overview")), i18nc("@item:inmenu", "&Overview"), this), QStringLiteral("view_render_mode_overview"), Okular::Settings::EnumViewMode::Summary); + const QList viewModeActions = d->viewModeActionGroup->actions(); + for (QAction *viewModeAction : viewModeActions) { + if (viewModeAction->data().toInt() == Okular::Settings::viewMode()) { + viewModeAction->setChecked(true); + break; + } + } + connect(d->viewModeActionGroup, &QActionGroup::triggered, this, &PageView::slotViewMode); + + // Continuous view action, add to view mode action menu. + d->aViewModeMenu->addSeparator(); + d->aViewContinuous = new KToggleAction(QIcon::fromTheme(QStringLiteral("view-pages-continuous")), i18n("&Continuous"), this); + d->aViewModeMenu->addAction(d->aViewContinuous); + ac->addAction(QStringLiteral("view_continuous"), d->aViewContinuous); + connect(d->aViewContinuous, &QAction::toggled, this, &PageView::slotContinuousToggled); + d->aViewContinuous->setChecked(Okular::Settings::viewContinuous()); + + // Reading direction toggle action. (Checked means RTL, unchecked means LTR.) + d->aReadingDirection = new KToggleAction(QIcon::fromTheme(QStringLiteral("format-text-direction-rtl")), i18nc("@action page layout", "Use Right to Left Reading Direction"), this); + d->aReadingDirection->setChecked(Okular::Settings::rtlReadingDirection()); + ac->addAction(QStringLiteral("rtl_page_layout"), d->aReadingDirection); + connect(d->aReadingDirection, &QAction::toggled, this, &PageView::slotReadingDirectionToggled); + connect(Okular::SettingsCore::self(), &Okular::SettingsCore::configChanged, this, &PageView::slotUpdateReadingDirectionAction); + + // Mouse mode actions for viewer mode + d->mouseModeActionGroup = new QActionGroup(this); + d->mouseModeActionGroup->setExclusive(true); + d->aMouseNormal = new QAction(QIcon::fromTheme(QStringLiteral("transform-browse")), i18n("&Browse"), this); + ac->addAction(QStringLiteral("mouse_drag"), d->aMouseNormal); + connect(d->aMouseNormal, &QAction::toggled, this, &PageView::slotMouseNormalToggled); + d->aMouseNormal->setCheckable(true); + ac->setDefaultShortcut(d->aMouseNormal, QKeySequence(Qt::CTRL + Qt::Key_1)); + d->aMouseNormal->setActionGroup(d->mouseModeActionGroup); + d->aMouseNormal->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::Browse); + + QAction *mz = new QAction(QIcon::fromTheme(QStringLiteral("page-zoom")), i18n("&Zoom"), this); + ac->addAction(QStringLiteral("mouse_zoom"), mz); + connect(mz, &QAction::triggered, this, &PageView::slotSetMouseZoom); + mz->setCheckable(true); + ac->setDefaultShortcut(mz, QKeySequence(Qt::CTRL + Qt::Key_2)); + mz->setActionGroup(d->mouseModeActionGroup); + mz->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::Zoom); + + QAction *aToggleChangeColors = new QAction(i18n("&Toggle Change Colors"), this); + ac->addAction(QStringLiteral("toggle_change_colors"), aToggleChangeColors); + connect(aToggleChangeColors, &QAction::triggered, this, &PageView::slotToggleChangeColors); +} + +// WARNING: 'setupViewerActions' must have been called before this method +void PageView::setupActions(KActionCollection *ac) +{ + d->actionCollection = ac; + + ac->setDefaultShortcuts(d->aZoomIn, KStandardShortcut::zoomIn()); + ac->setDefaultShortcuts(d->aZoomOut, KStandardShortcut::zoomOut()); + + // Mouse-Mode actions + d->aMouseSelect = new QAction(QIcon::fromTheme(QStringLiteral("select-rectangular")), i18n("Area &Selection"), this); + ac->addAction(QStringLiteral("mouse_select"), d->aMouseSelect); + connect(d->aMouseSelect, &QAction::triggered, this, &PageView::slotSetMouseSelect); + d->aMouseSelect->setCheckable(true); + ac->setDefaultShortcut(d->aMouseSelect, Qt::CTRL + Qt::Key_3); + + d->aMouseSelect->setActionGroup(d->mouseModeActionGroup); + d->aMouseSelect->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::RectSelect); + + d->aMouseTextSelect = new QAction(QIcon::fromTheme(QStringLiteral("edit-select-text")), i18n("&Text Selection"), this); + ac->addAction(QStringLiteral("mouse_textselect"), d->aMouseTextSelect); + connect(d->aMouseTextSelect, &QAction::triggered, this, &PageView::slotSetMouseTextSelect); + d->aMouseTextSelect->setCheckable(true); + ac->setDefaultShortcut(d->aMouseTextSelect, Qt::CTRL + Qt::Key_4); + d->aMouseTextSelect->setActionGroup(d->mouseModeActionGroup); + d->aMouseTextSelect->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::TextSelect); + + d->aMouseTableSelect = new QAction(QIcon::fromTheme(QStringLiteral("table")), i18n("T&able Selection"), this); + ac->addAction(QStringLiteral("mouse_tableselect"), d->aMouseTableSelect); + connect(d->aMouseTableSelect, &QAction::triggered, this, &PageView::slotSetMouseTableSelect); + d->aMouseTableSelect->setCheckable(true); + ac->setDefaultShortcut(d->aMouseTableSelect, Qt::CTRL + Qt::Key_5); + d->aMouseTableSelect->setActionGroup(d->mouseModeActionGroup); + d->aMouseTableSelect->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::TableSelect); + + d->aMouseMagnifier = new QAction(QIcon::fromTheme(QStringLiteral("document-preview")), i18n("&Magnifier"), this); + ac->addAction(QStringLiteral("mouse_magnifier"), d->aMouseMagnifier); + connect(d->aMouseMagnifier, &QAction::triggered, this, &PageView::slotSetMouseMagnifier); + d->aMouseMagnifier->setCheckable(true); + ac->setDefaultShortcut(d->aMouseMagnifier, Qt::CTRL + Qt::Key_6); + d->aMouseMagnifier->setActionGroup(d->mouseModeActionGroup); + d->aMouseMagnifier->setChecked(Okular::Settings::mouseMode() == Okular::Settings::EnumMouseMode::Magnifier); + + // Mouse-Mode action menu + d->aMouseModeMenu = new ToggleActionMenu(QIcon(), QString(), this, ToggleActionMenu::MenuButtonPopup, ToggleActionMenu::ImplicitDefaultAction); + d->aMouseModeMenu->addAction(d->aMouseSelect); + d->aMouseModeMenu->addAction(d->aMouseTextSelect); + d->aMouseModeMenu->addAction(d->aMouseTableSelect); + d->aMouseModeMenu->suggestDefaultAction(d->aMouseTextSelect); + d->aMouseModeMenu->setText(i18nc("@action", "Selection Tools")); + ac->addAction(QStringLiteral("mouse_selecttools"), d->aMouseModeMenu); + + // speak actions +#ifdef HAVE_SPEECH + d->aSpeakDoc = new QAction(QIcon::fromTheme(QStringLiteral("text-speak")), i18n("Speak Whole Document"), this); + ac->addAction(QStringLiteral("speak_document"), d->aSpeakDoc); + d->aSpeakDoc->setEnabled(false); + connect(d->aSpeakDoc, &QAction::triggered, this, &PageView::slotSpeakDocument); + + d->aSpeakPage = new QAction(QIcon::fromTheme(QStringLiteral("text-speak")), i18n("Speak Current Page"), this); + ac->addAction(QStringLiteral("speak_current_page"), d->aSpeakPage); + d->aSpeakPage->setEnabled(false); + connect(d->aSpeakPage, &QAction::triggered, this, &PageView::slotSpeakCurrentPage); + + d->aSpeakStop = new QAction(QIcon::fromTheme(QStringLiteral("media-playback-stop")), i18n("Stop Speaking"), this); + ac->addAction(QStringLiteral("speak_stop_all"), d->aSpeakStop); + d->aSpeakStop->setEnabled(false); + connect(d->aSpeakStop, &QAction::triggered, this, &PageView::slotStopSpeaks); + + d->aSpeakPauseResume = new QAction(QIcon::fromTheme(QStringLiteral("media-playback-pause")), i18n("Pause/Resume Speaking"), this); + ac->addAction(QStringLiteral("speak_pause_resume"), d->aSpeakPauseResume); + d->aSpeakPauseResume->setEnabled(false); + connect(d->aSpeakPauseResume, &QAction::triggered, this, &PageView::slotPauseResumeSpeech); +#else + d->aSpeakDoc = nullptr; + d->aSpeakPage = nullptr; + d->aSpeakStop = nullptr; + d->aSpeakPauseResume = nullptr; +#endif + + // Other actions + QAction *su = new QAction(i18n("Scroll Up"), this); + ac->addAction(QStringLiteral("view_scroll_up"), su); + connect(su, &QAction::triggered, this, &PageView::slotAutoScrollUp); + ac->setDefaultShortcut(su, QKeySequence(Qt::SHIFT + Qt::Key_Up)); + addAction(su); + + QAction *sd = new QAction(i18n("Scroll Down"), this); + ac->addAction(QStringLiteral("view_scroll_down"), sd); + connect(sd, &QAction::triggered, this, &PageView::slotAutoScrollDown); + ac->setDefaultShortcut(sd, QKeySequence(Qt::SHIFT + Qt::Key_Down)); + addAction(sd); + + QAction *spu = new QAction(i18n("Scroll Page Up"), this); + ac->addAction(QStringLiteral("view_scroll_page_up"), spu); + connect(spu, &QAction::triggered, this, &PageView::slotScrollUp); + ac->setDefaultShortcut(spu, QKeySequence(Qt::SHIFT + Qt::Key_Space)); + addAction(spu); + + QAction *spd = new QAction(i18n("Scroll Page Down"), this); + ac->addAction(QStringLiteral("view_scroll_page_down"), spd); + connect(spd, &QAction::triggered, this, &PageView::slotScrollDown); + ac->setDefaultShortcut(spd, QKeySequence(Qt::Key_Space)); + addAction(spd); + + d->aToggleForms = new KToggleAction(i18n("Show Forms"), this); + ac->addAction(QStringLiteral("view_toggle_forms"), d->aToggleForms); + connect(d->aToggleForms, &QAction::toggled, this, &PageView::slotToggleForms); + d->aToggleForms->setEnabled(false); + toggleFormWidgets(false); + + // Setup undo and redo actions + QAction *kundo = KStandardAction::create(KStandardAction::Undo, d->document, SLOT(undo()), ac); + QAction *kredo = KStandardAction::create(KStandardAction::Redo, d->document, SLOT(redo()), ac); + connect(d->document, &Okular::Document::canUndoChanged, kundo, &QAction::setEnabled); + connect(d->document, &Okular::Document::canRedoChanged, kredo, &QAction::setEnabled); + kundo->setEnabled(false); + kredo->setEnabled(false); + + if (!d->annotator) { + d->annotator = new PageViewAnnotator(this, d->document); + connect(d->annotator, &PageViewAnnotator::toolSelected, d->aMouseNormal, &QAction::trigger); + connect(d->annotator, &PageViewAnnotator::toolSelected, d->mouseAnnotation, &MouseAnnotation::reset); + } + d->annotator->setupActions(ac); +} + +bool PageView::canFitPageWidth() const +{ + return Okular::Settings::viewMode() != Okular::Settings::EnumViewMode::Single || d->zoomMode != ZoomFitWidth; +} + +void PageView::fitPageWidth(int page) +{ + // zoom: Fit Width, columns: 1. setActions + relayout + setPage + update + d->zoomMode = ZoomFitWidth; + Okular::Settings::setViewMode(0); + d->aZoomFitWidth->setChecked(true); + d->aZoomFitPage->setChecked(false); + d->aZoomAutoFit->setChecked(false); + updateViewMode(0); + viewport()->setUpdatesEnabled(false); + slotRelayoutPages(); + viewport()->setUpdatesEnabled(true); + d->document->setViewportPage(page); + updateZoomText(); + setFocus(); +} + +void PageView::openAnnotationWindow(Okular::Annotation *annotation, int pageNumber) +{ + if (!annotation) + return; + + // find the annot window + AnnotWindow *existWindow = nullptr; + for (AnnotWindow *aw : qAsConst(d->m_annowindows)) { + if (aw->annotation() == annotation) { + existWindow = aw; + break; + } + } + + if (existWindow == nullptr) { + existWindow = new AnnotWindow(this, annotation, d->document, pageNumber); + connect(existWindow, &QObject::destroyed, this, &PageView::slotAnnotationWindowDestroyed); + + d->m_annowindows << existWindow; + } else { + existWindow->raise(); + existWindow->findChild()->setFocus(); + } + + existWindow->show(); +} + +void PageView::slotAnnotationWindowDestroyed(QObject *window) +{ + d->m_annowindows.remove(static_cast(window)); +} + +void PageView::displayMessage(const QString &message, const QString &details, PageViewMessage::Icon icon, int duration) +{ + if (!Okular::Settings::showOSD()) { + if (icon == PageViewMessage::Error) { + if (!details.isEmpty()) + KMessageBox::detailedError(this, message, details); + else + KMessageBox::error(this, message); + } + return; + } + + // hide messageWindow if string is empty + if (message.isEmpty()) { + d->messageWindow->hide(); + return; + } + + // display message (duration is length dependent) + if (duration == -1) { + duration = 500 + 100 * message.length(); + if (!details.isEmpty()) + duration += 500 + 100 * details.length(); + } + d->messageWindow->display(message, details, icon, duration); +} + +void PageView::reparseConfig() +{ + // set smooth scrolling policies + PageView::updateSmoothScrollAnimationSpeed(); + + // set the scroll bars policies + Qt::ScrollBarPolicy scrollBarMode = Okular::Settings::showScrollBars() ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff; + if (horizontalScrollBarPolicy() != scrollBarMode) { + setHorizontalScrollBarPolicy(scrollBarMode); + setVerticalScrollBarPolicy(scrollBarMode); + } + + if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Summary && ((int)Okular::Settings::viewColumns() != d->setting_viewCols)) { + d->setting_viewCols = Okular::Settings::viewColumns(); + + slotRelayoutPages(); + } + + if (Okular::Settings::rtlReadingDirection() != d->rtl_Mode) { + d->rtl_Mode = Okular::Settings::rtlReadingDirection(); + slotRelayoutPages(); + } + + updatePageStep(); + + if (d->annotator) + d->annotator->reparseConfig(); + + // Something like invert colors may have changed + // As we don't have a way to find out the old value + // We just update the viewport, this shouldn't be that bad + // since it's just a repaint of pixmaps we already have + viewport()->update(); +} + +KActionCollection *PageView::actionCollection() const +{ + return d->actionCollection; +} + +QAction *PageView::toggleFormsAction() const +{ + return d->aToggleForms; +} + +int PageView::contentAreaWidth() const +{ + return horizontalScrollBar()->maximum() + viewport()->width(); +} + +int PageView::contentAreaHeight() const +{ + return verticalScrollBar()->maximum() + viewport()->height(); +} + +QPoint PageView::contentAreaPosition() const +{ + return QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()); +} + +QPoint PageView::contentAreaPoint(const QPoint pos) const +{ + return pos + contentAreaPosition(); +} + +QPointF PageView::contentAreaPoint(const QPointF pos) const +{ + return pos + contentAreaPosition(); +} + +QString PageViewPrivate::selectedText() const +{ + if (pagesWithTextSelection.isEmpty()) + return QString(); + + QString text; + QList selpages = pagesWithTextSelection.values(); + std::sort(selpages.begin(), selpages.end()); + const Okular::Page *pg = nullptr; + if (selpages.count() == 1) { + pg = document->page(selpages.first()); + text.append(pg->text(pg->textSelection(), Okular::TextPage::CentralPixelTextAreaInclusionBehaviour)); + } else { + pg = document->page(selpages.first()); + text.append(pg->text(pg->textSelection(), Okular::TextPage::CentralPixelTextAreaInclusionBehaviour)); + int end = selpages.count() - 1; + for (int i = 1; i < end; ++i) { + pg = document->page(selpages.at(i)); + text.append(pg->text(nullptr, Okular::TextPage::CentralPixelTextAreaInclusionBehaviour)); + } + pg = document->page(selpages.last()); + text.append(pg->text(pg->textSelection(), Okular::TextPage::CentralPixelTextAreaInclusionBehaviour)); + } + return text; +} + +void PageView::copyTextSelection() const +{ + const QString text = d->selectedText(); + if (!text.isEmpty()) { + QClipboard *cb = QApplication::clipboard(); + cb->setText(text, QClipboard::Clipboard); + } +} + +void PageView::selectAll() +{ + for (const PageViewItem *item : qAsConst(d->items)) { + Okular::RegularAreaRect *area = textSelectionForItem(item); + d->pagesWithTextSelection.insert(item->pageNumber()); + d->document->setPageTextSelection(item->pageNumber(), area, palette().color(QPalette::Active, QPalette::Highlight)); + } +} + +void PageView::createAnnotationsVideoWidgets(PageViewItem *item, const QLinkedList &annotations) +{ + qDeleteAll(item->videoWidgets()); + item->videoWidgets().clear(); + + for (Okular::Annotation *a : annotations) { + if (a->subType() == Okular::Annotation::AMovie) { + Okular::MovieAnnotation *movieAnn = static_cast(a); + VideoWidget *vw = new VideoWidget(movieAnn, movieAnn->movie(), d->document, viewport()); + item->videoWidgets().insert(movieAnn->movie(), vw); + vw->pageInitialized(); + } else if (a->subType() == Okular::Annotation::ARichMedia) { + Okular::RichMediaAnnotation *richMediaAnn = static_cast(a); + VideoWidget *vw = new VideoWidget(richMediaAnn, richMediaAnn->movie(), d->document, viewport()); + item->videoWidgets().insert(richMediaAnn->movie(), vw); + vw->pageInitialized(); + } else if (a->subType() == Okular::Annotation::AScreen) { + const Okular::ScreenAnnotation *screenAnn = static_cast(a); + Okular::Movie *movie = GuiUtils::renditionMovieFromScreenAnnotation(screenAnn); + if (movie) { + VideoWidget *vw = new VideoWidget(screenAnn, movie, d->document, viewport()); + item->videoWidgets().insert(movie, vw); + vw->pageInitialized(); + } + } + } +} + +// BEGIN DocumentObserver inherited methods +void PageView::notifySetup(const QVector &pageSet, int setupFlags) +{ + bool documentChanged = setupFlags & Okular::DocumentObserver::DocumentChanged; + const bool allowfillforms = d->document->isAllowed(Okular::AllowFillForms); + + // reuse current pages if nothing new + if ((pageSet.count() == d->items.count()) && !documentChanged && !(setupFlags & Okular::DocumentObserver::NewLayoutForPages)) { + int count = pageSet.count(); + for (int i = 0; (i < count) && !documentChanged; i++) { + if ((int)pageSet[i]->number() != d->items[i]->pageNumber()) { + documentChanged = true; + } else { + // even if the document has not changed, allowfillforms may have + // changed, so update all fields' "canBeFilled" flag + const QSet formWidgetsList = d->items[i]->formWidgets(); + for (FormWidgetIface *w : formWidgetsList) + w->setCanBeFilled(allowfillforms); + } + } + + if (!documentChanged) { + if (setupFlags & Okular::DocumentObserver::UrlChanged) { + // Here with UrlChanged and no document changed it means we + // need to update all the Annotation* and Form* otherwise + // they still point to the old document ones, luckily the old ones are still + // around so we can look for the new ones using unique ids, etc + d->mouseAnnotation->updateAnnotationPointers(); + + for (AnnotWindow *aw : qAsConst(d->m_annowindows)) { + Okular::Annotation *newA = d->document->page(aw->pageNumber())->annotation(aw->annotation()->uniqueName()); + aw->updateAnnotation(newA); + } + + const QRect viewportRect(horizontalScrollBar()->value(), verticalScrollBar()->value(), viewport()->width(), viewport()->height()); + for (int i = 0; i < count; i++) { + PageViewItem *item = d->items[i]; + const QSet fws = item->formWidgets(); + for (FormWidgetIface *w : fws) { + Okular::FormField *f = Okular::PagePrivate::findEquivalentForm(d->document->page(i), w->formField()); + if (f) { + w->setFormField(f); + } else { + qWarning() << "Lost form field on document save, something is wrong"; + item->formWidgets().remove(w); + delete w; + } + } + + // For the video widgets we don't really care about reusing them since they don't contain much info so just + // create them again + createAnnotationsVideoWidgets(item, pageSet[i]->annotations()); + const QHash videoWidgets = item->videoWidgets(); + for (VideoWidget *vw : videoWidgets) { + const Okular::NormalizedRect r = vw->normGeometry(); + vw->setGeometry(qRound(item->uncroppedGeometry().left() + item->uncroppedWidth() * r.left) + 1 - viewportRect.left(), + qRound(item->uncroppedGeometry().top() + item->uncroppedHeight() * r.top) + 1 - viewportRect.top(), + qRound(fabs(r.right - r.left) * item->uncroppedGeometry().width()), + qRound(fabs(r.bottom - r.top) * item->uncroppedGeometry().height())); + + // Workaround, otherwise the size somehow gets lost + vw->show(); + vw->hide(); + } + } + } + + return; + } + } + + // mouseAnnotation must not access our PageViewItem widgets any longer + d->mouseAnnotation->reset(); + + // delete all widgets (one for each page in pageSet) + qDeleteAll(d->items); + d->items.clear(); + d->visibleItems.clear(); + d->pagesWithTextSelection.clear(); + toggleFormWidgets(false); + if (d->formsWidgetController) + d->formsWidgetController->dropRadioButtons(); + + bool haspages = !pageSet.isEmpty(); + bool hasformwidgets = false; + // create children widgets + for (const Okular::Page *page : pageSet) { + PageViewItem *item = new PageViewItem(page); + d->items.push_back(item); +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug).nospace() << "cropped geom for " << d->items.last()->pageNumber() << " is " << d->items.last()->croppedGeometry(); +#endif + const QLinkedList pageFields = page->formFields(); + for (Okular::FormField *ff : pageFields) { + FormWidgetIface *w = FormWidgetFactory::createWidget(ff, viewport()); + if (w) { + w->setPageItem(item); + w->setFormWidgetsController(d->formWidgetsController()); + w->setVisibility(false); + w->setCanBeFilled(allowfillforms); + item->formWidgets().insert(w); + hasformwidgets = true; + } + } + + createAnnotationsVideoWidgets(item, page->annotations()); + } + + // invalidate layout so relayout/repaint will happen on next viewport change + if (haspages) { + // We do a delayed call to slotRelayoutPages but also set the dirtyLayout + // because we might end up in notifyViewportChanged while slotRelayoutPages + // has not been done and we don't want that to happen + d->dirtyLayout = true; + QMetaObject::invokeMethod(this, "slotRelayoutPages", Qt::QueuedConnection); + } else { + // update the mouse cursor when closing because we may have close through a link and + // want the cursor to come back to the normal cursor + updateCursor(); + // then, make the message window and scrollbars disappear, and trigger a repaint + d->messageWindow->hide(); + resizeContentArea(QSize(0, 0)); + viewport()->update(); // when there is no change to the scrollbars, no repaint would + // be done and the old document would still be shown + } + + // OSD to display pages + if (documentChanged && pageSet.count() > 0 && Okular::Settings::showOSD()) + d->messageWindow->display(i18np(" Loaded a one-page document.", " Loaded a %1-page document.", pageSet.count()), QString(), PageViewMessage::Info, 4000); + + updateActionState(haspages, hasformwidgets); + + // We need to assign it to a different list otherwise slotAnnotationWindowDestroyed + // will bite us and clear d->m_annowindows + QSet annowindows = d->m_annowindows; + d->m_annowindows.clear(); + qDeleteAll(annowindows); + + selectionClear(); +} + +void PageView::updateActionState(bool haspages, bool hasformwidgets) +{ + if (d->aTrimMargins) + d->aTrimMargins->setEnabled(haspages); + + if (d->aTrimToSelection) + d->aTrimToSelection->setEnabled(haspages); + + if (d->aViewModeMenu) + d->aViewModeMenu->setEnabled(haspages); + + if (d->aViewContinuous) + d->aViewContinuous->setEnabled(haspages); + + if (d->aZoomFitWidth) + d->aZoomFitWidth->setEnabled(haspages); + if (d->aZoomFitPage) + d->aZoomFitPage->setEnabled(haspages); + if (d->aZoomAutoFit) + d->aZoomAutoFit->setEnabled(haspages); + + if (d->aZoom) { + d->aZoom->selectableActionGroup()->setEnabled(haspages); + d->aZoom->setEnabled(haspages); + } + if (d->aZoomIn) + d->aZoomIn->setEnabled(haspages); + if (d->aZoomOut) + d->aZoomOut->setEnabled(haspages); + if (d->aZoomActual) + d->aZoomActual->setEnabled(haspages && d->zoomFactor != 1.0); + + if (d->aReadingDirection) { + d->aReadingDirection->setEnabled(haspages); + } + + if (d->mouseModeActionGroup) + d->mouseModeActionGroup->setEnabled(haspages); + if (d->aMouseModeMenu) + d->aMouseModeMenu->setEnabled(haspages); + + if (d->aRotateClockwise) + d->aRotateClockwise->setEnabled(haspages); + if (d->aRotateCounterClockwise) + d->aRotateCounterClockwise->setEnabled(haspages); + if (d->aRotateOriginal) + d->aRotateOriginal->setEnabled(haspages); + if (d->aToggleForms) { // may be null if dummy mode is on + d->aToggleForms->setEnabled(haspages && hasformwidgets); + } + bool allowAnnotations = d->document->isAllowed(Okular::AllowNotes); + if (d->annotator) { + bool allowTools = haspages && allowAnnotations; + d->annotator->setToolsEnabled(allowTools); + d->annotator->setTextToolsEnabled(allowTools && d->document->supportsSearching()); + } +#ifdef HAVE_SPEECH + if (d->aSpeakDoc) { + const bool enablettsactions = haspages ? Okular::Settings::useTTS() : false; + d->aSpeakDoc->setEnabled(enablettsactions); + d->aSpeakPage->setEnabled(enablettsactions); + } +#endif + if (d->aMouseMagnifier) + d->aMouseMagnifier->setEnabled(d->document->supportsTiles()); + if (d->aFitWindowToPage) + d->aFitWindowToPage->setEnabled(haspages && !Okular::Settings::viewContinuous()); +} + +void PageView::setupActionsPostGUIActivated() +{ + d->annotator->setupActionsPostGUIActivated(); +} + +bool PageView::areSourceLocationsShownGraphically() const +{ + return Okular::Settings::showSourceLocationsGraphically(); +} + +void PageView::setShowSourceLocationsGraphically(bool show) +{ + if (show == Okular::Settings::showSourceLocationsGraphically()) { + return; + } + Okular::Settings::setShowSourceLocationsGraphically(show); + viewport()->update(); +} + +void PageView::setLastSourceLocationViewport(const Okular::DocumentViewport &vp) +{ + if (vp.rePos.enabled) { + d->lastSourceLocationViewportNormalizedX = normClamp(vp.rePos.normalizedX, 0.5); + d->lastSourceLocationViewportNormalizedY = normClamp(vp.rePos.normalizedY, 0.0); + } else { + d->lastSourceLocationViewportNormalizedX = 0.5; + d->lastSourceLocationViewportNormalizedY = 0.0; + } + d->lastSourceLocationViewportPageNumber = vp.pageNumber; + viewport()->update(); +} + +void PageView::clearLastSourceLocationViewport() +{ + d->lastSourceLocationViewportPageNumber = -1; + d->lastSourceLocationViewportNormalizedX = 0.0; + d->lastSourceLocationViewportNormalizedY = 0.0; + viewport()->update(); +} + +void PageView::notifyViewportChanged(bool smoothMove) +{ + QMetaObject::invokeMethod(this, "slotRealNotifyViewportChanged", Qt::QueuedConnection, Q_ARG(bool, smoothMove)); +} + +void PageView::slotRealNotifyViewportChanged(bool smoothMove) +{ + // if we are the one changing viewport, skip this notify + if (d->blockViewport) + return; + + // block setViewport outgoing calls + d->blockViewport = true; + + // find PageViewItem matching the viewport description + const Okular::DocumentViewport &vp = d->document->viewport(); + const PageViewItem *item = nullptr; + for (const PageViewItem *tmpItem : qAsConst(d->items)) + if (tmpItem->pageNumber() == vp.pageNumber) { + item = tmpItem; + break; + } + if (!item) { + qCWarning(OkularUiDebug) << "viewport for page" << vp.pageNumber << "has no matching item!"; + d->blockViewport = false; + return; + } +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << "document viewport changed"; +#endif + // relayout in "Single Pages" mode or if a relayout is pending + d->blockPixmapsRequest = true; + if (!Okular::Settings::viewContinuous() || d->dirtyLayout) + slotRelayoutPages(); + + // restore viewport center or use default {x-center,v-top} alignment + const QPoint centerCoord = viewportToContentArea(vp); + + // if smooth movement requested, setup parameters and start it + center(centerCoord.x(), centerCoord.y(), smoothMove); + + d->blockPixmapsRequest = false; + + // request visible pixmaps in the current viewport and recompute it + slotRequestVisiblePixmaps(); + + // enable setViewport calls + d->blockViewport = false; + + if (viewport()) { + viewport()->update(); + } + + // since the page has moved below cursor, update it + updateCursor(); +} + +void PageView::notifyPageChanged(int pageNumber, int changedFlags) +{ + // only handle pixmap / highlight changes notifies + if (changedFlags & DocumentObserver::Bookmark) + return; + + if (changedFlags & DocumentObserver::Annotations) { + const QLinkedList annots = d->document->page(pageNumber)->annotations(); + const QLinkedList::ConstIterator annItEnd = annots.end(); + QSet::Iterator it = d->m_annowindows.begin(); + for (; it != d->m_annowindows.end();) { + QLinkedList::ConstIterator annIt = std::find(annots.begin(), annots.end(), (*it)->annotation()); + if (annIt != annItEnd) { + (*it)->reloadInfo(); + ++it; + } else { + AnnotWindow *w = *it; + it = d->m_annowindows.erase(it); + // Need to delete after removing from the list + // otherwise deleting will call slotAnnotationWindowDestroyed which will mess + // the list and the iterators + delete w; + } + } + + d->mouseAnnotation->notifyAnnotationChanged(pageNumber); + } + + if (changedFlags & DocumentObserver::BoundingBox) { +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << "BoundingBox change on page" << pageNumber; +#endif + slotRelayoutPages(); + slotRequestVisiblePixmaps(); // TODO: slotRelayoutPages() may have done this already! + // Repaint the whole widget since layout may have changed + viewport()->update(); + return; + } + + // iterate over visible items: if page(pageNumber) is one of them, repaint it + for (const PageViewItem *visibleItem : qAsConst(d->visibleItems)) + if (visibleItem->pageNumber() == pageNumber && visibleItem->isVisible()) { + // update item's rectangle plus the little outline + QRect expandedRect = visibleItem->croppedGeometry(); + // a PageViewItem is placed in the global page layout, + // while we need to map its position in the viewport coordinates + // (to get the correct area to repaint) + expandedRect.translate(-contentAreaPosition()); + expandedRect.adjust(-1, -1, 3, 3); + viewport()->update(expandedRect); + + // if we were "zoom-dragging" do not overwrite the "zoom-drag" cursor + if (cursor().shape() != Qt::SizeVerCursor) { + // since the page has been regenerated below cursor, update it + updateCursor(); + } + break; + } +} + +void PageView::notifyContentsCleared(int changedFlags) +{ + // if pixmaps were cleared, re-ask them + if (changedFlags & DocumentObserver::Pixmap) + QMetaObject::invokeMethod(this, "slotRequestVisiblePixmaps", Qt::QueuedConnection); +} + +void PageView::notifyZoom(int factor) +{ + if (factor > 0) + updateZoom(ZoomIn); + else + updateZoom(ZoomOut); +} + +bool PageView::canUnloadPixmap(int pageNumber) const +{ + if (Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Low || Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Normal) { + // if the item is visible, forbid unloading + for (const PageViewItem *visibleItem : qAsConst(d->visibleItems)) + if (visibleItem->pageNumber() == pageNumber) + return false; + } else { + // forbid unloading of the visible items, and of the previous and next + for (const PageViewItem *visibleItem : qAsConst(d->visibleItems)) + if (abs(visibleItem->pageNumber() - pageNumber) <= 1) + return false; + } + // if hidden premit unloading + return true; +} + +void PageView::notifyCurrentPageChanged(int previous, int current) +{ + if (previous != -1) { + PageViewItem *item = d->items.at(previous); + if (item) { + const QHash videoWidgetsList = item->videoWidgets(); + for (VideoWidget *videoWidget : videoWidgetsList) + videoWidget->pageLeft(); + } + + // On close, run the widget scripts, needed for running animated PDF + const Okular::Page *page = d->document->page(previous); + const QLinkedList annotations = page->annotations(); + for (Okular::Annotation *annotation : annotations) { + if (annotation->subType() == Okular::Annotation::AWidget) { + Okular::WidgetAnnotation *widgetAnnotation = static_cast(annotation); + d->document->processAction(widgetAnnotation->additionalAction(Okular::Annotation::PageClosing)); + } + } + } + + if (current != -1) { + PageViewItem *item = d->items.at(current); + if (item) { + const QHash videoWidgetsList = item->videoWidgets(); + for (VideoWidget *videoWidget : videoWidgetsList) + videoWidget->pageEntered(); + } + + // update zoom text and factor if in a ZoomFit/* zoom mode + if (d->zoomMode != ZoomFixed) + updateZoomText(); + + // Opening any widget scripts, needed for running animated PDF + const Okular::Page *page = d->document->page(current); + const QLinkedList annotations = page->annotations(); + for (Okular::Annotation *annotation : annotations) { + if (annotation->subType() == Okular::Annotation::AWidget) { + Okular::WidgetAnnotation *widgetAnnotation = static_cast(annotation); + d->document->processAction(widgetAnnotation->additionalAction(Okular::Annotation::PageOpening)); + } + } + } + + // if the view is paged (or not continuous) and there is a selected annotation, + // we call reset to avoid creating an artifact in the next page. + if (!Okular::Settings::viewContinuous()) { + if (d->mouseAnnotation && d->mouseAnnotation->isFocused()) { + d->mouseAnnotation->reset(); + } + } +} + +// END DocumentObserver inherited methods + +// BEGIN View inherited methods +bool PageView::supportsCapability(ViewCapability capability) const +{ + switch (capability) { + case Zoom: + case ZoomModality: + case Continuous: + case ViewModeModality: + case TrimMargins: + return true; + } + return false; +} + +Okular::View::CapabilityFlags PageView::capabilityFlags(ViewCapability capability) const +{ + switch (capability) { + case Zoom: + case ZoomModality: + case Continuous: + case ViewModeModality: + case TrimMargins: + return CapabilityRead | CapabilityWrite | CapabilitySerializable; + } + return NoFlag; +} + +QVariant PageView::capability(ViewCapability capability) const +{ + switch (capability) { + case Zoom: + return d->zoomFactor; + case ZoomModality: + return d->zoomMode; + case Continuous: + return d->aViewContinuous ? d->aViewContinuous->isChecked() : true; + case ViewModeModality: { + if (d->viewModeActionGroup) { + const QList actions = d->viewModeActionGroup->actions(); + for (const QAction *action : actions) { + if (action->isChecked()) { + return action->data(); + } + } + } + return QVariant(); + } + case TrimMargins: + return d->aTrimMargins ? d->aTrimMargins->isChecked() : false; + } + return QVariant(); +} + +void PageView::setCapability(ViewCapability capability, const QVariant &option) +{ + switch (capability) { + case Zoom: { + bool ok = true; + double factor = option.toDouble(&ok); + if (ok && factor > 0.0) { + d->zoomFactor = static_cast(factor); + updateZoom(ZoomRefreshCurrent); + } + break; + } + case ZoomModality: { + bool ok = true; + int mode = option.toInt(&ok); + if (ok) { + if (mode >= 0 && mode < 3) + updateZoom((ZoomMode)mode); + } + break; + } + case ViewModeModality: { + bool ok = true; + int mode = option.toInt(&ok); + if (ok) { + if (mode >= 0 && mode < Okular::Settings::EnumViewMode::COUNT) + updateViewMode(mode); + } + break; + } + case Continuous: { + bool mode = option.toBool(); + d->aViewContinuous->setChecked(mode); + slotContinuousToggled(mode); + break; + } + case TrimMargins: { + bool value = option.toBool(); + d->aTrimMargins->setChecked(value); + slotTrimMarginsToggled(value); + break; + } + } +} + +// END View inherited methods + +// BEGIN widget events +bool PageView::event(QEvent *event) +{ + if (event->type() == QEvent::Gesture) { + return gestureEvent(static_cast(event)); + } + + // do not stop the event + return QAbstractScrollArea::event(event); +} + +bool PageView::gestureEvent(QGestureEvent *event) +{ + QPinchGesture *pinch = static_cast(event->gesture(Qt::PinchGesture)); + + if (pinch) { + // Viewport zoom level at the moment where the pinch gesture starts. + // The viewport zoom level _during_ the gesture will be this value + // times the relative zoom reported by QGestureEvent. + static qreal vanillaZoom = d->zoomFactor; + + if (pinch->state() == Qt::GestureStarted) { + vanillaZoom = d->zoomFactor; + } + + const QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); + + // Zoom + if (pinch->changeFlags() & QPinchGesture::ScaleFactorChanged) { + d->zoomFactor = vanillaZoom * pinch->totalScaleFactor(); + + d->blockPixmapsRequest = true; + updateZoom(ZoomRefreshCurrent); + d->blockPixmapsRequest = false; + viewport()->update(); + } + + // Count the number of 90-degree rotations we did since the start of the pinch gesture. + // Otherwise a pinch turned to 90 degrees and held there will rotate the page again and again. + static int rotations = 0; + + if (changeFlags & QPinchGesture::RotationAngleChanged) { + // Rotation angle relative to the accumulated page rotations triggered by the current pinch + // We actually turn at 80 degrees rather than at 90 degrees. That's less strain on the hands. + const qreal relativeAngle = pinch->rotationAngle() - rotations * 90; + if (relativeAngle > 80) { + slotRotateClockwise(); + rotations++; + } + if (relativeAngle < -80) { + slotRotateCounterClockwise(); + rotations--; + } + } + + if (pinch->state() == Qt::GestureFinished) { + rotations = 0; + } + + return true; + } + + return false; +} + +void PageView::paintEvent(QPaintEvent *pe) +{ + const QPoint areaPos = contentAreaPosition(); + // create the rect into contents from the clipped screen rect + QRect viewportRect = viewport()->rect(); + viewportRect.translate(areaPos); + QRect contentsRect = pe->rect().translated(areaPos).intersected(viewportRect); + if (!contentsRect.isValid()) + return; + +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << "paintevent" << contentsRect; +#endif + + // create the screen painter. a pixel painted at contentsX,contentsY + // appears to the top-left corner of the scrollview. + QPainter screenPainter(viewport()); + // translate to simulate the scrolled content widget + screenPainter.translate(-areaPos); + + // selectionRect is the normalized mouse selection rect + QRect selectionRect = d->mouseSelectionRect; + if (!selectionRect.isNull()) + selectionRect = selectionRect.normalized(); + // selectionRectInternal without the border + QRect selectionRectInternal = selectionRect; + selectionRectInternal.adjust(1, 1, -1, -1); + // color for blending + QColor selBlendColor = (selectionRect.width() > 8 || selectionRect.height() > 8) ? d->mouseSelectionColor : Qt::red; + + // subdivide region into rects + QRegion rgn = pe->region(); + // preprocess rects area to see if it worths or not using subdivision + uint summedArea = 0; + for (const QRect &r : rgn) { + summedArea += r.width() * r.height(); + } + // very elementary check: SUMj(Region[j].area) is less than boundingRect.area + const bool useSubdivision = summedArea < (0.6 * contentsRect.width() * contentsRect.height()); + if (!useSubdivision) { + rgn = contentsRect; + } + + // iterate over the rects (only one loop if not using subdivision) + for (const QRect &r : rgn) { + if (useSubdivision) { + // set 'contentsRect' to a part of the sub-divided region + contentsRect = r.translated(areaPos).intersected(viewportRect); + if (!contentsRect.isValid()) + continue; + } +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << contentsRect; +#endif + + // note: this check will take care of all things requiring alpha blending (not only selection) + bool wantCompositing = !selectionRect.isNull() && contentsRect.intersects(selectionRect); + // also alpha-blend when there is a table selection... + wantCompositing |= !d->tableSelectionParts.isEmpty(); + + if (wantCompositing && Okular::Settings::enableCompositing()) { + // create pixmap and open a painter over it (contents{left,top} becomes pixmap {0,0}) + QPixmap doubleBuffer(contentsRect.size() * devicePixelRatioF()); + doubleBuffer.setDevicePixelRatio(devicePixelRatioF()); + QPainter pixmapPainter(&doubleBuffer); + + pixmapPainter.translate(-contentsRect.left(), -contentsRect.top()); + + // 1) Layer 0: paint items and clear bg on unpainted rects + drawDocumentOnPainter(contentsRect, &pixmapPainter); + // 2a) Layer 1a: paint (blend) transparent selection (rectangle) + if (!selectionRect.isNull() && selectionRect.intersects(contentsRect) && !selectionRectInternal.contains(contentsRect)) { + QRect blendRect = selectionRectInternal.intersected(contentsRect); + // skip rectangles covered by the selection's border + if (blendRect.isValid()) { + // grab current pixmap into a new one to colorize contents + QPixmap blendedPixmap(blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF()); + blendedPixmap.setDevicePixelRatio(devicePixelRatioF()); + QPainter p(&blendedPixmap); + + p.drawPixmap(0, + 0, + doubleBuffer, + (blendRect.left() - contentsRect.left()) * devicePixelRatioF(), + (blendRect.top() - contentsRect.top()) * devicePixelRatioF(), + blendRect.width() * devicePixelRatioF(), + blendRect.height() * devicePixelRatioF()); + + QColor blCol = selBlendColor.darker(140); + blCol.setAlphaF(0.2); + p.fillRect(blendedPixmap.rect(), blCol); + p.end(); + // copy the blended pixmap back to its place + pixmapPainter.drawPixmap(blendRect.left(), blendRect.top(), blendedPixmap); + } + // draw border (red if the selection is too small) + pixmapPainter.setPen(selBlendColor); + pixmapPainter.drawRect(selectionRect.adjusted(0, 0, -1, -1)); + } + // 2b) Layer 1b: paint (blend) transparent selection (table) + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + QRect selectionPartRect = tsp.rectInItem.geometry(tsp.item->uncroppedWidth(), tsp.item->uncroppedHeight()); + selectionPartRect.translate(tsp.item->uncroppedGeometry().topLeft()); + QRect selectionPartRectInternal = selectionPartRect; + selectionPartRectInternal.adjust(1, 1, -1, -1); + if (!selectionPartRect.isNull() && selectionPartRect.intersects(contentsRect) && !selectionPartRectInternal.contains(contentsRect)) { + QRect blendRect = selectionPartRectInternal.intersected(contentsRect); + // skip rectangles covered by the selection's border + if (blendRect.isValid()) { + // grab current pixmap into a new one to colorize contents + QPixmap blendedPixmap(blendRect.width() * devicePixelRatioF(), blendRect.height() * devicePixelRatioF()); + blendedPixmap.setDevicePixelRatio(devicePixelRatioF()); + QPainter p(&blendedPixmap); + p.drawPixmap(0, + 0, + doubleBuffer, + (blendRect.left() - contentsRect.left()) * devicePixelRatioF(), + (blendRect.top() - contentsRect.top()) * devicePixelRatioF(), + blendRect.width() * devicePixelRatioF(), + blendRect.height() * devicePixelRatioF()); + + QColor blCol = d->mouseSelectionColor.darker(140); + blCol.setAlphaF(0.2); + p.fillRect(blendedPixmap.rect(), blCol); + p.end(); + // copy the blended pixmap back to its place + pixmapPainter.drawPixmap(blendRect.left(), blendRect.top(), blendedPixmap); + } + // draw border (red if the selection is too small) + pixmapPainter.setPen(d->mouseSelectionColor); + pixmapPainter.drawRect(selectionPartRect.adjusted(0, 0, -1, -1)); + } + } + drawTableDividers(&pixmapPainter); + // 3a) Layer 1: give annotator painting control + if (d->annotator && d->annotator->routePaints(contentsRect)) + d->annotator->routePaint(&pixmapPainter, contentsRect); + // 3b) Layer 1: give mouseAnnotation painting control + d->mouseAnnotation->routePaint(&pixmapPainter, contentsRect); + + // 4) Layer 2: overlays + if (Okular::Settings::debugDrawBoundaries()) { + pixmapPainter.setPen(Qt::blue); + pixmapPainter.drawRect(contentsRect); + } + + // finish painting and draw contents + pixmapPainter.end(); + screenPainter.drawPixmap(contentsRect.left(), contentsRect.top(), doubleBuffer); + } else { + // 1) Layer 0: paint items and clear bg on unpainted rects + drawDocumentOnPainter(contentsRect, &screenPainter); + // 2a) Layer 1a: paint opaque selection (rectangle) + if (!selectionRect.isNull() && selectionRect.intersects(contentsRect) && !selectionRectInternal.contains(contentsRect)) { + screenPainter.setPen(palette().color(QPalette::Active, QPalette::Highlight).darker(110)); + screenPainter.drawRect(selectionRect); + } + // 2b) Layer 1b: paint opaque selection (table) + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + QRect selectionPartRect = tsp.rectInItem.geometry(tsp.item->uncroppedWidth(), tsp.item->uncroppedHeight()); + selectionPartRect.translate(tsp.item->uncroppedGeometry().topLeft()); + QRect selectionPartRectInternal = selectionPartRect; + selectionPartRectInternal.adjust(1, 1, -1, -1); + if (!selectionPartRect.isNull() && selectionPartRect.intersects(contentsRect) && !selectionPartRectInternal.contains(contentsRect)) { + screenPainter.setPen(palette().color(QPalette::Active, QPalette::Highlight).darker(110)); + screenPainter.drawRect(selectionPartRect); + } + } + drawTableDividers(&screenPainter); + // 3a) Layer 1: give annotator painting control + if (d->annotator && d->annotator->routePaints(contentsRect)) + d->annotator->routePaint(&screenPainter, contentsRect); + // 3b) Layer 1: give mouseAnnotation painting control + d->mouseAnnotation->routePaint(&screenPainter, contentsRect); + + // 4) Layer 2: overlays + if (Okular::Settings::debugDrawBoundaries()) { + screenPainter.setPen(Qt::red); + screenPainter.drawRect(contentsRect); + } + } + } +} + +void PageView::drawTableDividers(QPainter *screenPainter) +{ + if (!d->tableSelectionParts.isEmpty()) { + screenPainter->setPen(d->mouseSelectionColor.darker()); + if (d->tableDividersGuessed) { + QPen p = screenPainter->pen(); + p.setStyle(Qt::DashLine); + screenPainter->setPen(p); + } + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + QRect selectionPartRect = tsp.rectInItem.geometry(tsp.item->uncroppedWidth(), tsp.item->uncroppedHeight()); + selectionPartRect.translate(tsp.item->uncroppedGeometry().topLeft()); + QRect selectionPartRectInternal = selectionPartRect; + selectionPartRectInternal.adjust(1, 1, -1, -1); + for (double col : qAsConst(d->tableSelectionCols)) { + if (col >= tsp.rectInSelection.left && col <= tsp.rectInSelection.right) { + col = (col - tsp.rectInSelection.left) / (tsp.rectInSelection.right - tsp.rectInSelection.left); + const int x = selectionPartRect.left() + col * selectionPartRect.width() + 0.5; + screenPainter->drawLine(x, selectionPartRectInternal.top(), x, selectionPartRectInternal.top() + selectionPartRectInternal.height()); + } + } + for (double row : qAsConst(d->tableSelectionRows)) { + if (row >= tsp.rectInSelection.top && row <= tsp.rectInSelection.bottom) { + row = (row - tsp.rectInSelection.top) / (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + const int y = selectionPartRect.top() + row * selectionPartRect.height() + 0.5; + screenPainter->drawLine(selectionPartRectInternal.left(), y, selectionPartRectInternal.left() + selectionPartRectInternal.width(), y); + } + } + } + } +} + +void PageView::resizeEvent(QResizeEvent *e) +{ + if (d->items.isEmpty()) { + resizeContentArea(e->size()); + return; + } + + if ((d->zoomMode == ZoomFitWidth || d->zoomMode == ZoomFitAuto) && !verticalScrollBar()->isVisible() && qAbs(e->oldSize().height() - e->size().height()) < verticalScrollBar()->width() && d->verticalScrollBarVisible) { + // this saves us from infinite resizing loop because of scrollbars appearing and disappearing + // see bug 160628 for more info + // TODO looks are still a bit ugly because things are left uncentered + // but better a bit ugly than unusable + d->verticalScrollBarVisible = false; + resizeContentArea(e->size()); + return; + } else if (d->zoomMode == ZoomFitAuto && !horizontalScrollBar()->isVisible() && qAbs(e->oldSize().width() - e->size().width()) < horizontalScrollBar()->height() && d->horizontalScrollBarVisible) { + // this saves us from infinite resizing loop because of scrollbars appearing and disappearing + // TODO looks are still a bit ugly because things are left uncentered + // but better a bit ugly than unusable + d->horizontalScrollBarVisible = false; + resizeContentArea(e->size()); + return; + } + + // start a timer that will refresh the pixmap after 0.2s + d->delayResizeEventTimer->start(200); + d->verticalScrollBarVisible = verticalScrollBar()->isVisible(); + d->horizontalScrollBarVisible = horizontalScrollBar()->isVisible(); +} + +void PageView::keyPressEvent(QKeyEvent *e) +{ + e->accept(); + + // if performing a selection or dyn zooming, disable keys handling + if ((d->mouseSelecting && e->key() != Qt::Key_Escape) || (QApplication::mouseButtons() & Qt::MiddleButton)) + return; + + // move/scroll page by using keys + switch (e->key()) { + case Qt::Key_J: + case Qt::Key_Down: + slotScrollDown(1 /* go down 1 step */); + break; + + case Qt::Key_PageDown: + slotScrollDown(); + break; + + case Qt::Key_K: + case Qt::Key_Up: + slotScrollUp(1 /* go up 1 step */); + break; + + case Qt::Key_PageUp: + case Qt::Key_Backspace: + slotScrollUp(); + break; + + case Qt::Key_Left: + case Qt::Key_H: + if (horizontalScrollBar()->maximum() == 0) { + // if we cannot scroll we go to the previous page vertically + int next_page = d->document->currentPage() - viewColumns(); + d->document->setViewportPage(next_page); + } else { + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(-horizontalScrollBar()->singleStep(), 0), d->currentShortScrollDuration); + } + break; + case Qt::Key_Right: + case Qt::Key_L: + if (horizontalScrollBar()->maximum() == 0) { + // if we cannot scroll we advance the page vertically + int next_page = d->document->currentPage() + viewColumns(); + d->document->setViewportPage(next_page); + } else { + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(horizontalScrollBar()->singleStep(), 0), d->currentShortScrollDuration); + } + break; + case Qt::Key_Escape: + emit escPressed(); + selectionClear(d->tableDividersGuessed ? ClearOnlyDividers : ClearAllSelection); + d->mousePressPos = QPoint(); + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } + d->mouseAnnotation->routeKeyPressEvent(e); + break; + case Qt::Key_Delete: + d->mouseAnnotation->routeKeyPressEvent(e); + break; + case Qt::Key_Shift: + case Qt::Key_Control: + if (d->autoScrollTimer) { + if (d->autoScrollTimer->isActive()) + d->autoScrollTimer->stop(); + else + slotAutoScroll(); + return; + } + // fallthrough + default: + e->ignore(); + return; + } + // if a known key has been pressed, stop scrolling the page + if (d->autoScrollTimer) { + d->scrollIncrement = 0; + d->autoScrollTimer->stop(); + } +} + +void PageView::keyReleaseEvent(QKeyEvent *e) +{ + e->accept(); + + if (d->annotator && d->annotator->active()) { + if (d->annotator->routeKeyEvent(e)) + return; + } + + if (e->key() == Qt::Key_Escape && d->autoScrollTimer) { + d->scrollIncrement = 0; + d->autoScrollTimer->stop(); + } +} + +void PageView::inputMethodEvent(QInputMethodEvent *e) +{ + Q_UNUSED(e) +} + +void PageView::tabletEvent(QTabletEvent *e) +{ + // Ignore tablet events that we don't care about + if (!(e->type() == QEvent::TabletPress || e->type() == QEvent::TabletRelease || e->type() == QEvent::TabletMove)) { + e->ignore(); + return; + } + + // Determine pen state + bool penReleased = false; + if (e->type() == QEvent::TabletPress) { + d->penDown = true; + } + if (e->type() == QEvent::TabletRelease) { + d->penDown = false; + penReleased = true; + } + + // If we're editing an annotation and the tablet pen is either down or just released + // then dispatch event to annotator + if (d->annotator && d->annotator->active() && (d->penDown || penReleased)) { + // accept the event, otherwise it comes back as a mouse event + e->accept(); + + const QPoint eventPos = contentAreaPoint(e->pos()); + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + const QPoint localOriginInGlobal = mapToGlobal(QPoint(0, 0)); + + // routeTabletEvent will accept or ignore event as appropriate + d->annotator->routeTabletEvent(e, pageItem, localOriginInGlobal); + } else { + e->ignore(); + } +} + +void PageView::mouseMoveEvent(QMouseEvent *e) +{ + // For some reason in Qt 5.11.2 (no idea when this started) all wheel + // events are followed by mouse move events (without changing position), + // so we only actually reset the controlWheelAccumulatedDelta if there is a mouse movement + if (e->globalPos() != d->previousMouseMovePos) { + d->controlWheelAccumulatedDelta = 0; + } + d->previousMouseMovePos = e->globalPos(); + + // don't perform any mouse action when no document is shown + if (d->items.isEmpty()) + return; + + // if holding mouse mid button, perform zoom + if (e->buttons() & Qt::MiddleButton) { + int mouseY = e->globalPos().y(); + int deltaY = d->mouseMidLastY - mouseY; + + // wrap mouse from top to bottom + const QRect mouseContainer = QApplication::desktop()->screenGeometry(this); + const int absDeltaY = abs(deltaY); + if (absDeltaY > mouseContainer.height() / 2) { + deltaY = mouseContainer.height() - absDeltaY; + } + + const float upperZoomLimit = d->document->supportsTiles() ? 15.99 : 3.99; + if (mouseY <= mouseContainer.top() + 4 && d->zoomFactor < upperZoomLimit) { + mouseY = mouseContainer.bottom() - 5; + QCursor::setPos(e->globalPos().x(), mouseY); + } + // wrap mouse from bottom to top + else if (mouseY >= mouseContainer.bottom() - 4 && d->zoomFactor > 0.101) { + mouseY = mouseContainer.top() + 5; + QCursor::setPos(e->globalPos().x(), mouseY); + } + // remember last position + d->mouseMidLastY = mouseY; + + // update zoom level, perform zoom and redraw + if (deltaY) { + d->zoomFactor *= (1.0 + ((double)deltaY / 500.0)); + d->blockPixmapsRequest = true; + updateZoom(ZoomRefreshCurrent); + d->blockPixmapsRequest = false; + viewport()->update(); + } + return; + } + + const QPoint eventPos = contentAreaPoint(e->pos()); + + // if we're editing an annotation, dispatch event to it + if (d->annotator && d->annotator->active()) { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + updateCursor(eventPos); + d->annotator->routeMouseEvent(e, pageItem); + return; + } + + bool leftButton = (e->buttons() == Qt::LeftButton); + bool rightButton = (e->buttons() == Qt::RightButton); + + switch (d->mouseMode) { + case Okular::Settings::EnumMouseMode::Browse: { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + if (leftButton) { + d->leftClickTimer.stop(); + if (pageItem && d->mouseAnnotation->isActive()) { + // if left button pressed and annotation is focused, forward move event + d->mouseAnnotation->routeMouseMoveEvent(pageItem, eventPos, leftButton); + } + // drag page + else { + if (d->scroller->state() == QScroller::Inactive || d->scroller->state() == QScroller::Scrolling) { + d->mouseGrabOffset = QPoint(0, 0); + d->scroller->handleInput(QScroller::InputPress, e->pos(), e->timestamp() - 1); + } + + setCursor(Qt::ClosedHandCursor); + + QPoint mousePos = e->globalPos(); + + const QRect mouseContainer = QApplication::desktop()->screenGeometry(this); + + // wrap mouse from top to bottom + if (mousePos.y() <= mouseContainer.top() + 4 && verticalScrollBar()->value() < verticalScrollBar()->maximum() - 10) { + mousePos.setY(mouseContainer.bottom() - 5); + QCursor::setPos(mousePos); + d->mouseGrabOffset -= QPoint(0, mouseContainer.height()); + } + // wrap mouse from bottom to top + else if (mousePos.y() >= mouseContainer.bottom() - 4 && verticalScrollBar()->value() > 10) { + mousePos.setY(mouseContainer.top() + 5); + d->mouseGrabOffset += QPoint(0, mouseContainer.height()); + + QCursor::setPos(mousePos); + } + + d->scroller->handleInput(QScroller::InputMove, e->pos() + d->mouseGrabOffset, e->timestamp()); + } + } else if (rightButton && !d->mousePressPos.isNull() && d->aMouseSelect) { + // if mouse moves 5 px away from the press point, switch to 'selection' + int deltaX = d->mousePressPos.x() - e->globalPos().x(), deltaY = d->mousePressPos.y() - e->globalPos().y(); + if (deltaX > 5 || deltaX < -5 || deltaY > 5 || deltaY < -5) { + d->aPrevAction = d->aMouseNormal; + d->aMouseSelect->trigger(); + QPoint newPos = eventPos + QPoint(deltaX, deltaY); + selectionStart(newPos, palette().color(QPalette::Active, QPalette::Highlight).lighter(120), false); + updateSelection(eventPos); + break; + } + } else { + /* Forward move events which are still not yet consumed by "mouse grab" or aMouseSelect */ + d->mouseAnnotation->routeMouseMoveEvent(pageItem, eventPos, leftButton); + updateCursor(); + } + } break; + + case Okular::Settings::EnumMouseMode::Zoom: + case Okular::Settings::EnumMouseMode::RectSelect: + case Okular::Settings::EnumMouseMode::TableSelect: + case Okular::Settings::EnumMouseMode::TrimSelect: + // set second corner of selection + if (d->mouseSelecting) { + updateSelection(eventPos); + d->mouseOverLinkObject = nullptr; + } + updateCursor(); + break; + + case Okular::Settings::EnumMouseMode::Magnifier: + if (e->buttons()) // if any button is pressed at all + { + moveMagnifier(e->pos()); + updateMagnifier(eventPos); + } + break; + + case Okular::Settings::EnumMouseMode::TextSelect: + // if mouse moves 5 px away from the press point and the document supports text extraction, do 'textselection' + if (!d->mouseTextSelecting && !d->mousePressPos.isNull() && d->document->supportsSearching() && ((eventPos - d->mouseSelectPos).manhattanLength() > 5)) { + d->mouseTextSelecting = true; + } + updateSelection(eventPos); + updateCursor(); + break; + } +} + +void PageView::mousePressEvent(QMouseEvent *e) +{ + d->controlWheelAccumulatedDelta = 0; + + // don't perform any mouse action when no document is shown + if (d->items.isEmpty()) + return; + + // if performing a selection or dyn zooming, disable mouse press + if (d->mouseSelecting || (e->button() != Qt::MiddleButton && (e->buttons() & Qt::MiddleButton))) + return; + + // if the page is scrolling, stop it + if (d->autoScrollTimer) { + d->scrollIncrement = 0; + d->autoScrollTimer->stop(); + } + + // if pressing mid mouse button while not doing other things, begin 'continuous zoom' mode + if (e->button() == Qt::MiddleButton) { + d->mouseMidLastY = e->globalPos().y(); + setCursor(Qt::SizeVerCursor); + return; + } + + const QPoint eventPos = contentAreaPoint(e->pos()); + + // if we're editing an annotation, dispatch event to it + if (d->annotator && d->annotator->active()) { + d->scroller->stop(); + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + d->annotator->routeMouseEvent(e, pageItem); + return; + } + + // trigger history navigation for additional mouse buttons + if (e->button() == Qt::XButton1) { + emit mouseBackButtonClick(); + return; + } + if (e->button() == Qt::XButton2) { + emit mouseForwardButtonClick(); + return; + } + + // update press / 'start drag' mouse position + d->mousePressPos = e->globalPos(); + + // handle mode dependent mouse press actions + bool leftButton = e->button() == Qt::LeftButton, rightButton = e->button() == Qt::RightButton; + + // Not sure we should erase the selection when clicking with left. + if (d->mouseMode != Okular::Settings::EnumMouseMode::TextSelect) + textSelectionClear(); + + switch (d->mouseMode) { + case Okular::Settings::EnumMouseMode::Browse: // drag start / click / link following + { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + if (leftButton) { + if (pageItem) { + d->mouseAnnotation->routeMousePressEvent(pageItem, eventPos); + } + + if (!d->mouseOnRect) { + d->mouseGrabOffset = QPoint(0, 0); + d->scroller->handleInput(QScroller::InputPress, e->pos(), e->timestamp()); + d->leftClickTimer.start(QApplication::doubleClickInterval() + 10); + } + } + } break; + + case Okular::Settings::EnumMouseMode::Zoom: // set first corner of the zoom rect + if (leftButton) + selectionStart(eventPos, palette().color(QPalette::Active, QPalette::Highlight), false); + else if (rightButton) + updateZoom(ZoomOut); + break; + + case Okular::Settings::EnumMouseMode::Magnifier: + moveMagnifier(e->pos()); + d->magnifierView->show(); + updateMagnifier(eventPos); + break; + + case Okular::Settings::EnumMouseMode::RectSelect: // set first corner of the selection rect + case Okular::Settings::EnumMouseMode::TrimSelect: + if (leftButton) { + selectionStart(eventPos, palette().color(QPalette::Active, QPalette::Highlight).lighter(120), false); + } + break; + case Okular::Settings::EnumMouseMode::TableSelect: + if (leftButton) { + if (d->tableSelectionParts.isEmpty()) { + selectionStart(eventPos, palette().color(QPalette::Active, QPalette::Highlight).lighter(120), false); + } else { + QRect updatedRect; + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + QRect selectionPartRect = tsp.rectInItem.geometry(tsp.item->uncroppedWidth(), tsp.item->uncroppedHeight()); + selectionPartRect.translate(tsp.item->uncroppedGeometry().topLeft()); + + // This will update the whole table rather than just the added/removed divider + // (which can span more than one part). + updatedRect = updatedRect.united(selectionPartRect); + + if (!selectionPartRect.contains(eventPos)) + continue; + + // At this point it's clear we're either adding or removing a divider manually, so obviously the user is happy with the guess (if any). + d->tableDividersGuessed = false; + + // There's probably a neat trick to finding which edge it's closest to, + // but this way has the advantage of simplicity. + const int fromLeft = abs(selectionPartRect.left() - eventPos.x()); + const int fromRight = abs(selectionPartRect.left() + selectionPartRect.width() - eventPos.x()); + const int fromTop = abs(selectionPartRect.top() - eventPos.y()); + const int fromBottom = abs(selectionPartRect.top() + selectionPartRect.height() - eventPos.y()); + const int colScore = fromTop < fromBottom ? fromTop : fromBottom; + const int rowScore = fromLeft < fromRight ? fromLeft : fromRight; + + if (colScore < rowScore) { + bool deleted = false; + for (int i = 0; i < d->tableSelectionCols.length(); i++) { + const double col = (d->tableSelectionCols[i] - tsp.rectInSelection.left) / (tsp.rectInSelection.right - tsp.rectInSelection.left); + const int colX = selectionPartRect.left() + col * selectionPartRect.width() + 0.5; + if (abs(colX - eventPos.x()) <= 3) { + d->tableSelectionCols.removeAt(i); + deleted = true; + + break; + } + } + if (!deleted) { + double col = eventPos.x() - selectionPartRect.left(); + col /= selectionPartRect.width(); // at this point, it's normalised within the part + col *= (tsp.rectInSelection.right - tsp.rectInSelection.left); + col += tsp.rectInSelection.left; // at this point, it's normalised within the whole table + + d->tableSelectionCols.append(col); + std::sort(d->tableSelectionCols.begin(), d->tableSelectionCols.end()); + } + } else { + bool deleted = false; + for (int i = 0; i < d->tableSelectionRows.length(); i++) { + const double row = (d->tableSelectionRows[i] - tsp.rectInSelection.top) / (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + const int rowY = selectionPartRect.top() + row * selectionPartRect.height() + 0.5; + if (abs(rowY - eventPos.y()) <= 3) { + d->tableSelectionRows.removeAt(i); + deleted = true; + + break; + } + } + if (!deleted) { + double row = eventPos.y() - selectionPartRect.top(); + row /= selectionPartRect.height(); // at this point, it's normalised within the part + row *= (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + row += tsp.rectInSelection.top; // at this point, it's normalised within the whole table + + d->tableSelectionRows.append(row); + std::sort(d->tableSelectionRows.begin(), d->tableSelectionRows.end()); + } + } + } + updatedRect.translate(-contentAreaPosition()); + viewport()->update(updatedRect); + } + } + break; + case Okular::Settings::EnumMouseMode::TextSelect: + d->mouseSelectPos = eventPos; + if (!rightButton) { + textSelectionClear(); + } + break; + } +} + +void PageView::mouseReleaseEvent(QMouseEvent *e) +{ + d->controlWheelAccumulatedDelta = 0; + + // stop the drag scrolling + d->dragScrollTimer.stop(); + + d->leftClickTimer.stop(); + + const bool leftButton = e->button() == Qt::LeftButton; + const bool rightButton = e->button() == Qt::RightButton; + + if (d->mouseAnnotation->isActive() && leftButton) { + // Just finished to move the annotation + d->mouseAnnotation->routeMouseReleaseEvent(); + } + + // don't perform any mouse action when no document is shown.. + if (d->items.isEmpty()) { + // ..except for right Clicks (emitted even it viewport is empty) + if (e->button() == Qt::RightButton) + emit rightClick(nullptr, e->globalPos()); + return; + } + + const QPoint eventPos = contentAreaPoint(e->pos()); + + // handle mode independent mid bottom zoom + if (e->button() == Qt::MiddleButton) { + // request pixmaps since it was disabled during drag + slotRequestVisiblePixmaps(); + // the cursor may now be over a link.. update it + updateCursor(eventPos); + return; + } + + // if we're editing an annotation, dispatch event to it + if (d->annotator && d->annotator->active()) { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + d->annotator->routeMouseEvent(e, pageItem); + return; + } + + switch (d->mouseMode) { + case Okular::Settings::EnumMouseMode::Browse: { + d->scroller->handleInput(QScroller::InputRelease, e->pos() + d->mouseGrabOffset, e->timestamp()); + + // return the cursor to its normal state after dragging + if (cursor().shape() == Qt::ClosedHandCursor) + updateCursor(eventPos); + + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + const QPoint pressPos = contentAreaPoint(mapFromGlobal(d->mousePressPos)); + const PageViewItem *pageItemPressPos = pickItemOnPoint(pressPos.x(), pressPos.y()); + + // if the mouse has not moved since the press, that's a -click- + if (leftButton && pageItem && pageItem == pageItemPressPos && ((d->mousePressPos - e->globalPos()).manhattanLength() < QApplication::startDragDistance())) { + if (!mouseReleaseOverLink(d->mouseOverLinkObject) && (e->modifiers() == Qt::ShiftModifier)) { + const double nX = pageItem->absToPageX(eventPos.x()); + const double nY = pageItem->absToPageY(eventPos.y()); + const Okular::ObjectRect *rect; + // TODO: find a better way to activate the source reference "links" + // for the moment they are activated with Shift + left click + // Search the nearest source reference. + rect = pageItem->page()->objectRect(Okular::ObjectRect::SourceRef, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight()); + if (!rect) { + static const double s_minDistance = 0.025; // FIXME?: empirical value? + double distance = 0.0; + rect = pageItem->page()->nearestObjectRect(Okular::ObjectRect::SourceRef, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight(), &distance); + // distance is distanceSqr, adapt it to a normalized value + distance = distance / (pow(pageItem->uncroppedWidth(), 2) + pow(pageItem->uncroppedHeight(), 2)); + if (rect && (distance > s_minDistance)) + rect = nullptr; + } + if (rect) { + const Okular::SourceReference *ref = static_cast(rect->object()); + d->document->processSourceReference(ref); + } else { + const Okular::SourceReference *ref = d->document->dynamicSourceReference(pageItem->pageNumber(), nX * pageItem->page()->width(), nY * pageItem->page()->height()); + if (ref) { + d->document->processSourceReference(ref); + delete ref; + } + } + } +#if 0 + else + { + // a link can move us to another page or even to another document, there's no point in trying to + // process the click on the image once we have processes the click on the link + rect = pageItem->page()->objectRect( Okular::ObjectRect::Image, nX, nY, pageItem->width(), pageItem->height() ); + if ( rect ) + { + // handle click over a image + } +/* Enrico and me have decided this is not worth the trouble it generates + else + { + // if not on a rect, the click selects the page + // if ( pageItem->pageNumber() != (int)d->document->currentPage() ) + d->document->setViewportPage( pageItem->pageNumber(), this ); + }*/ + } +#endif + } else if (rightButton && !d->mouseAnnotation->isModified()) { + if (pageItem && pageItem == pageItemPressPos && ((d->mousePressPos - e->globalPos()).manhattanLength() < QApplication::startDragDistance())) { + QMenu *menu = createProcessLinkMenu(pageItem, eventPos); + + const QRect &itemRect = pageItem->uncroppedGeometry(); + const double nX = pageItem->absToPageX(eventPos.x()); + const double nY = pageItem->absToPageY(eventPos.y()); + + const QLinkedList annotRects = pageItem->page()->objectRects(Okular::ObjectRect::OAnnotation, nX, nY, itemRect.width(), itemRect.height()); + + AnnotationPopup annotPopup(d->document, AnnotationPopup::MultiAnnotationMode, this); + // Do not move annotPopup inside the if, it needs to live until menu->exec() + if (!annotRects.isEmpty()) { + for (const Okular::ObjectRect *annotRect : annotRects) { + Okular::Annotation *ann = ((Okular::AnnotationObjectRect *)annotRect)->annotation(); + if (ann && (ann->subType() != Okular::Annotation::AWidget)) { + annotPopup.addAnnotation(ann, pageItem->pageNumber()); + } + } + + connect(&annotPopup, &AnnotationPopup::openAnnotationWindow, this, &PageView::openAnnotationWindow); + + if (!menu) { + menu = new QMenu(this); + } + annotPopup.addActionsToMenu(menu); + } + + if (menu) { + menu->exec(e->globalPos()); + menu->deleteLater(); + } else { + // a link can move us to another page or even to another document, there's no point in trying to + // process the click on the image once we have processes the click on the link + const Okular::ObjectRect *rect = pageItem->page()->objectRect(Okular::ObjectRect::Image, nX, nY, itemRect.width(), itemRect.height()); + if (rect) { + // handle right click over a image + } else { + // right click (if not within 5 px of the press point, the mode + // had been already changed to 'Selection' instead of 'Normal') + emit rightClick(pageItem->page(), e->globalPos()); + } + } + } else { + // right click (if not within 5 px of the press point, the mode + // had been already changed to 'Selection' instead of 'Normal') + emit rightClick(pageItem ? pageItem->page() : nullptr, e->globalPos()); + } + } + } break; + + case Okular::Settings::EnumMouseMode::Zoom: + // if a selection rect has been defined, zoom into it + if (leftButton && d->mouseSelecting) { + QRect selRect = d->mouseSelectionRect.normalized(); + if (selRect.width() <= 8 && selRect.height() <= 8) { + selectionClear(); + break; + } + + // find out new zoom ratio and normalized view center (relative to the contentsRect) + double zoom = qMin((double)viewport()->width() / (double)selRect.width(), (double)viewport()->height() / (double)selRect.height()); + double nX = (double)(selRect.left() + selRect.right()) / (2.0 * (double)contentAreaWidth()); + double nY = (double)(selRect.top() + selRect.bottom()) / (2.0 * (double)contentAreaHeight()); + + const float upperZoomLimit = d->document->supportsTiles() ? 100.0 : 4.0; + if (d->zoomFactor <= upperZoomLimit || zoom <= 1.0) { + d->zoomFactor *= zoom; + viewport()->setUpdatesEnabled(false); + updateZoom(ZoomRefreshCurrent); + viewport()->setUpdatesEnabled(true); + } + + // recenter view and update the viewport + center((int)(nX * contentAreaWidth()), (int)(nY * contentAreaHeight())); + viewport()->update(); + + // hide message box and delete overlay window + selectionClear(); + } + break; + + case Okular::Settings::EnumMouseMode::Magnifier: + d->magnifierView->hide(); + break; + + case Okular::Settings::EnumMouseMode::TrimSelect: { + // if it is a left release checks if is over a previous link press + if (leftButton && mouseReleaseOverLink(d->mouseOverLinkObject)) { + selectionClear(); + break; + } + + // if mouse is released and selection is null this is a rightClick + if (rightButton && !d->mouseSelecting) { + break; + } + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + // ensure end point rests within a page, or ignore + if (!pageItem) { + break; + } + QRect selectionRect = d->mouseSelectionRect.normalized(); + + double nLeft = pageItem->absToPageX(selectionRect.left()); + double nRight = pageItem->absToPageX(selectionRect.right()); + double nTop = pageItem->absToPageY(selectionRect.top()); + double nBottom = pageItem->absToPageY(selectionRect.bottom()); + if (nLeft < 0) + nLeft = 0; + if (nTop < 0) + nTop = 0; + if (nRight > 1) + nRight = 1; + if (nBottom > 1) + nBottom = 1; + d->trimBoundingBox = Okular::NormalizedRect(nLeft, nTop, nRight, nBottom); + + // Trim Selection successfully done, hide prompt + d->messageWindow->hide(); + + // clear widget selection and invalidate rect + selectionClear(); + + // When Trim selection bbox interaction is over, we should switch to another mousemode. + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } else { + d->aMouseNormal->trigger(); + } + + // with d->trimBoundingBox defined, redraw for trim to take visual effect + if (d->document->pages() > 0) { + slotRelayoutPages(); + slotRequestVisiblePixmaps(); // TODO: slotRelayoutPages() may have done this already! + } + + break; + } + case Okular::Settings::EnumMouseMode::RectSelect: { + // if it is a left release checks if is over a previous link press + if (leftButton && mouseReleaseOverLink(d->mouseOverLinkObject)) { + selectionClear(); + break; + } + + // if mouse is released and selection is null this is a rightClick + if (rightButton && !d->mouseSelecting) { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + emit rightClick(pageItem ? pageItem->page() : nullptr, e->globalPos()); + break; + } + + // if a selection is defined, display a popup + if ((!leftButton && !d->aPrevAction) || (!rightButton && d->aPrevAction) || !d->mouseSelecting) + break; + + QRect selectionRect = d->mouseSelectionRect.normalized(); + if (selectionRect.width() <= 8 && selectionRect.height() <= 8) { + selectionClear(); + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } + break; + } + + // if we support text generation + QString selectedText; + if (d->document->supportsSearching()) { + // grab text in selection by extracting it from all intersected pages + const Okular::Page *okularPage = nullptr; + for (const PageViewItem *item : qAsConst(d->items)) { + if (!item->isVisible()) + continue; + + const QRect &itemRect = item->croppedGeometry(); + if (selectionRect.intersects(itemRect)) { + // request the textpage if there isn't one + okularPage = item->page(); + qCDebug(OkularUiDebug) << "checking if page" << item->pageNumber() << "has text:" << okularPage->hasTextPage(); + if (!okularPage->hasTextPage()) + d->document->requestTextPage(okularPage->number()); + // grab text in the rect that intersects itemRect + QRect relativeRect = selectionRect.intersected(itemRect); + relativeRect.translate(-item->uncroppedGeometry().topLeft()); + Okular::RegularAreaRect rects; + rects.append(Okular::NormalizedRect(relativeRect, item->uncroppedWidth(), item->uncroppedHeight())); + selectedText += okularPage->text(&rects); + } + } + } + + // popup that ask to copy:text and copy/save:image + QMenu menu(this); + menu.setObjectName(QStringLiteral("PopupMenu")); + QAction *textToClipboard = nullptr; +#ifdef HAVE_SPEECH + QAction *speakText = nullptr; +#endif + QAction *imageToClipboard = nullptr; + QAction *imageToFile = nullptr; + if (d->document->supportsSearching() && !selectedText.isEmpty()) { + menu.addAction(new OKMenuTitle(&menu, i18np("Text (1 character)", "Text (%1 characters)", selectedText.length()))); + textToClipboard = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy to Clipboard")); + textToClipboard->setObjectName(QStringLiteral("CopyTextToClipboard")); + bool copyAllowed = d->document->isAllowed(Okular::AllowCopy); + if (!copyAllowed) { + textToClipboard->setEnabled(false); + textToClipboard->setText(i18n("Copy forbidden by DRM")); + } +#ifdef HAVE_SPEECH + if (Okular::Settings::useTTS()) + speakText = menu.addAction(QIcon::fromTheme(QStringLiteral("text-speak")), i18n("Speak Text")); +#endif + if (copyAllowed) { + addSearchWithinDocumentAction(&menu, selectedText); + addWebShortcutsMenu(&menu, selectedText); + } + } + menu.addAction(new OKMenuTitle(&menu, i18n("Image (%1 by %2 pixels)", selectionRect.width(), selectionRect.height()))); + imageToClipboard = menu.addAction(QIcon::fromTheme(QStringLiteral("image-x-generic")), i18n("Copy to Clipboard")); + imageToFile = menu.addAction(QIcon::fromTheme(QStringLiteral("document-save")), i18n("Save to File...")); + QAction *choice = menu.exec(e->globalPos()); + // check if the user really selected an action + if (choice) { + // IMAGE operation chosen + if (choice == imageToClipboard || choice == imageToFile) { + // renders page into a pixmap + QPixmap copyPix(selectionRect.width(), selectionRect.height()); + QPainter copyPainter(©Pix); + copyPainter.translate(-selectionRect.left(), -selectionRect.top()); + drawDocumentOnPainter(selectionRect, ©Painter); + copyPainter.end(); + + if (choice == imageToClipboard) { + // [2] copy pixmap to clipboard + QClipboard *cb = QApplication::clipboard(); + cb->setPixmap(copyPix, QClipboard::Clipboard); + if (cb->supportsSelection()) + cb->setPixmap(copyPix, QClipboard::Selection); + d->messageWindow->display(i18n("Image [%1x%2] copied to clipboard.", copyPix.width(), copyPix.height())); + } else if (choice == imageToFile) { + // [3] save pixmap to file + QString fileName = QFileDialog::getSaveFileName(this, i18n("Save file"), QString(), i18n("Images (*.png *.jpeg)")); + if (fileName.isEmpty()) + d->messageWindow->display(i18n("File not saved."), QString(), PageViewMessage::Warning); + else { + QMimeDatabase db; + QMimeType mime = db.mimeTypeForUrl(QUrl::fromLocalFile(fileName)); + QString type; + if (!mime.isDefault()) + type = QStringLiteral("PNG"); + else + type = mime.name().section(QLatin1Char('/'), -1).toUpper(); + copyPix.save(fileName, qPrintable(type)); + d->messageWindow->display(i18n("Image [%1x%2] saved to %3 file.", copyPix.width(), copyPix.height(), type)); + } + } + } + // TEXT operation chosen + else { + if (choice == textToClipboard) { + // [1] copy text to clipboard + QClipboard *cb = QApplication::clipboard(); + cb->setText(selectedText, QClipboard::Clipboard); + if (cb->supportsSelection()) + cb->setText(selectedText, QClipboard::Selection); + } +#ifdef HAVE_SPEECH + else if (choice == speakText) { + // [2] speech selection using TTS + d->tts()->say(selectedText); + } +#endif + } + } + // clear widget selection and invalidate rect + selectionClear(); + + // restore previous action if came from it using right button + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } + } break; + + case Okular::Settings::EnumMouseMode::TableSelect: { + // if it is a left release checks if is over a previous link press + if (leftButton && mouseReleaseOverLink(d->mouseOverLinkObject)) { + selectionClear(); + break; + } + + // if mouse is released and selection is null this is a rightClick + if (rightButton && !d->mouseSelecting) { + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + emit rightClick(pageItem ? pageItem->page() : nullptr, e->globalPos()); + break; + } + + QRect selectionRect = d->mouseSelectionRect.normalized(); + if (selectionRect.width() <= 8 && selectionRect.height() <= 8 && d->tableSelectionParts.isEmpty()) { + selectionClear(); + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } + break; + } + + if (d->mouseSelecting) { + // break up the selection into page-relative pieces + d->tableSelectionParts.clear(); + const Okular::Page *okularPage = nullptr; + for (PageViewItem *item : qAsConst(d->items)) { + if (!item->isVisible()) + continue; + + const QRect &itemRect = item->croppedGeometry(); + if (selectionRect.intersects(itemRect)) { + // request the textpage if there isn't one + okularPage = item->page(); + qCDebug(OkularUiDebug) << "checking if page" << item->pageNumber() << "has text:" << okularPage->hasTextPage(); + if (!okularPage->hasTextPage()) + d->document->requestTextPage(okularPage->number()); + // grab text in the rect that intersects itemRect + QRect rectInItem = selectionRect.intersected(itemRect); + rectInItem.translate(-item->uncroppedGeometry().topLeft()); + QRect rectInSelection = selectionRect.intersected(itemRect); + rectInSelection.translate(-selectionRect.topLeft()); + d->tableSelectionParts.append( + TableSelectionPart(item, Okular::NormalizedRect(rectInItem, item->uncroppedWidth(), item->uncroppedHeight()), Okular::NormalizedRect(rectInSelection, selectionRect.width(), selectionRect.height()))); + } + } + + QRect updatedRect = d->mouseSelectionRect.normalized().adjusted(0, 0, 1, 1); + updatedRect.translate(-contentAreaPosition()); + d->mouseSelecting = false; + d->mouseSelectionRect.setCoords(0, 0, 0, 0); + d->tableSelectionCols.clear(); + d->tableSelectionRows.clear(); + guessTableDividers(); + viewport()->update(updatedRect); + } + + if (!d->document->isAllowed(Okular::AllowCopy)) { + d->messageWindow->display(i18n("Copy forbidden by DRM"), QString(), PageViewMessage::Info, -1); + break; + } + + QString selText; + QString selHtml; + QList xs = d->tableSelectionCols; + QList ys = d->tableSelectionRows; + xs.prepend(0.0); + xs.append(1.0); + ys.prepend(0.0); + ys.append(1.0); + selHtml = QString::fromLatin1( + "" + "" + ""); + for (int r = 0; r + 1 < ys.length(); r++) { + selHtml += QLatin1String(""); + for (int c = 0; c + 1 < xs.length(); c++) { + Okular::NormalizedRect cell(xs[c], ys[r], xs[c + 1], ys[r + 1]); + if (c) + selText += QLatin1Char('\t'); + QString txt; + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + // first, crop the cell to this part + if (!tsp.rectInSelection.intersects(cell)) + continue; + Okular::NormalizedRect cellPart = tsp.rectInSelection & cell; // intersection + + // second, convert it from table coordinates to part coordinates + cellPart.left -= tsp.rectInSelection.left; + cellPart.left /= (tsp.rectInSelection.right - tsp.rectInSelection.left); + cellPart.right -= tsp.rectInSelection.left; + cellPart.right /= (tsp.rectInSelection.right - tsp.rectInSelection.left); + cellPart.top -= tsp.rectInSelection.top; + cellPart.top /= (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + cellPart.bottom -= tsp.rectInSelection.top; + cellPart.bottom /= (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + + // third, convert from part coordinates to item coordinates + cellPart.left *= (tsp.rectInItem.right - tsp.rectInItem.left); + cellPart.left += tsp.rectInItem.left; + cellPart.right *= (tsp.rectInItem.right - tsp.rectInItem.left); + cellPart.right += tsp.rectInItem.left; + cellPart.top *= (tsp.rectInItem.bottom - tsp.rectInItem.top); + cellPart.top += tsp.rectInItem.top; + cellPart.bottom *= (tsp.rectInItem.bottom - tsp.rectInItem.top); + cellPart.bottom += tsp.rectInItem.top; + + // now get the text + Okular::RegularAreaRect rects; + rects.append(cellPart); + txt += tsp.item->page()->text(&rects, Okular::TextPage::CentralPixelTextAreaInclusionBehaviour); + } + QString html = txt; + selText += txt.replace(QLatin1Char('\n'), QLatin1Char(' ')); + html.replace(QLatin1Char('&'), QLatin1String("&")).replace(QLatin1Char('<'), QLatin1String("<")).replace(QLatin1Char('>'), QLatin1String(">")); + // Remove newlines, do not turn them into
, because + // Excel interprets
within cell as new cell... + html.replace(QLatin1Char('\n'), QLatin1String(" ")); + selHtml += QStringLiteral(""); + } + selText += QLatin1Char('\n'); + selHtml += QLatin1String("\n"); + } + selHtml += QLatin1String("
") + html + QStringLiteral("
\n"); + + QClipboard *cb = QApplication::clipboard(); + QMimeData *md = new QMimeData(); + md->setText(selText); + md->setHtml(selHtml); + cb->setMimeData(md, QClipboard::Clipboard); + if (cb->supportsSelection()) + cb->setMimeData(md, QClipboard::Selection); + + } break; + case Okular::Settings::EnumMouseMode::TextSelect: + // if it is a left release checks if is over a previous link press + if (leftButton && mouseReleaseOverLink(d->mouseOverLinkObject)) { + selectionClear(); + break; + } + + if (d->mouseTextSelecting) { + d->mouseTextSelecting = false; + // textSelectionClear(); + if (d->document->isAllowed(Okular::AllowCopy)) { + const QString text = d->selectedText(); + if (!text.isEmpty()) { + QClipboard *cb = QApplication::clipboard(); + if (cb->supportsSelection()) + cb->setText(text, QClipboard::Selection); + } + } + } else if (!d->mousePressPos.isNull() && rightButton) { + PageViewItem *item = pickItemOnPoint(eventPos.x(), eventPos.y()); + const Okular::Page *page; + // if there is text selected in the page + if (item) { + QAction *httpLink = nullptr; + QAction *textToClipboard = nullptr; + QString url; + + QMenu *menu = createProcessLinkMenu(item, eventPos); + const bool mouseClickOverLink = (menu != nullptr); +#ifdef HAVE_SPEECH + QAction *speakText = nullptr; +#endif + if ((page = item->page())->textSelection()) { + if (!menu) { + menu = new QMenu(this); + } + textToClipboard = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy Text")); + +#ifdef HAVE_SPEECH + if (Okular::Settings::useTTS()) + speakText = menu->addAction(QIcon::fromTheme(QStringLiteral("text-speak")), i18n("Speak Text")); +#endif + if (!d->document->isAllowed(Okular::AllowCopy)) { + textToClipboard->setEnabled(false); + textToClipboard->setText(i18n("Copy forbidden by DRM")); + } else { + addSearchWithinDocumentAction(menu, d->selectedText()); + addWebShortcutsMenu(menu, d->selectedText()); + } + + // if the right-click was over a link add "Follow This link" instead of "Go to" + if (!mouseClickOverLink) { + url = UrlUtils::getUrl(d->selectedText()); + if (!url.isEmpty()) { + const QString squeezedText = KStringHandler::rsqueeze(url, linkTextPreviewLength); + httpLink = menu->addAction(i18n("Go to '%1'", squeezedText)); + httpLink->setObjectName(QStringLiteral("GoToAction")); + } + } + } + + if (menu) { + menu->setObjectName(QStringLiteral("PopupMenu")); + + QAction *choice = menu->exec(e->globalPos()); + // check if the user really selected an action + if (choice) { + if (choice == textToClipboard) + copyTextSelection(); +#ifdef HAVE_SPEECH + else if (choice == speakText) { + const QString text = d->selectedText(); + d->tts()->say(text); + } +#endif + else if (choice == httpLink) { + new KRun(QUrl(url), this); + } + } + + menu->deleteLater(); + } + } + } + break; + } + + // reset mouse press / 'drag start' position + d->mousePressPos = QPoint(); +} + +void PageView::guessTableDividers() +{ + QList> colTicks, rowTicks, colSelectionTicks, rowSelectionTicks; + + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + // add ticks for the edges of this area... + colSelectionTicks.append(qMakePair(tsp.rectInSelection.left, +1)); + colSelectionTicks.append(qMakePair(tsp.rectInSelection.right, -1)); + rowSelectionTicks.append(qMakePair(tsp.rectInSelection.top, +1)); + rowSelectionTicks.append(qMakePair(tsp.rectInSelection.bottom, -1)); + + // get the words in this part + Okular::RegularAreaRect rects; + rects.append(tsp.rectInItem); + const Okular::TextEntity::List words = tsp.item->page()->words(&rects, Okular::TextPage::CentralPixelTextAreaInclusionBehaviour); + + for (const Okular::TextEntity *te : words) { + if (te->text().isEmpty()) { + delete te; + continue; + } + + Okular::NormalizedRect wordArea = *te->area(); + + // convert it from item coordinates to part coordinates + wordArea.left -= tsp.rectInItem.left; + wordArea.left /= (tsp.rectInItem.right - tsp.rectInItem.left); + wordArea.right -= tsp.rectInItem.left; + wordArea.right /= (tsp.rectInItem.right - tsp.rectInItem.left); + wordArea.top -= tsp.rectInItem.top; + wordArea.top /= (tsp.rectInItem.bottom - tsp.rectInItem.top); + wordArea.bottom -= tsp.rectInItem.top; + wordArea.bottom /= (tsp.rectInItem.bottom - tsp.rectInItem.top); + + // convert from part coordinates to table coordinates + wordArea.left *= (tsp.rectInSelection.right - tsp.rectInSelection.left); + wordArea.left += tsp.rectInSelection.left; + wordArea.right *= (tsp.rectInSelection.right - tsp.rectInSelection.left); + wordArea.right += tsp.rectInSelection.left; + wordArea.top *= (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + wordArea.top += tsp.rectInSelection.top; + wordArea.bottom *= (tsp.rectInSelection.bottom - tsp.rectInSelection.top); + wordArea.bottom += tsp.rectInSelection.top; + + // add to the ticks arrays... + colTicks.append(qMakePair(wordArea.left, +1)); + colTicks.append(qMakePair(wordArea.right, -1)); + rowTicks.append(qMakePair(wordArea.top, +1)); + rowTicks.append(qMakePair(wordArea.bottom, -1)); + + delete te; + } + } + + int tally = 0; + + std::sort(colSelectionTicks.begin(), colSelectionTicks.end()); + std::sort(rowSelectionTicks.begin(), rowSelectionTicks.end()); + + for (int i = 0; i < colSelectionTicks.length(); ++i) { + tally += colSelectionTicks[i].second; + if (tally == 0 && i + 1 < colSelectionTicks.length() && colSelectionTicks[i + 1].first != colSelectionTicks[i].first) { + colTicks.append(qMakePair(colSelectionTicks[i].first, +1)); + colTicks.append(qMakePair(colSelectionTicks[i + 1].first, -1)); + } + } + Q_ASSERT(tally == 0); + + for (int i = 0; i < rowSelectionTicks.length(); ++i) { + tally += rowSelectionTicks[i].second; + if (tally == 0 && i + 1 < rowSelectionTicks.length() && rowSelectionTicks[i + 1].first != rowSelectionTicks[i].first) { + rowTicks.append(qMakePair(rowSelectionTicks[i].first, +1)); + rowTicks.append(qMakePair(rowSelectionTicks[i + 1].first, -1)); + } + } + Q_ASSERT(tally == 0); + + std::sort(colTicks.begin(), colTicks.end()); + std::sort(rowTicks.begin(), rowTicks.end()); + + for (int i = 0; i < colTicks.length(); ++i) { + tally += colTicks[i].second; + if (tally == 0 && i + 1 < colTicks.length() && colTicks[i + 1].first != colTicks[i].first) { + d->tableSelectionCols.append((colTicks[i].first + colTicks[i + 1].first) / 2); + d->tableDividersGuessed = true; + } + } + Q_ASSERT(tally == 0); + + for (int i = 0; i < rowTicks.length(); ++i) { + tally += rowTicks[i].second; + if (tally == 0 && i + 1 < rowTicks.length() && rowTicks[i + 1].first != rowTicks[i].first) { + d->tableSelectionRows.append((rowTicks[i].first + rowTicks[i + 1].first) / 2); + d->tableDividersGuessed = true; + } + } + Q_ASSERT(tally == 0); +} + +void PageView::mouseDoubleClickEvent(QMouseEvent *e) +{ + d->controlWheelAccumulatedDelta = 0; + + if (e->button() == Qt::LeftButton) { + const QPoint eventPos = contentAreaPoint(e->pos()); + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + if (pageItem) { + // find out normalized mouse coords inside current item + double nX = pageItem->absToPageX(eventPos.x()); + double nY = pageItem->absToPageY(eventPos.y()); + + if (d->mouseMode == Okular::Settings::EnumMouseMode::TextSelect) { + textSelectionClear(); + + Okular::RegularAreaRect *wordRect = pageItem->page()->wordAt(Okular::NormalizedPoint(nX, nY)); + if (wordRect) { + // TODO words with hyphens across pages + d->document->setPageTextSelection(pageItem->pageNumber(), wordRect, palette().color(QPalette::Active, QPalette::Highlight)); + d->pagesWithTextSelection << pageItem->pageNumber(); + if (d->document->isAllowed(Okular::AllowCopy)) { + const QString text = d->selectedText(); + if (!text.isEmpty()) { + QClipboard *cb = QApplication::clipboard(); + if (cb->supportsSelection()) + cb->setText(text, QClipboard::Selection); + } + } + return; + } + } + + const QRect &itemRect = pageItem->uncroppedGeometry(); + Okular::Annotation *ann = nullptr; + const Okular::ObjectRect *orect = pageItem->page()->objectRect(Okular::ObjectRect::OAnnotation, nX, nY, itemRect.width(), itemRect.height()); + if (orect) + ann = ((Okular::AnnotationObjectRect *)orect)->annotation(); + if (ann && ann->subType() != Okular::Annotation::AWidget) { + openAnnotationWindow(ann, pageItem->pageNumber()); + } + } + } +} + +void PageView::wheelEvent(QWheelEvent *e) +{ + if (!d->document->isOpened()) { + QAbstractScrollArea::wheelEvent(e); + return; + } + + int delta = e->angleDelta().y(), vScroll = verticalScrollBar()->value(); + e->accept(); + if ((e->modifiers() & Qt::ControlModifier) == Qt::ControlModifier) { + d->controlWheelAccumulatedDelta += delta; + if (d->controlWheelAccumulatedDelta <= -QWheelEvent::DefaultDeltasPerStep) { + slotZoomOut(); + d->controlWheelAccumulatedDelta = 0; + } else if (d->controlWheelAccumulatedDelta >= QWheelEvent::DefaultDeltasPerStep) { + slotZoomIn(); + d->controlWheelAccumulatedDelta = 0; + } + } else { + d->controlWheelAccumulatedDelta = 0; + + if (delta <= -QWheelEvent::DefaultDeltasPerStep && !Okular::Settings::viewContinuous() && vScroll == verticalScrollBar()->maximum()) { + // go to next page + if ((int)d->document->currentPage() < d->items.count() - 1) { + // more optimized than document->setNextPage and then move view to top + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber += viewColumns(); + if (newViewport.pageNumber >= (int)d->items.count()) + newViewport.pageNumber = d->items.count() - 1; + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 0.0; + d->document->setViewport(newViewport); + d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar + } + } else if (delta >= QWheelEvent::DefaultDeltasPerStep && !Okular::Settings::viewContinuous() && vScroll == verticalScrollBar()->minimum()) { + // go to prev page + if (d->document->currentPage() > 0) { + // more optimized than document->setPrevPage and then move view to bottom + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber -= viewColumns(); + if (newViewport.pageNumber < 0) + newViewport.pageNumber = 0; + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 1.0; + d->document->setViewport(newViewport); + d->scroller->scrollTo(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), 0); // sync scroller with scrollbar + } + } else { + // When the shift key is held down, scroll ten times faster + int multiplier = e->modifiers() & Qt::ShiftModifier ? 10 : 1; + + if (delta != 0 && delta % QWheelEvent::DefaultDeltasPerStep == 0) { + // number of scroll wheel steps Qt gives to us at the same time + int count = abs(delta / QWheelEvent::DefaultDeltasPerStep) * multiplier; + if (delta < 0) { + slotScrollDown(count); + } else { + slotScrollUp(count); + } + } else { + d->scroller->scrollTo(d->scroller->finalPosition() - e->angleDelta() * multiplier / 4.0, 0); + } + } + } +} + +bool PageView::viewportEvent(QEvent *e) +{ + if (e->type() == QEvent::ToolTip + // Show tool tips only for those modes that change the cursor + // to a hand when hovering over the link. + && (d->mouseMode == Okular::Settings::EnumMouseMode::Browse || d->mouseMode == Okular::Settings::EnumMouseMode::RectSelect || d->mouseMode == Okular::Settings::EnumMouseMode::TextSelect || + d->mouseMode == Okular::Settings::EnumMouseMode::TrimSelect)) { + QHelpEvent *he = static_cast(e); + if (d->mouseAnnotation->isMouseOver()) { + d->mouseAnnotation->routeTooltipEvent(he); + } else { + const QPoint eventPos = contentAreaPoint(he->pos()); + PageViewItem *pageItem = pickItemOnPoint(eventPos.x(), eventPos.y()); + const Okular::ObjectRect *rect = nullptr; + const Okular::Action *link = nullptr; + if (pageItem) { + double nX = pageItem->absToPageX(eventPos.x()); + double nY = pageItem->absToPageY(eventPos.y()); + rect = pageItem->page()->objectRect(Okular::ObjectRect::Action, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight()); + if (rect) + link = static_cast(rect->object()); + } + + if (link) { + QRect r = rect->boundingRect(pageItem->uncroppedWidth(), pageItem->uncroppedHeight()); + r.translate(pageItem->uncroppedGeometry().topLeft()); + r.translate(-contentAreaPosition()); + QString tip = link->actionTip(); + if (!tip.isEmpty()) + QToolTip::showText(he->globalPos(), tip, viewport(), r); + } + } + e->accept(); + return true; + } else + // do not stop the event + return QAbstractScrollArea::viewportEvent(e); +} + +void PageView::scrollContentsBy(int dx, int dy) +{ + const QRect r = viewport()->rect(); + viewport()->scroll(dx, dy, r); + // HACK manually repaint the damaged regions, as it seems some updates are missed + // thus leaving artifacts around + QRegion rgn(r); + rgn -= rgn & r.translated(dx, dy); + + for (const QRect &rect : rgn) + viewport()->update(rect); + + updateCursor(); +} +// END widget events + +QList PageView::textSelections(const QPoint start, const QPoint end, int &firstpage) +{ + firstpage = -1; + QList ret; + QSet affectedItemsSet; + QRect selectionRect = QRect(start, end).normalized(); + for (const PageViewItem *item : qAsConst(d->items)) { + if (item->isVisible() && selectionRect.intersects(item->croppedGeometry())) + affectedItemsSet.insert(item->pageNumber()); + } +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << ">>>> item selected by mouse:" << affectedItemsSet.count(); +#endif + + if (!affectedItemsSet.isEmpty()) { + // is the mouse drag line the ne-sw diagonal of the selection rect? + bool direction_ne_sw = start == selectionRect.topRight() || start == selectionRect.bottomLeft(); + + int tmpmin = d->document->pages(); + int tmpmax = 0; + for (const int p : qAsConst(affectedItemsSet)) { + if (p < tmpmin) + tmpmin = p; + if (p > tmpmax) + tmpmax = p; + } + + PageViewItem *a = pickItemOnPoint((int)(direction_ne_sw ? selectionRect.right() : selectionRect.left()), (int)selectionRect.top()); + int min = a && (a->pageNumber() != tmpmax) ? a->pageNumber() : tmpmin; + PageViewItem *b = pickItemOnPoint((int)(direction_ne_sw ? selectionRect.left() : selectionRect.right()), (int)selectionRect.bottom()); + int max = b && (b->pageNumber() != tmpmin) ? b->pageNumber() : tmpmax; + + QList affectedItemsIds; + for (int i = min; i <= max; ++i) + affectedItemsIds.append(i); +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << ">>>> pages:" << affectedItemsIds; +#endif + firstpage = affectedItemsIds.first(); + + if (affectedItemsIds.count() == 1) { + PageViewItem *item = d->items[affectedItemsIds.first()]; + selectionRect.translate(-item->uncroppedGeometry().topLeft()); + ret.append(textSelectionForItem(item, direction_ne_sw ? selectionRect.topRight() : selectionRect.topLeft(), direction_ne_sw ? selectionRect.bottomLeft() : selectionRect.bottomRight())); + } else if (affectedItemsIds.count() > 1) { + // first item + PageViewItem *first = d->items[affectedItemsIds.first()]; + QRect geom = first->croppedGeometry().intersected(selectionRect).translated(-first->uncroppedGeometry().topLeft()); + ret.append(textSelectionForItem(first, selectionRect.bottom() > geom.height() ? (direction_ne_sw ? geom.topRight() : geom.topLeft()) : (direction_ne_sw ? geom.bottomRight() : geom.bottomLeft()), QPoint())); + // last item + PageViewItem *last = d->items[affectedItemsIds.last()]; + geom = last->croppedGeometry().intersected(selectionRect).translated(-last->uncroppedGeometry().topLeft()); + // the last item needs to appended at last... + Okular::RegularAreaRect *lastArea = + textSelectionForItem(last, QPoint(), selectionRect.bottom() > geom.height() ? (direction_ne_sw ? geom.bottomLeft() : geom.bottomRight()) : (direction_ne_sw ? geom.topLeft() : geom.topRight())); + affectedItemsIds.removeFirst(); + affectedItemsIds.removeLast(); + // item between the two above + for (const int page : qAsConst(affectedItemsIds)) { + ret.append(textSelectionForItem(d->items[page])); + } + ret.append(lastArea); + } + } + return ret; +} + +void PageView::drawDocumentOnPainter(const QRect contentsRect, QPainter *p) +{ + QColor backColor; + + if (Okular::Settings::useCustomBackgroundColor()) + backColor = Okular::Settings::backgroundColor(); + else + backColor = viewport()->palette().color(QPalette::Dark); + + // create a region from which we'll subtract painted rects + QRegion remainingArea(contentsRect); + + // This loop draws the actual pages + // iterate over all items painting the ones intersecting contentsRect + for (const PageViewItem *item : qAsConst(d->items)) { + // check if a piece of the page intersects the contents rect + if (!item->isVisible() || !item->croppedGeometry().intersects(contentsRect)) + continue; + + // get item and item's outline geometries + QRect itemGeometry = item->croppedGeometry(); + + // move the painter to the top-left corner of the real page + p->save(); + p->translate(itemGeometry.left(), itemGeometry.top()); + + // draw the page using the PagePainter with all flags active + if (contentsRect.intersects(itemGeometry)) { + Okular::NormalizedPoint *viewPortPoint = nullptr; + Okular::NormalizedPoint point(d->lastSourceLocationViewportNormalizedX, d->lastSourceLocationViewportNormalizedY); + if (Okular::Settings::showSourceLocationsGraphically() && item->pageNumber() == d->lastSourceLocationViewportPageNumber) { + viewPortPoint = &point; + } + QRect pixmapRect = contentsRect.intersected(itemGeometry); + pixmapRect.translate(-item->croppedGeometry().topLeft()); + PagePainter::paintCroppedPageOnPainter(p, item->page(), this, pageflags, item->uncroppedWidth(), item->uncroppedHeight(), pixmapRect, item->crop(), viewPortPoint); + } + + // remove painted area from 'remainingArea' and restore painter + remainingArea -= itemGeometry; + p->restore(); + } + + // fill the visible area around the page with the background color + for (const QRect &backRect : remainingArea) + p->fillRect(backRect, backColor); + + // take outline and shadow into account when testing whether a repaint is necessary + auto dpr = devicePixelRatioF(); + QRect checkRect = contentsRect; + checkRect.adjust(-3, -3, 1, 1); + + // Method to linearly interpolate between black (=(0,0,0), omitted) and the background color + auto interpolateColor = [&backColor](double t) { return QColor(t * backColor.red(), t * backColor.green(), t * backColor.blue()); }; + + // width of the shadow in device pixels + static const int shadowWidth = 2 * dpr; + + // iterate over all items painting a black outline and a simple bottom/right gradient + for (const PageViewItem *item : qAsConst(d->items)) { + // check if a piece of the page intersects the contents rect + if (!item->isVisible() || !item->croppedGeometry().intersects(checkRect)) + continue; + + // get item and item's outline geometries + QRect itemGeometry = item->croppedGeometry(); + + // move the painter to the top-left corner of the real page + p->save(); + p->translate(itemGeometry.left(), itemGeometry.top()); + + // draw the page outline (black border and bottom-right shadow) + if (!itemGeometry.contains(contentsRect)) { + int itemWidth = itemGeometry.width(); + int itemHeight = itemGeometry.height(); + // draw simple outline + QPen pen(Qt::black); + pen.setWidth(0); + p->setPen(pen); + + QRectF outline(-1.0 / dpr, -1.0 / dpr, itemWidth + 1.0 / dpr, itemHeight + 1.0 / dpr); + p->drawRect(outline); + + // draw bottom/right gradient + for (int i = 1; i <= shadowWidth; i++) { + pen.setColor(interpolateColor(double(i) / (shadowWidth + 1))); + p->setPen(pen); + QPointF left((i - 1) / dpr, itemHeight + i / dpr); + QPointF up(itemWidth + i / dpr, (i - 1) / dpr); + QPointF corner(itemWidth + i / dpr, itemHeight + i / dpr); + p->drawLine(left, corner); + p->drawLine(up, corner); + } + } + + p->restore(); + } +} + +void PageView::updateItemSize(PageViewItem *item, int colWidth, int rowHeight) +{ + const Okular::Page *okularPage = item->page(); + double width = okularPage->width(), height = okularPage->height(), zoom = d->zoomFactor; + Okular::NormalizedRect crop(0., 0., 1., 1.); + + // Handle cropping, due to either "Trim Margin" or "Trim to Selection" cases + if ((Okular::Settings::trimMargins() && okularPage->isBoundingBoxKnown() && !okularPage->boundingBox().isNull()) || (d->aTrimToSelection && d->aTrimToSelection->isChecked() && !d->trimBoundingBox.isNull())) { + crop = Okular::Settings::trimMargins() ? okularPage->boundingBox() : d->trimBoundingBox; + + // Rotate the bounding box + for (int i = okularPage->rotation(); i > 0; --i) { + Okular::NormalizedRect rot = crop; + crop.left = 1 - rot.bottom; + crop.top = rot.left; + crop.right = 1 - rot.top; + crop.bottom = rot.right; + } + + // Expand the crop slightly beyond the bounding box (for Trim Margins only) + if (Okular::Settings::trimMargins()) { + static const double cropExpandRatio = 0.04; + const double cropExpand = cropExpandRatio * ((crop.right - crop.left) + (crop.bottom - crop.top)) / 2; + crop = Okular::NormalizedRect(crop.left - cropExpand, crop.top - cropExpand, crop.right + cropExpand, crop.bottom + cropExpand) & Okular::NormalizedRect(0, 0, 1, 1); + } + + // We currently generate a larger image and then crop it, so if the + // crop rect is very small the generated image is huge. Hence, we shouldn't + // let the crop rect become too small. + static double minCropRatio; + if (Okular::Settings::trimMargins()) { + // Make sure we crop by at most 50% in either dimension: + minCropRatio = 0.5; + } else { + // Looser Constraint for "Trim Selection" + minCropRatio = 0.20; + } + if ((crop.right - crop.left) < minCropRatio) { + const double newLeft = (crop.left + crop.right) / 2 - minCropRatio / 2; + crop.left = qMax(0.0, qMin(1.0 - minCropRatio, newLeft)); + crop.right = crop.left + minCropRatio; + } + if ((crop.bottom - crop.top) < minCropRatio) { + const double newTop = (crop.top + crop.bottom) / 2 - minCropRatio / 2; + crop.top = qMax(0.0, qMin(1.0 - minCropRatio, newTop)); + crop.bottom = crop.top + minCropRatio; + } + + width *= (crop.right - crop.left); + height *= (crop.bottom - crop.top); +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug) << "Cropped page" << okularPage->number() << "to" << crop << "width" << width << "height" << height << "by bbox" << okularPage->boundingBox(); +#endif + } + + if (d->zoomMode == ZoomFixed) { + width *= zoom; + height *= zoom; + item->setWHZC((int)width, (int)height, d->zoomFactor, crop); + } else if (d->zoomMode == ZoomFitWidth) { + height = (height / width) * colWidth; + zoom = (double)colWidth / width; + item->setWHZC(colWidth, (int)height, zoom, crop); + if ((uint)item->pageNumber() == d->document->currentPage()) + d->zoomFactor = zoom; + } else if (d->zoomMode == ZoomFitPage) { + const double scaleW = (double)colWidth / (double)width; + const double scaleH = (double)rowHeight / (double)height; + zoom = qMin(scaleW, scaleH); + item->setWHZC((int)(zoom * width), (int)(zoom * height), zoom, crop); + if ((uint)item->pageNumber() == d->document->currentPage()) + d->zoomFactor = zoom; + } else if (d->zoomMode == ZoomFitAuto) { + const double aspectRatioRelation = 1.25; // relation between aspect ratios for "auto fit" + const double uiAspect = (double)rowHeight / (double)colWidth; + const double pageAspect = (double)height / (double)width; + const double rel = uiAspect / pageAspect; + + const bool isContinuous = Okular::Settings::viewContinuous(); + if (!isContinuous && rel > aspectRatioRelation) { + // UI space is relatively much higher than the page + zoom = (double)rowHeight / (double)height; + } else if (rel < 1.0 / aspectRatioRelation) { + // UI space is relatively much wider than the page in relation + zoom = (double)colWidth / (double)width; + } else { + // aspect ratios of page and UI space are very similar + const double scaleW = (double)colWidth / (double)width; + const double scaleH = (double)rowHeight / (double)height; + zoom = qMin(scaleW, scaleH); + } + item->setWHZC((int)(zoom * width), (int)(zoom * height), zoom, crop); + if ((uint)item->pageNumber() == d->document->currentPage()) + d->zoomFactor = zoom; + } +#ifndef NDEBUG + else + qCDebug(OkularUiDebug) << "calling updateItemSize with unrecognized d->zoomMode!"; +#endif +} + +PageViewItem *PageView::pickItemOnPoint(int x, int y) +{ + PageViewItem *item = nullptr; + for (PageViewItem *i : qAsConst(d->visibleItems)) { + const QRect &r = i->croppedGeometry(); + if (x < r.right() && x > r.left() && y < r.bottom()) { + if (y > r.top()) + item = i; + break; + } + } + return item; +} + +void PageView::textSelectionClear() +{ + // something to clear + if (!d->pagesWithTextSelection.isEmpty()) { + for (const int page : qAsConst(d->pagesWithTextSelection)) + d->document->setPageTextSelection(page, nullptr, QColor()); + d->pagesWithTextSelection.clear(); + } +} + +void PageView::selectionStart(const QPoint pos, const QColor &color, bool /*aboveAll*/) +{ + selectionClear(); + d->mouseSelecting = true; + d->mouseSelectionRect.setRect(pos.x(), pos.y(), 1, 1); + d->mouseSelectionColor = color; + // ensures page doesn't scroll + if (d->autoScrollTimer) { + d->scrollIncrement = 0; + d->autoScrollTimer->stop(); + } +} + +void PageView::scrollPosIntoView(const QPoint pos) +{ + // this number slows the speed of the page by its value, chosen not to be too fast or too slow, the actual speed is determined from the mouse position, not critical + const int damping = 6; + + if (pos.x() < horizontalScrollBar()->value()) + d->dragScrollVector.setX((pos.x() - horizontalScrollBar()->value()) / damping); + else if (horizontalScrollBar()->value() + viewport()->width() < pos.x()) + d->dragScrollVector.setX((pos.x() - horizontalScrollBar()->value() - viewport()->width()) / damping); + else + d->dragScrollVector.setX(0); + + if (pos.y() < verticalScrollBar()->value()) + d->dragScrollVector.setY((pos.y() - verticalScrollBar()->value()) / damping); + else if (verticalScrollBar()->value() + viewport()->height() < pos.y()) + d->dragScrollVector.setY((pos.y() - verticalScrollBar()->value() - viewport()->height()) / damping); + else + d->dragScrollVector.setY(0); + + if (d->dragScrollVector != QPoint(0, 0)) { + if (!d->dragScrollTimer.isActive()) + d->dragScrollTimer.start(1000 / 60); // 60 fps + } else + d->dragScrollTimer.stop(); +} + +QPoint PageView::viewportToContentArea(const Okular::DocumentViewport &vp) const +{ + Q_ASSERT(vp.pageNumber >= 0); + + const QRect &r = d->items[vp.pageNumber]->croppedGeometry(); + QPoint c {r.left(), r.top()}; + + if (vp.rePos.enabled) { + if (vp.rePos.pos == Okular::DocumentViewport::Center) { + c.rx() += qRound(normClamp(vp.rePos.normalizedX, 0.5) * (double)r.width()); + c.ry() += qRound(normClamp(vp.rePos.normalizedY, 0.0) * (double)r.height()); + } else { + // TopLeft + c.rx() += qRound(normClamp(vp.rePos.normalizedX, 0.0) * (double)r.width() + viewport()->width() / 2.0); + c.ry() += qRound(normClamp(vp.rePos.normalizedY, 0.0) * (double)r.height() + viewport()->height() / 2.0); + } + } else { + // exact repositioning disabled, align page top margin with viewport top border by default + c.rx() += r.width() / 2; + c.ry() += viewport()->height() / 2 - 10; + } + return c; +} + +void PageView::updateSelection(const QPoint pos) +{ + if (d->mouseSelecting) { + scrollPosIntoView(pos); + // update the selection rect + QRect updateRect = d->mouseSelectionRect; + d->mouseSelectionRect.setBottomLeft(pos); + updateRect |= d->mouseSelectionRect; + updateRect.translate(-contentAreaPosition()); + viewport()->update(updateRect.adjusted(-1, -2, 2, 1)); + } else if (d->mouseTextSelecting) { + scrollPosIntoView(pos); + int first = -1; + const QList selections = textSelections(pos, d->mouseSelectPos, first); + QSet pagesWithSelectionSet; + for (int i = 0; i < selections.count(); ++i) + pagesWithSelectionSet.insert(i + first); + + const QSet noMoreSelectedPages = d->pagesWithTextSelection - pagesWithSelectionSet; + // clear the selection from pages not selected anymore + for (int p : noMoreSelectedPages) { + d->document->setPageTextSelection(p, nullptr, QColor()); + } + // set the new selection for the selected pages + for (int p : qAsConst(pagesWithSelectionSet)) { + d->document->setPageTextSelection(p, selections[p - first], palette().color(QPalette::Active, QPalette::Highlight)); + } + d->pagesWithTextSelection = pagesWithSelectionSet; + } +} + +static Okular::NormalizedPoint rotateInNormRect(const QPoint rotated, const QRect rect, Okular::Rotation rotation) +{ + Okular::NormalizedPoint ret; + + switch (rotation) { + case Okular::Rotation0: + ret = Okular::NormalizedPoint(rotated.x(), rotated.y(), rect.width(), rect.height()); + break; + case Okular::Rotation90: + ret = Okular::NormalizedPoint(rotated.y(), rect.width() - rotated.x(), rect.height(), rect.width()); + break; + case Okular::Rotation180: + ret = Okular::NormalizedPoint(rect.width() - rotated.x(), rect.height() - rotated.y(), rect.width(), rect.height()); + break; + case Okular::Rotation270: + ret = Okular::NormalizedPoint(rect.height() - rotated.y(), rotated.x(), rect.height(), rect.width()); + break; + } + + return ret; +} + +Okular::RegularAreaRect *PageView::textSelectionForItem(const PageViewItem *item, const QPoint startPoint, const QPoint endPoint) +{ + const QRect &geometry = item->uncroppedGeometry(); + Okular::NormalizedPoint startCursor(0.0, 0.0); + if (!startPoint.isNull()) { + startCursor = rotateInNormRect(startPoint, geometry, item->page()->rotation()); + } + Okular::NormalizedPoint endCursor(1.0, 1.0); + if (!endPoint.isNull()) { + endCursor = rotateInNormRect(endPoint, geometry, item->page()->rotation()); + } + Okular::TextSelection mouseTextSelectionInfo(startCursor, endCursor); + + const Okular::Page *okularPage = item->page(); + + if (!okularPage->hasTextPage()) + d->document->requestTextPage(okularPage->number()); + + Okular::RegularAreaRect *selectionArea = okularPage->textArea(&mouseTextSelectionInfo); +#ifdef PAGEVIEW_DEBUG + qCDebug(OkularUiDebug).nospace() << "text areas (" << okularPage->number() << "): " << (selectionArea ? QString::number(selectionArea->count()) : "(none)"); +#endif + return selectionArea; +} + +void PageView::selectionClear(const ClearMode mode) +{ + QRect updatedRect = d->mouseSelectionRect.normalized().adjusted(-2, -2, 2, 2); + d->mouseSelecting = false; + d->mouseSelectionRect.setCoords(0, 0, 0, 0); + d->tableSelectionCols.clear(); + d->tableSelectionRows.clear(); + d->tableDividersGuessed = false; + for (const TableSelectionPart &tsp : qAsConst(d->tableSelectionParts)) { + QRect selectionPartRect = tsp.rectInItem.geometry(tsp.item->uncroppedWidth(), tsp.item->uncroppedHeight()); + selectionPartRect.translate(tsp.item->uncroppedGeometry().topLeft()); + // should check whether this is on-screen here? + updatedRect = updatedRect.united(selectionPartRect); + } + if (mode != ClearOnlyDividers) { + d->tableSelectionParts.clear(); + } + d->tableSelectionParts.clear(); + updatedRect.translate(-contentAreaPosition()); + viewport()->update(updatedRect); +} + +// const to be used for both zoomFactorFitMode function and slotRelayoutPages. +static const int kcolWidthMargin = 6; +static const int krowHeightMargin = 12; + +double PageView::zoomFactorFitMode(ZoomMode mode) +{ + const int pageCount = d->items.count(); + if (pageCount == 0) + return 0; + const bool facingCentered = Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::FacingFirstCentered || (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Facing && pageCount == 1); + const bool overrideCentering = facingCentered && pageCount < 3; + const int nCols = overrideCentering ? 1 : viewColumns(); + const int colWidth = viewport()->width() / nCols - kcolWidthMargin; + const double rowHeight = viewport()->height() - krowHeightMargin; + const PageViewItem *currentItem = d->items[qMax(0, (int)d->document->currentPage())]; + // prevent segmentation fault when opening a new document; + if (!currentItem) + return 0; + const Okular::Page *okularPage = currentItem->page(); + const double width = okularPage->width(), height = okularPage->height(); + if (mode == ZoomFitWidth) + return (double)colWidth / width; + if (mode == ZoomFitPage) { + const double scaleW = (double)colWidth / (double)width; + const double scaleH = (double)rowHeight / (double)height; + return qMin(scaleW, scaleH); + } + return 0; +} + +void PageView::updateZoom(ZoomMode newZoomMode) +{ + if (newZoomMode == ZoomFixed) { + if (d->aZoom->currentItem() == 0) + newZoomMode = ZoomFitWidth; + else if (d->aZoom->currentItem() == 1) + newZoomMode = ZoomFitPage; + else if (d->aZoom->currentItem() == 2) + newZoomMode = ZoomFitAuto; + } + + float newFactor = d->zoomFactor; + QAction *checkedZoomAction = nullptr; + switch (newZoomMode) { + case ZoomFixed: { // ZoomFixed case + QString z = d->aZoom->currentText(); + // kdelibs4 sometimes adds accelerators to actions' text directly :( + z.remove(QLatin1Char('&')); + z.remove(QLatin1Char('%')); + newFactor = QLocale().toDouble(z) / 100.0; + } break; + case ZoomIn: + case ZoomOut: { + const float zoomFactorFitWidth = zoomFactorFitMode(ZoomFitWidth); + const float zoomFactorFitPage = zoomFactorFitMode(ZoomFitPage); + + QVector zoomValue(kZoomValues.size()); + + std::copy(kZoomValues.begin(), kZoomValues.end(), zoomValue.begin()); + zoomValue.append(zoomFactorFitWidth); + zoomValue.append(zoomFactorFitPage); + std::sort(zoomValue.begin(), zoomValue.end()); + + QVector::iterator i; + if (newZoomMode == ZoomOut) { + if (newFactor <= zoomValue.first()) + return; + i = std::lower_bound(zoomValue.begin(), zoomValue.end(), newFactor) - 1; + } else { + if (newFactor >= zoomValue.last()) + return; + i = std::upper_bound(zoomValue.begin(), zoomValue.end(), newFactor); + } + const float tmpFactor = *i; + if (tmpFactor == zoomFactorFitWidth) { + newZoomMode = ZoomFitWidth; + checkedZoomAction = d->aZoomFitWidth; + } else if (tmpFactor == zoomFactorFitPage) { + newZoomMode = ZoomFitPage; + checkedZoomAction = d->aZoomFitPage; + } else { + newFactor = tmpFactor; + newZoomMode = ZoomFixed; + } + } break; + case ZoomActual: + newZoomMode = ZoomFixed; + newFactor = 1.0; + break; + case ZoomFitWidth: + checkedZoomAction = d->aZoomFitWidth; + break; + case ZoomFitPage: + checkedZoomAction = d->aZoomFitPage; + break; + case ZoomFitAuto: + checkedZoomAction = d->aZoomAutoFit; + break; + case ZoomRefreshCurrent: + newZoomMode = ZoomFixed; + d->zoomFactor = -1; + break; + } + const float upperZoomLimit = d->document->supportsTiles() ? 100.0 : 4.0; + if (newFactor > upperZoomLimit) + newFactor = upperZoomLimit; + if (newFactor < 0.1) + newFactor = 0.1; + + if (newZoomMode != d->zoomMode || (newZoomMode == ZoomFixed && newFactor != d->zoomFactor)) { + // rebuild layout and update the whole viewport + d->zoomMode = newZoomMode; + d->zoomFactor = newFactor; + // be sure to block updates to document's viewport + bool prevState = d->blockViewport; + d->blockViewport = true; + slotRelayoutPages(); + d->blockViewport = prevState; + // request pixmaps + slotRequestVisiblePixmaps(); + // update zoom text + updateZoomText(); + // update actions checked state + if (d->aZoomFitWidth) { + d->aZoomFitWidth->setChecked(checkedZoomAction == d->aZoomFitWidth); + d->aZoomFitPage->setChecked(checkedZoomAction == d->aZoomFitPage); + d->aZoomAutoFit->setChecked(checkedZoomAction == d->aZoomAutoFit); + } + } else if (newZoomMode == ZoomFixed && newFactor == d->zoomFactor) + updateZoomText(); + + d->aZoomIn->setEnabled(d->zoomFactor < upperZoomLimit - 0.001); + d->aZoomOut->setEnabled(d->zoomFactor > 0.101); + d->aZoomActual->setEnabled(d->zoomFactor != 1.0); +} + +void PageView::updateZoomText() +{ + // use current page zoom as zoomFactor if in ZoomFit/* mode + if (d->zoomMode != ZoomFixed && d->items.count() > 0) + d->zoomFactor = d->items[qMax(0, (int)d->document->currentPage())]->zoomFactor(); + float newFactor = d->zoomFactor; + d->aZoom->removeAllActions(); + + // add items that describe fit actions + QStringList translated; + translated << i18n("Fit Width") << i18n("Fit Page") << i18n("Auto Fit"); + + // add percent items + int idx = 0, selIdx = 3; + bool inserted = false; // use: "d->zoomMode != ZoomFixed" to hide Fit/* zoom ratio + int zoomValueCount = 11; + if (d->document->supportsTiles()) + zoomValueCount = kZoomValues.size(); + while (idx < zoomValueCount || !inserted) { + float value = idx < zoomValueCount ? kZoomValues[idx] : newFactor; + if (!inserted && newFactor < (value - 0.0001)) + value = newFactor; + else + idx++; + if (value > (newFactor - 0.0001) && value < (newFactor + 0.0001)) + inserted = true; + if (!inserted) + selIdx++; + // we do not need to display 2-digit precision + QString localValue(QLocale().toString(value * 100.0, 'f', 1)); + localValue.remove(QLocale().decimalPoint() + QLatin1Char('0')); + // remove a trailing zero in numbers like 66.70 + if (localValue.right(1) == QLatin1String("0") && localValue.indexOf(QLocale().decimalPoint()) > -1) + localValue.chop(1); + translated << QStringLiteral("%1%").arg(localValue); + } + d->aZoom->setItems(translated); + + // select current item in list + if (d->zoomMode == ZoomFitWidth) + selIdx = 0; + else if (d->zoomMode == ZoomFitPage) + selIdx = 1; + else if (d->zoomMode == ZoomFitAuto) + selIdx = 2; + // we have to temporarily enable the actions as otherwise we can't set a new current item + d->aZoom->setEnabled(true); + d->aZoom->selectableActionGroup()->setEnabled(true); + d->aZoom->setCurrentItem(selIdx); + d->aZoom->setEnabled(d->items.size() > 0); + d->aZoom->selectableActionGroup()->setEnabled(d->items.size() > 0); +} + +void PageView::updateViewMode(const int nr) +{ + const QList actions = d->viewModeActionGroup->actions(); + for (QAction *action : actions) { + QVariant mode_id = action->data(); + if (mode_id.toInt() == nr) { + action->trigger(); + } + } +} + +void PageView::updateCursor() +{ + const QPoint p = contentAreaPosition() + viewport()->mapFromGlobal(QCursor::pos()); + updateCursor(p); +} + +void PageView::updateCursor(const QPoint p) +{ + // reset mouse over link it will be re-set if that still valid + d->mouseOverLinkObject = nullptr; + + // detect the underlaying page (if present) + PageViewItem *pageItem = pickItemOnPoint(p.x(), p.y()); + QScroller::State scrollerState = d->scroller->state(); + + if (d->annotator && d->annotator->active()) { + if (pageItem || d->annotator->annotating()) + setCursor(d->annotator->cursor()); + else + setCursor(Qt::ForbiddenCursor); + } else if (scrollerState == QScroller::Pressed || scrollerState == QScroller::Dragging) { + setCursor(Qt::ClosedHandCursor); + } else if (pageItem) { + double nX = pageItem->absToPageX(p.x()); + double nY = pageItem->absToPageY(p.y()); + Qt::CursorShape cursorShapeFallback; + + // if over a ObjectRect (of type Link) change cursor to hand + switch (d->mouseMode) { + case Okular::Settings::EnumMouseMode::TextSelect: + if (d->mouseTextSelecting) { + setCursor(Qt::IBeamCursor); + return; + } + cursorShapeFallback = Qt::IBeamCursor; + break; + case Okular::Settings::EnumMouseMode::Magnifier: + setCursor(Qt::CrossCursor); + return; + case Okular::Settings::EnumMouseMode::RectSelect: + case Okular::Settings::EnumMouseMode::TrimSelect: + if (d->mouseSelecting) { + setCursor(Qt::CrossCursor); + return; + } + cursorShapeFallback = Qt::CrossCursor; + break; + case Okular::Settings::EnumMouseMode::Browse: + d->mouseOnRect = false; + if (d->mouseAnnotation->isMouseOver()) { + d->mouseOnRect = true; + setCursor(d->mouseAnnotation->cursor()); + return; + } else { + cursorShapeFallback = Qt::OpenHandCursor; + } + break; + default: + setCursor(Qt::ArrowCursor); + return; + } + + const Okular::ObjectRect *linkobj = pageItem->page()->objectRect(Okular::ObjectRect::Action, nX, nY, pageItem->uncroppedWidth(), pageItem->uncroppedHeight()); + if (linkobj) { + d->mouseOverLinkObject = linkobj; + d->mouseOnRect = true; + setCursor(Qt::PointingHandCursor); + } else { + setCursor(cursorShapeFallback); + } + } else { + // if there's no page over the cursor and we were showing the pointingHandCursor + // go back to the normal one + d->mouseOnRect = false; + setCursor(Qt::ArrowCursor); + } +} + +void PageView::reloadForms() +{ + if (d->m_formsVisible) { + for (PageViewItem *item : qAsConst(d->visibleItems)) { + item->reloadFormWidgetsState(); + } + } +} + +void PageView::moveMagnifier(const QPoint p) // non scaled point +{ + const int w = d->magnifierView->width() * 0.5; + const int h = d->magnifierView->height() * 0.5; + + int x = p.x() - w; + int y = p.y() - h; + + const int max_x = viewport()->width(); + const int max_y = viewport()->height(); + + QPoint scroll(0, 0); + + if (x < 0) { + if (horizontalScrollBar()->value() > 0) + scroll.setX(x - w); + x = 0; + } + + if (y < 0) { + if (verticalScrollBar()->value() > 0) + scroll.setY(y - h); + y = 0; + } + + if (p.x() + w > max_x) { + if (horizontalScrollBar()->value() < horizontalScrollBar()->maximum()) + scroll.setX(p.x() + 2 * w - max_x); + x = max_x - d->magnifierView->width() - 1; + } + + if (p.y() + h > max_y) { + if (verticalScrollBar()->value() < verticalScrollBar()->maximum()) + scroll.setY(p.y() + 2 * h - max_y); + y = max_y - d->magnifierView->height() - 1; + } + + if (!scroll.isNull()) + scrollPosIntoView(contentAreaPoint(p + scroll)); + + d->magnifierView->move(x, y); +} + +void PageView::updateMagnifier(const QPoint p) // scaled point +{ + /* translate mouse coordinates to page coordinates and inform the magnifier of the situation */ + PageViewItem *item = pickItemOnPoint(p.x(), p.y()); + if (item) { + Okular::NormalizedPoint np(item->absToPageX(p.x()), item->absToPageY(p.y())); + d->magnifierView->updateView(np, item->page()); + } +} + +int PageView::viewColumns() const +{ + int vm = Okular::Settings::viewMode(); + if (vm == Okular::Settings::EnumViewMode::Single) + return 1; + else if (vm == Okular::Settings::EnumViewMode::Facing || vm == Okular::Settings::EnumViewMode::FacingFirstCentered) + return 2; + else if (vm == Okular::Settings::EnumViewMode::Summary && d->document->pages() < Okular::Settings::viewColumns()) + return d->document->pages(); + else + return Okular::Settings::viewColumns(); +} + +void PageView::center(int cx, int cy, bool smoothMove) +{ + scrollTo(cx - viewport()->width() / 2, cy - viewport()->height() / 2, smoothMove); +} + +void PageView::scrollTo(int x, int y, bool smoothMove) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + // Workaround for QTBUG-88288, (KDE bug 425188): To avoid a crash in QScroller, + // we need to make sure the target widget intersects a physical screen. + // QScroller queries QDesktopWidget::screenNumber(). + + // If we are not on a physical screen, we try to make our widget big enough. + // The geometry will be restored to a sensible value once the Part is shown. + + // It should be enough to add this workaround ony in PageView::scrollTo(), + // because we don’t expect other QScroller::scrollTo() calls before PageView is shown. + if (QApplication::desktop()->screenNumber(this) < 0) { + setGeometry(QRect(-1000, -1000, 5000, 5000).united(QApplication::desktop()->availableGeometry())); + } +#endif + + bool prevState = d->blockPixmapsRequest; + + int newValue = -1; + if (x != horizontalScrollBar()->value() || y != verticalScrollBar()->value()) + newValue = 1; // Pretend this call is the result of a scrollbar event + + d->blockPixmapsRequest = true; + + if (smoothMove) + d->scroller->scrollTo(QPoint(x, y), d->currentLongScrollDuration); + else + d->scroller->scrollTo(QPoint(x, y), 0); + + d->blockPixmapsRequest = prevState; + + slotRequestVisiblePixmaps(newValue); +} + +void PageView::toggleFormWidgets(bool on) +{ + bool somehadfocus = false; + for (PageViewItem *item : qAsConst(d->items)) { + const bool hadfocus = item->setFormWidgetsVisible(on); + somehadfocus = somehadfocus || hadfocus; + } + if (somehadfocus) + setFocus(); + d->m_formsVisible = on; +} + +void PageView::resizeContentArea(const QSize newSize) +{ + const QSize vs = viewport()->size(); + int hRange = newSize.width() - vs.width(); + int vRange = newSize.height() - vs.height(); + if (horizontalScrollBar()->isVisible() && hRange == verticalScrollBar()->width() && verticalScrollBar()->isVisible() && vRange == horizontalScrollBar()->height() && Okular::Settings::showScrollBars()) { + hRange = 0; + vRange = 0; + } + horizontalScrollBar()->setRange(0, hRange); + verticalScrollBar()->setRange(0, vRange); + updatePageStep(); +} + +void PageView::updatePageStep() +{ + const QSize vs = viewport()->size(); + horizontalScrollBar()->setPageStep(vs.width()); + verticalScrollBar()->setPageStep(vs.height() * (100 - Okular::Settings::scrollOverlap()) / 100); +} + +void PageView::addWebShortcutsMenu(QMenu *menu, const QString &text) +{ + if (text.isEmpty()) { + return; + } + + QString searchText = text; + searchText = searchText.replace(QLatin1Char('\n'), QLatin1Char(' ')).replace(QLatin1Char('\r'), QLatin1Char(' ')).simplified(); + + if (searchText.isEmpty()) { + return; + } + + KUriFilterData filterData(searchText); + + filterData.setSearchFilteringOptions(KUriFilterData::RetrievePreferredSearchProvidersOnly); + + if (KUriFilter::self()->filterSearchUri(filterData, KUriFilter::NormalTextFilter)) { + const QStringList searchProviders = filterData.preferredSearchProviders(); + + if (!searchProviders.isEmpty()) { + QMenu *webShortcutsMenu = new QMenu(menu); + webShortcutsMenu->setIcon(QIcon::fromTheme(QStringLiteral("preferences-web-browser-shortcuts"))); + + const QString squeezedText = KStringHandler::rsqueeze(searchText, searchTextPreviewLength); + webShortcutsMenu->setTitle(i18n("Search for '%1' with", squeezedText)); + + QAction *action = nullptr; + + for (const QString &searchProvider : searchProviders) { + action = new QAction(searchProvider, webShortcutsMenu); + action->setIcon(QIcon::fromTheme(filterData.iconNameForPreferredSearchProvider(searchProvider))); + action->setData(filterData.queryForPreferredSearchProvider(searchProvider)); + connect(action, &QAction::triggered, this, &PageView::slotHandleWebShortcutAction); + webShortcutsMenu->addAction(action); + } + + webShortcutsMenu->addSeparator(); + + action = new QAction(i18n("Configure Web Shortcuts..."), webShortcutsMenu); + action->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + connect(action, &QAction::triggered, this, &PageView::slotConfigureWebShortcuts); + webShortcutsMenu->addAction(action); + + menu->addMenu(webShortcutsMenu); + } + } +} + +QMenu *PageView::createProcessLinkMenu(PageViewItem *item, const QPoint eventPos) +{ + // check if the right-click was over a link + const double nX = item->absToPageX(eventPos.x()); + const double nY = item->absToPageY(eventPos.y()); + const Okular::ObjectRect *rect = item->page()->objectRect(Okular::ObjectRect::Action, nX, nY, item->uncroppedWidth(), item->uncroppedHeight()); + if (rect) { + const Okular::Action *link = static_cast(rect->object()); + + if (!link) + return nullptr; + + QMenu *menu = new QMenu(this); + + // creating the menu and its actions + QAction *processLink = menu->addAction(i18n("Follow This Link")); + processLink->setObjectName(QStringLiteral("ProcessLinkAction")); + if (link->actionType() == Okular::Action::Sound) { + processLink->setText(i18n("Play this Sound")); + if (Okular::AudioPlayer::instance()->state() == Okular::AudioPlayer::PlayingState) { + QAction *actStopSound = menu->addAction(i18n("Stop Sound")); + connect(actStopSound, &QAction::triggered, []() { Okular::AudioPlayer::instance()->stopPlaybacks(); }); + } + } + + if (dynamic_cast(link)) { + QAction *actCopyLinkLocation = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy Link Address")); + actCopyLinkLocation->setObjectName(QStringLiteral("CopyLinkLocationAction")); + connect(actCopyLinkLocation, &QAction::triggered, menu, [link]() { + const Okular::BrowseAction *browseLink = static_cast(link); + QClipboard *cb = QApplication::clipboard(); + cb->setText(browseLink->url().toDisplayString(), QClipboard::Clipboard); + if (cb->supportsSelection()) + cb->setText(browseLink->url().toDisplayString(), QClipboard::Selection); + }); + } + + connect(processLink, &QAction::triggered, this, [this, link]() { d->document->processAction(link); }); + return menu; + } + return nullptr; +} + +void PageView::addSearchWithinDocumentAction(QMenu *menu, const QString &searchText) +{ + const QString squeezedText = KStringHandler::rsqueeze(searchText, searchTextPreviewLength); + QAction *action = new QAction(i18n("Search for '%1' in this document", squeezedText), menu); + action->setIcon(QIcon::fromTheme(QStringLiteral("document-preview"))); + connect(action, &QAction::triggered, this, [this, searchText] { Q_EMIT triggerSearch(searchText); }); + menu->addAction(action); +} + +void PageView::updateSmoothScrollAnimationSpeed() +{ + // If it's turned off in Okular's own settings, don't bother to look at the + // global settings + if (!Okular::Settings::smoothScrolling()) { + d->currentShortScrollDuration = 0; + d->currentLongScrollDuration = 0; + return; + } + + // If we are using smooth scrolling, scale the speed of the animated + // transitions according to the global animation speed setting + KConfigGroup kdeglobalsConfig = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("KDE")); + const qreal globalAnimationScale = qMax(0.0, kdeglobalsConfig.readEntry("AnimationDurationFactor", 1.0)); + d->currentShortScrollDuration = d->baseShortScrollDuration * globalAnimationScale; + d->currentLongScrollDuration = d->baseLongScrollDuration * globalAnimationScale; +} + +// BEGIN private SLOTS +void PageView::slotRelayoutPages() +// called by: notifySetup, viewportResizeEvent, slotViewMode, slotContinuousToggled, updateZoom +{ + // set an empty container if we have no pages + const int pageCount = d->items.count(); + if (pageCount < 1) { + return; + } + + int viewportWidth = viewport()->width(), viewportHeight = viewport()->height(), fullWidth = 0, fullHeight = 0; + + // handle the 'center first page in row' stuff + const bool facing = Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Facing && pageCount > 1; + const bool facingCentered = Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::FacingFirstCentered || (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Facing && pageCount == 1); + const bool overrideCentering = facingCentered && pageCount < 3; + const bool centerFirstPage = facingCentered && !overrideCentering; + const bool facingPages = facing || centerFirstPage; + const bool centerLastPage = centerFirstPage && pageCount % 2 == 0; + const bool continuousView = Okular::Settings::viewContinuous(); + const int nCols = overrideCentering ? 1 : viewColumns(); + const bool singlePageViewMode = Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Single; + + if (d->aFitWindowToPage) + d->aFitWindowToPage->setEnabled(!continuousView && singlePageViewMode); + + // set all items geometry and resize contents. handle 'continuous' and 'single' modes separately + + PageViewItem *currentItem = d->items[qMax(0, (int)d->document->currentPage())]; + + // Here we find out column's width and row's height to compute a table + // so we can place widgets 'centered in virtual cells'. + const int nRows = (int)ceil((float)(centerFirstPage ? (pageCount + nCols - 1) : pageCount) / (float)nCols); + + int *colWidth = new int[nCols], *rowHeight = new int[nRows], cIdx = 0, rIdx = 0; + for (int i = 0; i < nCols; i++) + colWidth[i] = viewportWidth / nCols; + for (int i = 0; i < nRows; i++) + rowHeight[i] = 0; + // handle the 'centering on first row' stuff + if (centerFirstPage) + cIdx += nCols - 1; + + // 1) find the maximum columns width and rows height for a grid in + // which each page must well-fit inside a cell + for (PageViewItem *item : qAsConst(d->items)) { + // update internal page size (leaving a little margin in case of Fit* modes) + updateItemSize(item, colWidth[cIdx] - kcolWidthMargin, viewportHeight - krowHeightMargin); + // find row's maximum height and column's max width + if (item->croppedWidth() + kcolWidthMargin > colWidth[cIdx]) + colWidth[cIdx] = item->croppedWidth() + kcolWidthMargin; + if (item->croppedHeight() + krowHeightMargin > rowHeight[rIdx]) + rowHeight[rIdx] = item->croppedHeight() + krowHeightMargin; + // handle the 'centering on first row' stuff + // update col/row indices + if (++cIdx == nCols) { + cIdx = 0; + rIdx++; + } + } + + const int pageRowIdx = ((centerFirstPage ? nCols - 1 : 0) + currentItem->pageNumber()) / nCols; + + // 2) compute full size + for (int i = 0; i < nCols; i++) + fullWidth += colWidth[i]; + if (continuousView) { + for (int i = 0; i < nRows; i++) + fullHeight += rowHeight[i]; + } else + fullHeight = rowHeight[pageRowIdx]; + + // 3) arrange widgets inside cells (and refine fullHeight if needed) + int insertX = 0, insertY = fullHeight < viewportHeight ? (viewportHeight - fullHeight) / 2 : 0; + const int origInsertY = insertY; + cIdx = 0; + rIdx = 0; + if (centerFirstPage) { + cIdx += nCols - 1; + for (int i = 0; i < cIdx; ++i) + insertX += colWidth[i]; + } + for (PageViewItem *item : qAsConst(d->items)) { + int cWidth = colWidth[cIdx], rHeight = rowHeight[rIdx]; + if (continuousView || rIdx == pageRowIdx) { + const bool reallyDoCenterFirst = item->pageNumber() == 0 && centerFirstPage; + const bool reallyDoCenterLast = item->pageNumber() == pageCount - 1 && centerLastPage; + int actualX = 0; + if (reallyDoCenterFirst || reallyDoCenterLast) { + // page is centered across entire viewport + actualX = (fullWidth - item->croppedWidth()) / 2; + } else if (facingPages) { + 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; + 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); + item->setVisible(true); + } else { + item->moveTo(0, 0); + item->setVisible(false); + } + item->setFormWidgetsVisible(d->m_formsVisible); + // advance col/row index + insertX += cWidth; + if (++cIdx == nCols) { + cIdx = 0; + rIdx++; + insertX = 0; + insertY += rHeight; + } +#ifdef PAGEVIEW_DEBUG + kWarning() << "updating size for pageno" << item->pageNumber() << "cropped" << item->croppedGeometry() << "uncropped" << item->uncroppedGeometry(); +#endif + } + + delete[] colWidth; + delete[] rowHeight; + + // 3) reset dirty state + d->dirtyLayout = false; + + // 4) update scrollview's contents size and recenter view + bool wasUpdatesEnabled = viewport()->updatesEnabled(); + if (fullWidth != contentAreaWidth() || fullHeight != contentAreaHeight()) { + const Okular::DocumentViewport vp = d->document->viewport(); + // disable updates and resize the viewportContents + if (wasUpdatesEnabled) + viewport()->setUpdatesEnabled(false); + resizeContentArea(QSize(fullWidth, fullHeight)); + // restore previous viewport if defined and updates enabled + if (wasUpdatesEnabled) { + if (vp.pageNumber >= 0) { + int prevX = horizontalScrollBar()->value(), prevY = verticalScrollBar()->value(); + + const QPoint centerPos = viewportToContentArea(vp); + center(centerPos.x(), centerPos.y()); + + // center() usually moves the viewport, that requests pixmaps too. + // if that doesn't happen we have to request them by hand + if (prevX == horizontalScrollBar()->value() && prevY == verticalScrollBar()->value()) + slotRequestVisiblePixmaps(); + } + // or else go to center page + else + center(fullWidth / 2, 0); + viewport()->setUpdatesEnabled(true); + } + } + + // 5) update the whole viewport if updated enabled + if (wasUpdatesEnabled) + viewport()->update(); +} + +void PageView::delayedResizeEvent() +{ + // If we already got here we don't need to execute the timer slot again + d->delayResizeEventTimer->stop(); + slotRelayoutPages(); + slotRequestVisiblePixmaps(); +} + +static void slotRequestPreloadPixmap(Okular::DocumentObserver *observer, const PageViewItem *i, const QRect expandedViewportRect, QLinkedList *requestedPixmaps) +{ + Okular::NormalizedRect preRenderRegion; + const QRect intersectionRect = expandedViewportRect.intersected(i->croppedGeometry()); + if (!intersectionRect.isEmpty()) + preRenderRegion = Okular::NormalizedRect(intersectionRect.translated(-i->uncroppedGeometry().topLeft()), i->uncroppedWidth(), i->uncroppedHeight()); + + // request the pixmap if not already present + if (!i->page()->hasPixmap(observer, i->uncroppedWidth(), i->uncroppedHeight(), preRenderRegion) && i->uncroppedWidth() > 0) { + Okular::PixmapRequest::PixmapRequestFeatures requestFeatures = Okular::PixmapRequest::Preload; + requestFeatures |= Okular::PixmapRequest::Asynchronous; + const bool pageHasTilesManager = i->page()->hasTilesManager(observer); + if (pageHasTilesManager && !preRenderRegion.isNull()) { + Okular::PixmapRequest *p = new Okular::PixmapRequest(observer, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRELOAD_PRIO, requestFeatures); + requestedPixmaps->push_back(p); + + p->setNormalizedRect(preRenderRegion); + p->setTile(true); + } else if (!pageHasTilesManager) { + Okular::PixmapRequest *p = new Okular::PixmapRequest(observer, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRELOAD_PRIO, requestFeatures); + requestedPixmaps->push_back(p); + p->setNormalizedRect(preRenderRegion); + } + } +} + +void PageView::slotRequestVisiblePixmaps(int newValue) +{ + // if requests are blocked (because raised by an unwanted event), exit + if (d->blockPixmapsRequest) + return; + + // precalc view limits for intersecting with page coords inside the loop + const bool isEvent = newValue != -1 && !d->blockViewport; + const QRect viewportRect(horizontalScrollBar()->value(), verticalScrollBar()->value(), viewport()->width(), viewport()->height()); + const QRect viewportRectAtZeroZero(0, 0, viewport()->width(), viewport()->height()); + + // some variables used to determine the viewport + int nearPageNumber = -1; + const double viewportCenterX = (viewportRect.left() + viewportRect.right()) / 2.0; + const double viewportCenterY = (viewportRect.top() + viewportRect.bottom()) / 2.0; + double focusedX = 0.5, focusedY = 0.0, minDistance = -1.0; + // Margin (in pixels) around the viewport to preload + const int pixelsToExpand = 512; + + // iterate over all items + d->visibleItems.clear(); + QLinkedList requestedPixmaps; + QVector visibleRects; + for (PageViewItem *i : qAsConst(d->items)) { + const QSet formWidgetsList = i->formWidgets(); + for (FormWidgetIface *fwi : formWidgetsList) { + Okular::NormalizedRect r = fwi->rect(); + fwi->moveTo(qRound(i->uncroppedGeometry().left() + i->uncroppedWidth() * r.left) + 1 - viewportRect.left(), qRound(i->uncroppedGeometry().top() + i->uncroppedHeight() * r.top) + 1 - viewportRect.top()); + } + const QHash videoWidgets = i->videoWidgets(); + for (VideoWidget *vw : videoWidgets) { + const Okular::NormalizedRect r = vw->normGeometry(); + vw->move(qRound(i->uncroppedGeometry().left() + i->uncroppedWidth() * r.left) + 1 - viewportRect.left(), qRound(i->uncroppedGeometry().top() + i->uncroppedHeight() * r.top) + 1 - viewportRect.top()); + + if (vw->isPlaying() && viewportRectAtZeroZero.intersected(vw->geometry()).isEmpty()) { + vw->stop(); + vw->pageLeft(); + } + } + + if (!i->isVisible()) + continue; +#ifdef PAGEVIEW_DEBUG + kWarning() << "checking page" << i->pageNumber(); + kWarning().nospace() << "viewportRect is " << viewportRect << ", page item is " << i->croppedGeometry() << " intersect : " << viewportRect.intersects(i->croppedGeometry()); +#endif + // if the item doesn't intersect the viewport, skip it + QRect intersectionRect = viewportRect.intersected(i->croppedGeometry()); + if (intersectionRect.isEmpty()) { + continue; + } + + // add the item to the 'visible list' + d->visibleItems.push_back(i); + Okular::VisiblePageRect *vItem = new Okular::VisiblePageRect(i->pageNumber(), Okular::NormalizedRect(intersectionRect.translated(-i->uncroppedGeometry().topLeft()), i->uncroppedWidth(), i->uncroppedHeight())); + visibleRects.push_back(vItem); +#ifdef PAGEVIEW_DEBUG + kWarning() << "checking for pixmap for page" << i->pageNumber() << "=" << i->page()->hasPixmap(this, i->uncroppedWidth(), i->uncroppedHeight()); + kWarning() << "checking for text for page" << i->pageNumber() << "=" << i->page()->hasTextPage(); +#endif + + Okular::NormalizedRect expandedVisibleRect = vItem->rect; + if (i->page()->hasTilesManager(this) && Okular::Settings::memoryLevel() != Okular::Settings::EnumMemoryLevel::Low) { + double rectMargin = pixelsToExpand / (double)i->uncroppedHeight(); + expandedVisibleRect.left = qMax(0.0, vItem->rect.left - rectMargin); + expandedVisibleRect.top = qMax(0.0, vItem->rect.top - rectMargin); + expandedVisibleRect.right = qMin(1.0, vItem->rect.right + rectMargin); + expandedVisibleRect.bottom = qMin(1.0, vItem->rect.bottom + rectMargin); + } + + // if the item has not the right pixmap, add a request for it + if (!i->page()->hasPixmap(this, i->uncroppedWidth(), i->uncroppedHeight(), expandedVisibleRect)) { +#ifdef PAGEVIEW_DEBUG + kWarning() << "rerequesting visible pixmaps for page" << i->pageNumber() << "!"; +#endif + Okular::PixmapRequest *p = new Okular::PixmapRequest(this, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, Okular::PixmapRequest::Asynchronous); + requestedPixmaps.push_back(p); + + if (i->page()->hasTilesManager(this)) { + p->setNormalizedRect(expandedVisibleRect); + p->setTile(true); + } else + p->setNormalizedRect(vItem->rect); + } + + // look for the item closest to viewport center and the relative + // position between the item and the viewport center + if (isEvent) { + const QRect &geometry = i->croppedGeometry(); + // compute distance between item center and viewport center (slightly moved left) + const double distance = hypot((geometry.left() + geometry.right()) / 2.0 - (viewportCenterX - 4), (geometry.top() + geometry.bottom()) / 2.0 - viewportCenterY); + if (distance >= minDistance && nearPageNumber != -1) + continue; + nearPageNumber = i->pageNumber(); + minDistance = distance; + if (geometry.height() > 0 && geometry.width() > 0) { + focusedX = (viewportCenterX - (double)geometry.left()) / (double)geometry.width(); + focusedY = (viewportCenterY - (double)geometry.top()) / (double)geometry.height(); + } + } + } + + // if preloading is enabled, add the pages before and after in preloading + if (!d->visibleItems.isEmpty() && Okular::SettingsCore::memoryLevel() != Okular::SettingsCore::EnumMemoryLevel::Low) { + // as the requests are done in the order as they appear in the list, + // request first the next page and then the previous + + int pagesToPreload = viewColumns(); + + // if the greedy option is set, preload all pages + if (Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Greedy) + pagesToPreload = d->items.count(); + + const QRect expandedViewportRect = viewportRect.adjusted(0, -pixelsToExpand, 0, pixelsToExpand); + + for (int j = 1; j <= pagesToPreload; j++) { + // add the page after the 'visible series' in preload + const int tailRequest = d->visibleItems.last()->pageNumber() + j; + if (tailRequest < (int)d->items.count()) { + slotRequestPreloadPixmap(this, d->items[tailRequest], expandedViewportRect, &requestedPixmaps); + } + + // add the page before the 'visible series' in preload + const int headRequest = d->visibleItems.first()->pageNumber() - j; + if (headRequest >= 0) { + slotRequestPreloadPixmap(this, d->items[headRequest], expandedViewportRect, &requestedPixmaps); + } + + // stop if we've already reached both ends of the document + if (headRequest < 0 && tailRequest >= (int)d->items.count()) + break; + } + } + + // send requests to the document + if (!requestedPixmaps.isEmpty()) { + d->document->requestPixmaps(requestedPixmaps); + } + // if this functions was invoked by viewport events, send update to document + if (isEvent && nearPageNumber != -1) { + // determine the document viewport + Okular::DocumentViewport newViewport(nearPageNumber); + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedX = focusedX; + newViewport.rePos.normalizedY = focusedY; + // set the viewport to other observers + // do not update history if the viewport is autoscrolling + d->document->setViewportWithHistory(newViewport, this, false, d->scroller->state() != QScroller::Scrolling); + } + d->document->setVisiblePageRects(visibleRects, this); +} + +void PageView::slotAutoScroll() +{ + // the first time create the timer + if (!d->autoScrollTimer) { + d->autoScrollTimer = new QTimer(this); + d->autoScrollTimer->setSingleShot(true); + connect(d->autoScrollTimer, &QTimer::timeout, this, &PageView::slotAutoScroll); + } + + // if scrollIncrement is zero, stop the timer + if (!d->scrollIncrement) { + d->autoScrollTimer->stop(); + return; + } + + // compute delay between timer ticks and scroll amount per tick + int index = abs(d->scrollIncrement) - 1; // 0..9 + const int scrollDelay[10] = {200, 100, 50, 30, 20, 30, 25, 20, 30, 20}; + const int scrollOffset[10] = {1, 1, 1, 1, 1, 2, 2, 2, 4, 4}; + d->autoScrollTimer->start(scrollDelay[index]); + int delta = d->scrollIncrement > 0 ? scrollOffset[index] : -scrollOffset[index]; + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(0, delta), scrollDelay[index]); +} + +void PageView::slotDragScroll() +{ + scrollTo(horizontalScrollBar()->value() + d->dragScrollVector.x(), verticalScrollBar()->value() + d->dragScrollVector.y()); + QPoint p = contentAreaPosition() + viewport()->mapFromGlobal(QCursor::pos()); + updateSelection(p); +} + +void PageView::slotShowWelcome() +{ + // show initial welcome text + d->messageWindow->display(i18n("Welcome"), QString(), PageViewMessage::Info, 2000); +} + +void PageView::slotShowSizeAllCursor() +{ + setCursor(Qt::SizeAllCursor); +} + +void PageView::slotHandleWebShortcutAction() +{ + QAction *action = qobject_cast(sender()); + + if (action) { + KUriFilterData filterData(action->data().toString()); + + if (KUriFilter::self()->filterSearchUri(filterData, KUriFilter::WebShortcutFilter)) { + QDesktopServices::openUrl(filterData.uri()); + } + } +} + +void PageView::slotConfigureWebShortcuts() +{ + KToolInvocation::kdeinitExec(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("webshortcuts")); +} + +void PageView::slotZoom() +{ + if (!d->aZoom->selectableActionGroup()->isEnabled()) + return; + + setFocus(); + updateZoom(ZoomFixed); +} + +void PageView::slotZoomIn() +{ + updateZoom(ZoomIn); +} + +void PageView::slotZoomOut() +{ + updateZoom(ZoomOut); +} + +void PageView::slotZoomActual() +{ + updateZoom(ZoomActual); +} + +void PageView::slotFitToWidthToggled(bool on) +{ + if (on) + updateZoom(ZoomFitWidth); +} + +void PageView::slotFitToPageToggled(bool on) +{ + if (on) + updateZoom(ZoomFitPage); +} + +void PageView::slotAutoFitToggled(bool on) +{ + if (on) + updateZoom(ZoomFitAuto); +} + +void PageView::slotViewMode(QAction *action) +{ + const int nr = action->data().toInt(); + if ((int)Okular::Settings::viewMode() != nr) { + Okular::Settings::setViewMode(nr); + Okular::Settings::self()->save(); + if (d->document->pages() > 0) + slotRelayoutPages(); + } +} + +void PageView::slotContinuousToggled(bool on) +{ + if (Okular::Settings::viewContinuous() != on) { + Okular::Settings::setViewContinuous(on); + Okular::Settings::self()->save(); + if (d->document->pages() > 0) + slotRelayoutPages(); + } +} + +void PageView::slotReadingDirectionToggled(bool leftToRight) +{ + Okular::Settings::setRtlReadingDirection(leftToRight); + Okular::Settings::self()->save(); +} + +void PageView::slotUpdateReadingDirectionAction() +{ + d->aReadingDirection->setChecked(Okular::Settings::rtlReadingDirection()); +} + +void PageView::slotMouseNormalToggled(bool checked) +{ + if (checked) { + d->mouseMode = Okular::Settings::EnumMouseMode::Browse; + Okular::Settings::setMouseMode(d->mouseMode); + // hide the messageWindow + d->messageWindow->hide(); + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); + } else { + d->annotator->detachAnnotation(); + } +} + +void PageView::slotSetMouseZoom() +{ + d->mouseMode = Okular::Settings::EnumMouseMode::Zoom; + Okular::Settings::setMouseMode(d->mouseMode); + // change the text in messageWindow (and show it if hidden) + d->messageWindow->display(i18n("Select zooming area. Right-click to zoom out."), QString(), PageViewMessage::Info, -1); + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); +} + +void PageView::slotSetMouseMagnifier() +{ + d->mouseMode = Okular::Settings::EnumMouseMode::Magnifier; + Okular::Settings::setMouseMode(d->mouseMode); + d->messageWindow->display(i18n("Click to see the magnified view."), QString()); + + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); +} + +void PageView::slotSetMouseSelect() +{ + d->mouseMode = Okular::Settings::EnumMouseMode::RectSelect; + Okular::Settings::setMouseMode(d->mouseMode); + // change the text in messageWindow (and show it if hidden) + d->messageWindow->display(i18n("Draw a rectangle around the text/graphics to copy."), QString(), PageViewMessage::Info, -1); + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); +} + +void PageView::slotSetMouseTextSelect() +{ + d->mouseMode = Okular::Settings::EnumMouseMode::TextSelect; + Okular::Settings::setMouseMode(d->mouseMode); + // change the text in messageWindow (and show it if hidden) + d->messageWindow->display(i18n("Select text"), QString(), PageViewMessage::Info, -1); + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); +} + +void PageView::slotSetMouseTableSelect() +{ + d->mouseMode = Okular::Settings::EnumMouseMode::TableSelect; + Okular::Settings::setMouseMode(d->mouseMode); + // change the text in messageWindow (and show it if hidden) + d->messageWindow->display(i18n("Draw a rectangle around the table, then click near edges to divide up; press Esc to clear."), QString(), PageViewMessage::Info, -1); + // force an update of the cursor + updateCursor(); + Okular::Settings::self()->save(); +} + +void PageView::slotAutoScrollUp() +{ + if (d->scrollIncrement < -9) + return; + d->scrollIncrement--; + slotAutoScroll(); + setFocus(); +} + +void PageView::slotAutoScrollDown() +{ + if (d->scrollIncrement > 9) + return; + d->scrollIncrement++; + slotAutoScroll(); + setFocus(); +} + +void PageView::slotScrollUp(int nSteps) +{ + // if in single page mode and at the top of the screen, go to \ page + if (Okular::Settings::viewContinuous() || verticalScrollBar()->value() > verticalScrollBar()->minimum()) { + if (nSteps) { + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(0, -100 * nSteps), d->currentShortScrollDuration); + } else { + if (d->scroller->finalPosition().y() > verticalScrollBar()->minimum()) + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(0, -(1 - Okular::Settings::scrollOverlap() / 100.0) * verticalScrollBar()->rect().height()), d->currentLongScrollDuration); + } + } else if (d->document->currentPage() > 0) { + // more optimized than document->setPrevPage and then move view to bottom + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber -= viewColumns(); + if (newViewport.pageNumber < 0) + newViewport.pageNumber = 0; + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 1.0; + d->document->setViewport(newViewport); + } +} + +void PageView::slotScrollDown(int nSteps) +{ + // if in single page mode and at the bottom of the screen, go to next page + if (Okular::Settings::viewContinuous() || verticalScrollBar()->value() < verticalScrollBar()->maximum()) { + if (nSteps) { + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(0, 100 * nSteps), d->currentShortScrollDuration); + } else { + if (d->scroller->finalPosition().y() < verticalScrollBar()->maximum()) + d->scroller->scrollTo(d->scroller->finalPosition() + QPoint(0, (1 - Okular::Settings::scrollOverlap() / 100.0) * verticalScrollBar()->rect().height()), d->currentLongScrollDuration); + } + } else if ((int)d->document->currentPage() < d->items.count() - 1) { + // more optimized than document->setNextPage and then move view to top + Okular::DocumentViewport newViewport = d->document->viewport(); + newViewport.pageNumber += viewColumns(); + if (newViewport.pageNumber >= (int)d->items.count()) + newViewport.pageNumber = d->items.count() - 1; + newViewport.rePos.enabled = true; + newViewport.rePos.normalizedY = 0.0; + d->document->setViewport(newViewport); + } +} + +void PageView::slotRotateClockwise() +{ + int id = ((int)d->document->rotation() + 1) % 4; + d->document->setRotation(id); +} + +void PageView::slotRotateCounterClockwise() +{ + int id = ((int)d->document->rotation() + 3) % 4; + d->document->setRotation(id); +} + +void PageView::slotRotateOriginal() +{ + d->document->setRotation(0); +} + +// Enforce mutual-exclusion between trim modes +// Each mode is uniquely identified by a single value +// From Okular::Settings::EnumTrimMode +void PageView::updateTrimMode(int except_id) +{ + const QList trimModeActions = d->aTrimMode->menu()->actions(); + for (QAction *trimModeAction : trimModeActions) { + if (trimModeAction->data().toInt() != except_id) + trimModeAction->setChecked(false); + } +} + +bool PageView::mouseReleaseOverLink(const Okular::ObjectRect *rect) const +{ + if (rect) { + // handle click over a link + const Okular::Action *action = static_cast(rect->object()); + d->document->processAction(action); + return true; + } + return false; +} + +void PageView::slotTrimMarginsToggled(bool on) +{ + if (on) { // Turn off any other Trim modes + updateTrimMode(d->aTrimMargins->data().toInt()); + } + + if (Okular::Settings::trimMargins() != on) { + Okular::Settings::setTrimMargins(on); + Okular::Settings::self()->save(); + if (d->document->pages() > 0) { + slotRelayoutPages(); + slotRequestVisiblePixmaps(); // TODO: slotRelayoutPages() may have done this already! + } + } +} + +void PageView::slotTrimToSelectionToggled(bool on) +{ + if (on) { // Turn off any other Trim modes + updateTrimMode(d->aTrimToSelection->data().toInt()); + + d->mouseMode = Okular::Settings::EnumMouseMode::TrimSelect; + // change the text in messageWindow (and show it if hidden) + d->messageWindow->display(i18n("Draw a rectangle around the page area you wish to keep visible"), QString(), PageViewMessage::Info, -1); + // force an update of the cursor + updateCursor(); + } else { + // toggled off while making selection + if (Okular::Settings::EnumMouseMode::TrimSelect == d->mouseMode) { + // clear widget selection and invalidate rect + selectionClear(); + + // When Trim selection bbox interaction is over, we should switch to another mousemode. + if (d->aPrevAction) { + d->aPrevAction->trigger(); + d->aPrevAction = nullptr; + } else { + d->aMouseNormal->trigger(); + } + } + + d->trimBoundingBox = Okular::NormalizedRect(); // invalidate box + if (d->document->pages() > 0) { + slotRelayoutPages(); + slotRequestVisiblePixmaps(); // TODO: slotRelayoutPages() may have done this already! + } + } +} + +void PageView::slotToggleForms() +{ + toggleFormWidgets(!d->m_formsVisible); +} + +void PageView::slotFormChanged(int pageNumber) +{ + if (!d->refreshTimer) { + d->refreshTimer = new QTimer(this); + d->refreshTimer->setSingleShot(true); + connect(d->refreshTimer, &QTimer::timeout, this, &PageView::slotRefreshPage); + } + d->refreshPages << pageNumber; + int delay = 0; + if (d->m_formsVisible) { + delay = 1000; + } + d->refreshTimer->start(delay); +} + +void PageView::slotRefreshPage() +{ + for (int req : qAsConst(d->refreshPages)) { + QTimer::singleShot(0, this, [this, req] { d->document->refreshPixmaps(req); }); + } + d->refreshPages.clear(); +} + +#ifdef HAVE_SPEECH +void PageView::slotSpeakDocument() +{ + QString text; + for (const PageViewItem *item : qAsConst(d->items)) { + Okular::RegularAreaRect *area = textSelectionForItem(item); + text.append(item->page()->text(area)); + text.append('\n'); + delete area; + } + + d->tts()->say(text); +} + +void PageView::slotSpeakCurrentPage() +{ + const int currentPage = d->document->viewport().pageNumber; + + PageViewItem *item = d->items.at(currentPage); + Okular::RegularAreaRect *area = textSelectionForItem(item); + const QString text = item->page()->text(area); + delete area; + + d->tts()->say(text); +} + +void PageView::slotStopSpeaks() +{ + if (!d->m_tts) + return; + + d->m_tts->stopAllSpeechs(); +} + +void PageView::slotPauseResumeSpeech() +{ + if (!d->m_tts) + return; + + d->m_tts->pauseResumeSpeech(); +} + +#endif + +void PageView::slotAction(Okular::Action *action) +{ + d->document->processAction(action); +} + +void PageView::externalKeyPressEvent(QKeyEvent *e) +{ + keyPressEvent(e); +} + +void PageView::slotProcessMovieAction(const Okular::MovieAction *action) +{ + const Okular::MovieAnnotation *movieAnnotation = action->annotation(); + if (!movieAnnotation) + return; + + Okular::Movie *movie = movieAnnotation->movie(); + if (!movie) + return; + + const int currentPage = d->document->viewport().pageNumber; + + PageViewItem *item = d->items.at(currentPage); + if (!item) + return; + + VideoWidget *vw = item->videoWidgets().value(movie); + if (!vw) + return; + + vw->show(); + + switch (action->operation()) { + case Okular::MovieAction::Play: + vw->stop(); + vw->play(); + break; + case Okular::MovieAction::Stop: + vw->stop(); + break; + case Okular::MovieAction::Pause: + vw->pause(); + break; + case Okular::MovieAction::Resume: + vw->play(); + break; + }; +} + +void PageView::slotProcessRenditionAction(const Okular::RenditionAction *action) +{ + Okular::Movie *movie = action->movie(); + if (!movie) + return; + + const int currentPage = d->document->viewport().pageNumber; + + PageViewItem *item = d->items.at(currentPage); + if (!item) + return; + + VideoWidget *vw = item->videoWidgets().value(movie); + if (!vw) + return; + + if (action->operation() == Okular::RenditionAction::None) + return; + + vw->show(); + + switch (action->operation()) { + case Okular::RenditionAction::Play: + vw->stop(); + vw->play(); + break; + case Okular::RenditionAction::Stop: + vw->stop(); + break; + case Okular::RenditionAction::Pause: + vw->pause(); + break; + case Okular::RenditionAction::Resume: + vw->play(); + break; + default: + return; + }; +} + +void PageView::slotSetChangeColors(bool active) +{ + Okular::SettingsCore::setChangeColors(active); + Okular::Settings::self()->save(); + viewport()->update(); +} + +void PageView::slotToggleChangeColors() +{ + slotSetChangeColors(!Okular::SettingsCore::changeColors()); +} + +void PageView::slotFitWindowToPage() +{ + const PageViewItem *currentPageItem = nullptr; + QSize viewportSize = viewport()->size(); + for (const PageViewItem *pageItem : qAsConst(d->items)) { + if (pageItem->isVisible()) { + currentPageItem = pageItem; + break; + } + } + + if (!currentPageItem) + return; + + const QSize pageSize = QSize(currentPageItem->uncroppedWidth() + kcolWidthMargin, currentPageItem->uncroppedHeight() + krowHeightMargin); + if (verticalScrollBar()->isVisible()) + viewportSize.setWidth(viewportSize.width() + verticalScrollBar()->width()); + if (horizontalScrollBar()->isVisible()) + viewportSize.setHeight(viewportSize.height() + horizontalScrollBar()->height()); + emit fitWindowToPage(viewportSize, pageSize); +} + +void PageView::slotSelectPage() +{ + textSelectionClear(); + const int currentPage = d->document->viewport().pageNumber; + PageViewItem *item = d->items.at(currentPage); + + if (item) { + Okular::RegularAreaRect *area = textSelectionForItem(item); + d->pagesWithTextSelection.insert(currentPage); + d->document->setPageTextSelection(currentPage, area, palette().color(QPalette::Active, QPalette::Highlight)); + } +} + +void PageView::highlightSignatureFormWidget(const Okular::FormFieldSignature *form) +{ + QVector::const_iterator dIt = d->items.constBegin(), dEnd = d->items.constEnd(); + for (; dIt != dEnd; ++dIt) { + const QSet fwi = (*dIt)->formWidgets(); + for (FormWidgetIface *fw : fwi) { + if (fw->formField() == form) { + SignatureEdit *widget = static_cast(fw); + widget->setDummyMode(true); + QTimer::singleShot(250, this, [=] { widget->setDummyMode(false); }); + return; + } + } + } +} + +// END private SLOTS + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/pageview.h b/part/pageview.h new file mode 100644 index 0000000..e836ef8 --- /dev/null +++ b/part/pageview.h @@ -0,0 +1,293 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2004 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * With portions of code from kpdf/kpdf_pagewidget.h by: * + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2003 by Christophe Devriese * + * * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2003 by Kurt Pfeifle * + * * + * 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. * + ***************************************************************************/ +// This file follows coding style described in kdebase/kicker/HACKING + +#ifndef _OKULAR_PAGEVIEW_H_ +#define _OKULAR_PAGEVIEW_H_ + +#include "core/area.h" +#include "core/observer.h" +#include "core/view.h" +#include "pageviewutils.h" +#include +#include +#include + +class QMenu; +class KActionCollection; + +namespace Okular +{ +class Action; +class Document; +class DocumentViewport; +class FormFieldSignature; +class Annotation; +class MovieAction; +class RenditionAction; +} + +class PageViewPrivate; + +class QGestureEvent; + +/** + * @short The main view. Handles zoom and continuous mode.. oh, and page + * @short display of course :-) + * ... + */ +class PageView : public QAbstractScrollArea, public Okular::DocumentObserver, public Okular::View +{ + Q_OBJECT + +public: + PageView(QWidget *parent, Okular::Document *document); + ~PageView() override; + + // Zoom mode ( last 4 are internally used only! ) + enum ZoomMode { ZoomFixed = 0, ZoomFitWidth = 1, ZoomFitPage = 2, ZoomFitAuto = 3, ZoomIn, ZoomOut, ZoomRefreshCurrent, ZoomActual }; + + enum ClearMode { ClearAllSelection, ClearOnlyDividers }; + + // create actions that interact with this widget + void setupBaseActions(KActionCollection *ac); + void setupViewerActions(KActionCollection *ac); + void setupActions(KActionCollection *ac); + void setupActionsPostGUIActivated(); + void updateActionState(bool docHasPages, bool docHasFormWidgets); + + // misc methods (from RMB menu/children) + bool canFitPageWidth() const; + void fitPageWidth(int page); + // keep in sync with pageviewutils + void displayMessage(const QString &message, const QString &details = QString(), PageViewMessage::Icon icon = PageViewMessage::Info, int duration = -1); + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyViewportChanged(bool smoothMove) override; + void notifyPageChanged(int pageNumber, int changedFlags) override; + void notifyContentsCleared(int changedFlags) override; + void notifyZoom(int factor) override; + bool canUnloadPixmap(int pageNum) const override; + void notifyCurrentPageChanged(int previous, int current) override; + + // inherited from View + bool supportsCapability(ViewCapability capability) const override; + CapabilityFlags capabilityFlags(ViewCapability capability) const override; + QVariant capability(ViewCapability capability) const override; + void setCapability(ViewCapability capability, const QVariant &option) override; + + QList textSelections(const QPoint start, const QPoint end, int &firstpage); + Okular::RegularAreaRect *textSelectionForItem(const PageViewItem *item, const QPoint startPoint = QPoint(), const QPoint endPoint = QPoint()); + + void reparseConfig(); + + KActionCollection *actionCollection() const; + QAction *toggleFormsAction() const; + + int contentAreaWidth() const; + int contentAreaHeight() const; + QPoint contentAreaPosition() const; + QPoint contentAreaPoint(const QPoint pos) const; + QPointF contentAreaPoint(const QPointF pos) const; + + bool areSourceLocationsShownGraphically() const; + void setShowSourceLocationsGraphically(bool show); + + void setLastSourceLocationViewport(const Okular::DocumentViewport &vp); + void clearLastSourceLocationViewport(); + + void updateCursor(); + + void highlightSignatureFormWidget(const Okular::FormFieldSignature *form); + +public Q_SLOTS: + void copyTextSelection() const; + void selectAll(); + + void openAnnotationWindow(Okular::Annotation *annotation, int pageNumber); + void reloadForms(); + + void slotToggleChangeColors(); + void slotSetChangeColors(bool active); + + void slotSelectPage(); + + void slotAction(Okular::Action *action); + void slotFormChanged(int pageNumber); + + void externalKeyPressEvent(QKeyEvent *e); + +Q_SIGNALS: + void rightClick(const Okular::Page *, const QPoint); + void mouseBackButtonClick(); + void mouseForwardButtonClick(); + void escPressed(); + void fitWindowToPage(const QSize pageViewPortSize, const QSize pageSize); + void triggerSearch(const QString &text); + +protected: + bool event(QEvent *event) override; + + void resizeEvent(QResizeEvent *) override; + bool gestureEvent(QGestureEvent *e); + + // mouse / keyboard events + void keyPressEvent(QKeyEvent *) override; + void keyReleaseEvent(QKeyEvent *) override; + void inputMethodEvent(QInputMethodEvent *) override; + void wheelEvent(QWheelEvent *) override; + + void paintEvent(QPaintEvent *e) override; + void tabletEvent(QTabletEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void mouseDoubleClickEvent(QMouseEvent *e) override; + + bool viewportEvent(QEvent *e) override; + + void scrollContentsBy(int dx, int dy) override; + +private: + // draw background and items on the opened qpainter + void drawDocumentOnPainter(const QRect contentsRect, QPainter *p); + // update item width and height using current zoom parameters + void updateItemSize(PageViewItem *item, int colWidth, int rowHeight); + // return the widget placed on a certain point or 0 if clicking on empty space + PageViewItem *pickItemOnPoint(int x, int y); + // start / modify / clear selection rectangle + void selectionStart(const QPoint pos, const QColor &color, bool aboveAll = false); + void selectionClear(const ClearMode mode = ClearAllSelection); + void drawTableDividers(QPainter *screenPainter); + void guessTableDividers(); + // update either text or rectangle selection + void updateSelection(const QPoint pos); + // compute the zoom factor value for FitWidth and FitPage mode + double zoomFactorFitMode(ZoomMode mode); + // update internal zoom values and end in a slotRelayoutPages(); + void updateZoom(ZoomMode newZoomMode); + // update the text on the label using global zoom value or current page's one + void updateZoomText(); + // update view mode (single, facing...) + void updateViewMode(const int nr); + void textSelectionClear(); + // updates cursor + void updateCursor(const QPoint p); + + void moveMagnifier(const QPoint p); + void updateMagnifier(const QPoint p); + + int viewColumns() const; + + void center(int cx, int cy, bool smoothMove = false); + void scrollTo(int x, int y, bool smoothMove = false); + + void toggleFormWidgets(bool on); + + void resizeContentArea(const QSize newSize); + void updatePageStep(); + + void addSearchWithinDocumentAction(QMenu *menu, const QString &searchText); + void addWebShortcutsMenu(QMenu *menu, const QString &text); + QMenu *createProcessLinkMenu(PageViewItem *item, const QPoint eventPos); + // used when selecting stuff, makes the view scroll as necessary to keep the mouse inside the view + void scrollPosIntoView(const QPoint pos); + QPoint viewportToContentArea(const Okular::DocumentViewport &vp) const; + + // called from slots to turn off trim modes mutually exclusive to id + void updateTrimMode(int except_id); + + // handle link clicked + bool mouseReleaseOverLink(const Okular::ObjectRect *rect) const; + + void createAnnotationsVideoWidgets(PageViewItem *item, const QLinkedList &annotations); + + // Update speed of animated smooth scroll transitions + void updateSmoothScrollAnimationSpeed(); + + // don't want to expose classes in here + class PageViewPrivate *d; + +private Q_SLOTS: + // used to decouple the notifyViewportChanged calle + void slotRealNotifyViewportChanged(bool smoothMove); + // activated either directly or via queued connection on notifySetup + void slotRelayoutPages(); + // activated by the resize event delay timer + void delayedResizeEvent(); + // activated either directly or via the contentsMoving(int,int) signal + void slotRequestVisiblePixmaps(int newValue = -1); + // activated by the autoscroll timer (Shift+Up/Down keys) + void slotAutoScroll(); + // activated by the dragScroll timer + void slotDragScroll(); + // show the welcome message + void slotShowWelcome(); + // activated by left click timer + void slotShowSizeAllCursor(); + + void slotHandleWebShortcutAction(); + void slotConfigureWebShortcuts(); + + // connected to local actions (toolbar, menu, ..) + void slotZoom(); + void slotZoomIn(); + void slotZoomOut(); + void slotZoomActual(); + void slotFitToWidthToggled(bool); + void slotFitToPageToggled(bool); + void slotAutoFitToggled(bool); + void slotViewMode(QAction *action); + void slotContinuousToggled(bool); + void slotReadingDirectionToggled(bool leftToRight); + void slotUpdateReadingDirectionAction(); + void slotMouseNormalToggled(bool); + void slotSetMouseZoom(); + void slotSetMouseMagnifier(); + void slotSetMouseSelect(); + void slotSetMouseTextSelect(); + void slotSetMouseTableSelect(); + void slotAutoScrollUp(); + void slotAutoScrollDown(); + void slotScrollUp(int nSteps = 0); + void slotScrollDown(int nSteps = 0); + void slotRotateClockwise(); + void slotRotateCounterClockwise(); + void slotRotateOriginal(); + void slotTrimMarginsToggled(bool); + void slotTrimToSelectionToggled(bool); + void slotToggleForms(); + void slotRefreshPage(); +#ifdef HAVE_SPEECH + void slotSpeakDocument(); + void slotSpeakCurrentPage(); + void slotStopSpeaks(); + void slotPauseResumeSpeech(); +#endif + void slotAnnotationWindowDestroyed(QObject *window); + void slotProcessMovieAction(const Okular::MovieAction *action); + void slotProcessRenditionAction(const Okular::RenditionAction *action); + void slotFitWindowToPage(); +}; + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/pageviewannotator.cpp b/part/pageviewannotator.cpp new file mode 100644 index 0000000..8aeb2b0 --- /dev/null +++ b/part/pageviewannotator.cpp @@ -0,0 +1,1419 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "pageviewannotator.h" + +// qt / kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// system includes +#include +#include +#include +#include +#include + +// local includes +#include "annotationactionhandler.h" +#include "core/annotations.h" +#include "core/area.h" +#include "core/document.h" +#include "core/page.h" +#include "debug_ui.h" +#include "editannottooldialog.h" +#include "guiutils.h" +#include "pageview.h" +#include "settings.h" + +/** @short PickPointEngine */ +class PickPointEngine : public AnnotatorEngine +{ +public: + PickPointEngine(const QDomElement &engineElement) + : AnnotatorEngine(engineElement) + , clicked(false) + , xscale(1.0) + , yscale(1.0) + { + // parse engine specific attributes + hoverIconName = engineElement.attribute(QStringLiteral("hoverIcon")); + iconName = m_annotElement.attribute(QStringLiteral("icon")); + if (m_annotElement.attribute(QStringLiteral("type")) == QLatin1String("Stamp") && !iconName.simplified().isEmpty()) + hoverIconName = iconName; + center = QVariant(engineElement.attribute(QStringLiteral("center"))).toBool(); + bool ok = true; + size = engineElement.attribute(QStringLiteral("size"), QStringLiteral("32")).toInt(&ok); + if (!ok) + size = 32; + m_block = QVariant(engineElement.attribute(QStringLiteral("block"))).toBool(); + + // create engine objects + if (!hoverIconName.simplified().isEmpty()) + pixmap = GuiUtils::loadStamp(hoverIconName, size); + } + + QRect event(EventType type, Button button, Modifiers modifiers, double nX, double nY, double xScale, double yScale, const Okular::Page *page) override + { + xscale = xScale; + yscale = yScale; + pagewidth = page->width(); + pageheight = page->height(); + // only proceed if pressing left button + if (button != Left) + return QRect(); + + // start operation on click + if (type == Press && clicked == false) { + clicked = true; + startpoint.x = nX; + startpoint.y = nY; + } + // repaint if moving while pressing + else if (type == Move && clicked == true) { + } + // operation finished on release + else if (type == Release && clicked == true) { + m_creationCompleted = true; + } else + return QRect(); + + // Constrain to 1:1 form factor (e.g. circle or square) + if (modifiers.constrainRatioAndAngle) { + double side = qMin(qAbs(nX - startpoint.x) * xScale, qAbs(nY - startpoint.y) * yScale); + nX = qBound(startpoint.x - side / xScale, nX, startpoint.x + side / xScale); + nY = qBound(startpoint.y - side / yScale, nY, startpoint.y + side / yScale); + } + // update variables and extents (zoom invariant rect) + point.x = nX; + point.y = nY; + if (center) { + rect.left = nX - (size / (xScale * 2.0)); + rect.top = nY - (size / (yScale * 2.0)); + } else { + rect.left = nX; + rect.top = nY; + } + rect.right = rect.left + size; + rect.bottom = rect.top + size; + QRect boundrect = rect.geometry((int)xScale, (int)yScale).adjusted(0, 0, 1, 1); + if (m_block) { + const Okular::NormalizedRect tmprect(qMin(startpoint.x, point.x), qMin(startpoint.y, point.y), qMax(startpoint.x, point.x), qMax(startpoint.y, point.y)); + boundrect |= tmprect.geometry((int)xScale, (int)yScale).adjusted(0, 0, 1, 1); + } + return boundrect; + } + + void paint(QPainter *painter, double xScale, double yScale, const QRect & /*clipRect*/) override + { + if (clicked) { + if (m_block) { + const QPen origpen = painter->pen(); + QPen pen = painter->pen(); + pen.setStyle(Qt::DashLine); + painter->setPen(pen); + const Okular::NormalizedRect tmprect(qMin(startpoint.x, point.x), qMin(startpoint.y, point.y), qMax(startpoint.x, point.x), qMax(startpoint.y, point.y)); + const QRect realrect = tmprect.geometry((int)xScale, (int)yScale); + painter->drawRect(realrect); + painter->setPen(origpen); + } + if (!pixmap.isNull()) + painter->drawPixmap(QPointF(rect.left * xScale, rect.top * yScale), pixmap); + } + } + + void addInPlaceTextAnnotation(Okular::Annotation *&ann, const QString &summary, const QString &content, Okular::TextAnnotation::InplaceIntent inplaceIntent) + { + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + ann = ta; + ta->setFlags(ta->flags() | Okular::Annotation::FixedRotation); + ta->setContents(content); + ta->setTextType(Okular::TextAnnotation::InPlace); + ta->setInplaceIntent(inplaceIntent); + // set alignment + if (m_annotElement.hasAttribute(QStringLiteral("align"))) + ta->setInplaceAlignment(m_annotElement.attribute(QStringLiteral("align")).toInt()); + // set font + if (m_annotElement.hasAttribute(QStringLiteral("font"))) { + QFont f; + f.fromString(m_annotElement.attribute(QStringLiteral("font"))); + ta->setTextFont(f); + } + // set font color + if (m_annotElement.hasAttribute(QStringLiteral("textColor"))) { + if (inplaceIntent == Okular::TextAnnotation::TypeWriter) + ta->setTextColor(m_annotElement.attribute(QStringLiteral("textColor"))); + else + ta->setTextColor(Qt::black); + } + // set width + if (m_annotElement.hasAttribute(QStringLiteral("width"))) { + ta->style().setWidth(m_annotElement.attribute(QStringLiteral("width")).toDouble()); + } + // set boundary + rect.left = qMin(startpoint.x, point.x); + rect.top = qMin(startpoint.y, point.y); + rect.right = qMax(startpoint.x, point.x); + rect.bottom = qMax(startpoint.y, point.y); + qCDebug(OkularUiDebug).nospace() << "xyScale=" << xscale << "," << yscale; + static const int padding = 2; + const QFontMetricsF mf(ta->textFont()); + const QRectF rcf = + mf.boundingRect(Okular::NormalizedRect(rect.left, rect.top, 1.0, 1.0).geometry((int)pagewidth, (int)pageheight).adjusted(padding, padding, -padding, -padding), Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, ta->contents()); + rect.right = qMax(rect.right, rect.left + (rcf.width() + padding * 2) / pagewidth); + rect.bottom = qMax(rect.bottom, rect.top + (rcf.height() + padding * 2) / pageheight); + ta->window().setSummary(summary); + } + + QList end() override + { + // find out annotation's description node + if (m_annotElement.isNull()) { + m_creationCompleted = false; + clicked = false; + return QList(); + } + + // find out annotation's type + Okular::Annotation *ann = nullptr; + const QString typeString = m_annotElement.attribute(QStringLiteral("type")); + // create InPlace TextAnnotation from path + if (typeString == QLatin1String("FreeText")) { + bool resok; + const QString content = QInputDialog::getMultiLineText(nullptr, i18n("New Text Note"), i18n("Text of the new note:"), QString(), &resok); + if (resok) + addInPlaceTextAnnotation(ann, i18n("Inline Note"), content, Okular::TextAnnotation::Unknown); + } else if (typeString == QLatin1String("Typewriter")) { + bool resok; + const QString content = QInputDialog::getMultiLineText(nullptr, i18n("New Text Note"), i18n("Text of the new note:"), QString(), &resok); + if (resok) + addInPlaceTextAnnotation(ann, i18n("Typewriter"), content, Okular::TextAnnotation::TypeWriter); + } else if (typeString == QLatin1String("Text")) { + Okular::TextAnnotation *ta = new Okular::TextAnnotation(); + ann = ta; + ta->setTextType(Okular::TextAnnotation::Linked); + ta->setTextIcon(iconName); + // ta->window.flags &= ~(Okular::Annotation::Hidden); + const double iconhei = 0.03; + rect.left = point.x; + rect.top = point.y; + rect.right = rect.left + iconhei; + rect.bottom = rect.top + iconhei * xscale / yscale; + ta->window().setSummary(i18n("Pop-up Note")); + } + // create StampAnnotation from path + else if (typeString == QLatin1String("Stamp")) { + Okular::StampAnnotation *sa = new Okular::StampAnnotation(); + ann = sa; + sa->setStampIconName(iconName); + // set boundary + rect.left = qMin(startpoint.x, point.x); + rect.top = qMin(startpoint.y, point.y); + rect.right = qMax(startpoint.x, point.x); + rect.bottom = qMax(startpoint.y, point.y); + const QRectF rcf = rect.geometry((int)xscale, (int)yscale); + const int ml = (rcf.bottomRight() - rcf.topLeft()).toPoint().manhattanLength(); + if (ml <= QApplication::startDragDistance()) { + const double stampxscale = pixmap.width() / xscale; + const double stampyscale = pixmap.height() / yscale; + if (center) { + rect.left = point.x - stampxscale / 2; + rect.top = point.y - stampyscale / 2; + } else { + rect.left = point.x; + rect.top = point.y; + } + rect.right = rect.left + stampxscale; + rect.bottom = rect.top + stampyscale; + } + } + // create GeomAnnotation + else if (typeString == QLatin1String("GeomSquare") || typeString == QLatin1String("GeomCircle")) { + Okular::GeomAnnotation *ga = new Okular::GeomAnnotation(); + ann = ga; + // set the type + if (typeString == QLatin1String("GeomSquare")) + ga->setGeometricalType(Okular::GeomAnnotation::InscribedSquare); + else + ga->setGeometricalType(Okular::GeomAnnotation::InscribedCircle); + if (m_annotElement.hasAttribute(QStringLiteral("width"))) + ann->style().setWidth(m_annotElement.attribute(QStringLiteral("width")).toDouble()); + if (m_annotElement.hasAttribute(QStringLiteral("innerColor"))) + ga->setGeometricalInnerColor(QColor(m_annotElement.attribute(QStringLiteral("innerColor")))); + // set boundary + rect.left = qMin(startpoint.x, point.x); + rect.top = qMin(startpoint.y, point.y); + rect.right = qMax(startpoint.x, point.x); + rect.bottom = qMax(startpoint.y, point.y); + } + + m_creationCompleted = false; + clicked = false; + + // safety check + if (!ann) + return QList(); + + // set common attributes + ann->style().setColor(m_annotElement.hasAttribute(QStringLiteral("color")) ? m_annotElement.attribute(QStringLiteral("color")) : m_engineColor); + if (m_annotElement.hasAttribute(QStringLiteral("opacity"))) + ann->style().setOpacity(m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble()); + + // set the bounding rectangle, and make sure that the newly created + // annotation lies within the page by translating it if necessary + if (rect.right > 1) { + rect.left -= rect.right - 1; + rect.right = 1; + } + if (rect.bottom > 1) { + rect.top -= rect.bottom - 1; + rect.bottom = 1; + } + ann->setBoundingRectangle(rect); + + // return annotation + return QList() << ann; + } + +private: + bool clicked; + Okular::NormalizedRect rect; + Okular::NormalizedPoint startpoint; + Okular::NormalizedPoint point; + QPixmap pixmap; + QString hoverIconName, iconName; + int size; + double xscale, yscale; + double pagewidth, pageheight; + bool center; + bool m_block; +}; + +/** @short PolyLineEngine */ +class PolyLineEngine : public AnnotatorEngine +{ +public: + PolyLineEngine(const QDomElement &engineElement) + : AnnotatorEngine(engineElement) + , last(false) + { + // parse engine specific attributes + m_block = engineElement.attribute(QStringLiteral("block")) == QLatin1String("true"); + bool ok = true; + // numofpoints represents the max number of points for the current + // polygon/polyline, with a pair of exceptions: + // -1 means: the polyline must close on the first point (polygon) + // 0 means: construct as many points as you want, right-click + // to construct the last point + numofpoints = engineElement.attribute(QStringLiteral("points")).toInt(&ok); + if (!ok) + numofpoints = -1; + } + + static Okular::NormalizedPoint constrainAngle(const Okular::NormalizedPoint &p1, double x, double y, double xScale, double yScale, double angleIncrement) + { + // given the normalized point (x, y), return the closest point such that the line segment from p1 forms an angle + // with the horizontal axis which is an integer multiple of angleIncrement on a reference area of size xScale x yScale + double dist = sqrt(p1.distanceSqr(x, y, xScale, yScale)); + double angle = atan2((y - p1.y) * yScale, (x - p1.x) * xScale); + double constrainedAngle = round(angle / angleIncrement) * angleIncrement; + double offset = dist * sin(angle - constrainedAngle); + x += offset * sin(constrainedAngle) / xScale; + y -= offset * cos(constrainedAngle) / yScale; + return Okular::NormalizedPoint(x, y); + } + + QRect event(EventType type, Button button, Modifiers modifiers, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/) override + { + // only proceed if pressing left button + // if ( button != Left ) + // return rect; + + // Constrain to 15° steps, except first point of course. + if (modifiers.constrainRatioAndAngle && !points.isEmpty()) { + const Okular::NormalizedPoint constrainedPoint = constrainAngle(points.constLast(), nX, nY, xScale, yScale, M_PI / 12.); + nX = constrainedPoint.x; + nY = constrainedPoint.y; + } + // process button press + if (type == Press) { + newPoint.x = nX; + newPoint.y = nY; + if (button == Right) + last = true; + } + // move the second point + else if (type == Move) { + movingpoint.x = nX; + movingpoint.y = nY; + const QRect oldmovingrect = movingrect; + movingrect = rect | QRect((int)(movingpoint.x * xScale), (int)(movingpoint.y * yScale), 1, 1); + return oldmovingrect | movingrect; + } else if (type == Release) { + const Okular::NormalizedPoint tmppoint(nX, nY); + if (fabs(tmppoint.x - newPoint.x) + fabs(tmppoint.y - newPoint.y) > 1e-2) + return rect; + + if (numofpoints == -1 && points.count() > 1 && (fabs(points[0].x - newPoint.x) + fabs(points[0].y - newPoint.y) < 1e-2)) { + last = true; + } else { + points.append(newPoint); + rect |= QRect((int)(newPoint.x * xScale), (int)(newPoint.y * yScale), 1, 1); + } + // end creation if we have constructed the last point of enough points + if (last || points.count() == numofpoints) { + m_creationCompleted = true; + last = false; + normRect = Okular::NormalizedRect(rect, xScale, yScale); + } + } + + return rect; + } + + void paint(QPainter *painter, double xScale, double yScale, const QRect & /*clipRect*/) override + { + if (points.count() < 1) + return; + + if (m_block && points.count() == 2) { + const Okular::NormalizedPoint first = points[0]; + const Okular::NormalizedPoint second = points[1]; + // draw a semitransparent block around the 2 points + painter->setPen(m_engineColor); + painter->setBrush(QBrush(m_engineColor.lighter(), Qt::Dense4Pattern)); + painter->drawRect((int)(first.x * (double)xScale), (int)(first.y * (double)yScale), (int)((second.x - first.x) * (double)xScale), (int)((second.y - first.y) * (double)yScale)); + } else { + // draw a polyline that connects the constructed points + painter->setPen(QPen(m_engineColor, 2)); + for (int i = 1; i < points.count(); ++i) + painter->drawLine((int)(points[i - 1].x * (double)xScale), (int)(points[i - 1].y * (double)yScale), (int)(points[i].x * (double)xScale), (int)(points[i].y * (double)yScale)); + painter->drawLine((int)(points.last().x * (double)xScale), (int)(points.last().y * (double)yScale), (int)(movingpoint.x * (double)xScale), (int)(movingpoint.y * (double)yScale)); + } + } + + QList end() override + { + m_creationCompleted = false; + + // find out annotation's description node + if (m_annotElement.isNull()) + return QList(); + + // find out annotation's type + Okular::Annotation *ann = nullptr; + const QString typeString = m_annotElement.attribute(QStringLiteral("type")); + + // create LineAnnotation from path + if (typeString == QLatin1String("Line") || typeString == QLatin1String("Polyline") || typeString == QLatin1String("Polygon")) { + if (points.count() < 2) + return QList(); + + // add note + Okular::LineAnnotation *la = new Okular::LineAnnotation(); + ann = la; + QLinkedList list; + for (int i = 0; i < points.count(); ++i) + list.append(points[i]); + + la->setLinePoints(list); + + if (numofpoints == -1) { + la->setLineClosed(true); + if (m_annotElement.hasAttribute(QStringLiteral("innerColor"))) + la->setLineInnerColor(QColor(m_annotElement.attribute(QStringLiteral("innerColor")))); + } else if (numofpoints == 2) { + if (m_annotElement.hasAttribute(QStringLiteral("leadFwd"))) + la->setLineLeadingForwardPoint(m_annotElement.attribute(QStringLiteral("leadFwd")).toDouble()); + if (m_annotElement.hasAttribute(QStringLiteral("leadBack"))) + la->setLineLeadingBackwardPoint(m_annotElement.attribute(QStringLiteral("leadBack")).toDouble()); + } + if (m_annotElement.hasAttribute(QStringLiteral("startStyle"))) + la->setLineStartStyle((Okular::LineAnnotation::TermStyle)m_annotElement.attribute(QStringLiteral("startStyle")).toInt()); + if (m_annotElement.hasAttribute(QStringLiteral("endStyle"))) + la->setLineEndStyle((Okular::LineAnnotation::TermStyle)m_annotElement.attribute(QStringLiteral("endStyle")).toInt()); + + la->setBoundingRectangle(normRect); + } + + // safety check + if (!ann) + return QList(); + + if (m_annotElement.hasAttribute(QStringLiteral("width"))) + ann->style().setWidth(m_annotElement.attribute(QStringLiteral("width")).toDouble()); + + // set common attributes + ann->style().setColor(m_annotElement.hasAttribute(QStringLiteral("color")) ? m_annotElement.attribute(QStringLiteral("color")) : m_engineColor); + if (m_annotElement.hasAttribute(QStringLiteral("opacity"))) + ann->style().setOpacity(m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble()); + // return annotation + + return QList() << ann; + } + +private: + QList points; + Okular::NormalizedPoint newPoint; + Okular::NormalizedPoint movingpoint; + QRect rect; + QRect movingrect; + Okular::NormalizedRect normRect; + bool m_block; + bool last; + int numofpoints; +}; + +/** @short TextSelectorEngine */ +class TextSelectorEngine : public AnnotatorEngine +{ +public: + TextSelectorEngine(const QDomElement &engineElement, PageView *pageView) + : AnnotatorEngine(engineElement) + , m_pageView(pageView) + { + // parse engine specific attributes + } + + QRect event(EventType type, Button button, Modifiers /*modifiers*/, double nX, double nY, double xScale, double yScale, const Okular::Page * /*page*/) override + { + // only proceed if pressing left button + if (button != Left) + return QRect(); + + if (type == Press) { + lastPoint.x = nX; + lastPoint.y = nY; + const QRect oldrect = rect; + rect = QRect(); + return oldrect; + } else if (type == Move) { + if (item()) { + const QPoint start((int)(lastPoint.x * item()->uncroppedWidth()), (int)(lastPoint.y * item()->uncroppedHeight())); + const QPoint end((int)(nX * item()->uncroppedWidth()), (int)(nY * item()->uncroppedHeight())); + selection.reset(); + std::unique_ptr newselection(m_pageView->textSelectionForItem(item(), start, end)); + if (newselection && !newselection->isEmpty()) { + const QList geom = newselection->geometry((int)xScale, (int)yScale); + QRect newrect; + for (const QRect &r : geom) { + if (newrect.isNull()) + newrect = r; + else + newrect |= r; + } + rect |= newrect; + selection = std::move(newselection); + } + } + } else if (type == Release) { + m_creationCompleted = true; + } + return rect; + } + + void paint(QPainter *painter, double xScale, double yScale, const QRect & /*clipRect*/) override + { + if (selection) { + painter->setPen(Qt::NoPen); + QColor col = m_engineColor; + col.setAlphaF(0.5); + painter->setBrush(col); + for (const Okular::NormalizedRect &r : qAsConst(*selection)) { + painter->drawRect(r.geometry((int)xScale, (int)yScale)); + } + } + } + + QList end() override + { + m_creationCompleted = false; + + // safety checks + if (m_annotElement.isNull() || !selection) + return QList(); + + // find out annotation's type + Okular::Annotation *ann = nullptr; + const QString typeString = m_annotElement.attribute(QStringLiteral("type")); + + Okular::HighlightAnnotation::HighlightType type = Okular::HighlightAnnotation::Highlight; + bool typevalid = false; + // create HighlightAnnotation's from the selected area + if (typeString == QLatin1String("Highlight")) { + type = Okular::HighlightAnnotation::Highlight; + typevalid = true; + } else if (typeString == QLatin1String("Squiggly")) { + type = Okular::HighlightAnnotation::Squiggly; + typevalid = true; + } else if (typeString == QLatin1String("Underline")) { + type = Okular::HighlightAnnotation::Underline; + typevalid = true; + } else if (typeString == QLatin1String("StrikeOut")) { + type = Okular::HighlightAnnotation::StrikeOut; + typevalid = true; + } + if (typevalid) { + Okular::HighlightAnnotation *ha = new Okular::HighlightAnnotation(); + ha->setHighlightType(type); + ha->setBoundingRectangle(Okular::NormalizedRect(rect, item()->uncroppedWidth(), item()->uncroppedHeight())); + for (const Okular::NormalizedRect &r : qAsConst(*selection)) { + Okular::HighlightAnnotation::Quad q; + q.setCapStart(false); + q.setCapEnd(false); + q.setFeather(1.0); + q.setPoint(Okular::NormalizedPoint(r.left, r.bottom), 0); + q.setPoint(Okular::NormalizedPoint(r.right, r.bottom), 1); + q.setPoint(Okular::NormalizedPoint(r.right, r.top), 2); + q.setPoint(Okular::NormalizedPoint(r.left, r.top), 3); + ha->highlightQuads().append(q); + } + ann = ha; + } + + selection.reset(); + + // safety check + if (!ann) + return QList(); + + // set common attributes + ann->style().setColor(m_annotElement.hasAttribute(QStringLiteral("color")) ? m_annotElement.attribute(QStringLiteral("color")) : m_engineColor); + if (m_annotElement.hasAttribute(QStringLiteral("opacity"))) + ann->style().setOpacity(m_annotElement.attribute(QStringLiteral("opacity"), QStringLiteral("1.0")).toDouble()); + + // return annotations + return QList() << ann; + } + + QCursor cursor() const override + { + return Qt::IBeamCursor; + } + +private: + // data + PageView *m_pageView; + // TODO: support more pages + std::unique_ptr selection; + Okular::NormalizedPoint lastPoint; + QRect rect; +}; + +/** @short AnnotationTools*/ +class AnnotationTools +{ +public: + AnnotationTools() + : m_toolsCount(0) + { + } + + void setTools(const QStringList &tools) + { + // Populate m_toolsDefinition + m_toolsCount = 0; + m_toolsDefinition.clear(); + QDomElement root = m_toolsDefinition.createElement(QStringLiteral("root")); + m_toolsDefinition.appendChild(root); + for (const QString &toolXml : tools) { + QDomDocument entryParser; + if (entryParser.setContent(toolXml)) { + root.appendChild(m_toolsDefinition.importNode(entryParser.documentElement(), true)); + m_toolsCount++; + } else { + qCWarning(OkularUiDebug) << "Skipping malformed tool XML in AnnotationTools setting"; + } + } + } + + QStringList toStringList() + { + QStringList tools; + QDomElement toolElement = m_toolsDefinition.documentElement().firstChildElement(); + QString str; + QTextStream stream(&str); + while (!toolElement.isNull()) { + str.clear(); + toolElement.save(stream, -1 /* indent disabled */); + tools << str; + toolElement = toolElement.nextSiblingElement(); + } + return tools; + } + + QDomElement tool(int toolId) + { + QDomElement toolElement = m_toolsDefinition.documentElement().firstChildElement(); + while (!toolElement.isNull() && toolElement.attribute(QStringLiteral("id")).toInt() != toolId) { + toolElement = toolElement.nextSiblingElement(); + } + return toolElement; // can return a null element + } + + void appendTool(QDomElement toolElement) + { + toolElement = toolElement.cloneNode().toElement(); + toolElement.setAttribute(QStringLiteral("id"), ++m_toolsCount); + m_toolsDefinition.documentElement().appendChild(toolElement); + } + + bool updateTool(QDomElement newToolElement, int toolId) + { + QDomElement toolElement = tool(toolId); + if (toolElement.isNull()) + return false; + newToolElement = newToolElement.cloneNode().toElement(); + newToolElement.setAttribute(QStringLiteral("id"), toolId); + QDomNode oldTool = m_toolsDefinition.documentElement().replaceChild(newToolElement, toolElement); + return !oldTool.isNull(); + } + + int findToolId(const QString &type) + { + int toolId = -1; + if (type.isEmpty()) { + return -1; + } + // FIXME: search from left. currently searching from right side as a workaround to avoid matching + // straight line tools to the arrow tool, which is also of type straight-line + QDomElement toolElement = m_toolsDefinition.documentElement().lastChildElement(); + while (!toolElement.isNull() && toolElement.attribute(QStringLiteral("type")) != type) { + toolElement = toolElement.previousSiblingElement(); + } + if (!toolElement.isNull() && toolElement.hasAttribute(QStringLiteral("id"))) { + bool ok; + toolId = toolElement.attribute(QStringLiteral("id")).toInt(&ok); + if (!ok) { + return -1; + } + } + return toolId; + } + +private: + QDomDocument m_toolsDefinition; + int m_toolsCount; +}; + +/** PageViewAnnotator **/ +const int PageViewAnnotator::STAMP_TOOL_ID = 14; + +PageViewAnnotator::PageViewAnnotator(PageView *parent, Okular::Document *storage) + : QObject(parent) + , m_document(storage) + , m_pageView(parent) + , m_actionHandler(nullptr) + , m_engine(nullptr) + , m_builtinToolsDefinition(nullptr) + , m_quickToolsDefinition(nullptr) + , m_continuousMode(true) + , m_constrainRatioAndAngle(false) + , m_lastToolId(-1) + , m_lockedItem(nullptr) +{ + reparseConfig(); + reparseBuiltinToolsConfig(); + reparseQuickToolsConfig(); + connect(Okular::Settings::self(), &Okular::Settings::builtinAnnotationToolsChanged, this, &PageViewAnnotator::reparseBuiltinToolsConfig); + connect(Okular::Settings::self(), &Okular::Settings::quickAnnotationToolsChanged, this, &PageViewAnnotator::reparseQuickToolsConfig); +} + +void PageViewAnnotator::reparseConfig() +{ + m_continuousMode = Okular::Settings::annotationContinuousMode(); + + if (Okular::Settings::identityAuthor().isEmpty()) + detachAnnotation(); +} + +void PageViewAnnotator::reparseBuiltinToolsConfig() +{ + // Read tool list from configuration. It's a list of XML elements + if (!m_builtinToolsDefinition) + m_builtinToolsDefinition = new AnnotationTools(); + m_builtinToolsDefinition->setTools(Okular::Settings::builtinAnnotationTools()); + + if (m_actionHandler) + m_actionHandler->reparseBuiltinToolsConfig(); +} + +void PageViewAnnotator::reparseQuickToolsConfig() +{ + // Read tool list from configuration. It's a list of XML elements + if (!m_quickToolsDefinition) + m_quickToolsDefinition = new AnnotationTools(); + m_quickToolsDefinition->setTools(Okular::Settings::quickAnnotationTools()); + + if (m_actionHandler) + m_actionHandler->reparseQuickToolsConfig(); +} + +PageViewAnnotator::~PageViewAnnotator() +{ + delete m_engine; + delete m_builtinToolsDefinition; + delete m_quickToolsDefinition; +} + +bool PageViewAnnotator::active() const +{ + return m_engine != nullptr; +} + +bool PageViewAnnotator::annotating() const +{ + return active() && m_lockedItem; +} + +QCursor PageViewAnnotator::cursor() const +{ + return m_engine->cursor(); +} + +QRect PageViewAnnotator::performRouteMouseOrTabletEvent(const AnnotatorEngine::EventType eventType, const AnnotatorEngine::Button button, const AnnotatorEngine::Modifiers modifiers, const QPointF pos, PageViewItem *item) +{ + // creationCompleted is intended to be set by event(), handled subsequently by end(), and cleared within end(). + // If it's set here, we recursed for some reason (e.g., stacked event loop). + // Just bail out, all we want to do is already on stack. + if (m_engine->creationCompleted()) { + return QRect(); + } + + // if the right mouse button was pressed, we simply do nothing. In this way, we are still editing the annotation + // and so this function will receive and process the right mouse button release event too. If we detach now the annotation tool, + // the release event will be processed by the PageView class which would create the annotation property widget, and we do not want this. + if (button == AnnotatorEngine::Right && eventType == AnnotatorEngine::Press) + return QRect(); + else if (button == AnnotatorEngine::Right && eventType == AnnotatorEngine::Release) { + detachAnnotation(); + return QRect(); + } + + // 1. lock engine to current item + if (!m_lockedItem && eventType == AnnotatorEngine::Press) { + m_lockedItem = item; + m_engine->setItem(m_lockedItem); + } + if (!m_lockedItem) { + return QRect(); + } + + // find out normalized mouse coords inside current item + const QRect &itemRect = m_lockedItem->uncroppedGeometry(); + const QPointF eventPos = m_pageView->contentAreaPoint(pos); + const double nX = qBound(0.0, m_lockedItem->absToPageX(eventPos.x()), 1.0); + const double nY = qBound(0.0, m_lockedItem->absToPageY(eventPos.y()), 1.0); + + QRect modifiedRect; + + // 2. use engine to perform operations + const QRect paintRect = m_engine->event(eventType, button, modifiers, nX, nY, itemRect.width(), itemRect.height(), m_lockedItem->page()); + + // 3. update absolute extents rect and send paint event(s) + if (paintRect.isValid()) { + // 3.1. unite old and new painting regions + QRegion compoundRegion(m_lastDrawnRect); + m_lastDrawnRect = paintRect; + m_lastDrawnRect.translate(itemRect.left(), itemRect.top()); + // 3.2. decompose paint region in rects and send paint events + const QRegion rgn = compoundRegion.united(m_lastDrawnRect); + const QPoint areaPos = m_pageView->contentAreaPosition(); + for (const QRect &r : rgn) + m_pageView->viewport()->update(r.translated(-areaPos)); + modifiedRect = compoundRegion.boundingRect() | m_lastDrawnRect; + } + + // 4. if engine has finished, apply Annotation to the page + if (m_engine->creationCompleted()) { + // apply engine data to the Annotation's and reset engine + const QList annotations = m_engine->end(); + // attach the newly filled annotations to the page + for (Okular::Annotation *annotation : annotations) { + if (!annotation) + continue; + + annotation->setCreationDate(QDateTime::currentDateTime()); + annotation->setModificationDate(QDateTime::currentDateTime()); + annotation->setAuthor(Okular::Settings::identityAuthor()); + m_document->addPageAnnotation(m_lockedItem->pageNumber(), annotation); + + if (annotation->openDialogAfterCreation()) + m_pageView->openAnnotationWindow(annotation, m_lockedItem->pageNumber()); + } + + if (m_continuousMode) + selectTool(m_lastToolId, ShowTip::No); + else + detachAnnotation(); + } + + return modifiedRect; +} + +QRect PageViewAnnotator::routeMouseEvent(QMouseEvent *e, PageViewItem *item) +{ + AnnotatorEngine::EventType eventType; + AnnotatorEngine::Button button; + AnnotatorEngine::Modifiers modifiers; + + // figure out the event type and button + AnnotatorEngine::decodeEvent(e, &eventType, &button); + + // Constrain angle if action checked XOR shift button pressed. + modifiers.constrainRatioAndAngle = (bool(constrainRatioAndAngleActive()) != bool(e->modifiers() & Qt::ShiftModifier)); + + return performRouteMouseOrTabletEvent(eventType, button, modifiers, e->localPos(), item); +} + +QRect PageViewAnnotator::routeTabletEvent(QTabletEvent *e, PageViewItem *item, const QPoint localOriginInGlobal) +{ + // Unlike routeMouseEvent, routeTabletEvent must explicitly ignore events it doesn't care about so that + // the corresponding mouse event will later be delivered. + if (!item) { + e->ignore(); + return QRect(); + } + + AnnotatorEngine::EventType eventType; + AnnotatorEngine::Button button; + AnnotatorEngine::Modifiers modifiers; + + // figure out the event type and button + AnnotatorEngine::decodeEvent(e, &eventType, &button); + + // Constrain angle if action checked XOR shift button pressed. + modifiers.constrainRatioAndAngle = (bool(constrainRatioAndAngleActive()) != bool(e->modifiers() & Qt::ShiftModifier)); + + const QPointF globalPosF = e->globalPosF(); + const QPointF localPosF = globalPosF - localOriginInGlobal; + return performRouteMouseOrTabletEvent(eventType, button, modifiers, localPosF, item); +} + +bool PageViewAnnotator::routeKeyEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape) { + detachAnnotation(); + return true; + } + return false; +} + +bool PageViewAnnotator::routePaints(const QRect wantedRect) const +{ + return m_engine && wantedRect.intersects(m_lastDrawnRect) && m_lockedItem; +} + +void PageViewAnnotator::routePaint(QPainter *painter, const QRect paintRect) +{ + // if there's no locked item, then there's no decided place to draw on + if (!m_lockedItem) + return; + +#ifndef NDEBUG + // [DEBUG] draw the paint region if enabled + if (Okular::Settings::debugDrawAnnotationRect()) + painter->drawRect(paintRect); +#endif + // move painter to current itemGeometry rect + const QRect &itemRect = m_lockedItem->uncroppedGeometry(); + painter->save(); + painter->translate(itemRect.topLeft()); + // TODO: Clip annotation painting to cropped page. + + // transform cliprect from absolute to item relative coords + QRect annotRect = paintRect.intersected(m_lastDrawnRect); + annotRect.translate(-itemRect.topLeft()); + + // use current engine for painting (in virtual page coordinates) + m_engine->paint(painter, m_lockedItem->uncroppedWidth(), m_lockedItem->uncroppedHeight(), annotRect); + painter->restore(); +} + +void PageViewAnnotator::selectTool(int toolId, ShowTip showTip) +{ + // ask for Author's name if not already set + if (toolId > 0 && Okular::Settings::identityAuthor().isEmpty()) { + // get default username from the kdelibs/kdecore/KUser + KUser currentUser; + QString userName = currentUser.property(KUser::FullName).toString(); + // ask the user for confirmation/change + if (userName.isEmpty()) { + bool ok = false; + userName = QInputDialog::getText(nullptr, i18n("Bookmark annotation"), i18n("Insert a custom name for the annotation:"), QLineEdit::Normal, QString(), &ok); + + if (!ok) { + detachAnnotation(); + return; + } + } + // save the name + Okular::Settings::setIdentityAuthor(userName); + Okular::Settings::self()->save(); + } + + // terminate any previous operation + if (m_engine) { + delete m_engine; + m_engine = nullptr; + } + m_lockedItem = nullptr; + if (m_lastDrawnRect.isValid()) { + m_pageView->viewport()->update(m_lastDrawnRect.translated(-m_pageView->contentAreaPosition())); + m_lastDrawnRect = QRect(); + } + + // store current tool for later usage + m_lastToolId = toolId; + + // handle tool deselection + if (toolId == -1) { + m_pageView->displayMessage(QString()); + m_pageView->updateCursor(); + return; + } + + // for the selected tool create the Engine + QDomElement toolElement = m_builtinToolsDefinition->tool(toolId); + if (!toolElement.isNull()) { + // parse tool properties + QDomElement engineElement = toolElement.firstChildElement(QStringLiteral("engine")); + if (!engineElement.isNull()) { + // create the AnnotatorEngine + QString type = engineElement.attribute(QStringLiteral("type")); + if (type == QLatin1String("SmoothLine")) + m_engine = new SmoothPathEngine(engineElement); + else if (type == QLatin1String("PickPoint")) + m_engine = new PickPointEngine(engineElement); + else if (type == QLatin1String("PolyLine")) + m_engine = new PolyLineEngine(engineElement); + else if (type == QLatin1String("TextSelector")) + m_engine = new TextSelectorEngine(engineElement, m_pageView); + else + qCWarning(OkularUiDebug).nospace() << "tools.xml: engine type:'" << type << "' is not defined!"; + + if (showTip == ShowTip::Yes) { + // display the tooltip + const QString annotType = toolElement.attribute(QStringLiteral("type")); + QString tip; + + if (annotType == QLatin1String("ellipse")) + tip = i18nc("Annotation tool", "Draw an ellipse (drag to select a zone)"); + else if (annotType == QLatin1String("highlight")) + tip = i18nc("Annotation tool", "Highlight text"); + else if (annotType == QLatin1String("ink")) + tip = i18nc("Annotation tool", "Draw a freehand line"); + else if (annotType == QLatin1String("note-inline")) + tip = i18nc("Annotation tool", "Inline Text Annotation (drag to select a zone)"); + else if (annotType == QLatin1String("note-linked")) + tip = i18nc("Annotation tool", "Put a pop-up note"); + else if (annotType == QLatin1String("polygon")) + tip = i18nc("Annotation tool", "Draw a polygon (click on the first point to close it)"); + else if (annotType == QLatin1String("rectangle")) + tip = i18nc("Annotation tool", "Draw a rectangle"); + else if (annotType == QLatin1String("squiggly")) + tip = i18nc("Annotation tool", "Squiggle text"); + else if (annotType == QLatin1String("stamp")) + tip = i18nc("Annotation tool", "Put a stamp symbol"); + else if (annotType == QLatin1String("straight-line")) + tip = i18nc("Annotation tool", "Draw a straight line"); + else if (annotType == QLatin1String("strikeout")) + tip = i18nc("Annotation tool", "Strike out text"); + else if (annotType == QLatin1String("underline")) + tip = i18nc("Annotation tool", "Underline text"); + else if (annotType == QLatin1String("typewriter")) + tip = i18nc("Annotation tool", "Typewriter Annotation (drag to select a zone)"); + + if (!tip.isEmpty()) + m_pageView->displayMessage(tip, QString(), PageViewMessage::Annotation); + } + } + + // consistency warning + if (!m_engine) { + qCWarning(OkularUiDebug) << "tools.xml: couldn't find good engine description. check xml."; + } + + m_pageView->updateCursor(); + } + + if (toolId > 0) + emit toolSelected(); +} + +void PageViewAnnotator::selectStampTool(const QString &stampSymbol) +{ + QDomElement toolElement = builtinTool(STAMP_TOOL_ID); + QDomElement engineElement = toolElement.firstChildElement(QStringLiteral("engine")); + QDomElement annotationElement = engineElement.firstChildElement(QStringLiteral("annotation")); + engineElement.setAttribute(QStringLiteral("hoverIcon"), stampSymbol); + annotationElement.setAttribute(QStringLiteral("icon"), stampSymbol); + saveBuiltinAnnotationTools(); + selectTool(STAMP_TOOL_ID, ShowTip::Yes); +} + +void PageViewAnnotator::detachAnnotation() +{ + selectTool(-1, ShowTip::No); + if (m_actionHandler) + m_actionHandler->deselectAllAnnotationActions(); +} + +QString PageViewAnnotator::defaultToolName(const QDomElement &toolElement) +{ + const QString annotType = toolElement.attribute(QStringLiteral("type")); + + if (annotType == QLatin1String("ellipse")) + return i18n("Ellipse"); + else if (annotType == QLatin1String("highlight")) + return i18n("Highlighter"); + else if (annotType == QLatin1String("ink")) + return i18n("Freehand Line"); + else if (annotType == QLatin1String("note-inline")) + return i18n("Inline Note"); + else if (annotType == QLatin1String("note-linked")) + return i18n("Pop-up Note"); + else if (annotType == QLatin1String("polygon")) + return i18n("Polygon"); + else if (annotType == QLatin1String("rectangle")) + return i18n("Rectangle"); + else if (annotType == QLatin1String("squiggly")) + return i18n("Squiggle"); + else if (annotType == QLatin1String("stamp")) + return i18n("Stamp"); + else if (annotType == QLatin1String("straight-line")) + return i18n("Straight Line"); + else if (annotType == QLatin1String("strikeout")) + return i18n("Strike out"); + else if (annotType == QLatin1String("underline")) + return i18n("Underline"); + else if (annotType == QLatin1String("typewriter")) + return i18n("Typewriter"); + else + return QString(); +} + +QPixmap PageViewAnnotator::makeToolPixmap(const QDomElement &toolElement) +{ + QPixmap pixmap(32 * qApp->devicePixelRatio(), 32 * qApp->devicePixelRatio()); + pixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + const QString annotType = toolElement.attribute(QStringLiteral("type")); + + // Load HiDPI variant on HiDPI screen + QString imageVariant; + if (qApp->devicePixelRatio() > 1.05) { + imageVariant = QStringLiteral("@2x"); + } + + // Load base pixmap. We'll draw on top of it + pixmap.load(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-base-okular" + imageVariant + ".png"))); + + /* Parse color, innerColor and icon (if present) */ + QColor engineColor, innerColor, textColor, annotColor; + QString icon; + QDomNodeList engineNodeList = toolElement.elementsByTagName(QStringLiteral("engine")); + if (engineNodeList.size() > 0) { + QDomElement engineEl = engineNodeList.item(0).toElement(); + if (!engineEl.isNull() && engineEl.hasAttribute(QStringLiteral("color"))) + engineColor = QColor(engineEl.attribute(QStringLiteral("color"))); + } + QDomNodeList annotationNodeList = toolElement.elementsByTagName(QStringLiteral("annotation")); + if (annotationNodeList.size() > 0) { + QDomElement annotationEl = annotationNodeList.item(0).toElement(); + if (!annotationEl.isNull()) { + if (annotationEl.hasAttribute(QStringLiteral("color"))) + annotColor = annotationEl.attribute(QStringLiteral("color")); + if (annotationEl.hasAttribute(QStringLiteral("innerColor"))) + innerColor = QColor(annotationEl.attribute(QStringLiteral("innerColor"))); + if (annotationEl.hasAttribute(QStringLiteral("textColor"))) + textColor = QColor(annotationEl.attribute(QStringLiteral("textColor"))); + if (annotationEl.hasAttribute(QStringLiteral("icon"))) + icon = annotationEl.attribute(QStringLiteral("icon")); + } + } + + QPainter p(&pixmap); + + if (annotType == QLatin1String("ellipse")) { + p.setRenderHint(QPainter::Antialiasing); + if (innerColor.isValid()) + p.setBrush(innerColor); + p.setPen(QPen(engineColor, 2)); + p.drawEllipse(2, 7, 21, 14); + } else if (annotType == QLatin1String("highlight")) { + QImage overlay(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-highlighter-okular-colorizable" + imageVariant + ".png"))); + QImage colorizedOverlay = overlay; + GuiUtils::colorizeImage(colorizedOverlay, engineColor); + + p.drawImage(QPoint(0, 0), colorizedOverlay); // Trail + p.drawImage(QPoint(0, -32), overlay); // Text + Shadow (uncolorized) + p.drawImage(QPoint(0, -64), colorizedOverlay); // Pen + } else if (annotType == QLatin1String("ink")) { + QImage overlay(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-ink-okular-colorizable" + imageVariant + ".png"))); + QImage colorizedOverlay = overlay; + GuiUtils::colorizeImage(colorizedOverlay, engineColor); + + p.drawImage(QPoint(0, 0), colorizedOverlay); // Trail + p.drawImage(QPoint(0, -32), overlay); // Shadow (uncolorized) + p.drawImage(QPoint(0, -64), colorizedOverlay); // Pen + } else if (annotType == QLatin1String("note-inline")) { + QImage overlay(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-note-inline-okular-colorizable" + imageVariant + ".png"))); + GuiUtils::colorizeImage(overlay, engineColor); + p.drawImage(QPoint(0, 0), overlay); + } else if (annotType == QLatin1String("note-linked")) { + QImage overlay(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-note-okular-colorizable" + imageVariant + ".png"))); + GuiUtils::colorizeImage(overlay, engineColor); + p.drawImage(QPoint(0, 0), overlay); + } else if (annotType == QLatin1String("polygon")) { + QPainterPath path; + path.moveTo(0, 7); + path.lineTo(19, 7); + path.lineTo(19, 14); + path.lineTo(23, 14); + path.lineTo(23, 20); + path.lineTo(0, 20); + if (innerColor.isValid()) + p.setBrush(innerColor); + p.setPen(QPen(engineColor, 1)); + p.drawPath(path); + } else if (annotType == QLatin1String("rectangle")) { + p.setRenderHint(QPainter::Antialiasing); + if (innerColor.isValid()) + p.setBrush(innerColor); + p.setPen(QPen(engineColor, 2)); + p.drawRect(2, 7, 21, 14); + } else if (annotType == QLatin1String("squiggly")) { + QPen pen(engineColor, 1); + pen.setDashPattern(QVector() << 1 << 1); + p.setPen(pen); + p.drawLine(1, 13, 16, 13); + p.drawLine(2, 14, 15, 14); + p.drawLine(0, 20, 19, 20); + p.drawLine(1, 21, 18, 21); + } else if (annotType == QLatin1String("stamp")) { + QPixmap stamp = GuiUtils::loadStamp(icon, 16, false /* keepAspectRatio */); + p.setRenderHint(QPainter::Antialiasing); + p.drawPixmap(16, 14, stamp); + } else if (annotType == QLatin1String("straight-line")) { + QPainterPath path; + path.moveTo(1, 8); + path.lineTo(20, 8); + path.lineTo(1, 27); + path.lineTo(20, 27); + p.setRenderHint(QPainter::Antialiasing); + p.setPen(QPen(engineColor, 1)); + p.drawPath(path); // TODO To be discussed: This is not a straight line! + } else if (annotType == QLatin1String("strikeout")) { + p.setPen(QPen(engineColor, 1)); + p.drawLine(1, 10, 16, 10); + p.drawLine(0, 17, 19, 17); + } else if (annotType == QLatin1String("underline")) { + p.setPen(QPen(engineColor, 1)); + p.drawLine(1, 13, 16, 13); + p.drawLine(0, 20, 19, 20); + } else if (annotType == QLatin1String("typewriter")) { + QImage overlay(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString("okular/pics/tool-typewriter-okular-colorizable" + imageVariant + ".png"))); + GuiUtils::colorizeImage(overlay, textColor); + p.drawImage(QPoint(-2, 2), overlay); + } else { + /* Unrecognized annotation type -- It shouldn't happen */ + p.setPen(QPen(engineColor)); + p.drawText(QPoint(20, 31), QStringLiteral("?")); + } + + return pixmap; +} + +void PageViewAnnotator::setupActions(KActionCollection *ac) +{ + if (!m_actionHandler) { + m_actionHandler = new AnnotationActionHandler(this, ac); + } +} + +void PageViewAnnotator::setupActionsPostGUIActivated() +{ + m_actionHandler->setupAnnotationToolBarVisibilityAction(); +} + +bool PageViewAnnotator::continuousMode() +{ + return m_continuousMode; +} + +void PageViewAnnotator::setContinuousMode(bool enabled) +{ + m_continuousMode = enabled; + Okular::Settings::setAnnotationContinuousMode(enabled); + Okular::Settings::self()->save(); +} + +bool PageViewAnnotator::constrainRatioAndAngleActive() +{ + return m_constrainRatioAndAngle; +} + +void PageViewAnnotator::setConstrainRatioAndAngle(bool enabled) +{ + m_constrainRatioAndAngle = enabled; +} + +void PageViewAnnotator::setToolsEnabled(bool enabled) +{ + if (m_actionHandler) + m_actionHandler->setToolsEnabled(enabled); +} + +void PageViewAnnotator::setTextToolsEnabled(bool enabled) +{ + if (m_actionHandler) + m_actionHandler->setTextToolsEnabled(enabled); +} + +void PageViewAnnotator::saveBuiltinAnnotationTools() +{ + Okular::Settings::setBuiltinAnnotationTools(m_builtinToolsDefinition->toStringList()); + Okular::Settings::self()->save(); +} + +int PageViewAnnotator::setQuickTool(int favToolId) +{ + int toolId = -1; + QDomElement favToolElement = m_quickToolsDefinition->tool(favToolId); + if (!favToolElement.isNull()) { + toolId = m_builtinToolsDefinition->findToolId(favToolElement.attribute(QStringLiteral("type"))); + if (toolId == -1) { + return -1; + } + if (m_builtinToolsDefinition->updateTool(favToolElement, toolId)) + saveBuiltinAnnotationTools(); + } + return toolId; +} + +QDomElement PageViewAnnotator::builtinTool(int toolId) +{ + return m_builtinToolsDefinition->tool(toolId); +} + +QDomElement PageViewAnnotator::quickTool(int toolId) +{ + return m_quickToolsDefinition->tool(toolId); +} + +QDomElement PageViewAnnotator::currentEngineElement() +{ + return m_builtinToolsDefinition->tool(m_lastToolId).firstChildElement(QStringLiteral("engine")); +} + +QDomElement PageViewAnnotator::currentAnnotationElement() +{ + return currentEngineElement().firstChildElement(QStringLiteral("annotation")); +} + +void PageViewAnnotator::setAnnotationWidth(double width) +{ + currentAnnotationElement().setAttribute(QStringLiteral("width"), QString::number(width)); + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +void PageViewAnnotator::setAnnotationColor(const QColor &color) +{ + currentEngineElement().setAttribute(QStringLiteral("color"), color.name(QColor::HexRgb)); + QDomElement annotationElement = currentAnnotationElement(); + QString annotType = annotationElement.attribute(QStringLiteral("type")); + if (annotType == QLatin1String("Typewriter")) { + annotationElement.setAttribute(QStringLiteral("textColor"), color.name(QColor::HexRgb)); + } else { + annotationElement.setAttribute(QStringLiteral("color"), color.name(QColor::HexRgb)); + } + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +void PageViewAnnotator::setAnnotationInnerColor(const QColor &color) +{ + QDomElement annotationElement = currentAnnotationElement(); + if (color == Qt::transparent) { + annotationElement.removeAttribute(QStringLiteral("innerColor")); + } else { + annotationElement.setAttribute(QStringLiteral("innerColor"), color.name(QColor::HexRgb)); + } + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +void PageViewAnnotator::setAnnotationOpacity(double opacity) +{ + currentAnnotationElement().setAttribute(QStringLiteral("opacity"), QString::number(opacity)); + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +void PageViewAnnotator::setAnnotationFont(const QFont &font) +{ + currentAnnotationElement().setAttribute(QStringLiteral("font"), font.toString()); + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +void PageViewAnnotator::addToQuickAnnotations() +{ + QDomElement sourceToolElement = m_builtinToolsDefinition->tool(m_lastToolId); + if (sourceToolElement.isNull()) + return; + + // set custom name for quick annotation + bool ok = false; + QString itemText = QInputDialog::getText(nullptr, i18n("Add favorite annotation"), i18n("Custom annotation name:"), QLineEdit::Normal, defaultToolName(sourceToolElement), &ok); + if (!ok) + return; + + QDomElement toolElement = sourceToolElement.cloneNode().toElement(); + // store name attribute only if the user specified a customized name + if (!itemText.isEmpty()) + toolElement.setAttribute(QStringLiteral("name"), itemText); + m_quickToolsDefinition->appendTool(toolElement); + Okular::Settings::setQuickAnnotationTools(m_quickToolsDefinition->toStringList()); + Okular::Settings::self()->save(); +} + +void PageViewAnnotator::slotAdvancedSettings() +{ + QDomElement toolElement = m_builtinToolsDefinition->tool(m_lastToolId); + + EditAnnotToolDialog t(nullptr, toolElement, true); + if (t.exec() != QDialog::Accepted) + return; + + QDomElement toolElementUpdated = t.toolXml().documentElement(); + int toolId = toolElement.attribute(QStringLiteral("id")).toInt(); + m_builtinToolsDefinition->updateTool(toolElementUpdated, toolId); + saveBuiltinAnnotationTools(); + selectTool(m_lastToolId, ShowTip::No); +} + +#include "moc_pageviewannotator.cpp" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/pageviewannotator.h b/part/pageviewannotator.h new file mode 100644 index 0000000..a3ef239 --- /dev/null +++ b/part/pageviewannotator.h @@ -0,0 +1,170 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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_PAGEVIEWANNOTATOR_H_ +#define _OKULAR_PAGEVIEWANNOTATOR_H_ + +#include +#include +#include + +#include + +#include "annotationtools.h" +#include "pageviewutils.h" + +class QKeyEvent; +class QMouseEvent; +class QPainter; +class AnnotationActionHandler; + +namespace Okular +{ +class Document; +} + +// engines are defined and implemented in the cpp +class AnnotatorEngine; +class AnnotationTools; +class PageView; + +/** + * @short PageView object devoted to annotation creation/handling. + * + * PageViewAnnotator is the okular class used for visually creating annotations. + * It uses internal 'engines' for interacting with user events and attaches + * the newly created annotation to the document when the creation is complete. + * In the meanwhile all PageView events (actually mouse/paint ones) are routed + * to this class that performs a rough visual representation of what the + * annotation will become when finished. + * + * m_builtinToolsDefinition is a AnnotationTools object that wraps a DOM object that + * contains Annotations/Engine association for the items placed in the toolbar. + * The XML is parsed after selecting a toolbar item, in which case an Ann is + * initialized with the values in the XML and an engine is created to handle + * that annotation. m_builtinToolsDefinition is created in reparseConfig according to + * user configuration. m_builtinToolsDefinition is updated (and saved to disk) (1) each + * time a property of an annotation (color, font, etc) is changed by the user, + * and (2) each time a "quick annotation" is selected, in which case the properties + * of the selected quick annotation are written over those of the corresponding + * builtin tool + */ +class PageViewAnnotator : public QObject +{ + Q_OBJECT +public: + static const int STAMP_TOOL_ID; + + PageViewAnnotator(PageView *parent, Okular::Document *storage); + ~PageViewAnnotator() override; + + // methods used when creating the annotation + // @return Is a tool currently selected? + bool active() const; + // @return Are we currently annotating (using the selected tool)? + bool annotating() const; + + // returns the preferred cursor for the current tool. call this only + // if active() == true + QCursor cursor() const; + + QRect routeMouseEvent(QMouseEvent *event, PageViewItem *item); + QRect routeTabletEvent(QTabletEvent *event, PageViewItem *item, const QPoint localOriginInGlobal); + QRect performRouteMouseOrTabletEvent(const AnnotatorEngine::EventType eventType, const AnnotatorEngine::Button button, const AnnotatorEngine::Modifiers modifiers, const QPointF pos, PageViewItem *item); + bool routeKeyEvent(QKeyEvent *event); + bool routePaints(const QRect wantedRect) const; + void routePaint(QPainter *painter, const QRect paintRect); + + void reparseConfig(); + + static QString defaultToolName(const QDomElement &toolElement); + static QPixmap makeToolPixmap(const QDomElement &toolElement); + + // methods related to the annotation actions + void setupActions(KActionCollection *ac); + // setup those actions that first require the GUI is fully created + void setupActionsPostGUIActivated(); + // @return Is continuous mode active (pin annotation)? + bool continuousMode(); + /** + * State of constrain ratio and angle action. + * While annotating, this value is XOR-ed with the Shift modifier. + */ + bool constrainRatioAndAngleActive(); + // enable/disable the annotation actions + void setToolsEnabled(bool enabled); + // enable/disable the text-selection annotation actions + void setTextToolsEnabled(bool enabled); + + enum class ShowTip { Yes, No }; + // selects the active tool + void selectTool(int toolId, ShowTip showTip); + // selects a stamp tool and sets the stamp symbol + void selectStampTool(const QString &stampSymbol); + // makes a quick annotation the active tool + int setQuickTool(int toolId); + // deselects the tool and uncheck all the annotation actions + void detachAnnotation(); + + // returns the builtin annotation tool with the given Id + QDomElement builtinTool(int toolId); + // returns the quick annotation tool with the given Id + QDomElement quickTool(int toolId); + + // methods that write the properties + void setAnnotationWidth(double width); + void setAnnotationColor(const QColor &color); + void setAnnotationInnerColor(const QColor &color); + void setAnnotationOpacity(double opacity); + void setAnnotationFont(const QFont &font); + +public Q_SLOTS: + void setContinuousMode(bool enabled); + /** + * State of constrain ratio and angle action. + * While annotating, this value is XOR-ed with the Shift modifier. + */ + void setConstrainRatioAndAngle(bool enabled); + void addToQuickAnnotations(); + void slotAdvancedSettings(); + +Q_SIGNALS: + void toolSelected(); + +private: + void reparseBuiltinToolsConfig(); + void reparseQuickToolsConfig(); + // save the builtin annotation tools to Okular settings + void saveBuiltinAnnotationTools(); + // returns the engine QDomElement of the the currently active tool + QDomElement currentEngineElement(); + // returns the annotation QDomElement of the the currently active tool + QDomElement currentAnnotationElement(); + + // global class pointers + Okular::Document *m_document; + PageView *m_pageView; + AnnotationActionHandler *m_actionHandler; + AnnotatorEngine *m_engine; + AnnotationTools *m_builtinToolsDefinition; + AnnotationTools *m_quickToolsDefinition; + bool m_continuousMode; + bool m_constrainRatioAndAngle; + + // creation related variables + int m_lastToolId; + QRect m_lastDrawnRect; + PageViewItem *m_lockedItem; + // selected annotation name + // QString m_selectedAnnotationName; +}; + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/pageviewmouseannotation.cpp b/part/pageviewmouseannotation.cpp new file mode 100644 index 0000000..9bb9837 --- /dev/null +++ b/part/pageviewmouseannotation.cpp @@ -0,0 +1,645 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tobias Deiminger * + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2006 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * With portions of code from kpdf/kpdf_pagewidget.cc by: * + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2003 by Christophe Devriese * + * * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2003 by Dirk Mueller * + * Copyright (C) 2004 by James Ots * + * Copyright (C) 2011 by Jiri Baum - NICTA * + * * + * 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. * + ***************************************************************************/ + +#include "pageviewmouseannotation.h" + +#include +#include +#include + +#include "core/document.h" +#include "core/page.h" +#include "guiutils.h" +#include "pageview.h" +#include "videowidget.h" + +static const int handleSize = 10; +static const int handleSizeHalf = handleSize / 2; + +bool AnnotationDescription::isValid() const +{ + return (annotation != nullptr); +} + +bool AnnotationDescription::isContainedInPage(const Okular::Document *document, int pageNumber) const +{ + if (AnnotationDescription::pageNumber == pageNumber) { + /* Don't access page via pageViewItem here. pageViewItem might have been deleted. */ + const Okular::Page *page = document->page(pageNumber); + if (page != nullptr) { + if (page->annotations().contains(annotation)) { + return true; + } + } + } + return false; +} + +void AnnotationDescription::invalidate() +{ + annotation = nullptr; + pageViewItem = nullptr; + pageNumber = -1; +} + +AnnotationDescription::AnnotationDescription(PageViewItem *newPageViewItem, const QPoint eventPos) +{ + const Okular::AnnotationObjectRect *annObjRect = nullptr; + if (newPageViewItem) { + const QRect &uncroppedPage = newPageViewItem->uncroppedGeometry(); + /* find out normalized mouse coords inside current item (nX and nY will be in the range of 0..1). */ + const double nX = newPageViewItem->absToPageX(eventPos.x()); + const double nY = newPageViewItem->absToPageY(eventPos.y()); + annObjRect = (Okular::AnnotationObjectRect *)newPageViewItem->page()->objectRect(Okular::ObjectRect::OAnnotation, nX, nY, uncroppedPage.width(), uncroppedPage.height()); + } + + if (annObjRect) { + annotation = annObjRect->annotation(); + pageViewItem = newPageViewItem; + pageNumber = pageViewItem->pageNumber(); + } else { + invalidate(); + } +} + +MouseAnnotation::MouseAnnotation(PageView *parent, Okular::Document *document) + : QObject(parent) + , m_document(document) + , m_pageView(parent) + , m_state(StateInactive) + , m_handle(RH_None) +{ + m_resizeHandleList << RH_Left << RH_Right << RH_Top << RH_Bottom << RH_TopLeft << RH_TopRight << RH_BottomLeft << RH_BottomRight; +} + +MouseAnnotation::~MouseAnnotation() +{ +} + +void MouseAnnotation::routeMousePressEvent(PageViewItem *pageViewItem, const QPoint eventPos) +{ + /* Is there a selected annotation? */ + if (m_focusedAnnotation.isValid()) { + m_mousePosition = eventPos - pageViewItem->uncroppedGeometry().topLeft(); + m_handle = getHandleAt(m_mousePosition, m_focusedAnnotation); + if (m_handle != RH_None) { + /* Returning here means, the selection-rectangle gets control, unconditionally. + * Even if it overlaps with another annotation. */ + return; + } + } + + AnnotationDescription ad(pageViewItem, eventPos); + /* qDebug() << "routeMousePressEvent: eventPos = " << eventPos; */ + if (ad.isValid()) { + if (ad.annotation->subType() == Okular::Annotation::AMovie || ad.annotation->subType() == Okular::Annotation::AScreen || ad.annotation->subType() == Okular::Annotation::AFileAttachment) { + /* qDebug() << "routeMousePressEvent: trigger action for AMovie/AScreen/AFileAttachment"; */ + processAction(ad); + } else { + /* qDebug() << "routeMousePressEvent: select for modification"; */ + m_mousePosition = eventPos - pageViewItem->uncroppedGeometry().topLeft(); + m_handle = getHandleAt(m_mousePosition, ad); + if (m_handle != RH_None) { + setState(StateFocused, ad); + } + } + } else { + /* qDebug() << "routeMousePressEvent: no annotation under mouse, enter StateInactive"; */ + setState(StateInactive, ad); + } +} + +void MouseAnnotation::routeMouseReleaseEvent() +{ + if (isModified()) { + /* qDebug() << "routeMouseReleaseEvent: finish command"; */ + finishCommand(); + setState(StateFocused, m_focusedAnnotation); + } + /* + else + { + qDebug() << "routeMouseReleaseEvent: ignore"; + } + */ +} + +void MouseAnnotation::routeMouseMoveEvent(PageViewItem *pageViewItem, const QPoint eventPos, bool leftButtonPressed) +{ + if (!pageViewItem) { + /* qDebug() << "routeMouseMoveEvent: no pageViewItem provided, ignore"; */ + return; + } + + if (leftButtonPressed) { + if (isFocused()) { + /* On first move event after annotation is selected, enter modification state */ + if (m_handle == RH_Content) { + /* qDebug() << "routeMouseMoveEvent: handle " << m_handle << ", enter StateMoving"; */ + setState(StateMoving, m_focusedAnnotation); + } else if (m_handle != RH_None) { + /* qDebug() << "routeMouseMoveEvent: handle " << m_handle << ", enter StateResizing"; */ + setState(StateResizing, m_focusedAnnotation); + } + } + + if (isModified()) { + /* qDebug() << "routeMouseMoveEvent: perform command, delta " << eventPos - m_mousePosition; */ + updateViewport(m_focusedAnnotation); + performCommand(eventPos); + m_mousePosition = eventPos - pageViewItem->uncroppedGeometry().topLeft(); + updateViewport(m_focusedAnnotation); + } + } else { + if (isFocused()) { + /* qDebug() << "routeMouseMoveEvent: update cursor for focused annotation, new eventPos " << eventPos; */ + m_mousePosition = eventPos - pageViewItem->uncroppedGeometry().topLeft(); + m_handle = getHandleAt(m_mousePosition, m_focusedAnnotation); + m_pageView->updateCursor(); + } + + /* We get here quite frequently. */ + const AnnotationDescription ad(pageViewItem, eventPos); + m_mousePosition = eventPos - pageViewItem->uncroppedGeometry().topLeft(); + if (ad.isValid()) { + if (!(m_mouseOverAnnotation == ad)) { + /* qDebug() << "routeMouseMoveEvent: Annotation under mouse (subtype " << ad.annotation->subType() << ", flags " << ad.annotation->flags() << ")"; */ + m_mouseOverAnnotation = ad; + m_pageView->updateCursor(); + } + } else { + if (!(m_mouseOverAnnotation == ad)) { + /* qDebug() << "routeMouseMoveEvent: Annotation disappeared under mouse."; */ + m_mouseOverAnnotation.invalidate(); + m_pageView->updateCursor(); + } + } + } +} + +void MouseAnnotation::routeKeyPressEvent(const QKeyEvent *e) +{ + switch (e->key()) { + case Qt::Key_Escape: + cancel(); + break; + case Qt::Key_Delete: + if (m_focusedAnnotation.isValid()) { + AnnotationDescription adToBeDeleted = m_focusedAnnotation; + cancel(); + m_document->removePageAnnotation(adToBeDeleted.pageNumber, adToBeDeleted.annotation); + } + break; + } +} + +void MouseAnnotation::routeTooltipEvent(const QHelpEvent *helpEvent) +{ + /* qDebug() << "MouseAnnotation::routeTooltipEvent, event " << helpEvent; */ + if (m_mouseOverAnnotation.isValid() && m_mouseOverAnnotation.annotation->subType() != Okular::Annotation::AWidget) { + /* get boundingRect in uncropped page coordinates */ + QRect boundingRect = Okular::AnnotationUtils::annotationGeometry(m_mouseOverAnnotation.annotation, m_mouseOverAnnotation.pageViewItem->uncroppedWidth(), m_mouseOverAnnotation.pageViewItem->uncroppedHeight()); + + /* uncropped page to content area */ + boundingRect.translate(m_mouseOverAnnotation.pageViewItem->uncroppedGeometry().topLeft()); + /* content area to viewport */ + boundingRect.translate(-m_pageView->contentAreaPosition()); + + const QString tip = GuiUtils::prettyToolTip(m_mouseOverAnnotation.annotation); + QToolTip::showText(helpEvent->globalPos(), tip, m_pageView->viewport(), boundingRect); + } +} + +void MouseAnnotation::routePaint(QPainter *painter, const QRect paintRect) +{ + /* QPainter draws relative to the origin of uncropped viewport. */ + static const QColor borderColor = QColor::fromHsvF(0, 0, 1.0); + static const QColor fillColor = QColor::fromHsvF(0, 0, 0.75, 0.66); + + if (!isFocused()) + return; + /* + * Get annotation bounding rectangle in uncropped page coordinates. + * Distinction between AnnotationUtils::annotationGeometry() and AnnotationObjectRect::boundingRect() is, + * that boundingRect would enlarge the QRect to a minimum size of 14 x 14. + * This is useful for getting focus an a very small annotation, + * but for drawing and modification we want the real size. + */ + const QRect boundingRect = Okular::AnnotationUtils::annotationGeometry(m_focusedAnnotation.annotation, m_focusedAnnotation.pageViewItem->uncroppedWidth(), m_focusedAnnotation.pageViewItem->uncroppedHeight()); + + if (!paintRect.intersects(boundingRect.translated(m_focusedAnnotation.pageViewItem->uncroppedGeometry().topLeft()).adjusted(-handleSizeHalf, -handleSizeHalf, handleSizeHalf, handleSizeHalf))) { + /* Our selection rectangle is not in a region that needs to be (re-)drawn. */ + return; + } + + painter->save(); + painter->translate(m_focusedAnnotation.pageViewItem->uncroppedGeometry().topLeft()); + painter->setPen(QPen(fillColor, 2, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); + painter->drawRect(boundingRect); + if (m_focusedAnnotation.annotation->canBeResized()) { + painter->setPen(borderColor); + painter->setBrush(fillColor); + for (const ResizeHandle &handle : qAsConst(m_resizeHandleList)) { + QRect rect = getHandleRect(handle, m_focusedAnnotation); + painter->drawRect(rect); + } + } + painter->restore(); +} + +Okular::Annotation *MouseAnnotation::annotation() const +{ + if (m_focusedAnnotation.isValid()) { + return m_focusedAnnotation.annotation; + } + return nullptr; +} + +bool MouseAnnotation::isActive() const +{ + return (m_state != StateInactive); +} + +bool MouseAnnotation::isMouseOver() const +{ + return (m_mouseOverAnnotation.isValid() || m_handle != RH_None); +} + +bool MouseAnnotation::isFocused() const +{ + return (m_state == StateFocused); +} + +bool MouseAnnotation::isMoved() const +{ + return (m_state == StateMoving); +} + +bool MouseAnnotation::isResized() const +{ + return (m_state == StateResizing); +} + +bool MouseAnnotation::isModified() const +{ + return (m_state == StateMoving || m_state == StateResizing); +} + +Qt::CursorShape MouseAnnotation::cursor() const +{ + if (m_handle != RH_None) { + if (isMoved()) { + return Qt::SizeAllCursor; + } else if (isFocused() || isResized()) { + switch (m_handle) { + case RH_Top: + return Qt::SizeVerCursor; + case RH_TopRight: + return Qt::SizeBDiagCursor; + case RH_Right: + return Qt::SizeHorCursor; + case RH_BottomRight: + return Qt::SizeFDiagCursor; + case RH_Bottom: + return Qt::SizeVerCursor; + case RH_BottomLeft: + return Qt::SizeBDiagCursor; + case RH_Left: + return Qt::SizeHorCursor; + case RH_TopLeft: + return Qt::SizeFDiagCursor; + case RH_Content: + return Qt::SizeAllCursor; + default: + return Qt::OpenHandCursor; + } + } + } else if (m_mouseOverAnnotation.isValid()) { + /* Mouse is over annotation, but the annotation is not yet selected. */ + if (m_mouseOverAnnotation.annotation->subType() == Okular::Annotation::AMovie) { + return Qt::PointingHandCursor; + } else if (m_mouseOverAnnotation.annotation->subType() == Okular::Annotation::ARichMedia) { + return Qt::PointingHandCursor; + } else if (m_mouseOverAnnotation.annotation->subType() == Okular::Annotation::AScreen) { + if (GuiUtils::renditionMovieFromScreenAnnotation(static_cast(m_mouseOverAnnotation.annotation)) != nullptr) { + return Qt::PointingHandCursor; + } + } else if (m_mouseOverAnnotation.annotation->subType() == Okular::Annotation::AFileAttachment) { + return Qt::PointingHandCursor; + } else { + return Qt::ArrowCursor; + } + } + + /* There's no none cursor, so we still have to return something. */ + return Qt::ArrowCursor; +} + +void MouseAnnotation::notifyAnnotationChanged(int pageNumber) +{ + const AnnotationDescription emptyAd; + + if (m_focusedAnnotation.isValid() && !m_focusedAnnotation.isContainedInPage(m_document, pageNumber)) { + setState(StateInactive, emptyAd); + } + + if (m_mouseOverAnnotation.isValid() && !m_mouseOverAnnotation.isContainedInPage(m_document, pageNumber)) { + m_mouseOverAnnotation = emptyAd; + m_pageView->updateCursor(); + } +} + +void MouseAnnotation::updateAnnotationPointers() +{ + if (m_focusedAnnotation.annotation) { + m_focusedAnnotation.annotation = m_document->page(m_focusedAnnotation.pageNumber)->annotation(m_focusedAnnotation.annotation->uniqueName()); + } + + if (m_mouseOverAnnotation.annotation) { + m_mouseOverAnnotation.annotation = m_document->page(m_mouseOverAnnotation.pageNumber)->annotation(m_mouseOverAnnotation.annotation->uniqueName()); + } +} + +void MouseAnnotation::cancel() +{ + if (isActive()) { + finishCommand(); + setState(StateInactive, m_focusedAnnotation); + } +} + +void MouseAnnotation::reset() +{ + cancel(); + m_focusedAnnotation.invalidate(); + m_mouseOverAnnotation.invalidate(); +} + +/* Handle state changes for the focused annotation. */ +void MouseAnnotation::setState(MouseAnnotationState state, const AnnotationDescription &ad) +{ + /* qDebug() << "setState: requested " << state; */ + if (m_focusedAnnotation.isValid()) { + /* If there was a annotation before, request also repaint for the previous area. */ + updateViewport(m_focusedAnnotation); + } + + if (!ad.isValid()) { + /* qDebug() << "No annotation provided, forcing state inactive." << state; */ + state = StateInactive; + } else if ((state == StateMoving && !ad.annotation->canBeMoved()) || (state == StateResizing && !ad.annotation->canBeResized())) { + /* qDebug() << "Annotation does not support requested state, forcing state selected." << state; */ + state = StateInactive; + } + + switch (state) { + case StateMoving: + m_focusedAnnotation = ad; + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() | Okular::Annotation::BeingMoved); + updateViewport(m_focusedAnnotation); + break; + case StateResizing: + m_focusedAnnotation = ad; + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() | Okular::Annotation::BeingResized); + updateViewport(m_focusedAnnotation); + break; + case StateFocused: + m_focusedAnnotation = ad; + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() & ~(Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)); + updateViewport(m_focusedAnnotation); + break; + case StateInactive: + default: + if (m_focusedAnnotation.isValid()) { + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() & ~(Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)); + } + m_focusedAnnotation.invalidate(); + m_handle = RH_None; + } + + /* qDebug() << "setState: enter " << state; */ + m_state = state; + m_pageView->updateCursor(); +} + +/* Get the rectangular boundary of the given annotation, enlarged for space needed by resize handles. + * Returns a QRect in page view item coordinates. */ +QRect MouseAnnotation::getFullBoundingRect(const AnnotationDescription &ad) const +{ + QRect boundingRect; + if (ad.isValid()) { + boundingRect = Okular::AnnotationUtils::annotationGeometry(ad.annotation, ad.pageViewItem->uncroppedWidth(), ad.pageViewItem->uncroppedHeight()); + boundingRect = boundingRect.adjusted(-handleSizeHalf, -handleSizeHalf, handleSizeHalf, handleSizeHalf); + } + return boundingRect; +} + +/* Apply the command determined by m_state to the currently focused annotation. */ +void MouseAnnotation::performCommand(const QPoint newPos) +{ + const QRect &pageViewItemRect = m_focusedAnnotation.pageViewItem->uncroppedGeometry(); + QPointF mouseDelta(newPos - pageViewItemRect.topLeft() - m_mousePosition); + QPointF normalizedRotatedMouseDelta(rotateInRect(QPointF(mouseDelta.x() / pageViewItemRect.width(), mouseDelta.y() / pageViewItemRect.height()), m_focusedAnnotation.pageViewItem->page()->rotation())); + + if (isMoved()) { + m_document->translatePageAnnotation(m_focusedAnnotation.pageNumber, m_focusedAnnotation.annotation, Okular::NormalizedPoint(normalizedRotatedMouseDelta.x(), normalizedRotatedMouseDelta.y())); + } else if (isResized()) { + QPointF delta1, delta2; + handleToAdjust(normalizedRotatedMouseDelta, delta1, delta2, m_handle, m_focusedAnnotation.pageViewItem->page()->rotation()); + m_document->adjustPageAnnotation(m_focusedAnnotation.pageNumber, m_focusedAnnotation.annotation, Okular::NormalizedPoint(delta1.x(), delta1.y()), Okular::NormalizedPoint(delta2.x(), delta2.y())); + } +} + +/* Finalize a command in progress for the currently focused annotation. */ +void MouseAnnotation::finishCommand() +{ + /* + * Note: + * Translate-/resizePageAnnotation causes PopplerAnnotationProxy::notifyModification, + * where modify flag needs to be already cleared. So it is important to call + * setFlags before translatePageAnnotation-/adjustPageAnnotation. + */ + if (isMoved()) { + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() & ~Okular::Annotation::BeingMoved); + m_document->translatePageAnnotation(m_focusedAnnotation.pageNumber, m_focusedAnnotation.annotation, Okular::NormalizedPoint(0.0, 0.0)); + } else if (isResized()) { + m_focusedAnnotation.annotation->setFlags(m_focusedAnnotation.annotation->flags() & ~Okular::Annotation::BeingResized); + m_document->adjustPageAnnotation(m_focusedAnnotation.pageNumber, m_focusedAnnotation.annotation, Okular::NormalizedPoint(0.0, 0.0), Okular::NormalizedPoint(0.0, 0.0)); + } +} + +/* Tell viewport widget that the rectangular of the given annotation needs to be repainted. */ +void MouseAnnotation::updateViewport(const AnnotationDescription &ad) const +{ + const QRect &changedPageViewItemRect = getFullBoundingRect(ad); + if (changedPageViewItemRect.isValid()) { + m_pageView->viewport()->update(changedPageViewItemRect.translated(ad.pageViewItem->uncroppedGeometry().topLeft()).translated(-m_pageView->contentAreaPosition())); + } +} + +/* eventPos: Mouse position in uncropped page coordinates. + ad: The annotation to get the handle for. */ +MouseAnnotation::ResizeHandle MouseAnnotation::getHandleAt(const QPoint eventPos, const AnnotationDescription &ad) const +{ + ResizeHandle selected = RH_None; + + if (ad.annotation->canBeResized()) { + for (const ResizeHandle &handle : m_resizeHandleList) { + const QRect rect = getHandleRect(handle, ad); + if (rect.contains(eventPos)) { + selected |= handle; + } + } + + /* + * Handles may overlap when selection is very small. + * Then it can happen that cursor is over more than one handles, + * and therefore maybe more than two flags are set. + * Favor one handle in that case. + */ + if ((selected & RH_BottomRight) == RH_BottomRight) + return RH_BottomRight; + if ((selected & RH_TopRight) == RH_TopRight) + return RH_TopRight; + if ((selected & RH_TopLeft) == RH_TopLeft) + return RH_TopLeft; + if ((selected & RH_BottomLeft) == RH_BottomLeft) + return RH_BottomLeft; + } + + if (selected == RH_None && ad.annotation->canBeMoved()) { + const QRect boundingRect = Okular::AnnotationUtils::annotationGeometry(ad.annotation, ad.pageViewItem->uncroppedWidth(), ad.pageViewItem->uncroppedHeight()); + if (boundingRect.contains(eventPos)) { + return RH_Content; + } + } + + return selected; +} + +/* Get the rectangle for a specified resizie handle. */ +QRect MouseAnnotation::getHandleRect(ResizeHandle handle, const AnnotationDescription &ad) const +{ + const QRect boundingRect = Okular::AnnotationUtils::annotationGeometry(ad.annotation, ad.pageViewItem->uncroppedWidth(), ad.pageViewItem->uncroppedHeight()); + int left, top; + + if (handle & RH_Top) { + top = boundingRect.top() - handleSizeHalf; + } else if (handle & RH_Bottom) { + top = boundingRect.bottom() - handleSizeHalf; + } else { + top = boundingRect.top() + boundingRect.height() / 2 - handleSizeHalf; + } + + if (handle & RH_Left) { + left = boundingRect.left() - handleSizeHalf; + } else if (handle & RH_Right) { + left = boundingRect.right() - handleSizeHalf; + } else { + left = boundingRect.left() + boundingRect.width() / 2 - handleSizeHalf; + } + + return QRect(left, top, handleSize, handleSize); +} + +/* Convert a resize handle delta into two adjust delta coordinates. */ +void MouseAnnotation::handleToAdjust(const QPointF dIn, QPointF &dOut1, QPointF &dOut2, MouseAnnotation::ResizeHandle handle, Okular::Rotation rotation) +{ + const MouseAnnotation::ResizeHandle rotatedHandle = MouseAnnotation::rotateHandle(handle, rotation); + dOut1.rx() = (rotatedHandle & MouseAnnotation::RH_Left) ? dIn.x() : 0; + dOut1.ry() = (rotatedHandle & MouseAnnotation::RH_Top) ? dIn.y() : 0; + dOut2.rx() = (rotatedHandle & MouseAnnotation::RH_Right) ? dIn.x() : 0; + dOut2.ry() = (rotatedHandle & MouseAnnotation::RH_Bottom) ? dIn.y() : 0; +} + +QPointF MouseAnnotation::rotateInRect(const QPointF rotated, Okular::Rotation rotation) +{ + QPointF ret; + + switch (rotation) { + case Okular::Rotation90: + ret = QPointF(rotated.y(), -rotated.x()); + break; + case Okular::Rotation180: + ret = QPointF(-rotated.x(), -rotated.y()); + break; + case Okular::Rotation270: + ret = QPointF(-rotated.y(), rotated.x()); + break; + case Okular::Rotation0: /* no modifications */ + default: /* other cases */ + ret = rotated; + } + + return ret; +} + +MouseAnnotation::ResizeHandle MouseAnnotation::rotateHandle(MouseAnnotation::ResizeHandle handle, Okular::Rotation rotation) +{ + unsigned int rotatedHandle = 0; + switch (rotation) { + case Okular::Rotation90: + /* bit rotation: #1 => #4, #2 => #1, #3 => #2, #4 => #3 */ + rotatedHandle = (handle << 3 | handle >> (4 - 3)) & RH_AllHandles; + break; + case Okular::Rotation180: + /* bit rotation: #1 => #3, #2 => #4, #3 => #1, #4 => #2 */ + rotatedHandle = (handle << 2 | handle >> (4 - 2)) & RH_AllHandles; + break; + case Okular::Rotation270: + /* bit rotation: #1 => #2, #2 => #3, #3 => #4, #4 => #1 */ + rotatedHandle = (handle << 1 | handle >> (4 - 1)) & RH_AllHandles; + break; + case Okular::Rotation0: /* no modifications */ + default: /* other cases */ + rotatedHandle = handle; + break; + } + return (MouseAnnotation::ResizeHandle)rotatedHandle; +} + +/* Start according action for AMovie/ARichMedia/AScreen/AFileAttachment. + * It was formerly (before mouse annotation refactoring) called on mouse release event. + * Now it's called on mouse press. Should we keep the former behavior? */ +void MouseAnnotation::processAction(const AnnotationDescription &ad) +{ + if (ad.isValid()) { + Okular::Annotation *ann = ad.annotation; + PageViewItem *pageItem = ad.pageViewItem; + + if (ann->subType() == Okular::Annotation::AMovie) { + VideoWidget *vw = pageItem->videoWidgets().value(static_cast(ann)->movie()); + vw->show(); + vw->play(); + } else if (ann->subType() == Okular::Annotation::ARichMedia) { + VideoWidget *vw = pageItem->videoWidgets().value(static_cast(ann)->movie()); + vw->show(); + vw->play(); + } else if (ann->subType() == Okular::Annotation::AScreen) { + m_document->processAction(static_cast(ann)->action()); + } else if (ann->subType() == Okular::Annotation::AFileAttachment) { + const Okular::FileAttachmentAnnotation *fileAttachAnnot = static_cast(ann); + GuiUtils::saveEmbeddedFile(fileAttachAnnot->embeddedFile(), m_pageView); + } + } +} diff --git a/part/pageviewmouseannotation.h b/part/pageviewmouseannotation.h new file mode 100644 index 0000000..859dd95 --- /dev/null +++ b/part/pageviewmouseannotation.h @@ -0,0 +1,176 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tobias Deiminger * + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2004-2006 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * With portions of code from kpdf/kpdf_pagewidget.cc by: * + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2003 by Christophe Devriese * + * * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2003 by Dirk Mueller * + * Copyright (C) 2004 by James Ots * + * Copyright (C) 2011 by Jiri Baum - NICTA * + * * + * 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_PAGEVIEWMOUSEANNOTATION_H_ +#define _OKULAR_PAGEVIEWMOUSEANNOTATION_H_ + +#include + +#include "core/annotations.h" +#include "pageviewutils.h" + +class QHelpEvent; +class QPainter; +class QPoint; +class PageView; +class PageViewItem; +class AnnotationDescription; + +namespace Okular +{ +class Document; +} + +/* This class shall help to keep data for one annotation consistent. */ +class AnnotationDescription +{ +public: + AnnotationDescription() + : annotation(nullptr) + , pageViewItem(nullptr) + , pageNumber(-1) + { + } + AnnotationDescription(PageViewItem *newPageViewItem, const QPoint eventPos); + bool isValid() const; + bool isContainedInPage(const Okular::Document *document, int pageNumber) const; + void invalidate(); + bool operator==(const AnnotationDescription &rhs) const + { + return (annotation == rhs.annotation); + } + Okular::Annotation *annotation; + PageViewItem *pageViewItem; + int pageNumber; +}; + +/** + * @short Handle UI for annotation interactions, like moving, resizing and triggering actions. + * + * An object of this class tracks which annotation is currently under the mouse cursor. + * Some annotation types can be focused in order to move or resize them. + * State is determined from mouse and keyboard events, which are forwarded from the parent PageView object. + * Move and resize actions are dispatched to the Document object. + */ +class MouseAnnotation : public QObject +{ + Q_OBJECT + +public: + MouseAnnotation(PageView *parent, Okular::Document *document); + ~MouseAnnotation() override; + + /* Process a mouse press event. eventPos: Mouse position in content area coordinates. */ + void routeMousePressEvent(PageViewItem *pageViewItem, const QPoint eventPos); + + /* Process a mouse release event. */ + void routeMouseReleaseEvent(); + + /* Process a mouse move event. eventPos: Mouse position in content area coordinates. */ + void routeMouseMoveEvent(PageViewItem *pageViewItem, const QPoint eventPos, bool leftButtonPressed); + + /* Process a key event. */ + void routeKeyPressEvent(const QKeyEvent *e); + + /* Process a tooltip event. eventPos: Mouse position in content area coordinates. */ + void routeTooltipEvent(const QHelpEvent *helpEvent); + + /* Process a paint event. */ + void routePaint(QPainter *painter, const QRect paintRect); + + /* Cancel the current selection or action, if any. */ + void cancel(); + + /* Reset to initial state. Cancel current action and relinquish references to PageViewItem widgets. */ + void reset(); + + Okular::Annotation *annotation() const; + + /* Return true, if MouseAnnotation demands control for a mouse click on the current cursor position. */ + bool isMouseOver() const; + + bool isActive() const; + + bool isFocused() const; + + bool isMoved() const; + + bool isResized() const; + + bool isModified() const; + + Qt::CursorShape cursor() const; + + /* Forward DocumentObserver::notifyPageChanged to this method. */ + void notifyAnnotationChanged(int pageNumber); + + /* Forward DocumentObserver::notifySetup to this method. */ + void updateAnnotationPointers(); + + enum MouseAnnotationState { StateInactive, StateFocused, StateMoving, StateResizing }; + + enum ResizeHandleFlag { + RH_None = 0, + RH_Top = 1, + RH_Right = 2, + RH_Bottom = 4, + RH_Left = 8, + RH_TopLeft = RH_Top | RH_Left, + RH_BottomLeft = RH_Bottom | RH_Left, + RH_TopRight = RH_Top | RH_Right, + RH_BottomRight = RH_Bottom | RH_Right, + RH_Content = 16, + RH_AllHandles = RH_Top | RH_Right | RH_Bottom | RH_Left + }; + Q_DECLARE_FLAGS(ResizeHandle, ResizeHandleFlag) + +private: + void setState(MouseAnnotationState state, const AnnotationDescription &ad); + QRect getFullBoundingRect(const AnnotationDescription &ad) const; + void performCommand(const QPoint newPos); + void finishCommand(); + void updateViewport(const AnnotationDescription &ad) const; + ResizeHandle getHandleAt(const QPoint eventPos, const AnnotationDescription &ad) const; + QRect getHandleRect(ResizeHandle handle, const AnnotationDescription &ad) const; + static void handleToAdjust(const QPointF dIn, QPointF &dOut1, QPointF &dOut2, MouseAnnotation::ResizeHandle handle, Okular::Rotation rotation); + static QPointF rotateInRect(const QPointF rotated, Okular::Rotation rotation); + static ResizeHandle rotateHandle(ResizeHandle handle, Okular::Rotation rotation); + void processAction(const AnnotationDescription &ad); + + /* We often have to delegate to the document model and our parent widget. */ + Okular::Document *m_document; + PageView *m_pageView; + + /* Remember which annotation is currently focused/modified. */ + MouseAnnotationState m_state; + MouseAnnotation::ResizeHandle m_handle; + AnnotationDescription m_focusedAnnotation; + + /* Mouse tracking, always kept up to date with the latest mouse position and annotation under mouse cursor. */ + AnnotationDescription m_mouseOverAnnotation; + QPoint m_mousePosition; // in page view item coordinates + + QList m_resizeHandleList; +}; + +#endif diff --git a/part/pageviewutils.cpp b/part/pageviewutils.cpp new file mode 100644 index 0000000..b396c76 --- /dev/null +++ b/part/pageviewutils.cpp @@ -0,0 +1,386 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "pageviewutils.h" + +// qt/kde includes +#include +#include +#include +#include +#include + +// local includes +#include "core/form.h" +#include "core/page.h" +#include "formwidgets.h" +#include "settings.h" +#include "videowidget.h" + +/*********************/ +/** PageViewItem */ +/*********************/ + +PageViewItem::PageViewItem(const Okular::Page *page) + : m_page(page) + , m_zoomFactor(1.0) + , m_visible(true) + , m_formsVisible(false) + , m_crop(0., 0., 1., 1.) +{ +} + +PageViewItem::~PageViewItem() +{ + qDeleteAll(m_formWidgets); + qDeleteAll(m_videoWidgets); +} + +const Okular::Page *PageViewItem::page() const +{ + return m_page; +} + +int PageViewItem::pageNumber() const +{ + return m_page->number(); +} + +const QRect &PageViewItem::croppedGeometry() const +{ + return m_croppedGeometry; +} + +int PageViewItem::croppedWidth() const +{ + return m_croppedGeometry.width(); +} + +int PageViewItem::croppedHeight() const +{ + return m_croppedGeometry.height(); +} + +const QRect &PageViewItem::uncroppedGeometry() const +{ + return m_uncroppedGeometry; +} + +int PageViewItem::uncroppedWidth() const +{ + return m_uncroppedGeometry.width(); +} + +int PageViewItem::uncroppedHeight() const +{ + return m_uncroppedGeometry.height(); +} + +const Okular::NormalizedRect &PageViewItem::crop() const +{ + return m_crop; +} + +double PageViewItem::zoomFactor() const +{ + return m_zoomFactor; +} + +double PageViewItem::absToPageX(double absX) const +{ + return (absX - m_uncroppedGeometry.left()) / m_uncroppedGeometry.width(); +} + +double PageViewItem::absToPageY(double absY) const +{ + return (absY - m_uncroppedGeometry.top()) / m_uncroppedGeometry.height(); +} + +bool PageViewItem::isVisible() const +{ + return m_visible; +} + +QSet &PageViewItem::formWidgets() +{ + return m_formWidgets; +} + +QHash &PageViewItem::videoWidgets() +{ + return m_videoWidgets; +} + +void PageViewItem::setWHZC(int w, int h, double z, const Okular::NormalizedRect &c) +{ + m_croppedGeometry.setWidth(w); + m_croppedGeometry.setHeight(h); + m_zoomFactor = z; + m_crop = c; + m_uncroppedGeometry.setWidth(qRound(w / (c.right - c.left))); + m_uncroppedGeometry.setHeight(qRound(h / (c.bottom - c.top))); + for (FormWidgetIface *fwi : qAsConst(m_formWidgets)) { + Okular::NormalizedRect r = fwi->rect(); + fwi->setWidthHeight(qRound(fabs(r.right - r.left) * m_uncroppedGeometry.width()), qRound(fabs(r.bottom - r.top) * m_uncroppedGeometry.height())); + } + for (VideoWidget *vw : qAsConst(m_videoWidgets)) { + const Okular::NormalizedRect r = vw->normGeometry(); + vw->resize(qRound(fabs(r.right - r.left) * m_uncroppedGeometry.width()), qRound(fabs(r.bottom - r.top) * m_uncroppedGeometry.height())); + } +} + +void PageViewItem::moveTo(int x, int y) +// Assumes setWHZC() has already been called +{ + m_croppedGeometry.moveLeft(x); + m_croppedGeometry.moveTop(y); + m_uncroppedGeometry.moveLeft(qRound(x - m_crop.left * m_uncroppedGeometry.width())); + m_uncroppedGeometry.moveTop(qRound(y - m_crop.top * m_uncroppedGeometry.height())); + QSet::iterator it = m_formWidgets.begin(), itEnd = m_formWidgets.end(); + for (; it != itEnd; ++it) { + Okular::NormalizedRect r = (*it)->rect(); + (*it)->moveTo(qRound(x + m_uncroppedGeometry.width() * r.left) + 1, qRound(y + m_uncroppedGeometry.height() * r.top) + 1); + } + for (VideoWidget *vw : qAsConst(m_videoWidgets)) { + const Okular::NormalizedRect r = vw->normGeometry(); + vw->move(qRound(x + m_uncroppedGeometry.width() * r.left) + 1, qRound(y + m_uncroppedGeometry.height() * r.top) + 1); + } +} + +void PageViewItem::setVisible(bool visible) +{ + setFormWidgetsVisible(visible && m_formsVisible); + m_visible = visible; +} + +void PageViewItem::invalidate() +{ + m_croppedGeometry.setRect(0, 0, 0, 0); + m_uncroppedGeometry.setRect(0, 0, 0, 0); +} + +bool PageViewItem::setFormWidgetsVisible(bool visible) +{ + m_formsVisible = visible; + + if (!m_visible) + return false; + + bool somehadfocus = false; + QSet::iterator it = m_formWidgets.begin(), itEnd = m_formWidgets.end(); + for (; it != itEnd; ++it) { + bool hadfocus = (*it)->setVisibility(visible && (*it)->formField()->isVisible() && FormWidgetsController::shouldFormWidgetBeShown((*it)->formField())); + somehadfocus = somehadfocus || hadfocus; + } + return somehadfocus; +} + +void PageViewItem::reloadFormWidgetsState() +{ + for (FormWidgetIface *fwi : qAsConst(m_formWidgets)) { + fwi->setVisibility(fwi->formField()->isVisible() && FormWidgetsController::shouldFormWidgetBeShown(fwi->formField())); + } +} + +/*********************/ +/** PageViewMessage */ +/*********************/ + +PageViewMessage::PageViewMessage(QWidget *parent) + : QWidget(parent) + , m_timer(nullptr) + , m_lineSpacing(0) +{ + setObjectName(QStringLiteral("pageViewMessage")); + setFocusPolicy(Qt::NoFocus); + QPalette pal = palette(); + pal.setColor(QPalette::Active, QPalette::Window, QApplication::palette().color(QPalette::Active, QPalette::Window)); + setPalette(pal); + // if the layout is LtR, we can safely place it in the right position + if (layoutDirection() == Qt::LeftToRight) + move(10, 10); + resize(0, 0); + hide(); +} + +void PageViewMessage::display(const QString &message, const QString &details, Icon icon, int durationMs) +// give Caesar what belongs to Caesar: code taken from Amarok's osd.h/.cpp +// "redde (reddite, pl.) cesari quae sunt cesaris", just btw. :) +// The code has been heavily modified since then. +{ + if (!Okular::Settings::showOSD()) { + hide(); + return; + } + + // set text + m_message = message; + m_details = details; + // reset vars + m_lineSpacing = 0; + + // load icon (if set) + m_symbol = QPixmap(); + const auto symbolSize = style()->pixelMetric(QStyle::PM_SmallIconSize); + if (icon != None) { + switch (icon) { + case Annotation: + m_symbol = QIcon::fromTheme(QStringLiteral("draw-freehand")).pixmap(symbolSize); + break; + case Find: + m_symbol = QIcon::fromTheme(QStringLiteral("zoom-original")).pixmap(symbolSize); + break; + case Error: + m_symbol = QIcon::fromTheme(QStringLiteral("dialog-error")).pixmap(symbolSize); + break; + case Warning: + m_symbol = QIcon::fromTheme(QStringLiteral("dialog-warning")).pixmap(symbolSize); + break; + default: + m_symbol = QIcon::fromTheme(QStringLiteral("dialog-information")).pixmap(symbolSize); + break; + } + } + + computeSizeAndResize(); + // show widget and schedule a repaint + show(); + update(); + + // close the message window after given mS + if (durationMs > 0) { + if (!m_timer) { + m_timer = new QTimer(this); + m_timer->setSingleShot(true); + connect(m_timer, &QTimer::timeout, this, &PageViewMessage::hide); + } + m_timer->start(durationMs); + } else if (m_timer) + m_timer->stop(); + + qobject_cast(parentWidget())->viewport()->installEventFilter(this); +} + +QRect PageViewMessage::computeTextRect(const QString &message, int extra_width) const +// Return the QRect which embeds the text +{ + int charSize = fontMetrics().averageCharWidth(); + /* width of the viewport, minus 20 (~ size removed by further resizing), + minus the extra size (usually the icon width), minus (a bit empirical) + twice the mean width of a character to ensure that the bounding box is + really smaller than the container. + */ + const int boundingWidth = qobject_cast(parentWidget())->viewport()->width() - 20 - (extra_width > 0 ? 2 + extra_width : 0) - 2 * charSize; + QRect textRect = fontMetrics().boundingRect(0, 0, boundingWidth, 0, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, message); + textRect.translate(-textRect.left(), -textRect.top()); + textRect.adjust(0, 0, 2, 2); + + return textRect; +} + +void PageViewMessage::computeSizeAndResize() +{ + // determine text rectangle + const QRect textRect = computeTextRect(m_message, m_symbol.width()); + int width = textRect.width(), height = textRect.height(); + + if (!m_details.isEmpty()) { + // determine details text rectangle + const QRect detailsRect = computeTextRect(m_details, m_symbol.width()); + width = qMax(width, detailsRect.width()); + height += detailsRect.height(); + + // plus add a ~60% line spacing + m_lineSpacing = static_cast(fontMetrics().height() * 0.6); + height += m_lineSpacing; + } + + // update geometry with icon information + if (!m_symbol.isNull()) { + width += 2 + m_symbol.width(); + height = qMax(height, m_symbol.height()); + } + + // resize widget + resize(QRect(0, 0, width + 10, height + 8).size()); + + // if the layout is RtL, we can move it to the right place only after we + // know how much size it will take + if (layoutDirection() == Qt::RightToLeft) + move(parentWidget()->width() - geometry().width() - 10 - 1, 10); +} + +bool PageViewMessage::eventFilter(QObject *obj, QEvent *event) +{ + /* if the parent object (scroll area) resizes, the message should + resize as well */ + if (event->type() == QEvent::Resize) { + QResizeEvent *resizeEvent = static_cast(event); + if (resizeEvent->oldSize() != resizeEvent->size()) { + computeSizeAndResize(); + } + } + // standard event processing + return QObject::eventFilter(obj, event); +} + +void PageViewMessage::paintEvent(QPaintEvent * /* e */) +{ + const QRect textRect = computeTextRect(m_message, m_symbol.width()); + + QRect detailsRect; + if (!m_details.isEmpty()) { + detailsRect = computeTextRect(m_details, m_symbol.width()); + } + + int textXOffset = 0, + // add 2 to account for the reduced drawRoundedRect later + textYOffset = (geometry().height() - textRect.height() - detailsRect.height() - m_lineSpacing + 2) / 2, iconXOffset = 0, iconYOffset = !m_symbol.isNull() ? (geometry().height() - m_symbol.height()) / 2 : 0, shadowOffset = 1; + + if (layoutDirection() == Qt::RightToLeft) + iconXOffset = 2 + textRect.width(); + else + textXOffset = 2 + m_symbol.width(); + + // draw background + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(Qt::black); + painter.setBrush(palette().color(QPalette::Window)); + painter.translate(0.5, 0.5); + painter.drawRoundedRect(1, 1, width() - 2, height() - 2, 1600.0 / width(), 1600.0 / height()); + + // draw icon if present + if (!m_symbol.isNull()) + painter.drawPixmap(5 + iconXOffset, iconYOffset, m_symbol, 0, 0, m_symbol.width(), m_symbol.height()); + + const int xStartPoint = 5 + textXOffset; + const int yStartPoint = textYOffset; + const int textDrawingFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap; + + // draw shadow and text + painter.setPen(palette().color(QPalette::Window).darker(115)); + painter.drawText(xStartPoint + shadowOffset, yStartPoint + shadowOffset, textRect.width(), textRect.height(), textDrawingFlags, m_message); + if (!m_details.isEmpty()) + painter.drawText(xStartPoint + shadowOffset, yStartPoint + textRect.height() + m_lineSpacing + shadowOffset, textRect.width(), detailsRect.height(), textDrawingFlags, m_details); + painter.setPen(palette().color(QPalette::WindowText)); + painter.drawText(xStartPoint, yStartPoint, textRect.width(), textRect.height(), textDrawingFlags, m_message); + if (!m_details.isEmpty()) + painter.drawText(xStartPoint + shadowOffset, yStartPoint + textRect.height() + m_lineSpacing, textRect.width(), detailsRect.height(), textDrawingFlags, m_details); +} + +void PageViewMessage::mousePressEvent(QMouseEvent * /*e*/) +{ + if (m_timer) + m_timer->stop(); + hide(); +} diff --git a/part/pageviewutils.h b/part/pageviewutils.h new file mode 100644 index 0000000..f71169e --- /dev/null +++ b/part/pageviewutils.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Enrico Ros * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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 _PAGEVIEW_UTILS_H_ +#define _PAGEVIEW_UTILS_H_ + +#include +#include +#include +#include + +#include "core/area.h" + +class QTimer; +class FormWidgetIface; +class PageView; +class VideoWidget; + +namespace Okular +{ +class Movie; +class Page; +} + +/** + * @short PageViewItem represents graphically a page into the PageView. + * + * It has methods for settings Item's geometry and other visual properties such + * as the individual zoom factor. + */ +class PageViewItem +{ +public: + explicit PageViewItem(const Okular::Page *page); + ~PageViewItem(); + + PageViewItem(const PageViewItem &) = delete; + PageViewItem &operator=(const PageViewItem &) = delete; + + const Okular::Page *page() const; + int pageNumber() const; + double zoomFactor() const; + bool isVisible() const; + QSet &formWidgets(); + QHash &videoWidgets(); + + /* The page is cropped as follows: */ + const Okular::NormalizedRect &crop() const; + + /* Real geometry into which the cropped page is rendered: */ + const QRect &croppedGeometry() const; + int croppedWidth() const; + int croppedHeight() const; + + /* "Uncropped" geometry: + * If the whole page was rendered into the uncropped geometry then the + * cropped page would be rendered into the real geometry. + * (Hence, uncropped always contains cropped, and they are equal only if + * the page is uncropped.) This is just for convenience in calculations. + */ + const QRect &uncroppedGeometry() const; + int uncroppedWidth() const; + int uncroppedHeight() const; + + /* Convert absolute geometry coordinates to normalized [0,1] page coordinates: */ + double absToPageX(double absX) const; + double absToPageY(double absY) const; + + void setWHZC(int w, int h, double zoom, const Okular::NormalizedRect &c); + void moveTo(int x, int y); + void setVisible(bool visible); + void invalidate(); + bool setFormWidgetsVisible(bool visible); + void reloadFormWidgetsState(); + +private: + const Okular::Page *m_page; + double m_zoomFactor; + bool m_visible; + bool m_formsVisible; + QRect m_croppedGeometry; + QRect m_uncroppedGeometry; + Okular::NormalizedRect m_crop; + QSet m_formWidgets; + QHash m_videoWidgets; +}; + +/** + * @short A widget that displays messages in the top-left corner. + * + * This is a widget with thin border and rounded corners that displays a given + * text along as an icon. It's meant to be used for displaying messages to the + * user by placing this above other widgets. + */ +class PageViewMessage : public QWidget +{ + Q_OBJECT + +public: + explicit PageViewMessage(QWidget *parent); + + enum Icon { None, Info, Warning, Error, Find, Annotation }; + void display(const QString &message, const QString &details = QString(), Icon icon = Info, int durationMs = 4000); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + +private: + QRect computeTextRect(const QString &message, int extra_width) const; + void computeSizeAndResize(); + QString m_message; + QString m_details; + QPixmap m_symbol; + QTimer *m_timer; + int m_lineSpacing; +}; + +#endif diff --git a/part/part-viewermode.rc b/part/part-viewermode.rc new file mode 100644 index 0000000..862679a --- /dev/null +++ b/part/part-viewermode.rc @@ -0,0 +1,72 @@ + + + + + &File + + + + &Settings + + + + + &Help + + + + + + + + + + + + + + + + + &Orientation + + + + + + + + + + + + + + + + + + &Bookmarks + + + + + + + + + + + + +Viewer Toolbar + + + + + + + + + + diff --git a/part/part.cpp b/part/part.cpp new file mode 100644 index 0000000..8d57ed0 --- /dev/null +++ b/part/part.cpp @@ -0,0 +1,3499 @@ +/*************************************************************************** + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2002 by Chris Cheney * + * Copyright (C) 2002 by Malcolm Hunter * + * Copyright (C) 2003-2004 by Christophe Devriese * + * * + * Copyright (C) 2003 by Daniel Molkentin * + * Copyright (C) 2003 by Andy Goossens * + * Copyright (C) 2003 by Dirk Mueller * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2004 by Dominique Devriese * + * Copyright (C) 2004 by Christoph Cullmann * + * Copyright (C) 2004 by Henrique Pinto * + * Copyright (C) 2004 by Waldo Bastian * + * Copyright (C) 2004-2008 by Albert Astals Cid * + * Copyright (C) 2004 by Antti Markus * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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. * + ***************************************************************************/ + +#include "part.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_KWALLET +#include +#endif +#include +#include + +#if PURPOSE_FOUND +#include +#include +#endif + +#if 0 +#include +#endif + +// local includes +#include "aboutdata.h" +#include "bookmarklist.h" +#include "core/action.h" +#include "core/annotations.h" +#include "core/bookmarkmanager.h" +#include "core/document_p.h" +#include "core/fileprinter.h" +#include "core/form.h" +#include "core/generator.h" +#include "core/page.h" +#include "core/printoptionswidget.h" +#include "debug_ui.h" +#include "drawingtoolactions.h" +#include "embeddedfilesdialog.h" +#include "extensions.h" +#include "fileprinterpreview.h" +#include "findbar.h" +#include "guiutils.h" +#include "layers.h" +#include "minibar.h" +#include "okmenutitle.h" +#include "pagesizelabel.h" +#include "pageview.h" +#include "preferencesdialog.h" +#include "presentationwidget.h" +#include "propertiesdialog.h" +#include "searchwidget.h" +#include "settings.h" +#include "side_reviews.h" +#include "sidebar.h" +#include "signatureguiutils.h" +#include "signaturepanel.h" +#include "thumbnaillist.h" +#include "toc.h" +#include "xmlgui_helper.h" +#include + +#ifdef OKULAR_KEEP_FILE_OPEN +class FileKeeper +{ +public: + FileKeeper() + : m_handle(nullptr) + { + } + + ~FileKeeper() + { + } + + void open(const QString &path) + { + if (!m_handle) + m_handle = std::fopen(QFile::encodeName(path).constData(), "r"); + } + + void close() + { + if (m_handle) { + int ret = std::fclose(m_handle); + Q_UNUSED(ret) + m_handle = nullptr; + } + } + + QTemporaryFile *copyToTemporary() const + { + if (!m_handle) + return nullptr; + + QTemporaryFile *retFile = new QTemporaryFile; + retFile->open(); + + std::rewind(m_handle); + int c = -1; + do { + c = std::fgetc(m_handle); + if (c == EOF) + break; + if (!retFile->putChar((char)c)) + break; + } while (!feof(m_handle)); + + retFile->flush(); + + return retFile; + } + +private: + std::FILE *m_handle; +}; +#endif + +K_PLUGIN_FACTORY(OkularPartFactory, registerPlugin();) + +static QAction *actionForExportFormat(const Okular::ExportFormat &format, QObject *parent = Q_NULLPTR) +{ + QAction *act = new QAction(format.description(), parent); + if (!format.icon().isNull()) { + act->setIcon(format.icon()); + } + return act; +} + +static KFilterDev::CompressionType compressionTypeFor(const QString &mime_to_check) +{ + // The compressedMimeMap is here in case you have a very old shared mime database + // that doesn't have inheritance info for things like gzeps, etc + // Otherwise the "is()" calls below are just good enough + static QHash compressedMimeMap; + static bool supportBzip = false; + static bool supportXz = false; + const QString app_gzip(QStringLiteral("application/x-gzip")); + const QString app_bzip(QStringLiteral("application/x-bzip")); + const QString app_xz(QStringLiteral("application/x-xz")); + if (compressedMimeMap.isEmpty()) { + std::unique_ptr f; + compressedMimeMap[QStringLiteral("image/x-gzeps")] = KFilterDev::GZip; + // check we can read bzip2-compressed files + f.reset(KCompressionDevice::filterForCompressionType(KCompressionDevice::BZip2)); + if (f.get()) { + supportBzip = true; + compressedMimeMap[QStringLiteral("application/x-bzpdf")] = KFilterDev::BZip2; + compressedMimeMap[QStringLiteral("application/x-bzpostscript")] = KFilterDev::BZip2; + compressedMimeMap[QStringLiteral("application/x-bzdvi")] = KFilterDev::BZip2; + compressedMimeMap[QStringLiteral("image/x-bzeps")] = KFilterDev::BZip2; + } + // check if we can read XZ-compressed files + f.reset(KCompressionDevice::filterForCompressionType(KCompressionDevice::Xz)); + if (f.get()) { + supportXz = true; + } + } + QHash::const_iterator it = compressedMimeMap.constFind(mime_to_check); + if (it != compressedMimeMap.constEnd()) + return it.value(); + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForName(mime_to_check); + if (mime.isValid()) { + if (mime.inherits(app_gzip)) + return KFilterDev::GZip; + else if (supportBzip && mime.inherits(app_bzip)) + return KFilterDev::BZip2; + else if (supportXz && mime.inherits(app_xz)) + return KFilterDev::Xz; + } + + return KFilterDev::None; +} + +static Okular::EmbedMode detectEmbedMode(QWidget *parentWidget, QObject *parent, const QVariantList &args) +{ + Q_UNUSED(parentWidget); + + if (parent && (parent->objectName().startsWith(QLatin1String("okular::Shell")) || parent->objectName().startsWith(QLatin1String("okular/okular__Shell")))) + return Okular::NativeShellMode; + + if (parent && (QByteArray("KHTMLPart") == parent->metaObject()->className())) + return Okular::KHTMLPartMode; + + for (const QVariant &arg : args) { + if (arg.type() == QVariant::String) { + if (arg.toString() == QLatin1String("Print/Preview")) { + return Okular::PrintPreviewMode; + } else if (arg.toString() == QLatin1String("ViewerWidget")) { + return Okular::ViewerWidgetMode; + } + } + } + + return Okular::UnknownEmbedMode; +} + +static QString detectConfigFileName(const QVariantList &args) +{ + for (const QVariant &arg : args) { + if (arg.type() == QVariant::String) { + QString argString = arg.toString(); + int separatorIndex = argString.indexOf(QStringLiteral("=")); + if (separatorIndex >= 0 && argString.left(separatorIndex) == QLatin1String("ConfigFileName")) { + return argString.mid(separatorIndex + 1); + } + } + } + + return QString(); +} + +#undef OKULAR_KEEP_FILE_OPEN + +#ifdef OKULAR_KEEP_FILE_OPEN +static bool keepFileOpen() +{ + static bool keep_file_open = !qgetenv("OKULAR_NO_KEEP_FILE_OPEN").toInt(); + return keep_file_open; +} +#endif + +int Okular::Part::numberOfParts = 0; + +namespace Okular +{ +Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &args) + : KParts::ReadWritePart(parent) + , m_tempfile(nullptr) + , m_documentOpenWithPassword(false) + , m_swapInsteadOfOpening(false) + , m_tocEnabled(false) + , m_isReloading(false) + , m_fileWasRemoved(false) + , m_showMenuBarAction(nullptr) + , m_showFullScreenAction(nullptr) + , m_actionsSearched(false) + , m_cliPresentation(false) + , m_cliPrint(false) + , m_cliPrintAndExit(false) + , m_embedMode(detectEmbedMode(parentWidget, parent, args)) + , m_generatorGuiClient(nullptr) + , m_keeper(nullptr) +{ + // make sure that the component name is okular otherwise the XMLGUI .rc files are not found + // when this part is used in an application other than okular (e.g. unit tests) + setComponentName(QStringLiteral("okular"), QString()); + + const QLatin1String configFileName("okularpartrc"); + + // first, we check if a config file name has been specified + QString configFilePath = detectConfigFileName(args); + + if (configFilePath.isEmpty()) { + configFilePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + configFileName; + } + + // Migrate old config + if (!QFile::exists(configFilePath)) { + qCDebug(OkularUiDebug) << "Did not find a config file, attempting to look for old config"; + + // Migrate old config + UI + Kdelibs4ConfigMigrator configMigrator(componentName()); + // UI file is handled automatically, we only need to specify config name because we're a part + configMigrator.setConfigFiles(QStringList(configFileName)); + + // If there's no old okular config to migrate, look for kpdf + if (!configMigrator.migrate()) { + qCDebug(OkularUiDebug) << "Did not find an old okular config file, attempting to look for kpdf config"; + + // First try the automatic detection, using $KDEHOME etc. + Kdelibs4Migration migration; + QString kpdfConfig = migration.locateLocal("config", QStringLiteral("kpdfpartrc")); + + // Fallback just in case it tried e. g. ~/.kde4 + if (kpdfConfig.isEmpty()) { + kpdfConfig = QDir::homePath() + QStringLiteral("/.kde/share/config/kpdfpartrc"); + } + + if (QFile::exists(kpdfConfig)) { + qCDebug(OkularUiDebug) << "Found old kpdf config" << kpdfConfig << "copying to" << configFilePath; + QFile::copy(kpdfConfig, configFilePath); + } else { + qCDebug(OkularUiDebug) << "Did not find an old kpdf config file"; + } + } else { + qCDebug(OkularUiDebug) << "Migrated old okular config"; + } + } + + Okular::Settings::instance(configFilePath); + + // In part.rc 47 we introduced a new mandatory toolbar that kxmlgui doesn't know how to merge properly + // so unfortunately we have to remove any customized part.rc that is older than 47 + const QStringList files = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kxmlgui5/okular/part.rc")); + for (const QString &file : files) { + removeRCFileIfVersionSmallerThan(file, 47); + } + + numberOfParts++; + if (numberOfParts == 1) { + m_registerDbusName = QStringLiteral("/okular"); + } else { + m_registerDbusName = QStringLiteral("/okular%1").arg(numberOfParts); + } + QDBusConnection::sessionBus().registerObject(m_registerDbusName, this, QDBusConnection::ExportScriptableSlots); + + // connect the started signal to tell the job the mimetypes we like, + // and get some more information from it + connect(this, &KParts::ReadOnlyPart::started, this, &Part::slotJobStarted); + + // connect the completed signal so we can put the window caption when loading remote files + connect(this, QOverload<>::of(&Part::completed), this, &Part::setWindowTitleFromDocument); + connect(this, &KParts::ReadOnlyPart::canceled, this, &Part::loadCancelled); + + // create browser extension (for printing when embedded into browser) + m_bExtension = new BrowserExtension(this); + // create live connect extension (for integrating with browser scripting) + new OkularLiveConnectExtension(this); + + GuiUtils::addIconLoader(iconLoader()); + + m_sidebar = new Sidebar(parentWidget); + setWidget(m_sidebar); + connect(m_sidebar, &Sidebar::urlsDropped, this, &Part::handleDroppedUrls); + + // build the document + m_document = new Okular::Document(widget()); + connect(m_document, &Document::linkFind, this, &Part::slotFind); + connect(m_document, &Document::linkGoToPage, this, &Part::slotGoToPage); + connect(m_document, &Document::linkPresentation, this, &Part::slotShowPresentation); + connect(m_document, &Document::linkEndPresentation, this, &Part::slotHidePresentation); + connect(m_document, &Document::openUrl, this, &Part::openUrlFromDocument); + connect(m_document->bookmarkManager(), &BookmarkManager::openUrl, this, &Part::openUrlFromBookmarks); + connect(m_document, &Document::close, this, &Part::close); + connect(m_document, &Document::undoHistoryCleanChanged, this, [this](bool clean) { + setModified(!clean); + setWindowTitleFromDocument(); + }); + + if (parent && parent->metaObject()->indexOfSlot(QMetaObject::normalizedSignature("slotQuit()").constData()) != -1) + connect(m_document, SIGNAL(quit()), parent, SLOT(slotQuit())); // clazy:exclude=old-style-connect + else + connect(m_document, &Document::quit, this, &Part::cannotQuit); + // widgets: ^searchbar (toolbar containing label and SearchWidget) + // m_searchToolBar = new KToolBar( parentWidget, "searchBar" ); + // m_searchToolBar->boxLayout()->setSpacing( KDialog::spacingHint() ); + // QLabel * sLabel = new QLabel( i18n( "&Search:" ), m_searchToolBar, "kde toolbar widget" ); + // m_searchWidget = new SearchWidget( m_searchToolBar, m_document ); + // sLabel->setBuddy( m_searchWidget ); + // m_searchToolBar->setStretchableWidget( m_searchWidget ); + + // [left toolbox optional item: Table of Contents] | [] + m_toc = new TOC(nullptr, m_document); + connect(m_toc.data(), &TOC::hasTOC, this, &Part::enableTOC); + connect(m_toc.data(), &TOC::rightClick, this, &Part::slotShowTOCMenu); + + // [left toolbox optional item: Layers] | [] + m_layers = new Layers(nullptr, m_document); + connect(m_layers.data(), &Layers::hasLayers, this, &Part::enableLayers); + + // [left toolbox: Thumbnails and Bookmarks] | [] + QWidget *thumbsBox = new ThumbnailsBox(nullptr); + thumbsBox->layout()->setSpacing(6); + m_searchWidget = new SearchWidget(thumbsBox, m_document); + thumbsBox->layout()->addWidget(m_searchWidget); + m_thumbnailList = new ThumbnailList(thumbsBox, m_document); + thumbsBox->layout()->addWidget(m_thumbnailList); + // ThumbnailController * m_tc = new ThumbnailController( thumbsBox, m_thumbnailList ); + connect(m_thumbnailList.data(), &ThumbnailList::rightClick, this, &Part::slotShowMenu); + m_sidebar->addItem(thumbsBox, QIcon::fromTheme(QStringLiteral("view-preview")), i18n("Thumbnails")); + + m_sidebar->setCurrentItem(thumbsBox); + + // [left toolbox: Reviews] | [] + m_reviewsWidget = new Reviews(nullptr, m_document); + m_sidebar->addItem(m_reviewsWidget, QIcon::fromTheme(QStringLiteral("draw-freehand")), i18n("Annotations")); + + // [left toolbox: Bookmarks] | [] + m_bookmarkList = new BookmarkList(m_document, nullptr); + m_sidebar->addItem(m_bookmarkList, QIcon::fromTheme(QStringLiteral("bookmarks")), i18n("Bookmarks")); + + // [left toolbox optional item: Signature Panel] | [] + m_signaturePanel = new SignaturePanel(m_document, nullptr); + connect(m_signaturePanel.data(), &SignaturePanel::documentHasSignatures, this, &Part::enableSidebarSignaturesItem); + + // widgets: [../miniBarContainer] | [] +#ifdef OKULAR_ENABLE_MINIBAR + QWidget *miniBarContainer = new QWidget(0); + m_sidebar->setBottomWidget(miniBarContainer); + QVBoxLayout *miniBarLayout = new QVBoxLayout(miniBarContainer); + miniBarLayout->setContentsMargins(0, 0, 0, 0); + // widgets: [../[spacer/..]] | [] + miniBarLayout->addItem(new QSpacerItem(6, 6, QSizePolicy::Fixed, QSizePolicy::Fixed)); + // widgets: [../[../MiniBar]] | [] + QFrame *bevelContainer = new QFrame(miniBarContainer); + bevelContainer->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + QVBoxLayout *bevelContainerLayout = new QVBoxLayout(bevelContainer); + bevelContainerLayout->setContentsMargins(4, 4, 4, 4); + m_progressWidget = new ProgressWidget(bevelContainer, m_document); + bevelContainerLayout->addWidget(m_progressWidget); + miniBarLayout->addWidget(bevelContainer); + miniBarLayout->addItem(new QSpacerItem(6, 6, QSizePolicy::Fixed, QSizePolicy::Fixed)); +#endif + + // widgets: [] | [right 'pageView'] + QWidget *rightContainer = new QWidget(nullptr); + m_sidebar->setMainWidget(rightContainer); + QVBoxLayout *rightLayout = new QVBoxLayout(rightContainer); + rightLayout->setContentsMargins(0, 0, 0, 0); + rightLayout->setSpacing(0); + // KToolBar * rtb = new KToolBar( rightContainer, "mainToolBarSS" ); + // rightLayout->addWidget( rtb ); + m_migrationMessage = new KMessageWidget(rightContainer); + m_migrationMessage->setVisible(false); + m_migrationMessage->setWordWrap(true); + m_migrationMessage->setMessageType(KMessageWidget::Warning); + m_migrationMessage->setText( + i18n("This document contains annotations or form data that were saved internally by a previous Okular version. Internal storage is no longer supported.
Please save to a file in order to move them if you want to continue " + "to edit the document.")); + rightLayout->addWidget(m_migrationMessage); + m_topMessage = new KMessageWidget(rightContainer); + m_topMessage->setVisible(false); + m_topMessage->setWordWrap(true); + m_topMessage->setMessageType(KMessageWidget::Information); + m_topMessage->setText(i18n("This document has embedded files.
Click here to see them or go to File -> Embedded Files.")); + m_topMessage->setIcon(QIcon::fromTheme(QStringLiteral("mail-attachment"))); + connect(m_topMessage, &KMessageWidget::linkActivated, this, &Part::slotShowEmbeddedFiles); + rightLayout->addWidget(m_topMessage); + m_formsMessage = new KMessageWidget(rightContainer); + m_formsMessage->setVisible(false); + m_formsMessage->setWordWrap(true); + m_formsMessage->setMessageType(KMessageWidget::Information); + rightLayout->addWidget(m_formsMessage); + m_infoMessage = new KMessageWidget(rightContainer); + m_infoMessage->setVisible(false); + m_infoMessage->setWordWrap(true); + m_infoMessage->setMessageType(KMessageWidget::Information); + rightLayout->addWidget(m_infoMessage); + m_infoTimer = new QTimer(); + m_infoTimer->setSingleShot(true); + connect(m_infoTimer, &QTimer::timeout, m_infoMessage, &KMessageWidget::animatedHide); + m_signatureMessage = new KMessageWidget(rightContainer); + m_signatureMessage->setVisible(false); + m_signatureMessage->setWordWrap(true); + rightLayout->addWidget(m_signatureMessage); + m_pageView = new PageView(rightContainer, m_document); + rightContainer->setFocusProxy(m_pageView); + QMetaObject::invokeMethod(m_pageView, "setFocus", Qt::QueuedConnection); // usability setting + // m_splitter->setFocusProxy(m_pageView); + connect(m_pageView.data(), &PageView::rightClick, this, &Part::slotShowMenu); + connect(m_pageView, &PageView::triggerSearch, this, [this](const QString &searchText) { + m_findBar->startSearch(searchText); + slotShowFindBar(); + }); + connect(m_document, &Document::error, this, &Part::errorMessage); + connect(m_document, &Document::warning, this, &Part::warningMessage); + connect(m_document, &Document::notice, this, &Part::noticeMessage); + connect(m_document, &Document::sourceReferenceActivated, this, &Part::slotHandleActivatedSourceReference); + connect(m_pageView.data(), &PageView::fitWindowToPage, this, &Part::fitWindowToPage); + rightLayout->addWidget(m_pageView); + m_layers->setPageView(m_pageView); + m_signaturePanel->setPageView(m_pageView); + m_findBar = new FindBar(m_document, rightContainer); + rightLayout->addWidget(m_findBar); + m_bottomBar = new QWidget(rightContainer); + QHBoxLayout *bottomBarLayout = new QHBoxLayout(m_bottomBar); + m_pageSizeLabel = new PageSizeLabel(m_bottomBar, m_document); + bottomBarLayout->setContentsMargins(0, 0, 0, 0); + bottomBarLayout->setSpacing(0); + bottomBarLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum)); + m_miniBarLogic = new MiniBarLogic(this, m_document); + m_miniBar = new MiniBar(m_bottomBar, m_miniBarLogic); + bottomBarLayout->addWidget(m_miniBar); + bottomBarLayout->addWidget(m_pageSizeLabel); + rightLayout->addWidget(m_bottomBar); + + m_pageNumberTool = new MiniBar(nullptr, m_miniBarLogic); + + connect(m_findBar, &FindBar::forwardKeyPressEvent, m_pageView, &PageView::externalKeyPressEvent); + connect(m_findBar, &FindBar::onCloseButtonPressed, m_pageView, QOverload<>::of(&PageView::setFocus)); + connect(m_miniBar, &MiniBar::forwardKeyPressEvent, m_pageView, &PageView::externalKeyPressEvent); + connect(m_pageView.data(), &PageView::escPressed, m_findBar, &FindBar::resetSearch); + connect(m_pageNumberTool, &MiniBar::forwardKeyPressEvent, m_pageView, &PageView::externalKeyPressEvent); + + connect(m_reviewsWidget.data(), &Reviews::openAnnotationWindow, m_pageView.data(), &PageView::openAnnotationWindow); + + // add document observers + m_document->addObserver(this); + m_document->addObserver(m_thumbnailList); + m_document->addObserver(m_pageView); + m_document->registerView(m_pageView); + m_document->addObserver(m_toc); + m_document->addObserver(m_miniBarLogic); +#ifdef OKULAR_ENABLE_MINIBAR + m_document->addObserver(m_progressWidget); +#endif + m_document->addObserver(m_reviewsWidget); + m_document->addObserver(m_pageSizeLabel); + m_document->addObserver(m_bookmarkList); + m_document->addObserver(m_signaturePanel); + + connect(m_document->bookmarkManager(), &BookmarkManager::saved, this, &Part::slotRebuildBookmarkMenu); + + setupViewerActions(); + + if (m_embedMode != ViewerWidgetMode) { + setupActions(); + } else { + setViewerShortcuts(); + } + + // document watcher and reloader + m_watcher = new KDirWatch(this); + connect(m_watcher, &KDirWatch::dirty, this, &Part::slotFileDirty); + connect(m_watcher, &KDirWatch::created, this, &Part::slotFileDirty); + connect(m_watcher, &KDirWatch::deleted, this, &Part::slotFileDirty); + m_dirtyHandler = new QTimer(this); + m_dirtyHandler->setSingleShot(true); + connect(m_dirtyHandler, &QTimer::timeout, this, [this] { slotAttemptReload(); }); + + slotNewConfig(); + + // keep us informed when the user changes settings + connect(Okular::Settings::self(), &KCoreConfigSkeleton::configChanged, this, &Part::slotNewConfig); + +#ifdef HAVE_SPEECH + // [SPEECH] check for TTS presence and usability + Okular::Settings::setUseTTS(true); + Okular::Settings::self()->save(); +#endif + + rebuildBookmarkMenu(false); + + if (m_embedMode == ViewerWidgetMode) { + // set the XML-UI resource file for the viewer mode + setXMLFile(QStringLiteral("part-viewermode.rc")); + } else { + // set our main XML-UI resource file + setXMLFile(QStringLiteral("part.rc")); + } + + m_pageView->setupBaseActions(actionCollection()); + + m_sidebar->setSidebarVisibility(false); + if (m_embedMode != PrintPreviewMode) { + // now set up actions that are required for all remaining modes + m_pageView->setupViewerActions(actionCollection()); + // and if we are not in viewer mode, we want the full GUI + if (m_embedMode != ViewerWidgetMode) { + unsetDummyMode(); + } + } + + // ensure history actions are in the correct state + updateViewActions(); + + // also update the state of the actions in the page view + m_pageView->updateActionState(false, false); + + if (m_embedMode == NativeShellMode) + m_sidebar->setAutoFillBackground(false); + +#ifdef OKULAR_KEEP_FILE_OPEN + m_keeper = new FileKeeper(); +#endif +} + +void Part::setupViewerActions() +{ + // ACTIONS + KActionCollection *ac = actionCollection(); + + // Page Traversal actions + m_gotoPage = KStandardAction::gotoPage(this, SLOT(slotGoToPage()), ac); + ac->setDefaultShortcuts(m_gotoPage, KStandardShortcut::gotoLine()); + // dirty way to activate gotopage when pressing miniBar's button + connect(m_miniBar.data(), &MiniBar::gotoPage, m_gotoPage, &QAction::trigger); + connect(m_pageNumberTool.data(), &MiniBar::gotoPage, m_gotoPage, &QAction::trigger); + + m_prevPage = KStandardAction::prior(this, SLOT(slotPreviousPage()), ac); + m_prevPage->setIconText(i18nc("Previous page", "Previous")); + m_prevPage->setToolTip(i18n("Go back to the Previous Page")); + m_prevPage->setWhatsThis(i18n("Moves to the previous page of the document")); + ac->setDefaultShortcut(m_prevPage, QKeySequence()); + // dirty way to activate prev page when pressing miniBar's button + connect(m_miniBar.data(), &MiniBar::prevPage, m_prevPage, &QAction::trigger); + connect(m_pageNumberTool.data(), &MiniBar::prevPage, m_prevPage, &QAction::trigger); +#ifdef OKULAR_ENABLE_MINIBAR + connect(m_progressWidget, SIGNAL(prevPage()), m_prevPage, SLOT(trigger())); +#endif + + m_nextPage = KStandardAction::next(this, SLOT(slotNextPage()), ac); + m_nextPage->setIconText(i18nc("Next page", "Next")); + m_nextPage->setToolTip(i18n("Advance to the Next Page")); + m_nextPage->setWhatsThis(i18n("Moves to the next page of the document")); + ac->setDefaultShortcut(m_nextPage, QKeySequence()); + // dirty way to activate next page when pressing miniBar's button + connect(m_miniBar.data(), &MiniBar::nextPage, m_nextPage, &QAction::trigger); + connect(m_pageNumberTool.data(), &MiniBar::nextPage, m_nextPage, &QAction::trigger); +#ifdef OKULAR_ENABLE_MINIBAR + connect(m_progressWidget, SIGNAL(nextPage()), m_nextPage, SLOT(trigger())); +#endif + + m_beginningOfDocument = KStandardAction::firstPage(this, SLOT(slotGotoFirst()), ac); + ac->addAction(QStringLiteral("first_page"), m_beginningOfDocument); + m_beginningOfDocument->setText(i18n("Beginning of the document")); + m_beginningOfDocument->setWhatsThis(i18n("Moves to the beginning of the document")); + + m_endOfDocument = KStandardAction::lastPage(this, SLOT(slotGotoLast()), ac); + ac->addAction(QStringLiteral("last_page"), m_endOfDocument); + m_endOfDocument->setText(i18n("End of the document")); + m_endOfDocument->setWhatsThis(i18n("Moves to the end of the document")); + + // we do not want back and next in history in the dummy mode + m_historyBack = nullptr; + m_historyNext = nullptr; + + m_addBookmark = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), ac); + m_addBookmarkText = m_addBookmark->text(); + m_addBookmarkIcon = m_addBookmark->icon(); + + m_renameBookmark = ac->addAction(QStringLiteral("rename_bookmark")); + m_renameBookmark->setText(i18n("Rename Bookmark")); + m_renameBookmark->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename"))); + m_renameBookmark->setWhatsThis(i18n("Rename the current bookmark")); + connect(m_renameBookmark, &QAction::triggered, this, &Part::slotRenameCurrentViewportBookmark); + + m_prevBookmark = ac->addAction(QStringLiteral("previous_bookmark")); + m_prevBookmark->setText(i18n("Previous Bookmark")); + m_prevBookmark->setIcon(QIcon::fromTheme(QStringLiteral("go-up-search"))); + m_prevBookmark->setWhatsThis(i18n("Go to the previous bookmark")); + connect(m_prevBookmark, &QAction::triggered, this, &Part::slotPreviousBookmark); + + m_nextBookmark = ac->addAction(QStringLiteral("next_bookmark")); + m_nextBookmark->setText(i18n("Next Bookmark")); + m_nextBookmark->setIcon(QIcon::fromTheme(QStringLiteral("go-down-search"))); + m_nextBookmark->setWhatsThis(i18n("Go to the next bookmark")); + connect(m_nextBookmark, &QAction::triggered, this, &Part::slotNextBookmark); + + m_copy = nullptr; + + m_selectAll = nullptr; + m_selectCurrentPage = nullptr; + + // Find and other actions + m_find = KStandardAction::find(this, SLOT(slotShowFindBar()), ac); + QList s = m_find->shortcuts(); + s.append(QKeySequence(Qt::Key_Slash)); + ac->setDefaultShortcuts(m_find, s); + m_find->setEnabled(false); + + m_findNext = KStandardAction::findNext(this, SLOT(slotFindNext()), ac); + m_findNext->setEnabled(false); + + m_findPrev = KStandardAction::findPrev(this, SLOT(slotFindPrev()), ac); + m_findPrev->setEnabled(false); + + m_save = nullptr; + m_saveAs = nullptr; + m_openContainingFolder = nullptr; + + QAction *prefs = KStandardAction::preferences(this, SLOT(slotPreferences()), ac); + if (m_embedMode == NativeShellMode) { + prefs->setText(i18n("Configure Okular...")); + } else { + // TODO: improve this message + prefs->setText(i18n("Configure Viewer...")); + } + + QAction *genPrefs = new QAction(ac); + ac->addAction(QStringLiteral("options_configure_generators"), genPrefs); + if (m_embedMode == ViewerWidgetMode) { + genPrefs->setText(i18n("Configure Viewer Backends...")); + } else { + genPrefs->setText(i18n("Configure Backends...")); + } + genPrefs->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + genPrefs->setEnabled(m_document->configurableGenerators() > 0); + connect(genPrefs, &QAction::triggered, this, &Part::slotGeneratorPreferences); + + m_printPreview = KStandardAction::printPreview(this, SLOT(slotPrintPreview()), ac); + m_printPreview->setEnabled(false); + + m_showLeftPanel = nullptr; + m_showBottomBar = nullptr; + m_showSignaturePanel = nullptr; + + m_showProperties = ac->addAction(QStringLiteral("properties")); + m_showProperties->setText(i18n("&Properties")); + m_showProperties->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); + ac->setDefaultShortcuts(m_showProperties, {QKeySequence(Qt::ALT + Qt::Key_Return)}); + connect(m_showProperties, &QAction::triggered, this, &Part::slotShowProperties); + m_showProperties->setEnabled(false); + + m_showEmbeddedFiles = nullptr; + m_showPresentation = nullptr; + + m_exportAs = nullptr; + m_exportAsMenu = nullptr; + m_exportAsText = nullptr; + m_exportAsDocArchive = nullptr; + +#if PURPOSE_FOUND + m_share = nullptr; + m_shareMenu = nullptr; +#endif + + m_presentationDrawingActions = nullptr; + + m_aboutBackend = ac->addAction(QStringLiteral("help_about_backend")); + m_aboutBackend->setText(i18n("About Backend")); + m_aboutBackend->setEnabled(false); + connect(m_aboutBackend, &QAction::triggered, this, &Part::slotAboutBackend); + + QAction *reload = ac->add(QStringLiteral("file_reload")); + reload->setText(i18n("Reloa&d")); + reload->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); + reload->setWhatsThis(i18n("Reload the current document from disk.")); + connect(reload, &QAction::triggered, this, &Part::slotReload); + ac->setDefaultShortcuts(reload, KStandardShortcut::reload()); + m_reload = reload; + + m_closeFindBar = ac->addAction(QStringLiteral("close_find_bar"), this, SLOT(slotHideFindBar())); + m_closeFindBar->setText(i18n("Close &Find Bar")); + ac->setDefaultShortcut(m_closeFindBar, QKeySequence(Qt::Key_Escape)); + m_closeFindBar->setEnabled(false); + + QWidgetAction *pageno = new QWidgetAction(ac); + pageno->setText(i18n("Page Number")); + pageno->setDefaultWidget(m_pageNumberTool); + ac->addAction(QStringLiteral("page_number"), pageno); +} + +void Part::setViewerShortcuts() +{ + KActionCollection *ac = actionCollection(); + + ac->setDefaultShortcut(m_gotoPage, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_G)); + ac->setDefaultShortcut(m_find, QKeySequence()); + + ac->setDefaultShortcut(m_findNext, QKeySequence()); + ac->setDefaultShortcut(m_findPrev, QKeySequence()); + + ac->setDefaultShortcut(m_addBookmark, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_B)); + + ac->setDefaultShortcut(m_beginningOfDocument, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Home)); + ac->setDefaultShortcut(m_endOfDocument, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_End)); + + QAction *action = static_cast(ac->action(QStringLiteral("file_reload"))); + if (action) { + ac->setDefaultShortcut(action, QKeySequence(Qt::ALT + Qt::Key_F5)); + } +} + +void Part::setupActions() +{ + KActionCollection *ac = actionCollection(); + + m_copy = KStandardAction::create(KStandardAction::Copy, m_pageView, SLOT(copyTextSelection()), ac); + + m_selectAll = KStandardAction::selectAll(m_pageView, SLOT(selectAll()), ac); + + // Setup select all action for the current page + m_selectCurrentPage = ac->addAction(QStringLiteral("edit_select_all_current_page")); + m_selectCurrentPage->setText(i18n("Select All Text on Current Page")); + connect(m_selectCurrentPage, &QAction::triggered, m_pageView, &PageView::slotSelectPage); + m_selectCurrentPage->setEnabled(false); + + m_save = KStandardAction::save( + this, [this] { saveFile(); }, ac); + m_save->setEnabled(false); + + m_saveAs = KStandardAction::saveAs(this, SLOT(slotSaveFileAs()), ac); + m_saveAs->setEnabled(false); + m_migrationMessage->addAction(m_saveAs); + + m_showLeftPanel = ac->add(QStringLiteral("show_leftpanel")); + m_showLeftPanel->setText(i18n("Show S&idebar")); + m_showLeftPanel->setIcon(QIcon::fromTheme(QStringLiteral("view-sidetree"))); + connect(m_showLeftPanel, &QAction::toggled, this, &Part::slotShowLeftPanel); + ac->setDefaultShortcut(m_showLeftPanel, QKeySequence(Qt::Key_F7)); + m_showLeftPanel->setChecked(Okular::Settings::showLeftPanel()); + slotShowLeftPanel(); + + m_showBottomBar = ac->add(QStringLiteral("show_bottombar")); + m_showBottomBar->setText(i18n("Show &Page Bar")); + connect(m_showBottomBar, &QAction::toggled, this, &Part::slotShowBottomBar); + m_showBottomBar->setChecked(Okular::Settings::showBottomBar()); + slotShowBottomBar(); + + m_showSignaturePanel = ac->add(QStringLiteral("show_signatures")); + m_showSignaturePanel->setText(i18n("Show &Signatures Panel")); + connect(m_showSignaturePanel, &QAction::triggered, this, [this] { + if (m_sidebar->currentItem() != m_signaturePanel) { + m_sidebar->setCurrentItem(m_signaturePanel); + } + m_showLeftPanel->setChecked(true); + slotShowLeftPanel(); + }); + + m_showEmbeddedFiles = ac->addAction(QStringLiteral("embedded_files")); + m_showEmbeddedFiles->setText(i18n("&Embedded Files")); + m_showEmbeddedFiles->setIcon(QIcon::fromTheme(QStringLiteral("mail-attachment"))); + connect(m_showEmbeddedFiles, &QAction::triggered, this, &Part::slotShowEmbeddedFiles); + m_showEmbeddedFiles->setEnabled(false); + + m_exportAs = ac->addAction(QStringLiteral("file_export_as")); + m_exportAs->setText(i18n("E&xport As")); + m_exportAs->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); + m_exportAsMenu = new QMenu(); + connect(m_exportAsMenu, &QMenu::triggered, this, &Part::slotExportAs); + m_exportAs->setMenu(m_exportAsMenu); + m_exportAsText = actionForExportFormat(Okular::ExportFormat::standardFormat(Okular::ExportFormat::PlainText), m_exportAsMenu); + m_exportAsMenu->addAction(m_exportAsText); + m_exportAs->setEnabled(false); + m_exportAsText->setEnabled(false); + +#if PURPOSE_FOUND + m_share = ac->addAction(QStringLiteral("file_share")); + m_share->setText(i18n("S&hare")); + m_share->setIcon(QIcon::fromTheme(QStringLiteral("document-share"))); + m_share->setEnabled(false); + m_shareMenu = new Purpose::Menu(); + connect(m_shareMenu, &Purpose::Menu::finished, this, &Part::slotShareActionFinished); + m_share->setMenu(m_shareMenu); +#endif + + m_showPresentation = ac->addAction(QStringLiteral("presentation")); + m_showPresentation->setText(i18n("P&resentation")); + m_showPresentation->setIcon(QIcon::fromTheme(QStringLiteral("view-presentation"))); + connect(m_showPresentation, &QAction::triggered, this, &Part::slotShowPresentation); + ac->setDefaultShortcut(m_showPresentation, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_P)); + m_showPresentation->setEnabled(false); + + m_openContainingFolder = ac->addAction(QStringLiteral("open_containing_folder")); + m_openContainingFolder->setText(i18n("Open Con&taining Folder")); + m_openContainingFolder->setIcon(QIcon::fromTheme(QStringLiteral("document-open-folder"))); + connect(m_openContainingFolder, &QAction::triggered, this, &Part::slotOpenContainingFolder); + m_openContainingFolder->setEnabled(false); + + QAction *importPS = ac->addAction(QStringLiteral("import_ps")); + importPS->setText(i18n("&Import PostScript as PDF...")); + importPS->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); + connect(importPS, &QAction::triggered, this, &Part::slotImportPSFile); +#if 0 + QAction * ghns = ac->addAction("get_new_stuff"); + ghns->setText(i18n("&Get Books From Internet...")); + ghns->setIcon(QIcon::fromTheme("get-hot-new-stuff")); + connect(ghns, SIGNAL(triggered()), this, SLOT(slotGetNewStuff())); +#endif + + KToggleAction *blackscreenAction = new KToggleAction(i18n("Switch Blackscreen Mode"), ac); + ac->addAction(QStringLiteral("switch_blackscreen_mode"), blackscreenAction); + ac->setDefaultShortcut(blackscreenAction, QKeySequence(Qt::Key_B)); + blackscreenAction->setIcon(QIcon::fromTheme(QStringLiteral("view-presentation"))); + blackscreenAction->setEnabled(false); + + m_presentationDrawingActions = new DrawingToolActions(ac); + + QAction *eraseDrawingAction = new QAction(i18n("Erase Drawing"), ac); + ac->addAction(QStringLiteral("presentation_erase_drawings"), eraseDrawingAction); + eraseDrawingAction->setIcon(QIcon::fromTheme(QStringLiteral("draw-eraser-delete-objects"))); + eraseDrawingAction->setEnabled(false); + + QAction *configureAnnotations = new QAction(i18n("Configure Annotations..."), ac); + ac->addAction(QStringLiteral("options_configure_annotations"), configureAnnotations); + configureAnnotations->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + connect(configureAnnotations, &QAction::triggered, this, &Part::slotAnnotationPreferences); + + QAction *playPauseAction = new QAction(i18n("Play/Pause Presentation"), ac); + ac->addAction(QStringLiteral("presentation_play_pause"), playPauseAction); + playPauseAction->setEnabled(false); +} + +Part::~Part() +{ + QDBusConnection::sessionBus().unregisterObject(m_registerDbusName); + + GuiUtils::removeIconLoader(iconLoader()); + m_document->removeObserver(this); + + if (m_document->isOpened()) + Part::closeUrl(false); + + delete m_toc; + delete m_layers; + delete m_pageView; + delete m_thumbnailList; + delete m_miniBar; + delete m_pageNumberTool; + delete m_miniBarLogic; + delete m_bottomBar; +#ifdef OKULAR_ENABLE_MINIBAR + delete m_progressWidget; +#endif + delete m_pageSizeLabel; + delete m_reviewsWidget; + delete m_bookmarkList; + delete m_infoTimer; + delete m_signaturePanel; + + delete m_document; + + delete m_tempfile; + + qDeleteAll(m_bookmarkActions); + + delete m_exportAsMenu; +#if PURPOSE_FOUND + delete m_shareMenu; +#endif + +#ifdef OKULAR_KEEP_FILE_OPEN + delete m_keeper; +#endif +} + +bool Part::openDocument(const QUrl &url, uint page) +{ + Okular::DocumentViewport vp(page - 1); + vp.rePos.enabled = true; + vp.rePos.normalizedX = 0; + vp.rePos.normalizedY = 0; + vp.rePos.pos = Okular::DocumentViewport::TopLeft; + if (vp.isValid()) + m_document->setNextDocumentViewport(vp); + return openUrl(url); +} + +void Part::startPresentation() +{ + m_cliPresentation = true; +} + +QStringList Part::supportedMimeTypes() const +{ + return m_document->supportedMimeTypes(); +} + +QUrl Part::realUrl() const +{ + if (!m_realUrl.isEmpty()) + return m_realUrl; + + return url(); +} + +// ViewerInterface + +void Part::showSourceLocation(const QString &fileName, int line, int column, bool showGraphically) +{ + Q_UNUSED(column); + + const QString u = QStringLiteral("src:%1 %2").arg(line + 1).arg(fileName); + GotoAction action(QString(), u); + m_document->processAction(&action); + if (showGraphically) { + m_pageView->setLastSourceLocationViewport(m_document->viewport()); + } +} + +void Part::clearLastShownSourceLocation() +{ + m_pageView->clearLastSourceLocationViewport(); +} + +bool Part::isWatchFileModeEnabled() const +{ + return !m_watcher->signalsBlocked(); +} + +void Part::setWatchFileModeEnabled(bool enabled) +{ + // Don't call 'KDirWatch::stopScan()' in here (as of KDE Frameworks 5.51.0, see bug 400541)! + // 'KDirWatch::stopScan' has a bug that may affect other code paths that make use of KDirWatch + // (other loaded KParts, for example). + if (isWatchFileModeEnabled() == enabled) { + return; + } + + m_watcher->blockSignals(!enabled); + + if (!enabled) { + m_dirtyHandler->stop(); + } +} + +bool Part::areSourceLocationsShownGraphically() const +{ + return m_pageView->areSourceLocationsShownGraphically(); +} + +void Part::setShowSourceLocationsGraphically(bool show) +{ + m_pageView->setShowSourceLocationsGraphically(show); +} + +bool Part::openNewFilesInTabs() const +{ + return Okular::Settings::self()->shellOpenFileInTabs(); +} + +bool Part::activateTabIfAlreadyOpenFile() const +{ + return Okular::Settings::self()->switchToTabIfOpen(); +} + +void Part::slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled) +{ + emit openSourceReference(absFileName, line, col); + if (m_embedMode == Okular::ViewerWidgetMode) { + *handled = true; + } +} + +void Part::openUrlFromDocument(const QUrl &url) +{ + if (m_embedMode == PrintPreviewMode) + return; + + if (url.isLocalFile()) { + if (!QFile::exists(url.toLocalFile())) { + KMessageBox::error(widget(), i18n("Could not open '%1'. File does not exist", url.toDisplayString())); + return; + } + } else { + KIO::StatJob *statJob = KIO::stat(url, KIO::StatJob::SourceSide, 0); + KJobWidgets::setWindow(statJob, widget()); + if (!statJob->exec() || statJob->error()) { + KMessageBox::error(widget(), i18n("Could not open '%1' (%2) ", url.toDisplayString(), statJob->errorString())); + return; + } + } + + emit m_bExtension->openUrlNotify(); + emit m_bExtension->setLocationBarUrl(url.toDisplayString()); + openUrl(url); +} + +void Part::openUrlFromBookmarks(const QUrl &_url) +{ + QUrl url = _url; + Okular::DocumentViewport vp(_url.fragment(QUrl::FullyDecoded)); + if (vp.isValid()) + m_document->setNextDocumentViewport(vp); + url.setFragment(QString()); + if (m_document->currentDocument() == url) { + if (vp.isValid()) + m_document->setViewport(vp); + } else + openUrl(url); +} + +void Part::handleDroppedUrls(const QList &urls) +{ + if (urls.isEmpty()) + return; + + if (m_embedMode != NativeShellMode || !openNewFilesInTabs()) { + openUrlFromDocument(urls.first()); + return; + } + + emit urlsDropped(urls); +} + +void Part::slotJobStarted(KIO::Job *job) +{ + if (job) { + QStringList supportedMimeTypes = m_document->supportedMimeTypes(); + job->addMetaData(QStringLiteral("accept"), supportedMimeTypes.join(QStringLiteral(", ")) + QStringLiteral(", */*;q=0.5")); + + connect(job, &KJob::result, this, &Part::slotJobFinished); + } +} + +void Part::slotJobFinished(KJob *job) +{ + if (job->error() == KIO::ERR_USER_CANCELED) { + m_pageView->displayMessage(i18n("The loading of %1 has been canceled.", realUrl().toDisplayString(QUrl::PreferLocalFile))); + } +} + +void Part::loadCancelled(const QString &reason) +{ + emit setWindowCaption(QString()); + resetStartArguments(); + + // when m_viewportDirty.pageNumber != -1 we come from slotAttemptReload + // so we don't want to show an ugly messagebox just because the document is + // taking more than usual to be recreated + if (m_viewportDirty.pageNumber == -1) { + if (m_urlWithFragment.isValid() && !m_urlWithFragment.isLocalFile()) { + tryOpeningUrlWithFragmentAsName(); + } else if (!reason.isEmpty()) { + KMessageBox::error(widget(), i18n("Could not open %1. Reason: %2", url().toDisplayString(), reason)); + } + } +} + +void Part::setWindowTitleFromDocument() +{ + // If 'DocumentTitle' should be used, check if the document has one. If + // either case is false, use the file name. + QString title = Okular::Settings::displayDocumentNameOrPath() == Okular::Settings::EnumDisplayDocumentNameOrPath::Path ? realUrl().toDisplayString(QUrl::PreferLocalFile) : realUrl().fileName(); + + if (Okular::Settings::displayDocumentTitle()) { + const QString docTitle = m_document->metaData(QStringLiteral("DocumentTitle")).toString(); + if (!docTitle.isEmpty() && !docTitle.trimmed().isEmpty()) { + title = docTitle; + } + } + + emit setWindowCaption(title); +} + +KConfigDialog *Part::slotGeneratorPreferences() +{ + // Create dialog + KConfigDialog *dialog = new Okular::BackendConfigDialog(m_pageView, QStringLiteral("generator_prefs"), Okular::Settings::self()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + + if (m_embedMode == ViewerWidgetMode) { + dialog->setWindowTitle(i18n("Configure Viewer Backends")); + } else { + dialog->setWindowTitle(i18n("Configure Backends")); + } + + m_document->fillConfigDialog(dialog); + + // Show it + dialog->setWindowModality(Qt::ApplicationModal); + dialog->show(); + + return dialog; +} + +void Part::notifySetup(const QVector & /*pages*/, int setupFlags) +{ + // Hide the migration message if the user has just migrated. Otherwise, + // if m_migrationMessage is already hidden, this does nothing. + if (!m_document->isDocdataMigrationNeeded()) + m_migrationMessage->animatedHide(); + + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) + return; + + rebuildBookmarkMenu(); + updateAboutBackendAction(); + m_findBar->resetSearch(); + m_searchWidget->setEnabled(m_document->supportsSearching()); +} + +void Part::notifyViewportChanged(bool /*smoothMove*/) +{ + updateViewActions(); +} + +void Part::notifyPageChanged(int page, int flags) +{ + if (!(flags & Okular::DocumentObserver::Bookmark)) + return; + + rebuildBookmarkMenu(); + if (page == m_document->viewport().pageNumber) + updateBookmarksActions(); +} + +void Part::goToPage(uint page) +{ + if (page <= m_document->pages()) + m_document->setViewportPage(page - 1); +} + +void Part::openDocument(const QString &doc) +{ + openUrl(QUrl::fromUserInput(doc)); +} + +uint Part::pages() +{ + return m_document->pages(); +} + +uint Part::currentPage() +{ + return m_document->pages() ? m_document->currentPage() + 1 : 0; +} + +QString Part::currentDocument() +{ + return m_document->currentDocument().toDisplayString(QUrl::PreferLocalFile); +} + +QString Part::documentMetaData(const QString &metaData) const +{ + const Okular::DocumentInfo info = m_document->documentInfo(); + return info.get(metaData); +} + +bool Part::slotImportPSFile() +{ + QString app = QStandardPaths::findExecutable(QStringLiteral("ps2pdf")); + if (app.isEmpty()) { + // TODO point the user to their distro packages? + KMessageBox::error(widget(), i18n("The program \"ps2pdf\" was not found, so Okular can not import PS files using it."), i18n("ps2pdf not found")); + return false; + } + + QMimeDatabase mimeDatabase; + QString filter = i18n("PostScript files (%1)", mimeDatabase.mimeTypeForName(QStringLiteral("application/postscript")).globPatterns().join(QLatin1Char(' '))); + + QUrl url = QFileDialog::getOpenFileUrl(widget(), QString(), QUrl(), filter); + if (url.isLocalFile()) { + QTemporaryFile tf(QDir::tempPath() + QLatin1String("/okular_XXXXXX.pdf")); + tf.setAutoRemove(false); + if (!tf.open()) + return false; + m_temporaryLocalFile = tf.fileName(); + tf.close(); + + setLocalFilePath(url.toLocalFile()); + QStringList args; + QProcess *p = new QProcess(); + args << url.toLocalFile() << m_temporaryLocalFile; + m_pageView->displayMessage(i18n("Importing PS file as PDF (this may take a while)...")); + connect(p, QOverload::of(&QProcess::finished), this, &Part::psTransformEnded); + p->start(app, args); + return true; + } + + m_temporaryLocalFile.clear(); + return false; +} + +void Part::setFileToWatch(const QString &filePath) +{ + if (!m_watchedFilePath.isEmpty()) + unsetFileToWatch(); + + const QFileInfo fi(filePath); + + m_watchedFilePath = filePath; + m_watcher->addFile(m_watchedFilePath); + + if (fi.isSymLink()) { + m_watchedFileSymlinkTarget = fi.symLinkTarget(); + m_watcher->addFile(m_watchedFileSymlinkTarget); + } else { + m_watchedFileSymlinkTarget.clear(); + } +} + +void Part::unsetFileToWatch() +{ + if (m_watchedFilePath.isEmpty()) + return; + + m_watcher->removeFile(m_watchedFilePath); + + if (!m_watchedFileSymlinkTarget.isEmpty()) + m_watcher->removeFile(m_watchedFileSymlinkTarget); + + m_watchedFilePath.clear(); + m_watchedFileSymlinkTarget.clear(); +} + +Document::OpenResult Part::doOpenFile(const QMimeType &mimeA, const QString &fileNameToOpenA, bool *isCompressedFile) +{ + QMimeDatabase db; + Document::OpenResult openResult = Document::OpenError; + bool uncompressOk = true; + QMimeType mime = mimeA; + QString fileNameToOpen = fileNameToOpenA; + KFilterDev::CompressionType compressionType = compressionTypeFor(mime.name()); + if (compressionType != KFilterDev::None) { + *isCompressedFile = true; + uncompressOk = handleCompressed(fileNameToOpen, localFilePath(), compressionType); + mime = db.mimeTypeForFile(fileNameToOpen); + } else { + *isCompressedFile = false; + } + + if (m_swapInsteadOfOpening) { + m_swapInsteadOfOpening = false; + + if (!uncompressOk) + return Document::OpenError; + + if (mime.inherits(QStringLiteral("application/vnd.kde.okular-archive"))) { + isDocumentArchive = true; + if (!m_document->swapBackingFileArchive(fileNameToOpen, url())) + return Document::OpenError; + } else { + isDocumentArchive = false; + if (!m_document->swapBackingFile(fileNameToOpen, url())) + return Document::OpenError; + } + + m_fileLastModified = QFileInfo(localFilePath()).lastModified(); + return Document::OpenSuccess; + } + + isDocumentArchive = false; + if (uncompressOk) { + if (mime.inherits(QStringLiteral("application/vnd.kde.okular-archive"))) { + openResult = m_document->openDocumentArchive(fileNameToOpen, url()); + isDocumentArchive = true; + } else { + openResult = m_document->openDocument(fileNameToOpen, url(), mime); + } + m_documentOpenWithPassword = false; + +#ifdef WITH_KWALLET + // if the file didn't open correctly it might be encrypted, so ask for a pass + QString walletName, walletFolder, walletKey; + m_document->walletDataForFile(fileNameToOpen, &walletName, &walletFolder, &walletKey); + bool firstInput = true; + bool triedWallet = false; + KWallet::Wallet *wallet = nullptr; + bool keep = true; + while (openResult == Document::OpenNeedsPassword) { + QString password; + + // 1.A. try to retrieve the first password from the kde wallet system + if (!triedWallet && !walletKey.isNull()) { + const WId parentwid = widget()->effectiveWinId(); + wallet = KWallet::Wallet::openWallet(walletName, parentwid); + if (wallet) { + // use the KPdf folder (and create if missing) + if (!wallet->hasFolder(walletFolder)) + wallet->createFolder(walletFolder); + wallet->setFolder(walletFolder); + + // look for the pass in that folder + QString retrievedPass; + if (!wallet->readPassword(walletKey, retrievedPass)) + password = retrievedPass; + } + triedWallet = true; + } + + // 1.B. if not retrieved, ask the password using the kde password dialog + if (password.isNull()) { + QString prompt; + if (firstInput) + prompt = i18n("Please enter the password to read the document:"); + else + prompt = i18n("Incorrect password. Try again:"); + firstInput = false; + + // if the user presses cancel, abort opening + KPasswordDialog dlg(widget(), wallet ? KPasswordDialog::ShowKeepPassword : KPasswordDialog::KPasswordDialogFlags()); + dlg.setWindowTitle(i18n("Document Password")); + dlg.setPrompt(prompt); + if (!dlg.exec()) + break; + password = dlg.password(); + if (wallet) + keep = dlg.keepPassword(); + } + + // 2. reopen the document using the password + if (mime.inherits(QStringLiteral("application/vnd.kde.okular-archive"))) { + openResult = m_document->openDocumentArchive(fileNameToOpen, url(), password); + isDocumentArchive = true; + } else { + openResult = m_document->openDocument(fileNameToOpen, url(), mime, password); + } + + if (openResult == Document::OpenSuccess) { + m_documentOpenWithPassword = true; + + // 3. if the password is correct and the user chose to remember it, store it to the wallet + if (wallet && /*safety check*/ wallet->isOpen() && keep) { + wallet->writePassword(walletKey, password); + } + } + } +#endif + } + + if (openResult == Document::OpenSuccess) { + m_fileLastModified = QFileInfo(localFilePath()).lastModified(); + } + return openResult; +} + +bool Part::openFile() +{ + QList mimes; + QString fileNameToOpen = localFilePath(); + const bool isstdin = url().isLocalFile() && url().fileName() == QLatin1String("-"); + const QFileInfo fileInfo(fileNameToOpen); + if ((!isstdin) && (!fileInfo.exists())) + return false; + QMimeDatabase db; + QMimeType pathMime = db.mimeTypeForFile(fileNameToOpen); + if (!arguments().mimeType().isEmpty()) { + QMimeType argMime = db.mimeTypeForName(arguments().mimeType()); + + // Select the "childmost" mimetype, if none of them + // inherits the other trust more what pathMime says + // but still do a second try if that one fails + if (argMime.inherits(pathMime.name())) { + mimes << argMime; + } else if (pathMime.inherits(argMime.name())) { + mimes << pathMime; + } else { + mimes << pathMime << argMime; + } + + if (mimes[0].inherits(QStringLiteral("text/plain"))) { + const QMimeType contentMime = db.mimeTypeForFile(fileNameToOpen, QMimeDatabase::MatchContent); + if (contentMime.name() != QLatin1String("text/plain")) { + mimes.prepend(contentMime); + } + } + } else { + mimes << pathMime; + } + + QMimeType mime; + Document::OpenResult openResult = Document::OpenError; + bool isCompressedFile = false; + while (!mimes.isEmpty() && openResult == Document::OpenError) { + mime = mimes.takeFirst(); + openResult = doOpenFile(mime, fileNameToOpen, &isCompressedFile); + } + + bool canSearch = m_document->supportsSearching(); + emit mimeTypeChanged(mime); + + // update one-time actions + const bool ok = openResult == Document::OpenSuccess; + emit enableCloseAction(ok); + m_find->setEnabled(ok && canSearch); + m_findNext->setEnabled(ok && canSearch); + m_findPrev->setEnabled(ok && canSearch); + if (m_save) + m_save->setEnabled(ok && !(isstdin || mime.inherits(QStringLiteral("inode/directory")))); + if (m_saveAs) + m_saveAs->setEnabled(ok && !(isstdin || mime.inherits(QStringLiteral("inode/directory")))); + emit enablePrintAction(ok && m_document->printingSupport() != Okular::Document::NoPrinting); + m_printPreview->setEnabled(ok && m_document->printingSupport() != Okular::Document::NoPrinting); + m_showProperties->setEnabled(ok); + if (m_openContainingFolder) + m_openContainingFolder->setEnabled(ok); + bool hasEmbeddedFiles = ok && m_document->embeddedFiles() && m_document->embeddedFiles()->count() > 0; + if (m_showEmbeddedFiles) + m_showEmbeddedFiles->setEnabled(hasEmbeddedFiles); + m_topMessage->setVisible(hasEmbeddedFiles && Okular::Settings::showOSD()); + m_migrationMessage->setVisible(m_document->isDocdataMigrationNeeded()); + + // Warn the user that XFA forms are not supported yet (NOTE: poppler generator only) + if (ok && m_document->metaData(QStringLiteral("HasUnsupportedXfaForm")).toBool() == true) { + m_formsMessage->setText(i18n("This document has XFA forms, which are currently unsupported.")); + m_formsMessage->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); + m_formsMessage->setMessageType(KMessageWidget::Warning); + m_formsMessage->setVisible(true); + } + // m_pageView->toggleFormsAction() may be null on dummy mode + else if (ok && m_pageView->toggleFormsAction() && m_pageView->toggleFormsAction()->isEnabled()) { + m_formsMessage->setText(i18n("This document has forms. Click on the button to interact with them, or use View -> Show Forms.")); + m_formsMessage->setMessageType(KMessageWidget::Information); + m_formsMessage->setVisible(true); + } else { + m_formsMessage->setVisible(false); + } + + if (ok) { + const uint numPages = m_document->pages(); + bool isDigitallySigned = false; + for (uint i = 0; i < numPages; i++) { + const QLinkedList formFields = m_document->page(i)->formFields(); + for (const Okular::FormField *f : formFields) { + if (f->type() == Okular::FormField::FormSignature) + isDigitallySigned = true; + } + } + + if (isDigitallySigned) { + if (m_embedMode == PrintPreviewMode) { + m_signatureMessage->setText(i18n("All editing and interactive features for this document are disabled. Please save a copy and reopen to edit this document.")); + } else { + const QVector signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_document, true, 0); + bool allSignaturesValid = true; + for (const Okular::FormFieldSignature *signature : signatureFormFields) { + const Okular::SignatureInfo &info = signature->signatureInfo(); + if (info.signatureStatus() != SignatureInfo::SignatureValid) { + allSignaturesValid = false; + } + } + + if (allSignaturesValid) { + if (signatureFormFields.last()->signatureInfo().signsTotalDocument()) { + m_signatureMessage->setMessageType(KMessageWidget::Information); + m_signatureMessage->setText(i18n("This document is digitally signed.")); + } else { + m_signatureMessage->setMessageType(KMessageWidget::Warning); + m_signatureMessage->setText(i18n("This document is digitally signed. There have been changes since last signed.")); + } + } else { + m_signatureMessage->setMessageType(KMessageWidget::Warning); + m_signatureMessage->setText(i18n("This document is digitally signed. Some of the signatures could not be validated properly.")); + } + } + m_signatureMessage->setVisible(true); + } + } + + if (m_showPresentation) + m_showPresentation->setEnabled(ok); + if (ok) { + if (m_exportAs) { + m_exportFormats = m_document->exportFormats(); + QList::ConstIterator it = m_exportFormats.constBegin(); + QList::ConstIterator itEnd = m_exportFormats.constEnd(); + QMenu *menu = m_exportAs->menu(); + for (; it != itEnd; ++it) { + menu->addAction(actionForExportFormat(*it)); + } + } +#if PURPOSE_FOUND + if (m_share) { + m_shareMenu->model()->setInputData(QJsonObject {{QStringLiteral("mimeType"), mime.name()}, {QStringLiteral("urls"), QJsonArray {url().toString()}}}); + m_shareMenu->model()->setPluginType(QStringLiteral("Export")); + m_shareMenu->reload(); + } +#endif + if (isCompressedFile) { + m_realUrl = url(); + } +#ifdef OKULAR_KEEP_FILE_OPEN + 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); +#if PURPOSE_FOUND + if (m_share) + m_share->setEnabled(ok); +#endif + + // update viewing actions + updateViewActions(); + + m_fileWasRemoved = false; + + if (!ok) { + // if can't open document, update windows so they display blank contents + m_pageView->viewport()->update(); + m_thumbnailList->update(); + setUrl(QUrl()); + return false; + } + + // set the file to the fileWatcher + if (url().isLocalFile()) + setFileToWatch(localFilePath()); + + // if the 'OpenTOC' flag is set, open the TOC + if (m_document->metaData(QStringLiteral("OpenTOC")).toBool() && m_tocEnabled && m_sidebar->currentItem() != m_toc) { + m_sidebar->setCurrentItem(m_toc); + } + // if the 'StartFullScreen' flag is set and we're not in viewer widget mode, or the command line flag was + // specified, start presentation + const bool presentationBecauseOfDocumentMetadata = (m_embedMode != ViewerWidgetMode) && m_document->metaData(QStringLiteral("StartFullScreen")).toBool(); + if ((presentationBecauseOfDocumentMetadata || m_cliPresentation) && !m_isReloading) { + bool goAheadWithPresentationMode = true; + if (!m_cliPresentation) { + const QString text = i18n( + "This document wants to be shown full screen.\n" + "Leave normal mode and enter presentation mode?"); + const QString caption = i18n("Request to Change Viewing Mode"); + const KGuiItem yesItem = KGuiItem(i18n("Enter Presentation Mode"), QStringLiteral("dialog-ok")); + const KGuiItem noItem = KGuiItem(i18n("Deny Request"), QStringLiteral("dialog-cancel")); + const int result = KMessageBox::questionYesNo(widget(), text, caption, yesItem, noItem); + if (result == KMessageBox::No) + goAheadWithPresentationMode = false; + } + m_cliPresentation = false; + if (goAheadWithPresentationMode) + QMetaObject::invokeMethod(this, "slotShowPresentation", Qt::QueuedConnection); + } + m_generatorGuiClient = factory() ? m_document->guiClient() : nullptr; + if (m_generatorGuiClient) + factory()->addClient(m_generatorGuiClient); + if (m_cliPrint) { + m_cliPrint = false; + slotPrint(); + } else if (m_cliPrintAndExit) { + slotPrint(); + } + return true; +} + +bool Part::openUrl(const QUrl &url) +{ + return openUrl(url, false /* swapInsteadOfOpening */); +} + +bool Part::openUrl(const QUrl &_url, bool swapInsteadOfOpening) +{ + /* Store swapInsteadOfOpening, so that closeUrl and openFile will be able + * to read it */ + m_swapInsteadOfOpening = swapInsteadOfOpening; + + // The subsequent call to closeUrl clears the arguments. + // We want to save them and restore them later. + const KParts::OpenUrlArguments args = arguments(); + + // Close current document if any + if (!closeUrl()) + return false; + + setArguments(args); + + QUrl url(_url); + if (url.hasFragment()) { + m_urlWithFragment = _url; + const QString dest = url.fragment(QUrl::FullyDecoded); + bool ok = true; + int page = dest.toInt(&ok); + + if (!ok) { + const QStringList parameters = dest.split(QChar('&')); + for (const QString ¶meter : parameters) { + if (parameter.startsWith(QStringLiteral("page="), Qt::CaseInsensitive)) { + page = dest.midRef(5).toInt(&ok); + } + } + } + + if (ok) { + Okular::DocumentViewport vp(page - 1); + vp.rePos.enabled = true; + vp.rePos.normalizedX = 0; + vp.rePos.normalizedY = 0; + vp.rePos.pos = Okular::DocumentViewport::TopLeft; + m_document->setNextDocumentViewport(vp); + } else { + m_document->setNextDocumentDestination(dest); + } + url.setFragment(QString()); + } else { + m_urlWithFragment.clear(); + } + + // this calls in sequence the 'closeUrl' and 'openFile' methods + bool openOk = KParts::ReadWritePart::openUrl(url); + + if (openOk) { + m_viewportDirty.pageNumber = -1; + + setWindowTitleFromDocument(); + } else { + if (m_urlWithFragment.isValid() && m_urlWithFragment.isLocalFile()) { + openOk = tryOpeningUrlWithFragmentAsName(); + } else { + resetStartArguments(); + /* TRANSLATORS: Adding the reason (%2) why the opening failed (if any). */ + QString errorMessage = i18n("Could not open %1. %2", url.toDisplayString(), QStringLiteral("\n%1").arg(m_document->openError())); + KMessageBox::error(widget(), errorMessage); + } + } + + return openOk; +} + +bool Part::tryOpeningUrlWithFragmentAsName() +{ + QUrl url = m_urlWithFragment; + url.setPath(url.path() + QLatin1Char('#') + url.fragment()); + url.setFragment(QString()); + return openUrl(url); +} + +bool Part::queryClose() +{ + if (!isReadWrite() || !isModified()) + return true; + + // TODO When we get different saving backends we need to query the backend + // as to if it can save changes even if the open file has been modified, + // since we only have poppler as saving backend for now we're skipping that check + if (m_fileLastModified != QFileInfo(localFilePath()).lastModified()) { + int res; + if (m_isReloading) { + res = KMessageBox::warningYesNo( + widget(), + i18n("There are unsaved changes, and the file '%1' has been modified by another program. Your changes will be lost, because the file can no longer be saved.
Do you want to continue reloading the file?", url().fileName()), + i18n("File Changed"), + KGuiItem(i18n("Continue Reloading")), // <- KMessageBox::Yes + KGuiItem(i18n("Abort Reloading"))); + } else { + res = KMessageBox::warningYesNo( + widget(), + i18n("There are unsaved changes, and the file '%1' has been modified by another program. Your changes will be lost, because the file can no longer be saved.
Do you want to continue closing the file?", url().fileName()), + i18n("File Changed"), + KGuiItem(i18n("Continue Closing")), // <- KMessageBox::Yes + KGuiItem(i18n("Abort Closing"))); + } + return res == KMessageBox::Yes; + } + + const int res = KMessageBox::warningYesNoCancel(widget(), i18n("Do you want to save your changes to \"%1\" or discard them?", url().fileName()), i18n("Close Document"), KStandardGuiItem::save(), KStandardGuiItem::discard()); + + switch (res) { + case KMessageBox::Yes: // Save + saveFile(); + return !isModified(); // Only allow closing if file was really saved + case KMessageBox::No: // Discard + return true; + default: // Cancel + return false; + } +} + +bool Part::closeUrl(bool promptToSave) +{ + if (promptToSave && !queryClose()) + return false; + + if (m_swapInsteadOfOpening) { + // If we're swapping the backing file, we don't want to close the + // current one when openUrl() calls us internally + return true; // pretend it worked + } + + m_document->setHistoryClean(true); + + if (!m_temporaryLocalFile.isNull() && m_temporaryLocalFile != localFilePath()) { + QFile::remove(m_temporaryLocalFile); + m_temporaryLocalFile.clear(); + } + + slotHidePresentation(); + emit enableCloseAction(false); + m_find->setEnabled(false); + m_findNext->setEnabled(false); + m_findPrev->setEnabled(false); + if (m_save) + m_save->setEnabled(false); + if (m_saveAs) + m_saveAs->setEnabled(false); + m_printPreview->setEnabled(false); + m_showProperties->setEnabled(false); + if (m_showEmbeddedFiles) + m_showEmbeddedFiles->setEnabled(false); + if (m_exportAs) + m_exportAs->setEnabled(false); + if (m_exportAsText) + m_exportAsText->setEnabled(false); + m_exportFormats.clear(); + if (m_exportAs) { + QMenu *menu = m_exportAs->menu(); + QList acts = menu->actions(); + int num = acts.count(); + for (int i = 1; i < num; ++i) { + menu->removeAction(acts.at(i)); + delete acts.at(i); + } + } +#if PURPOSE_FOUND + if (m_share) { + m_share->setEnabled(false); + m_shareMenu->clear(); + } +#endif + if (m_showPresentation) + m_showPresentation->setEnabled(false); + emit setWindowCaption(QLatin1String("")); + emit enablePrintAction(false); + m_realUrl = QUrl(); + if (url().isLocalFile()) + unsetFileToWatch(); + m_fileWasRemoved = false; + if (m_generatorGuiClient) + factory()->removeClient(m_generatorGuiClient); + m_generatorGuiClient = nullptr; + m_document->closeDocument(); + m_fileLastModified = QDateTime(); + updateViewActions(); + delete m_tempfile; + m_tempfile = nullptr; + if (widget()) { + m_searchWidget->clearText(); + m_migrationMessage->setVisible(false); + m_topMessage->setVisible(false); + m_formsMessage->setVisible(false); + m_signatureMessage->setVisible(false); + } +#ifdef OKULAR_KEEP_FILE_OPEN + m_keeper->close(); +#endif + bool r = KParts::ReadWritePart::closeUrl(); + setUrl(QUrl()); + + return r; +} + +bool Part::closeUrl() +{ + return closeUrl(true); +} + +void Part::guiActivateEvent(KParts::GUIActivateEvent *event) +{ + updateViewActions(); + + KParts::ReadWritePart::guiActivateEvent(event); + + setWindowTitleFromDocument(); + + if (event->activated()) { + m_pageView->setupActionsPostGUIActivated(); + } +} + +void Part::close() +{ + if (m_embedMode == NativeShellMode) { + closeUrl(); + } else + KMessageBox::information(widget(), i18n("This link points to a close document action that does not work when using the embedded viewer."), QString(), QStringLiteral("warnNoCloseIfNotInOkular")); +} + +void Part::cannotQuit() +{ + KMessageBox::information(widget(), i18n("This link points to a quit application action that does not work when using the embedded viewer."), QString(), QStringLiteral("warnNoQuitIfNotInOkular")); +} + +void Part::slotShowLeftPanel() +{ + bool showLeft = m_showLeftPanel->isChecked(); + Okular::Settings::setShowLeftPanel(showLeft); + Okular::Settings::self()->save(); + // show/hide left panel + m_sidebar->setSidebarVisibility(showLeft); +} + +void Part::slotShowBottomBar() +{ + const bool showBottom = m_showBottomBar->isChecked(); + Okular::Settings::setShowBottomBar(showBottom); + Okular::Settings::self()->save(); + // show/hide bottom bar + m_bottomBar->setVisible(showBottom); +} + +void Part::slotFileDirty(const QString &path) +{ + // The beauty of this is that each start cancels the previous one. + // This means that timeout() is only fired when there have + // no changes to the file for the last 750 millisecs. + // This ensures that we don't update on every other byte that gets + // written to the file. + if (path == localFilePath()) { + // Only start watching the file in case if it wasn't removed + if (QFile::exists(localFilePath())) + m_dirtyHandler->start(750); + else + m_fileWasRemoved = true; + } else { + const QFileInfo fi(localFilePath()); + if (fi.absolutePath() == path) { + // Our parent has been dirtified + if (!QFile::exists(localFilePath())) { + m_fileWasRemoved = true; + } else if (m_fileWasRemoved && QFile::exists(localFilePath())) { + // we need to watch the new file + unsetFileToWatch(); + setFileToWatch(localFilePath()); + m_dirtyHandler->start(750); + } + } else if (fi.isSymLink() && fi.symLinkTarget() == path) { + if (QFile::exists(fi.symLinkTarget())) + m_dirtyHandler->start(750); + else + m_fileWasRemoved = true; + } + } +} + +// Attempt to reload the document, one or more times, optionally from a different URL +bool Part::slotAttemptReload(bool oneShot, const QUrl &newUrl) +{ + // Skip reload when another reload is already in progress + if (m_isReloading) { + return false; + } + QScopedValueRollback rollback(m_isReloading, true); + + bool tocReloadPrepared = false; + + // do the following the first time the file is reloaded + if (m_viewportDirty.pageNumber == -1) { + // store the url of the current document + m_oldUrl = newUrl.isEmpty() ? url() : newUrl; + + // store the current viewport + m_viewportDirty = m_document->viewport(); + + // store the current toolbox pane + m_dirtyToolboxItem = m_sidebar->currentItem(); + m_wasSidebarVisible = m_sidebar->isSidebarVisible(); + + // store if presentation view was open + m_wasPresentationOpen = ((PresentationWidget *)m_presentationWidget != nullptr); + + // preserves the toc state after reload + m_toc->prepareForReload(); + tocReloadPrepared = true; + + // store the page rotation + m_dirtyPageRotation = m_document->rotation(); + + // inform the user about the operation in progress + // TODO: Remove this line and integrate reload info in queryClose + m_pageView->displayMessage(i18n("Reloading the document...")); + } + + // close and (try to) reopen the document + if (!closeUrl()) { + m_viewportDirty.pageNumber = -1; + + if (tocReloadPrepared) { + m_toc->rollbackReload(); + } + return false; + } + + if (tocReloadPrepared) + m_toc->finishReload(); + + // inform the user about the operation in progress + m_pageView->displayMessage(i18n("Reloading the document...")); + + bool reloadSucceeded = false; + + if (KParts::ReadWritePart::openUrl(m_oldUrl)) { + // on successful opening, restore the previous viewport + if (m_viewportDirty.pageNumber >= (int)m_document->pages()) + m_viewportDirty.pageNumber = (int)m_document->pages() - 1; + m_document->setViewport(m_viewportDirty); + m_oldUrl = QUrl(); + m_viewportDirty.pageNumber = -1; + m_document->setRotation(m_dirtyPageRotation); + if (m_sidebar->currentItem() != m_dirtyToolboxItem) { + m_sidebar->setCurrentItem(m_dirtyToolboxItem); + } + if (m_sidebar->isSidebarVisible() != m_wasSidebarVisible) { + m_sidebar->setSidebarVisibility(m_wasSidebarVisible); + } + if (m_wasPresentationOpen) + slotShowPresentation(); + emit enablePrintAction(true && m_document->printingSupport() != Okular::Document::NoPrinting); + + reloadSucceeded = true; + } else if (!oneShot) { + // start watching the file again (since we dropped it on close) + setFileToWatch(localFilePath()); + m_dirtyHandler->start(750); + } + + return reloadSucceeded; +} + +void Part::updateViewActions() +{ + bool opened = m_document->pages() > 0; + if (opened) { + m_gotoPage->setEnabled(m_document->pages() > 1); + + // Check if you are at the beginning or not + if (m_document->currentPage() != 0) { + m_beginningOfDocument->setEnabled(true); + m_prevPage->setEnabled(true); + } else { + if (m_pageView->verticalScrollBar()->value() != 0) { + // The page isn't at the very beginning + m_beginningOfDocument->setEnabled(true); + } else { + // The page is at the very beginning of the document + m_beginningOfDocument->setEnabled(false); + } + // The document is at the first page, you can go to a page before + m_prevPage->setEnabled(false); + } + + if (m_document->pages() == m_document->currentPage() + 1) { + // If you are at the end, disable go to next page + m_nextPage->setEnabled(false); + if (m_pageView->verticalScrollBar()->value() == m_pageView->verticalScrollBar()->maximum()) { + // If you are the end of the page of the last document, you can't go to the last page + m_endOfDocument->setEnabled(false); + } else { + // Otherwise you can move to the endif + m_endOfDocument->setEnabled(true); + } + } else { + // If you are not at the end, enable go to next page + m_nextPage->setEnabled(true); + m_endOfDocument->setEnabled(true); + } + + if (m_historyBack) + m_historyBack->setEnabled(!m_document->historyAtBegin()); + if (m_historyNext) + m_historyNext->setEnabled(!m_document->historyAtEnd()); + m_reload->setEnabled(true); + if (m_copy) + m_copy->setEnabled(true); + if (m_selectAll) + m_selectAll->setEnabled(true); + if (m_selectCurrentPage) + m_selectCurrentPage->setEnabled(true); + } else { + m_gotoPage->setEnabled(false); + m_beginningOfDocument->setEnabled(false); + m_endOfDocument->setEnabled(false); + m_prevPage->setEnabled(false); + m_nextPage->setEnabled(false); + if (m_historyBack) + m_historyBack->setEnabled(false); + if (m_historyNext) + m_historyNext->setEnabled(false); + m_reload->setEnabled(false); + if (m_copy) + m_copy->setEnabled(false); + if (m_selectAll) + m_selectAll->setEnabled(false); + if (m_selectCurrentPage) + m_selectCurrentPage->setEnabled(false); + } + + if (factory()) { + QWidget *menu = factory()->container(QStringLiteral("menu_okular_part_viewer"), this); + if (menu) + menu->setEnabled(opened); + + menu = factory()->container(QStringLiteral("view_orientation"), this); + if (menu) + menu->setEnabled(opened); + } + emit viewerMenuStateChange(opened); + + updateBookmarksActions(); +} + +void Part::updateBookmarksActions() +{ + bool opened = m_document->pages() > 0; + if (opened) { + m_addBookmark->setEnabled(true); + if (m_document->bookmarkManager()->isBookmarked(m_document->viewport())) { + m_addBookmark->setText(i18n("Remove Bookmark")); + m_addBookmark->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete-bookmark"))); + m_renameBookmark->setEnabled(true); + } else { + m_addBookmark->setText(m_addBookmarkText); + m_addBookmark->setIcon(m_addBookmarkIcon); + m_renameBookmark->setEnabled(false); + } + } else { + m_addBookmark->setEnabled(false); + m_addBookmark->setText(m_addBookmarkText); + m_addBookmark->setIcon(m_addBookmarkIcon); + m_renameBookmark->setEnabled(false); + } +} + +void Part::enableTOC(bool enable) +{ + if (!enable) { + m_tocEnabled = false; + return; + } + + m_sidebar->addItem(m_toc, QIcon::fromTheme(QApplication::isLeftToRight() ? QStringLiteral("format-justify-left") : QStringLiteral("format-justify-right")), i18n("Contents")); + m_tocEnabled = true; + + // If present, show the TOC when a document is opened + if (m_sidebar->currentItem() != m_toc) { + m_sidebar->setCurrentItem(m_toc); + } +} + +void Part::slotRebuildBookmarkMenu() +{ + rebuildBookmarkMenu(); +} + +void Part::enableLayers(bool enable) +{ + if (!enable) { + return; + } + + m_sidebar->addItem(m_layers, QIcon::fromTheme(QStringLiteral("format-list-unordered")), i18n("Layers")); +} + +void Part::enableSidebarSignaturesItem(bool enable) +{ + if (!enable) { + return; + } + + m_sidebar->addItem(m_signaturePanel, QIcon::fromTheme(QStringLiteral("application-pkcs7-signature")), i18n("Signatures")); +} + +void Part::slotShowFindBar() +{ + m_findBar->show(); + m_findBar->focusAndSetCursor(); + m_closeFindBar->setEnabled(true); +} + +void Part::slotHideFindBar() +{ + if (m_findBar->maybeHide()) { + m_pageView->setFocus(); + m_closeFindBar->setEnabled(false); + } +} + +// BEGIN go to page dialog +class GotoPageDialog : public QDialog +{ + Q_OBJECT + +public: + GotoPageDialog(QWidget *p, int current, int max) + : QDialog(p) + { + setWindowTitle(i18n("Go to Page")); + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + QVBoxLayout *topLayout = new QVBoxLayout(this); + topLayout->setContentsMargins(6, 6, 6, 6); + QHBoxLayout *midLayout = new QHBoxLayout(); + spinbox = new QSpinBox(this); + spinbox->setRange(1, max); + spinbox->setValue(current); + spinbox->setFocus(); + + slider = new QSlider(Qt::Horizontal, this); + slider->setRange(1, max); + slider->setValue(current); + slider->setSingleStep(1); + slider->setTickPosition(QSlider::TicksBelow); + slider->setTickInterval(max / 10); + + connect(slider, &QSlider::valueChanged, spinbox, &QSpinBox::setValue); + connect(spinbox, static_cast(&QSpinBox::valueChanged), slider, &QSlider::setValue); + + QLabel *label = new QLabel(i18n("&Page:"), this); + label->setBuddy(spinbox); + topLayout->addWidget(label); + topLayout->addLayout(midLayout); + midLayout->addWidget(slider); + midLayout->addWidget(spinbox); + + // A little bit extra space + topLayout->addStretch(10); + topLayout->addWidget(buttonBox); + spinbox->setFocus(); + } + + int getPage() const + { + return spinbox->value(); + } + +protected: + QSpinBox *spinbox; + QSlider *slider; + QDialogButtonBox *buttonBox; +}; +// END go to page dialog + +void Part::slotGoToPage() +{ + GotoPageDialog pageDialog(m_pageView, m_document->currentPage() + 1, m_document->pages()); + if (pageDialog.exec() == QDialog::Accepted) + m_document->setViewportPage(pageDialog.getPage() - 1, nullptr, true); +} + +void Part::slotPreviousPage() +{ + if (m_document->isOpened() && !(m_document->currentPage() < 1)) + m_document->setViewportPage(m_document->currentPage() - 1, nullptr, true); +} + +void Part::slotNextPage() +{ + if (m_document->isOpened() && m_document->currentPage() < (m_document->pages() - 1)) + m_document->setViewportPage(m_document->currentPage() + 1, nullptr, true); +} + +void Part::slotGotoFirst() +{ + if (m_document->isOpened()) { + m_document->setViewportPage(0, nullptr, true); + m_beginningOfDocument->setEnabled(false); + } +} + +void Part::slotGotoLast() +{ + if (m_document->isOpened()) { + DocumentViewport endPage(m_document->pages() - 1); + endPage.rePos.enabled = true; + endPage.rePos.normalizedX = 0; + endPage.rePos.normalizedY = 1; + endPage.rePos.pos = Okular::DocumentViewport::TopLeft; + m_document->setViewport(endPage, nullptr, true); + m_endOfDocument->setEnabled(false); + } +} + +void Part::slotHistoryBack() +{ + m_document->setPrevViewport(); +} + +void Part::slotHistoryNext() +{ + m_document->setNextViewport(); +} + +void Part::slotAddBookmark() +{ + DocumentViewport vp = m_document->viewport(); + if (m_document->bookmarkManager()->isBookmarked(vp)) { + m_document->bookmarkManager()->removeBookmark(vp); + } else { + m_document->bookmarkManager()->addBookmark(vp); + } +} + +void Part::slotRenameBookmark(const DocumentViewport &viewport) +{ + Q_ASSERT(m_document->bookmarkManager()->isBookmarked(viewport)); + if (m_document->bookmarkManager()->isBookmarked(viewport)) { + KBookmark bookmark = m_document->bookmarkManager()->bookmark(viewport); + const QString newName = QInputDialog::getText(widget(), i18n("Rename Bookmark"), i18n("Enter the new name of the bookmark:"), QLineEdit::Normal, bookmark.fullText()); + if (!newName.isEmpty()) { + m_document->bookmarkManager()->renameBookmark(&bookmark, newName); + } + } +} + +void Part::slotRenameBookmarkFromMenu() +{ + QAction *action = dynamic_cast(sender()); + Q_ASSERT(action); + if (action) { + DocumentViewport vp(action->data().toString()); + slotRenameBookmark(vp); + } +} + +void Part::slotRemoveBookmarkFromMenu() +{ + QAction *action = dynamic_cast(sender()); + Q_ASSERT(action); + if (action) { + DocumentViewport vp(action->data().toString()); + slotRemoveBookmark(vp); + } +} + +void Part::slotRemoveBookmark(const DocumentViewport &viewport) +{ + Q_ASSERT(m_document->bookmarkManager()->isBookmarked(viewport)); + if (m_document->bookmarkManager()->isBookmarked(viewport)) { + m_document->bookmarkManager()->removeBookmark(viewport); + } +} + +void Part::slotRenameCurrentViewportBookmark() +{ + slotRenameBookmark(m_document->viewport()); +} + +bool Part::aboutToShowContextMenu(QMenu * /*menu*/, QAction *action, QMenu *contextMenu) +{ + KBookmarkAction *ba = dynamic_cast(action); + if (ba != nullptr) { + QAction *separatorAction = contextMenu->addSeparator(); + separatorAction->setObjectName(QStringLiteral("OkularPrivateRenameBookmarkActions")); + QAction *renameAction = contextMenu->addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename this Bookmark"), this, &Part::slotRenameBookmarkFromMenu); + renameAction->setData(ba->property("htmlRef").toString()); + renameAction->setObjectName(QStringLiteral("OkularPrivateRenameBookmarkActions")); + QAction *deleteAction = contextMenu->addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove this Bookmark"), this, &Part::slotRemoveBookmarkFromMenu); + deleteAction->setData(ba->property("htmlRef").toString()); + deleteAction->setObjectName(QStringLiteral("OkularPrivateRenameBookmarkActions")); + } + return ba; +} + +void Part::slotPreviousBookmark() +{ + const KBookmark bookmark = m_document->bookmarkManager()->previousBookmark(m_document->viewport()); + + if (!bookmark.isNull()) { + DocumentViewport vp(bookmark.url().fragment(QUrl::FullyDecoded)); + m_document->setViewport(vp, nullptr, true); + } +} + +void Part::slotNextBookmark() +{ + const KBookmark bookmark = m_document->bookmarkManager()->nextBookmark(m_document->viewport()); + + if (!bookmark.isNull()) { + DocumentViewport vp(bookmark.url().fragment(QUrl::FullyDecoded)); + m_document->setViewport(vp, nullptr, true); + } +} + +void Part::slotFind() +{ + // when in presentation mode, there's already a search bar, taking care of + // the 'find' requests + if ((PresentationWidget *)m_presentationWidget != nullptr) { + m_presentationWidget->slotFind(); + } else { + slotShowFindBar(); + } +} + +void Part::slotFindNext() +{ + if (m_findBar->isHidden()) + slotShowFindBar(); + else + m_findBar->findNext(); +} + +void Part::slotFindPrev() +{ + if (m_findBar->isHidden()) + slotShowFindBar(); + else + m_findBar->findPrev(); +} + +bool Part::saveFile() +{ + if (!isModified()) + return true; + else + return saveAs(url()); +} + +bool Part::slotSaveFileAs(bool showOkularArchiveAsDefaultFormat) +{ + if (m_embedMode == PrintPreviewMode) + return false; + + // Determine the document's mimetype + QMimeDatabase db; + QMimeType originalMimeType; + const QString typeName = m_document->documentInfo().get(DocumentInfo::MimeType); + if (!typeName.isEmpty()) + originalMimeType = db.mimeTypeForName(typeName); + + // What data would we lose if we saved natively? + bool wontSaveForms, wontSaveAnnotations; + checkNativeSaveDataLoss(&wontSaveForms, &wontSaveAnnotations); + + const QMimeType okularArchiveMimeType = db.mimeTypeForName(QStringLiteral("application/vnd.kde.okular-archive")); + + // Prepare "Save As" dialog + const QString originalMimeTypeFilter = i18nc("File type name and pattern", "%1 (%2)", originalMimeType.comment(), originalMimeType.globPatterns().join(QLatin1Char(' '))); + const QString okularArchiveMimeTypeFilter = i18nc("File type name and pattern", "%1 (%2)", okularArchiveMimeType.comment(), okularArchiveMimeType.globPatterns().join(QLatin1Char(' '))); + + // What format choice should we show as default? + QString selectedFilter = (isDocumentArchive || showOkularArchiveAsDefaultFormat || wontSaveForms || wontSaveAnnotations) ? okularArchiveMimeTypeFilter : originalMimeTypeFilter; + + QString filter = originalMimeTypeFilter + QStringLiteral(";;") + okularArchiveMimeTypeFilter; + + const QUrl saveUrl = QFileDialog::getSaveFileUrl(widget(), i18n("Save As"), url(), filter, &selectedFilter); + + if (!saveUrl.isValid() || saveUrl.isEmpty()) + return false; + + // Has the user chosen to save in .okular archive format? + const bool saveAsOkularArchive = (selectedFilter == okularArchiveMimeTypeFilter); + + return saveAs(saveUrl, saveAsOkularArchive ? SaveAsOkularArchive : NoSaveAsFlags); +} + +bool Part::saveAs(const QUrl &saveUrl) +{ + // Save in the same format (.okular vs native) as the current file + return saveAs(saveUrl, isDocumentArchive ? SaveAsOkularArchive : NoSaveAsFlags); +} + +static QUrl resolveSymlinksIfFileExists(const QUrl &saveUrl) +{ + if (saveUrl.isLocalFile()) { + const QFileInfo fi(saveUrl.toLocalFile()); + return fi.exists() ? QUrl::fromLocalFile(fi.canonicalFilePath()) : saveUrl; + } else { + return saveUrl; + } +} + +bool Part::saveAs(const QUrl &saveUrl, SaveAsFlags flags) +{ + // TODO When we get different saving backends we need to query the backend + // as to if it can save changes even if the open file has been modified, + // since we only have poppler as saving backend for now we're skipping that check + if (m_fileLastModified != QFileInfo(localFilePath()).lastModified()) { + KMessageBox::sorry(widget(), i18n("The file '%1' has been modified by another program, which means it can no longer be saved.", url().fileName()), i18n("File Changed")); + return false; + } + + bool hasUserAcceptedReload = false; + if (m_documentOpenWithPassword) { + const int res = KMessageBox::warningYesNo( + widget(), + i18n("The current document is protected with a password.
In order to save, the file needs to be reloaded. You will be asked for the password again and your undo/redo history will be lost.
Do you want to continue?"), + i18n("Save - Warning")); + + switch (res) { + case KMessageBox::Yes: + hasUserAcceptedReload = true; + // do nothing + break; + case KMessageBox::No: // User said no to continue, so return true even if save didn't happen otherwise we will get an error + return true; + } + } + + bool setModifiedAfterSave = false; + + QTemporaryFile tf; + QString fileName; + if (!tf.open()) { + KMessageBox::information(widget(), i18n("Could not open the temporary file for saving.")); + return false; + } + fileName = tf.fileName(); + tf.close(); + + // Figure out the real save url, for symlinks we don't want to copy over the symlink but over the target file + const QUrl realSaveUrl = resolveSymlinksIfFileExists(saveUrl); + + QScopedPointer tempFile; + KIO::Job *copyJob = nullptr; // this will be filled with the job that writes to saveUrl + + // Does the user want a .okular archive? + if (flags & SaveAsOkularArchive) { + if (!hasUserAcceptedReload && !m_document->canSwapBackingFile()) { + const int res = KMessageBox::warningYesNo(widget(), i18n("After saving, the current document format requires the file to be reloaded. Your undo/redo history will be lost.
Do you want to continue?"), i18n("Save - Warning")); + + switch (res) { + case KMessageBox::Yes: + // do nothing + break; + case KMessageBox::No: // User said no to continue, so return true even if save didn't happen otherwise we will get an error + return true; + } + } + + if (!m_document->saveDocumentArchive(fileName)) { + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", fileName)); + return false; + } + + copyJob = KIO::file_copy(QUrl::fromLocalFile(fileName), realSaveUrl, -1, KIO::Overwrite); + } else { + bool wontSaveForms, wontSaveAnnotations; + checkNativeSaveDataLoss(&wontSaveForms, &wontSaveAnnotations); + + // If something can't be saved in this format, ask for confirmation + QStringList listOfwontSaves; + if (wontSaveForms) + listOfwontSaves << i18n("Filled form contents"); + if (wontSaveAnnotations) + listOfwontSaves << i18n("User annotations"); + if (!listOfwontSaves.isEmpty()) { + if (saveUrl == url()) { + // Save + const QString warningMessage = i18n("You are about to save changes, but the current file format does not support saving the following elements. Please use the Okular document archive format to preserve them."); + const int result = KMessageBox::warningYesNoList(widget(), + warningMessage, + listOfwontSaves, + i18n("Warning"), + KGuiItem(i18n("Save as Okular document archive..."), QStringLiteral("document-save-as")), // <- KMessageBox::Yes + KStandardGuiItem::cancel()); + + switch (result) { + case KMessageBox::Yes: // -> Save as Okular document archive + return slotSaveFileAs(true /* showOkularArchiveAsDefaultFormat */); + default: + return false; + } + } else { + // Save as + const QString warningMessage = m_document->canSwapBackingFile() ? i18n( + "You are about to save changes, but the current file format does not support saving the following elements. Please use the Okular document " + "archive format to preserve them. Click Continue to save the document and discard these elements.") + : i18n( + "You are about to save changes, but the current file format does not support saving the following elements. Please use the Okular document " + "archive format to preserve them. Click Continue to save, but you will lose these elements as well as the undo/redo history."); + const QString continueMessage = m_document->canSwapBackingFile() ? i18n("Continue") : i18n("Continue losing changes"); + const int result = KMessageBox::warningYesNoCancelList(widget(), + warningMessage, + listOfwontSaves, + i18n("Warning"), + KGuiItem(i18n("Save as Okular document archive..."), QStringLiteral("document-save-as")), // <- KMessageBox::Yes + KGuiItem(continueMessage, QStringLiteral("arrow-right"))); // <- KMessageBox::NO + + switch (result) { + case KMessageBox::Yes: // -> Save as Okular document archive + return slotSaveFileAs(true /* showOkularArchiveAsDefaultFormat */); + case KMessageBox::No: // -> Continue + setModifiedAfterSave = m_document->canSwapBackingFile(); + break; + case KMessageBox::Cancel: + return false; + } + } + } + + if (m_document->canSaveChanges()) { + // If the generator supports saving changes, save them + + QString errorText; + if (!m_document->saveChanges(fileName, &errorText)) { + if (errorText.isEmpty()) + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", fileName)); + else + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. %2", fileName, errorText)); + + return false; + } + + copyJob = KIO::file_copy(QUrl::fromLocalFile(fileName), realSaveUrl, -1, KIO::Overwrite); + } else { + // If the generators doesn't support saving changes, we will + // just copy the original file. + + if (isDocumentArchive) { + // Special case: if the user is extracting the contents of a + // .okular archive back to the native format, we can't just copy + // the open file (which is a .okular). So let's ask to core to + // extract and give us the real file + + if (!m_document->extractArchivedFile(fileName)) { + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", fileName)); + return false; + } + + copyJob = KIO::file_copy(QUrl::fromLocalFile(fileName), realSaveUrl, -1, KIO::Overwrite); + } else { + // Otherwise just copy the open file. + // make use of the already downloaded (in case of remote URLs) file, + // no point in downloading that again + QUrl srcUrl = QUrl::fromLocalFile(localFilePath()); + // duh, our local file disappeared... + if (!QFile::exists(localFilePath())) { + if (url().isLocalFile()) { +#ifdef OKULAR_KEEP_FILE_OPEN + // local file: try to get it back from the open handle on it + tempFile.reset(m_keeper->copyToTemporary()); + if (tempFile) + srcUrl = KUrl::fromPath(tempFile->fileName()); +#else + const QString msg = i18n("Okular cannot copy %1 to the specified location.\n\nThe document does not exist anymore.", localFilePath()); + KMessageBox::sorry(widget(), msg); + return false; +#endif + } else { + // we still have the original remote URL of the document, + // so copy the document from there + srcUrl = url(); + } + } + + if (srcUrl != saveUrl) { + copyJob = KIO::file_copy(srcUrl, realSaveUrl, -1, KIO::Overwrite); + } else { + // Don't do a real copy in this case, just update the timestamps + copyJob = KIO::setModificationTime(realSaveUrl, QDateTime::currentDateTime()); + } + } + } + } + + // Stop watching for changes while we write the new file (useful when + // overwriting) + if (url().isLocalFile()) + unsetFileToWatch(); + + KJobWidgets::setWindow(copyJob, widget()); + if (!copyJob->exec()) { + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. Error: '%2'. Try to save it to another location.", saveUrl.toDisplayString(), copyJob->errorString())); + + // Restore watcher + if (url().isLocalFile()) + setFileToWatch(localFilePath()); + + return false; + } + + m_document->setHistoryClean(true); + + if (m_document->isDocdataMigrationNeeded()) + m_document->docdataMigrationDone(); + + bool reloadedCorrectly = true; + + // Make the generator use the new file instead of the old one + if (m_document->canSwapBackingFile() && !m_documentOpenWithPassword) { + QWidget *currentSidebarItem = m_sidebar->currentItem(); + // this calls openFile internally, which in turn actually calls + // m_document->swapBackingFile() instead of the regular loadDocument + if (openUrl(saveUrl, true /* swapInsteadOfOpening */)) { + if (setModifiedAfterSave) { + m_document->setHistoryClean(false); + } + } else { + reloadedCorrectly = false; + } + + if (m_sidebar->currentItem() != currentSidebarItem) + m_sidebar->setCurrentItem(currentSidebarItem); + } else { + // If the generator doesn't support swapping file, then just reload + // the document from the new location + if (!slotAttemptReload(true, saveUrl)) + reloadedCorrectly = false; + } + + // In case of file swapping errors, close the document to avoid inconsistencies + if (!reloadedCorrectly) { + qWarning() << "The document hasn't been reloaded/swapped correctly"; + closeUrl(); + } + + // Restore watcher + if (url().isLocalFile()) + setFileToWatch(localFilePath()); + + // Set correct permission taking into account the umask value +#ifndef Q_OS_WIN + const QString saveFilePath = saveUrl.toLocalFile(); + if (QFile::exists(saveFilePath)) { + const mode_t mask = umask(0); + umask(mask); + const mode_t fileMode = 0666 & ~mask; + chmod(QFile::encodeName(saveFilePath).constData(), fileMode); + } +#endif + + return true; +} + +// If the user wants to save in the original file's format, some features might +// not be available. Find out what cannot be saved in this format +void Part::checkNativeSaveDataLoss(bool *out_wontSaveForms, bool *out_wontSaveAnnotations) const +{ + bool wontSaveForms = false; + bool wontSaveAnnotations = false; + + if (!m_document->canSaveChanges(Document::SaveFormsCapability)) { + /* Set wontSaveForms only if there are forms */ + const int pagecount = m_document->pages(); + + for (int pageno = 0; pageno < pagecount; ++pageno) { + const Okular::Page *page = m_document->page(pageno); + if (!page->formFields().empty()) { + wontSaveForms = true; + break; + } + } + } + + if (!m_document->canSaveChanges(Document::SaveAnnotationsCapability)) { + /* Set wontSaveAnnotations only if there are local annotations */ + const int pagecount = m_document->pages(); + + for (int pageno = 0; pageno < pagecount; ++pageno) { + const QLinkedList annotations = m_document->page(pageno)->annotations(); + for (const Okular::Annotation *ann : annotations) { + if (!(ann->flags() & Okular::Annotation::External)) { + wontSaveAnnotations = true; + break; + } + } + if (wontSaveAnnotations) + break; + } + } + + *out_wontSaveForms = wontSaveForms; + *out_wontSaveAnnotations = wontSaveAnnotations; +} + +void Part::slotGetNewStuff() +{ +#if 0 + KNS::Engine engine(widget()); + engine.init( "okular.knsrc" ); + // show the modal dialog over pageview and execute it + KNS::Entry::List entries = engine.downloadDialogModal( m_pageView ); + Q_UNUSED( entries ) +#endif +} + +void Part::slotPreferences() +{ + // Create dialog + PreferencesDialog *dialog = new PreferencesDialog(m_pageView, Okular::Settings::self(), m_embedMode); + dialog->setAttribute(Qt::WA_DeleteOnClose); + + // Show it + dialog->show(); +} + +void Part::slotToggleChangeColors() +{ + m_pageView->slotToggleChangeColors(); +} + +void Part::slotSetChangeColors(bool active) +{ + m_pageView->slotSetChangeColors(active); +} + +void Part::slotAnnotationPreferences() +{ + // Create dialog + PreferencesDialog *dialog = new PreferencesDialog(m_pageView, Okular::Settings::self(), m_embedMode); + dialog->setAttribute(Qt::WA_DeleteOnClose); + + // Show it + dialog->switchToAnnotationsPage(); + dialog->show(); +} + +void Part::slotNewConfig() +{ + // Apply settings here. A good policy is to check whether the setting has + // changed before applying changes. + + // Watch File + setWatchFileModeEnabled(Okular::Settings::watchFile()); + + // Main View (pageView) + m_pageView->reparseConfig(); + + // update document settings + m_document->reparseConfig(); + + // update TOC settings + if (m_tocEnabled) + m_toc->reparseConfig(); + + // update ThumbnailList contents + if (Okular::Settings::showLeftPanel() && !m_thumbnailList->isHidden()) + m_thumbnailList->updateWidgets(); + + // update Reviews settings + m_reviewsWidget->reparseConfig(); + + setWindowTitleFromDocument(); + + if (m_presentationDrawingActions) { + m_presentationDrawingActions->reparseConfig(); + if (factory()) { + factory()->refreshActionProperties(); + } + } +} + +void Part::slotPrintPreview() +{ + if (m_document->pages() == 0) + return; + + QPrinter printer; + QString tempFilePattern; + + if (m_document->printingSupport() == Okular::Document::PostscriptPrinting) { + tempFilePattern = (QDir::tempPath() + QLatin1String("/okular_XXXXXX.ps")); + } else if (m_document->printingSupport() == Okular::Document::NativePrinting) { + tempFilePattern = (QDir::tempPath() + QLatin1String("/okular_XXXXXX.pdf")); + } else { + return; + } + + // Generate a temp filename for Print to File, then release the file so generator can write to it + QTemporaryFile tf(tempFilePattern); + tf.setAutoRemove(true); + tf.open(); + printer.setOutputFileName(tf.fileName()); + tf.close(); + setupPrint(printer); + doPrint(printer); + if (QFile::exists(printer.outputFileName())) { + Okular::FilePrinterPreview previewdlg(printer.outputFileName(), widget()); + previewdlg.exec(); + } +} + +void Part::slotShowTOCMenu(const Okular::DocumentViewport &vp, const QPoint point, const QString &title) +{ + showMenu(m_document->page(vp.pageNumber), point, title, vp, true); +} + +void Part::slotShowMenu(const Okular::Page *page, const QPoint point) +{ + showMenu(page, point); +} + +void Part::showMenu(const Okular::Page *page, const QPoint point, const QString &bookmarkTitle, const Okular::DocumentViewport &vp, bool showTOCActions) +{ + if (m_embedMode == PrintPreviewMode) + return; + + bool reallyShow = false; + const bool currentPage = page && page->number() == m_document->viewport().pageNumber; + + if (!m_actionsSearched) { + // the quest for options_show_menubar + KActionCollection *ac; + QAction *act; + + if (factory()) { + const QList clients(factory()->clients()); + for (int i = 0; (!m_showMenuBarAction || !m_showFullScreenAction) && i < clients.size(); ++i) { + ac = clients.at(i)->actionCollection(); + // show_menubar + act = ac->action(QStringLiteral("options_show_menubar")); + if (act && qobject_cast(act)) + m_showMenuBarAction = qobject_cast(act); + // fullscreen + act = ac->action(QStringLiteral("fullscreen")); + if (act && qobject_cast(act)) + m_showFullScreenAction = qobject_cast(act); + } + } + m_actionsSearched = true; + } + + QMenu *popup = new QMenu(widget()); + if (showTOCActions) { + popup->addAction(i18n("Expand whole section"), m_toc.data(), &TOC::expandRecursively); + popup->addAction(i18n("Collapse whole section"), m_toc.data(), &TOC::collapseRecursively); + popup->addAction(i18n("Expand all"), m_toc.data(), &TOC::expandAll); + popup->addAction(i18n("Collapse all"), m_toc.data(), &TOC::collapseAll); + reallyShow = true; + } + + QAction *addBookmark = nullptr; + QAction *removeBookmark = nullptr; + QAction *fitPageWidth = nullptr; + if (page) { + popup->addAction(new OKMenuTitle(popup, i18n("Page %1", page->number() + 1))); + if ((!currentPage && m_document->bookmarkManager()->isBookmarked(page->number())) || (currentPage && m_document->bookmarkManager()->isBookmarked(m_document->viewport()))) + removeBookmark = popup->addAction(QIcon::fromTheme(QStringLiteral("edit-delete-bookmark")), i18n("Remove Bookmark")); + else + addBookmark = popup->addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), i18n("Add Bookmark")); + if (m_pageView->canFitPageWidth()) + fitPageWidth = popup->addAction(QIcon::fromTheme(QStringLiteral("zoom-fit-best")), i18n("Fit Width")); + popup->addAction(m_prevBookmark); + popup->addAction(m_nextBookmark); + reallyShow = true; + } + + if ((m_showMenuBarAction && !m_showMenuBarAction->isChecked()) || (m_showFullScreenAction && m_showFullScreenAction->isChecked())) { + popup->addAction(new OKMenuTitle(popup, i18n("Tools"))); + if (m_showMenuBarAction && !m_showMenuBarAction->isChecked()) + popup->addAction(m_showMenuBarAction); + if (m_showFullScreenAction && m_showFullScreenAction->isChecked()) + popup->addAction(m_showFullScreenAction); + reallyShow = true; + } + + if (reallyShow) { + QAction *res = popup->exec(point); + if (res) { + if (res == addBookmark) { + if (currentPage && bookmarkTitle.isEmpty()) + m_document->bookmarkManager()->addBookmark(m_document->viewport()); + else if (!bookmarkTitle.isEmpty()) + m_document->bookmarkManager()->addBookmark(m_document->currentDocument(), vp, bookmarkTitle); + else + m_document->bookmarkManager()->addBookmark(page->number()); + } else if (res == removeBookmark) { + if (currentPage) + m_document->bookmarkManager()->removeBookmark(m_document->viewport()); + else + m_document->bookmarkManager()->removeBookmark(page->number()); + } else if (res == fitPageWidth) { + m_pageView->fitPageWidth(page->number()); + } + } + } + delete popup; +} + +void Part::slotShowProperties() +{ + PropertiesDialog *d = new PropertiesDialog(widget(), m_document); + connect(d, &QDialog::finished, d, &QObject::deleteLater); + d->open(); +} + +void Part::slotShowEmbeddedFiles() +{ + EmbeddedFilesDialog *d = new EmbeddedFilesDialog(widget(), m_document); + connect(d, &QDialog::finished, d, &QObject::deleteLater); + d->open(); +} + +void Part::slotShowPresentation() +{ + if (!m_presentationWidget) { + m_presentationWidget = new PresentationWidget(widget(), m_document, m_presentationDrawingActions, actionCollection()); + } +} + +void Part::slotHidePresentation() +{ + if (m_presentationWidget) + delete (PresentationWidget *)m_presentationWidget; +} + +void Part::slotTogglePresentation() +{ + if (m_document->isOpened()) { + if (!m_presentationWidget) + m_presentationWidget = new PresentationWidget(widget(), m_document, m_presentationDrawingActions, actionCollection()); + else + delete (PresentationWidget *)m_presentationWidget; + } +} + +void Part::reload() +{ + if (m_document->isOpened()) { + slotReload(); + } +} + +void Part::enableStartWithPrint() +{ + m_cliPrint = true; +} + +void Part::enableExitAfterPrint() +{ + m_cliPrintAndExit = true; +} + +static const char *kKPlugin = "KPlugin"; + +void Part::slotAboutBackend() +{ + const KPluginMetaData data = m_document->generatorInfo(); + if (!data.isValid()) + return; + + // Here we do a bit of magic because KPluginMetaData doesn't have setters + // so we get the json info from it, modify it and use that for the KAboutPluginDialog + // in case the internals of KPluginMetaData change it won't be too bad, at most we're + // missing the icon or the generator extra description + QJsonObject rawData = data.rawData(); + const QIcon icon = QIcon::fromTheme(data.iconName()); + + // fall back to mime type icon + if (icon.isNull()) { + const Okular::DocumentInfo documentInfo = m_document->documentInfo(QSet() << DocumentInfo::MimeType); + const QString mimeTypeName = documentInfo.get(DocumentInfo::MimeType); + if (!mimeTypeName.isEmpty()) { + QMimeDatabase db; + QMimeType type = db.mimeTypeForName(mimeTypeName); + if (type.isValid()) { + QJsonObject kplugin = rawData[kKPlugin].toObject(); + kplugin[QStringLiteral("Icon")] = type.iconName(); + rawData[kKPlugin] = kplugin; + } + } + } + + const QString extraDescription = m_document->metaData(QStringLiteral("GeneratorExtraDescription")).toString(); + + if (!extraDescription.isEmpty()) { + const QString descriptionAndLang = QStringLiteral("Description[%1]").arg(QLocale().name()); + QJsonObject kplugin = rawData[kKPlugin].toObject(); + kplugin[descriptionAndLang] = QStringLiteral("%1\n\n%2").arg(data.description(), extraDescription); + rawData[kKPlugin] = kplugin; + } + + KAboutPluginDialog dlg(KPluginMetaData(rawData, data.fileName()), widget()); + dlg.exec(); +} + +void Part::slotExportAs(QAction *act) +{ + QList acts = m_exportAs->menu() ? m_exportAs->menu()->actions() : QList(); + int id = acts.indexOf(act); + if ((id < 0) || (id >= acts.count())) + return; + + QMimeDatabase mimeDatabase; + QMimeType mimeType; + switch (id) { + case 0: + mimeType = mimeDatabase.mimeTypeForName(QStringLiteral("text/plain")); + break; + default: + mimeType = m_exportFormats.at(id - 1).mimeType(); + break; + } + QString filter = i18nc("File type name and pattern", "%1 (%2)", mimeType.comment(), mimeType.globPatterns().join(QLatin1Char(' '))); + + QString fileName = QFileDialog::getSaveFileName(widget(), QString(), QString(), filter); + + if (!fileName.isEmpty()) { + bool saved = false; + switch (id) { + case 0: + saved = m_document->exportToText(fileName); + break; + default: + saved = m_document->exportTo(fileName, m_exportFormats.at(id - 1)); + break; + } + if (!saved) + KMessageBox::information(widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", fileName)); + } +} + +void Part::slotReload() +{ + // stop the dirty handler timer, otherwise we may conflict with the + // auto-refresh system + m_dirtyHandler->stop(); + + slotAttemptReload(); +} + +void Part::slotPrint() +{ + if (m_document->pages() == 0) + return; + +#ifdef Q_OS_WIN + QPrinter printer(QPrinter::HighResolution); +#else + QPrinter printer; +#endif + QPrintDialog *printDialog = nullptr; + QWidget *printConfigWidget = nullptr; + + // Must do certain QPrinter setup before creating QPrintDialog + setupPrint(printer); + + // Create the Print Dialog with extra config widgets if required + if (m_document->canConfigurePrinter()) { + printConfigWidget = m_document->printConfigurationWidget(); + } else { + printConfigWidget = new DefaultPrintOptionsWidget(); + } + + printDialog = new QPrintDialog(&printer, widget()); + printDialog->setWindowTitle(i18nc("@title:window", "Print")); + QList options; + if (printConfigWidget) { + options << printConfigWidget; + } + printDialog->setOptionTabs(options); + + if (printDialog) { + // Set the available Print Range + printDialog->setMinMax(1, m_document->pages()); + printDialog->setFromTo(1, m_document->pages()); + + // If the user has bookmarked pages for printing, then enable Selection + if (!m_document->bookmarkedPageRange().isEmpty()) { + printDialog->addEnabledOption(QAbstractPrintDialog::PrintSelection); + } + + // If the Document type doesn't support print to both PS & PDF then disable the Print Dialog option + if (printDialog->isOptionEnabled(QAbstractPrintDialog::PrintToFile) && !m_document->supportsPrintToFile()) { + printDialog->setEnabledOptions(printDialog->enabledOptions() ^ QAbstractPrintDialog::PrintToFile); + } + + // Enable the Current Page option in the dialog. + if (m_document->pages() > 1 && currentPage() > 0) { + printDialog->setOption(QAbstractPrintDialog::PrintCurrentPage); + } + + bool success = true; + if (printDialog->exec()) { + // set option for margins if widget is of corresponding type that holds this information + PrintOptionsWidget *optionWidget = dynamic_cast(printConfigWidget); + if (optionWidget != nullptr) + printer.setFullPage(optionWidget->ignorePrintMargins()); + else { + // printConfigurationWidget() method should always return an object of type Okular::PrintOptionsWidget, + // (signature does not (yet) require it for ABI stability reasons), so emit a warning if the object is of another type + qWarning() << "printConfigurationWidget() method did not return an Okular::PrintOptionsWidget. This is strongly discouraged!"; + } + + success = doPrint(printer); + } + delete printDialog; + if (m_cliPrintAndExit) + exit(success ? EXIT_SUCCESS : EXIT_FAILURE); + } +} + +void Part::setupPrint(QPrinter &printer) +{ + printer.setOrientation(m_document->orientation()); + + // title + QString title = m_document->metaData(QStringLiteral("DocumentTitle")).toString(); + if (title.isEmpty()) { + title = m_document->currentDocument().fileName(); + } + if (!title.isEmpty()) { + printer.setDocName(title); + } +} + +bool Part::doPrint(QPrinter &printer) +{ + if (!m_document->isAllowed(Okular::AllowPrint)) { + KMessageBox::error(widget(), i18n("Printing this document is not allowed.")); + return false; + } + + if (!m_document->print(printer)) { + const QString error = m_document->printError(); + if (error.isEmpty()) { + KMessageBox::error(widget(), i18n("Could not print the document. Unknown error. Please report to bugs.kde.org")); + } else { + KMessageBox::error(widget(), i18n("Could not print the document. Detailed error is \"%1\". Please report to bugs.kde.org", error)); + } + return false; + } + return true; +} + +void Part::psTransformEnded(int exit, QProcess::ExitStatus status) +{ + Q_UNUSED(exit) + if (status != QProcess::NormalExit) + return; + + QProcess *senderobj = sender() ? qobject_cast(sender()) : nullptr; + if (senderobj) { + senderobj->close(); + senderobj->deleteLater(); + } + + setLocalFilePath(m_temporaryLocalFile); + openUrl(QUrl::fromLocalFile(m_temporaryLocalFile)); + m_temporaryLocalFile.clear(); +} + +void Part::displayInfoMessage(const QString &message, KMessageWidget::MessageType messageType, int duration) +{ + if (!Okular::Settings::showOSD()) { + if (messageType == KMessageWidget::Error) { + KMessageBox::error(widget(), message); + } + return; + } + + // hide messageWindow if string is empty + if (message.isEmpty()) + m_infoMessage->animatedHide(); + + // display message (duration is length dependent) + if (duration < 0) { + duration = 500 + 100 * message.length(); + } + m_infoTimer->start(duration); + m_infoMessage->setText(message); + m_infoMessage->setMessageType(messageType); + m_infoMessage->setVisible(true); +} + +void Part::errorMessage(const QString &message, int duration) +{ + displayInfoMessage(message, KMessageWidget::Error, duration); +} + +void Part::warningMessage(const QString &message, int duration) +{ + displayInfoMessage(message, KMessageWidget::Warning, duration); +} + +void Part::noticeMessage(const QString &message, int duration) +{ + // less important message -> simpler display widget in the PageView + m_pageView->displayMessage(message, QString(), PageViewMessage::Info, duration); +} + +void Part::moveSplitter(int sideWidgetSize) +{ + m_sidebar->moveSplitter(sideWidgetSize); +} + +void Part::unsetDummyMode() +{ + if (m_embedMode == PrintPreviewMode) + return; + + m_sidebar->setSidebarVisibility(Okular::Settings::showLeftPanel()); + + // add back and next in history + m_historyBack = KStandardAction::documentBack(this, SLOT(slotHistoryBack()), actionCollection()); + m_historyBack->setWhatsThis(i18n("Go to the place you were before")); + connect(m_pageView.data(), &PageView::mouseBackButtonClick, m_historyBack, &QAction::trigger); + + m_historyNext = KStandardAction::documentForward(this, SLOT(slotHistoryNext()), actionCollection()); + m_historyNext->setWhatsThis(i18n("Go to the place you were after")); + connect(m_pageView.data(), &PageView::mouseForwardButtonClick, m_historyNext, &QAction::trigger); + + m_pageView->setupActions(actionCollection()); + + // attach the actions of the children widgets too + m_formsMessage->addAction(m_pageView->toggleFormsAction()); + + m_signatureMessage->addAction(m_showSignaturePanel); + + // ensure history actions are in the correct state + updateViewActions(); +} + +bool Part::handleCompressed(QString &destpath, const QString &path, KFilterDev::CompressionType compressionType) +{ + m_tempfile = nullptr; + + // we are working with a compressed file, decompressing + // temporary file for decompressing + QTemporaryFile *newtempfile = new QTemporaryFile(); + newtempfile->setAutoRemove(true); + + if (!newtempfile->open()) { + KMessageBox::error(widget(), + i18n("File Error! Could not create temporary file " + "%1.", + newtempfile->errorString())); + delete newtempfile; + return false; + } + + // decompression filer + KCompressionDevice dev(path, compressionType); + + if (!dev.open(QIODevice::ReadOnly)) { + KMessageBox::detailedError(widget(), + i18n("File Error! Could not open the file " + "%1 for uncompression. " + "The file will not be loaded.", + path), + i18n("This error typically occurs if you do " + "not have enough permissions to read the file. " + "You can check ownership and permissions if you " + "right-click on the file in the Dolphin " + "file manager, then choose the 'Properties' option, " + "and select 'Permissions' tab in the opened window.")); + + delete newtempfile; + return false; + } + + char buf[65536]; + int read = 0, wrtn = 0; + + while ((read = dev.read(buf, sizeof(buf))) > 0) { + wrtn = newtempfile->write(buf, read); + if (read != wrtn) + break; + } + if ((read != 0) || (newtempfile->size() == 0)) { + KMessageBox::detailedError(widget(), + i18n("File Error! Could not uncompress " + "the file %1. " + "The file will not be loaded.", + path), + i18n("This error typically occurs if the file is corrupt. " + "If you want to be sure, try to decompress the file manually " + "using command-line tools.")); + delete newtempfile; + return false; + } + m_tempfile = newtempfile; + destpath = m_tempfile->fileName(); + return true; +} + +void Part::rebuildBookmarkMenu(bool unplugActions) +{ + if (unplugActions) { + unplugActionList(QStringLiteral("bookmarks_currentdocument")); + qDeleteAll(m_bookmarkActions); + m_bookmarkActions.clear(); + } + QUrl u = m_document->currentDocument(); + if (u.isValid()) { + m_bookmarkActions = m_document->bookmarkManager()->actionsForUrl(u); + } + bool havebookmarks = true; + if (m_bookmarkActions.isEmpty()) { + havebookmarks = false; + QAction *a = new QAction(nullptr); + a->setText(i18n("No Bookmarks")); + a->setEnabled(false); + m_bookmarkActions.append(a); + } + plugActionList(QStringLiteral("bookmarks_currentdocument"), m_bookmarkActions); + + if (factory()) { + const QList clients(factory()->clients()); + bool containerFound = false; + for (int i = 0; !containerFound && i < clients.size(); ++i) { + QMenu *container = dynamic_cast(factory()->container(QStringLiteral("bookmarks"), clients[i])); + if (container && container->actions().contains(m_bookmarkActions.first())) { + container->installEventFilter(this); + containerFound = true; + } + } + } + + m_prevBookmark->setEnabled(havebookmarks); + m_nextBookmark->setEnabled(havebookmarks); +} + +bool Part::eventFilter(QObject *watched, QEvent *event) +{ + switch (event->type()) { + case QEvent::ContextMenu: { + QContextMenuEvent *e = static_cast(event); + QMenu *menu = static_cast(watched); + + QScopedPointer ctxMenu(new QMenu); + + QPoint pos; + bool ret = false; + if (e->reason() == QContextMenuEvent::Mouse) { + pos = e->pos(); + ret = aboutToShowContextMenu(menu, menu->actionAt(e->pos()), ctxMenu.data()); + } else if (menu->activeAction()) { + pos = menu->actionGeometry(menu->activeAction()).center(); + ret = aboutToShowContextMenu(menu, menu->activeAction(), ctxMenu.data()); + } + ctxMenu->exec(menu->mapToGlobal(pos)); + + if (ret) { + event->accept(); + } + return ret; + } + + default: + break; + } + + return KParts::ReadWritePart::eventFilter(watched, event); +} + +void Part::updateAboutBackendAction() +{ + const KPluginMetaData data = m_document->generatorInfo(); + m_aboutBackend->setEnabled(data.isValid()); +} + +void Part::resetStartArguments() +{ + m_cliPrint = false; + m_cliPrintAndExit = false; +} + +#if PURPOSE_FOUND +void Part::slotShareActionFinished(const QJsonObject &output, int error, const QString &message) +{ + if (error) { + KMessageBox::error(widget(), i18n("There was a problem sharing the document: %1", message), i18n("Share")); + } else { + const QString url = output[QStringLiteral("url")].toString(); + if (url.isEmpty()) { + m_pageView->displayMessage(i18n("Document shared successfully")); + } else { + KMessageBox::information(widget(), i18n("You can find the shared document at: %1", url), i18n("Share"), QString(), KMessageBox::Notify | KMessageBox::AllowLink); + } + } +} +#endif + +void Part::setReadWrite(bool readwrite) +{ + m_document->setAnnotationEditingEnabled(readwrite); + ReadWritePart::setReadWrite(readwrite); +} + +void Part::enableStartWithFind(const QString &text) +{ + m_textToFindOnOpen = QString(text); +} + +void Part::slotOpenContainingFolder() +{ + KIO::highlightInFileManager({QUrl(localFilePath())}); +} + +} // namespace Okular + +#include "part.moc" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/part.h b/part/part.h new file mode 100644 index 0000000..ce9fd00 --- /dev/null +++ b/part/part.h @@ -0,0 +1,439 @@ +/*************************************************************************** + * Copyright (C) 2002 by Wilco Greven * + * Copyright (C) 2003-2004 by Christophe Devriese * + * * + * Copyright (C) 2003 by Andy Goossens * + * Copyright (C) 2003 by Laurent Montel * + * Copyright (C) 2004 by Dominique Devriese * + * Copyright (C) 2004-2007 by Albert Astals Cid * + * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * + * company, info@kdab.com. Work sponsored by the * + * LiMux project of the city of Munich * + * * + * 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 _PART_H_ +#define _PART_H_ + +#include +#include +#include +#include +#include +#include // krazy:exclude=includes + +#include +#include +#include +#include +#include + +#include "../core/document.h" +#include "../core/observer.h" +#include "../interfaces/viewerinterface.h" +#include "../kdocumentviewer.h" + +#include "okularpart_export.h" + +#include + +class QAction; +class QWidget; +class QPrinter; +class QMenu; + +class KConfigDialog; +class KDirWatch; +class KToggleAction; +class KToggleFullScreenAction; +class QTemporaryFile; +class QAction; +class QJsonObject; +namespace KParts +{ +class GUIActivateEvent; +} + +class FindBar; +class ThumbnailList; +class PageSizeLabel; +class PageView; +class PresentationWidget; +class ProgressWidget; +class SearchWidget; +class Sidebar; +class TOC; +class MiniBar; +class MiniBarLogic; +class FileKeeper; +class Reviews; +class BookmarkList; +class DrawingToolActions; +class Layers; +class SignaturePanel; + +#if PURPOSE_FOUND +namespace Purpose +{ +class Menu; +} +#endif + +namespace Okular +{ +class BrowserExtension; +class ExportFormat; + +/** + * Describes the possible embedding modes of the part + * + * @since 0.14 (KDE 4.8) + */ +enum EmbedMode { + UnknownEmbedMode, + NativeShellMode, // embedded in the native Okular' shell + PrintPreviewMode, // embedded to show the print preview of a document + KHTMLPartMode, // embedded in KHTML + ViewerWidgetMode // the part acts as a widget that can display all kinds of documents +}; + +/** + * This is a "Part". It that does all the real work in a KPart + * application. + * + * @short Main Part + * @author Wilco Greven + * @version 0.2 + */ +class OKULARPART_EXPORT Part : public KParts::ReadWritePart, public Okular::DocumentObserver, public KDocumentViewer, public Okular::ViewerInterface +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.okular") + Q_INTERFACES(KDocumentViewer) + Q_INTERFACES(Okular::ViewerInterface) + + friend class PartTest; + +public: + // Default constructor + /** + * If one element of 'args' contains one of the strings "Print/Preview" or "ViewerWidget", + * the part will be set up in the corresponding mode. Additionally, it is possible to specify + * which config file should be used by adding a string containing "ConfigFileName=" + * to 'args'. + **/ + Part(QWidget *parentWidget, QObject *parent, const QVariantList &args); + + // Destructor + ~Part() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyViewportChanged(bool smoothMove) override; + void notifyPageChanged(int page, int flags) override; + + bool openDocument(const QUrl &url, uint page) override; + void startPresentation() override; + QStringList supportedMimeTypes() const override; + + QUrl realUrl() const; + + void showSourceLocation(const QString &fileName, int line, int column, bool showGraphically = true) override; + void clearLastShownSourceLocation() override; + bool isWatchFileModeEnabled() const override; + void setWatchFileModeEnabled(bool enable) override; + bool areSourceLocationsShownGraphically() const override; + void setShowSourceLocationsGraphically(bool show) override; + bool openNewFilesInTabs() const override; + Q_INVOKABLE bool activateTabIfAlreadyOpenFile() const; + +public Q_SLOTS: // dbus + Q_SCRIPTABLE Q_NOREPLY void goToPage(uint page) override; + Q_SCRIPTABLE Q_NOREPLY void openDocument(const QString &doc); + Q_SCRIPTABLE uint pages(); + Q_SCRIPTABLE uint currentPage(); + Q_SCRIPTABLE QString currentDocument(); + Q_SCRIPTABLE QString documentMetaData(const QString &metaData) const; + Q_SCRIPTABLE void slotPreferences(); + Q_SCRIPTABLE void slotFind(); + Q_SCRIPTABLE void slotPrintPreview(); + Q_SCRIPTABLE void slotPreviousPage(); + Q_SCRIPTABLE void slotNextPage(); + Q_SCRIPTABLE void slotGotoFirst(); + Q_SCRIPTABLE void slotGotoLast(); + Q_SCRIPTABLE void slotTogglePresentation(); + Q_SCRIPTABLE void slotToggleChangeColors(); + Q_SCRIPTABLE void slotSetChangeColors(bool active); + 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_SCRIPTABLE void slotOpenContainingFolder(); + +Q_SIGNALS: + void enablePrintAction(bool enable); + void openSourceReference(const QString &absFileName, int line, int column); + void viewerMenuStateChange(bool enabled); + void enableCloseAction(bool enable); + void mimeTypeChanged(const QMimeType &mimeType); + void urlsDropped(const QList &urls); + void fitWindowToPage(const QSize pageViewPortSize, const QSize pageSize); + +protected: + // reimplemented from KParts::ReadWritePart + bool openFile() override; + bool openUrl(const QUrl &url) override; + void guiActivateEvent(KParts::GUIActivateEvent *event) override; + void displayInfoMessage(const QString &message, KMessageWidget::MessageType messageType = KMessageWidget::Information, int duration = -1); + +public: + bool queryClose() override; + bool closeUrl() override; + bool closeUrl(bool promptToSave) override; + void setReadWrite(bool readwrite) override; + bool saveAs(const QUrl &saveUrl) override; + +protected Q_SLOTS: + // connected to actions + void openUrlFromDocument(const QUrl &url); + void openUrlFromBookmarks(const QUrl &url); + void handleDroppedUrls(const QList &urls); + void slotGoToPage(); + void slotHistoryBack(); + void slotHistoryNext(); + void slotAddBookmark(); + void slotRenameBookmarkFromMenu(); + void slotRemoveBookmarkFromMenu(); + void slotRenameCurrentViewportBookmark(); + void slotPreviousBookmark(); + void slotNextBookmark(); + void slotFindNext(); + void slotFindPrev(); + bool slotSaveFileAs(bool showOkularArchiveAsDefaultFormat = false); + void slotGetNewStuff(); + void slotNewConfig(); + void slotShowMenu(const Okular::Page *page, const QPoint point); + void slotShowTOCMenu(const Okular::DocumentViewport &vp, const QPoint point, const QString &title); + void slotShowProperties(); + void slotShowEmbeddedFiles(); + void slotShowLeftPanel(); + void slotShowBottomBar(); + void slotShowPresentation(); + void slotHidePresentation(); + void slotExportAs(QAction *); + bool slotImportPSFile(); + void slotAboutBackend(); + void slotReload(); + void close(); + void cannotQuit(); + void slotShowFindBar(); + void slotHideFindBar(); + void slotJobStarted(KIO::Job *job); + void slotJobFinished(KJob *job); + void loadCancelled(const QString &reason); + void setWindowTitleFromDocument(); + // can be connected to widget elements + void updateViewActions(); + void updateBookmarksActions(); + void enableTOC(bool enable); + void slotRebuildBookmarkMenu(); + void enableLayers(bool enable); + void enableSidebarSignaturesItem(bool enable); + +public Q_SLOTS: + bool saveFile() override; + // connected to Shell action (and browserExtension), not local one + void slotPrint(); + void slotFileDirty(const QString &); + bool slotAttemptReload(bool oneShot = false, const QUrl &newUrl = QUrl()); + void psTransformEnded(int, QProcess::ExitStatus); + KConfigDialog *slotGeneratorPreferences(); + + void errorMessage(const QString &message, int duration = 0); + void warningMessage(const QString &message, int duration = -1); + void noticeMessage(const QString &message, int duration = -1); + + void moveSplitter(const int sideWidgetSize); + +private: + bool aboutToShowContextMenu(QMenu *menu, QAction *action, QMenu *contextMenu); + void showMenu(const Okular::Page *page, const QPoint point, const QString &bookmarkTitle = QString(), const Okular::DocumentViewport &vp = DocumentViewport(), bool showTOCActions = false); + bool eventFilter(QObject *watched, QEvent *event) override; + Document::OpenResult doOpenFile(const QMimeType &mime, const QString &fileNameToOpen, bool *isCompressedFile); + bool openUrl(const QUrl &url, bool swapInsteadOfOpening); + + void setupViewerActions(); + void setViewerShortcuts(); + void setupActions(); + + void setupPrint(QPrinter &printer); + bool doPrint(QPrinter &printer); + bool handleCompressed(QString &destpath, const QString &path, KCompressionDevice::CompressionType compressionType); + void rebuildBookmarkMenu(bool unplugActions = true); + void updateAboutBackendAction(); + void unsetDummyMode(); + void slotRenameBookmark(const DocumentViewport &viewport); + void slotRemoveBookmark(const DocumentViewport &viewport); + void resetStartArguments(); + void checkNativeSaveDataLoss(bool *out_wontSaveForms, bool *out_wontSaveAnnotations) const; + + enum SaveAsFlag { + NoSaveAsFlags = 0, ///< No options + SaveAsOkularArchive = 1 ///< Save as Okular Archive (.okular) instead of document's native format + }; + Q_DECLARE_FLAGS(SaveAsFlags, SaveAsFlag) + + bool saveAs(const QUrl &saveUrl, SaveAsFlags flags); + + void setFileToWatch(const QString &filePath); + void unsetFileToWatch(); + +#if PURPOSE_FOUND + void slotShareActionFinished(const QJsonObject &output, int error, const QString &message); +#endif + + bool tryOpeningUrlWithFragmentAsName(); + + static int numberOfParts; + + QTemporaryFile *m_tempfile; + + // the document + Okular::Document *m_document; + QDateTime m_fileLastModified; + QString m_temporaryLocalFile; + bool isDocumentArchive; + bool m_documentOpenWithPassword; + bool m_swapInsteadOfOpening; // if set, the next open operation will replace the backing file (used when reloading just saved files) + + // main widgets + Sidebar *m_sidebar; + SearchWidget *m_searchWidget; + FindBar *m_findBar; + KMessageWidget *m_migrationMessage; + KMessageWidget *m_topMessage; + KMessageWidget *m_formsMessage; + KMessageWidget *m_infoMessage; + KMessageWidget *m_signatureMessage; + QPointer m_thumbnailList; + QPointer m_pageView; + QPointer m_toc; + bool m_tocEnabled; + QPointer m_miniBarLogic; + QPointer m_miniBar; + QPointer m_pageNumberTool; + QPointer m_bottomBar; + QPointer m_presentationWidget; + QPointer m_progressWidget; + QPointer m_pageSizeLabel; + QPointer m_reviewsWidget; + QPointer m_bookmarkList; + QPointer m_layers; + QPointer m_signaturePanel; + + // document watcher (and reloader) variables + KDirWatch *m_watcher; + QString m_watchedFilePath, m_watchedFileSymlinkTarget; + QTimer *m_dirtyHandler; + QUrl m_oldUrl; + Okular::DocumentViewport m_viewportDirty; + bool m_isReloading; + bool m_wasPresentationOpen; + QWidget *m_dirtyToolboxItem; + bool m_wasSidebarVisible; + bool m_fileWasRemoved; + Rotation m_dirtyPageRotation; + + // Remember the search history + QStringList m_searchHistory; + + // actions + QAction *m_gotoPage; + QAction *m_prevPage; + QAction *m_nextPage; + QAction *m_beginningOfDocument; + QAction *m_endOfDocument; + QAction *m_historyBack; + QAction *m_historyNext; + QAction *m_addBookmark; + QAction *m_renameBookmark; + QAction *m_prevBookmark; + QAction *m_nextBookmark; + QAction *m_copy; + QAction *m_selectAll; + QAction *m_selectCurrentPage; + QAction *m_find; + QAction *m_findNext; + QAction *m_findPrev; + QAction *m_save; + QAction *m_saveAs; + QAction *m_saveCopyAs; + QAction *m_printPreview; + QAction *m_showProperties; + QAction *m_showEmbeddedFiles; + QAction *m_exportAs; + QAction *m_exportAsText; + QAction *m_exportAsDocArchive; +#if PURPOSE_FOUND + QAction *m_share; +#endif + QAction *m_showPresentation; + QAction *m_openContainingFolder; + KToggleAction *m_showMenuBarAction; + KToggleAction *m_showLeftPanel; + KToggleAction *m_showBottomBar; + QAction *m_showSignaturePanel; + KToggleFullScreenAction *m_showFullScreenAction; + QAction *m_aboutBackend; + QAction *m_reload; + QMenu *m_exportAsMenu; +#if PURPOSE_FOUND + Purpose::Menu *m_shareMenu; +#endif + QAction *m_closeFindBar; + DrawingToolActions *m_presentationDrawingActions; + + bool m_actionsSearched; + BrowserExtension *m_bExtension; + + QList m_exportFormats; + QList m_bookmarkActions; + bool m_cliPresentation; + bool m_cliPrint; + bool m_cliPrintAndExit; + QString m_addBookmarkText; + QIcon m_addBookmarkIcon; + + EmbedMode m_embedMode; + + QUrl m_realUrl; + + KXMLGUIClient *m_generatorGuiClient; + FileKeeper *m_keeper; + + // Timer for m_infoMessage + QTimer *m_infoTimer; + + QString m_registerDbusName; + + // String to search in document startup + QString m_textToFindOnOpen; + + // Set when opening an url that had fragment so that if it fails opening we try adding the fragment to the filename + // if we're opening http://localhost/foo#bar.pdf and the filename contains an # we can open it after trying to open foo fails + QUrl m_urlWithFragment; + +private Q_SLOTS: + void slotAnnotationPreferences(); + void slotHandleActivatedSourceReference(const QString &absFileName, int line, int col, bool *handled); +}; + +} + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/part.rc b/part/part.rc new file mode 100644 index 0000000..59e2d61 --- /dev/null +++ b/part/part.rc @@ -0,0 +1,134 @@ + + + + &File + + + + + + + + + + + + + + &Edit + + + + + + + + + + + + + &View + + + + + + + + + + + + &Orientation + + + + + + + + + &Go + + + + + + + + + + + + &Bookmarks + + + + + + + + &Tools + + + + + + + + + + + + + + + &Settings + + + + + + &Help + + + +Main Toolbar + + + + + + + + + + + + + + diff --git a/part/preferencesdialog.cpp b/part/preferencesdialog.cpp new file mode 100644 index 0000000..d03a678 --- /dev/null +++ b/part/preferencesdialog.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +// reimplementing this +#include "preferencesdialog.h" + +#include + +// single config pages +#include "dlgaccessibility.h" +#include "dlgannotations.h" +#include "dlgdebug.h" +#include "dlgeditor.h" +#include "dlggeneral.h" +#include "dlgperformance.h" +#include "dlgpresentation.h" + +PreferencesDialog::PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton, Okular::EmbedMode embedMode) + : KConfigDialog(parent, QStringLiteral("preferences"), skeleton) +{ + setWindowModality(Qt::ApplicationModal); + + m_general = new DlgGeneral(this, embedMode); + m_performance = new DlgPerformance(this); + m_accessibility = new DlgAccessibility(this); + m_presentation = nullptr; + m_annotations = nullptr; + m_annotationsPage = nullptr; + m_editor = nullptr; +#ifdef OKULAR_DEBUG_CONFIGPAGE + m_debug = new DlgDebug(this); +#endif + + addPage(m_general, i18n("General"), QStringLiteral("okular"), i18n("General Options")); + addPage(m_accessibility, i18n("Accessibility"), QStringLiteral("preferences-desktop-accessibility"), i18n("Accessibility Reading Aids")); + addPage(m_performance, i18n("Performance"), QStringLiteral("preferences-system-performance"), i18n("Performance Tuning")); + if (embedMode == Okular::ViewerWidgetMode) { + setWindowTitle(i18n("Configure Viewer")); + } else { + m_presentation = new DlgPresentation(this); + m_annotations = new DlgAnnotations(this); + m_editor = new DlgEditor(this); + addPage(m_presentation, i18n("Presentation"), QStringLiteral("view-presentation"), i18n("Options for Presentation Mode")); + m_annotationsPage = addPage(m_annotations, i18n("Annotations"), QStringLiteral("draw-freehand"), i18n("Annotation Options")); + addPage(m_editor, i18n("Editor"), QStringLiteral("accessories-text-editor"), i18n("Editor Options")); + } +#ifdef OKULAR_DEBUG_CONFIGPAGE + addPage(m_debug, "Debug", "system-run", "Debug options"); +#endif + setHelp(QStringLiteral("configure"), QStringLiteral("okular")); +} + +void PreferencesDialog::switchToAnnotationsPage() +{ + if (m_annotationsPage) + setCurrentPage(m_annotationsPage); +} diff --git a/part/preferencesdialog.h b/part/preferencesdialog.h new file mode 100644 index 0000000..d2f761f --- /dev/null +++ b/part/preferencesdialog.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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 _PREFERENCESDIALOG_H +#define _PREFERENCESDIALOG_H + +#include "part.h" +#include "settings.h" +#include + +class QWidget; +class KConfigSkeleton; + +class DlgGeneral; +class DlgPerformance; +class DlgAccessibility; +class DlgPresentation; +class DlgAnnotations; +class DlgEditor; +class DlgDebug; + +class PreferencesDialog : public KConfigDialog +{ + Q_OBJECT + +public: + PreferencesDialog(QWidget *parent, KConfigSkeleton *skeleton, Okular::EmbedMode embedMode); + + void switchToAnnotationsPage(); + +protected: + // void updateSettings(); // Called when OK/Apply is pressed. + // void updateWidgets(); // Called upon construction or when Reset is pressed + // void updateWidgetsDefault(); // Called when Defaults button is pressed + // bool hasChanged(); // In order to correctly disable/enable Apply button + // bool isDefault(); // In order to correctly disable/enable Defaults button + +private: + DlgGeneral *m_general; + DlgPerformance *m_performance; + DlgAccessibility *m_accessibility; + DlgPresentation *m_presentation; + DlgAnnotations *m_annotations; + DlgEditor *m_editor; +#ifdef OKULAR_DEBUG_CONFIGPAGE + DlgDebug *m_debug; +#endif + + KPageWidgetItem *m_annotationsPage; +}; + +#endif diff --git a/part/presentationsearchbar.cpp b/part/presentationsearchbar.cpp new file mode 100644 index 0000000..91d17ea --- /dev/null +++ b/part/presentationsearchbar.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "presentationsearchbar.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "searchlineedit.h" + +#define SNAP_DELTA 15 + +class HandleDrag : public QWidget +{ + Q_OBJECT + +public: + HandleDrag(QWidget *parent = Q_NULLPTR) + : QWidget(parent) + { + setCursor(Qt::SizeAllCursor); + setFixedWidth(style()->pixelMetric(QStyle::PM_ToolBarHandleExtent)); + } + + void paintEvent(QPaintEvent *) override + { + QStyleOption opt; + opt.initFrom(this); + opt.state |= QStyle::State_Horizontal; + QStylePainter p(this); + p.drawPrimitive(QStyle::PE_IndicatorToolBarHandle, opt); + } +}; + +PresentationSearchBar::PresentationSearchBar(Okular::Document *document, QWidget *anchor, QWidget *parent) + : QWidget(parent) + , m_anchor(anchor) + , m_snapped(true) +{ + setAutoFillBackground(true); + + QHBoxLayout *lay = new QHBoxLayout(this); + lay->setContentsMargins(0, 0, 0, 0); + + m_handle = new HandleDrag(this); + m_handle->installEventFilter(this); + lay->addWidget(m_handle); + + QToolButton *closeBtn = new QToolButton(this); + closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); + closeBtn->setIconSize(QSize(24, 24)); + closeBtn->setToolTip(i18n("Close")); + closeBtn->setAutoRaise(true); + lay->addWidget(closeBtn); + + m_search = new SearchLineEdit(this, document); + m_search->setClearButtonEnabled(true); + m_search->setSearchCaseSensitivity(Qt::CaseInsensitive); + m_search->setSearchMinimumLength(0); + m_search->setSearchType(Okular::Document::NextMatch); + m_search->setSearchId(PRESENTATION_SEARCH_ID); + m_search->setSearchColor(qRgb(255, 255, 64)); + m_search->setSearchMoveViewport(true); + lay->addWidget(m_search); + + QPushButton *findNextBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("go-down-search")), i18n("Find Next"), this); + lay->addWidget(findNextBtn); + + m_anchor->installEventFilter(this); + + connect(closeBtn, &QAbstractButton::clicked, this, &QWidget::close); + connect(findNextBtn, &QPushButton::clicked, m_search, &SearchLineEdit::findNext); +} + +PresentationSearchBar::~PresentationSearchBar() +{ +} + +void PresentationSearchBar::forceSnap() +{ + m_point = QPoint(m_anchor->width() / 2, m_anchor->height()); + m_snapped = true; + move(m_point.x() - width() / 2, m_point.y() - height()); +} + +void PresentationSearchBar::focusOnSearchEdit() +{ + m_search->setFocus(); +} + +void PresentationSearchBar::resizeEvent(QResizeEvent *) +{ + // if in snap mode, then force the snap and place ourselves correctly again + if (m_snapped) + forceSnap(); +} + +bool PresentationSearchBar::eventFilter(QObject *obj, QEvent *e) +{ + if (obj == m_handle && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove)) { + QMouseEvent *me = (QMouseEvent *)e; + if (e->type() == QEvent::MouseButtonPress) { + m_drag = m_handle->mapTo(this, me->pos()); + } else if (e->type() == QEvent::MouseButtonRelease) { + m_drag = QPoint(); + } else if (e->type() == QEvent::MouseMove) { + QPoint snapdelta(width() / 2, height()); + QPoint delta = m_handle->mapTo(this, me->pos()) - m_drag; + QPoint newpostemp = pos() + delta; + QPoint tmp = newpostemp + snapdelta - m_point; + QPoint newpos = abs(tmp.x()) < SNAP_DELTA && abs(tmp.y()) < SNAP_DELTA ? m_point - snapdelta : newpostemp; + m_snapped = newpos == (m_point - snapdelta); + move(newpos); + } + return true; + } + if (obj == m_anchor && e->type() == QEvent::Resize) { + m_point = QPoint(m_anchor->width() / 2, m_anchor->height()); + + if (m_snapped) + move(m_point.x() - width() / 2, m_point.y() - height()); + } + + return false; +} + +#include "presentationsearchbar.moc" diff --git a/part/presentationsearchbar.h b/part/presentationsearchbar.h new file mode 100644 index 0000000..c1d3163 --- /dev/null +++ b/part/presentationsearchbar.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2007 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_PRESENTATIONSEARCHBAR_H_ +#define _OKULAR_PRESENTATIONSEARCHBAR_H_ + +#include + +class SearchLineEdit; + +namespace Okular +{ +class Document; +} + +class PresentationSearchBar : public QWidget +{ + Q_OBJECT + +public: + PresentationSearchBar(Okular::Document *document, QWidget *anchor, QWidget *parent = nullptr); + ~PresentationSearchBar() override; + + void forceSnap(); + void focusOnSearchEdit(); + +protected: + void resizeEvent(QResizeEvent *) override; + bool eventFilter(QObject *, QEvent *) override; + +private: + QWidget *m_handle; + QWidget *m_anchor; + QPoint m_point; + bool m_snapped; + QPoint m_drag; + + SearchLineEdit *m_search; +}; + +#endif diff --git a/part/presentationwidget.cpp b/part/presentationwidget.cpp new file mode 100644 index 0000000..e225e47 --- /dev/null +++ b/part/presentationwidget.cpp @@ -0,0 +1,2243 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "presentationwidget.h" + +// qt/kde includes +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_LINUX +#include +#include // For ::close() for sleep inhibition +#endif + +// system includes +#include +#include + +// local includes +#include "annotationtools.h" +#include "core/action.h" +#include "core/annotations.h" +#include "core/audioplayer.h" +#include "core/document.h" +#include "core/generator.h" +#include "core/movie.h" +#include "core/page.h" +#include "debug_ui.h" +#include "drawingtoolactions.h" +#include "guiutils.h" +#include "pagepainter.h" +#include "presentationsearchbar.h" +#include "priorities.h" +#include "settings.h" +#include "settings_core.h" +#include "videowidget.h" + +// comment this to disable the top-right progress indicator +#define ENABLE_PROGRESS_OVERLAY + +// a frame contains a pointer to the page object, its geometry and the +// transition effect to the next frame +struct PresentationFrame { + PresentationFrame() = default; + + ~PresentationFrame() + { + qDeleteAll(videoWidgets); + } + + PresentationFrame(const PresentationFrame &) = delete; + PresentationFrame &operator=(const PresentationFrame &) = delete; + + void recalcGeometry(int width, int height, float screenRatio) + { + // calculate frame geometry keeping constant aspect ratio + float pageRatio = page->ratio(); + int pageWidth = width, pageHeight = height; + if (pageRatio > screenRatio) + pageWidth = (int)((float)pageHeight / pageRatio); + else + pageHeight = (int)((float)pageWidth * pageRatio); + geometry.setRect((width - pageWidth) / 2, (height - pageHeight) / 2, pageWidth, pageHeight); + + for (VideoWidget *vw : qAsConst(videoWidgets)) { + const Okular::NormalizedRect r = vw->normGeometry(); + QRect vwgeom = r.geometry(geometry.width(), geometry.height()); + vw->resize(vwgeom.size()); + vw->move(geometry.topLeft() + vwgeom.topLeft()); + } + } + + const Okular::Page *page; + QRect geometry; + QHash videoWidgets; + QLinkedList drawings; +}; + +// a custom QToolBar that basically does not propagate the event if the widget +// background is not automatically filled +class PresentationToolBar : public QToolBar +{ + Q_OBJECT + +public: + PresentationToolBar(QWidget *parent = Q_NULLPTR) + : QToolBar(parent) + { + } + +protected: + void mousePressEvent(QMouseEvent *e) override + { + QToolBar::mousePressEvent(e); + e->accept(); + } + + void mouseReleaseEvent(QMouseEvent *e) override + { + QToolBar::mouseReleaseEvent(e); + e->accept(); + } +}; + +PresentationWidget::PresentationWidget(QWidget *parent, Okular::Document *doc, DrawingToolActions *drawingToolActions, KActionCollection *collection) + : QWidget(nullptr /* must be null, to have an independent widget */, Qt::FramelessWindowHint) + , m_pressedLink(nullptr) + , m_handCursor(false) + , m_drawingEngine(nullptr) + , m_screenInhibitCookie(0) + , m_sleepInhibitFd(-1) + , m_parentWidget(parent) + , m_document(doc) + , m_frameIndex(-1) + , m_topBar(nullptr) + , m_pagesEdit(nullptr) + , m_searchBar(nullptr) + , m_ac(collection) + , m_screenSelect(nullptr) + , m_isSetup(false) + , m_blockNotifications(false) + , m_inBlackScreenMode(false) + , m_showSummaryView(Okular::Settings::slidesShowSummary()) + , m_advanceSlides(Okular::SettingsCore::slidesAdvance()) + , m_goToPreviousPageOnRelease(false) + , m_goToNextPageOnRelease(false) +{ + Q_UNUSED(parent) + setAttribute(Qt::WA_DeleteOnClose); + setAttribute(Qt::WA_OpaquePaintEvent); + setObjectName(QStringLiteral("presentationWidget")); + QString caption = doc->metaData(QStringLiteral("DocumentTitle")).toString(); + if (caption.trimmed().isEmpty()) + caption = doc->currentDocument().fileName(); + caption = i18nc("[document title/filename] – Presentation", "%1 – Presentation", caption); + setWindowTitle(caption); + + m_width = -1; + + // create top toolbar + m_topBar = new PresentationToolBar(this); + m_topBar->setObjectName(QStringLiteral("presentationBar")); + m_topBar->setMovable(false); + m_topBar->layout()->setContentsMargins(0, 0, 0, 0); + m_topBar->addAction(QIcon::fromTheme(layoutDirection() == Qt::RightToLeft ? QStringLiteral("go-next") : QStringLiteral("go-previous")), i18n("Previous Page"), this, SLOT(slotPrevPage())); + m_pagesEdit = new KLineEdit(m_topBar); + QSizePolicy sp = m_pagesEdit->sizePolicy(); + sp.setHorizontalPolicy(QSizePolicy::Minimum); + m_pagesEdit->setSizePolicy(sp); + QFontMetrics fm(m_pagesEdit->font()); + QStyleOptionFrame option; + option.initFrom(m_pagesEdit); + m_pagesEdit->setMaximumWidth(fm.horizontalAdvance(QString::number(m_document->pages())) + 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, m_pagesEdit) + + 4); // the 4 comes from 2*horizontalMargin, horizontalMargin being a define in qlineedit.cpp + QIntValidator *validator = new QIntValidator(1, m_document->pages(), m_pagesEdit); + m_pagesEdit->setValidator(validator); + m_topBar->addWidget(m_pagesEdit); + QLabel *pagesLabel = new QLabel(m_topBar); + pagesLabel->setText(QLatin1String(" / ") + QString::number(m_document->pages()) + QLatin1String(" ")); + m_topBar->addWidget(pagesLabel); + connect(m_pagesEdit, &QLineEdit::returnPressed, this, &PresentationWidget::slotPageChanged); + m_topBar->addAction(QIcon::fromTheme(layoutDirection() == Qt::RightToLeft ? QStringLiteral("go-previous") : QStringLiteral("go-next")), i18n("Next Page"), this, SLOT(slotNextPage())); + m_topBar->addSeparator(); + QAction *playPauseAct = collection->action(QStringLiteral("presentation_play_pause")); + playPauseAct->setEnabled(true); + connect(playPauseAct, &QAction::triggered, this, &PresentationWidget::slotTogglePlayPause); + m_topBar->addAction(playPauseAct); + addAction(playPauseAct); + m_topBar->addSeparator(); + + const QList actionsList = drawingToolActions->actions(); + for (QAction *action : actionsList) { + action->setEnabled(true); + m_topBar->addAction(action); + addAction(action); + } + connect(drawingToolActions, &DrawingToolActions::changeEngine, this, &PresentationWidget::slotChangeDrawingToolEngine); + connect(drawingToolActions, &DrawingToolActions::actionsRecreated, this, &PresentationWidget::slotAddDrawingToolActions); + + QAction *eraseDrawingAct = collection->action(QStringLiteral("presentation_erase_drawings")); + eraseDrawingAct->setEnabled(true); + connect(eraseDrawingAct, &QAction::triggered, this, &PresentationWidget::clearDrawings); + m_topBar->addAction(eraseDrawingAct); + addAction(eraseDrawingAct); + + const int screenCount = QApplication::screens().count(); + if (screenCount > 1) { + m_topBar->addSeparator(); + m_screenSelect = new KSelectAction(QIcon::fromTheme(QStringLiteral("video-display")), i18n("Switch Screen"), m_topBar); + m_screenSelect->setToolBarMode(KSelectAction::MenuMode); + m_screenSelect->setToolButtonPopupMode(QToolButton::InstantPopup); + m_topBar->addAction(m_screenSelect); + for (int i = 0; i < screenCount; ++i) { + QAction *act = m_screenSelect->addAction(i18nc("%1 is the screen number (0, 1, ...)", "Screen %1", i)); + act->setData(QVariant::fromValue(i)); + } + } + QWidget *spacer = new QWidget(m_topBar); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); + m_topBar->addWidget(spacer); + m_topBar->addAction(QIcon::fromTheme(QStringLiteral("application-exit")), i18n("Exit Presentation Mode"), this, SLOT(close())); + m_topBar->setAutoFillBackground(true); + showTopBar(false); + // change topbar background color + QPalette p = m_topBar->palette(); + p.setColor(QPalette::Active, QPalette::Button, Qt::gray); + p.setColor(QPalette::Active, QPalette::Window, Qt::darkGray); + m_topBar->setPalette(p); + + // Grab swipe gestures to change pages + grabGesture(Qt::SwipeGesture); + + // misc stuff + setMouseTracking(true); + setContextMenuPolicy(Qt::PreventContextMenu); + m_transitionTimer = new QTimer(this); + m_transitionTimer->setSingleShot(true); + connect(m_transitionTimer, &QTimer::timeout, this, &PresentationWidget::slotTransitionStep); + m_overlayHideTimer = new QTimer(this); + m_overlayHideTimer->setSingleShot(true); + connect(m_overlayHideTimer, &QTimer::timeout, this, &PresentationWidget::slotHideOverlay); + m_nextPageTimer = new QTimer(this); + m_nextPageTimer->setSingleShot(true); + connect(m_nextPageTimer, &QTimer::timeout, this, &PresentationWidget::slotNextPage); + setPlayPauseIcon(); + + connect(m_document, &Okular::Document::processMovieAction, this, &PresentationWidget::slotProcessMovieAction); + connect(m_document, &Okular::Document::processRenditionAction, this, &PresentationWidget::slotProcessRenditionAction); + + // handle cursor appearance as specified in configuration + if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::HiddenDelay) { + KCursor::setAutoHideCursor(this, true); + KCursor::setHideCursorDelay(3000); + } else if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::Hidden) { + setCursor(QCursor(Qt::BlankCursor)); + } + + setupActions(); + + // inhibit power management + inhibitPowerManagement(); + + QTimer::singleShot(0, this, &PresentationWidget::slotDelayedEvents); + + // setFocus() so KCursor::setAutoHideCursor() goes into effect if it's enabled + setFocus(Qt::OtherFocusReason); + + // Catch TabletEnterProximity and TabletLeaveProximity events from the QApplication + qApp->installEventFilter(this); +} + +PresentationWidget::~PresentationWidget() +{ + // allow power management saver again + allowPowerManagement(); + + // stop the audio playbacks + Okular::AudioPlayer::instance()->stopPlaybacks(); + + // remove our highlights + if (m_searchBar) { + m_document->resetSearch(PRESENTATION_SEARCH_ID); + } + + // remove this widget from document observer + m_document->removeObserver(this); + + const QList actionsList = actions(); + for (QAction *action : actionsList) { + action->setChecked(false); + action->setEnabled(false); + } + + delete m_drawingEngine; + + // delete frames + qDeleteAll(m_frames); + + qApp->removeEventFilter(this); +} + +void PresentationWidget::notifySetup(const QVector &pageSet, int setupFlags) +{ + // same document, nothing to change - here we assume the document sets up + // us with the whole document set as first notifySetup() + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) + return; + + // delete previous frames (if any (shouldn't be)) + qDeleteAll(m_frames); + if (!m_frames.isEmpty()) + qCWarning(OkularUiDebug) << "Frames setup changed while a Presentation is in progress."; + m_frames.clear(); + + // create the new frames + float screenRatio = (float)m_height / (float)m_width; + for (const Okular::Page *page : pageSet) { + PresentationFrame *frame = new PresentationFrame(); + frame->page = page; + const QLinkedList annotations = page->annotations(); + for (Okular::Annotation *a : annotations) { + if (a->subType() == Okular::Annotation::AMovie) { + Okular::MovieAnnotation *movieAnn = static_cast(a); + VideoWidget *vw = new VideoWidget(movieAnn, movieAnn->movie(), m_document, this); + frame->videoWidgets.insert(movieAnn->movie(), vw); + vw->pageInitialized(); + } else if (a->subType() == Okular::Annotation::ARichMedia) { + Okular::RichMediaAnnotation *richMediaAnn = static_cast(a); + if (richMediaAnn->movie()) { + VideoWidget *vw = new VideoWidget(richMediaAnn, richMediaAnn->movie(), m_document, this); + frame->videoWidgets.insert(richMediaAnn->movie(), vw); + vw->pageInitialized(); + } + } else if (a->subType() == Okular::Annotation::AScreen) { + const Okular::ScreenAnnotation *screenAnn = static_cast(a); + Okular::Movie *movie = GuiUtils::renditionMovieFromScreenAnnotation(screenAnn); + if (movie) { + VideoWidget *vw = new VideoWidget(screenAnn, movie, m_document, this); + frame->videoWidgets.insert(movie, vw); + vw->pageInitialized(); + } + } + } + frame->recalcGeometry(m_width, m_height, screenRatio); + // add the frame to the vector + m_frames.push_back(frame); + } + + // get metadata from the document + m_metaStrings.clear(); + const Okular::DocumentInfo info = m_document->documentInfo(QSet() << Okular::DocumentInfo::Title << Okular::DocumentInfo::Author); + if (!info.get(Okular::DocumentInfo::Title).isNull()) + m_metaStrings += i18n("Title: %1", info.get(Okular::DocumentInfo::Title)); + if (!info.get(Okular::DocumentInfo::Author).isNull()) + m_metaStrings += i18n("Author: %1", info.get(Okular::DocumentInfo::Author)); + m_metaStrings += i18n("Pages: %1", m_document->pages()); + m_metaStrings += i18n("Click to begin"); + + m_isSetup = true; +} + +void PresentationWidget::notifyViewportChanged(bool /*smoothMove*/) +{ + // display the current page + changePage(m_document->viewport().pageNumber); + + // auto advance to the next page if set + startAutoChangeTimer(); +} + +void PresentationWidget::notifyPageChanged(int pageNumber, int changedFlags) +{ + // if we are blocking the notifications, do nothing + if (m_blockNotifications) + return; + + // check if it's the last requested pixmap. if so update the widget. + if ((changedFlags & (DocumentObserver::Pixmap | DocumentObserver::Annotations | DocumentObserver::Highlights)) && pageNumber == m_frameIndex) + generatePage(changedFlags & (DocumentObserver::Annotations | DocumentObserver::Highlights)); +} + +void PresentationWidget::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + if (previousPage != -1) { + // stop video playback + for (VideoWidget *vw : qAsConst(m_frames[previousPage]->videoWidgets)) { + vw->stop(); + vw->pageLeft(); + } + + // stop audio playback, if any + Okular::AudioPlayer::instance()->stopPlaybacks(); + + // perform the page closing action, if any + if (m_document->page(previousPage)->pageAction(Okular::Page::Closing)) + m_document->processAction(m_document->page(previousPage)->pageAction(Okular::Page::Closing)); + + // perform the additional actions of the page's annotations, if any + const QLinkedList annotationsList = m_document->page(previousPage)->annotations(); + for (const Okular::Annotation *annotation : annotationsList) { + Okular::Action *action = nullptr; + + if (annotation->subType() == Okular::Annotation::AScreen) + action = static_cast(annotation)->additionalAction(Okular::Annotation::PageClosing); + else if (annotation->subType() == Okular::Annotation::AWidget) + action = static_cast(annotation)->additionalAction(Okular::Annotation::PageClosing); + + if (action) + m_document->processAction(action); + } + } + + if (currentPage != -1) { + m_frameIndex = currentPage; + + // check if pixmap exists or else request it + PresentationFrame *frame = m_frames[m_frameIndex]; + int pixW = frame->geometry.width(); + int pixH = frame->geometry.height(); + + bool signalsBlocked = m_pagesEdit->signalsBlocked(); + m_pagesEdit->blockSignals(true); + m_pagesEdit->setText(QString::number(m_frameIndex + 1)); + m_pagesEdit->blockSignals(signalsBlocked); + + // if pixmap not inside the Okular::Page we request it and wait for + // notifyPixmapChanged call or else we can proceed to pixmap generation + if (!frame->page->hasPixmap(this, ceil(pixW * qApp->devicePixelRatio()), ceil(pixH * qApp->devicePixelRatio()))) { + requestPixmaps(); + } else { + // make the background pixmap + generatePage(); + } + + // perform the page opening action, if any + if (m_document->page(m_frameIndex)->pageAction(Okular::Page::Opening)) + m_document->processAction(m_document->page(m_frameIndex)->pageAction(Okular::Page::Opening)); + + // perform the additional actions of the page's annotations, if any + const QLinkedList annotationsList = m_document->page(m_frameIndex)->annotations(); + for (const Okular::Annotation *annotation : annotationsList) { + Okular::Action *action = nullptr; + + if (annotation->subType() == Okular::Annotation::AScreen) + action = static_cast(annotation)->additionalAction(Okular::Annotation::PageOpening); + else if (annotation->subType() == Okular::Annotation::AWidget) + action = static_cast(annotation)->additionalAction(Okular::Annotation::PageOpening); + + if (action) + m_document->processAction(action); + } + + // start autoplay video playback + for (VideoWidget *vw : qAsConst(m_frames[m_frameIndex]->videoWidgets)) { + vw->pageEntered(); + } + } +} + +bool PresentationWidget::canUnloadPixmap(int pageNumber) const +{ + if (Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Low || Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Normal) { + // can unload all pixmaps except for the currently visible one + return pageNumber != m_frameIndex; + } else { + // can unload all pixmaps except for the currently visible one, previous and next + return qAbs(pageNumber - m_frameIndex) <= 1; + } +} + +void PresentationWidget::setupActions() +{ + addAction(m_ac->action(QStringLiteral("first_page"))); + addAction(m_ac->action(QStringLiteral("last_page"))); + addAction(m_ac->action(QString::fromLocal8Bit(KStandardAction::name(KStandardAction::Prior)))); + addAction(m_ac->action(QString::fromLocal8Bit(KStandardAction::name(KStandardAction::Next)))); + addAction(m_ac->action(QString::fromLocal8Bit(KStandardAction::name(KStandardAction::DocumentBack)))); + addAction(m_ac->action(QString::fromLocal8Bit(KStandardAction::name(KStandardAction::DocumentForward)))); + + QAction *action = m_ac->action(QStringLiteral("switch_blackscreen_mode")); + connect(action, &QAction::toggled, this, &PresentationWidget::toggleBlackScreenMode); + action->setEnabled(true); + addAction(action); +} + +void PresentationWidget::setPlayPauseIcon() +{ + QAction *playPauseAction = m_ac->action(QStringLiteral("presentation_play_pause")); + if (m_nextPageTimer->isActive()) { + playPauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); + playPauseAction->setToolTip(i18nc("For Presentation", "Pause")); + } else { + playPauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); + playPauseAction->setToolTip(i18nc("For Presentation", "Play")); + } +} + +bool PresentationWidget::eventFilter(QObject *o, QEvent *e) +{ + if (o == qApp) { + if (e->type() == QTabletEvent::TabletEnterProximity) { + setCursor(QCursor(Qt::CrossCursor)); + } else if (e->type() == QTabletEvent::TabletLeaveProximity) { + setCursor(QCursor(Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::Hidden ? Qt::BlankCursor : Qt::ArrowCursor)); + if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::HiddenDelay) { + // Trick KCursor to hide the cursor if needed by sending an "unknown" key press event + // Send also the key release to make the world happy even it's probably not needed + QKeyEvent kp(QEvent::KeyPress, 0, Qt::NoModifier); + qApp->sendEvent(this, &kp); + QKeyEvent kr(QEvent::KeyRelease, 0, Qt::NoModifier); + qApp->sendEvent(this, &kr); + } + } + } + return false; +} + +// +bool PresentationWidget::event(QEvent *e) +{ + if (e->type() == QEvent::Gesture) + return gestureEvent(static_cast(e)); + + if (e->type() == QEvent::ToolTip) { + QHelpEvent *he = (QHelpEvent *)e; + + QRect r; + const Okular::Action *link = getLink(he->x(), he->y(), &r); + + if (link) { + QString tip = link->actionTip(); + if (!tip.isEmpty()) + QToolTip::showText(he->globalPos(), tip, this, r); + } + e->accept(); + return true; + } else + // do not stop the event + return QWidget::event(e); +} + +bool PresentationWidget::gestureEvent(QGestureEvent *event) +{ + // Swiping left or right on a touch screen will go to the previous or next slide, respectively. + // The precise gesture is the standard Qt swipe: with three(!) fingers. + if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) { + QSwipeGesture *swipeEvent = static_cast(swipe); + + if (swipeEvent->state() == Qt::GestureFinished) { + if (swipeEvent->horizontalDirection() == QSwipeGesture::Left) { + slotPrevPage(); + event->accept(); + return true; + } + if (swipeEvent->horizontalDirection() == QSwipeGesture::Right) { + slotNextPage(); + event->accept(); + return true; + } + } + } + + return false; +} +void PresentationWidget::keyPressEvent(QKeyEvent *e) +{ + if (!m_isSetup) + return; + + switch (e->key()) { + case Qt::Key_Left: + case Qt::Key_Backspace: + case Qt::Key_PageUp: + case Qt::Key_Up: + slotPrevPage(); + break; + case Qt::Key_Right: + case Qt::Key_Space: + case Qt::Key_PageDown: + case Qt::Key_Down: + slotNextPage(); + break; + case Qt::Key_Home: + slotFirstPage(); + break; + case Qt::Key_End: + slotLastPage(); + break; + case Qt::Key_Escape: + if (!m_topBar->isHidden()) + showTopBar(false); + else + close(); + break; + } +} + +void PresentationWidget::wheelEvent(QWheelEvent *e) +{ + if (!m_isSetup) + return; + + // performance note: don't remove the clipping + int div = e->angleDelta().y() / 120; + if (div > 0) { + if (div > 3) + div = 3; + while (div--) + slotPrevPage(); + } else if (div < 0) { + if (div < -3) + div = -3; + while (div++) + slotNextPage(); + } +} + +void PresentationWidget::mousePressEvent(QMouseEvent *e) +{ + if (!m_isSetup) + return; + + if (m_drawingEngine) { + QRect r = routeMouseDrawingEvent(e); + if (r.isValid()) { + m_drawingRect |= r.translated(m_frames[m_frameIndex]->geometry.topLeft()); + update(m_drawingRect); + } + return; + } + + // pressing left button + if (e->button() == Qt::LeftButton) { + // if pressing on a link, skip other checks + if ((m_pressedLink = getLink(e->x(), e->y()))) + return; + + const Okular::Annotation *annotation = getAnnotation(e->x(), e->y()); + if (annotation) { + if (annotation->subType() == Okular::Annotation::AMovie) { + const Okular::MovieAnnotation *movieAnnotation = static_cast(annotation); + + VideoWidget *vw = m_frames[m_frameIndex]->videoWidgets.value(movieAnnotation->movie()); + vw->show(); + vw->play(); + return; + } else if (annotation->subType() == Okular::Annotation::ARichMedia) { + const Okular::RichMediaAnnotation *richMediaAnnotation = static_cast(annotation); + + VideoWidget *vw = m_frames[m_frameIndex]->videoWidgets.value(richMediaAnnotation->movie()); + vw->show(); + vw->play(); + return; + } else if (annotation->subType() == Okular::Annotation::AScreen) { + m_document->processAction(static_cast(annotation)->action()); + return; + } + } + + // handle clicking on top-right overlay + if (!(Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::Hidden) && m_overlayGeometry.contains(e->pos())) { + overlayClick(e->pos()); + return; + } + + // Actual mouse press events always lead to the next page page + if (e->source() == Qt::MouseEventNotSynthesized) { + m_goToNextPageOnRelease = true; + } + // Touch events may lead to the previous or next page + else if (Okular::Settings::slidesTapNavigation() != Okular::Settings::EnumSlidesTapNavigation::Disabled) { + switch (Okular::Settings::slidesTapNavigation()) { + case Okular::Settings::EnumSlidesTapNavigation::ForwardBackward: { + if (e->x() < (geometry().width() / 2)) { + m_goToPreviousPageOnRelease = true; + } else { + m_goToNextPageOnRelease = true; + } + break; + } + case Okular::Settings::EnumSlidesTapNavigation::Forward: { + m_goToNextPageOnRelease = true; + break; + } + case Okular::Settings::EnumSlidesTapNavigation::Disabled: { + // Do Nothing + } + } + } + } + // pressing forward button + else if (e->button() == Qt::ForwardButton) { + m_goToNextPageOnRelease = true; + } + // pressing right or backward button + else if (e->button() == Qt::RightButton || e->button() == Qt::BackButton) + m_goToPreviousPageOnRelease = true; +} + +void PresentationWidget::mouseReleaseEvent(QMouseEvent *e) +{ + if (m_drawingEngine) { + routeMouseDrawingEvent(e); + return; + } + + // if releasing on the same link we pressed over, execute it + if (m_pressedLink && e->button() == Qt::LeftButton) { + const Okular::Action *link = getLink(e->x(), e->y()); + if (link == m_pressedLink) + m_document->processAction(link); + m_pressedLink = nullptr; + } + + if (m_goToPreviousPageOnRelease) { + slotPrevPage(); + m_goToPreviousPageOnRelease = false; + } + + if (m_goToNextPageOnRelease) { + slotNextPage(); + m_goToNextPageOnRelease = false; + } +} + +void PresentationWidget::mouseMoveEvent(QMouseEvent *e) +{ + // safety check + if (!m_isSetup) + return; + + // update cursor and tooltip if hovering a link + if (!m_drawingEngine && Okular::Settings::slidesCursor() != Okular::Settings::EnumSlidesCursor::Hidden) + testCursorOnLink(e->x(), e->y()); + + if (!m_topBar->isHidden()) { + // hide a shown bar when exiting the area + if (e->y() > (m_topBar->height() + 1)) { + showTopBar(false); + setFocus(Qt::OtherFocusReason); + } + } else { + if (m_drawingEngine && e->buttons() != Qt::NoButton) { + QRect r = routeMouseDrawingEvent(e); + if (r.isValid()) { + m_drawingRect |= r.translated(m_frames[m_frameIndex]->geometry.topLeft()); + update(m_drawingRect); + } + } else { + // show the bar if reaching top 2 pixels + if (e->y() <= 1) + showTopBar(true); + // handle "dragging the wheel" if clicking on its geometry + else if ((QApplication::mouseButtons() & Qt::LeftButton) && m_overlayGeometry.contains(e->pos())) + overlayClick(e->pos()); + } + } +} + +void PresentationWidget::paintEvent(QPaintEvent *pe) +{ + qreal dpr = devicePixelRatioF(); + + if (m_inBlackScreenMode) { + QPainter painter(this); + painter.fillRect(pe->rect(), Qt::black); + return; + } + + if (!m_isSetup) { + m_width = width(); + m_height = height(); + + connect(m_document, &Okular::Document::linkFind, this, &PresentationWidget::slotFind); + + // register this observer in document. events will come immediately + m_document->addObserver(this); + + // show summary if requested + if (Okular::Settings::slidesShowSummary()) + generatePage(); + } + + // check painting rect consistency + QRect r = pe->rect().intersected(QRect(QPoint(0, 0), geometry().size())); + if (r.isNull()) + return; + + if (m_lastRenderedPixmap.isNull()) { + QPainter painter(this); + painter.fillRect(pe->rect(), Okular::Settings::slidesBackgroundColor()); + return; + } + + // blit the pixmap to the screen + QPainter painter(this); + for (const QRect &r : pe->region()) { + if (!r.isValid()) + continue; +#ifdef ENABLE_PROGRESS_OVERLAY + const QRect dR(QRectF(r.x() * dpr, r.y() * dpr, r.width() * dpr, r.height() * dpr).toAlignedRect()); + if (Okular::Settings::slidesShowProgress() && r.intersects(m_overlayGeometry)) { + // backbuffer the overlay operation + QPixmap backPixmap(dR.size()); + backPixmap.setDevicePixelRatio(dpr); + QPainter pixPainter(&backPixmap); + + // first draw the background on the backbuffer + pixPainter.drawPixmap(QPoint(0, 0), m_lastRenderedPixmap, dR); + + // then blend the overlay (a piece of) over the background + QRect ovr = m_overlayGeometry.intersected(r); + pixPainter.drawPixmap((ovr.left() - r.left()), (ovr.top() - r.top()), m_lastRenderedOverlay, (ovr.left() - m_overlayGeometry.left()) * dpr, (ovr.top() - m_overlayGeometry.top()) * dpr, ovr.width() * dpr, ovr.height() * dpr); + + // finally blit the pixmap to the screen + pixPainter.end(); + const QRect backPixmapRect = backPixmap.rect(); + const QRect dBackPixmapRect(QRectF(backPixmapRect.x() * dpr, backPixmapRect.y() * dpr, backPixmapRect.width() * dpr, backPixmapRect.height() * dpr).toAlignedRect()); + painter.drawPixmap(r.topLeft(), backPixmap, dBackPixmapRect); + } else +#endif + // copy the rendered pixmap to the screen + painter.drawPixmap(r.topLeft(), m_lastRenderedPixmap, dR); + } + + // paint drawings + if (m_frameIndex != -1) { + painter.save(); + + const QRect &geom = m_frames[m_frameIndex]->geometry; + + const QSize pmSize(geom.width() * dpr, geom.height() * dpr); + QPixmap pm(pmSize); + pm.fill(Qt::transparent); + QPainter pmPainter(&pm); + + pm.setDevicePixelRatio(dpr); + pmPainter.setRenderHints(QPainter::Antialiasing); + + // Paint old paths + for (const SmoothPath &drawing : qAsConst(m_frames[m_frameIndex]->drawings)) { + drawing.paint(&pmPainter, pmSize.width(), pmSize.height()); + } + + // Paint the path that is currently being drawn by the user + if (m_drawingEngine && m_drawingRect.intersects(pe->rect())) + m_drawingEngine->paint(&pmPainter, pmSize.width(), pmSize.height(), m_drawingRect.intersected(pe->rect())); + + painter.setRenderHints(QPainter::Antialiasing); + painter.drawPixmap(geom.topLeft(), pm); + + painter.restore(); + } + painter.end(); +} + +void PresentationWidget::resizeEvent(QResizeEvent *re) +{ + m_width = width(); + m_height = height(); + + // if by chance the new size equals the old, do not invalidate pixmaps and such.. + if (size() == re->oldSize()) + return; + + // BEGIN Top toolbar + // tool bar height in pixels, make it large enough to hold the text fields with the page numbers + const int toolBarHeight = m_pagesEdit->height() * 1.5; + + m_topBar->setGeometry(0, 0, width(), toolBarHeight); + m_topBar->setIconSize(QSize(toolBarHeight * 0.75, toolBarHeight * 0.75)); + // END Top toolbar + + // BEGIN Content area + // update the frames + const float screenRatio = (float)m_height / (float)m_width; + for (PresentationFrame *frame : qAsConst(m_frames)) { + frame->recalcGeometry(m_width, m_height, screenRatio); + } + + if (m_frameIndex != -1) { + // ugliness alarm! + const_cast(m_frames[m_frameIndex]->page)->deletePixmap(this); + // force the regeneration of the pixmap + m_lastRenderedPixmap = QPixmap(); + m_blockNotifications = true; + requestPixmaps(); + m_blockNotifications = false; + } + + if (m_transitionTimer->isActive()) { + m_transitionTimer->stop(); + } + + generatePage(true /* no transitions */); + // END Content area +} + +void PresentationWidget::leaveEvent(QEvent *e) +{ + Q_UNUSED(e) + + if (!m_topBar->isHidden()) { + showTopBar(false); + } +} +// + +const void *PresentationWidget::getObjectRect(Okular::ObjectRect::ObjectType type, int x, int y, QRect *geometry) const +{ + // no links on invalid pages + if (geometry && !geometry->isNull()) + geometry->setRect(0, 0, 0, 0); + if (m_frameIndex < 0 || m_frameIndex >= (int)m_frames.size()) + return nullptr; + + // get frame, page and geometry + const PresentationFrame *frame = m_frames[m_frameIndex]; + const Okular::Page *page = frame->page; + const QRect &frameGeometry = frame->geometry; + + // compute normalized x and y + double nx = (double)(x - frameGeometry.left()) / (double)frameGeometry.width(); + double ny = (double)(y - frameGeometry.top()) / (double)frameGeometry.height(); + + // no links outside the pages + if (nx < 0 || nx > 1 || ny < 0 || ny > 1) + return nullptr; + + // check if 1) there is an object and 2) it's a link + const QRect screenRect = oldQt_screenOf(this)->geometry(); + const Okular::ObjectRect *object = page->objectRect(type, nx, ny, screenRect.width(), screenRect.height()); + if (!object) + return nullptr; + + // compute link geometry if destination rect present + if (geometry) { + *geometry = object->boundingRect(frameGeometry.width(), frameGeometry.height()); + geometry->translate(frameGeometry.left(), frameGeometry.top()); + } + + // return the link pointer + return object->object(); +} + +const Okular::Action *PresentationWidget::getLink(int x, int y, QRect *geometry) const +{ + return reinterpret_cast(getObjectRect(Okular::ObjectRect::Action, x, y, geometry)); +} + +const Okular::Annotation *PresentationWidget::getAnnotation(int x, int y, QRect *geometry) const +{ + return reinterpret_cast(getObjectRect(Okular::ObjectRect::OAnnotation, x, y, geometry)); +} + +void PresentationWidget::testCursorOnLink(int x, int y) +{ + const Okular::Action *link = getLink(x, y, nullptr); + const Okular::Annotation *annotation = getAnnotation(x, y, nullptr); + + const bool needsHandCursor = ((link != nullptr) || ((annotation != nullptr) && (annotation->subType() == Okular::Annotation::AMovie)) || ((annotation != nullptr) && (annotation->subType() == Okular::Annotation::ARichMedia)) || + ((annotation != nullptr) && (annotation->subType() == Okular::Annotation::AScreen) && (GuiUtils::renditionMovieFromScreenAnnotation(static_cast(annotation)) != nullptr))); + + // only react on changes (in/out from a link) + if ((needsHandCursor && !m_handCursor) || (!needsHandCursor && m_handCursor)) { + // change cursor shape + m_handCursor = needsHandCursor; + setCursor(QCursor(m_handCursor ? Qt::PointingHandCursor : Qt::ArrowCursor)); + } +} + +void PresentationWidget::overlayClick(const QPoint position) +{ + // clicking the progress indicator + int xPos = position.x() - m_overlayGeometry.x() - m_overlayGeometry.width() / 2, yPos = m_overlayGeometry.height() / 2 - position.y(); + if (!xPos && !yPos) + return; + + // compute angle relative to indicator (note coord transformation) + float angle = 0.5 + 0.5 * atan2((double)-xPos, (double)-yPos) / M_PI; + int pageIndex = (int)(angle * (m_frames.count() - 1) + 0.5); + + // go to selected page + changePage(pageIndex); +} + +void PresentationWidget::changePage(int newPage) +{ + if (m_showSummaryView) { + m_showSummaryView = false; + m_frameIndex = -1; + return; + } + + if (m_frameIndex == newPage) + return; + + // switch to newPage + m_document->setViewportPage(newPage, this); + + if ((Okular::Settings::slidesShowSummary() && !m_showSummaryView) || m_frameIndex == -1) + notifyCurrentPageChanged(-1, newPage); +} + +void PresentationWidget::generatePage(bool disableTransition) +{ + if (m_lastRenderedPixmap.isNull()) { + qreal dpr = qApp->devicePixelRatio(); + m_lastRenderedPixmap = QPixmap(m_width * dpr, m_height * dpr); + m_lastRenderedPixmap.setDevicePixelRatio(dpr); + + m_previousPagePixmap = QPixmap(); + } else { + m_previousPagePixmap = m_lastRenderedPixmap; + } + + // opens the painter over the pixmap + QPainter pixmapPainter; + pixmapPainter.begin(&m_lastRenderedPixmap); + // generate welcome page + if (m_frameIndex == -1) + generateIntroPage(pixmapPainter); + // generate a normal pixmap with extended margin filling + if (m_frameIndex >= 0 && m_frameIndex < (int)m_document->pages()) + generateContentsPage(m_frameIndex, pixmapPainter); + pixmapPainter.end(); + + // generate the top-right corner overlay +#ifdef ENABLE_PROGRESS_OVERLAY + if (Okular::Settings::slidesShowProgress() && m_frameIndex != -1) + generateOverlay(); +#endif + + // start transition on pages that have one + if (!disableTransition && Okular::Settings::slidesTransitionsEnabled()) { + const Okular::PageTransition *transition = m_frameIndex != -1 ? m_frames[m_frameIndex]->page->transition() : nullptr; + if (transition) + initTransition(transition); + else { + Okular::PageTransition trans = defaultTransition(); + initTransition(&trans); + } + } else { + Okular::PageTransition trans = defaultTransition(Okular::Settings::EnumSlidesTransition::Replace); + initTransition(&trans); + } + + // update cursor + tooltip + if (!m_drawingEngine && Okular::Settings::slidesCursor() != Okular::Settings::EnumSlidesCursor::Hidden) { + QPoint p = mapFromGlobal(QCursor::pos()); + testCursorOnLink(p.x(), p.y()); + } +} + +void PresentationWidget::generateIntroPage(QPainter &p) +{ + qreal dpr = qApp->devicePixelRatio(); + + // use a vertical gray gradient background + int blend1 = m_height / 10, blend2 = 9 * m_height / 10; + int baseTint = QColor(Qt::gray).red(); + for (int i = 0; i < m_height; i++) { + int k = baseTint; + if (i < blend1) + k -= (int)(baseTint * (i - blend1) * (i - blend1) / (float)(blend1 * blend1)); + if (i > blend2) + k += (int)((255 - baseTint) * (i - blend2) * (i - blend2) / (float)(blend1 * blend1)); + p.fillRect(0, i, m_width, 1, QColor(k, k, k)); + } + + // draw okular logo in the four corners + QPixmap logo = QIcon::fromTheme(QStringLiteral("okular")).pixmap(64 * dpr); + logo.setDevicePixelRatio(dpr); + if (!logo.isNull()) { + p.drawPixmap(5, 5, logo); + p.drawPixmap(m_width - 5 - logo.width(), 5, logo); + p.drawPixmap(m_width - 5 - logo.width(), m_height - 5 - logo.height(), logo); + p.drawPixmap(5, m_height - 5 - logo.height(), logo); + } + + // draw metadata text (the last line is 'click to begin') + int strNum = m_metaStrings.count(), strHeight = m_height / (strNum + 4), fontHeight = 2 * strHeight / 3; + QFont font(p.font()); + font.setPixelSize(fontHeight); + QFontMetrics metrics(font); + for (int i = 0; i < strNum; i++) { + // set a font to fit text width + float wScale = (float)metrics.boundingRect(m_metaStrings[i]).width() / (float)m_width; + QFont f(font); + if (wScale > 1.0) + f.setPixelSize((int)((float)fontHeight / (float)wScale)); + p.setFont(f); + + // text shadow + p.setPen(Qt::darkGray); + p.drawText(2, m_height / 4 + strHeight * i + 2, m_width, strHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_metaStrings[i]); + // text body + p.setPen(128 + (127 * i) / strNum); + p.drawText(0, m_height / 4 + strHeight * i, m_width, strHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_metaStrings[i]); + } +} + +void PresentationWidget::generateContentsPage(int pageNum, QPainter &p) +{ + PresentationFrame *frame = m_frames[pageNum]; + + // translate painter and contents rect + QRect geom(frame->geometry); + p.translate(geom.left(), geom.top()); + geom.translate(-geom.left(), -geom.top()); + + // draw the page using the shared PagePainter class + int flags = PagePainter::Accessibility | PagePainter::Highlights | PagePainter::Annotations; + + PagePainter::paintPageOnPainter(&p, frame->page, this, flags, geom.width(), geom.height(), geom); + + // restore painter + p.translate(-frame->geometry.left(), -frame->geometry.top()); + + // fill unpainted areas with background color + const QRegion unpainted(QRect(0, 0, m_width, m_height)); + const QRegion rgn = unpainted.subtracted(frame->geometry); + for (const QRect &r : rgn) { + p.fillRect(r, Okular::Settings::slidesBackgroundColor()); + } +} + +// from Arthur - Qt4 - (is defined elsewhere as 'qt_div_255' to not break final compilation) +inline int qt_div255(int x) +{ + return (x + (x >> 8) + 0x80) >> 8; +} +void PresentationWidget::generateOverlay() +{ +#ifdef ENABLE_PROGRESS_OVERLAY + qreal dpr = qApp->devicePixelRatio(); + + // calculate overlay geometry and resize pixmap if needed + double side = m_width / 16.0; + m_overlayGeometry.setRect(m_width - side - 4, 4, side, side); + + // note: to get a sort of antialiasing, we render the pixmap double sized + // and the resulting image is smoothly scaled down. So here we open a + // painter on the double sized pixmap. + side *= 2; + + QPixmap doublePixmap(side * dpr, side * dpr); + doublePixmap.setDevicePixelRatio(dpr); + doublePixmap.fill(Qt::black); + QPainter pixmapPainter(&doublePixmap); + pixmapPainter.setRenderHints(QPainter::Antialiasing); + + // draw PIE SLICES in blue levels (the levels will then be the alpha component) + int pages = m_document->pages(); + if (pages > 28) { // draw continuous slices + int degrees = (int)(360 * (float)(m_frameIndex + 1) / (float)pages); + pixmapPainter.setPen(0x05); + pixmapPainter.setBrush(QColor(0x40)); + pixmapPainter.drawPie(2, 2, side - 4, side - 4, 90 * 16, (360 - degrees) * 16); + pixmapPainter.setPen(0x40); + pixmapPainter.setBrush(QColor(0xF0)); + pixmapPainter.drawPie(2, 2, side - 4, side - 4, 90 * 16, -degrees * 16); + } else { // draw discrete slices + float oldCoord = -90; + for (int i = 0; i < pages; i++) { + float newCoord = -90 + 360 * (float)(i + 1) / (float)pages; + pixmapPainter.setPen(i <= m_frameIndex ? 0x40 : 0x05); + pixmapPainter.setBrush(QColor(i <= m_frameIndex ? 0xF0 : 0x40)); + pixmapPainter.drawPie(2, 2, side - 4, side - 4, (int)(-16 * (oldCoord + 1)), (int)(-16 * (newCoord - (oldCoord + 2)))); + oldCoord = newCoord; + } + } + int circleOut = side / 4; + pixmapPainter.setPen(Qt::black); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawEllipse(circleOut, circleOut, side - 2 * circleOut, side - 2 * circleOut); + + // draw TEXT using maximum opacity + QFont f(pixmapPainter.font()); + f.setPixelSize(side / 4); + pixmapPainter.setFont(f); + pixmapPainter.setPen(0xFF); + // use a little offset to prettify output + pixmapPainter.drawText(2, 2, side, side, Qt::AlignCenter, QString::number(m_frameIndex + 1)); + + // end drawing pixmap and halve image + pixmapPainter.end(); + QImage image(doublePixmap.toImage().scaled((side / 2) * dpr, (side / 2) * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + image.setDevicePixelRatio(dpr); + image = image.convertToFormat(QImage::Format_ARGB32); + image.setDevicePixelRatio(dpr); + + // draw circular shadow using the same technique + doublePixmap.fill(Qt::black); + pixmapPainter.begin(&doublePixmap); + pixmapPainter.setPen(0x40); + pixmapPainter.setBrush(QColor(0x80)); + pixmapPainter.drawEllipse(0, 0, side, side); + pixmapPainter.end(); + QImage shadow(doublePixmap.toImage().scaled((side / 2) * dpr, (side / 2) * dpr, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + shadow.setDevicePixelRatio(dpr); + + // generate a 2 colors pixmap using mixing shadow (made with highlight color) + // and image (made with highlightedText color) + QPalette pal = palette(); + QColor color = pal.color(QPalette::Active, QPalette::HighlightedText); + int red = color.red(), green = color.green(), blue = color.blue(); + color = pal.color(QPalette::Active, QPalette::Highlight); + int sRed = color.red(), sGreen = color.green(), sBlue = color.blue(); + // pointers + unsigned int *data = reinterpret_cast(image.bits()), *shadowData = reinterpret_cast(shadow.bits()), pixels = image.width() * image.height(); + // cache data (reduce computation time to 26%!) + int c1 = -1, c2 = -1, cR = 0, cG = 0, cB = 0, cA = 0; + // foreach pixel + for (unsigned int i = 0; i < pixels; ++i) { + // alpha for shadow and image + int shadowAlpha = shadowData[i] & 0xFF, srcAlpha = data[i] & 0xFF; + // cache values + if (srcAlpha != c1 || shadowAlpha != c2) { + c1 = srcAlpha; + c2 = shadowAlpha; + // fuse color components and alpha value of image over shadow + data[i] = qRgba(cR = qt_div255(srcAlpha * red + (255 - srcAlpha) * sRed), + cG = qt_div255(srcAlpha * green + (255 - srcAlpha) * sGreen), + cB = qt_div255(srcAlpha * blue + (255 - srcAlpha) * sBlue), + cA = qt_div255(srcAlpha * srcAlpha + (255 - srcAlpha) * shadowAlpha)); + } else + data[i] = qRgba(cR, cG, cB, cA); + } + m_lastRenderedOverlay = QPixmap::fromImage(image); + m_lastRenderedOverlay.setDevicePixelRatio(dpr); + + // start the autohide timer + // repaint( m_overlayGeometry ); // toggle with next line + update(m_overlayGeometry); + m_overlayHideTimer->start(2500); +#endif +} + +QRect PresentationWidget::routeMouseDrawingEvent(QMouseEvent *e) +{ + if (m_frameIndex == -1) // Can't draw on the summary page + return QRect(); + + const QRect &geom = m_frames[m_frameIndex]->geometry; + const Okular::Page *page = m_frames[m_frameIndex]->page; + + AnnotatorEngine::EventType eventType; + AnnotatorEngine::Button button; + AnnotatorEngine::Modifiers modifiers; + + // figure out the event type and button + AnnotatorEngine::decodeEvent(e, &eventType, &button); + + static bool hasclicked = false; + if (eventType == AnnotatorEngine::Press) + hasclicked = true; + + QPointF mousePos = e->localPos(); + double nX = (mousePos.x() - (double)geom.left()) / (double)geom.width(); + double nY = (mousePos.y() - (double)geom.top()) / (double)geom.height(); + QRect ret; + bool isInside = nX >= 0 && nX < 1 && nY >= 0 && nY < 1; + + if (hasclicked && !isInside) { + // Fake a move to the last border pos + nX = qBound(0., nX, 1.); + nY = qBound(0., nY, 1.); + m_drawingEngine->event(AnnotatorEngine::Move, button, modifiers, nX, nY, geom.width(), geom.height(), page); + + // Fake a release in the following lines + eventType = AnnotatorEngine::Release; + isInside = true; + } else if (!hasclicked && isInside) { + // we're coming from the outside, pretend we started clicking at the closest border + if (nX < (1 - nX) && nX < nY && nX < (1 - nY)) + nX = 0; + else if (nY < (1 - nY) && nY < nX && nY < (1 - nX)) + nY = 0; + else if ((1 - nX) < nX && (1 - nX) < nY && (1 - nX) < (1 - nY)) + nX = 1; + else + nY = 1; + + hasclicked = true; + eventType = AnnotatorEngine::Press; + } + + if (hasclicked && isInside) { + ret = m_drawingEngine->event(eventType, button, modifiers, nX, nY, geom.width(), geom.height(), page); + } + + if (eventType == AnnotatorEngine::Release) { + hasclicked = false; + } + + if (m_drawingEngine->creationCompleted()) { + // add drawing to current page + m_frames[m_frameIndex]->drawings << m_drawingEngine->endSmoothPath(); + + // remove the actual drawer and create a new one just after + // that - that gives continuous drawing + delete m_drawingEngine; + m_drawingRect = QRect(); + m_drawingEngine = new SmoothPathEngine(m_currentDrawingToolElement); + + // schedule repaint + update(); + } + + return ret; +} + +void PresentationWidget::startAutoChangeTimer() +{ + double pageDuration = m_frameIndex >= 0 && m_frameIndex < (int)m_frames.count() ? m_frames[m_frameIndex]->page->duration() : -1; + if (m_advanceSlides || pageDuration >= 0.0) { + double secs; + if (pageDuration < 0.0) + secs = Okular::SettingsCore::slidesAdvanceTime(); + else if (m_advanceSlides) + secs = qMin(pageDuration, Okular::SettingsCore::slidesAdvanceTime()); + else + secs = pageDuration; + + m_nextPageTimer->start((int)(secs * 1000)); + } + setPlayPauseIcon(); +} + +QScreen *PresentationWidget::defaultScreen() const +{ + const int preferenceScreen = Okular::Settings::slidesScreen(); + + if (preferenceScreen == -2) { + return oldQt_screenOf(m_parentWidget); + } else if (preferenceScreen == -1) { + return QApplication::primaryScreen(); + } else if (preferenceScreen >= 0 && preferenceScreen < QApplication::screens().count()) { + return QApplication::screens().at(preferenceScreen); + } else { + return oldQt_screenOf(m_parentWidget); + } +} + +void PresentationWidget::requestPixmaps() +{ + PresentationFrame *frame = m_frames[m_frameIndex]; + int pixW = frame->geometry.width(); + int pixH = frame->geometry.height(); + + // operation will take long: set busy cursor + QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); + // request the pixmap + QLinkedList requests; + requests.push_back(new Okular::PixmapRequest(this, m_frameIndex, pixW, pixH, PRESENTATION_PRIO, Okular::PixmapRequest::NoFeature)); + // restore cursor + QApplication::restoreOverrideCursor(); + // ask for next and previous page if not in low memory usage setting + if (Okular::SettingsCore::memoryLevel() != Okular::SettingsCore::EnumMemoryLevel::Low) { + int pagesToPreload = 1; + + // If greedy, preload everything + if (Okular::SettingsCore::memoryLevel() == Okular::SettingsCore::EnumMemoryLevel::Greedy) + pagesToPreload = (int)m_document->pages(); + + Okular::PixmapRequest::PixmapRequestFeatures requestFeatures = Okular::PixmapRequest::Preload; + requestFeatures |= Okular::PixmapRequest::Asynchronous; + + for (int j = 1; j <= pagesToPreload; j++) { + int tailRequest = m_frameIndex + j; + if (tailRequest < (int)m_document->pages()) { + PresentationFrame *nextFrame = m_frames[tailRequest]; + pixW = nextFrame->geometry.width(); + pixH = nextFrame->geometry.height(); + if (!nextFrame->page->hasPixmap(this, pixW, pixH)) + requests.push_back(new Okular::PixmapRequest(this, tailRequest, pixW, pixH, PRESENTATION_PRELOAD_PRIO, requestFeatures)); + } + + int headRequest = m_frameIndex - j; + if (headRequest >= 0) { + PresentationFrame *prevFrame = m_frames[headRequest]; + pixW = prevFrame->geometry.width(); + pixH = prevFrame->geometry.height(); + if (!prevFrame->page->hasPixmap(this, pixW, pixH)) + requests.push_back(new Okular::PixmapRequest(this, headRequest, pixW, pixH, PRESENTATION_PRELOAD_PRIO, requestFeatures)); + } + + // stop if we've already reached both ends of the document + if (headRequest < 0 && tailRequest >= (int)m_document->pages()) + break; + } + } + m_document->requestPixmaps(requests); +} + +void PresentationWidget::slotNextPage() +{ + int nextIndex = m_frameIndex + 1; + + // loop when configured + if (nextIndex == m_frames.count() && Okular::Settings::slidesLoop()) + nextIndex = 0; + + if (nextIndex < m_frames.count()) { + // go to next page + changePage(nextIndex); + // auto advance to the next page if set + startAutoChangeTimer(); + } else { +#ifdef ENABLE_PROGRESS_OVERLAY + if (Okular::Settings::slidesShowProgress()) + generateOverlay(); +#endif + if (m_transitionTimer->isActive()) { + m_transitionTimer->stop(); + m_lastRenderedPixmap = m_currentPagePixmap; + update(); + } + } + // we need the setFocus() call here to let KCursor::autoHide() work correctly + setFocus(); +} + +void PresentationWidget::slotPrevPage() +{ + if (m_frameIndex > 0) { + // go to previous page + changePage(m_frameIndex - 1); + + // auto advance to the next page if set + startAutoChangeTimer(); + } else { +#ifdef ENABLE_PROGRESS_OVERLAY + if (Okular::Settings::slidesShowProgress()) + generateOverlay(); +#endif + if (m_transitionTimer->isActive()) { + m_transitionTimer->stop(); + m_lastRenderedPixmap = m_currentPagePixmap; + update(); + } + } +} + +void PresentationWidget::slotFirstPage() +{ + changePage(0); +} + +void PresentationWidget::slotLastPage() +{ + changePage((int)m_frames.count() - 1); +} + +void PresentationWidget::slotHideOverlay() +{ + QRect geom(m_overlayGeometry); + m_overlayGeometry.setCoords(0, 0, -1, -1); + update(geom); +} + +void PresentationWidget::slotTransitionStep() +{ + switch (m_currentTransition.type()) { + case Okular::PageTransition::Fade: { + QPainter pixmapPainter; + m_currentPixmapOpacity += 1.0 / m_transitionSteps; + m_lastRenderedPixmap = QPixmap(m_lastRenderedPixmap.size()); + m_lastRenderedPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); + m_lastRenderedPixmap.fill(Qt::transparent); + pixmapPainter.begin(&m_lastRenderedPixmap); + pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); + pixmapPainter.setOpacity(1 - m_currentPixmapOpacity); + pixmapPainter.drawPixmap(0, 0, m_previousPagePixmap); + pixmapPainter.setOpacity(m_currentPixmapOpacity); + pixmapPainter.drawPixmap(0, 0, m_currentPagePixmap); + update(); + if (m_currentPixmapOpacity >= 1) + return; + } break; + default: { + if (m_transitionRects.empty()) { + // it's better to fix the transition to cover the whole screen than + // enabling the following line that wastes cpu for nothing + // update(); + return; + } + + for (int i = 0; i < m_transitionMul && !m_transitionRects.empty(); i++) { + update(m_transitionRects.first()); + m_transitionRects.pop_front(); + } + } break; + } + m_transitionTimer->start(m_transitionDelay); +} + +void PresentationWidget::slotDelayedEvents() +{ + setScreen(defaultScreen()); + show(); + + if (m_screenSelect) { + m_screenSelect->setCurrentItem(QApplication::screens().indexOf(oldQt_screenOf(this))); + connect(m_screenSelect->selectableActionGroup(), &QActionGroup::triggered, this, &PresentationWidget::chooseScreen); + } + + // inform user on how to exit from presentation mode + KMessageBox::information( + this, + i18n("There are two ways of exiting presentation mode, you can press either ESC key or click with the quit button that appears when placing the mouse in the top-right corner. Of course you can cycle windows (Alt+TAB by default)"), + QString(), + QStringLiteral("presentationInfo")); +} + +void PresentationWidget::slotPageChanged() +{ + bool ok = true; + int p = m_pagesEdit->text().toInt(&ok); + if (!ok) + return; + + changePage(p - 1); +} + +void PresentationWidget::slotChangeDrawingToolEngine(const QDomElement &element) +{ + if (element.isNull()) { + delete m_drawingEngine; + m_drawingEngine = nullptr; + m_drawingRect = QRect(); + setCursor(Qt::ArrowCursor); + } else { + m_drawingEngine = new SmoothPathEngine(element); + setCursor(QCursor(QPixmap(QStringLiteral("pencil")), Qt::ArrowCursor)); + m_currentDrawingToolElement = element; + } +} + +void PresentationWidget::slotAddDrawingToolActions() +{ + DrawingToolActions *drawingToolActions = qobject_cast(sender()); + + const QList actionsList = drawingToolActions->actions(); + for (QAction *action : actionsList) { + action->setEnabled(true); + m_topBar->addAction(action); + addAction(action); + } +} + +void PresentationWidget::clearDrawings() +{ + if (m_frameIndex != -1) + m_frames[m_frameIndex]->drawings.clear(); + update(); +} + +void PresentationWidget::chooseScreen(QAction *act) +{ + if (!act || act->data().type() != QVariant::Int) + return; + + const int newScreen = act->data().toInt(); + if (newScreen < QApplication::screens().count()) { + setScreen(QApplication::screens().at(newScreen)); + } +} + +void PresentationWidget::toggleBlackScreenMode(bool) +{ + m_inBlackScreenMode = !m_inBlackScreenMode; + + update(); +} + +void PresentationWidget::setScreen(const QScreen *newScreen) +{ + // To move to a new screen, need to disable fullscreen first: +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + if (newScreen != screen()) { +#else + if (true) { // TODO Qt6 (oldQt_screenOf() doesn’t help here, because it has a default value.) +#endif + setWindowState(windowState() & ~Qt::WindowFullScreen); + } + setGeometry(newScreen->geometry()); + setWindowState(windowState() | Qt::WindowFullScreen); +} + +void PresentationWidget::inhibitPowerManagement() +{ +#ifdef Q_OS_LINUX + QString reason = i18nc("Reason for inhibiting the screensaver activation, when the presentation mode is active", "Giving a presentation"); + + if (!m_screenInhibitCookie) { + QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("Inhibit")); + message << QCoreApplication::applicationName(); + message << reason; + + QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(message); + reply.waitForFinished(); + if (reply.isValid()) { + m_screenInhibitCookie = reply.value(); + qCDebug(OkularUiDebug) << "Screen inhibition cookie" << m_screenInhibitCookie; + } else { + qCWarning(OkularUiDebug) << "Unable to inhibit screensaver" << reply.error(); + } + } + + if (m_sleepInhibitFd != -1) { + QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("Inhibit")); + message << QStringLiteral("sleep"); + message << QCoreApplication::applicationName(); + message << reason; + message << QStringLiteral("block"); + + QDBusPendingReply reply = QDBusConnection::systemBus().asyncCall(message); + reply.waitForFinished(); + if (reply.isValid()) { + m_sleepInhibitFd = dup(reply.value().fileDescriptor()); + } else { + qCWarning(OkularUiDebug) << "Unable to inhibit sleep" << reply.error(); + } + } +#endif +} + +void PresentationWidget::allowPowerManagement() +{ +#ifdef Q_OS_LINUX + if (m_sleepInhibitFd != -1) { + ::close(m_sleepInhibitFd); + m_sleepInhibitFd = -1; + } + + if (m_screenInhibitCookie) { + QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("UnInhibit")); + message << m_screenInhibitCookie; + + QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(message); + reply.waitForFinished(); + + m_screenInhibitCookie = 0; + } +#endif +} + +void PresentationWidget::showTopBar(bool show) +{ + if (show) { + m_topBar->show(); + + // Don't autohide the mouse cursor if it's over the toolbar + if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::HiddenDelay) { + KCursor::setAutoHideCursor(this, false); + } + + // Always show a cursor when topBar is visible + if (!m_drawingEngine) { + setCursor(QCursor(Qt::ArrowCursor)); + } + } else { + m_topBar->hide(); + + // Reenable autohide if need be when leaving the toolbar + if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::HiddenDelay) { + KCursor::setAutoHideCursor(this, true); + } + + // Or hide the cursor again if hidden cursor is enabled + else if (Okular::Settings::slidesCursor() == Okular::Settings::EnumSlidesCursor::Hidden) { + // Don't hide the cursor if drawing mode is on + if (!m_drawingEngine) { + setCursor(QCursor(Qt::BlankCursor)); + } + } + } + + // Make sure mouse tracking isn't off after the KCursor::setAutoHideCursor() calls + setMouseTracking(true); +} + +void PresentationWidget::slotFind() +{ + if (!m_searchBar) { + m_searchBar = new PresentationSearchBar(m_document, this, this); + m_searchBar->forceSnap(); + } + m_searchBar->focusOnSearchEdit(); + m_searchBar->show(); +} + +const Okular::PageTransition PresentationWidget::defaultTransition() const +{ + return defaultTransition(Okular::Settings::slidesTransition()); +} + +const Okular::PageTransition PresentationWidget::defaultTransition(int type) const +{ + switch (type) { + case Okular::Settings::EnumSlidesTransition::BlindsHorizontal: { + Okular::PageTransition transition(Okular::PageTransition::Blinds); + transition.setAlignment(Okular::PageTransition::Horizontal); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::BlindsVertical: { + Okular::PageTransition transition(Okular::PageTransition::Blinds); + transition.setAlignment(Okular::PageTransition::Vertical); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::BoxIn: { + Okular::PageTransition transition(Okular::PageTransition::Box); + transition.setDirection(Okular::PageTransition::Inward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::BoxOut: { + Okular::PageTransition transition(Okular::PageTransition::Box); + transition.setDirection(Okular::PageTransition::Outward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::Dissolve: { + return Okular::PageTransition(Okular::PageTransition::Dissolve); + break; + } + case Okular::Settings::EnumSlidesTransition::GlitterDown: { + Okular::PageTransition transition(Okular::PageTransition::Glitter); + transition.setAngle(270); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::GlitterRight: { + Okular::PageTransition transition(Okular::PageTransition::Glitter); + transition.setAngle(0); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::GlitterRightDown: { + Okular::PageTransition transition(Okular::PageTransition::Glitter); + transition.setAngle(315); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::Random: { + return defaultTransition(KRandom::random() % 18); + break; + } + case Okular::Settings::EnumSlidesTransition::SplitHorizontalIn: { + Okular::PageTransition transition(Okular::PageTransition::Split); + transition.setAlignment(Okular::PageTransition::Horizontal); + transition.setDirection(Okular::PageTransition::Inward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::SplitHorizontalOut: { + Okular::PageTransition transition(Okular::PageTransition::Split); + transition.setAlignment(Okular::PageTransition::Horizontal); + transition.setDirection(Okular::PageTransition::Outward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::SplitVerticalIn: { + Okular::PageTransition transition(Okular::PageTransition::Split); + transition.setAlignment(Okular::PageTransition::Vertical); + transition.setDirection(Okular::PageTransition::Inward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::SplitVerticalOut: { + Okular::PageTransition transition(Okular::PageTransition::Split); + transition.setAlignment(Okular::PageTransition::Vertical); + transition.setDirection(Okular::PageTransition::Outward); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::WipeDown: { + Okular::PageTransition transition(Okular::PageTransition::Wipe); + transition.setAngle(270); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::WipeRight: { + Okular::PageTransition transition(Okular::PageTransition::Wipe); + transition.setAngle(0); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::WipeLeft: { + Okular::PageTransition transition(Okular::PageTransition::Wipe); + transition.setAngle(180); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::WipeUp: { + Okular::PageTransition transition(Okular::PageTransition::Wipe); + transition.setAngle(90); + return transition; + break; + } + case Okular::Settings::EnumSlidesTransition::Fade: { + return Okular::PageTransition(Okular::PageTransition::Fade); + break; + } + case Okular::Settings::EnumSlidesTransition::Replace: + default: + return Okular::PageTransition(Okular::PageTransition::Replace); + break; + } + // should not happen, just make gcc happy + return Okular::PageTransition(); +} + +/** ONLY the TRANSITIONS GENERATION function from here on **/ +void PresentationWidget::initTransition(const Okular::PageTransition *transition) +{ + // if it's just a 'replace' transition, repaint the screen + if (transition->type() == Okular::PageTransition::Replace) { + update(); + return; + } + + const bool isInward = transition->direction() == Okular::PageTransition::Inward; + const bool isHorizontal = transition->alignment() == Okular::PageTransition::Horizontal; + const float totalTime = transition->duration(); + + m_transitionRects.clear(); + m_currentTransition = *transition; + m_currentPagePixmap = m_lastRenderedPixmap; + + switch (transition->type()) { + // split: horizontal / vertical and inward / outward + case Okular::PageTransition::Split: { + const int steps = isHorizontal ? 100 : 75; + if (isHorizontal) { + if (isInward) { + int xPosition = 0; + for (int i = 0; i < steps; i++) { + int xNext = ((i + 1) * m_width) / (2 * steps); + m_transitionRects.push_back(QRect(xPosition, 0, xNext - xPosition, m_height)); + m_transitionRects.push_back(QRect(m_width - xNext, 0, xNext - xPosition, m_height)); + xPosition = xNext; + } + } else { + int xPosition = m_width / 2; + for (int i = 0; i < steps; i++) { + int xNext = ((steps - (i + 1)) * m_width) / (2 * steps); + m_transitionRects.push_back(QRect(xNext, 0, xPosition - xNext, m_height)); + m_transitionRects.push_back(QRect(m_width - xPosition, 0, xPosition - xNext, m_height)); + xPosition = xNext; + } + } + } else { + if (isInward) { + int yPosition = 0; + for (int i = 0; i < steps; i++) { + int yNext = ((i + 1) * m_height) / (2 * steps); + m_transitionRects.push_back(QRect(0, yPosition, m_width, yNext - yPosition)); + m_transitionRects.push_back(QRect(0, m_height - yNext, m_width, yNext - yPosition)); + yPosition = yNext; + } + } else { + int yPosition = m_height / 2; + for (int i = 0; i < steps; i++) { + int yNext = ((steps - (i + 1)) * m_height) / (2 * steps); + m_transitionRects.push_back(QRect(0, yNext, m_width, yPosition - yNext)); + m_transitionRects.push_back(QRect(0, m_height - yPosition, m_width, yPosition - yNext)); + yPosition = yNext; + } + } + } + m_transitionMul = 2; + m_transitionDelay = (int)((totalTime * 1000) / steps); + } break; + + // blinds: horizontal(l-to-r) / vertical(t-to-b) + case Okular::PageTransition::Blinds: { + const int blinds = isHorizontal ? 8 : 6; + const int steps = m_width / (4 * blinds); + if (isHorizontal) { + int xPosition[8]; + for (int b = 0; b < blinds; b++) + xPosition[b] = (b * m_width) / blinds; + + for (int i = 0; i < steps; i++) { + int stepOffset = (int)(((float)i * (float)m_width) / ((float)blinds * (float)steps)); + for (int b = 0; b < blinds; b++) { + m_transitionRects.push_back(QRect(xPosition[b], 0, stepOffset, m_height)); + xPosition[b] = stepOffset + (b * m_width) / blinds; + } + } + } else { + int yPosition[6]; + for (int b = 0; b < blinds; b++) + yPosition[b] = (b * m_height) / blinds; + + for (int i = 0; i < steps; i++) { + int stepOffset = (int)(((float)i * (float)m_height) / ((float)blinds * (float)steps)); + for (int b = 0; b < blinds; b++) { + m_transitionRects.push_back(QRect(0, yPosition[b], m_width, stepOffset)); + yPosition[b] = stepOffset + (b * m_height) / blinds; + } + } + } + m_transitionMul = blinds; + m_transitionDelay = (int)((totalTime * 1000) / steps); + } break; + + // box: inward / outward + case Okular::PageTransition::Box: { + const int steps = m_width / 10; + if (isInward) { + int L = 0, T = 0, R = m_width, B = m_height; + for (int i = 0; i < steps; i++) { + // compute shrunk box coords + int newL = ((i + 1) * m_width) / (2 * steps); + int newT = ((i + 1) * m_height) / (2 * steps); + int newR = m_width - newL; + int newB = m_height - newT; + // add left, right, topcenter, bottomcenter rects + m_transitionRects.push_back(QRect(L, T, newL - L, B - T)); + m_transitionRects.push_back(QRect(newR, T, R - newR, B - T)); + m_transitionRects.push_back(QRect(newL, T, newR - newL, newT - T)); + m_transitionRects.push_back(QRect(newL, newB, newR - newL, B - newB)); + L = newL; + T = newT; + R = newR, B = newB; + } + } else { + int L = m_width / 2, T = m_height / 2, R = L, B = T; + for (int i = 0; i < steps; i++) { + // compute shrunk box coords + int newL = ((steps - (i + 1)) * m_width) / (2 * steps); + int newT = ((steps - (i + 1)) * m_height) / (2 * steps); + int newR = m_width - newL; + int newB = m_height - newT; + // add left, right, topcenter, bottomcenter rects + m_transitionRects.push_back(QRect(newL, newT, L - newL, newB - newT)); + m_transitionRects.push_back(QRect(R, newT, newR - R, newB - newT)); + m_transitionRects.push_back(QRect(L, newT, R - L, T - newT)); + m_transitionRects.push_back(QRect(L, B, R - L, newB - B)); + L = newL; + T = newT; + R = newR, B = newB; + } + } + m_transitionMul = 4; + m_transitionDelay = (int)((totalTime * 1000) / steps); + } break; + + // wipe: implemented for 4 canonical angles + case Okular::PageTransition::Wipe: { + const int angle = transition->angle(); + const int steps = (angle == 0) || (angle == 180) ? m_width / 8 : m_height / 8; + if (angle == 0) { + int xPosition = 0; + for (int i = 0; i < steps; i++) { + int xNext = ((i + 1) * m_width) / steps; + m_transitionRects.push_back(QRect(xPosition, 0, xNext - xPosition, m_height)); + xPosition = xNext; + } + } else if (angle == 90) { + int yPosition = m_height; + for (int i = 0; i < steps; i++) { + int yNext = ((steps - (i + 1)) * m_height) / steps; + m_transitionRects.push_back(QRect(0, yNext, m_width, yPosition - yNext)); + yPosition = yNext; + } + } else if (angle == 180) { + int xPosition = m_width; + for (int i = 0; i < steps; i++) { + int xNext = ((steps - (i + 1)) * m_width) / steps; + m_transitionRects.push_back(QRect(xNext, 0, xPosition - xNext, m_height)); + xPosition = xNext; + } + } else if (angle == 270) { + int yPosition = 0; + for (int i = 0; i < steps; i++) { + int yNext = ((i + 1) * m_height) / steps; + m_transitionRects.push_back(QRect(0, yPosition, m_width, yNext - yPosition)); + yPosition = yNext; + } + } else { + update(); + return; + } + m_transitionMul = 1; + m_transitionDelay = (int)((totalTime * 1000) / steps); + } break; + + // dissolve: replace 'random' rects + case Okular::PageTransition::Dissolve: { + const int gridXsteps = 50; + const int gridYsteps = 38; + const int steps = gridXsteps * gridYsteps; + int oldX = 0; + int oldY = 0; + // create a grid of gridXstep by gridYstep QRects + for (int y = 0; y < gridYsteps; y++) { + int newY = (int)(m_height * ((float)(y + 1) / (float)gridYsteps)); + for (int x = 0; x < gridXsteps; x++) { + int newX = (int)(m_width * ((float)(x + 1) / (float)gridXsteps)); + m_transitionRects.push_back(QRect(oldX, oldY, newX - oldX, newY - oldY)); + oldX = newX; + } + oldX = 0; + oldY = newY; + } + // randomize the grid + for (int i = 0; i < steps; i++) { +#ifndef Q_OS_WIN + int n1 = (int)(steps * drand48()); + int n2 = (int)(steps * drand48()); +#else + int n1 = (int)(steps * (std::rand() / RAND_MAX)); + int n2 = (int)(steps * (std::rand() / RAND_MAX)); +#endif + // swap items if index differs + if (n1 != n2) { + QRect r = m_transitionRects[n2]; + m_transitionRects[n2] = m_transitionRects[n1]; + m_transitionRects[n1] = r; + } + } + // set global transition parameters + m_transitionMul = 40; + m_transitionDelay = (int)((m_transitionMul * 1000 * totalTime) / steps); + } break; + + // glitter: similar to dissolve but has a direction + case Okular::PageTransition::Glitter: { + const int gridXsteps = 50; + const int gridYsteps = 38; + const int steps = gridXsteps * gridYsteps; + const int angle = transition->angle(); + // generate boxes using a given direction + if (angle == 90) { + int yPosition = m_height; + for (int i = 0; i < gridYsteps; i++) { + int yNext = ((gridYsteps - (i + 1)) * m_height) / gridYsteps; + int xPosition = 0; + for (int j = 0; j < gridXsteps; j++) { + int xNext = ((j + 1) * m_width) / gridXsteps; + m_transitionRects.push_back(QRect(xPosition, yNext, xNext - xPosition, yPosition - yNext)); + xPosition = xNext; + } + yPosition = yNext; + } + } else if (angle == 180) { + int xPosition = m_width; + for (int i = 0; i < gridXsteps; i++) { + int xNext = ((gridXsteps - (i + 1)) * m_width) / gridXsteps; + int yPosition = 0; + for (int j = 0; j < gridYsteps; j++) { + int yNext = ((j + 1) * m_height) / gridYsteps; + m_transitionRects.push_back(QRect(xNext, yPosition, xPosition - xNext, yNext - yPosition)); + yPosition = yNext; + } + xPosition = xNext; + } + } else if (angle == 270) { + int yPosition = 0; + for (int i = 0; i < gridYsteps; i++) { + int yNext = ((i + 1) * m_height) / gridYsteps; + int xPosition = 0; + for (int j = 0; j < gridXsteps; j++) { + int xNext = ((j + 1) * m_width) / gridXsteps; + m_transitionRects.push_back(QRect(xPosition, yPosition, xNext - xPosition, yNext - yPosition)); + xPosition = xNext; + } + yPosition = yNext; + } + } else // if angle is 0 or 315 + { + int xPosition = 0; + for (int i = 0; i < gridXsteps; i++) { + int xNext = ((i + 1) * m_width) / gridXsteps; + int yPosition = 0; + for (int j = 0; j < gridYsteps; j++) { + int yNext = ((j + 1) * m_height) / gridYsteps; + m_transitionRects.push_back(QRect(xPosition, yPosition, xNext - xPosition, yNext - yPosition)); + yPosition = yNext; + } + xPosition = xNext; + } + } + // add a 'glitter' (1 over 10 pieces is randomized) + int randomSteps = steps / 20; + for (int i = 0; i < randomSteps; i++) { +#ifndef Q_OS_WIN + int n1 = (int)(steps * drand48()); + int n2 = (int)(steps * drand48()); +#else + int n1 = (int)(steps * (std::rand() / RAND_MAX)); + int n2 = (int)(steps * (std::rand() / RAND_MAX)); +#endif + // swap items if index differs + if (n1 != n2) { + QRect r = m_transitionRects[n2]; + m_transitionRects[n2] = m_transitionRects[n1]; + m_transitionRects[n1] = r; + } + } + // set global transition parameters + m_transitionMul = (angle == 90) || (angle == 270) ? gridYsteps : gridXsteps; + m_transitionMul /= 2; + m_transitionDelay = (int)((m_transitionMul * 1000 * totalTime) / steps); + } break; + + case Okular::PageTransition::Fade: { + enum { FADE_TRANSITION_FPS = 20 }; + const int steps = totalTime * FADE_TRANSITION_FPS; + m_transitionSteps = steps; + QPainter pixmapPainter; + m_currentPixmapOpacity = (double)1 / steps; + m_transitionDelay = (int)(totalTime * 1000) / steps; + m_lastRenderedPixmap = QPixmap(m_lastRenderedPixmap.size()); + m_lastRenderedPixmap.fill(Qt::transparent); + pixmapPainter.begin(&m_lastRenderedPixmap); + pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); + pixmapPainter.setOpacity(1 - m_currentPixmapOpacity); + pixmapPainter.drawPixmap(0, 0, m_previousPagePixmap); + pixmapPainter.setOpacity(m_currentPixmapOpacity); + pixmapPainter.drawPixmap(0, 0, m_currentPagePixmap); + pixmapPainter.end(); + update(); + } break; + // implement missing transitions (a binary raster engine needed here) + case Okular::PageTransition::Fly: + + case Okular::PageTransition::Push: + + case Okular::PageTransition::Cover: + + case Okular::PageTransition::Uncover: + + default: + update(); + return; + } + + // send the first start to the timer + m_transitionTimer->start(0); +} + +void PresentationWidget::slotProcessMovieAction(const Okular::MovieAction *action) +{ + const Okular::MovieAnnotation *movieAnnotation = action->annotation(); + if (!movieAnnotation) + return; + + Okular::Movie *movie = movieAnnotation->movie(); + if (!movie) + return; + + VideoWidget *vw = m_frames[m_frameIndex]->videoWidgets.value(movieAnnotation->movie()); + if (!vw) + return; + + vw->show(); + + switch (action->operation()) { + case Okular::MovieAction::Play: + vw->stop(); + vw->play(); + break; + case Okular::MovieAction::Stop: + vw->stop(); + break; + case Okular::MovieAction::Pause: + vw->pause(); + break; + case Okular::MovieAction::Resume: + vw->play(); + break; + }; +} + +void PresentationWidget::slotProcessRenditionAction(const Okular::RenditionAction *action) +{ + Okular::Movie *movie = action->movie(); + if (!movie) + return; + + VideoWidget *vw = m_frames[m_frameIndex]->videoWidgets.value(movie); + if (!vw) + return; + + if (action->operation() == Okular::RenditionAction::None) + return; + + vw->show(); + + switch (action->operation()) { + case Okular::RenditionAction::Play: + vw->stop(); + vw->play(); + break; + case Okular::RenditionAction::Stop: + vw->stop(); + break; + case Okular::RenditionAction::Pause: + vw->pause(); + break; + case Okular::RenditionAction::Resume: + vw->play(); + break; + default: + return; + }; +} + +void PresentationWidget::slotTogglePlayPause() +{ + if (!m_nextPageTimer->isActive()) { + m_advanceSlides = true; + startAutoChangeTimer(); + } else { + m_nextPageTimer->stop(); + m_advanceSlides = false; + setPlayPauseIcon(); + } +} + +#include "presentationwidget.moc" diff --git a/part/presentationwidget.h b/part/presentationwidget.h new file mode 100644 index 0000000..a2ed4e4 --- /dev/null +++ b/part/presentationwidget.h @@ -0,0 +1,194 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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_PRESENTATIONWIDGET_H_ +#define _OKULAR_PRESENTATIONWIDGET_H_ + +#include "core/area.h" +#include "core/observer.h" +#include "core/pagetransition.h" +#include +#include +#include +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) // TODO Qt6: These are needed for oldQt_screenOf(). +#include +#include +#include +#endif + +class QLineEdit; +class QToolBar; +class QTimer; +class QGestureEvent; +class KActionCollection; +class KSelectAction; +class SmoothPathEngine; +struct PresentationFrame; +class PresentationSearchBar; +class DrawingToolActions; + +namespace Okular +{ +class Action; +class Annotation; +class Document; +class MovieAction; +class Page; +class RenditionAction; +} + +/** + * @short A widget that shows pages as fullscreen slides (with transitions fx). + * + * This is a fullscreen widget that displays + */ +class PresentationWidget : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT +public: + PresentationWidget(QWidget *parent, Okular::Document *doc, DrawingToolActions *drawingToolActions, KActionCollection *collection); + ~PresentationWidget() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyViewportChanged(bool smoothMove) override; + void notifyPageChanged(int pageNumber, int changedFlags) override; + bool canUnloadPixmap(int pageNumber) const override; + void notifyCurrentPageChanged(int previous, int current) override; + +public Q_SLOTS: + void slotFind(); + +protected: + // widget events + bool event(QEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + void leaveEvent(QEvent *e) override; + bool gestureEvent(QGestureEvent *e); + + // Catch TabletEnterProximity and TabletLeaveProximity events from the QApplication + bool eventFilter(QObject *o, QEvent *ev) override; + +private: + const void *getObjectRect(Okular::ObjectRect::ObjectType type, int x, int y, QRect *geometry = nullptr) const; + const Okular::Action *getLink(int x, int y, QRect *geometry = nullptr) const; + const Okular::Annotation *getAnnotation(int x, int y, QRect *geometry = nullptr) const; + void testCursorOnLink(int x, int y); + void overlayClick(const QPoint position); + void changePage(int newPage); + void generatePage(bool disableTransition = false); + void generateIntroPage(QPainter &p); + void generateContentsPage(int page, QPainter &p); + void generateOverlay(); + void initTransition(const Okular::PageTransition *transition); + const Okular::PageTransition defaultTransition() const; + const Okular::PageTransition defaultTransition(int) const; + QRect routeMouseDrawingEvent(QMouseEvent *); + void startAutoChangeTimer(); + /** @returns Configure -> Presentation -> Preferred screen */ + QScreen *defaultScreen() const; + void requestPixmaps(); + /** @param newScreen must be valid. */ + void setScreen(const QScreen *newScreen); + void inhibitPowerManagement(); + void allowPowerManagement(); + void showTopBar(bool); + // create actions that interact with this widget + void setupActions(); + void setPlayPauseIcon(); + + // cache stuff + int m_width; + int m_height; + QPixmap m_lastRenderedPixmap; + QPixmap m_lastRenderedOverlay; + QRect m_overlayGeometry; + const Okular::Action *m_pressedLink; + bool m_handCursor; + SmoothPathEngine *m_drawingEngine; + QRect m_drawingRect; + uint m_screenInhibitCookie; + int m_sleepInhibitFd; + + // transition related + QTimer *m_transitionTimer; + QTimer *m_overlayHideTimer; + QTimer *m_nextPageTimer; + int m_transitionDelay; + int m_transitionMul; + int m_transitionSteps; + QList m_transitionRects; + Okular::PageTransition m_currentTransition; + QPixmap m_currentPagePixmap; + QPixmap m_previousPagePixmap; + double m_currentPixmapOpacity; + + // misc stuff + QWidget *m_parentWidget; + Okular::Document *m_document; + QVector m_frames; + int m_frameIndex; + QStringList m_metaStrings; + QToolBar *m_topBar; + QLineEdit *m_pagesEdit; + PresentationSearchBar *m_searchBar; + KActionCollection *m_ac; + KSelectAction *m_screenSelect; + QDomElement m_currentDrawingToolElement; + bool m_isSetup; + bool m_blockNotifications; + bool m_inBlackScreenMode; + bool m_showSummaryView; + bool m_advanceSlides; + bool m_goToPreviousPageOnRelease; + bool m_goToNextPageOnRelease; + + /** TODO Qt6: Just use QWidget::screen() instead of this. */ + static inline QScreen *oldQt_screenOf(const QWidget *widget) + { +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + return widget->screen(); +#else + if (widget->window() && widget->window()->windowHandle() && widget->window()->windowHandle()->screen()) { + return widget->window()->windowHandle()->screen(); + } else { + return QApplication::primaryScreen(); + } +#endif + } + +private Q_SLOTS: + void slotNextPage(); + void slotPrevPage(); + void slotFirstPage(); + void slotLastPage(); + void slotHideOverlay(); + void slotTransitionStep(); + void slotDelayedEvents(); + void slotPageChanged(); + void clearDrawings(); + void chooseScreen(QAction *); + void toggleBlackScreenMode(bool); + void slotProcessMovieAction(const Okular::MovieAction *action); + void slotProcessRenditionAction(const Okular::RenditionAction *action); + void slotTogglePlayPause(); + void slotChangeDrawingToolEngine(const QDomElement &element); + void slotAddDrawingToolActions(); +}; + +#endif diff --git a/part/priorities.h b/part/priorities.h new file mode 100644 index 0000000..a3cf2ff --- /dev/null +++ b/part/priorities.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (C) 2013 by Albert Astals Cid * + * * + * 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 PRIORITIES_H +#define PRIORITIES_H + +/** PRIORITIES for requests. Globally defined here. **/ +#define PAGEVIEW_PRIO 1 +#define PAGEVIEW_PRELOAD_PRIO 4 +#define THUMBNAILS_PRIO 2 +#define THUMBNAILS_PRELOAD_PRIO 5 +#define PRESENTATION_PRIO 0 +#define PRESENTATION_PRELOAD_PRIO 3 + +#endif diff --git a/part/propertiesdialog.cpp b/part/propertiesdialog.cpp new file mode 100644 index 0000000..08c25a8 --- /dev/null +++ b/part/propertiesdialog.cpp @@ -0,0 +1,506 @@ +/*************************************************************************** + * Copyright (C) 2004 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "propertiesdialog.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// local includes +#include "core/document.h" + +static const int IsExtractableRole = Qt::UserRole; +static const int FontInfoRole = Qt::UserRole + 1; + +PropertiesDialog::PropertiesDialog(QWidget *parent, Okular::Document *doc) + : KPageDialog(parent) + , m_document(doc) + , m_fontPage(nullptr) + , m_fontModel(nullptr) + , m_pageSizesModel(nullptr) + , m_fontInfo(nullptr) + , m_fontProgressBar(nullptr) + , m_fontScanStarted(false) +{ + setFaceType(Tabbed); + setWindowTitle(i18n("Unknown File")); + setStandardButtons(QDialogButtonBox::Ok); + + // PROPERTIES + QFrame *page = new QFrame(); + KPageWidgetItem *item = addPage(page, i18n("&Properties")); + item->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); + + // get document info + const Okular::DocumentInfo info = doc->documentInfo(); + QFormLayout *layout = new QFormLayout(page); + + // mime name based on mimetype id + QString mimeName = info.get(Okular::DocumentInfo::MimeType).section(QLatin1Char('/'), -1).toUpper(); + setWindowTitle(i18n("%1 Properties", mimeName)); + + /* obtains the properties list, conveniently ordered */ + QStringList orderedProperties; + orderedProperties << Okular::DocumentInfo::getKeyString(Okular::DocumentInfo::FilePath) << Okular::DocumentInfo::getKeyString(Okular::DocumentInfo::PagesSize) << Okular::DocumentInfo::getKeyString(Okular::DocumentInfo::DocumentSize); + for (Okular::DocumentInfo::Key ks = Okular::DocumentInfo::Title; ks <= Okular::DocumentInfo::Keywords; ks = Okular::DocumentInfo::Key(ks + 1)) { + orderedProperties << Okular::DocumentInfo::getKeyString(ks); + } + const QStringList infoKeys = info.keys(); + for (const QString &ks : infoKeys) { + if (!orderedProperties.contains(ks)) { + orderedProperties << ks; + } + } + + for (const QString &key : qAsConst(orderedProperties)) { + const QString titleString = info.getKeyTitle(key); + const QString valueString = info.get(key); + if (titleString.isNull() || valueString.isNull()) + continue; + + // create labels and layout them + QWidget *value = nullptr; + if (key == Okular::DocumentInfo::getKeyString(Okular::DocumentInfo::MimeType)) { + /// for mime type fields, show icon as well + value = new QWidget(page); + /// place icon left of mime type's name + QHBoxLayout *hboxLayout = new QHBoxLayout(value); + hboxLayout->setContentsMargins(0, 0, 0, 0); + /// retrieve icon and place it in a QLabel + QMimeDatabase db; + QMimeType mimeType = db.mimeTypeForName(valueString); + KSqueezedTextLabel *squeezed; + if (mimeType.isValid()) { + /// retrieve icon and place it in a QLabel + QLabel *pixmapLabel = new QLabel(value); + hboxLayout->addWidget(pixmapLabel, 0); + const QIcon icon = QIcon::fromTheme(mimeType.iconName(), QIcon::fromTheme(QStringLiteral("application-octet-stream"))); + pixmapLabel->setPixmap(icon.pixmap(KIconLoader::SizeSmall)); + /// mime type's name and label + squeezed = new KSqueezedTextLabel(i18nc("mimetype information, example: \"PDF Document (application/pdf)\"", "%1 (%2)", mimeType.comment(), valueString), value); + } else { + /// only mime type name + squeezed = new KSqueezedTextLabel(valueString, value); + } + squeezed->setTextInteractionFlags(Qt::TextSelectableByMouse); + hboxLayout->addWidget(squeezed, 1); + } else { + /// default for any other document information + KSqueezedTextLabel *label = new KSqueezedTextLabel(valueString, page); + label->setTextInteractionFlags(Qt::TextSelectableByMouse); + value = label; + } + layout->addRow(new QLabel(i18n("%1:", titleString)), value); + } + + // FONTS + if (doc->canProvideFontInformation()) { + // create fonts tab and layout it + QFrame *page2 = new QFrame(); + m_fontPage = addPage(page2, i18n("&Fonts")); + m_fontPage->setIcon(QIcon::fromTheme(QStringLiteral("dialog-text-and-font"))); + QVBoxLayout *page2Layout = new QVBoxLayout(page2); + // add a tree view + QTreeView *view = new QTreeView(page2); + view->setContextMenuPolicy(Qt::CustomContextMenu); + connect(view, &QTreeView::customContextMenuRequested, this, &PropertiesDialog::showFontsMenu); + page2Layout->addWidget(view); + view->setRootIsDecorated(false); + view->setAlternatingRowColors(true); + view->setSortingEnabled(true); + // creating a proxy model so we can sort the data + QSortFilterProxyModel *proxymodel = new QSortFilterProxyModel(view); + proxymodel->setDynamicSortFilter(true); + proxymodel->setSortCaseSensitivity(Qt::CaseInsensitive); + m_fontModel = new FontsListModel(view); + proxymodel->setSourceModel(m_fontModel); + view->setModel(proxymodel); + view->sortByColumn(0, Qt::AscendingOrder); + m_fontInfo = new QLabel(this); + page2Layout->addWidget(m_fontInfo); + m_fontInfo->setText(i18n("Reading font information...")); + m_fontInfo->hide(); + m_fontProgressBar = new QProgressBar(this); + page2Layout->addWidget(m_fontProgressBar); + m_fontProgressBar->setRange(0, 100); + m_fontProgressBar->setValue(0); + m_fontProgressBar->hide(); + } + + // PAGE SIZES + if (!m_document->allPagesSize().isValid()) { + // create page sizes tab tab and layout it when there are multiple page sizes + QFrame *page3 = new QFrame(); + KPageWidgetItem *pageSizesPage = addPage(page3, i18n("&Page Sizes")); + pageSizesPage->setIcon(QIcon::fromTheme(QStringLiteral("view-pages-overview"))); + QVBoxLayout *page3Layout = new QVBoxLayout(page3); + + // Add a table view + QTableView *view = new QTableView(page3); + m_pageSizesModel = new PageSizesModel(view, m_document); + page3Layout->addWidget(view); + view->setModel(m_pageSizesModel); + view->setAlternatingRowColors(true); + view->setCornerButtonEnabled(false); + view->resizeColumnsToContents(); + view->verticalHeader()->hide(); + + // Stretch the last column, which is the widest + QHeaderView *headerView = view->horizontalHeader(); + headerView->setSectionResizeMode(0, QHeaderView::Interactive); + headerView->setSectionResizeMode(1, QHeaderView::Stretch); + } + + // KPageDialog is a bit buggy, it doesn't fix its own sizeHint, so we have to manually resize + resize(layout->sizeHint()); + + connect(pageWidget(), QOverload::of(&KPageWidget::currentPageChanged), this, &PropertiesDialog::pageChanged); +} + +PropertiesDialog::~PropertiesDialog() +{ + m_document->stopFontReading(); +} + +void PropertiesDialog::pageChanged(KPageWidgetItem *current, KPageWidgetItem *) +{ + if (current == m_fontPage && !m_fontScanStarted) { + connect(m_document, &Okular::Document::gotFont, m_fontModel, &FontsListModel::addFont); + connect(m_document, &Okular::Document::fontReadingProgress, this, &PropertiesDialog::slotFontReadingProgress); + connect(m_document, &Okular::Document::fontReadingEnded, this, &PropertiesDialog::slotFontReadingEnded); + QTimer::singleShot(0, this, &PropertiesDialog::reallyStartFontReading); + + m_fontScanStarted = true; + } +} + +void PropertiesDialog::slotFontReadingProgress(int page) +{ + m_fontProgressBar->setValue(m_fontProgressBar->maximum() * (page + 1) / m_document->pages()); +} + +void PropertiesDialog::slotFontReadingEnded() +{ + m_fontInfo->hide(); + m_fontProgressBar->hide(); +} + +void PropertiesDialog::reallyStartFontReading() +{ + m_fontInfo->show(); + m_fontProgressBar->show(); + m_document->startFontReading(); +} + +void PropertiesDialog::showFontsMenu(const QPoint pos) +{ + QTreeView *view = static_cast(sender()); + QModelIndex index = view->indexAt(pos); + if (index.data(IsExtractableRole).toBool()) { + QMenu *menu = new QMenu(this); + menu->addAction(i18nc("@action:inmenu", "&Extract Font")); + QAction *result = menu->exec(view->viewport()->mapToGlobal(pos)); + if (result) { + Okular::FontInfo fi = index.data(FontInfoRole).value(); + const QString caption = i18n("Where do you want to save %1?", fi.name()); + const QString path = QFileDialog::getSaveFileName(this, caption, fi.name()); + if (path.isEmpty()) + return; + + QFile f(path); + if (f.open(QIODevice::WriteOnly)) { + f.write(m_document->fontData(fi)); + f.close(); + } else { + KMessageBox::error(this, i18n("Could not open \"%1\" for writing. File was not saved.", path)); + } + } + } +} + +FontsListModel::FontsListModel(QObject *parent) + : QAbstractTableModel(parent) +{ +} + +FontsListModel::~FontsListModel() +{ +} + +void FontsListModel::addFont(const Okular::FontInfo &fi) +{ + beginInsertRows(QModelIndex(), m_fonts.size(), m_fonts.size()); + + m_fonts << fi; + + endInsertRows(); +} + +int FontsListModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : 3; +} + +static QString descriptionForFontType(Okular::FontInfo::FontType type) +{ + switch (type) { + case Okular::FontInfo::Type1: + return i18n("Type 1"); + break; + case Okular::FontInfo::Type1C: + return i18n("Type 1C"); + break; + case Okular::FontInfo::Type1COT: + return i18nc("OT means OpenType", "Type 1C (OT)"); + break; + case Okular::FontInfo::Type3: + return i18n("Type 3"); + break; + case Okular::FontInfo::TrueType: + return i18n("TrueType"); + break; + case Okular::FontInfo::TrueTypeOT: + return i18nc("OT means OpenType", "TrueType (OT)"); + break; + case Okular::FontInfo::CIDType0: + return i18n("CID Type 0"); + break; + case Okular::FontInfo::CIDType0C: + return i18n("CID Type 0C"); + break; + case Okular::FontInfo::CIDType0COT: + return i18nc("OT means OpenType", "CID Type 0C (OT)"); + break; + case Okular::FontInfo::CIDTrueType: + return i18n("CID TrueType"); + break; + case Okular::FontInfo::CIDTrueTypeOT: + return i18nc("OT means OpenType", "CID TrueType (OT)"); + break; + case Okular::FontInfo::TeXPK: + return i18n("TeX PK"); + break; + case Okular::FontInfo::TeXVirtual: + return i18n("TeX virtual"); + break; + case Okular::FontInfo::TeXFontMetric: + return i18n("TeX Font Metric"); + break; + case Okular::FontInfo::TeXFreeTypeHandled: + return i18n("TeX FreeType-handled"); + break; + case Okular::FontInfo::Unknown: + return i18nc("Unknown font type", "Unknown"); + break; + } + return QString(); +} + +static QString pathOrDescription(const Okular::FontInfo &font) +{ + switch (font.embedType()) { + case Okular::FontInfo::NotEmbedded: + return font.file(); + break; + case Okular::FontInfo::EmbeddedSubset: + return i18n("Embedded (subset)"); + break; + case Okular::FontInfo::FullyEmbedded: + return i18n("Fully embedded"); + break; + } + return QString(); +} + +static QString descriptionForEmbedType(Okular::FontInfo::EmbedType type) +{ + switch (type) { + case Okular::FontInfo::NotEmbedded: + return i18n("No"); + break; + case Okular::FontInfo::EmbeddedSubset: + return i18n("Yes (subset)"); + break; + case Okular::FontInfo::FullyEmbedded: + return i18n("Yes"); + break; + } + return QString(); +} + +QVariant FontsListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() >= m_fonts.count()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case 0: { + const Okular::FontInfo &fi = m_fonts.at(index.row()); + const QString fontname = fi.name(); + const QString substituteName = fi.substituteName(); + if (fi.embedType() == Okular::FontInfo::NotEmbedded && !substituteName.isEmpty() && !fontname.isEmpty() && substituteName != fontname) { + return i18nc("Replacing missing font with another one", "%1 (substituting with %2)", fontname, substituteName); + } + return fontname.isEmpty() ? i18nc("font name not available (empty)", "[n/a]") : fontname; + break; + } + case 1: + return descriptionForFontType(m_fonts.at(index.row()).type()); + break; + case 2: + return pathOrDescription(m_fonts.at(index.row())); + break; + } + break; + case Qt::ToolTipRole: { + QString fontname = m_fonts.at(index.row()).name(); + if (fontname.isEmpty()) + fontname = i18n("Unknown font"); + QString tooltip = QLatin1String("") + fontname + QLatin1String(""); + if (m_fonts.at(index.row()).embedType() == Okular::FontInfo::NotEmbedded) + tooltip += QStringLiteral(" (%2)").arg(fontname, fontname); + tooltip += QLatin1String("
") + i18n("Embedded: %1", descriptionForEmbedType(m_fonts.at(index.row()).embedType())); + tooltip += QLatin1String(""); + return tooltip; + break; + } + case IsExtractableRole: { + return m_fonts.at(index.row()).canBeExtracted(); + } + case FontInfoRole: { + QVariant v; + v.setValue(m_fonts.at(index.row())); + return v; + } + } + + return QVariant(); +} + +QVariant FontsListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal) + return QVariant(); + + if (role == Qt::TextAlignmentRole) + return QVariant(Qt::AlignLeft); + + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return i18n("Name"); + break; + case 1: + return i18n("Type"); + break; + case 2: + return i18n("File"); + break; + default: + return QVariant(); + } +} + +int FontsListModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : m_fonts.size(); +} + +PageSizesModel::PageSizesModel(QObject *parent, Okular::Document *doc) + : QAbstractTableModel(parent) + , m_document(doc) +{ +} + +PageSizesModel::~PageSizesModel() +{ +} + +int PageSizesModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : 2; +} + +QVariant PageSizesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() >= (int)m_document->pages()) + return QVariant(); + + switch (index.column()) { + case 0: { + if (role == Qt::DisplayRole) + return index.row() + 1; // Page zero doesn't make sense to the user + else if (role == Qt::TextAlignmentRole) + return Qt::AlignCenter; + break; + } + case 1: + if (role == Qt::DisplayRole) + return m_document->pageSizeString(index.row()); + break; + } + + return QVariant(); +} + +QVariant PageSizesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal) + return QVariant(); + + if (role == Qt::TextAlignmentRole) + return QVariant(Qt::AlignLeft); + + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return i18n("Page"); + break; + case 1: + return i18n("Size"); + break; + default: + return QVariant(); + } +} + +int PageSizesModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : m_document->pages(); +} + +#include "moc_propertiesdialog.cpp" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/propertiesdialog.h b/part/propertiesdialog.h new file mode 100644 index 0000000..fd537b2 --- /dev/null +++ b/part/propertiesdialog.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2004 by Albert Astals Cid * + * * + * 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 _PROPERTIESDIALOG_H_ +#define _PROPERTIESDIALOG_H_ + +#include +#include + +#include + +#include "core/fontinfo.h" + +class QLabel; +class QProgressBar; +class FontsListModel; +class PageSizesModel; + +namespace Okular +{ +class Document; +} + +class PropertiesDialog : public KPageDialog +{ + Q_OBJECT + +public: + PropertiesDialog(QWidget *parent, Okular::Document *doc); + ~PropertiesDialog() override; + +private Q_SLOTS: + void pageChanged(KPageWidgetItem *, KPageWidgetItem *); + void slotFontReadingProgress(int page); + void slotFontReadingEnded(); + void reallyStartFontReading(); + void showFontsMenu(const QPoint pos); + +private: + Okular::Document *m_document; + KPageWidgetItem *m_fontPage; + FontsListModel *m_fontModel; + PageSizesModel *m_pageSizesModel; + QLabel *m_fontInfo; + QProgressBar *m_fontProgressBar; + bool m_fontScanStarted; +}; + +class FontsListModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit FontsListModel(QObject *parent = nullptr); + ~FontsListModel() override; + + // reimplementations from QAbstractTableModel + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + +public Q_SLOTS: + void addFont(const Okular::FontInfo &fi); + +private: + QList m_fonts; +}; + +class PageSizesModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit PageSizesModel(QObject *parent = nullptr, Okular::Document *doc = nullptr); + ~PageSizesModel() override; + + // reimplementations from QAbstractTableModel + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + +private: + Okular::Document *m_document; +}; + +#endif + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/revisionviewer.cpp b/part/revisionviewer.cpp new file mode 100644 index 0000000..ccef3bb --- /dev/null +++ b/part/revisionviewer.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "revisionviewer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fileprinterpreview.h" + +class RevisionPreview : public Okular::FilePrinterPreview +{ + Q_OBJECT + +public: + explicit RevisionPreview(const QString &revisionFile, QWidget *parent = nullptr); + +private Q_SLOTS: + void doSave(); + +private: + QString m_filename; +}; + +RevisionPreview::RevisionPreview(const QString &revisionFile, QWidget *parent) + : FilePrinterPreview(revisionFile, parent) + , m_filename(revisionFile) +{ + setWindowTitle(i18n("Revision Preview")); + + QDialogButtonBox *btnBox = findChild(); + auto saveBtn = new QPushButton(i18n("Save As"), this); + btnBox->addButton(saveBtn, QDialogButtonBox::ActionRole); + connect(saveBtn, &QPushButton::clicked, this, &RevisionPreview::doSave); +} + +void RevisionPreview::doSave() +{ + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForFile(m_filename); + const QString caption = i18n("Where do you want to save this revision?"); + const QString path = QFileDialog::getSaveFileName(this, caption, QStringLiteral("Revision"), mime.filterString()); + if (!path.isEmpty() && !QFile::copy(m_filename, path)) { + KMessageBox::error(this, i18n("Could not save file %1.", path)); + return; + } +} + +RevisionViewer::RevisionViewer(const QByteArray &revisionData, QWidget *parent) + : QObject(parent) + , m_parent(parent) + , m_revisionData(revisionData) +{ +} + +void RevisionViewer::viewRevision() +{ + QMimeDatabase db; + const QMimeType mime = db.mimeTypeForData(m_revisionData); + const QString tempDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation); + QTemporaryFile tf(tempDir + QStringLiteral("/okular_revision_XXXXXX.%1").arg(mime.suffixes().constFirst())); + if (!tf.open()) { + KMessageBox::error(m_parent, i18n("Could not view revision.")); + return; + } + tf.write(m_revisionData); + RevisionPreview previewdlg(tf.fileName(), m_parent); + previewdlg.exec(); +} + +#include "revisionviewer.moc" diff --git a/part/revisionviewer.h b/part/revisionviewer.h new file mode 100644 index 0000000..f22f013 --- /dev/null +++ b/part/revisionviewer.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_REVISIONVIEWER_H +#define OKULAR_REVISIONVIEWER_H + +#include +#include + +class QWidget; + +class RevisionViewer : public QObject +{ + Q_OBJECT + +public: + explicit RevisionViewer(const QByteArray &revisionData, QWidget *parent = nullptr); + +public Q_SLOTS: + void viewRevision(); + +private: + QWidget *m_parent; + QByteArray m_revisionData; +}; + +#endif diff --git a/part/searchlineedit.cpp b/part/searchlineedit.cpp new file mode 100644 index 0000000..6e08a6b --- /dev/null +++ b/part/searchlineedit.cpp @@ -0,0 +1,309 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2007, 2009-2010 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. * + ***************************************************************************/ + +#include "searchlineedit.h" + +// local includes + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include + +SearchLineEdit::SearchLineEdit(QWidget *parent, Okular::Document *document) + : KLineEdit(parent) + , m_document(document) + , m_minLength(0) + , m_caseSensitivity(Qt::CaseInsensitive) + , m_searchType(Okular::Document::AllDocument) + , m_id(-1) + , m_moveViewport(false) + , m_changed(false) + , m_fromStart(true) + , m_findAsYouType(true) + , m_searchRunning(false) +{ + setObjectName(QStringLiteral("SearchLineEdit")); + setClearButtonEnabled(true); + + // a timer to ensure that we don't flood the document with requests to search + m_inputDelayTimer = new QTimer(this); + m_inputDelayTimer->setSingleShot(true); + connect(m_inputDelayTimer, &QTimer::timeout, this, &SearchLineEdit::startSearch); + + connect(this, &SearchLineEdit::textChanged, this, &SearchLineEdit::slotTextChanged); + connect(document, &Okular::Document::searchFinished, this, &SearchLineEdit::searchFinished); +} + +void SearchLineEdit::clearText() +{ + clear(); +} + +void SearchLineEdit::setSearchCaseSensitivity(Qt::CaseSensitivity cs) +{ + m_caseSensitivity = cs; + m_changed = true; +} + +void SearchLineEdit::setSearchMinimumLength(int length) +{ + m_minLength = length; + m_changed = true; +} + +void SearchLineEdit::setSearchType(Okular::Document::SearchType type) +{ + if (type == m_searchType) + return; + + disconnect(this, &SearchLineEdit::returnPressed, this, &SearchLineEdit::slotReturnPressed); + + m_searchType = type; + + // Only connect Enter for next/prev searches, the rest of searches are document global so + // next/prev search does not make sense for them + if (m_searchType == Okular::Document::NextMatch || m_searchType == Okular::Document::PreviousMatch) { + connect(this, &SearchLineEdit::returnPressed, this, &SearchLineEdit::slotReturnPressed); + } + + if (!m_changed) + m_changed = (m_searchType != Okular::Document::NextMatch && m_searchType != Okular::Document::PreviousMatch); +} + +void SearchLineEdit::setSearchId(int id) +{ + m_id = id; + m_changed = true; +} + +void SearchLineEdit::setSearchColor(const QColor &color) +{ + m_color = color; + m_changed = true; +} + +void SearchLineEdit::setSearchMoveViewport(bool move) +{ + m_moveViewport = move; +} + +void SearchLineEdit::setSearchFromStart(bool fromStart) +{ + m_fromStart = fromStart; +} + +void SearchLineEdit::setFindAsYouType(bool findAsYouType) +{ + m_findAsYouType = findAsYouType; +} + +void SearchLineEdit::resetSearch() +{ + // Stop the currently running search, if any + stopSearch(); + + // Clear highlights + if (m_id != -1) + m_document->resetSearch(m_id); + + // Make sure that the search will be reset at the next one + m_changed = true; + + // Reset input box color + prepareLineEditForSearch(); +} + +bool SearchLineEdit::isSearchRunning() const +{ + return m_searchRunning; +} + +void SearchLineEdit::restartSearch() +{ + m_inputDelayTimer->stop(); + m_inputDelayTimer->start(700); + m_changed = true; +} + +void SearchLineEdit::stopSearch() +{ + if (m_id == -1 || !m_searchRunning) + return; + + m_inputDelayTimer->stop(); + // ### this should just cancel the search with id m_id, not all of them + m_document->cancelSearch(); + // flagging as "changed" so the search will be reset at the next one + m_changed = true; +} + +void SearchLineEdit::findNext() +{ + if (m_id == -1 || m_searchType != Okular::Document::NextMatch) + return; + + if (!m_changed) { + emit searchStarted(); + m_searchRunning = true; + m_document->continueSearch(m_id, m_searchType); + } else + startSearch(); +} + +void SearchLineEdit::findPrev() +{ + if (m_id == -1 || m_searchType != Okular::Document::PreviousMatch) + return; + + if (!m_changed) { + emit searchStarted(); + m_searchRunning = true; + m_document->continueSearch(m_id, m_searchType); + } else + startSearch(); +} + +void SearchLineEdit::slotTextChanged(const QString &text) +{ + Q_UNUSED(text); + + prepareLineEditForSearch(); + + if (m_findAsYouType) + restartSearch(); + else + m_changed = true; +} + +void SearchLineEdit::prepareLineEditForSearch() +{ + QPalette pal = palette(); + const int textLength = text().length(); + if (textLength > 0 && textLength < m_minLength) { + const KColorScheme scheme(QPalette::Active, KColorScheme::View); + pal.setBrush(QPalette::Base, scheme.background(KColorScheme::NegativeBackground)); + pal.setBrush(QPalette::Text, scheme.foreground(KColorScheme::NegativeText)); + } else { + const QPalette qAppPalette = QApplication::palette(); + pal.setColor(QPalette::Base, qAppPalette.color(QPalette::Base)); + pal.setColor(QPalette::Text, qAppPalette.color(QPalette::Text)); + } + setPalette(pal); +} + +void SearchLineEdit::slotReturnPressed(const QString &text) +{ + Q_UNUSED(text); + + m_inputDelayTimer->stop(); + prepareLineEditForSearch(); + if (QApplication::keyboardModifiers() == Qt::ShiftModifier) { + m_searchType = Okular::Document::PreviousMatch; + findPrev(); + } else { + m_searchType = Okular::Document::NextMatch; + findNext(); + } +} + +void SearchLineEdit::startSearch() +{ + if (m_id == -1 || !m_color.isValid()) + return; + + if (m_changed && (m_searchType == Okular::Document::NextMatch || m_searchType == Okular::Document::PreviousMatch)) { + m_document->resetSearch(m_id); + } + m_changed = false; + // search text if have more than 3 chars or else clear search + QString thistext = text(); + if (thistext.length() >= qMax(m_minLength, 1)) { + emit searchStarted(); + m_searchRunning = true; + m_document->searchText(m_id, thistext, m_fromStart, m_caseSensitivity, m_searchType, m_moveViewport, m_color); + } else + m_document->resetSearch(m_id); +} + +void SearchLineEdit::searchFinished(int id, Okular::Document::SearchStatus endStatus) +{ + // ignore the searches not started by this search edit + if (id != m_id) + return; + + // if not found, use warning colors + if (endStatus == Okular::Document::NoMatchFound) { + QPalette pal = palette(); + const KColorScheme scheme(QPalette::Active, KColorScheme::View); + pal.setBrush(QPalette::Base, scheme.background(KColorScheme::NegativeBackground)); + pal.setBrush(QPalette::Text, scheme.foreground(KColorScheme::NegativeText)); + setPalette(pal); + } else { + QPalette pal = palette(); + const QPalette qAppPalette = QApplication::palette(); + pal.setColor(QPalette::Base, qAppPalette.color(QPalette::Base)); + pal.setColor(QPalette::Text, qAppPalette.color(QPalette::Text)); + setPalette(pal); + } + + m_searchRunning = false; + emit searchStopped(); +} + +SearchLineWidget::SearchLineWidget(QWidget *parent, Okular::Document *document) + : QWidget(parent) +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + + m_edit = new SearchLineEdit(this, document); + layout->addWidget(m_edit); + + m_anim = new KBusyIndicatorWidget(this); + m_anim->setFixedSize(22, 22); + layout->addWidget(m_anim); + m_anim->hide(); + + m_timer = new QTimer(this); + m_timer->setSingleShot(true); + connect(m_timer, &QTimer::timeout, this, &SearchLineWidget::slotTimedout); + + connect(m_edit, &SearchLineEdit::searchStarted, this, &SearchLineWidget::slotSearchStarted); + connect(m_edit, &SearchLineEdit::searchStopped, this, &SearchLineWidget::slotSearchStopped); +} + +SearchLineEdit *SearchLineWidget::lineEdit() const +{ + return m_edit; +} + +void SearchLineWidget::slotSearchStarted() +{ + m_timer->start(100); +} + +void SearchLineWidget::slotSearchStopped() +{ + m_timer->stop(); + m_anim->hide(); +} + +void SearchLineWidget::slotTimedout() +{ + m_anim->show(); +} + +#include "moc_searchlineedit.cpp" diff --git a/part/searchlineedit.h b/part/searchlineedit.h new file mode 100644 index 0000000..62b55bd --- /dev/null +++ b/part/searchlineedit.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * Copyright (C) 2007, 2009-2010 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_SEARCHLINEEDIT_H_ +#define _OKULAR_SEARCHLINEEDIT_H_ + +#include "core/document.h" + +#include + +#include +class KBusyIndicatorWidget; +class QTimer; + +/** + * @short A line edit for find-as-you-type search. Outputs to the Document. + */ +class SearchLineEdit : public KLineEdit +{ + Q_OBJECT +public: + SearchLineEdit(QWidget *parent, Okular::Document *document); + + void clearText(); + + void setSearchCaseSensitivity(Qt::CaseSensitivity cs); + void setSearchMinimumLength(int length); + void setSearchType(Okular::Document::SearchType type); + void setSearchId(int id); + void setSearchColor(const QColor &color); + void setSearchMoveViewport(bool move); + void setSearchFromStart(bool fromStart); + void setFindAsYouType(bool findAsYouType); + void resetSearch(); + + bool isSearchRunning() const; + +Q_SIGNALS: + void searchStarted(); + void searchStopped(); + +public Q_SLOTS: + void restartSearch(); + void stopSearch(); + void findNext(); + void findPrev(); + +private: + void prepareLineEditForSearch(); + + Okular::Document *m_document; + QTimer *m_inputDelayTimer; + int m_minLength; + Qt::CaseSensitivity m_caseSensitivity; + Okular::Document::SearchType m_searchType; + int m_id; + QColor m_color; + bool m_moveViewport; + bool m_changed; + bool m_fromStart; + bool m_findAsYouType; + bool m_searchRunning; + +private Q_SLOTS: + void slotTextChanged(const QString &text); + void slotReturnPressed(const QString &text); + void startSearch(); + void searchFinished(int id, Okular::Document::SearchStatus endStatus); +}; + +class SearchLineWidget : public QWidget +{ + Q_OBJECT +public: + SearchLineWidget(QWidget *parent, Okular::Document *document); + + SearchLineEdit *lineEdit() const; + +private Q_SLOTS: + void slotSearchStarted(); + void slotSearchStopped(); + void slotTimedout(); + +private: + SearchLineEdit *m_edit; + KBusyIndicatorWidget *m_anim; + QTimer *m_timer; +}; + +#endif diff --git a/part/searchwidget.cpp b/part/searchwidget.cpp new file mode 100644 index 0000000..0018508 --- /dev/null +++ b/part/searchwidget.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "searchwidget.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "searchlineedit.h" + +SearchWidget::SearchWidget(QWidget *parent, Okular::Document *document) + : QWidget(parent) +{ + setObjectName(QStringLiteral("iSearchBar")); + + QSizePolicy sp = sizePolicy(); + sp.setVerticalPolicy(QSizePolicy::Minimum); + setSizePolicy(sp); + + QHBoxLayout *mainlay = new QHBoxLayout(this); + mainlay->setContentsMargins(0, 0, 0, 0); + mainlay->setSpacing(3); + + // 2. text line + m_lineEdit = new SearchLineEdit(this, document); + m_lineEdit->setClearButtonEnabled(true); + m_lineEdit->setPlaceholderText(i18n("Search...")); + m_lineEdit->setToolTip(i18n("Enter at least 3 letters to filter pages")); + m_lineEdit->setSearchCaseSensitivity(Qt::CaseInsensitive); + m_lineEdit->setSearchMinimumLength(3); + m_lineEdit->setSearchType(Okular::Document::GoogleAll); + m_lineEdit->setSearchId(SW_SEARCH_ID); + m_lineEdit->setSearchColor(qRgb(0, 183, 255)); + mainlay->addWidget(m_lineEdit); + + // 3.1. create the popup menu for changing filtering features + m_menu = new QMenu(this); + m_caseSensitiveAction = m_menu->addAction(i18n("Case Sensitive")); + m_menu->addSeparator(); + m_matchPhraseAction = m_menu->addAction(i18n("Match Phrase")); + m_marchAllWordsAction = m_menu->addAction(i18n("Match All Words")); + m_marchAnyWordsAction = m_menu->addAction(i18n("Match Any Word")); + + m_caseSensitiveAction->setCheckable(true); + QActionGroup *actgrp = new QActionGroup(this); + m_matchPhraseAction->setCheckable(true); + m_matchPhraseAction->setActionGroup(actgrp); + m_marchAllWordsAction->setCheckable(true); + m_marchAllWordsAction->setActionGroup(actgrp); + m_marchAnyWordsAction->setCheckable(true); + m_marchAnyWordsAction->setActionGroup(actgrp); + + m_marchAllWordsAction->setChecked(true); + connect(m_menu, &QMenu::triggered, this, &SearchWidget::slotMenuChaged); + + // 3.2. create the toolbar button that spawns the popup menu + QToolButton *optionsMenuAction = new QToolButton(this); + mainlay->addWidget(optionsMenuAction); + optionsMenuAction->setAutoRaise(true); + optionsMenuAction->setIcon(QIcon::fromTheme(QStringLiteral("view-filter"))); + optionsMenuAction->setToolTip(i18n("Filter Options")); + optionsMenuAction->setPopupMode(QToolButton::InstantPopup); + optionsMenuAction->setMenu(m_menu); +} + +void SearchWidget::clearText() +{ + m_lineEdit->clear(); +} + +void SearchWidget::slotMenuChaged(QAction *act) +{ + // update internal variables and checked state + if (act == m_caseSensitiveAction) { + m_lineEdit->setSearchCaseSensitivity(m_caseSensitiveAction->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive); + } else if (act == m_matchPhraseAction) { + m_lineEdit->setSearchType(Okular::Document::AllDocument); + } else if (act == m_marchAllWordsAction) { + m_lineEdit->setSearchType(Okular::Document::GoogleAll); + } else if (act == m_marchAnyWordsAction) { + m_lineEdit->setSearchType(Okular::Document::GoogleAny); + } else + return; + + // update search + m_lineEdit->restartSearch(); +} + +#include "moc_searchwidget.cpp" diff --git a/part/searchwidget.h b/part/searchwidget.h new file mode 100644 index 0000000..2958fbe --- /dev/null +++ b/part/searchwidget.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2004 by Enrico Ros * + * * + * 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_SEARCHWIDGET_H_ +#define _OKULAR_SEARCHWIDGET_H_ + +#include + +namespace Okular +{ +class Document; +} + +class QAction; +class QMenu; + +class SearchLineEdit; + +/** + * @short A widget for find-as-you-type search. Outputs to the Document. + * + * This widget accepts keyboard input and performs a call to findTextAll(..) + * in the Okular::Document class when there are 3 or more chars to search for. + * It supports case sensitive/unsensitive(default) and provides a button + * for switching between the 2 modes. + */ +class SearchWidget : public QWidget +{ + Q_OBJECT +public: + SearchWidget(QWidget *parent, Okular::Document *document); + void clearText(); + +private: + QMenu *m_menu; + QAction *m_matchPhraseAction, *m_caseSensitiveAction, *m_marchAllWordsAction, *m_marchAnyWordsAction; + SearchLineEdit *m_lineEdit; + +private Q_SLOTS: + void slotMenuChaged(QAction *); +}; + +#endif diff --git a/part/side_reviews.cpp b/part/side_reviews.cpp new file mode 100644 index 0000000..476fdbf --- /dev/null +++ b/part/side_reviews.cpp @@ -0,0 +1,309 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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. * + ***************************************************************************/ + +#include "side_reviews.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// local includes +#include "annotationmodel.h" +#include "annotationpopup.h" +#include "annotationproxymodels.h" +#include "core/annotations.h" +#include "core/document.h" +#include "core/page.h" +#include "ktreeviewsearchline.h" +#include "settings.h" + +class TreeView : public QTreeView +{ + Q_OBJECT + +public: + TreeView(Okular::Document *document, QWidget *parent = Q_NULLPTR) + : QTreeView(parent) + , m_document(document) + { + } + +protected: + void paintEvent(QPaintEvent *event) override + { + bool hasAnnotations = false; + for (uint i = 0; i < m_document->pages(); ++i) + if (m_document->page(i)->hasAnnotations()) { + hasAnnotations = true; + break; + } + if (!hasAnnotations) { + QPainter p(viewport()); + p.setRenderHint(QPainter::Antialiasing, true); + p.setClipRect(event->rect()); + + QTextDocument document; + document.setHtml( + i18n("

No annotations

" + "To create new annotations press F6 or select Tools -> Annotations" + " from the menu.
")); + document.setTextWidth(width() - 50); + + const uint w = document.size().width() + 20; + const uint h = document.size().height() + 20; + + p.setBrush(palette().window()); + p.translate(0.5, 0.5); + p.drawRoundedRect(15, 15, w, h, (8 * 200.0) / w, (8 * 200.0) / h); + p.translate(20, 20); + document.drawContents(&p); + + } else { + QTreeView::paintEvent(event); + } + } + +private: + Okular::Document *m_document; +}; + +Reviews::Reviews(QWidget *parent, Okular::Document *document) + : QWidget(parent) + , m_document(document) +{ + // create widgets and layout them vertically + QVBoxLayout *vLayout = new QVBoxLayout(this); + vLayout->setSpacing(6); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Annotations")); + + m_view = new TreeView(m_document, this); + m_view->setAlternatingRowColors(true); + m_view->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_view->header()->hide(); + + QToolBar *toolBar = new QToolBar(this); + toolBar->setObjectName(QStringLiteral("reviewOptsBar")); + QSizePolicy sp = toolBar->sizePolicy(); + sp.setVerticalPolicy(QSizePolicy::Minimum); + toolBar->setSizePolicy(sp); + + m_model = new AnnotationModel(m_document, m_view); + + m_filterProxy = new PageFilterProxyModel(m_view); + m_groupProxy = new PageGroupProxyModel(m_view); + m_authorProxy = new AuthorGroupProxyModel(m_view); + + m_filterProxy->setSourceModel(m_model); + m_groupProxy->setSourceModel(m_filterProxy); + m_authorProxy->setSourceModel(m_groupProxy); + + m_view->setModel(m_authorProxy); + + m_searchLine = new KTreeViewSearchLine(this, m_view); + m_searchLine->setPlaceholderText(i18n("Search...")); + m_searchLine->setCaseSensitivity(Okular::Settings::self()->reviewsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive); + m_searchLine->setRegularExpression(Okular::Settings::self()->reviewsSearchRegularExpression()); + connect(m_searchLine, &KTreeViewSearchLine::searchOptionsChanged, this, &Reviews::saveSearchOptions); + vLayout->addWidget(titleWidget); + vLayout->setAlignment(titleWidget, Qt::AlignHCenter); + vLayout->addWidget(m_searchLine); + vLayout->addWidget(m_view); + vLayout->addWidget(toolBar); + + toolBar->setIconSize(QSize(16, 16)); + toolBar->setMovable(false); + // - add Page button + QAction *groupByPageAction = toolBar->addAction(QIcon::fromTheme(QStringLiteral("text-x-generic")), i18n("Group by Page")); + groupByPageAction->setCheckable(true); + connect(groupByPageAction, &QAction::toggled, this, &Reviews::slotPageEnabled); + groupByPageAction->setChecked(Okular::Settings::groupByPage()); + // - add Author button + QAction *groupByAuthorAction = toolBar->addAction(QIcon::fromTheme(QStringLiteral("user-identity")), i18n("Group by Author")); + groupByAuthorAction->setCheckable(true); + connect(groupByAuthorAction, &QAction::toggled, this, &Reviews::slotAuthorEnabled); + groupByAuthorAction->setChecked(Okular::Settings::groupByAuthor()); + + // - add separator + toolBar->addSeparator(); + // - add Current Page Only button + QAction *curPageOnlyAction = toolBar->addAction(QIcon::fromTheme(QStringLiteral("arrow-down")), i18n("Show annotations for current page only")); + curPageOnlyAction->setCheckable(true); + connect(curPageOnlyAction, &QAction::toggled, this, &Reviews::slotCurrentPageOnly); + curPageOnlyAction->setChecked(Okular::Settings::currentPageOnly()); + + // Adds space between left actions, so that the next two buttons are aligned to the right + QWidget *spacer = new QWidget(); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + toolBar->addWidget(spacer); + + QAction *expandAll = toolBar->addAction(QIcon::fromTheme(QStringLiteral("expand-all")), i18n("Expand all elements")); + connect(expandAll, &QAction::triggered, this, &Reviews::slotExpandAll); + QAction *collapseAll = toolBar->addAction(QIcon::fromTheme(QStringLiteral("collapse-all")), i18n("Collapse all elements")); + connect(collapseAll, &QAction::triggered, this, &Reviews::slotCollapseAll); + + connect(m_view, &TreeView::activated, this, &Reviews::activated); + + m_view->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_view, &TreeView::customContextMenuRequested, this, &Reviews::contextMenuRequested); +} + +Reviews::~Reviews() +{ + m_document->removeObserver(this); +} + +// BEGIN DocumentObserver Notifies +void Reviews::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + Q_UNUSED(previousPage) + + m_filterProxy->setCurrentPage(currentPage); +} +// END DocumentObserver Notifies + +void Reviews::reparseConfig() +{ + m_searchLine->setCaseSensitivity(Okular::Settings::reviewsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive); + m_searchLine->setRegularExpression(Okular::Settings::reviewsSearchRegularExpression()); + m_view->update(); +} + +// BEGIN GUI Slots -> requestListViewUpdate +void Reviews::slotPageEnabled(bool on) +{ + // store toggle state in Settings and update the listview + Okular::Settings::setGroupByPage(on); + m_groupProxy->groupByPage(on); + + m_view->expandAll(); +} + +void Reviews::slotAuthorEnabled(bool on) +{ + // store toggle state in Settings and update the listview + Okular::Settings::setGroupByAuthor(on); + m_authorProxy->groupByAuthor(on); + + m_view->expandAll(); +} + +void Reviews::slotCurrentPageOnly(bool on) +{ + // store toggle state in Settings and update the listview + Okular::Settings::setCurrentPageOnly(on); + m_filterProxy->groupByCurrentPage(on); + + m_view->expandAll(); +} + +void Reviews::slotExpandAll() +{ + m_view->expandAll(); +} + +void Reviews::slotCollapseAll() +{ + m_view->collapseAll(); +} +// END GUI Slots + +void Reviews::activated(const QModelIndex &index) +{ + const QModelIndex authorIndex = m_authorProxy->mapToSource(index); + const QModelIndex filterIndex = m_groupProxy->mapToSource(authorIndex); + const QModelIndex annotIndex = m_filterProxy->mapToSource(filterIndex); + + Okular::Annotation *annotation = m_model->annotationForIndex(annotIndex); + if (!annotation) + return; + + int pageNumber = m_model->data(annotIndex, AnnotationModel::PageRole).toInt(); + const Okular::Page *page = m_document->page(pageNumber); + + // calculating the right coordinates to center the view on the annotation + QRect rect = Okular::AnnotationUtils::annotationGeometry(annotation, page->width(), page->height()); + Okular::NormalizedRect nr(rect, (int)page->width(), (int)page->height()); + // set the viewport parameters + Okular::DocumentViewport vp; + vp.pageNumber = pageNumber; + vp.rePos.enabled = true; + vp.rePos.pos = Okular::DocumentViewport::Center; + vp.rePos.normalizedX = (nr.right + nr.left) / 2.0; + vp.rePos.normalizedY = (nr.bottom + nr.top) / 2.0; + // setting the viewport + m_document->setViewport(vp, nullptr, true); +} + +QModelIndexList Reviews::retrieveAnnotations(const QModelIndex &idx) const +{ + QModelIndexList ret; + if (idx.isValid()) { + const QAbstractItemModel *model = idx.model(); + if (model->hasChildren(idx)) { + int rowCount = model->rowCount(idx); + for (int i = 0; i < rowCount; i++) { + ret += retrieveAnnotations(model->index(i, idx.column(), idx)); + } + } else { + ret += idx; + } + } + + return ret; +} + +void Reviews::contextMenuRequested(const QPoint pos) +{ + AnnotationPopup popup(m_document, AnnotationPopup::SingleAnnotationMode, this); + connect(&popup, &AnnotationPopup::openAnnotationWindow, this, &Reviews::openAnnotationWindow); + + const QModelIndexList indexes = m_view->selectionModel()->selectedIndexes(); + for (const QModelIndex &index : indexes) { + const QModelIndexList annotations = retrieveAnnotations(index); + for (const QModelIndex &idx : annotations) { + const QModelIndex authorIndex = m_authorProxy->mapToSource(idx); + const QModelIndex filterIndex = m_groupProxy->mapToSource(authorIndex); + const QModelIndex annotIndex = m_filterProxy->mapToSource(filterIndex); + Okular::Annotation *annotation = m_model->annotationForIndex(annotIndex); + if (annotation) { + const int pageNumber = m_model->data(annotIndex, AnnotationModel::PageRole).toInt(); + popup.addAnnotation(annotation, pageNumber); + } + } + } + + popup.exec(m_view->viewport()->mapToGlobal(pos)); +} + +void Reviews::saveSearchOptions() +{ + Okular::Settings::setReviewsSearchRegularExpression(m_searchLine->regularExpression()); + Okular::Settings::setReviewsSearchCaseSensitive(m_searchLine->caseSensitivity() == Qt::CaseSensitive ? true : false); + Okular::Settings::self()->save(); +} + +#include "side_reviews.moc" diff --git a/part/side_reviews.h b/part/side_reviews.h new file mode 100644 index 0000000..1cc91b0 --- /dev/null +++ b/part/side_reviews.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2005 by Enrico Ros * + * * + * 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_SIDE_REVIEWS_H_ +#define _OKULAR_SIDE_REVIEWS_H_ + +#include +#include +#include + +#include "core/observer.h" + +class QModelIndex; + +namespace Okular +{ +class Annotation; +class Document; +} + +class AnnotationModel; +class AuthorGroupProxyModel; +class PageFilterProxyModel; +class PageGroupProxyModel; +class KTreeViewSearchLine; +class TreeView; + +/** + * @short ... + */ +class Reviews : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT +public: + Reviews(QWidget *parent, Okular::Document *document); + ~Reviews() override; + + // [INHERITED] from DocumentObserver + void notifyCurrentPageChanged(int previous, int current) override; + + void reparseConfig(); + +public Q_SLOTS: + void slotPageEnabled(bool); + void slotAuthorEnabled(bool); + void slotCurrentPageOnly(bool); + void slotExpandAll(); + void slotCollapseAll(); + +Q_SIGNALS: + void openAnnotationWindow(Okular::Annotation *annotation, int pageNumber); + +private Q_SLOTS: + void activated(const QModelIndex &); + void contextMenuRequested(const QPoint); + void saveSearchOptions(); + +private: + QModelIndexList retrieveAnnotations(const QModelIndex &idx) const; + + // data fields (GUI) + KTreeViewSearchLine *m_searchLine; + TreeView *m_view; + // internal storage + Okular::Document *m_document; + AnnotationModel *m_model; + AuthorGroupProxyModel *m_authorProxy; + PageFilterProxyModel *m_filterProxy; + PageGroupProxyModel *m_groupProxy; +}; + +#endif diff --git a/part/sidebar.cpp b/part/sidebar.cpp new file mode 100644 index 0000000..bf43ae1 --- /dev/null +++ b/part/sidebar.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 2007 by Pino Toscano * + * Copyright (C) 2009 by Eike Hein * + * * + * 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. * + ***************************************************************************/ + +#include "sidebar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "settings.h" + +/* Private storage. */ +class Sidebar::Private +{ +public: + Private() + : sideWidget(nullptr) + , bottomWidget(nullptr) + , splitterSizesSet(false) + { + } + + QSplitter *splitter; + QTabWidget *viewChooserTabs; + QWidget *sideContainer; + QVBoxLayout *vlay; + QWidget *sideWidget; + QWidget *bottomWidget; + bool splitterSizesSet; +}; + +Sidebar::Sidebar(QWidget *parent) + : QWidget(parent) + , d(new Private) +{ + QHBoxLayout *mainlay = new QHBoxLayout(this); + mainlay->setContentsMargins(0, 0, 0, 0); + mainlay->setSpacing(0); + + setAutoFillBackground(true); + setAcceptDrops(true); + + d->splitter = new QSplitter(this); + mainlay->addWidget(d->splitter); + d->splitter->setOpaqueResize(true); + d->splitter->setChildrenCollapsible(false); + + // d->sideContainer holds all the actual content + d->sideContainer = new QWidget(d->splitter); + d->sideContainer->setMinimumWidth(90); + d->sideContainer->setMaximumWidth(600); + d->vlay = new QVBoxLayout(d->sideContainer); + d->vlay->setContentsMargins(0, 0, 0, 0); + + d->viewChooserTabs = new QTabWidget(d->sideContainer); + d->viewChooserTabs->setDocumentMode(true); + d->vlay->addWidget(d->viewChooserTabs); + + connect(d->splitter, &QSplitter::splitterMoved, this, &Sidebar::splitterMoved); +} + +Sidebar::~Sidebar() +{ + delete d; +} + +int Sidebar::addItem(QWidget *widget, const QIcon &icon, const QString &text) +{ + if (!widget) + return -1; + + widget->setParent(d->viewChooserTabs); + d->viewChooserTabs->addTab(widget, icon, text); + const int thisTabIndex = d->viewChooserTabs->count() - 1; + // Hide all text and use large icons + d->viewChooserTabs->setTabText(thisTabIndex, QString()); + d->viewChooserTabs->setIconSize(QSize(22, 22)); + d->viewChooserTabs->setTabToolTip(thisTabIndex, text); + return thisTabIndex; +} + +void Sidebar::setMainWidget(QWidget *widget) +{ + delete d->sideWidget; + d->sideWidget = widget; + if (d->sideWidget) { + // setting the splitter as parent for the widget automatically plugs it + // into the splitter, neat! + d->sideWidget->setParent(d->splitter); + setFocusProxy(widget); + + if (!d->splitterSizesSet) { + QList splitterSizes = Okular::Settings::splitterSizes(); + if (splitterSizes.isEmpty()) { + // the first time use 1/10 for the panel and 9/10 for the pageView + splitterSizes.push_back(50); + splitterSizes.push_back(500); + } + d->splitter->setSizes(splitterSizes); + d->splitterSizesSet = true; + } + } +} + +void Sidebar::setBottomWidget(QWidget *widget) +{ + delete d->bottomWidget; + d->bottomWidget = widget; + if (d->bottomWidget) { + d->bottomWidget->setParent(this); + d->vlay->addWidget(d->bottomWidget); + } +} + +void Sidebar::setCurrentItem(QWidget *widget) +{ + d->viewChooserTabs->setCurrentWidget(widget); +} + +QWidget *Sidebar::currentItem() const +{ + if (d->viewChooserTabs->currentIndex() == -1) + return nullptr; + + return d->viewChooserTabs->currentWidget(); +} + +void Sidebar::setSidebarVisibility(bool visible) +{ + d->sideContainer->setHidden(!visible); +} + +bool Sidebar::isSidebarVisible() const +{ + return !d->sideContainer->isHidden(); +} + +void Sidebar::moveSplitter(int sideWidgetSize) +{ + QList splitterSizeList = d->splitter->sizes(); + const int total = splitterSizeList.at(0) + splitterSizeList.at(1); + splitterSizeList.replace(0, total - sideWidgetSize); + splitterSizeList.replace(1, sideWidgetSize); + d->splitter->setSizes(splitterSizeList); +} + +void Sidebar::splitterMoved(int /*pos*/, int index) +{ + // if the side panel has been resized, save splitter sizes + if (index == 1) + saveSplitterSize(); +} + +void Sidebar::saveSplitterSize() const +{ + Okular::Settings::setSplitterSizes(d->splitter->sizes()); + Okular::Settings::self()->save(); +} + +void Sidebar::dragEnterEvent(QDragEnterEvent *event) +{ + event->setAccepted(event->mimeData()->hasUrls()); +} + +void Sidebar::dropEvent(QDropEvent *event) +{ + const QList list = KUrlMimeData::urlsFromMimeData(event->mimeData()); + emit urlsDropped(list); +} diff --git a/part/sidebar.h b/part/sidebar.h new file mode 100644 index 0000000..7f56da9 --- /dev/null +++ b/part/sidebar.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2007 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 _SIDEBAR_H_ +#define _SIDEBAR_H_ + +#include "okularpart_export.h" +#include + +class QIcon; +class QListWidgetItem; + +class OKULARPART_EXPORT Sidebar : public QWidget +{ + Q_OBJECT +public: + explicit Sidebar(QWidget *parent = nullptr); + ~Sidebar() override; + + int addItem(QWidget *widget, const QIcon &icon, const QString &text); + + void setMainWidget(QWidget *widget); + void setBottomWidget(QWidget *widget); + + void setCurrentItem(QWidget *widget); + QWidget *currentItem() const; + + void setSidebarVisibility(bool visible); + bool isSidebarVisible() const; + + void moveSplitter(int sideWidgetSize); + +Q_SIGNALS: + void urlsDropped(const QList &urls); + +protected: + void dragEnterEvent(QDragEnterEvent *event) override; + void dropEvent(QDropEvent *event) override; + +private Q_SLOTS: + void splitterMoved(int pos, int index); + +private: + void saveSplitterSize() const; + + // private storage + class Private; + Private *d; +}; + +#endif diff --git a/part/signatureguiutils.cpp b/part/signatureguiutils.cpp new file mode 100644 index 0000000..0a8fe1f --- /dev/null +++ b/part/signatureguiutils.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "signatureguiutils.h" + +#include + +#include "core/document.h" +#include "core/form.h" +#include "core/page.h" + +namespace SignatureGuiUtils +{ +QVector getSignatureFormFields(Okular::Document *doc, bool allPages, int pageNum) +{ + uint curPage = allPages ? 0 : pageNum; + const uint endPage = allPages ? doc->pages() - 1 : pageNum; + QVector signatureFormFields; + while (curPage <= endPage) { + const QLinkedList formFields = doc->page(curPage++)->formFields(); + for (Okular::FormField *f : formFields) { + if (f->type() == Okular::FormField::FormSignature) { + signatureFormFields.append(static_cast(f)); + } + } + } + return signatureFormFields; +} + +QString getReadableSignatureStatus(Okular::SignatureInfo::SignatureStatus sigStatus) +{ + switch (sigStatus) { + case Okular::SignatureInfo::SignatureValid: + return i18n("The signature is cryptographically valid."); + case Okular::SignatureInfo::SignatureInvalid: + return i18n("The signature is cryptographically invalid."); + case Okular::SignatureInfo::SignatureDigestMismatch: + return i18n("Digest Mismatch occurred."); + case Okular::SignatureInfo::SignatureDecodingError: + return i18n("The signature CMS/PKCS7 structure is malformed."); + case Okular::SignatureInfo::SignatureNotFound: + return i18n("The requested signature is not present in the document."); + default: + return i18n("The signature could not be verified."); + } +} + +QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus) +{ + switch (certStatus) { + case Okular::SignatureInfo::CertificateTrusted: + return i18n("Certificate is Trusted."); + case Okular::SignatureInfo::CertificateUntrustedIssuer: + return i18n("Certificate issuer isn't Trusted."); + case Okular::SignatureInfo::CertificateUnknownIssuer: + return i18n("Certificate issuer is unknown."); + case Okular::SignatureInfo::CertificateRevoked: + return i18n("Certificate has been Revoked."); + case Okular::SignatureInfo::CertificateExpired: + return i18n("Certificate has Expired."); + case Okular::SignatureInfo::CertificateNotVerified: + return i18n("Certificate has not yet been verified."); + default: + return i18n("Unknown issue with Certificate or corrupted data."); + } +} + +QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg) +{ + switch (hashAlg) { + case Okular::SignatureInfo::HashAlgorithmMd2: + return i18n("MD2"); + case Okular::SignatureInfo::HashAlgorithmMd5: + return i18n("MD5"); + case Okular::SignatureInfo::HashAlgorithmSha1: + return i18n("SHA1"); + case Okular::SignatureInfo::HashAlgorithmSha256: + return i18n("SHA256"); + case Okular::SignatureInfo::HashAlgorithmSha384: + return i18n("SHA384"); + case Okular::SignatureInfo::HashAlgorithmSha512: + return i18n("SHA512"); + case Okular::SignatureInfo::HashAlgorithmSha224: + return i18n("SHA224"); + default: + return i18n("Unknown Algorithm"); + } +} + +QString getReadablePublicKeyType(Okular::CertificateInfo::PublicKeyType type) +{ + switch (type) { + case Okular::CertificateInfo::RsaKey: + return i18n("RSA"); + case Okular::CertificateInfo::DsaKey: + return i18n("DSA"); + case Okular::CertificateInfo::EcKey: + return i18n("EC"); + case Okular::CertificateInfo::OtherKey: + return i18n("Unknown Type"); + } + + return i18n("Unknown Type"); +} + +QString getReadableKeyUsage(Okular::CertificateInfo::KeyUsageExtensions kuExtensions, const QString &separator) +{ + QStringList ku; + if (kuExtensions.testFlag(Okular::CertificateInfo::KuDigitalSignature)) + ku << i18n("Digital Signature"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuNonRepudiation)) + ku << i18n("Non-Repudiation"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyEncipherment)) + ku << i18n("Encrypt Keys"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuDataEncipherment)) + ku << i18n("Decrypt Keys"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyAgreement)) + ku << i18n("Key Agreement"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuKeyCertSign)) + ku << i18n("Sign Certificate"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuClrSign)) + ku << i18n("Sign CRL"); + if (kuExtensions.testFlag(Okular::CertificateInfo::KuEncipherOnly)) + ku << i18n("Encrypt Only"); + if (ku.isEmpty()) + ku << i18n("No Usage Specified"); + return ku.join(separator); +} + +QString getReadableKeyUsageCommaSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions) +{ + return getReadableKeyUsage(kuExtensions, i18nc("Joins the various ways a signature key can be used in a longer string", ", ")); +} + +QString getReadableKeyUsageNewLineSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions) +{ + return getReadableKeyUsage(kuExtensions, QStringLiteral("\n")); +} + +} diff --git a/part/signatureguiutils.h b/part/signatureguiutils.h new file mode 100644 index 0000000..19ead72 --- /dev/null +++ b/part/signatureguiutils.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_SIGNATUREGUIUTILS_H +#define OKULAR_SIGNATUREGUIUTILS_H + +#include + +#include "core/signatureutils.h" + +namespace Okular +{ +class Document; +class FormFieldSignature; +} + +namespace SignatureGuiUtils +{ +/** + * Returns a vector containing signature form fields. If @p allPages is true then all signature form fields in the + * document are returned otherwise the fields in page number @p pageNum are returned. + */ +QVector getSignatureFormFields(Okular::Document *doc, bool allPages, int pageNum); +QString getReadableSignatureStatus(Okular::SignatureInfo::SignatureStatus sigStatus); +QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatus); +QString getReadableHashAlgorithm(Okular::SignatureInfo::HashAlgorithm hashAlg); +QString getReadablePublicKeyType(Okular::CertificateInfo::PublicKeyType type); +QString getReadableKeyUsageCommaSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions); +QString getReadableKeyUsageNewLineSeparated(Okular::CertificateInfo::KeyUsageExtensions kuExtensions); + +} + +#endif diff --git a/part/signaturemodel.cpp b/part/signaturemodel.cpp new file mode 100644 index 0000000..626bacd --- /dev/null +++ b/part/signaturemodel.cpp @@ -0,0 +1,265 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan + +#include +#include +#include + +#include "core/document.h" +#include "core/form.h" +#include "core/observer.h" +#include "core/page.h" +#include "core/signatureutils.h" + +struct SignatureItem { + enum DataType { Root, RevisionInfo, ValidityStatus, SigningTime, Reason, FieldInfo }; + + SignatureItem(); + SignatureItem(SignatureItem *parent, const Okular::FormFieldSignature *form, DataType type, int page); + ~SignatureItem(); + + SignatureItem(const SignatureItem &) = delete; + SignatureItem &operator=(const SignatureItem &) = delete; + + QVector children; + SignatureItem *parent; + const Okular::FormFieldSignature *form; + QString displayString; + DataType type; + int page; +}; + +SignatureItem::SignatureItem() + : parent(nullptr) + , form(nullptr) + , type(Root) + , page(-1) +{ +} + +SignatureItem::SignatureItem(SignatureItem *_parent, const Okular::FormFieldSignature *_form, DataType _type, int _page) + : parent(_parent) + , form(_form) + , type(_type) + , page(_page) +{ + Q_ASSERT(parent); + parent->children.append(this); +} + +SignatureItem::~SignatureItem() +{ + qDeleteAll(children); +} + +class SignatureModelPrivate : public Okular::DocumentObserver +{ +public: + SignatureModelPrivate(SignatureModel *qq); + ~SignatureModelPrivate() override; + + void notifySetup(const QVector &pages, int setupFlags) override; + + QModelIndex indexForItem(SignatureItem *item) const; + + SignatureModel *q; + SignatureItem *root; + QPointer document; +}; + +SignatureModelPrivate::SignatureModelPrivate(SignatureModel *qq) + : q(qq) + , root(new SignatureItem) +{ +} + +SignatureModelPrivate::~SignatureModelPrivate() +{ + delete root; +} + +static void updateFormFieldSignaturePointer(SignatureItem *item, const QVector &pages) +{ + if (item->form) { + const QLinkedList formFields = pages[item->page]->formFields(); + for (Okular::FormField *f : formFields) { + if (item->form->id() == f->id()) { + item->form = static_cast(f); + break; + } + } + if (!item->form) + qWarning() << "Lost signature form field, something went wrong"; + } + + for (SignatureItem *child : qAsConst(item->children)) { + updateFormFieldSignaturePointer(child, pages); + } +} + +void SignatureModelPrivate::notifySetup(const QVector &pages, int setupFlags) +{ + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) { + if (setupFlags & Okular::DocumentObserver::UrlChanged) { + updateFormFieldSignaturePointer(root, pages); + } + return; + } + + q->beginResetModel(); + qDeleteAll(root->children); + root->children.clear(); + for (const Okular::Page *page : pages) { + const int currentPage = page->number(); + // get form fields page by page so that page number and index of the form can be determined. + const QVector signatureFormFields = SignatureGuiUtils::getSignatureFormFields(document, false, currentPage); + if (signatureFormFields.isEmpty()) + continue; + + for (int i = 0; i < signatureFormFields.count(); i++) { + const Okular::FormFieldSignature *sf = signatureFormFields[i]; + const Okular::SignatureInfo &info = sf->signatureInfo(); + + // based on whether or not signature form is a nullptr it is decided if clicking on an item should change the viewport. + auto *parentItem = new SignatureItem(root, sf, SignatureItem::RevisionInfo, currentPage); + parentItem->displayString = i18n("Rev. %1: Signed By %2", i + 1, info.signerName()); + + auto childItem1 = new SignatureItem(parentItem, nullptr, SignatureItem::ValidityStatus, currentPage); + childItem1->displayString = SignatureGuiUtils::getReadableSignatureStatus(info.signatureStatus()); + + auto childItem2 = new SignatureItem(parentItem, nullptr, SignatureItem::SigningTime, currentPage); + childItem2->displayString = i18n("Signing Time: %1", info.signingTime().toString(Qt::DefaultLocaleLongDate)); + + auto childItem3 = new SignatureItem(parentItem, nullptr, SignatureItem::Reason, currentPage); + childItem3->displayString = i18n("Reason: %1", !info.reason().isEmpty() ? info.reason() : i18n("Not Available")); + + auto childItem4 = new SignatureItem(parentItem, sf, SignatureItem::FieldInfo, currentPage); + childItem4->displayString = i18n("Field: %1 on page %2", sf->name(), currentPage + 1); + } + } + q->endResetModel(); +} + +QModelIndex SignatureModelPrivate::indexForItem(SignatureItem *item) const +{ + if (item->parent) { + const int index = item->parent->children.indexOf(item); + if (index >= 0 && index < item->parent->children.count()) + return q->createIndex(index, 0, item); + } + return QModelIndex(); +} + +SignatureModel::SignatureModel(Okular::Document *doc, QObject *parent) + : QAbstractItemModel(parent) + , d_ptr(new SignatureModelPrivate(this)) +{ + Q_D(SignatureModel); + d->document = doc; + d->document->addObserver(d); +} + +SignatureModel::~SignatureModel() +{ + Q_D(SignatureModel); + d->document->removeObserver(d); +} + +int SignatureModel::columnCount(const QModelIndex &) const +{ + return 1; +} + +QVariant SignatureModel::data(const QModelIndex &index, int role) const +{ + Q_D(const SignatureModel); + + if (!index.isValid()) + return QVariant(); + + const SignatureItem *item = static_cast(index.internalPointer()); + if (item == d->root) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + case Qt::ToolTipRole: + return item->displayString; + case Qt::DecorationRole: + if (item->type == SignatureItem::RevisionInfo) { + const Okular::SignatureInfo::SignatureStatus signatureStatus = item->form->signatureInfo().signatureStatus(); + switch (signatureStatus) { + case Okular::SignatureInfo::SignatureValid: + return QIcon::fromTheme(QStringLiteral("dialog-ok")); + case Okular::SignatureInfo::SignatureInvalid: + return QIcon::fromTheme(QStringLiteral("dialog-close")); + case Okular::SignatureInfo::SignatureDigestMismatch: + return QIcon::fromTheme(QStringLiteral("dialog-warning")); + default: + return QIcon::fromTheme(QStringLiteral("dialog-question")); + } + } + return QIcon(); + case FormRole: + return QVariant::fromValue(item->form); + case PageRole: + return item->page; + } + + return QVariant(); +} + +bool SignatureModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return true; + + const SignatureItem *item = static_cast(parent.internalPointer()); + return !item->children.isEmpty(); +} + +QModelIndex SignatureModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const SignatureModel); + + if (row < 0 || column != 0) + return QModelIndex(); + + const SignatureItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + if (row < item->children.count()) + return createIndex(row, column, item->children.at(row)); + + return QModelIndex(); +} + +QModelIndex SignatureModel::parent(const QModelIndex &index) const +{ + Q_D(const SignatureModel); + + if (!index.isValid()) + return QModelIndex(); + + const SignatureItem *item = static_cast(index.internalPointer()); + return d->indexForItem(item->parent); +} + +int SignatureModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const SignatureModel); + + const SignatureItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + return item->children.count(); +} + +#include "moc_signaturemodel.cpp" diff --git a/part/signaturemodel.h b/part/signaturemodel.h new file mode 100644 index 0000000..7e399c5 --- /dev/null +++ b/part/signaturemodel.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan + +namespace Okular +{ +class Document; +} + +class SignatureModelPrivate; + +class SignatureModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + enum { FormRole = Qt::UserRole + 1000, PageRole }; + + explicit SignatureModel(Okular::Document *doc, QObject *parent = nullptr); + ~SignatureModel() override; + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + +private: + Q_DECLARE_PRIVATE(SignatureModel) + QScopedPointer d_ptr; +}; + +#endif diff --git a/part/signaturepanel.cpp b/part/signaturepanel.cpp new file mode 100644 index 0000000..ee33416 --- /dev/null +++ b/part/signaturepanel.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "signaturepanel.h" + +#include "pageview.h" +#include "revisionviewer.h" +#include "signatureguiutils.h" +#include "signaturemodel.h" +#include "signaturepropertiesdialog.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "core/document.h" +#include "core/form.h" + +class SignaturePanelPrivate +{ +public: + Okular::Document *m_document; + const Okular::FormFieldSignature *m_currentForm; + QTreeView *m_view; + SignatureModel *m_model; + PageView *m_pageView; +}; + +SignaturePanel::SignaturePanel(Okular::Document *document, QWidget *parent) + : QWidget(parent) + , d_ptr(new SignaturePanelPrivate) +{ + Q_D(SignaturePanel); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Signatures")); + + d->m_view = new QTreeView(this); + d->m_view->setAlternatingRowColors(true); + d->m_view->setSelectionMode(QAbstractItemView::SingleSelection); + d->m_view->setContextMenuPolicy(Qt::CustomContextMenu); + d->m_view->header()->hide(); + + d->m_document = document; + d->m_model = new SignatureModel(d->m_document, this); + + d->m_view->setModel(d->m_model); + connect(d->m_view->selectionModel(), &QItemSelectionModel::currentChanged, this, &SignaturePanel::activated); + connect(d->m_view, &QTreeView::customContextMenuRequested, this, &SignaturePanel::slotShowContextMenu); + + auto vLayout = new QVBoxLayout(this); + vLayout->setSpacing(6); + + vLayout->addWidget(titleWidget); + vLayout->setAlignment(titleWidget, Qt::AlignHCenter); + vLayout->addWidget(d->m_view); +} + +void SignaturePanel::activated(const QModelIndex &index) +{ + Q_D(SignaturePanel); + d->m_currentForm = d->m_model->data(index, SignatureModel::FormRole).value(); + if (!d->m_currentForm) + return; + const Okular::NormalizedRect nr = d->m_currentForm->rect(); + Okular::DocumentViewport vp; + vp.pageNumber = d->m_model->data(index, SignatureModel::PageRole).toInt(); + vp.rePos.enabled = true; + vp.rePos.pos = Okular::DocumentViewport::Center; + vp.rePos.normalizedX = (nr.right + nr.left) / 2.0; + vp.rePos.normalizedY = (nr.bottom + nr.top) / 2.0; + d->m_document->setViewport(vp, nullptr); + d->m_pageView->highlightSignatureFormWidget(d->m_currentForm); +} + +void SignaturePanel::slotShowContextMenu() +{ + Q_D(SignaturePanel); + if (!d->m_currentForm) + return; + + QMenu *menu = new QMenu(this); + QAction *sigProp = new QAction(i18n("Properties"), menu); + connect(sigProp, &QAction::triggered, this, &SignaturePanel::slotViewProperties); + menu->addAction(sigProp); + menu->exec(QCursor::pos()); + delete menu; +} + +void SignaturePanel::slotViewProperties() +{ + Q_D(SignaturePanel); + SignaturePropertiesDialog propDlg(d->m_document, d->m_currentForm, this); + propDlg.exec(); +} + +void SignaturePanel::notifySetup(const QVector & /*pages*/, int setupFlags) +{ + if (!(setupFlags & Okular::DocumentObserver::UrlChanged)) + return; + + Q_D(SignaturePanel); + const QVector signatureForms = SignatureGuiUtils::getSignatureFormFields(d->m_document, true, -1); + emit documentHasSignatures(!signatureForms.isEmpty()); +} + +SignaturePanel::~SignaturePanel() +{ + Q_D(SignaturePanel); + d->m_document->removeObserver(this); + delete d->m_model; +} + +void SignaturePanel::setPageView(PageView *pv) +{ + Q_D(SignaturePanel); + d->m_pageView = pv; +} diff --git a/part/signaturepanel.h b/part/signaturepanel.h new file mode 100644 index 0000000..cea4e25 --- /dev/null +++ b/part/signaturepanel.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_SIGNATUREPANEL_H +#define OKULAR_SIGNATUREPANEL_H + +#include +#include + +#include "core/observer.h" + +namespace Okular +{ +class Document; +} + +class PageView; + +class SignaturePanelPrivate; + +class SignaturePanel : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT +public: + SignaturePanel(Okular::Document *document, QWidget *parent); + ~SignaturePanel() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + + void setPageView(PageView *pv); + +Q_SIGNALS: + void documentHasSignatures(bool hasSignatures); + +private Q_SLOTS: + void activated(const QModelIndex &); + void slotShowContextMenu(); + void slotViewProperties(); + +private: + Q_DECLARE_PRIVATE(SignaturePanel) + QScopedPointer d_ptr; +}; + +#endif diff --git a/part/signaturepropertiesdialog.cpp b/part/signaturepropertiesdialog.cpp new file mode 100644 index 0000000..7a14a95 --- /dev/null +++ b/part/signaturepropertiesdialog.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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. * + ***************************************************************************/ + +#include "signaturepropertiesdialog.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "core/document.h" +#include "core/form.h" + +#include "certificateviewer.h" +#include "revisionviewer.h" +#include "signatureguiutils.h" + +static QString getValidDisplayString(const QString &str) +{ + return !str.isEmpty() ? str : i18n("Not Available"); +} + +SignaturePropertiesDialog::SignaturePropertiesDialog(Okular::Document *doc, const Okular::FormFieldSignature *form, QWidget *parent) + : QDialog(parent) + , m_doc(doc) + , m_signatureForm(form) +{ + setModal(true); + setWindowTitle(i18n("Signature Properties")); + + const Okular::SignatureInfo &signatureInfo = form->signatureInfo(); + const Okular::SignatureInfo::SignatureStatus signatureStatus = signatureInfo.signatureStatus(); + const QString readableSignatureStatus = SignatureGuiUtils::getReadableSignatureStatus(signatureStatus); + const QString signerName = getValidDisplayString(signatureInfo.signerName()); + const QString signingTime = getValidDisplayString(signatureInfo.signingTime().toString(Qt::DefaultLocaleLongDate)); + const QString signingLocation = getValidDisplayString(signatureInfo.location()); + const QString signingReason = getValidDisplayString(signatureInfo.reason()); + + // signature validation status + QString modificationSummary; + if (signatureStatus == Okular::SignatureInfo::SignatureValid) { + if (signatureInfo.signsTotalDocument()) { + modificationSummary = i18n("The document has not been modified since it was signed."); + } else { + modificationSummary = i18n( + "The revision of the document that was covered by this signature has not been modified;\n" + "however there have been subsequent changes to the document."); + } + } else if (signatureStatus == Okular::SignatureInfo::SignatureDigestMismatch) { + modificationSummary = i18n("The document has been modified in a way not permitted by a previous signer."); + } else { + modificationSummary = i18n("The document integrity verification could not be completed."); + } + + auto signatureStatusBox = new QGroupBox(i18n("Validity Status")); + auto signatureStatusFormLayout = new QFormLayout(signatureStatusBox); + signatureStatusFormLayout->setLabelAlignment(Qt::AlignLeft); + signatureStatusFormLayout->addRow(i18n("Signature Validity:"), new QLabel(readableSignatureStatus)); + signatureStatusFormLayout->addRow(i18n("Document Modifications:"), new QLabel(modificationSummary)); + + // additional information + auto extraInfoBox = new QGroupBox(i18n("Additional Information")); + auto extraInfoFormLayout = new QFormLayout(extraInfoBox); + extraInfoFormLayout->setLabelAlignment(Qt::AlignLeft); + extraInfoFormLayout->addRow(i18n("Signed By:"), new QLabel(signerName)); + extraInfoFormLayout->addRow(i18n("Signing Time:"), new QLabel(signingTime)); + extraInfoFormLayout->addRow(i18n("Reason:"), new QLabel(signingReason)); + extraInfoFormLayout->addRow(i18n("Location:"), new QLabel(signingLocation)); + + // keep width of column 1 same + auto resizer = new KColumnResizer(this); + resizer->addWidgetsFromLayout(signatureStatusFormLayout->layout(), 0); + resizer->addWidgetsFromLayout(extraInfoFormLayout->layout(), 0); + + // document revision info + QGroupBox *revisionBox = nullptr; + if (signatureStatus != Okular::SignatureInfo::SignatureStatusUnknown && !signatureInfo.signsTotalDocument()) { + revisionBox = new QGroupBox(i18n("Document Version")); + auto revisionLayout = new QHBoxLayout(revisionBox); + const QVector signatureFormFields = SignatureGuiUtils::getSignatureFormFields(m_doc, true, -1); + revisionLayout->addWidget(new QLabel(i18nc("Document Revision of ", "Document Revision %1 of %2", signatureFormFields.indexOf(m_signatureForm) + 1, signatureFormFields.size()))); + revisionLayout->addStretch(); + auto revisionBtn = new QPushButton(i18n("View Signed Version...")); + connect(revisionBtn, &QPushButton::clicked, this, &SignaturePropertiesDialog::viewSignedVersion); + revisionLayout->addWidget(revisionBtn); + } + + // button box + auto btnBox = new QDialogButtonBox(QDialogButtonBox::Close, this); + auto certPropBtn = new QPushButton(i18n("View Certificate...")); + certPropBtn->setEnabled(!signatureInfo.certificateInfo().isNull()); + btnBox->addButton(certPropBtn, QDialogButtonBox::ActionRole); + connect(btnBox, &QDialogButtonBox::rejected, this, &SignaturePropertiesDialog::reject); + connect(certPropBtn, &QPushButton::clicked, this, &SignaturePropertiesDialog::viewCertificateProperties); + + auto mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(signatureStatusBox); + mainLayout->addWidget(extraInfoBox); + if (revisionBox) { + mainLayout->addWidget(revisionBox); + } + mainLayout->addWidget(btnBox); + + resize(mainLayout->sizeHint()); +} + +void SignaturePropertiesDialog::viewCertificateProperties() +{ + CertificateViewer certViewer(m_signatureForm->signatureInfo().certificateInfo(), this); + certViewer.exec(); +} + +void SignaturePropertiesDialog::viewSignedVersion() +{ + const QByteArray data = m_doc->requestSignedRevisionData(m_signatureForm->signatureInfo()); + RevisionViewer revViewer(data, this); + revViewer.viewRevision(); +} + +#include "moc_signaturepropertiesdialog.cpp" diff --git a/part/signaturepropertiesdialog.h b/part/signaturepropertiesdialog.h new file mode 100644 index 0000000..77d24b9 --- /dev/null +++ b/part/signaturepropertiesdialog.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * + * * + * 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_SIGNATUREPROPERTIESDIALOG_H +#define OKULAR_SIGNATUREPROPERTIESDIALOG_H + +#include + +#include + +namespace Okular +{ +class Document; +class FormFieldSignature; +} + +class SignaturePropertiesDialog : public QDialog +{ + Q_OBJECT + +public: + SignaturePropertiesDialog(Okular::Document *doc, const Okular::FormFieldSignature *form, QWidget *parent = nullptr); + +public Q_SLOTS: + void viewSignedVersion(); + void viewCertificateProperties(); + +private: + Okular::Document *m_doc; + const Okular::FormFieldSignature *m_signatureForm; +}; + +#endif diff --git a/part/snapshottaker.cpp b/part/snapshottaker.cpp new file mode 100644 index 0000000..83e1f1e --- /dev/null +++ b/part/snapshottaker.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2012 by Tobias Koening * + * * + * 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. * + ***************************************************************************/ + +#include "snapshottaker.h" + +#include +#include + +#include + +SnapshotTaker::SnapshotTaker(const QUrl &url, QObject *parent) + : QObject(parent) + , m_player(new Phonon::VideoPlayer(Phonon::NoCategory, nullptr)) +{ + m_player->load(url); + m_player->hide(); + + connect(m_player->mediaObject(), &Phonon::MediaObject::stateChanged, this, &SnapshotTaker::stateChanged); + + m_player->play(); +} + +SnapshotTaker::~SnapshotTaker() +{ + m_player->stop(); + delete m_player; +} + +void SnapshotTaker::stateChanged(Phonon::State newState, Phonon::State) +{ + if (newState == Phonon::PlayingState) { + const QImage image = m_player->videoWidget()->snapshot(); + if (!image.isNull()) + emit finished(image); + + m_player->stop(); + deleteLater(); + } +} diff --git a/part/snapshottaker.h b/part/snapshottaker.h new file mode 100644 index 0000000..ae479fe --- /dev/null +++ b/part/snapshottaker.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2012 by Tobias Koening * + * * + * 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 SNAPSHOTTAKER_H +#define SNAPSHOTTAKER_H + +#include + +#include + +class QImage; + +class SnapshotTaker : public QObject +{ + Q_OBJECT + +public: + explicit SnapshotTaker(const QUrl &url, QObject *parent = nullptr); + ~SnapshotTaker() override; + +Q_SIGNALS: + void finished(const QImage &image); + +private Q_SLOTS: + void stateChanged(Phonon::State, Phonon::State); + +private: + Phonon::VideoPlayer *m_player; +}; + +#endif diff --git a/part/textdocumentsettings.ui b/part/textdocumentsettings.ui new file mode 100644 index 0000000..f72d014 --- /dev/null +++ b/part/textdocumentsettings.ui @@ -0,0 +1,13 @@ + + + TextDocumentSettings + + + + QFormLayout::ExpandingFieldsGrow + + + + + + diff --git a/part/thumbnaillist.cpp b/part/thumbnaillist.cpp new file mode 100644 index 0000000..7a259d1 --- /dev/null +++ b/part/thumbnaillist.cpp @@ -0,0 +1,1000 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "thumbnaillist.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +// local includes +#include "core/area.h" +#include "core/bookmarkmanager.h" +#include "core/document.h" +#include "core/generator.h" +#include "core/page.h" +#include "pagepainter.h" +#include "priorities.h" +#include "settings.h" + +class ThumbnailWidget; + +ThumbnailsBox::ThumbnailsBox(QWidget *parent) + : QWidget(parent) +{ + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setSpacing(0); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Thumbnails")); + vbox->addWidget(titleWidget); + vbox->setAlignment(titleWidget, Qt::AlignHCenter); +} + +QSize ThumbnailsBox::sizeHint() const +{ + return QSize(); +} + +class ThumbnailListPrivate : public QWidget +{ + Q_OBJECT +public: + ThumbnailListPrivate(ThumbnailList *qq, Okular::Document *document); + ~ThumbnailListPrivate() override; + + enum ChangePageDirection { Null, Left, Right, Up, Down }; + + ThumbnailList *q; + Okular::Document *m_document; + ThumbnailWidget *m_selected; + QTimer *m_delayTimer; + QPixmap *m_bookmarkOverlay; + QVector m_thumbnails; + QList m_visibleThumbnails; + int m_vectorIndex; + // Grabbing variables + QPoint m_mouseGrabPos; + ThumbnailWidget *m_mouseGrabItem; + int m_pageCurrentlyGrabbed; + + // resize thumbnails to fit the width + void viewportResizeEvent(QResizeEvent *); + // called by ThumbnailWidgets to get the overlay bookmark pixmap + const QPixmap *getBookmarkOverlay() const; + // called by ThumbnailWidgets to send (forward) the mouse move signals + ChangePageDirection forwardTrack(const QPoint, const QSize); + + ThumbnailWidget *itemFor(const QPoint p) const; + void delayedRequestVisiblePixmaps(int delayMs = 0); + + // SLOTS: + // make requests for generating pixmaps for visible thumbnails + void slotRequestVisiblePixmaps(); + // delay timeout: resize overlays and requests pixmaps + void slotDelayTimeout(); + ThumbnailWidget *getPageByNumber(int page) const; + int getNewPageOffset(int n, ThumbnailListPrivate::ChangePageDirection dir) const; + ThumbnailWidget *getThumbnailbyOffset(int current, int offset) const; + +protected: + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + void contextMenuEvent(QContextMenuEvent *e) override; + void paintEvent(QPaintEvent *e) override; +}; + +// ThumbnailWidget represents a single thumbnail in the ThumbnailList +class ThumbnailWidget +{ +public: + ThumbnailWidget(ThumbnailListPrivate *parent, const Okular::Page *page); + + // set internal parameters to fit the page in the given width + void resizeFitWidth(int width); + // set thumbnail's selected state + void setSelected(bool selected); + // set the visible rect of the current page + void setVisibleRect(const Okular::NormalizedRect &rect); + + // query methods + int heightHint() const + { + return m_pixmapHeight + m_labelHeight + m_margin; + } + int pixmapWidth() const + { + return m_pixmapWidth; + } + int pixmapHeight() const + { + return m_pixmapHeight; + } + int pageNumber() const + { + return m_page->number(); + } + const Okular::Page *page() const + { + return m_page; + } + QRect visibleRect() const + { + return m_visibleRect.geometry(m_pixmapWidth, m_pixmapHeight); + } + + void paint(QPainter &p, const QRect clipRect); + + static int margin() + { + return m_margin; + } + + // simulating QWidget + QRect rect() const + { + return m_rect; + } + int height() const + { + return m_rect.height(); + } + int width() const + { + return m_rect.width(); + } + QPoint pos() const + { + return m_rect.topLeft(); + } + void move(int x, int y) + { + m_rect.setTopLeft(QPoint(x, y)); + } + void update() + { + m_parent->update(m_rect); + } + void update(const QRect rect) + { + m_parent->update(rect.translated(m_rect.topLeft())); + } + +private: + // the margin around the widget + static int const m_margin = 16; + + ThumbnailListPrivate *m_parent; + const Okular::Page *m_page; + bool m_selected; + int m_pixmapWidth, m_pixmapHeight; + int m_labelHeight, m_labelNumber; + Okular::NormalizedRect m_visibleRect; + QRect m_rect; +}; + +ThumbnailListPrivate::ThumbnailListPrivate(ThumbnailList *qq, Okular::Document *document) + : QWidget() + , q(qq) + , m_document(document) + , m_selected(nullptr) + , m_delayTimer(nullptr) + , m_bookmarkOverlay(nullptr) + , m_vectorIndex(0) +{ + setMouseTracking(true); + m_mouseGrabItem = nullptr; +} + +ThumbnailWidget *ThumbnailListPrivate::getPageByNumber(int page) const +{ + QVector::const_iterator tIt = m_thumbnails.constBegin(), tEnd = m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) { + if ((*tIt)->pageNumber() == page) + return (*tIt); + } + return nullptr; +} + +ThumbnailListPrivate::~ThumbnailListPrivate() +{ +} + +ThumbnailWidget *ThumbnailListPrivate::itemFor(const QPoint p) const +{ + QVector::const_iterator tIt = m_thumbnails.constBegin(), tEnd = m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) { + if ((*tIt)->rect().contains(p)) + return (*tIt); + } + return nullptr; +} + +void ThumbnailListPrivate::paintEvent(QPaintEvent *e) +{ + QPainter painter(this); + QVector::const_iterator tIt = m_thumbnails.constBegin(), tEnd = m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) { + QRect rect = e->rect().intersected((*tIt)->rect()); + if (!rect.isNull()) { + rect.translate(-(*tIt)->pos()); + painter.save(); + painter.translate((*tIt)->pos()); + (*tIt)->paint(painter, rect); + painter.restore(); + } + } +} + +/** ThumbnailList implementation **/ + +ThumbnailList::ThumbnailList(QWidget *parent, Okular::Document *document) + : QScrollArea(parent) + , d(new ThumbnailListPrivate(this, document)) +{ + setObjectName(QStringLiteral("okular::Thumbnails")); + // set scrollbars + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + verticalScrollBar()->setEnabled(false); + + setAttribute(Qt::WA_StaticContents); + + viewport()->setBackgroundRole(QPalette::Base); + + setWidget(d); + // widget setup: can be focused by mouse click (not wheel nor tab) + widget()->setFocusPolicy(Qt::ClickFocus); + widget()->show(); + widget()->setBackgroundRole(QPalette::Base); + + connect(verticalScrollBar(), &QScrollBar::valueChanged, d, &ThumbnailListPrivate::slotRequestVisiblePixmaps); +} + +ThumbnailList::~ThumbnailList() +{ + d->m_document->removeObserver(this); + delete d->m_bookmarkOverlay; +} + +// BEGIN DocumentObserver inherited methods +void ThumbnailList::notifySetup(const QVector &pages, int setupFlags) +{ + // if there was a widget selected, save its pagenumber to restore + // its selection (if available in the new set of pages) + int prevPage = -1; + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged) && d->m_selected) { + prevPage = d->m_selected->page()->number(); + } else + prevPage = d->m_document->viewport().pageNumber; + + // delete all the Thumbnails + QVector::const_iterator tIt = d->m_thumbnails.constBegin(), tEnd = d->m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) + delete *tIt; + d->m_thumbnails.clear(); + d->m_visibleThumbnails.clear(); + d->m_selected = nullptr; + d->m_mouseGrabItem = nullptr; + + if (pages.count() < 1) { + widget()->resize(0, 0); + return; + } + + // show pages containing highlighted text or bookmarked ones + // RESTORE THIS int flags = Okular::Settings::filterBookmarks() ? Okular::Page::Bookmark : Okular::Page::Highlight; + + // if no page matches filter rule, then display all pages + QVector::const_iterator pIt = pages.constBegin(), pEnd = pages.constEnd(); + bool skipCheck = true; + for (; pIt != pEnd; ++pIt) + // if ( (*pIt)->attributes() & flags ) + if ((*pIt)->hasHighlights(SW_SEARCH_ID)) + skipCheck = false; + + // generate Thumbnails for the given set of pages + const int width = viewport()->width(); + int height = 0; + int centerHeight = 0; + for (pIt = pages.constBegin(); pIt != pEnd; ++pIt) + // if ( skipCheck || (*pIt)->attributes() & flags ) + if (skipCheck || (*pIt)->hasHighlights(SW_SEARCH_ID)) { + ThumbnailWidget *t = new ThumbnailWidget(d, *pIt); + t->move(0, height); + // add to the internal queue + d->m_thumbnails.push_back(t); + // update total height (asking widget its own height) + t->resizeFitWidth(width); + // restoring the previous selected page, if any + if ((*pIt)->number() < prevPage) { + centerHeight = height + t->height() + this->style()->layoutSpacing(QSizePolicy::Frame, QSizePolicy::Frame, Qt::Vertical) / 2; + } + if ((*pIt)->number() == prevPage) { + d->m_selected = t; + d->m_selected->setSelected(true); + centerHeight = height + t->height() / 2; + } + height += t->height() + this->style()->layoutSpacing(QSizePolicy::Frame, QSizePolicy::Frame, Qt::Vertical); + } + + // update scrollview's contents size (sets scrollbars limits) + height -= this->style()->layoutSpacing(QSizePolicy::Frame, QSizePolicy::Frame, Qt::Vertical); + widget()->resize(width, height); + + // enable scrollbar when there's something to scroll + verticalScrollBar()->setEnabled(viewport()->height() < height); + verticalScrollBar()->setValue(centerHeight - viewport()->height() / 2); + + // request for thumbnail generation + d->delayedRequestVisiblePixmaps(200); +} + +void ThumbnailList::notifyCurrentPageChanged(int previousPage, int currentPage) +{ + Q_UNUSED(previousPage) + + // skip notifies for the current page (already selected) + if (d->m_selected && d->m_selected->pageNumber() == currentPage) + return; + + // deselect previous thumbnail + if (d->m_selected) + d->m_selected->setSelected(false); + d->m_selected = nullptr; + + // select the page with viewport and ensure it's centered in the view + d->m_vectorIndex = 0; + QVector::const_iterator tIt = d->m_thumbnails.constBegin(), tEnd = d->m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) { + if ((*tIt)->pageNumber() == currentPage) { + d->m_selected = *tIt; + d->m_selected->setSelected(true); + if (Okular::Settings::syncThumbnailsViewport()) { + int yOffset = qMax(viewport()->height() / 4, d->m_selected->height() / 2); + ensureVisible(0, d->m_selected->pos().y() + d->m_selected->height() / 2, 0, yOffset); + } + break; + } + d->m_vectorIndex++; + } +} + +void ThumbnailList::notifyPageChanged(int pageNumber, int changedFlags) +{ + static const int interestingFlags = DocumentObserver::Pixmap | DocumentObserver::Bookmark | DocumentObserver::Highlights | DocumentObserver::Annotations; + // only handle change notifications we are interested in + if (!(changedFlags & interestingFlags)) + return; + + // iterate over visible items: if page(pageNumber) is one of them, repaint it + QList::const_iterator vIt = d->m_visibleThumbnails.constBegin(), vEnd = d->m_visibleThumbnails.constEnd(); + for (; vIt != vEnd; ++vIt) + if ((*vIt)->pageNumber() == pageNumber) { + (*vIt)->update(); + break; + } +} + +void ThumbnailList::notifyContentsCleared(int changedFlags) +{ + // if pixmaps were cleared, re-ask them + if (changedFlags & DocumentObserver::Pixmap) + d->slotRequestVisiblePixmaps(); +} + +void ThumbnailList::notifyVisibleRectsChanged() +{ + bool found = false; + const QVector &visibleRects = d->m_document->visiblePageRects(); + QVector::const_iterator tIt = d->m_thumbnails.constBegin(), tEnd = d->m_thumbnails.constEnd(); + QVector::const_iterator vEnd = visibleRects.end(); + for (; tIt != tEnd; ++tIt) { + found = false; + QVector::const_iterator vIt = visibleRects.begin(); + for (; (vIt != vEnd) && !found; ++vIt) { + if ((*tIt)->pageNumber() == (*vIt)->pageNumber) { + (*tIt)->setVisibleRect((*vIt)->rect); + found = true; + } + } + if (!found) { + (*tIt)->setVisibleRect(Okular::NormalizedRect()); + } + } +} + +bool ThumbnailList::canUnloadPixmap(int pageNumber) const +{ + // if the thumbnail 'pageNumber' is one of the visible ones, forbid unloading + QList::const_iterator vIt = d->m_visibleThumbnails.constBegin(), vEnd = d->m_visibleThumbnails.constEnd(); + for (; vIt != vEnd; ++vIt) + if ((*vIt)->pageNumber() == pageNumber) + return false; + // if hidden permit unloading + return true; +} +// END DocumentObserver inherited methods + +void ThumbnailList::updateWidgets() +{ + // Update all visible widgets + QList::const_iterator vIt = d->m_visibleThumbnails.constBegin(), vEnd = d->m_visibleThumbnails.constEnd(); + for (; vIt != vEnd; ++vIt) { + ThumbnailWidget *t = *vIt; + t->update(); + } +} + +int ThumbnailListPrivate::getNewPageOffset(int n, ThumbnailListPrivate::ChangePageDirection dir) const +{ + int reason = 1; + int facingFirst = 0; // facingFirstCentered cornercase + if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Facing) + reason = 2; + else if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::FacingFirstCentered) { + facingFirst = 1; + reason = 2; + } else if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::Summary) + reason = 3; + if (dir == ThumbnailListPrivate::Up) { + if (facingFirst && n == 1) + return -1; + return -reason; + } + if (dir == ThumbnailListPrivate::Down) + return reason; + if (dir == ThumbnailListPrivate::Left && reason > 1 && (n + facingFirst) % reason) + return -1; + if (dir == ThumbnailListPrivate::Right && reason > 1 && (n + 1 + facingFirst) % reason) + return 1; + return 0; +} + +ThumbnailWidget *ThumbnailListPrivate::getThumbnailbyOffset(int current, int offset) const +{ + QVector::const_iterator it = m_thumbnails.begin(); + QVector::const_iterator itE = m_thumbnails.end(); + int idx = 0; + while (it != itE) { + if ((*it)->pageNumber() == current) + break; + ++idx; + ++it; + } + if (it == itE) + return nullptr; + idx += offset; + if (idx < 0 || idx >= m_thumbnails.size()) + return nullptr; + return m_thumbnails[idx]; +} + +ThumbnailListPrivate::ChangePageDirection ThumbnailListPrivate::forwardTrack(const QPoint point, const QSize r) +{ + Okular::DocumentViewport vp = m_document->viewport(); + const double deltaX = (double)point.x() / r.width(), deltaY = (double)point.y() / r.height(); + vp.rePos.normalizedX -= deltaX; + vp.rePos.normalizedY -= deltaY; + if (vp.rePos.normalizedY > 1.0) + return ThumbnailListPrivate::Down; + if (vp.rePos.normalizedY < 0.0) + return ThumbnailListPrivate::Up; + if (vp.rePos.normalizedX > 1.0) + return ThumbnailListPrivate::Right; + if (vp.rePos.normalizedX < 0.0) + return ThumbnailListPrivate::Left; + vp.rePos.enabled = true; + m_document->setViewport(vp); + return ThumbnailListPrivate::Null; +} + +const QPixmap *ThumbnailListPrivate::getBookmarkOverlay() const +{ + return m_bookmarkOverlay; +} + +void ThumbnailList::slotFilterBookmarks(bool filterOn) +{ + // save state + Okular::Settings::setFilterBookmarks(filterOn); + Okular::Settings::self()->save(); + // ask for the 'notifySetup' with a little trick (on reinsertion the + // document sends the list again) + d->m_document->removeObserver(this); + d->m_document->addObserver(this); +} + +// BEGIN widget events +void ThumbnailList::keyPressEvent(QKeyEvent *keyEvent) +{ + if (d->m_thumbnails.count() < 1) { + keyEvent->ignore(); + return; + } + + int nextPage = -1; + if (keyEvent->key() == Qt::Key_Up) { + if (!d->m_selected) + nextPage = 0; + else if (d->m_vectorIndex > 0) + nextPage = d->m_thumbnails[d->m_vectorIndex - 1]->pageNumber(); + } else if (keyEvent->key() == Qt::Key_Down) { + if (!d->m_selected) + nextPage = 0; + else if (d->m_vectorIndex < (int)d->m_thumbnails.count() - 1) + nextPage = d->m_thumbnails[d->m_vectorIndex + 1]->pageNumber(); + } else if (keyEvent->key() == Qt::Key_PageUp) + verticalScrollBar()->triggerAction(QScrollBar::SliderPageStepSub); + else if (keyEvent->key() == Qt::Key_PageDown) + verticalScrollBar()->triggerAction(QScrollBar::SliderPageStepAdd); + else if (keyEvent->key() == Qt::Key_Home) + nextPage = d->m_thumbnails[0]->pageNumber(); + else if (keyEvent->key() == Qt::Key_End) + nextPage = d->m_thumbnails[d->m_thumbnails.count() - 1]->pageNumber(); + + if (nextPage == -1) { + keyEvent->ignore(); + return; + } + + keyEvent->accept(); + if (d->m_selected) + d->m_selected->setSelected(false); + d->m_selected = nullptr; + d->m_document->setViewportPage(nextPage); +} + +bool ThumbnailList::viewportEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::Resize: { + d->viewportResizeEvent((QResizeEvent *)e); + break; + } + default:; + } + return QScrollArea::viewportEvent(e); +} + +void ThumbnailListPrivate::viewportResizeEvent(QResizeEvent *e) +{ + if (m_thumbnails.count() < 1 || width() < 1) + return; + + // if width changed resize all the Thumbnails, reposition them to the + // right place and recalculate the contents area + if (e->size().width() != e->oldSize().width()) { + // runs the timer avoiding a thumbnail regeneration by 'contentsMoving' + delayedRequestVisiblePixmaps(2000); + + // resize and reposition items + const int newWidth = q->viewport()->width(); + int newHeight = 0; + QVector::const_iterator tIt = m_thumbnails.constBegin(), tEnd = m_thumbnails.constEnd(); + for (; tIt != tEnd; ++tIt) { + ThumbnailWidget *t = *tIt; + t->move(0, newHeight); + t->resizeFitWidth(newWidth); + newHeight += t->height() + this->style()->layoutSpacing(QSizePolicy::Frame, QSizePolicy::Frame, Qt::Vertical); + } + + // update scrollview's contents size (sets scrollbars limits) + newHeight -= this->style()->layoutSpacing(QSizePolicy::Frame, QSizePolicy::Frame, Qt::Vertical); + const int oldHeight = q->widget()->height(); + const int oldYCenter = q->verticalScrollBar()->value() + q->viewport()->height() / 2; + q->widget()->resize(newWidth, newHeight); + + // enable scrollbar when there's something to scroll + q->verticalScrollBar()->setEnabled(q->viewport()->height() < newHeight); + + // ensure that what was visible before remains visible now + q->ensureVisible(0, int((qreal)oldYCenter * q->widget()->height() / oldHeight), 0, q->viewport()->height() / 2); + } else if (e->size().height() <= e->oldSize().height()) + return; + + // invalidate the bookmark overlay + if (m_bookmarkOverlay) { + delete m_bookmarkOverlay; + m_bookmarkOverlay = nullptr; + } + + // update Thumbnails since width has changed or height has increased + delayedRequestVisiblePixmaps(500); +} +// END widget events + +// BEGIN internal SLOTS +void ThumbnailListPrivate::slotRequestVisiblePixmaps() +{ + // if an update is already scheduled or the widget is hidden, don't proceed + if ((m_delayTimer && m_delayTimer->isActive()) || q->isHidden()) + return; + + // scroll from the top to the last visible thumbnail + m_visibleThumbnails.clear(); + QLinkedList requestedPixmaps; + QVector::const_iterator tIt = m_thumbnails.constBegin(), tEnd = m_thumbnails.constEnd(); + const QRect viewportRect = q->viewport()->rect().translated(q->horizontalScrollBar()->value(), q->verticalScrollBar()->value()); + for (; tIt != tEnd; ++tIt) { + ThumbnailWidget *t = *tIt; + const QRect thumbRect = t->rect(); + if (!thumbRect.intersects(viewportRect)) + continue; + // add ThumbnailWidget to visible list + m_visibleThumbnails.push_back(t); + // if pixmap not present add it to requests + if (!t->page()->hasPixmap(q, t->pixmapWidth(), t->pixmapHeight())) { + Okular::PixmapRequest *p = new Okular::PixmapRequest(q, t->pageNumber(), t->pixmapWidth(), t->pixmapHeight(), THUMBNAILS_PRIO, Okular::PixmapRequest::Asynchronous); + requestedPixmaps.push_back(p); + } + } + + // actually request pixmaps + if (!requestedPixmaps.isEmpty()) + m_document->requestPixmaps(requestedPixmaps); +} + +void ThumbnailListPrivate::slotDelayTimeout() +{ + // resize the bookmark overlay + delete m_bookmarkOverlay; + const int expectedWidth = q->viewport()->width() / 4; + if (expectedWidth > 10) + m_bookmarkOverlay = new QPixmap(QIcon::fromTheme(QStringLiteral("bookmarks")).pixmap(expectedWidth)); + else + m_bookmarkOverlay = nullptr; + + // request pixmaps + slotRequestVisiblePixmaps(); +} +// END internal SLOTS + +void ThumbnailListPrivate::delayedRequestVisiblePixmaps(int delayMs) +{ + if (!m_delayTimer) { + m_delayTimer = new QTimer(q); + m_delayTimer->setSingleShot(true); + connect(m_delayTimer, &QTimer::timeout, this, &ThumbnailListPrivate::slotDelayTimeout); + } + m_delayTimer->start(delayMs); +} + +/** ThumbnailWidget implementation **/ + +ThumbnailWidget::ThumbnailWidget(ThumbnailListPrivate *parent, const Okular::Page *page) + : m_parent(parent) + , m_page(page) + , m_selected(false) + , m_pixmapWidth(10) + , m_pixmapHeight(10) +{ + m_labelNumber = m_page->number() + 1; + m_labelHeight = QFontMetrics(m_parent->font()).height(); +} + +void ThumbnailWidget::resizeFitWidth(int width) +{ + m_pixmapWidth = width - m_margin; + m_pixmapHeight = qRound(m_page->ratio() * (double)m_pixmapWidth); + m_rect.setSize(QSize(width, heightHint())); +} + +void ThumbnailWidget::setSelected(bool selected) +{ + // update selected state + if (m_selected != selected) { + m_selected = selected; + update(); + } +} + +void ThumbnailWidget::setVisibleRect(const Okular::NormalizedRect &rect) +{ + if (rect == m_visibleRect) + return; + + m_visibleRect = rect; + update(); +} + +void ThumbnailListPrivate::mousePressEvent(QMouseEvent *e) +{ + ThumbnailWidget *item = itemFor(e->pos()); + if (!item) { // mouse on the spacing between items + e->ignore(); + return; + } + + const QRect r = item->visibleRect(); + const int margin = ThumbnailWidget::margin(); + const QPoint p = e->pos() - item->pos(); + + if (e->button() != Qt::RightButton && r.contains(p - QPoint(margin / 2, margin / 2))) { + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); + m_mouseGrabItem = item; + m_pageCurrentlyGrabbed = item->pageNumber(); + m_mouseGrabItem = item; + } else { + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); + m_mouseGrabItem = nullptr; + } +} + +void ThumbnailListPrivate::mouseReleaseEvent(QMouseEvent *e) +{ + ThumbnailWidget *item = itemFor(e->pos()); + m_mouseGrabItem = item; + if (!item) { // mouse on the spacing between items + e->ignore(); + return; + } + + QRect r = item->visibleRect(); + const QPoint p = e->pos() - item->pos(); + + // jump center of viewport to cursor if it wasn't dragged + if (m_mouseGrabPos.isNull()) { + 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, nullptr, true); + } + setCursor(Qt::OpenHandCursor); + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); +} + +void ThumbnailListPrivate::mouseMoveEvent(QMouseEvent *e) +{ + if (e->buttons() == Qt::NoButton) { + ThumbnailWidget *item = itemFor(e->pos()); + if (!item) { // mouse on the spacing between items + e->ignore(); + return; + } + + 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); + } + + e->ignore(); + return; + } + // no item under the mouse or previously selected + if (!m_mouseGrabItem) { + e->ignore(); + return; + } + const QRect r = m_mouseGrabItem->rect(); + if (!m_mouseGrabPos.isNull()) { + const QPoint mousePos = e->pos(); + const QPoint delta = m_mouseGrabPos - mousePos; + m_mouseGrabPos = e->pos(); + // don't handle the mouse move, forward it to the thumbnail list + ThumbnailListPrivate::ChangePageDirection direction; + if ((direction = forwardTrack(delta, r.size())) != ThumbnailListPrivate::Null) { + // Changing the selected page + const int offset = getNewPageOffset(m_pageCurrentlyGrabbed, direction); + const ThumbnailWidget *newThumb = getThumbnailbyOffset(m_pageCurrentlyGrabbed, offset); + if (!newThumb) + return; + int newPageOn = newThumb->pageNumber(); + if (newPageOn == m_pageCurrentlyGrabbed || newPageOn < 0 || newPageOn >= (int)m_document->pages()) { + return; + } + Okular::DocumentViewport vp = m_document->viewport(); + const float origNormalX = vp.rePos.normalizedX; + const float origNormalY = vp.rePos.normalizedY; + vp = Okular::DocumentViewport(newPageOn); + vp.rePos.normalizedX = origNormalX; + vp.rePos.normalizedY = origNormalY; + if (direction == ThumbnailListPrivate::Up) { + vp.rePos.normalizedY = 1.0; + if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::FacingFirstCentered && !newPageOn) { + if (m_pageCurrentlyGrabbed == 1) + vp.rePos.normalizedX = origNormalX - 0.5; + else + vp.rePos.normalizedX = origNormalX + 0.5; + if (vp.rePos.normalizedX < 0.0) + vp.rePos.normalizedX = 0.0; + else if (vp.rePos.normalizedX > 1.0) + vp.rePos.normalizedX = 1.0; + } + } else if (direction == ThumbnailListPrivate::Down) { + vp.rePos.normalizedY = 0.0; + if (Okular::Settings::viewMode() == Okular::Settings::EnumViewMode::FacingFirstCentered && !m_pageCurrentlyGrabbed) { + if (origNormalX < 0.5) { + vp = Okular::DocumentViewport(--newPageOn); + vp.rePos.normalizedX = origNormalX + 0.5; + } else + vp.rePos.normalizedX = origNormalX - 0.5; + if (vp.rePos.normalizedX < 0.0) + vp.rePos.normalizedX = 0.0; + else if (vp.rePos.normalizedX > 1.0) + vp.rePos.normalizedX = 1.0; + } + } else if (Okular::Settings::viewMode() != Okular::Settings::EnumViewMode::Single) { + if (direction == ThumbnailListPrivate::Left) + vp.rePos.normalizedX = 1.0; + else + vp.rePos.normalizedX = 0.0; + } + vp.rePos.pos = Okular::DocumentViewport::Center; + vp.rePos.enabled = true; + m_document->setViewport(vp); + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); + m_pageCurrentlyGrabbed = newPageOn; + m_mouseGrabItem = getPageByNumber(m_pageCurrentlyGrabbed); + } + // wrap mouse from top to bottom + const QRect mouseContainer = QApplication::desktop()->screenGeometry(this); + QPoint currentMousePos = QCursor::pos(); + if (currentMousePos.y() <= mouseContainer.top() + 4) { + currentMousePos.setY(mouseContainer.bottom() - 5); + QCursor::setPos(currentMousePos); + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); + } + // wrap mouse from bottom to top + else if (currentMousePos.y() >= mouseContainer.bottom() - 4) { + currentMousePos.setY(mouseContainer.top() + 5); + QCursor::setPos(currentMousePos); + m_mouseGrabPos.setX(0); + m_mouseGrabPos.setY(0); + } + } else { + setCursor(Qt::ClosedHandCursor); + m_mouseGrabPos = e->pos(); + } +} + +void ThumbnailListPrivate::wheelEvent(QWheelEvent *e) +{ + const ThumbnailWidget *item = itemFor(e->pos()); + if (!item) { // wheeling on the spacing between items + e->ignore(); + return; + } + + const QRect r = item->visibleRect(); + const int margin = ThumbnailWidget::margin(); + + if (r.contains(e->pos() - QPoint(margin / 2, margin / 2)) && e->orientation() == Qt::Vertical && e->modifiers() == Qt::ControlModifier) { + m_document->setZoom(e->angleDelta().y()); + } else { + e->ignore(); + } +} + +void ThumbnailListPrivate::contextMenuEvent(QContextMenuEvent *e) +{ + const ThumbnailWidget *item = itemFor(e->pos()); + if (item) { + emit q->rightClick(item->page(), e->globalPos()); + } +} + +void ThumbnailWidget::paint(QPainter &p, const QRect _clipRect) +{ + const int width = m_pixmapWidth + m_margin; + QRect clipRect = _clipRect; + const QPalette pal = m_parent->palette(); + + // draw the bottom label + highlight mark + const QColor fillColor = m_selected ? pal.color(QPalette::Active, QPalette::Highlight) : pal.color(QPalette::Active, QPalette::Base); + p.fillRect(clipRect, fillColor); + p.setPen(m_selected ? pal.color(QPalette::Active, QPalette::HighlightedText) : pal.color(QPalette::Active, QPalette::Text)); + p.drawText(0, m_pixmapHeight + (m_margin - 3), width, m_labelHeight, Qt::AlignCenter, QString::number(m_labelNumber)); + + // draw page outline and pixmap + if (clipRect.top() < m_pixmapHeight + m_margin) { + // if page is bookmarked draw a colored border + const bool isBookmarked = m_parent->m_document->bookmarkManager()->isBookmarked(pageNumber()); + // draw the inner rect + p.setPen(isBookmarked ? QColor(0xFF8000) : Qt::black); + p.drawRect(m_margin / 2 - 1, m_margin / 2 - 1, m_pixmapWidth + 1, m_pixmapHeight + 1); + // draw the clear rect + p.setPen(isBookmarked ? QColor(0x804000) : pal.color(QPalette::Active, QPalette::Base)); + // draw the bottom and right shadow edges + if (!isBookmarked) { + int left, right, bottom, top; + left = m_margin / 2 + 1; + right = m_margin / 2 + m_pixmapWidth + 1; + bottom = m_pixmapHeight + m_margin / 2 + 1; + top = m_margin / 2 + 1; + p.setPen(Qt::gray); + p.drawLine(left, bottom, right, bottom); + p.drawLine(right, top, right, bottom); + } + + // draw the page using the shared PagePainter class + p.translate(m_margin / 2.0, m_margin / 2.0); + clipRect.translate(-m_margin / 2, -m_margin / 2); + clipRect = clipRect.intersected(QRect(0, 0, m_pixmapWidth, m_pixmapHeight)); + if (clipRect.isValid()) { + int flags = PagePainter::Accessibility | PagePainter::Highlights | PagePainter::Annotations; + PagePainter::paintPageOnPainter(&p, m_page, m_parent->q, flags, m_pixmapWidth, m_pixmapHeight, clipRect); + } + + if (!m_visibleRect.isNull()) { + p.save(); + p.setPen(QColor(255, 255, 0, 200)); + p.setBrush(QColor(0, 0, 0, 100)); + p.drawRect(m_visibleRect.geometry(m_pixmapWidth, m_pixmapHeight).adjusted(0, 0, -1, -1)); + p.restore(); + } + + // draw the bookmark overlay on the top-right corner + const QPixmap *bookmarkPixmap = m_parent->getBookmarkOverlay(); + if (isBookmarked && bookmarkPixmap) { + int pixW = bookmarkPixmap->width(), pixH = bookmarkPixmap->height(); + clipRect = clipRect.intersected(QRect(m_pixmapWidth - pixW, 0, pixW, pixH)); + if (clipRect.isValid()) + p.drawPixmap(m_pixmapWidth - pixW, -pixH / 8, *bookmarkPixmap); + } + } +} + +/** ThumbnailsController implementation **/ + +#define FILTERB_ID 1 + +ThumbnailController::ThumbnailController(QWidget *parent, ThumbnailList *list) + : QToolBar(parent) +{ + setObjectName(QStringLiteral("ThumbsControlBar")); + // change toolbar appearance + setIconSize(QSize(16, 16)); + setMovable(false); + QSizePolicy sp = sizePolicy(); + sp.setVerticalPolicy(QSizePolicy::Minimum); + setSizePolicy(sp); + + // insert a togglebutton [show only bookmarked pages] + // insertSeparator(); + QAction *showBoomarkOnlyAction = addAction(QIcon::fromTheme(QStringLiteral("bookmarks")), i18n("Show bookmarked pages only")); + showBoomarkOnlyAction->setCheckable(true); + connect(showBoomarkOnlyAction, &QAction::toggled, list, &ThumbnailList::slotFilterBookmarks); + showBoomarkOnlyAction->setChecked(Okular::Settings::filterBookmarks()); + // insertLineSeparator(); +} + +#include "thumbnaillist.moc" + +/* kate: replace-tabs on; indent-width 4; */ diff --git a/part/thumbnaillist.h b/part/thumbnaillist.h new file mode 100644 index 0000000..4bdebf6 --- /dev/null +++ b/part/thumbnaillist.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright (C) 2004 by Albert Astals Cid * + * * + * 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_THUMBNAILLIST_H_ +#define _OKULAR_THUMBNAILLIST_H_ + +#include +#include + +#include "core/observer.h" + +class ThumbnailListPrivate; + +namespace Okular +{ +class Document; +} + +/** + * @short A scrollview that displays page pixmap previews (aka thumbnails). + * + * ... + */ +class ThumbnailList : public QScrollArea, public Okular::DocumentObserver +{ + Q_OBJECT +public: + ThumbnailList(QWidget *parent, Okular::Document *document); + ~ThumbnailList() override; + + // inherited: create thumbnails ( inherited as a DocumentObserver ) + void notifySetup(const QVector &pages, int setupFlags) override; + // inherited: hilihght current thumbnail ( inherited as DocumentObserver ) + void notifyCurrentPageChanged(int previous, int current) override; + // inherited: redraw thumbnail ( inherited as DocumentObserver ) + void notifyPageChanged(int pageNumber, int changedFlags) override; + // inherited: request all visible pixmap (due to a global change or so..) + void notifyContentsCleared(int changedFlags) override; + // inherited: the visible areas of the page have changed + void notifyVisibleRectsChanged() override; + // inherited: tell if pixmap is hidden and can be unloaded + bool canUnloadPixmap(int pageNumber) const override; + + // redraw visible widgets (useful for refreshing contents...) + void updateWidgets(); + +public Q_SLOTS: + // these are connected to ThumbnailController buttons + void slotFilterBookmarks(bool filterOn); + +protected: + // scroll up/down the view + void keyPressEvent(QKeyEvent *keyEvent) override; + + // catch the viewport event and filter them if necessary + bool viewportEvent(QEvent *) override; + +Q_SIGNALS: + void rightClick(const Okular::Page *, const QPoint); + +private: + friend class ThumbnailListPrivate; + ThumbnailListPrivate *d; +}; + +/** + * @short A vertical boxed container with zero size hint (for insertion on left toolbox) + */ +class ThumbnailsBox : public QWidget +{ + Q_OBJECT + +public: + explicit ThumbnailsBox(QWidget *parent); + QSize sizeHint() const override; +}; + +/** + * @short A toolbar that sets ThumbnailList properties when clicking on items + * + * This class is the small toolbar that resides in the bottom of the + * ThumbnailsBox container (below ThumbnailList and the SearchLine) and + * emits signals whenever a button is pressed. A click action results + * in invoking some method (or slot) in ThumbnailList. + */ +class ThumbnailController : public QToolBar +{ + Q_OBJECT + +public: + ThumbnailController(QWidget *parent, ThumbnailList *thumbnailList); +}; + +#endif diff --git a/part/toc.cpp b/part/toc.cpp new file mode 100644 index 0000000..7bd2f75 --- /dev/null +++ b/part/toc.cpp @@ -0,0 +1,228 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "toc.h" + +// qt/kde includes +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +// local includes +#include "core/action.h" +#include "ktreeviewsearchline.h" +#include "pageitemdelegate.h" +#include "settings.h" +#include "tocmodel.h" + +TOC::TOC(QWidget *parent, Okular::Document *document) + : QWidget(parent) + , m_document(document) +{ + QVBoxLayout *mainlay = new QVBoxLayout(this); + mainlay->setSpacing(6); + + KTitleWidget *titleWidget = new KTitleWidget(this); + titleWidget->setLevel(2); + titleWidget->setText(i18n("Contents")); + mainlay->addWidget(titleWidget); + mainlay->setAlignment(titleWidget, Qt::AlignHCenter); + m_searchLine = new KTreeViewSearchLine(this); + mainlay->addWidget(m_searchLine); + m_searchLine->setPlaceholderText(i18n("Search...")); + m_searchLine->setCaseSensitivity(Okular::Settings::self()->contentsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive); + m_searchLine->setRegularExpression(Okular::Settings::self()->contentsSearchRegularExpression()); + connect(m_searchLine, &KTreeViewSearchLine::searchOptionsChanged, this, &TOC::saveSearchOptions); + + m_treeView = new QTreeView(this); + mainlay->addWidget(m_treeView); + m_model = new TOCModel(document, m_treeView); + m_treeView->setModel(m_model); + m_treeView->setSortingEnabled(false); + m_treeView->setRootIsDecorated(true); + m_treeView->setAlternatingRowColors(true); + m_treeView->setItemDelegate(new PageItemDelegate(m_treeView)); + m_treeView->header()->hide(); + m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); + connect(m_treeView, &QTreeView::clicked, this, &TOC::slotExecuted); + connect(m_treeView, &QTreeView::activated, this, &TOC::slotExecuted); + m_searchLine->setTreeView(m_treeView); +} + +TOC::~TOC() +{ + m_document->removeObserver(this); +} + +void TOC::notifySetup(const QVector & /*pages*/, int setupFlags) +{ + if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) + return; + + // clear contents + m_model->clear(); + + // request synopsis description (is a dom tree) + const Okular::DocumentSynopsis *syn = m_document->documentSynopsis(); + if (!syn) { + if (m_document->isOpened()) { + // Make sure we clear the reload old model data + m_model->setOldModelData(nullptr, QVector()); + } + emit hasTOC(false); + return; + } + + m_model->fill(syn); + emit hasTOC(!m_model->isEmpty()); +} + +void TOC::notifyCurrentPageChanged(int, int) +{ + m_model->setCurrentViewport(m_document->viewport()); +} + +void TOC::prepareForReload() +{ + if (m_model->isEmpty()) + return; + + const QVector list = expandedNodes(); + TOCModel *m = m_model; + m_model = new TOCModel(m_document, m_treeView); + m_model->setOldModelData(m, list); + m->setParent(nullptr); +} + +void TOC::rollbackReload() +{ + if (!m_model->hasOldModelData()) + return; + + TOCModel *m = m_model; + m_model = m->clearOldModelData(); + m_model->setParent(m_treeView); + delete m; +} + +void TOC::finishReload() +{ + m_treeView->setModel(m_model); + m_model->setParent(m_treeView); +} + +QVector TOC::expandedNodes(const QModelIndex &parent) const +{ + QVector list; + for (int i = 0; i < m_model->rowCount(parent); i++) { + const QModelIndex index = m_model->index(i, 0, parent); + if (m_treeView->isExpanded(index)) { + list << index; + } + if (m_model->hasChildren(index)) { + list << expandedNodes(index); + } + } + return list; +} + +void TOC::reparseConfig() +{ + m_searchLine->setCaseSensitivity(Okular::Settings::contentsSearchCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive); + m_searchLine->setRegularExpression(Okular::Settings::contentsSearchRegularExpression()); + m_treeView->update(); +} + +void TOC::slotExecuted(const QModelIndex &index) +{ + if (!index.isValid()) + return; + + QString url = m_model->urlForIndex(index); + if (!url.isEmpty()) { + Okular::BrowseAction action(QUrl::fromLocalFile(url)); + m_document->processAction(&action); + return; + } + + QString externalFileName = m_model->externalFileNameForIndex(index); + Okular::DocumentViewport viewport = m_model->viewportForIndex(index); + if (!externalFileName.isEmpty()) { + Okular::GotoAction action(externalFileName, viewport); + m_document->processAction(&action); + } else if (viewport.isValid()) { + m_document->setViewport(viewport); + } +} + +void TOC::saveSearchOptions() +{ + Okular::Settings::setContentsSearchRegularExpression(m_searchLine->regularExpression()); + Okular::Settings::setContentsSearchCaseSensitive(m_searchLine->caseSensitivity() == Qt::CaseSensitive ? true : false); + Okular::Settings::self()->save(); +} + +void TOC::contextMenuEvent(QContextMenuEvent *e) +{ + QModelIndex index = m_treeView->currentIndex(); + if (!index.isValid()) + return; + + Okular::DocumentViewport viewport = m_model->viewportForIndex(index); + + emit rightClick(viewport, e->globalPos(), m_model->data(index).toString()); +} + +void TOC::expandRecursively() +{ + QList worklist = {m_treeView->currentIndex()}; + if (!worklist[0].isValid()) { + return; + } + while (!worklist.isEmpty()) { + QModelIndex index = worklist.takeLast(); + m_treeView->expand(index); + for (int i = 0; i < m_model->rowCount(index); i++) { + worklist += m_model->index(i, 0, index); + } + } +} + +void TOC::collapseRecursively() +{ + QList worklist = {m_treeView->currentIndex()}; + if (!worklist[0].isValid()) { + return; + } + while (!worklist.isEmpty()) { + QModelIndex index = worklist.takeLast(); + m_treeView->collapse(index); + for (int i = 0; i < m_model->rowCount(index); i++) { + worklist += m_model->index(i, 0, index); + } + } +} + +void TOC::expandAll() +{ + m_treeView->expandAll(); +} + +void TOC::collapseAll() +{ + m_treeView->collapseAll(); +} diff --git a/part/toc.h b/part/toc.h new file mode 100644 index 0000000..3ce694d --- /dev/null +++ b/part/toc.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2004-2006 by Albert Astals Cid * + * * + * 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_TOC_H_ +#define _OKULAR_TOC_H_ + +#include "core/document.h" +#include "core/observer.h" +#include +#include + +#include "okularpart_export.h" + +class QModelIndex; +class QTreeView; +class KTreeViewSearchLine; +class TOCModel; + +namespace Okular +{ +class Document; +class PartTest; +} + +class OKULARPART_EXPORT TOC : public QWidget, public Okular::DocumentObserver +{ + Q_OBJECT + friend class Okular::PartTest; + +public: + TOC(QWidget *parent, Okular::Document *document); + ~TOC() override; + + // inherited from DocumentObserver + void notifySetup(const QVector &pages, int setupFlags) override; + void notifyCurrentPageChanged(int previous, int current) override; + + void reparseConfig(); + + void prepareForReload(); + void rollbackReload(); + void finishReload(); + +public Q_SLOTS: + void expandRecursively(); + void collapseRecursively(); + void expandAll(); + void collapseAll(); + +Q_SIGNALS: + void hasTOC(bool has); + void rightClick(const Okular::DocumentViewport &, const QPoint, const QString &); + +private Q_SLOTS: + void slotExecuted(const QModelIndex &); + void saveSearchOptions(); + +protected: + void contextMenuEvent(QContextMenuEvent *e) override; + +private: + QVector expandedNodes(const QModelIndex &parent = QModelIndex()) const; + + Okular::Document *m_document; + QTreeView *m_treeView; + KTreeViewSearchLine *m_searchLine; + TOCModel *m_model; +}; + +#endif diff --git a/part/tocmodel.cpp b/part/tocmodel.cpp new file mode 100644 index 0000000..32ab3a8 --- /dev/null +++ b/part/tocmodel.cpp @@ -0,0 +1,470 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ + +#include "tocmodel.h" + +#include +#include +#include +#include + +#include + +#include "core/document.h" +#include "core/page.h" + +Q_DECLARE_METATYPE(QModelIndex) + +struct TOCItem { + TOCItem(); + TOCItem(TOCItem *parent, const QDomElement &e); + ~TOCItem(); + + TOCItem(const TOCItem &) = delete; + TOCItem &operator=(const TOCItem &) = delete; + + QString text; + Okular::DocumentViewport viewport; + QString extFileName; + QString url; + bool highlight : 1; + TOCItem *parent; + QList children; + TOCModelPrivate *model; +}; + +class TOCModelPrivate +{ +public: + TOCModelPrivate(TOCModel *qq); + ~TOCModelPrivate(); + + void addChildren(const QDomNode &parentNode, TOCItem *parentItem); + QModelIndex indexForItem(TOCItem *item) const; + void findViewport(const Okular::DocumentViewport &viewport, TOCItem *item, QList &list) const; + + TOCModel *q; + TOCItem *root; + bool dirty : 1; + Okular::Document *document; + QList itemsToOpen; + QList currentPage; + TOCModel *m_oldModel; + QVector m_oldTocExpandedIndexes; +}; + +TOCItem::TOCItem() + : highlight(false) + , parent(nullptr) + , model(nullptr) +{ +} + +TOCItem::TOCItem(TOCItem *_parent, const QDomElement &e) + : highlight(false) + , parent(_parent) +{ + parent->children.append(this); + model = parent->model; + text = e.tagName(); + + // viewport loading + if (e.hasAttribute(QStringLiteral("Viewport"))) { + // if the node has a viewport, set it + viewport = Okular::DocumentViewport(e.attribute(QStringLiteral("Viewport"))); + } else if (e.hasAttribute(QStringLiteral("ViewportName"))) { + // if the node references a viewport, get the reference and set it + const QString &page = e.attribute(QStringLiteral("ViewportName")); + QString viewport_string = model->document->metaData(QStringLiteral("NamedViewport"), page).toString(); + if (!viewport_string.isEmpty()) + viewport = Okular::DocumentViewport(viewport_string); + } + + extFileName = e.attribute(QStringLiteral("ExternalFileName")); + url = e.attribute(QStringLiteral("URL")); +} + +TOCItem::~TOCItem() +{ + qDeleteAll(children); +} + +TOCModelPrivate::TOCModelPrivate(TOCModel *qq) + : q(qq) + , root(new TOCItem) + , dirty(false) + , m_oldModel(nullptr) +{ + root->model = this; +} + +TOCModelPrivate::~TOCModelPrivate() +{ + delete root; + delete m_oldModel; +} + +void TOCModelPrivate::addChildren(const QDomNode &parentNode, TOCItem *parentItem) +{ + TOCItem *currentItem = nullptr; + QDomNode n = parentNode.firstChild(); + while (!n.isNull()) { + // convert the node to an element (sure it is) + QDomElement e = n.toElement(); + + // insert the entry as top level (listview parented) or 2nd+ level + currentItem = new TOCItem(parentItem, e); + + // descend recursively and advance to the next node + if (e.hasChildNodes()) + addChildren(n, currentItem); + + // open/keep close the item + bool isOpen = false; + if (e.hasAttribute(QStringLiteral("Open"))) + isOpen = QVariant(e.attribute(QStringLiteral("Open"))).toBool(); + if (isOpen) + itemsToOpen.append(currentItem); + + n = n.nextSibling(); + emit q->countChanged(); + } +} + +QModelIndex TOCModelPrivate::indexForItem(TOCItem *item) const +{ + if (item->parent) { + int id = item->parent->children.indexOf(item); + if (id >= 0 && id < item->parent->children.count()) + return q->createIndex(id, 0, item); + } + return QModelIndex(); +} + +void TOCModelPrivate::findViewport(const Okular::DocumentViewport &viewport, TOCItem *item, QList &list) const +{ + TOCItem *todo = item; + + while (todo) { + const TOCItem *current = todo; + todo = nullptr; + TOCItem *pos = nullptr; + + for (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; + } + } +} + +TOCModel::TOCModel(Okular::Document *document, QObject *parent) + : QAbstractItemModel(parent) + , d(new TOCModelPrivate(this)) +{ + d->document = document; + + qRegisterMetaType(); +} + +TOCModel::~TOCModel() +{ + delete d; +} + +QHash TOCModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + roles[(int)PageItemDelegate::PageRole] = "page"; + roles[(int)PageItemDelegate::PageLabelRole] = "pageLabel"; + roles[HighlightRole] = "highlight"; + roles[HighlightedParentRole] = "highlightedParent"; + return roles; +} + +int TOCModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant TOCModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + TOCItem *item = static_cast(index.internalPointer()); + switch (role) { + case Qt::DisplayRole: + case Qt::ToolTipRole: + return item->text; + break; + case Qt::FontRole: + if (item->highlight) { + QFont font; + font.setBold(true); + + TOCItem *lastHighlighted = d->currentPage.last(); + + // in the mobile version our parent is not a QTreeView; embolden the last highlighted item + // TODO misusing parent() here, fix + QTreeView *view = dynamic_cast(QObject::parent()); + if (!view) { + if (item == lastHighlighted) + return font; + return QVariant(); + } + + if (view->isExpanded(index)) { + // if this is the last highlighted node, its child is on a page below, thus it gets emboldened + if (item == lastHighlighted) + return font; + } else { + return font; + } + } + break; + case HighlightRole: + return item->highlight; + case PageItemDelegate::PageRole: + if (item->viewport.isValid()) + return item->viewport.pageNumber + 1; + break; + case PageItemDelegate::PageLabelRole: + if (item->viewport.isValid() && item->viewport.pageNumber < int(d->document->pages())) + return d->document->page(item->viewport.pageNumber)->label(); + break; + } + return QVariant(); +} + +bool TOCModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return true; + + TOCItem *item = static_cast(parent.internalPointer()); + return !item->children.isEmpty(); +} + +QVariant TOCModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal) + return QVariant(); + + if (section == 0 && role == Qt::DisplayRole) + return QStringLiteral("Topics"); + + return QVariant(); +} + +QModelIndex TOCModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 || column != 0) + return QModelIndex(); + + TOCItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + if (row < item->children.count()) + return createIndex(row, column, item->children.at(row)); + + return QModelIndex(); +} + +QModelIndex TOCModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + TOCItem *item = static_cast(index.internalPointer()); + return d->indexForItem(item->parent); +} + +int TOCModel::rowCount(const QModelIndex &parent) const +{ + TOCItem *item = parent.isValid() ? static_cast(parent.internalPointer()) : d->root; + return item->children.count(); +} + +static QModelIndex indexForIndex(const QModelIndex &oldModelIndex, QAbstractItemModel *newModel) +{ + QModelIndex newModelIndex; + if (oldModelIndex.parent().isValid()) { + newModelIndex = newModel->index(oldModelIndex.row(), oldModelIndex.column(), indexForIndex(oldModelIndex.parent(), newModel)); + } else { + newModelIndex = newModel->index(oldModelIndex.row(), oldModelIndex.column()); + } + return newModelIndex; +} + +void TOCModel::fill(const Okular::DocumentSynopsis *toc) +{ + if (!toc) + return; + + clear(); + emit layoutAboutToBeChanged(); + d->addChildren(*toc, d->root); + d->dirty = true; + emit layoutChanged(); + if (equals(d->m_oldModel)) { + for (const QModelIndex &oldIndex : qAsConst(d->m_oldTocExpandedIndexes)) { + const QModelIndex index = indexForIndex(oldIndex, this); + if (!index.isValid()) + continue; + + // TODO misusing parent() here, fix + QMetaObject::invokeMethod(QObject::parent(), "expand", Qt::QueuedConnection, Q_ARG(QModelIndex, index)); + } + } else { + for (TOCItem *item : qAsConst(d->itemsToOpen)) { + const QModelIndex index = d->indexForItem(item); + if (!index.isValid()) + continue; + + // TODO misusing parent() here, fix + QMetaObject::invokeMethod(QObject::parent(), "expand", Qt::QueuedConnection, Q_ARG(QModelIndex, index)); + } + } + d->itemsToOpen.clear(); + delete d->m_oldModel; + d->m_oldModel = nullptr; + d->m_oldTocExpandedIndexes.clear(); +} + +void TOCModel::clear() +{ + if (!d->dirty) + return; + + beginResetModel(); + qDeleteAll(d->root->children); + d->root->children.clear(); + d->currentPage.clear(); + endResetModel(); + d->dirty = false; +} + +void TOCModel::setCurrentViewport(const Okular::DocumentViewport &viewport) +{ + for (TOCItem *item : qAsConst(d->currentPage)) { + QModelIndex index = d->indexForItem(item); + if (!index.isValid()) + continue; + + item->highlight = false; + emit dataChanged(index, index); + } + d->currentPage.clear(); + + QList newCurrentPage; + d->findViewport(viewport, d->root, newCurrentPage); + + d->currentPage = newCurrentPage; + + for (TOCItem *item : qAsConst(d->currentPage)) { + QModelIndex index = d->indexForItem(item); + if (!index.isValid()) + continue; + + item->highlight = true; + emit dataChanged(index, index); + } +} + +bool TOCModel::isEmpty() const +{ + return d->root->children.isEmpty(); +} + +bool TOCModel::equals(const TOCModel *model) const +{ + if (model) + return checkequality(model); + else + return false; +} + +void TOCModel::setOldModelData(TOCModel *model, const QVector &list) +{ + delete d->m_oldModel; + d->m_oldModel = model; + d->m_oldTocExpandedIndexes = list; +} + +bool TOCModel::hasOldModelData() const +{ + return (d->m_oldModel != nullptr); +} + +TOCModel *TOCModel::clearOldModelData() const +{ + TOCModel *oldModel = d->m_oldModel; + d->m_oldModel = nullptr; + d->m_oldTocExpandedIndexes.clear(); + return oldModel; +} + +QString TOCModel::externalFileNameForIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return QString(); + + TOCItem *item = static_cast(index.internalPointer()); + return item->extFileName; +} + +Okular::DocumentViewport TOCModel::viewportForIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return Okular::DocumentViewport(); + + TOCItem *item = static_cast(index.internalPointer()); + return item->viewport; +} + +QString TOCModel::urlForIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return QString(); + + TOCItem *item = static_cast(index.internalPointer()); + return item->url; +} + +bool TOCModel::checkequality(const TOCModel *model, const QModelIndex &parentA, const QModelIndex &parentB) const +{ + if (rowCount(parentA) != model->rowCount(parentB)) + return false; + for (int i = 0; i < rowCount(parentA); i++) { + QModelIndex indxA = index(i, 0, parentA); + QModelIndex indxB = model->index(i, 0, parentB); + if (indxA.data() != indxB.data()) { + return false; + } + if (hasChildren(indxA) != model->hasChildren(indxB)) { + return false; + } + if (!checkequality(model, indxA, indxB)) { + return false; + } + } + return true; +} +#include "moc_tocmodel.cpp" diff --git a/part/tocmodel.h b/part/tocmodel.h new file mode 100644 index 0000000..c82ba86 --- /dev/null +++ b/part/tocmodel.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2007 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 TOCMODEL_H +#define TOCMODEL_H + +#include "pageitemdelegate.h" +#include +#include + +namespace Okular +{ +class Document; +class DocumentSynopsis; +class DocumentViewport; +} + +class TOCModelPrivate; + +class TOCModel : public QAbstractItemModel +{ + Q_OBJECT + /** + * How many items are in this model, useful for QML + */ + Q_PROPERTY(int count READ count NOTIFY countChanged) + +public: + enum Roles { HighlightRole = PageItemDelegate::PageLabelRole + 1, HighlightedParentRole }; + + explicit TOCModel(Okular::Document *document, QObject *parent = nullptr); + ~TOCModel() override; + + // reimplementations from QAbstractItemModel + QHash roleNames() const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + void fill(const Okular::DocumentSynopsis *toc); + void clear(); + void setCurrentViewport(const Okular::DocumentViewport &viewport); + + bool isEmpty() const; + bool equals(const TOCModel *model) const; + void setOldModelData(TOCModel *model, const QVector &list); + bool hasOldModelData() const; + TOCModel *clearOldModelData() const; + + QString externalFileNameForIndex(const QModelIndex &index) const; + Okular::DocumentViewport viewportForIndex(const QModelIndex &index) const; + QString urlForIndex(const QModelIndex &index) const; + + int count() const + { + return rowCount(); + } + +Q_SIGNALS: + void countChanged(); + +private: + // storage + friend class TOCModelPrivate; + TOCModelPrivate *const d; + bool checkequality(const TOCModel *model, const QModelIndex &parentA = QModelIndex(), const QModelIndex &parentB = QModelIndex()) const; +}; + +#endif diff --git a/part/toggleactionmenu.cpp b/part/toggleactionmenu.cpp new file mode 100644 index 0000000..f78cd6d --- /dev/null +++ b/part/toggleactionmenu.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2019 by David Hurka * + * * + * Inspired by and replacing toolaction.h by: * + * Copyright (C) 2004-2006 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "toggleactionmenu.h" + +#include +#include + +ToggleActionMenu::ToggleActionMenu(QObject *parent) + : ToggleActionMenu(QIcon(), QString(), parent) +{ +} + +ToggleActionMenu::ToggleActionMenu(const QString &text, QObject *parent) + : ToggleActionMenu(QIcon(), text, parent) +{ +} + +ToggleActionMenu::ToggleActionMenu(const QIcon &icon, const QString &text, QObject *parent, PopupMode popupMode, MenuLogic logic) + : KActionMenu(icon, text, parent) + , m_defaultAction(nullptr) + , m_suggestedDefaultAction(nullptr) + , m_menuLogic(logic) +{ + connect(this, &QAction::changed, this, &ToggleActionMenu::updateButtons); + + if (popupMode == DelayedPopup) { + setDelayed(true); + } else { + setDelayed(false); + } + setStickyMenu(false); + + if (logic & ImplicitDefaultAction) { + connect(menu(), &QMenu::triggered, this, &ToggleActionMenu::setDefaultAction); + } +} + +QWidget *ToggleActionMenu::createWidget(QWidget *parent) +{ + QToolButton *button = qobject_cast(KActionMenu::createWidget(parent)); + if (!button) { + // This function is used to add a button into the toolbar. + // KActionMenu will plug itself as QToolButton. + // So, if no QToolButton was returned, this was not called the intended way. + return button; + } + + // Remove this menu action from the button, + // so it doesn't compose a menu of this menu action and its own menu. + button->removeAction(this); + // The button has lost the menu now, let it use the correct menu. + button->setMenu(menu()); + + m_buttons.append(QPointer(button)); + + // Apply other properties to the button. + updateButtons(); + + return button; +} + +void ToggleActionMenu::setDefaultAction(QAction *action) +{ + m_defaultAction = action; + updateButtons(); +} + +void ToggleActionMenu::suggestDefaultAction(QAction *action) +{ + m_suggestedDefaultAction = action; +} + +QAction *ToggleActionMenu::checkedAction(QMenu *menu) const +{ + // Look at each action a in the menu whether it is checked. + // If a is a menu, recursively call checkedAction(). + const QList actions = menu->actions(); + for (QAction *a : actions) { + if (a->isChecked()) { + return a; + } else if (a->menu()) { + QAction *b = checkedAction(a->menu()); + if (b) { + return b; + } + } + } + return nullptr; +} + +void ToggleActionMenu::updateButtons() +{ + for (const QPointer &button : qAsConst(m_buttons)) { + if (button) { + button->setDefaultAction(defaultAction()); + + // Override some properties of the default action, + // where the property of this menu makes more sense. + button->setEnabled(isEnabled()); + + if (delayed()) { + button->setPopupMode(QToolButton::DelayedPopup); + } else if (stickyMenu()) { + button->setPopupMode(QToolButton::InstantPopup); + } else { + button->setPopupMode(QToolButton::MenuButtonPopup); + } + } + } +} + +QAction *ToggleActionMenu::defaultAction() +{ + if ((m_menuLogic & ImplicitDefaultAction) && !m_defaultAction) { + m_defaultAction = checkedAction(menu()); + } + if (!m_defaultAction) { + m_defaultAction = m_suggestedDefaultAction; + } + return m_defaultAction; +} diff --git a/part/toggleactionmenu.h b/part/toggleactionmenu.h new file mode 100644 index 0000000..cb61f59 --- /dev/null +++ b/part/toggleactionmenu.h @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2019 by David Hurka * + * * + * Inspired by and replacing toolaction.h by: * + * Copyright (C) 2004-2006 by Albert Astals Cid * + * * + * 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 TOGGLEACTIONMENU_H +#define TOGGLEACTIONMENU_H + +#include +#include +#include + +/** + * @brief A KActionMenu, with allows to set the default action of its toolbar buttons. + * + * Usually, a KActionMenu creates toolbar buttons which reflect its own action properties + * (icon, text, tooltip, checked state,...), as it is a QAction itself. + * + * ToggleActionMenu will use its own action properties only when plugged as submenu in another menu. + * The default action of the toolbar buttons can easily be changed with the slot setDefaultAction(). + * + * Naming: The user can *Toggle* the checked state of an *Action* by directly clicking the toolbar button, + * but can also open a *Menu*. + * + * @par Intention + * Setting the default action of the toolbar button can be useful for: + * * Providing the most probably needed entry of a menu directly on the menu button. + * * Showing the last used menu entry on the menu button, including its checked state. + * The advantage is that the user often does not need to open the menu, + * and that the toolbar button shows additional information + * like checked state or the user's last selection. + * + * This shall replace the former ToolAction in Okular, + * while being flexible enough for other (planned) action menus. + */ +class ToggleActionMenu : public KActionMenu +{ + Q_OBJECT + +public: + /** + * Defines how the menu behaves. + */ + enum MenuLogic { + DefaultLogic = 0x0, + /** + * Automatically makes the triggered action the default action, even if in a submenu. + * When a toolbar button is constructed, + * the default action is set to the default action set with setDefaultAction() before, + * otherwise to the first checked action in the menu, + * otherwise to the action suggested with suggestDefaultAction(). + */ + ImplicitDefaultAction = 0x1 + }; + + enum PopupMode { DelayedPopup, MenuButtonPopup }; + + explicit ToggleActionMenu(QObject *parent); + ToggleActionMenu(const QString &text, QObject *parent); + /** + * Constructs an empty ToggleActionMenu. + * + * @param icon The icon of this menu, when plugged into another menu. + * @param text The name of this menu, when plugged into another menu. + * @param parent Parent @c QOject. + * @param popupMode The popup mode of the toolbar buttons. + * You will want to use @c DelayedPopup or @c MenuButtonPopup, + * @c InstantPopup would make @c ToggleActionMenu pointless. + * @param logic To define special behaviour of @c ToggleActionMenu, + * to simplify the usage. + */ + ToggleActionMenu(const QIcon &icon, const QString &text, QObject *parent, PopupMode popupMode = MenuButtonPopup, MenuLogic logic = DefaultLogic); + + QWidget *createWidget(QWidget *parent) override; + + /** + * Returns the current default action of the toolbar buttons. + * + * In ImplicitDefaultAction mode, + * when the default action was not yet set with setDefaultAction(), + * it will determine it from the first checked action in the menu, + * otherwise from the action set with suggestDefaultAction(). + */ + QAction *defaultAction(); + + /** + * Suggests a default action to be used as fallback. + * + * It will be used if the default action is not determined another way. + * This is useful for ImplicitDefaultAction mode, + * when you can not guarantee that one action in the menu + * will be checked. + * + * @note + * In DefaultLogic mode, or when you already have called setDefaultAction(), + * you have to use setDefaultAction() instead. + */ + void suggestDefaultAction(QAction *action); + +public slots: + /** + * Sets the default action of the toolbar buttons. + * + * This action will be triggered by clicking directly on the toolbar buttons. + * It will also set the text, icon, checked state, etc. of the toolbar buttons. + * + * @note + * The default action will not set the enabled state or popup mode of the menu buttons. + * These properties are still set by the corresponding properties of this ToggleActionMenu. + * + * @warning + * The action will not be added to the menu, + * it usually makes sense to addAction() it before to setDefaultAction() it. + * + * @see suggestDefaultAction() + */ + void setDefaultAction(QAction *action); + +private: + QAction *m_defaultAction; + QAction *m_suggestedDefaultAction; + QList> m_buttons; + MenuLogic m_menuLogic; + + /** + * Returns the first checked action in @p menu and its submenus, + * or nullptr if no action is checked. + */ + QAction *checkedAction(QMenu *menu) const; + +private slots: + /** + * Updates the toolbar buttons, using both the default action and properties of this menu itself. + * + * This ensures that the toolbar buttons reflect e. g. a disabled state of this menu. + */ + void updateButtons(); +}; + +#endif // TOGGLEACTIONMENU_H diff --git a/part/tts.cpp b/part/tts.cpp new file mode 100644 index 0000000..ede555b --- /dev/null +++ b/part/tts.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "tts.h" + +#include +#include + +#include + +#include "settings.h" + +/* Private storage. */ +class OkularTTS::Private +{ +public: + Private(OkularTTS *qq) + : q(qq) + , speech(new QTextToSpeech(Okular::Settings::ttsEngine())) + { + } + + ~Private() + { + delete speech; + speech = nullptr; + } + + OkularTTS *q; + QTextToSpeech *speech; + // Which speech engine was used when above object was created. + // When the setting changes, we need to stop speaking and recreate. + QString speechEngine; +}; + +OkularTTS::OkularTTS(QObject *parent) + : QObject(parent) + , d(new Private(this)) +{ + // Initialize speechEngine so we can reinitialize if it changes. + d->speechEngine = Okular::Settings::ttsEngine(); + connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged); + connect(Okular::Settings::self(), &KConfigSkeleton::configChanged, this, &OkularTTS::slotConfigChanged); +} + +OkularTTS::~OkularTTS() +{ + delete d; +} + +void OkularTTS::say(const QString &text) +{ + if (text.isEmpty()) + return; + + d->speech->say(text); +} + +void OkularTTS::stopAllSpeechs() +{ + if (!d->speech) + return; + + d->speech->stop(); +} + +void OkularTTS::pauseResumeSpeech() +{ + if (!d->speech) + return; + + if (d->speech->state() == QTextToSpeech::Speaking) + d->speech->pause(); + else + d->speech->resume(); +} + +void OkularTTS::slotSpeechStateChanged(QTextToSpeech::State state) +{ + if (state == QTextToSpeech::Speaking) { + emit isSpeaking(true); + emit canPauseOrResume(true); + } else { + emit isSpeaking(false); + if (state == QTextToSpeech::Paused) + emit canPauseOrResume(true); + else + emit canPauseOrResume(false); + } +} + +void OkularTTS::slotConfigChanged() +{ + const QString engine = Okular::Settings::ttsEngine(); + if (engine != d->speechEngine) { + d->speech->stop(); + delete d->speech; + d->speech = new QTextToSpeech(engine); + connect(d->speech, &QTextToSpeech::stateChanged, this, &OkularTTS::slotSpeechStateChanged); + d->speechEngine = engine; + } +} diff --git a/part/tts.h b/part/tts.h new file mode 100644 index 0000000..b31af92 --- /dev/null +++ b/part/tts.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * 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 _TTS_H_ +#define _TTS_H_ + +#include +#include + +class OkularTTS : public QObject +{ + Q_OBJECT +public: + explicit OkularTTS(QObject *parent = nullptr); + ~OkularTTS() override; + + void say(const QString &text); + void stopAllSpeechs(); + void pauseResumeSpeech(); + +public slots: + void slotSpeechStateChanged(QTextToSpeech::State state); + void slotConfigChanged(); + +signals: + void isSpeaking(bool speaking); + void canPauseOrResume(bool speakingOrPaused); + +private: + // private storage + class Private; + Private *d; +}; + +#endif diff --git a/part/url_utils.h b/part/url_utils.h new file mode 100644 index 0000000..1bcab02 --- /dev/null +++ b/part/url_utils.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2013 Jaydeep Solanki * + * * + * 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 URL_UTILS_H +#define URL_UTILS_H + +#include + +namespace UrlUtils +{ +QString getUrl(QString txt) +{ + // match the url + QRegularExpression reg(QStringLiteral("\\b((https?|ftp)://(www\\d{0,3}[.])?[\\S]+)|((www\\d{0,3}[.])[\\S]+)")); + // blocks from detecting invalid urls + QRegularExpression reg1(QStringLiteral("[\\w'\"\\(\\)]+https?://|[\\w'\"\\(\\)]+ftp://|[\\w'\"\\(\\)]+www\\d{0,3}[.]")); + txt = txt.remove(QLatin1Char('\n')); + + if (reg1.match(txt).hasMatch()) { // return early if there is a match (url is not valid) + return QString(); + } + + QRegularExpressionMatch match = reg.match(txt); + QString url = match.captured(); + if (match.hasMatch() && QUrl(url).isValid()) { + if (url.startsWith(QLatin1String("www"))) { + url.prepend(QLatin1String("http://")); + } + return url; + } + + return QString(); +} +} + +#endif diff --git a/part/videowidget.cpp b/part/videowidget.cpp new file mode 100644 index 0000000..d6197b4 --- /dev/null +++ b/part/videowidget.cpp @@ -0,0 +1,418 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#include "videowidget.h" + +// qt/kde includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "core/annotations.h" +#include "core/area.h" +#include "core/document.h" +#include "core/movie.h" +#include "snapshottaker.h" + +static QAction *createToolBarButtonWithWidgetPopup(QToolBar *toolBar, QWidget *widget, const QIcon &icon) +{ + QToolButton *button = new QToolButton(toolBar); + QAction *action = toolBar->addWidget(button); + button->setAutoRaise(true); + button->setIcon(icon); + button->setPopupMode(QToolButton::InstantPopup); + QMenu *menu = new QMenu(button); + button->setMenu(menu); + QWidgetAction *widgetAction = new QWidgetAction(menu); + QWidget *dummy = new QWidget(menu); + widgetAction->setDefaultWidget(dummy); + QVBoxLayout *dummyLayout = new QVBoxLayout(dummy); + dummyLayout->setContentsMargins(5, 5, 5, 5); + dummyLayout->addWidget(widget); + menu->addAction(widgetAction); + return action; +} + +/* Private storage. */ +class VideoWidget::Private +{ +public: + Private(Okular::Movie *m, Okular::Document *doc, VideoWidget *qq) + : q(qq) + , movie(m) + , document(doc) + , player(nullptr) + , loaded(false) + { + } + + ~Private() + { + if (player) + player->stop(); + } + + enum PlayPauseMode { PlayMode, PauseMode }; + + void load(); + void setupPlayPauseAction(PlayPauseMode mode); + void setPosterImage(const QImage &); + void takeSnapshot(); + void videoStopped(); + void stateChanged(Phonon::State newState); + + // slots + void finished(); + void playOrPause(); + + VideoWidget *q; + Okular::Movie *movie; + Okular::Document *document; + Okular::NormalizedRect geom; + Phonon::VideoPlayer *player; + Phonon::SeekSlider *seekSlider; + QToolBar *controlBar; + QAction *playPauseAction; + QAction *stopAction; + QAction *seekSliderAction; + QAction *seekSliderMenuAction; + QStackedLayout *pageLayout; + QLabel *posterImagePage; + bool loaded : 1; + double repetitionsLeft; +}; + +static QUrl urlFromUrlString(const QString &url, Okular::Document *document) +{ + QUrl newurl; + if (url.startsWith(QLatin1Char('/'))) { + newurl = QUrl::fromLocalFile(url); + } else { + newurl = QUrl(url); + if (newurl.isRelative()) { + newurl = document->currentDocument().adjusted(QUrl::RemoveFilename); + newurl.setPath(newurl.path() + url); + } + } + return newurl; +} + +void VideoWidget::Private::load() +{ + repetitionsLeft = movie->playRepetitions(); + if (loaded) + return; + + loaded = true; + + player->load(urlFromUrlString(movie->url(), document)); + + connect(player->mediaObject(), &Phonon::MediaObject::stateChanged, q, [this](Phonon::State s) { stateChanged(s); }); + + seekSlider->setEnabled(true); +} + +void VideoWidget::Private::setupPlayPauseAction(PlayPauseMode mode) +{ + if (mode == PlayMode) { + playPauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); + playPauseAction->setText(i18nc("start the movie playback", "Play")); + } else if (mode == PauseMode) { + playPauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); + playPauseAction->setText(i18nc("pause the movie playback", "Pause")); + } +} + +void VideoWidget::Private::takeSnapshot() +{ + const QUrl url = urlFromUrlString(movie->url(), document); + SnapshotTaker *taker = new SnapshotTaker(url, q); + + q->connect(taker, &SnapshotTaker::finished, q, [this](const QImage &image) { setPosterImage(image); }); +} + +void VideoWidget::Private::videoStopped() +{ + if (movie->showPosterImage()) + pageLayout->setCurrentIndex(1); + else + q->hide(); +} + +void VideoWidget::Private::finished() +{ + switch (movie->playMode()) { + case Okular::Movie::PlayLimited: + case Okular::Movie::PlayOpen: + repetitionsLeft -= 1.0; + if (repetitionsLeft < 1e-5) { // allow for some calculation error + // playback has ended + stopAction->setEnabled(false); + setupPlayPauseAction(PlayMode); + if (movie->playMode() == Okular::Movie::PlayLimited) + controlBar->setVisible(false); + videoStopped(); + } else + // not done yet, repeat + // if repetitionsLeft is less than 1, we are supposed to stop midway, but not even Adobe reader does this + player->play(); + break; + case Okular::Movie::PlayRepeat: + // repeat the playback + player->play(); + break; + case Okular::Movie::PlayPalindrome: + // FIXME we should play backward, but we cannot + player->play(); + break; + } +} + +void VideoWidget::Private::playOrPause() +{ + if (player->isPlaying()) { + player->pause(); + setupPlayPauseAction(PlayMode); + } else { + q->play(); + } +} + +void VideoWidget::Private::setPosterImage(const QImage &image) +{ + if (!image.isNull()) { + // cache the snapshot image + movie->setPosterImage(image); + } + + posterImagePage->setPixmap(QPixmap::fromImage(image)); +} + +void VideoWidget::Private::stateChanged(Phonon::State newState) +{ + if (newState == Phonon::PlayingState) + pageLayout->setCurrentIndex(0); +} + +VideoWidget::VideoWidget(const Okular::Annotation *annotation, Okular::Movie *movie, Okular::Document *document, QWidget *parent) + : QWidget(parent) + , d(new Private(movie, document, this)) +{ + // do not propagate the mouse events to the parent widget; + // they should be tied to this widget, not spread around... + setAttribute(Qt::WA_NoMousePropagation); + + // Setup player page + QWidget *playerPage = new QWidget(this); + + QVBoxLayout *mainlay = new QVBoxLayout(playerPage); + mainlay->setContentsMargins(0, 0, 0, 0); + mainlay->setSpacing(0); + + d->player = new Phonon::VideoPlayer(Phonon::NoCategory, playerPage); + d->player->installEventFilter(playerPage); + mainlay->addWidget(d->player); + + d->controlBar = new QToolBar(playerPage); + d->controlBar->setIconSize(QSize(16, 16)); + d->controlBar->setAutoFillBackground(true); + mainlay->addWidget(d->controlBar); + + d->playPauseAction = new QAction(d->controlBar); + d->controlBar->addAction(d->playPauseAction); + d->setupPlayPauseAction(Private::PlayMode); + d->stopAction = d->controlBar->addAction(QIcon::fromTheme(QStringLiteral("media-playback-stop")), i18nc("stop the movie playback", "Stop"), this, SLOT(stop())); + d->stopAction->setEnabled(false); + d->controlBar->addSeparator(); + d->seekSlider = new Phonon::SeekSlider(d->player->mediaObject(), d->controlBar); + d->seekSliderAction = d->controlBar->addWidget(d->seekSlider); + d->seekSlider->setEnabled(false); + + Phonon::SeekSlider *verticalSeekSlider = new Phonon::SeekSlider(d->player->mediaObject(), nullptr); + verticalSeekSlider->setMaximumHeight(100); + d->seekSliderMenuAction = createToolBarButtonWithWidgetPopup(d->controlBar, verticalSeekSlider, QIcon::fromTheme(QStringLiteral("player-time"))); + d->seekSliderMenuAction->setVisible(false); + + d->controlBar->setVisible(movie->showControls()); + + connect(d->player, &Phonon::VideoPlayer::finished, this, [this] { d->finished(); }); + connect(d->playPauseAction, &QAction::triggered, this, [this] { d->playOrPause(); }); + + d->geom = annotation->transformedBoundingRectangle(); + + // Setup poster image page + d->posterImagePage = new QLabel; + d->posterImagePage->setScaledContents(true); + d->posterImagePage->installEventFilter(this); + d->posterImagePage->setCursor(Qt::PointingHandCursor); + + d->pageLayout = new QStackedLayout(this); + d->pageLayout->setMargin(0); + d->pageLayout->setSpacing(0); + d->pageLayout->addWidget(playerPage); + d->pageLayout->addWidget(d->posterImagePage); + + if (movie->showPosterImage()) { + d->pageLayout->setCurrentIndex(1); + + const QImage posterImage = movie->posterImage(); + if (posterImage.isNull()) { + d->takeSnapshot(); + } else { + d->setPosterImage(posterImage); + } + } else { + d->pageLayout->setCurrentIndex(0); + } +} + +VideoWidget::~VideoWidget() +{ + delete d; +} + +void VideoWidget::setNormGeometry(const Okular::NormalizedRect &rect) +{ + d->geom = rect; +} + +Okular::NormalizedRect VideoWidget::normGeometry() const +{ + return d->geom; +} + +bool VideoWidget::isPlaying() const +{ + return d->player->isPlaying(); +} + +void VideoWidget::pageInitialized() +{ + hide(); +} + +void VideoWidget::pageEntered() +{ + if (d->movie->showPosterImage()) { + d->pageLayout->setCurrentIndex(1); + show(); + } + + if (d->movie->autoPlay()) { + show(); + QMetaObject::invokeMethod(this, "play", Qt::QueuedConnection); + } +} + +void VideoWidget::pageLeft() +{ + d->player->stop(); + d->videoStopped(); + + hide(); +} + +void VideoWidget::play() +{ + d->controlBar->setVisible(d->movie->showControls()); + d->load(); + // if d->repetitionsLeft is less than 1, we are supposed to stop midway, but not even Adobe reader does this + d->player->play(); + d->stopAction->setEnabled(true); + d->setupPlayPauseAction(Private::PauseMode); +} + +void VideoWidget::stop() +{ + d->player->stop(); + d->stopAction->setEnabled(false); + d->setupPlayPauseAction(Private::PlayMode); +} + +void VideoWidget::pause() +{ + d->player->pause(); + d->setupPlayPauseAction(Private::PlayMode); +} + +bool VideoWidget::eventFilter(QObject *object, QEvent *event) +{ + if (object == d->player || object == d->posterImagePage) { + switch (event->type()) { + case QEvent::MouseButtonPress: { + QMouseEvent *me = static_cast(event); + if (me->button() == Qt::LeftButton) { + if (!d->player->isPlaying()) { + play(); + } + event->accept(); + } + break; + } + case QEvent::Wheel: { + if (object == d->posterImagePage) { + QWheelEvent *we = static_cast(event); + + // forward wheel events to parent widget + QWheelEvent *copy = new QWheelEvent(we->pos(), we->globalPos(), we->angleDelta().y(), we->buttons(), we->modifiers(), we->orientation()); + QCoreApplication::postEvent(parentWidget(), copy); + } + break; + } + default:; + } + } + + return false; +} + +bool VideoWidget::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::ToolTip: + // "eat" the help events (= tooltips), avoid parent widgets receiving them + event->accept(); + return true; + break; + default:; + } + + return QWidget::event(event); +} + +void VideoWidget::resizeEvent(QResizeEvent *event) +{ + const QSize &s = event->size(); + int usedSpace = d->seekSlider->geometry().left() + d->seekSlider->iconSize().width(); + // try to give the slider at least 30px of space + if (s.width() < (usedSpace + 30)) { + d->seekSliderAction->setVisible(false); + d->seekSliderMenuAction->setVisible(true); + } else { + d->seekSliderAction->setVisible(true); + d->seekSliderMenuAction->setVisible(false); + } +} + +#include "moc_videowidget.cpp" diff --git a/part/videowidget.h b/part/videowidget.h new file mode 100644 index 0000000..2463b77 --- /dev/null +++ b/part/videowidget.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * 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_VIDEOWIDGET_H_ +#define _OKULAR_VIDEOWIDGET_H_ + +#include + +namespace Okular +{ +class Annotation; +class Document; +class Movie; +class NormalizedRect; +} + +class VideoWidget : public QWidget +{ + Q_OBJECT +public: + VideoWidget(const Okular::Annotation *annot, Okular::Movie *movie, Okular::Document *document, QWidget *parent = nullptr); + ~VideoWidget() override; + + void setNormGeometry(const Okular::NormalizedRect &rect); + Okular::NormalizedRect normGeometry() const; + + bool isPlaying() const; + + /** + * This method is called when the page the video widget is located on has been initialized. + */ + void pageInitialized(); + + /** + * This method is called when the page the video widget is located on has been entered. + */ + void pageEntered(); + + /** + * This method is called when the page the video widget is located on has been left. + */ + void pageLeft(); + +public Q_SLOTS: + void play(); + void pause(); + void stop(); + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + bool event(QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + +private: + // private storage + class Private; + Private *d; +}; + +#endif diff --git a/part/widgetannottools.cpp b/part/widgetannottools.cpp new file mode 100644 index 0000000..5dfb55d --- /dev/null +++ b/part/widgetannottools.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * * + * 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. * + ***************************************************************************/ + +#include "widgetannottools.h" +#include "editannottooldialog.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pageviewannotator.h" + +// Used to store tools' XML description in m_list's items +static const int ToolXmlRole = Qt::UserRole; + +WidgetAnnotTools::WidgetAnnotTools(QWidget *parent) + : WidgetConfigurationToolsBase(parent) +{ +} + +WidgetAnnotTools::~WidgetAnnotTools() +{ +} + +/* Before returning the XML strings, this functions updates the id and + * shortcut properties. + * Note: The shortcut is only assigned to the first nine tools */ +QStringList WidgetAnnotTools::tools() const +{ + QStringList res; + + const int count = m_list->count(); + for (int i = 0; i < count; ++i) { + QListWidgetItem *listEntry = m_list->item(i); + + // Parse associated DOM data + QDomDocument doc; + doc.setContent(listEntry->data(ToolXmlRole).value()); + + // Set id + QDomElement toolElement = doc.documentElement(); + toolElement.setAttribute(QStringLiteral("id"), i + 1); + + // Remove old shortcut, if any + QDomNode oldShortcut = toolElement.elementsByTagName(QStringLiteral("shortcut")).item(0); + if (oldShortcut.isElement()) + toolElement.removeChild(oldShortcut); + + // Create new shortcut element (only the first 9 tools are assigned a shortcut key) + if (i < 9) { + QDomElement newShortcut = doc.createElement(QStringLiteral("shortcut")); + newShortcut.appendChild(doc.createTextNode(QString::number(i + 1))); + toolElement.appendChild(newShortcut); + } + + // Append to output + res << doc.toString(-1); + } + + return res; +} + +void WidgetAnnotTools::setTools(const QStringList &items) +{ + m_list->clear(); + + // Parse each string and populate the list widget + for (const QString &toolXml : items) { + QDomDocument entryParser; + if (!entryParser.setContent(toolXml)) { + qWarning() << "Skipping malformed tool XML string"; + break; + } + + QDomElement toolElement = entryParser.documentElement(); + if (toolElement.tagName() == QLatin1String("tool")) { + // Create list item and attach the source XML string as data + QString itemText = toolElement.attribute(QStringLiteral("name")); + if (itemText.isEmpty()) + itemText = PageViewAnnotator::defaultToolName(toolElement); + QListWidgetItem *listEntry = new QListWidgetItem(itemText, m_list); + listEntry->setData(ToolXmlRole, QVariant::fromValue(toolXml)); + listEntry->setIcon(PageViewAnnotator::makeToolPixmap(toolElement)); + } + } + + updateButtons(); +} + +void WidgetAnnotTools::slotEdit() +{ + QListWidgetItem *listEntry = m_list->currentItem(); + + QDomDocument doc; + doc.setContent(listEntry->data(ToolXmlRole).value()); + QDomElement toolElement = doc.documentElement(); + + EditAnnotToolDialog t(this, toolElement); + + if (t.exec() != QDialog::Accepted) + return; + + doc = t.toolXml(); + toolElement = doc.documentElement(); + + QString itemText = t.name(); + + // Store name attribute only if the user specified a customized name + if (!itemText.isEmpty()) + toolElement.setAttribute(QStringLiteral("name"), itemText); + else + itemText = PageViewAnnotator::defaultToolName(toolElement); + + // Edit list entry and attach XML string as data + listEntry->setText(itemText); + listEntry->setData(ToolXmlRole, QVariant::fromValue(doc.toString(-1))); + listEntry->setIcon(PageViewAnnotator::makeToolPixmap(toolElement)); + + // Select and scroll + m_list->setCurrentItem(listEntry); + m_list->scrollToItem(listEntry); + updateButtons(); + emit changed(); +} + +void WidgetAnnotTools::slotAdd() +{ + EditAnnotToolDialog t(this); + + if (t.exec() != QDialog::Accepted) + return; + + QDomDocument rootDoc = t.toolXml(); + QDomElement toolElement = rootDoc.documentElement(); + + QString itemText = t.name(); + + // Store name attribute only if the user specified a customized name + if (!itemText.isEmpty()) + toolElement.setAttribute(QStringLiteral("name"), itemText); + else + itemText = PageViewAnnotator::defaultToolName(toolElement); + + // Create list entry and attach XML string as data + QListWidgetItem *listEntry = new QListWidgetItem(itemText, m_list); + listEntry->setData(ToolXmlRole, QVariant::fromValue(rootDoc.toString(-1))); + listEntry->setIcon(PageViewAnnotator::makeToolPixmap(toolElement)); + + // Select and scroll + m_list->setCurrentItem(listEntry); + m_list->scrollToItem(listEntry); + updateButtons(); + emit changed(); +} diff --git a/part/widgetannottools.h b/part/widgetannottools.h new file mode 100644 index 0000000..7c025a7 --- /dev/null +++ b/part/widgetannottools.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2012 by Fabio D'Urso * + * * + * 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 _WIDGETANNOTTOOLS_H_ +#define _WIDGETANNOTTOOLS_H_ + +#include "widgetconfigurationtoolsbase.h" + +#include +#include + +class WidgetAnnotTools : public WidgetConfigurationToolsBase +{ + Q_OBJECT +public: + explicit WidgetAnnotTools(QWidget *parent = nullptr); + ~WidgetAnnotTools() override; + + QStringList tools() const override; + void setTools(const QStringList &items) override; + +protected Q_SLOTS: + void slotAdd() override; + void slotEdit() override; +}; + +#endif diff --git a/part/widgetconfigurationtoolsbase.cpp b/part/widgetconfigurationtoolsbase.cpp new file mode 100644 index 0000000..641967f --- /dev/null +++ b/part/widgetconfigurationtoolsbase.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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. * + ***************************************************************************/ + +#include "widgetconfigurationtoolsbase.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +WidgetConfigurationToolsBase::WidgetConfigurationToolsBase(QWidget *parent) + : QWidget(parent) +{ + QHBoxLayout *hBoxLayout = new QHBoxLayout(this); + m_list = new QListWidget(this); + m_list->setIconSize(QSize(32, 32)); + hBoxLayout->addWidget(m_list); + + QVBoxLayout *vBoxLayout = new QVBoxLayout(); + m_btnAdd = new QPushButton(i18n("&Add..."), this); + m_btnAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); + vBoxLayout->addWidget(m_btnAdd); + m_btnEdit = new QPushButton(i18n("&Edit..."), this); + m_btnEdit->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename"))); + m_btnEdit->setEnabled(false); + vBoxLayout->addWidget(m_btnEdit); + m_btnRemove = new QPushButton(i18n("&Remove"), this); + m_btnRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); + m_btnRemove->setEnabled(false); + vBoxLayout->addWidget(m_btnRemove); + m_btnMoveUp = new QPushButton(i18n("Move &Up"), this); + m_btnMoveUp->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up"))); + m_btnMoveUp->setEnabled(false); + vBoxLayout->addWidget(m_btnMoveUp); + m_btnMoveDown = new QPushButton(i18n("Move &Down"), this); + m_btnMoveDown->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down"))); + m_btnMoveDown->setEnabled(false); + vBoxLayout->addWidget(m_btnMoveDown); + vBoxLayout->addStretch(); + hBoxLayout->addLayout(vBoxLayout); + + connect(m_list, &QListWidget::itemDoubleClicked, this, &WidgetConfigurationToolsBase::slotEdit); + connect(m_list, &QListWidget::currentRowChanged, this, &WidgetConfigurationToolsBase::updateButtons); + connect(m_btnAdd, &QPushButton::clicked, this, &WidgetConfigurationToolsBase::slotAdd); + connect(m_btnEdit, &QPushButton::clicked, this, &WidgetConfigurationToolsBase::slotEdit); + connect(m_btnRemove, &QPushButton::clicked, this, &WidgetConfigurationToolsBase::slotRemove); + connect(m_btnMoveUp, &QPushButton::clicked, this, &WidgetConfigurationToolsBase::slotMoveUp); + connect(m_btnMoveDown, &QPushButton::clicked, this, &WidgetConfigurationToolsBase::slotMoveDown); +} + +WidgetConfigurationToolsBase::~WidgetConfigurationToolsBase() +{ +} + +void WidgetConfigurationToolsBase::updateButtons() +{ + const int row = m_list->currentRow(); + const int last = m_list->count() - 1; + + m_btnEdit->setEnabled(row != -1); + m_btnRemove->setEnabled(row != -1); + m_btnMoveUp->setEnabled(row > 0); + m_btnMoveDown->setEnabled(row != -1 && row != last); +} + +void WidgetConfigurationToolsBase::slotRemove() +{ + const int row = m_list->currentRow(); + delete m_list->takeItem(row); + updateButtons(); + emit changed(); +} + +void WidgetConfigurationToolsBase::slotMoveUp() +{ + const int row = m_list->currentRow(); + m_list->insertItem(row, m_list->takeItem(row - 1)); + m_list->scrollToItem(m_list->currentItem()); + updateButtons(); + emit changed(); +} + +void WidgetConfigurationToolsBase::slotMoveDown() +{ + const int row = m_list->currentRow(); + m_list->insertItem(row, m_list->takeItem(row + 1)); + m_list->scrollToItem(m_list->currentItem()); + updateButtons(); + emit changed(); +} diff --git a/part/widgetconfigurationtoolsbase.h b/part/widgetconfigurationtoolsbase.h new file mode 100644 index 0000000..93dc11a --- /dev/null +++ b/part/widgetconfigurationtoolsbase.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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 WIDGETCONFIGURATIONTOOLSBASE_H +#define WIDGETCONFIGURATIONTOOLSBASE_H + +#include +class QListWidget; +class QPushButton; + +class WidgetConfigurationToolsBase : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(QStringList tools READ tools WRITE setTools NOTIFY changed USER true) + +public: + explicit WidgetConfigurationToolsBase(QWidget *parent = nullptr); + ~WidgetConfigurationToolsBase() override; + + virtual QStringList tools() const = 0; + virtual void setTools(const QStringList &items) = 0; + +Q_SIGNALS: + void changed(); + +protected: + QListWidget *m_list; + +private: + QPushButton *m_btnAdd; + QPushButton *m_btnEdit; + QPushButton *m_btnRemove; + QPushButton *m_btnMoveUp; + QPushButton *m_btnMoveDown; + +protected Q_SLOTS: + virtual void slotAdd() = 0; + virtual void slotEdit() = 0; + void updateButtons(); + void slotRemove(); + void slotMoveUp(); + void slotMoveDown(); +}; + +#endif // WIDGETCONFIGURATIONTOOLSBASE_H diff --git a/part/widgetdrawingtools.cpp b/part/widgetdrawingtools.cpp new file mode 100644 index 0000000..5124b7b --- /dev/null +++ b/part/widgetdrawingtools.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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. * + ***************************************************************************/ + +#include "widgetdrawingtools.h" + +#include "editdrawingtooldialog.h" + +#include +#include + +#include +#include +#include +#include + +// Used to store tools' XML description in m_list's items +static const int ToolXmlRole = Qt::UserRole; + +static QPixmap colorDecorationFromToolDescription(const QString &toolDescription) +{ + QDomDocument doc; + doc.setContent(toolDescription, true); + const QDomElement toolElement = doc.documentElement(); + const QDomElement engineElement = toolElement.elementsByTagName(QStringLiteral("engine")).at(0).toElement(); + const QDomElement annotationElement = engineElement.elementsByTagName(QStringLiteral("annotation")).at(0).toElement(); + + QPixmap pm(50, 20); + pm.fill(QColor(annotationElement.attribute(QStringLiteral("color")))); + + QPainter p(&pm); + p.setPen(Qt::black); + p.drawRect(QRect(0, 0, pm.width() - 1, pm.height() - 1)); + + return pm; +} + +WidgetDrawingTools::WidgetDrawingTools(QWidget *parent) + : WidgetConfigurationToolsBase(parent) +{ +} + +WidgetDrawingTools::~WidgetDrawingTools() +{ +} + +QStringList WidgetDrawingTools::tools() const +{ + QStringList res; + + const int count = m_list->count(); + for (int i = 0; i < count; ++i) { + QListWidgetItem *listEntry = m_list->item(i); + + // Parse associated DOM data + QDomDocument doc; + doc.setContent(listEntry->data(ToolXmlRole).value()); + + // Append to output + res << doc.toString(-1); + } + + return res; +} + +void WidgetDrawingTools::setTools(const QStringList &items) +{ + m_list->clear(); + + // Parse each string and populate the list widget + for (const QString &toolXml : items) { + QDomDocument entryParser; + if (!entryParser.setContent(toolXml)) { + qWarning() << "Skipping malformed tool XML string"; + break; + } + + const QDomElement toolElement = entryParser.documentElement(); + if (toolElement.tagName() == QLatin1String("tool")) { + const QString name = toolElement.attribute(QStringLiteral("name")); + QString itemText; + if (toolElement.attribute(QStringLiteral("default"), QStringLiteral("false")) == QLatin1String("true")) + itemText = i18n(name.toLatin1().constData()); + else + itemText = name; + + QListWidgetItem *listEntry = new QListWidgetItem(itemText, m_list); + listEntry->setData(ToolXmlRole, QVariant::fromValue(toolXml)); + listEntry->setData(Qt::DecorationRole, colorDecorationFromToolDescription(toolXml)); + } + } + + updateButtons(); +} + +QString WidgetDrawingTools::defaultName() const +{ + int nameIndex = 1; + bool freeNameFound = false; + QString candidateName; + while (!freeNameFound) { + candidateName = i18n("Default Drawing Tool #%1", nameIndex); + int i = 0; + for (; i < m_list->count(); ++i) { + QListWidgetItem *listEntry = m_list->item(i); + if (candidateName == listEntry->text()) { + break; + } + } + freeNameFound = i == m_list->count(); + ++nameIndex; + } + return candidateName; +} + +void WidgetDrawingTools::slotAdd() +{ + EditDrawingToolDialog dlg(QDomElement(), this); + + if (dlg.exec() != QDialog::Accepted) + return; + + const QDomDocument rootDoc = dlg.toolXml(); + QDomElement toolElement = rootDoc.documentElement(); + + QString itemText = dlg.name().trimmed(); + + if (itemText.isEmpty()) { + itemText = defaultName(); + } + + for (int i = 0; i < m_list->count(); ++i) { + QListWidgetItem *listEntry = m_list->item(i); + if (itemText == listEntry->text()) { + KMessageBox::information(this, i18n("There's already a tool with that name. Using a default one"), i18n("Duplicated Name")); + itemText = defaultName(); + break; + } + } + + // Store name attribute only if the user specified a customized name + toolElement.setAttribute(QStringLiteral("name"), itemText); + + // Create list entry and attach XML string as data + const QString toolXml = rootDoc.toString(-1); + QListWidgetItem *listEntry = new QListWidgetItem(itemText, m_list); + listEntry->setData(ToolXmlRole, QVariant::fromValue(toolXml)); + listEntry->setData(Qt::DecorationRole, colorDecorationFromToolDescription(toolXml)); + + // Select and scroll + m_list->setCurrentItem(listEntry); + m_list->scrollToItem(listEntry); + updateButtons(); + emit changed(); +} + +void WidgetDrawingTools::slotEdit() +{ + QListWidgetItem *listEntry = m_list->currentItem(); + + QDomDocument doc; + doc.setContent(listEntry->data(ToolXmlRole).value()); + QDomElement toolElement = doc.documentElement(); + + EditDrawingToolDialog dlg(toolElement, this); + + if (dlg.exec() != QDialog::Accepted) + return; + + doc = dlg.toolXml(); + toolElement = doc.documentElement(); + + QString itemText = dlg.name(); + + for (int i = 0; i < m_list->count(); ++i) { + QListWidgetItem *auxListEntry = m_list->item(i); + if (itemText == auxListEntry->text() && auxListEntry != listEntry) { + KMessageBox::information(this, i18n("There's already a tool with that name. Using a default one"), i18n("Duplicated Name")); + itemText = defaultName(); + break; + } + } + + // Store name attribute only if the user specified a customized name + toolElement.setAttribute(QStringLiteral("name"), itemText); + + // Edit list entry and attach XML string as data + const QString toolXml = doc.toString(-1); + listEntry->setText(itemText); + listEntry->setData(ToolXmlRole, QVariant::fromValue(toolXml)); + listEntry->setData(Qt::DecorationRole, colorDecorationFromToolDescription(toolXml)); + + // Select and scroll + m_list->setCurrentItem(listEntry); + m_list->scrollToItem(listEntry); + updateButtons(); + emit changed(); +} diff --git a/part/widgetdrawingtools.h b/part/widgetdrawingtools.h new file mode 100644 index 0000000..03c940d --- /dev/null +++ b/part/widgetdrawingtools.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2015 by Laurent Montel * + * * + * 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 WIDGETDRAWINGTOOLS_H +#define WIDGETDRAWINGTOOLS_H + +#include "widgetconfigurationtoolsbase.h" + +class WidgetDrawingTools : public WidgetConfigurationToolsBase +{ + Q_OBJECT +public: + explicit WidgetDrawingTools(QWidget *parent = nullptr); + ~WidgetDrawingTools() override; + + QStringList tools() const override; + void setTools(const QStringList &items) override; + + QString defaultName() const; + +protected Q_SLOTS: + void slotAdd() override; + void slotEdit() override; +}; + +#endif // WIDGETDRAWINGTOOLS_H diff --git a/part/xmlgui_helper.cpp b/part/xmlgui_helper.cpp new file mode 100644 index 0000000..9a80fa1 --- /dev/null +++ b/part/xmlgui_helper.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2020 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include "xmlgui_helper.h" + +#include "kxmlgui_version.h" + +#if KXMLGUI_VERSION >= QT_VERSION_CHECK(5, 73, 0) +#include +#endif + +#include +#include + +#if KXMLGUI_VERSION < QT_VERSION_CHECK(5, 73, 0) + +// Copied from KXmlGuiVersionHandler::findVersionNumber :/ +static QString findVersionNumber(const QString &xml) +{ + enum { ST_START, ST_AFTER_OPEN, ST_AFTER_GUI, ST_EXPECT_VERSION, ST_VERSION_NUM } state = ST_START; + const int length = xml.length(); + for (int pos = 0; pos < length; pos++) { + switch (state) { + case ST_START: + if (xml[pos] == QLatin1Char('<')) { + state = ST_AFTER_OPEN; + } + break; + case ST_AFTER_OPEN: { + // Jump to gui.. + const int guipos = xml.indexOf(QLatin1String("gui"), pos, Qt::CaseInsensitive); + if (guipos == -1) { + return QString(); // Reject + } + + pos = guipos + 2; // Position at i, so we're moved ahead to the next character by the ++; + state = ST_AFTER_GUI; + break; + } + case ST_AFTER_GUI: + state = ST_EXPECT_VERSION; + break; + case ST_EXPECT_VERSION: { + const int verpos = xml.indexOf(QLatin1String("version"), pos, Qt::CaseInsensitive); + if (verpos == -1) { + return QString(); // Reject + } + pos = verpos + 7; // strlen("version") is 7 + while (xml.at(pos).isSpace()) { + ++pos; + } + if (xml.at(pos++) != QLatin1Char('=')) { + return QString(); // Reject + } + while (xml.at(pos).isSpace()) { + ++pos; + } + + state = ST_VERSION_NUM; + break; + } + case ST_VERSION_NUM: { + int endpos; + for (endpos = pos; endpos < length; endpos++) { + const ushort ch = xml[endpos].unicode(); + if (ch >= QLatin1Char('0') && ch <= QLatin1Char('9')) { + continue; // Number.. + } + if (ch == QLatin1Char('"')) { // End of parameter + break; + } else { // This shouldn't be here.. + endpos = length; + } + } + + if (endpos != pos && endpos < length) { + const QString matchCandidate = xml.mid(pos, endpos - pos); // Don't include " ". + return matchCandidate; + } + + state = ST_EXPECT_VERSION; // Try to match a well-formed version.. + break; + } // case.. + } // switch + } // for + + return QString(); +} + +#endif + +namespace Okular +{ +void removeRCFileIfVersionSmallerThan(const QString &filePath, int version) +{ + QFile f(filePath); + if (f.open(QIODevice::ReadOnly)) { + const QByteArray contents = f.readAll(); + f.close(); +#if KXMLGUI_VERSION < QT_VERSION_CHECK(5, 73, 0) + const QString fileVersion = findVersionNumber(contents); +#else + const QString fileVersion = KXMLGUIClient::findVersionNumber(contents); +#endif + if (fileVersion.toInt() < version) { + QFile::remove(filePath); + } + } +} + +} diff --git a/part/xmlgui_helper.h b/part/xmlgui_helper.h new file mode 100644 index 0000000..221dbc6 --- /dev/null +++ b/part/xmlgui_helper.h @@ -0,0 +1,15 @@ +/*************************************************************************** + * Copyright (C) 2020 by Albert Astals Cid * + * * + * 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. * + ***************************************************************************/ + +#include + +namespace Okular +{ +void removeRCFileIfVersionSmallerThan(const QString &filePath, int version); +} diff --git a/po/ar/okular.po b/po/ar/okular.po new file mode 100644 index 0000000..b033fec --- /dev/null +++ b/po/ar/okular.po @@ -0,0 +1,5726 @@ +# translation of okular.po to Arabic +# translation of okular.po to +# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Mohamed Aser(محمد عَصَر) ,2002-10-04 11:50+0200. +# Youssef Chahibi , 2007. +# Usama Akkad , 2008. +# zayed , 2008. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2014-07-07 18:48+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Usama Akkad,زايد السعيدي,عبدالرحيم الفاخوري" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "uahello@gmail.com,zayed.alsaidi@gmail.com,abdilra7eem@yahoo.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "أوكلار" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "أوكلار ، عارض عالمي للمستندات" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2009 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "المشرف السابق" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "الكثير من هياكل العمل ، نهايات خلفية ل ODT و FictionBook" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "مطور KPDF" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "أنشئ أوكلار من الكود الأساس ل KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "مطور KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "فنان التعليقات" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "أداة اختيار الجداول" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "تحسينات الحاشية" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "اذهب إلى صفحة %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "افتح ملفا خارجيا" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "نفذ '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "أول صفحة" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "صفحة سابقة" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "صفحة تالية" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "أخر صفحة" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "للخلف" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "للأمام" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "اخرج" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "ابدأ العرض" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "أنهِ العرض" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "بحث..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "اذهب إلى صفحة..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "تشغيل صوت..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "نص جافا سكربت" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "تشغيل عرض..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "شغِل الفِلم" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "أوقِف الفِلم" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "أوقف الفلم مؤقتاً" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "استأنِف الفِلم" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "تحديد النهاية الخلفية" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"أكثر من نهاية خلفية وجدت لنوع التنسيق :
%1 (%2).

أختر أيها سيستعمل:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "اذهب إلى صفحة %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 في (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 مم (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "تعذر إيجاد ملحق للتعامل مع المستند المطلوب." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "أزِل الحواشي" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "المستند يحاول تشغيل تطبيق خارجي ؛ و لأمانك أوكلار لا يسمح بذلك." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "لم يجد تطبيق لفتح الملف من نوع التنسيق %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "تعذر فتح الملف المؤقت" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "تعذر إيجاد الملف للطباعة" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "تعذر فتح '%1'. الملف غير موجود" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "العنوان" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "الموضوع" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "الوصف" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "المؤلف" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "المُنشئ" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "المُنتج" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "حقوق النسخ" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "الصفحات" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "أنشئ" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "عُدل" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "نوع التنسيق الملف" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "التصنيف" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "الكلمات المفتاحية" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "مسار الملف" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "حجم الملف" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "حجم الصفحة" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "أضف حاشيةً" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "أزِل حاشيةً" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "عدِّل خصائص الحاشية" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "ترجِم الحاشية" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "أضف حاشيةً" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "حرِّر النَص" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "حرّر محتوى الحاشية" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "حرّر محتوى النموذَج" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "حرِّر اللائحة من الخيارات" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "حرِّر من حالات الزِرّ" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "نص &صرف..." + +# | msgid "KPDF" +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "نص OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "خيارات المحرر" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "نمط اللون:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "أغلق هذه الرسالة" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "المصدر: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "ال&خَط الافتراضي:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "أعد ال&تحميل" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "اسمح" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "الشاشة" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "ناسب العرض" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "خيارات الحاشية" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "أدوات الحاشية" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "أدوات الحاشية" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "أدوات الحاشية" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "أدوات الحاشية" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "تعليق" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "خيارات الحاشية" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&لون:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&لون:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "تجريبي" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "أ&دوات التحديد" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "الحواشي" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlighter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "قلم التحديد" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "تسطير" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "خط متعرج" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "اشطب" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "الكتابة عليه" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "ملاحظة مضمنة" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "ملاحظة منبثقة" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "خط رسم حُرّ" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "خط مستقيم" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "مستطيل" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "بيضاوي" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "مضلّع" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "الختم" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "الحواشي" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "أضف حاشيةً" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "أنشئ أداة حواشٍ" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "خط:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "خيارات الحاشية" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "السطر" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "الت&عتيم:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "الصفحة %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "تعليق" +msgstr[1] "لا تعليق" +msgstr[2] "تعليق" +msgstr[3] "%1 تعليقات" +msgstr[4] "%1 تعليقا" +msgstr[5] "%1 تعليقات" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "افتح " + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "ا&حذف" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&خصائص" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "ا&حفظ '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "الم&ظهر" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&عام" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&مؤلف:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "أنشئ" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "عُدل" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "خصائص الملاحظة المنبثقة" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "خصائص القبعة" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "خصائص الملاحظة المضمنة" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "خصائص الخط المستقيم" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "خصائص المضلع" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "خصائص الهندسة" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "خصائص وسم النَّص" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "ختم الخصائص" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "خصائص خط الرسم الحر" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "خصائص القبعة" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "خصائص " + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "خصائص الصوت" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "خصائص الفلم" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "خصائص التعليق" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "معدل: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "ضع رمز ختم" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&لون:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "الت&عتيم:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "أيقونة" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "تعليق" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "مساعدة" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "أدرج" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "مفتاح" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "فقرة جديدة" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "ملاحظة" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "فقرة" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "خط:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&لون:" + +#: part/annotationwidgets.cpp:389 +#, fuzzy, kde-format +msgid "&Align:" +msgstr "الإزاحة:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "اليسار" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "الوسط" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "اليمين" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "مصادق عليه" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "كما هو" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "سري" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "إداري" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "مسودة" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "تجريبي" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "نهائي" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "للتعليق" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "للنشر العام" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "غير مصادق عليه" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "ليس للنشر العام" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "مباع" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "سرّي للغاية" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "علامة موقع" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "معلومات" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "كدي" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "رمز الختم" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "ناسب العرض" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "السطر" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "السطر" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "بدون" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "طول خط القائد:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "طول لواحق خط القائد:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "حفظ إلى ملف.." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "النوع:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "إبراز" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "خط متعرج" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "تسطير" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "شطب خارج" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "مستطيل" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "بيضاوي" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "رمز ملحق الملف" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "رسمة" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "دبوس" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "مشبك الورق" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "وسم" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "ملف" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "غ/م" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "لا وصف متاح." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "&Name:" +msgid "Name:" +msgstr "الا&سم:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "الوصف" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "رمز القبعة" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "بدون" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "جملة" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "أغلق هذه الملاحظة" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "الخيارات" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"يمكن أن تحوي هذه الحاشية أكواد لاتِخ. \n" +"اضغط هنا لتصييرها." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "تعذر إيجاد برنامج لاتِخ تنفيذيّ." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "فشل تصيير لاتِخ" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "تعذر إيجاد البرنامج التنفيذيّ dvipng" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "حدثت مشكلة أثناء تنفيذ الأمر 'latex'" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "حدثت مشكلة أثناء تنفيذ الأمر 'dvipng'." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"لا يوجد علامة" +msgstr[1] "" +"%1\n" +"\n" +"علامة واحدة" +msgstr[2] "" +"%1\n" +"\n" +"علامتين" +msgstr[3] "" +"%1\n" +"\n" +"%2 علامات" +msgstr[4] "" +"%1\n" +"\n" +"%2 علامة" +msgstr[5] "" +"%1\n" +"\n" +"%2 علامة" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "علامات المواقع" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "ا&بحث:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "المستند الحالي فقط" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "اذهب إلى علامة الموقع هذه" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "غير اسم العلامة" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "حذف علامة موقع" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "افتح المستند" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "احذف العلامات" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "رقم الصفحة" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "منتهي" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "الموضوع" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "استخدام الذاكرة" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&خصائص" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "اضبط العارض" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "&صدِّر إلى" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "عام" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "أين تريد حفظ %1؟" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "أعد ال&تحميل" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "الشاشة" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "اسمح" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "ارسم حدودا حول ال&صور" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "ارسم حدودا حول ال&روابط" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "غير الأ&لوان" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "تحذير: هذه الخيارات قد تضر بشدة بسرعة الرسم." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "نمط اللون:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "اعكس الألوان" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "غيّر لون الورق" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "غيّر ألوان العتمة و الضوء" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "حوّل إلى أسود & أبيض" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "لون الورق:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "اللون المعتم:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "اللون الفاتح:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "العتبة:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "التباين:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "الهوية" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&مؤلف:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"لاحظ: المعلومات هنا تستخدم فقط للتعليقات و المراجعات. المعلومات " +"المدرجة هنا لن تنقل دون معرفتك." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "حرّر أداة حواشٍ" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "محرر نصوص مخصص" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "كيت" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "كايل" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "عميل إي ماكس" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "عميل lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"ضع الأمر محرر النصوص المخصص لينفذ.
\n" +"يمكنك أيضا أن تضع بعض ماسكات الأمكنة:\n" +"
    \n" +"
  • %f - اسم الملف
  • \n" +"
  • %l - السطر المراد الوصول إليه في الملف
  • \n" +"
  • %c -عمود الملف المراد الوصولة إليه
  • \n" +"
\n" +"إذا لم يحدد %f فإن اسم الملف سيضاف إلى الأمر المحدد." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "المحرر" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "المحرر:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "اختر المحرر الذي تريد إطلاقه عندما يريد أوكلار فتح ملف مصدر." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "الأمر:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "المظهر" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "اعرض الأ&شرطة المنزلقة:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "اربط ال&مصغرات بالصفحة" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "اعرض ت&لميحات و رسائل المعلومات" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "اعرض عنوان المستند في شريط العنوان إن وُجِد" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "عند عدم عرض عنوان المستند:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "اعرض فقط اسم الملف" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "اعرض المسار الكامل للملف" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "لون الخلفية:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "خصائص البرنامج" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "افتح الملفات الجديدة في أل&سِنة" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "أ&طع تقييدات DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "أ&عد تحميل المستند عند تغيّر الملفر" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "اعرض حوار اختيار المنتهي الخلفي" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "خيارات العرض" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "أعمد الع&رض العام:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "حدِّد مقدار مساحة العرض التي ستبقى ظاهرة عند ضغط مفتاح Page Up/Down." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "تداخُل مفتاح &Page Up/Down:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"يُحدِّد وضع التقريب المبدئيّ للملفات التي لم تُفتَح قبلاً.\n" +"للملفات المفتوحة قَبلاً يتم تطبيق التقريب السابِق." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"يُحدِّد وضع التقريب المبدئيّ للملفات التي لم تُفتَح قبلاً.\n" +"للملفات المفتوحة قَبلاً يتم تطبيق التقريب السابِق." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "التقريب المبدئيّ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "ناسب العرض" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "ناسب الصفحة" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "لائم الحجم آليًّا" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"يبقي الذاكرة المستعملة منخفضة قدر الإمكان. لا تعد استعمال أي شيء. (للأنظمة " +"ذات الذاكرة المنخفضة.)" + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"جمع جيد بين استعمال الذاكرة و السرعة. تحميل مسبق للصفحة التالية و تسريع " +"البحث. (للأنظمة ذات ذاكرة 256م‌ب، عادة.)" + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"أبق كل شيء في الذاكرة. تحميل مسبق للصفحات التالية. يسريع البحث. (للأنظمة مع " +"أكثر من 512 م.بايت من الذاكرة.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"يُحمِّل ويُبقي كل شيء في الذاكرة. تحميل مسبق للصور. (سيستخدم 50% على الأكثر من " +"الذاكرة الكليّة أو الذاكرة الحرّة لديك، أيهما أكبر)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "استخدام المعالج" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "مكن &مؤثرات الشفافية" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "استخدام الذاكرة" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&منخفض" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&عادي (افتراضي)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "&شديد" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "التصيير" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "فعِّل تنعيم حواف الخط" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "فعِّل تنعيم حواف الرسوميات" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "فعِّل التلميحات على النَّص" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "الشاشة الحالية" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "الشاشة الافتراضية" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "الشاشة %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] "من الثواني" +msgstr[1] "ثانية" +msgstr[2] "من الثواني" +msgstr[3] "ثوانٍ" +msgstr[4] "ثانية" +msgstr[5] "ثانية" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "الملاحة" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "تقدم كل:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "كرر بعد الصفحة الأخيرة" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "الملاحة" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "لون الخلفية:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "مؤشر الفأرة:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "مخفي بعد التأخير" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "دائماً مرئي" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "دائماً مخفي" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "اعرض &مؤشر التقدم" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "اعرض &صفحة الملخص" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "اسمح بالتنقلات" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "التنقل الافتراضي:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "ستائر رأسي" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "ستائر أفقي" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "مربع للداخل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "مربع للخارج" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "إذابة" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "لمعان للأسفل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "لمعان لليمين" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "لمعان يمين-أسفل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "انتقال عشوائي" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "استبدل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "انقسام أفقي للداخل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "انقسام أفقي للخارج" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "انقسام رأسي للداخل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "انقسام رأسي للخارج" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "مسح للأسفل" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "مسح لليمين" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "مسح لليسار" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "مسح للأعلى" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "الموضع" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "الشاشة:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "مسح الرسومات" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "الا&سم:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "النو&ع:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "ملاحظة منبثقة" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "ملاحظة مضمنة" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "خط رسم حُرّ" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "خط مستقيم" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "مضلّع" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "إبراز النَّص" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "الختم" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgid "Typewriter" +msgstr "الكتابة عليه" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "أنشئ أداة حواشٍ" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "حرّر أداة حواشٍ" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&لون:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "ناسب العرض" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgid "Create drawing tool" +msgstr "أنشئ أداة حواشٍ" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Edit drawing tool" +msgstr "حرّر أداة حواشٍ" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "غير معروف" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "ملفات مضمنة" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "ا&عرض" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "الاسم" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "الوصف" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "الحجم" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "أُنشئ" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "عُدل" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "ا&حفظ ك..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "ا&عرض" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "تعذر تحميل جزء معاينة الطباعة" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "معاينة الطباعة" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "أغلق" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "ا&عثر:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "النص للبحث عنه" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "التالي" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "اذهب للمطابقة التالية" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "اذهب للمطابقة السابقة" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "انتقل إلى المطابقة السابقة" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "عدل سلوك البحث" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "حساس للحالة" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "من الصفحة الحالية" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|كل الملفات" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "خصائص القبعة" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Straight Line Properties" +msgid "Straight Line with Comment" +msgstr "خصائص الخط المستقيم" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "للتعليق" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "الهندسة" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Highlight text" +msgid "Highlight with Comment" +msgstr "أبرِز النَّص" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Squiggle text" +msgid "Squiggle with Comment" +msgstr "نصّ متمايِل" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Underline text" +msgid "Underline with Comment" +msgstr "سطِّر النصّ" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Strike out text" +msgid "Strike Out with Comment" +msgstr "اشطب النصّ" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "اشطب" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Freehand Line Properties" +msgid "Freehand Line with Comment" +msgstr "خصائص خط الرسم الحر" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "القبعة" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "ملف مرفق" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "الصوت" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "الفلم" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "الشاشة" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "وِدجَة" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "مجهول" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "مؤلف: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "أين تريد حفظ %1؟" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "تعذر فتح \"%1\" للكتابة. الملف لم يحفظ." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "خيارات البحث" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "حساس للحالة" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "تعبير اعتياديّ" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "ا&بحث:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "من" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "تكبير" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "أدر للي&مين" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "يمين" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "أدر للي&سار" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "يسار" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "الاتجاه الأصلي" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "ا&عرض" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&قطع الهوامش" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "تحديد النص" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "ملائمة ال&عرض" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "ملائمة ال&صفحة" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "ملاءمة تل&قائيّة" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "ملائمة ال&صفحة" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "نمط ال&عرض" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "صفحة مفردة" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "صفحات متقابلة" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "صفحة الواجهة (واسِط الصفحة الأولى)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "نظرة عامة" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&مستمر" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "تصفح" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "تكبير" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &colors" +msgid "&Toggle Change Colors" +msgstr "غير الأ&لوان" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "تحديد النص" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "تحديد النص" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "تحديد الجدول" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "الم&كبِر" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "أدوات التحديد" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "انطق بالمستند كاملا" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "انطق بالصفحة الحالية" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "أوقف النطق" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "لف لأعلى" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "لف لأسفل" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "التمرير لأعلى" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "التمرير لأسفل" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "اعرض الاستمارات" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "حمل مستند ذو %1 صفحة." +msgstr[1] "حمل مستند ذو صفحة واحدة." +msgstr[2] "حمل مستند ذو صفحتين." +msgstr[3] "حمل مستند ذو %1 صفحات." +msgstr[4] "حمل مستند ذو %1 صفحة." +msgstr[5] "حمل مستند ذو %1 صفحة." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "نص (لا محارف)ف" +msgstr[1] "نص (محرف)" +msgstr[2] "نص (محرفان)" +msgstr[3] "نص (%1 محارف)" +msgstr[4] "نص (%1 محرفا)" +msgstr[5] "نص (%1 محرف)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "نسخ إلى الحافظة" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "منع النسخ من قبل DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "اقرأ النص" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "صورة (%1 ب %2 بكسل)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "حفظ إلى ملف.." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "الصورة [%1×%2] نسخت إلى الحافظة" + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "حفظ إلى ملف.." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "الملف لم يحفظ" + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "الصورة [%1×%2] حفظة إلى الملف %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "نسخ نص" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "اذهب إلى '%1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "ابحث عن '%1' باستخدام" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "اضبط اختصارات الوِب..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "اتبع هذه الوصلة" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "تشغيل صوت..." + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "أوقف الصوت" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "انسخ رابط العنوان" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "ابحث عن '%1' باستخدام" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "مرحبا" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "اختر منطقة التكبير. نقرة-يمنى للتصغير." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "اضغط هنا لرؤية العرض المُكَبَّر" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "ارسم مربعا حول النص/الصورة المراد نسخه." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "حدد نص" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"ارسم مستطيلاً حول الجدول، ثم انقر بالفأرة بالقرب من الحافة لتُقَسِّم؛ اضغط Esc " +"للإلغاء." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "ارسم مربعا حول النص/الصورة المراد نسخه." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "ملاحظة نصية جديدة" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "نص الملاحظة الجديدة:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "أضف حاشيةً" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "تعليق نصي مضمن (اسحب لتحديد محل)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "أبرِز النَّص" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "ارسم خطًّا حُرًّا" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "تعليق نصي مضمن (اسحب لتحديد محل)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "ضَع ملاحظة منبثقة" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "رسم مضلع (انقر على النقطة الأولى لإغلاقه)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "ارسم مستطيلاً" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "نصّ متمايِل" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "ضع رمز ختم" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "ارسم خطًّا مستقيماً" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "اشطب النصّ" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "سطِّر النصّ" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "تعليق نصي مضمن (اسحب لتحديد محل)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "قلم التحديد" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "أضف حاشيةً" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Custom annotation name:" +msgstr "أضف حاشيةً" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&ملف" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "إ&عدادات" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "م&ساعدة" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "الا&تجاه" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&علامات المواقع" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "شريط أدوات العارِض" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "مصغرات" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "الحواشي" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"هذا المستند فيه ملفات مضمنة. انقر هنا " +"لرؤيتها أو اذهب إلى ملف -> ملفات مضمنة." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "السابق" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "ارجع للصفحة السابقة" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "انتقل للصفحة السابقة من المستند" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "التالي" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "انتقل إلى الصفحة التالية" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "ينقل إلى الصفحة التالية من المستند" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "بداية المستند" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "ينتقل إلى بداية المستنَد" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "نهاية المستند" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "ينتقل إلى نهاية المستنَد" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "أعد تسمية العلامة الحاليّة" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "العلامة السابقة" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "اذهب إلى العلامة السابقة" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "العلامة التالية" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "اذهب إلى العلامة التالية" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "اضبط أوكلار..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "اضبط العارض..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "اضبط النهايات الخلفية للعارِض..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "اضبط النهايات الخلفية..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "حول المنتهى الخلفي" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "أعد ال&تحميل" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "أعد تحميل المستند الحالي من القرص." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "أغلق شريط &بحث" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "رقم الصفحة" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "انطق بالصفحة الحالية" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show scroll&bars" +msgid "Show S&idebar" +msgstr "اعرض الأ&شرطة المنزلقة:" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "اعرض &شريط الملاحة" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&ملفات مضمنة" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&صدِّر إلى" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&عرض تقديمي" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&استورد PostScript كـ PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&احصل على كتب من الإنترنت..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "بدل نمط الشاشة السوداء" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "مسح الرسومات" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "اضبط الحواشي" + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "اعرض أو أوقف العرض مؤقتاً" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "تعذر فتح %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "" + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "تعذر فتح %1. السبب: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "اضبط النهايات الخلفية للعارِض" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "اضبط النهايات الخلفية" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"البرنامج \"ps2pdf\" غير موجود ، لذا لا يمكن لأوكلار استيراد ملفات PS أو " +"استخدامها." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf غير موجود" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "تستورد ملفات PS ك pdf (قد يأخذ هذا وقتا)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "يُرجى إدخال كلمة السِر لقراءة المستنَد:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "كلمة سر المستند" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"هذا المستند فيه استمارات. انقر على الزر للتعامل معها ، أو استعمل عرض -> اعرض " +"الاستمارات." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "لا يسمح بطباعة هذا المستند." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "لا يسمح بطباعة هذا المستند." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "اخرج من وضع العرض التقديمي" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "تعذر فتح %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&مستمر" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&مستمر" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "أغلق المستند" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"هذا الرابط يشير إلى أمر إغلاق المستند والذي لا يعمل عند استخدام العارض " +"المضمن." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"هذا الرابط يشير إلى أمر الخروج من التطبيق و لا يعمل عند استخدام العراض " +"المضمن." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "يعيد تحميل المستند..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "المحتويات" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "اذهب إلى صفحة" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&صفحة:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "أعد تسمية هذه العلامة" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename this Bookmark" +msgid "Remove this Bookmark" +msgstr "أعد تسمية هذه العلامة" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "ا&حفظ ك..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "تعذر فتح الملف المؤقت للحفظ." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "تعذر حفظ الملف في '%1'. حاول حفظه في مكان آخر." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgctxt "Edit an form's text contents" +#| msgid "edit form contents" +msgid "Filled form contents" +msgstr "حرّر محتوى النموذَج" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgctxt "remove a collection of annotations from the page" +#| msgid "remove annotations" +msgid "User annotations" +msgstr "أزِل الحواشي" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&مستمر" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "تعذر حفظ الملف في '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"لم يتمكن أوكلار من نسخ %1 للموقع المحدد.\n" +"\n" +"المستند لم يعد موجودا." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "تعذر حفظ الملف في '%1'. حاول حفظه في مكان آخر." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "أنهِ العرض" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "إضافة علامة موقع" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "أدوات" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "لا يسمح بطباعة هذا المستند." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "تعذرت طباعة المستند. خطأ غير معروف. يُرجى التبليغ عنه إلى bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"تعذرت طباعة المستند. الخطأ بالتفصيل هو \"%1\". يُرجى التبليغ إلى bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "اذهب إلى حيث كنت" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "اذهب إلى حيث كنت بعده" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"خطأ ملف! تعذّر إنشاء ملف مؤقّت %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded.
" +msgstr "" +"خطأ ملف! تعذّر فتح الملف %1 لفك الضغط. لن يتم تحميل الملف." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"يحدث هذا الخطأ إذا لم يكن لديك الصلاحيّات الكافية لقراءة الملف. يمكنك فحص " +"الملكية والصلاحيات إذا ضغطت بالزر الأيمن على الملف في مدير الملفات دولفين ثم " +"قمت باختيار لسان `خصائص`" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded.
" +msgstr "" +"خطأ ملف! تعذّر فك ضغط الملف %1. لن يتم تحميل الملف." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"يحدث هذا الخطأ عادة إذا كان الملف معطوباً. إذا أردت أن تتأكد ،ا فحاول فك " +"ضغط الملف يدياً باستخدام أدوات سطر الأوام." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "لا علامات مواقع" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&حرر" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "ا&عرض" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "ا&ذهب" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&أدوات" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "شريط الأدوات الرئيسي" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "أدوات الحاشية" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "خيارات عامة" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "تسهيل الوصول" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "إتاحة مساعدة القراءة" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "الأداء" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "مضبط الأداء" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "اضبط العارض" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "عرض تقديمي" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "خيارات لوضع العرض التقديمي" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "خيارات الحاشية" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "خيارات المحرر" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "بحث عن التالي" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – عرض تقديميّ" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "بدل الشاشة" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "الشاشة %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "اخرج من وضع العرض التقديمي" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "عنوان: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "الصفحات: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "انقر للبدء" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "أوقف مؤقتاً" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "شغّل" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"هناك طريقتان للخروج من نمط العرض التقديمي ، يمكنك ضغط مفتاح ESC أو نقر زر " +"خروج الذي يظهر عند وضع الفأرة على الزاوية العلوية اليسارية. بلا شك يمكنك " +"تدوير النوافذ (Alt+TAB بشكل افتراضي)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "إعطاء عرض تقديمي" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "ملف غير معروف" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "خصائص %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&خطوط" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "قراءة معلومات الخط..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&حجم الصفحة" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "ا&ستخراج الخط" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "النوع 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "النوع 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "النوع 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "النوع 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "تروتايب" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "تروتايب (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "نوع CID ٠" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "نوع CID 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "نوع CID 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID تروتايب" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID تروتايب (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "غير معروف" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "مضمن (جزئية)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "مضمن كاملا" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "لا" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "نعم (جزئية)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "نعم" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[غ/م]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "خط مجهول" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "مضمن: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "الاسم" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "النوع" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "ملف" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "الصفحات" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "الحجم" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "معاينة الطباعة" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "أين تريد حفظ %1؟" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "تعذر فتح %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "تعذر فتح %1. السبب: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "أدخل 3 حروف على الأقل لترشيح الصفحات" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "حساس للحالة" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "طابق العبارة" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "طابق كل الكلمات" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "طابق أي كلمة" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "خيارات المرشح" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

لا تعليق

لإنشاء تعليق جديد اضغط F6 أو حدد أدوات " +"-> معاينة من القائمة.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "اجمع حسب الصفحة" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "اجمع حسب المؤلف" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "اعرض مراجعات للصفحة الحالية فقط" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "خط مجهول" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "ملف غير معروف" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "لا وصف متاح." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "الصفحات: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&خصائص" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "معلومات" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "تعليق" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "أرشيف المستند" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "اعرض الصفحات المعلمة فقط" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "شغّل" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "انتظر" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "أوقف" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "أ&ضِف" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&حرر..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "أ&زِل" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "حرك لأ&على" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "انقل لأ&سفل" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "الصفحة من المستند لتعرض" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "ابدأ المستند في نمط العرض التقديمي" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "ابدأ بحوار الطباعة" + +#: shell/main.cpp:78 +#, fuzzy, kde-format +#| msgid "Start with print dialog" +msgid "Start with print dialog and exit after printing" +msgstr "ابدأ بحوار الطباعة" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "تحكم \"بالنسخة الفريدة\" " + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +#| msgid "Document to open. Specify '-' to read from stdin." +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "اسم الملف لفتحه. حدد '-' لتقرأ من stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "خطأ: لا يُمكِن فتح أكثر من مستند واحد باستخدام الخيار unique--" + +#: shell/okular_main.cpp:130 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "خطأ: لا يُمكِن فتح أكثر من مستند واحد باستخدام الخيار unique--" + +#: shell/okular_main.cpp:136 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --print switch" +msgstr "خطأ: لا يُمكِن فتح أكثر من مستند واحد باستخدام الخيار unique--" + +#: shell/okular_main.cpp:142 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --page switch" +msgstr "خطأ: لا يُمكِن فتح أكثر من مستند واحد باستخدام الخيار unique--" + +#: shell/okular_main.cpp:148 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --find switch" +msgstr "خطأ: لا يُمكِن فتح أكثر من مستند واحد باستخدام الخيار unique--" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "عجز عن إيجاد مكون أوكلار." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "هناك جلسة أوكلار فريدة مفتوحة بالفعل. لن تكون هذه الجلسة جلسة فريدة." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "عجز عن إيجاد مكون أوكلار." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"انقر لفتح ملف\n" +"انقر و أمسك لفتح ملف أخير" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "انقر لفتح ملف انقر وأمسك لتحديد ملف حديث" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "اللسان التالي" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "اللسان السابق" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|كل الملفات" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "المستند المفتوح" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "أغلق" + +#: shell/shell.cpp:606 +#, fuzzy, kde-format +#| msgid "" +#| "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "هناك ملف بنفس الاسم \"%1\" موجود مسبقا. أمتأكد من رغبتك بالكتابة عليه؟" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "مراجعات" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "اخف الاستمارات" + +#~ msgid "Expired" +#~ msgstr "منتهي" + +#~ msgid "&Review" +#~ msgstr "ال&مراجعة" + +#~ msgid "Annotations author" +#~ msgstr "مؤلف التعليقات" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "ضع اسمك أو بداياته:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "اعرض &شريط الملاحة" + +#~ msgid "Show Text" +#~ msgstr "اعرض النص" + +#~ msgid "Small Icons" +#~ msgstr "أيقونات صغيرة" + +#~ msgid "Normal Icons" +#~ msgstr "أيقونات عادية" + +#~ msgid "Large Icons" +#~ msgstr "أيقونات كبيرة" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "انقر لاستخدام أداة التحديد الحالية\n" +#~ "انقر و أمسك لاختيار أداة تحديد أخرى" + +#~ msgid "Created: %1" +#~ msgstr "منشئ: %1" + +#~ msgid "Line Extensions" +#~ msgstr "امتدادات الخط" + +#~ msgid "Style" +#~ msgstr "الأسلوب" + +#~ msgid "&Size:" +#~ msgstr "ال&حجم:" + +#~ msgid "Inner color:" +#~ msgstr "لون داخلين:" + +#~ msgid "Name: %1" +#~ msgstr "الاسم: %1" + +#~ msgid "Size: %1" +#~ msgstr "الحجم: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "أداة التصفح" + +#~ msgid "&Zoom Tool" +#~ msgstr "أداة التكبير" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "كبر" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "التحديد" + +#~ msgid "&Text Selection Tool" +#~ msgstr "أداة النص المختار" + +#~ msgid "T&able Selection Tool" +#~ msgstr "أدوات تحديد الج&داول" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "المكبر" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "نهاية المستند" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "بدون" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "طلب المستند بتشغيله في نمط العرض التقديمي.\n" +#~ "أترغب بالسماح له؟" + +#~ msgid "Presentation Mode" +#~ msgstr "نمط العرض التقديمي" + +#~ msgid "Allow" +#~ msgstr "اسمح" + +#~ msgid "Allow the presentation mode" +#~ msgstr "اسمح بنمط العرض التقديمي" + +#~ msgid "Do Not Allow" +#~ msgstr "لا تسمح" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "لا تسمح بنمط العرض التقديمي" + +#~ msgid "Save &Copy As..." +#~ msgstr "حفظ &نسخة ك..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "لن يتم تصدير حواشيك. \n" +#~ "يمكنك تصدير المستند بحواشيه باستخدام ملف -> صدِّر إلى -> أرشيف مستند" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "وصل إلى نهاية المستند.\n" +#~ "أيتابع من البداية؟" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "وصل إلى بداية المستند.\n" +#~ "أيتابع من الأسفل؟" + +#~ msgid "Current maintainer" +#~ msgstr "المشرف الحالي" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr "ث." + +#~ msgid "Pencil color:" +#~ msgstr "لون قلم الرصاص:" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "حجم ورق عرضيّ غير معروف" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "حجم ورق طوليّ غير معروف" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "بدل نمط الرسم" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "فشل تشغيل خدمة Jovie ناطِق النصوص: %1" + +#~ msgid "Search Columns" +#~ msgstr "ابحث في الأعمدة" + +#~ msgid "All Visible Columns" +#~ msgstr "كل الأعمدة الظاهرة" + +#~ msgid "No document opened." +#~ msgstr "لا يوجد مستند مفتوح." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "لا يمكن فتح أكثر من مستند واحد في جلسة أوكلار الفريدة" + +#~ msgid "No matches found for '%1'." +#~ msgstr "لا مطابق ل '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "جاري البحث..." + +#~ msgid "Searching for %1" +#~ msgstr "البحث عن %1" + +#~ msgid "Identity Settings" +#~ msgstr "إعدادات الهوية" + +#~ msgid "Highlight Properties" +#~ msgstr "إضاءة الخصائص" + +#~ msgid "Ink Properties" +#~ msgstr "حبّر الخصائص" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "تعليق نصي" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "حبر أخضر" + +#~ msgid "Yellow Highlighter" +#~ msgstr "مضيء أصفر" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "إضاءة صفراء" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "خط أصفر مستقيم" + +#~ msgid "Black Underlining" +#~ msgstr "تسطير أسود" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "سطّر تحت النص بخط أسود" + +#~ msgid "Cyan Ellipse" +#~ msgstr "سيان بيضوي" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "إهليلج سماوي" + +#~ msgid "Ink" +#~ msgstr "الحبر" + +#~ msgid "Enable &background generation" +#~ msgstr "مكن ت&وليد الخلفية" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "اخف الاستمارات" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "ينقل إلى الصفحة الأولى من المستند" + +#~ msgid "You must set this name:" +#~ msgstr "يجب تعيين الاسم:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "ال&كتابة عليه" + +#~ msgid "Pages:" +#~ msgstr "صفحات:" + +#~ msgid "Green Highlighter" +#~ msgstr "مضيء أخضر" diff --git a/po/ar/okular_chm.po b/po/ar/okular_chm.po new file mode 100644 index 0000000..6710f34 --- /dev/null +++ b/po/ar/okular_chm.po @@ -0,0 +1,63 @@ +# translation of okular_chm.po to Arabic +# translation of okular_chm.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# ahmad samawi , 2008. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2008-12-21 20:32+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mohamed SAAD محمد سعد ,Ahmad M. Al samawi احمد محمد السماوي " + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "metehyi@free.fr ,ahmad.samawi@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "خلفية CHM " + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "معالج لملفات المساعدة الخاصة بنظام ويندوز مايكروسوفت" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/ar/okular_comicbook.po b/po/ar/okular_comicbook.po new file mode 100644 index 0000000..5a85e56 --- /dev/null +++ b/po/ar/okular_comicbook.po @@ -0,0 +1,59 @@ +# translation of okular_comicbook.po to Arabic +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2008-12-17 12:03+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "تعذر فتح المستند ، لم يتم العثور على برنامج unrar" + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"النسخة الموجودة من برنامج unrar على النظام غير مناسبة لفتح مستندات comicbook" + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "تنسيق comicbooks غير معروف" + +#~ msgid "ComicBook Backend" +#~ msgstr "القاعدة الخلفية لـ comicbooks" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "برنامج لعرض العديد من تنسيقات comicbooks" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "حقوق النسخ 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ar/okular_djvu.po b/po/ar/okular_djvu.po new file mode 100644 index 0000000..889ccd7 --- /dev/null +++ b/po/ar/okular_djvu.po @@ -0,0 +1,139 @@ +# translation of okular_djvu.po to Arabic +# translation of okular_djvu.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# hayig2000 , 2008. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-12-17 12:02+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mohamed SAAD محمد سعد,زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "metehyi@free.fr,zayed.alsaidi@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "المحرر" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "الناشر" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "الحجم" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "نوع المستند" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "مجهول" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "مكوّن الملفات" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "مجهول" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "صفحة مفردة" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "رزمة" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "غير مباشر" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "رزمة (قديم)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "مفهرس (قديم)" + +#~ msgid "DjVu Backend" +#~ msgstr "خلفية DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "خلفية DjVu معتمدة على DjVuLibre" + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "مجهول" diff --git a/po/ar/okular_dvi.po b/po/ar/okular_dvi.po new file mode 100644 index 0000000..4a318b0 --- /dev/null +++ b/po/ar/okular_dvi.po @@ -0,0 +1,729 @@ +# translation of okular_dvi.po to Arabic +# translation of okular_dvi.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# hayig2000 , 2008. +# zayed , 2008. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-07-05 17:47+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "hayig2000,زايد السعيدي,عبدالرحيم الفاخوري" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "hayig2000@gmail.com,zayed.alsaidi@gmail.com,abdilra7eem@yahoo.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

لم يتمكن أوكلار من العثور على برنامج dvipdfm على حاسوبك. هذا " +"البرنامج ضروريّ لعمل دالة التصدير. على أى حال من الممكن تحويل ملف DVI إلىPDF " +"بإستخدام وظيفة الطباعة لدى أوكلار، لكن هذا عادة سيُنشئ ملفات جيدة للطباعة، " +"ولكن جودتها للعرض في قارئ مستندات أدوبي سيئة للغاية. قد يكون أكثر حكمة أن " +"ترقِّي إلى آخر إصدار من توزيعة التكس التي تتضمن برنامج dvipdfm.

تلميحة إلى مدير النظام المُحتار: أوكلار يستخدم متغيِّر البيئة PATH عندما " +"يبحث عن البرامج.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +" البرنامج الخارجي dvipdfm الذي استخدَم في تصدير الملفّ أقر خطأ. ربما ترغب " +"فى النظر إلى مستند معلومات الحوار الذي ستجده في قائمة " +"الملف لمعرفة الخطأ " + +#: dviexport.cpp:158 +#, fuzzy, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"

ملفّ ال DVI يشير إلى رسوم ملفات خارجية ليست فى تنسيق PostScript " +"ولا يمكن معالجتها ببرنامج dvips الذي يستخدمه برنامج أوكلار " +"داخليا فى طبع أو تصدير إلى ال PostScript. ولذلك الوظيفة التي تطلبها غير " +"متوافرة فى هذا الإصدار من أوكلار.

وكحل آخر لهذا يمكن استخدام " +"قائمة ملف/ صدِّر ك فى حفظ هذا الملفّ على تنسيق ال PDF ثم " +"تستخدم مستعرض ال PDF

ومن المخطط إضافة هذه الوظيفة لاحقا

" + +#: dviexport.cpp:166 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvips' on your computer. That " +#| "program is essential for the export function to work.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"أوكلار لم يتمكن من العثور على برنامج dvips على جهازك. ذلك البرنامج هو أساسي " +"لعمل دالة التصدير .\n" +"تلميحة إلى مدير النظام: أوكلار يستخدم بيئة ال PATH المتغيرة عند البحث على " +"البرامج. " + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +" البرنامج الخارجي 'dvips'، والذي استخدم لتصدير ملف، بلّغ عن خطأ. ربما " +"ترغب في نظرة إلى مربع حوار معلومات المستند والتي " +"ستجدها في قائمة ملف لتقرير خطأ دقيق. " + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "ملف الـ DVI لا يبدأ بالتمهيد." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"ملف الـ DVI يحوي إصدار خاطئ من مخرجات الـ DVI لهذا البرنامج. تلميحة: إذا كنت " +"تستعمل نظام إعداد الخط أوميغا، يبغي لك استخدام برنامج خاص، مثل oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "ملف DVI تالف جدا. أوكلار تعذر من العثور على الـpostamble." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "الـpostamble لا يبدأ بأمر اﻹرسال" + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "الـ postamble حوى أمر آخر غير FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "الصفحة %1 لا تبدأ بأمر BOP." + +#: dviFile.cpp:380 +#, fuzzy, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

الـبرنامج الخارجى pdf2ps لم يتمكن من الابتداء ، " +"كنتيجة لهذا ملف ال PDF %1 لم يكن من الممكن تحويله إلى ال PostScript . " +"ولهذا بعض العناصر التخطيطية لن تعرض.

اﻷسباب المحتملة " +"برنامج pdf2ps ربما لا يكون مُثبّتا أو غير موجود فى مسار البحث " +"الحالى

ما الحل برنامجpdf2ps عادة يكون فى " +"توزيعات نظام ghostscript PostScript interpreter .. إذا لم يكن ال " +"ghostscript مُثبّت على الجهاز فمن الممكن تثبيته اﻷن. إذا كنت متأكدا من تثبيت " +"ال ghostscript فرجاء محاولة استخدام pdf2ps من سطر " +"اﻷوامر حتى تتأكد إذا كان يعمل حقا أم لا

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

ملفّ الـ PDF %1 لم يكن من الممكن تحويله إلى PostScript. ولهذا بعض " +"العناصر التخطيطية لن تعرض.

اﻷسباب المحتملة ملفّ %1 معطوب أو " +"ليس ملفّ PDF. هذا هو خرج برنامجpdf2ps الذي استعمله " +"أوكلار :

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "ملف معطوب. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "لا يمكن تضمين كل ملفات بوست سكرِبت في مستندِك. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "تم تضمين كل ملفات بوست سكرِبت في مستندِك." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "الملف المحدد '%1' غير موجود." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"لقد طلبتَ من أوكلار أن يحدد مكان ملف DVI المرتبط بالسطر %1 في ملف تِكس %2. لكن " +"يبدو أن ملف DVI لا يحوي معلومات الملف المصدر الضرورية." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"لم يتمكن أوكلار من إيجاد المكان في ملف DVI المرتبط بالسطر %1 في ملف تِكس %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr " رمز الـ DVI ضبط حرف غير معروف " + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "شفرة الـ DVI تُشير إلى الخط #%1، والذي هو غير معرّف سابقا." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "المكدس لم يكن فارغا عندما لاقى أمر EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "المكدس كان فارغا عندما لاقى أمر POP " + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "رمز الـ DVI أشار إلى خط لم يتم تعريفه" + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "تم مواجهة أمر غير شرعي" + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "تم مواجهة %1 op-code المجهول." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "تضمين %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"صفحة %1: ملف ال PDF %2 لم يكن من الممكن تحويله إلى " +"PostScript
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"صفحة %1: ملف ال PostScript %2 لم يتم العثور عليه.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "معلومات حجم الورق'%1' لا يمكن تحليلها." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

لم يتمكن أوكلار من إيجاد ملفات الخطوط الضرورية لعرض ملف DVI الحاليّ. " +"قد يكون مستندك غير قابل للقراءة.

المسار: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

حدثت مشاكل أثناء تشغيل kpsewhich. نتيجة لذلك، تعذر تحديد بعض " +"ملفات الخطوط، والمستند قد يكون غير مقروء.
الأسباب المحتملة: ربما برنامج " +"kpsewhich غير مثبت في نظامك، أو أنه تعذر إيجاده في مسار البحث " +"الحاليّ.

المسار: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"أُجهِض توليد الخط باستخدام kpsewhich (معطياً رمز الخطأ %1، والخطأ " +"%2). نتيجة لذلك، فإن بعض ملفات الخطوط تعذر إيجاد مكانها، وقد لا يكون مستندك " +"قابلاً للقراءة." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "جاري حاليا توليد %1 بـ %2 نقطة لكل بوصة..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "مولد/تاريخ" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "ملف الخط لم يتم العثور عليه" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "عمودي" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "أفقي" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"لا يحوي إصدار جوستسكرِبت المثبَّت على هذا الحاسوب أيًّا من معرّفات عتاد جوستسكرِبت " +"التي يعرفها أوكلار. لذا تم تعطيل دعم بوست سكرِبت في أوكلار." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

برنامج ال Ghostview الذى يستخدمه أوكلار داخليا فى عرض رسوم ال " +"PostScript المدرج فى ملف ال DVI المستخدم حاليا، هو عموما قادر على كتابة " +"الخارج بتنسيقات مختلفة. البرامج الفرعية التي يستخدمها Ghostview لهذه المهام " +"تسمى سواق اﻷدوات؛ يوجد سائق أداة واحد لكل تنسيق ال Ghostview قادر على " +"كتابته. اﻹصدارات المختلفة لل Ghostview عادة تكون لديها مجموعات مختلفة من " +"سواق اﻷدوات متوفرة. يبدو أن إصدار ال Ghostview المثبت على جهازك لا يحوى على " +"أى من سواق اﻷدوات المعروفة لأوكلار.

من الممكن " +"أيضا ،على غير المعتاد، ألا يحتوى التثبيت العادى لل Ghostview على هذة السولق. " +"ولهذا، هذا الخطأ من الممكن أن يشير إلى إعداد خاطئ جدى لل Ghostview على " +"جهازك. .

إذا أردت إصلاح المشاكل المتعاقة بال Ghostview استخدم أمر " +"gs --help لإظهار قائمة عن سواق اﻷدوات المستخدمة في ال " +"Ghostview. من ضمن أشياء آخرى، من الممكن لأوكلار أن يستخدم سواق ال 'png256'و " +"'jpeg' و 'pnm'. ملاحظة: أوكلار يحتاج إلى إعادة تشغيله حتى يعيد تفعيل دعم ال " +"PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "ذلك يُحدث 25 خطأ. لن تُطبع رسائل خطأ إضافية ." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"خطأ فى ملف ال DVI '%1' صفحة %2. تم مواجهة أمر اللون الشعبى عندما كانت " +"كومة اﻷلوان فارغة." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"معامل مشوّه في الأمر الخاص epsf . \n" +"كان متوقع من الطائف أن يتبع %1 في %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"لم يتم العثور على ملف\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"خطأ فى ملف ال DVI '%1' صفحة %2. لم يتمكن من ترجمة الزاوية فى دوران النص " +"الخاص." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "الأمر الخاص '%1' لم يطبق بعد." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "ملف الخط %1 يمكن فتحه وقراءته، ولكن صياغ الخط غير مدعوم." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "ملف الخط %1 تالف، أو لا يمكن فتحه أو قراءته." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "FreeType بلغ عن خطأ عندما كان يضبط حجم الحرف لملف الخط%1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType عاجز عن تحميل رسمة#%1 من ملف الخط %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType عاجز عن عرض رسمة#%1 من ملف الخط %2. " + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "رسمة #%1 فارغة." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "رسمة #%1 من ملف الخط %2 فارغة." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType عاجز عن تحميل القياس لل glyph # %1 من ملف الخط %2. " + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "لا يستطيع فتح الخط %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: المحرف %1 غير معرف في الخط %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "غير متوقع %1 في ملف PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "المحرف %1 كبير جدا في الملف %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "رقم خطأ في مجموعة البت المخزنة: المحرف. %1، خط %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "ملف pk (%1) غير صالح، مجموعة بت أكثر من اللازم" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "الخط له نسبة عرض إلى إرتفاع غير مربعة" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "غير قادر على العثور على خط %1, الملف %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "خطأ في تدقيق المجموع لملف الخط %1 " + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "عاجز عن التعرف على تنسيق ملف الخط %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"خطأ مُهلِك \n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"هذا على الأرجح يعني إما أنك وجدت عثرة في اﻷكلار ،\n" +"أو أن ملف الـ DVI، أو أن الملفات الإضافية )مثل ملفات الخط،\n" +"أو ملفات الخط الوهمي( حقيقةً تالفة.\n" +"أوكلار سيُجهض بعد هذه الرسالة. إذا كنت تعتقد أنك\n" +"وجدت عثرة، أو أن أوكلار ينبغي أن يحّسن في هذه الحالة\n" +"فضلا بلغ عن المشكلة." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "تم العثور على أمر بايت خاطئ في قائمة ماكرو VF: %1" + +#~ msgid "DVI Backend" +#~ msgstr "خلفية DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "عارض ملف DVI " + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

أوكلار يعتمد على kpsewhich لتحديد ملفات الخطوط على القرص " +#~ "الصلب حتى يولد خطوط ال PK فى الضرورة

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "أوكلار يقوم حاليا بتوليد الصور النقطية للخطوط..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "هذا يجهض عملية توليد الخطوط لا تقم بذلك" + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "الأوكلار حاليا يولد خطوط الصورة النقطية والتي يُحتاج إليها في عرض " +#~ "مستنداتك. لهذا، أوكلار يستخدم عدد من البرامج الخارجية مثل MetaFont. يمكنك " +#~ "أن تجد الخارج لهذه البرامج لاحقا في مربع معلومات المستند. " + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "يقوم أوكلار حاليا بتوليد الخطوط. فضلا انتظر." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr " مربع عملية توليد الخط " + +#~ msgid "Abort" +#~ msgstr "أجهض" + +#~ msgid "What is happening here?" +#~ msgstr "ماذا يحصل هنا؟" + +#~ msgid "%v of %m" +#~ msgstr "%v من %m" + +#~ msgid "Please be patient" +#~ msgstr "فضلا كن صبورا" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|تنسيق المستند المحمول (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "صدر الملف كـ" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "الملف %1\n" +#~ "موجود. هل تريد الكتابة عليه؟" + +#~ msgid "Overwrite File" +#~ msgstr "اكتب على الملف" + +#~ msgid "Overwrite" +#~ msgstr "اكتب فوقه" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "استعمال dvipdfm لتصدير الملف إلى PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "أوكلار حاليا يستخدم برنامجا خارجيا 'dvipdfm' لتحويل ملف DVI إلى PDF. " +#~ "أحيانا تأخذ هذه العملية وقتا لأن dvipdfm يحتاج لتوليد الصور النقطية " +#~ "للخطوط الخاصة به فضلا كن صبورا. ." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "انتظار dvipdfm لينتهي..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|بوست سكربت (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "إستعمال dvips لتصدير الملف إلى PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "أوكلار يستخدم حاليا برنامج خارجي 'dvips' لتحويل ملف الـ DVI إلى " +#~ "PostScript. قد يأخذ ذلك أحيانا وقتا لأن dvips يحتاج إلى توليد الصور " +#~ "النقطية للخطوط الخاصة به، فضلا كن صبورا." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "ينتظر dvips لينتهي..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "الوظيفة غير متوفّر" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ " ملف فاسد أوكلار لم يتمكن من ترجمة ملفك ال DVI. " +#~ "هذا يحدث عادة نتيجة ملف فاسد " + +#~ msgid "DVI File Error" +#~ msgstr "خطأ ملف DVI " + +#~ msgid "Not All Font Files Found" +#~ msgstr "لم تتم العثور على كل ملفات الخطوط" + +#~ msgid "Locating fonts..." +#~ msgstr "تحديد خطوط..." + +#~ msgid "Problem locating fonts" +#~ msgstr "لم يتمكن فى العثور على الخطوط" + +#~ msgid "Font generation aborted" +#~ msgstr "تم إجهاض عملية توليد الخط" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "تصدير: %1 إلى PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "صدر: %1 إلى PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "قائمة الخطوط فارغة حاليا." + +#~ msgid "TeX Name" +#~ msgstr "اسم TeX " + +#~ msgid "Family" +#~ msgstr "العائلة" + +#~ msgid "Zoom" +#~ msgstr "تكبير" + +#~ msgid "Type" +#~ msgstr "النوع" + +#~ msgid "Encoding" +#~ msgstr "الترميز" + +#~ msgid "Comment" +#~ msgstr "التعليق" + +#~ msgid "TeX virtual" +#~ msgstr "TeX الوهمي" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX Font Metric" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/ar/okular_epub.po b/po/ar/okular_epub.po new file mode 100644 index 0000000..f1b8df0 --- /dev/null +++ b/po/ar/okular_epub.po @@ -0,0 +1,57 @@ +# translation of okular_epub.po to Arabic +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# zayed , 2008. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-07-05 19:05+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "حدث خطأ أثناء فتح مستند الـ EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, fuzzy, kde-format +msgid "EPub Backend Configuration" +msgstr "قاعدة خلفية لـ EPub" + +#~ msgid "EPub Backend" +#~ msgstr "قاعدة خلفية لـ EPub" + +#~ msgid "An EPub backend" +#~ msgstr "قاعدة خلفية لـ EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "حقوق النسخ 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/ar/okular_fax.po b/po/ar/okular_fax.po new file mode 100644 index 0000000..75dea5f --- /dev/null +++ b/po/ar/okular_fax.po @@ -0,0 +1,46 @@ +# translation of okular_fax.po to Arabic +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-17 12:03+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "تعذر تحميل المستند" + +#~ msgid "Fax Backend" +#~ msgstr "القاعدة الخلفية للفاكس" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "القاعدة الخلفية لمستندات الفاكس G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "حقوق النسخ 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ar/okular_fictionbook.po b/po/ar/okular_fictionbook.po new file mode 100644 index 0000000..2de5fb3 --- /dev/null +++ b/po/ar/okular_fictionbook.po @@ -0,0 +1,85 @@ +# translation of okular_fictionbook.po to Arabic +# translation of okular_fictionbook.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# ahmad samawi , 2008. +# zayed , 2008. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-07-05 19:05+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ahmad Samawi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ahmad.samawi@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "المستند ليس FictionBook صحيح" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "لا يمكن فتح الملف: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "نوع ملف غير صحيح , ليس ملف أرشيف من نوع zip" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "بنية ملف غير صحيحة (المجلد الرئيسي مفقود)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "لا يوجد محتوى في المستند" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "مستند XML غير صحيح %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +msgid "FictionBook Backend Configuration" +msgstr "منصة خلفية لملفات Fiction book" + +#~ msgid "Fiction Book Backend" +#~ msgstr "منصة خلفية لملفات Fiction book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "معالج الكتب الالكترونية الخاصة ب FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ar/okular_ghostview.po b/po/ar/okular_ghostview.po new file mode 100644 index 0000000..980b9a5 --- /dev/null +++ b/po/ar/okular_ghostview.po @@ -0,0 +1,95 @@ +# translation of okular_ghostview.po to Arabic +# translation of okular_ghostview.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# ahmad samawi , 2008. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-23 11:26+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "احمد السماوي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ahmad.samawi@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "استعمل خطوط المنصة" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"تحدد إذا ما كان يستطيع Ghostscript أن يستخدم خطوط المنصة ، إذا كان لا ؛ فإنه " +"سيستعمل الخطوط المضمنة في المستند." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "الإعدادات العامة" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "ا&ستعمل خطوط المنصة" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript غوست سكريبت" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "اعدادات منصة غوست سكريبت الخلفية" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "إصدار المستند" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "مستوى اللغة" + +#~ msgid "PS Backend" +#~ msgstr "منصة خلفية لملفات PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "معالج ملفات بوست سكريبتز" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "جميع الحقوق محفوظة البرت استلس سيد 2007-2008" + +#~ msgid "Based on the Spectre library." +#~ msgstr "مبني على مكتبة سبيكتري spectre" + +#~ msgid "Albert Astals Cid" +#~ msgstr "البرت استلس سيد" diff --git a/po/ar/okular_kimgio.po b/po/ar/okular_kimgio.po new file mode 100644 index 0000000..9e0018d --- /dev/null +++ b/po/ar/okular_kimgio.po @@ -0,0 +1,70 @@ +# translation of okular_kimgio.po to Arabic +# translation of okular_kimgio.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# zayed , 2008, 2012. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2012-01-22 22:32+0400\n" +"Last-Translator: Zayed Al-Saidi \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "عاجز عن تحميل مستند: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "محرك الصور" + +#~ msgid "A simple image backend" +#~ msgstr "محرك صور بسيط" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "شريط الأدوات الرئيسي" diff --git a/po/ar/okular_mobi.po b/po/ar/okular_mobi.po new file mode 100644 index 0000000..f2335ad --- /dev/null +++ b/po/ar/okular_mobi.po @@ -0,0 +1,62 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Zayed Al-Saidi , 2009. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-07-05 19:06+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "خطأ أثناء فتح مستند Mobipocket ." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "هذا الكتاب محمي بواسطة DRM و يمكن عرضه فقط في جهاز مخصص" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, fuzzy, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "خلفية Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "خلفية Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "خلفية Mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/ar/okular_plucker.po b/po/ar/okular_plucker.po new file mode 100644 index 0000000..5744b51 --- /dev/null +++ b/po/ar/okular_plucker.po @@ -0,0 +1,48 @@ +# translation of okular_plucker.po to Arabic +# translation of okular_plucker.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-17 12:03+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "الاسم" + +#~ msgid "Plucker Document Backend" +#~ msgstr "القاعدة الخلفية لمستندات Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "برنامج لعرض الكتب الإلكترونية بصيغة Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "حقوق النسخ 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ar/okular_poppler.po b/po/ar/okular_poppler.po new file mode 100644 index 0000000..c66893b --- /dev/null +++ b/po/ar/okular_poppler.po @@ -0,0 +1,226 @@ +# translation of okular_poppler.po to Arabic +# translation of okular_poppler.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# hayig2000 , 2008. +# zayed , 2008, 2012. +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-07-05 19:04+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "حَسِّن الخطوط الرفيعة" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "لا" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "صلب" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "الشكل" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "خيارات PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "اطبع الحواشي" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "ضَمِّن الحواشي في المستند المطبوع" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"ضمِّن الحواشي في المستند المطبوع. عطِّل هذا الخيار إذا كنت تريد طباعة المستند " +"الأصلي غير ذي الحواشي." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "أجبر التحويل" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "حول إلى صورة قبل الطباعة" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"أجبر تحويل كل صفحة إلى صورة قبل الطباعة. هذا عادة يعطى نتائج أسوا ولكنه مفيد " +"فى طباعة الملفات التى تطبع بشكل خاطئ." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "التنسيق" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "مشفّرة" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "غير مشفّرة" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "الأمن" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "نعم" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "محسّن" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, fuzzy, kde-format +msgid "PDF Backend Configuration" +msgstr "خلفية PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "خلفية PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "مصير (محول) لملفات PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "حفظ الملفات بالتشفير غير مدعوم." + +#~ msgid "Unknown" +#~ msgstr "مجهول" + +#~ msgid "Unknown Date" +#~ msgstr "التاريخ مجهول" + +#~ msgid "Unknown Encryption" +#~ msgstr "التشفير مجهول" + +#~ msgid "Unknown Optimization" +#~ msgstr "التحسين مجهول" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "رجاء أدخل كلمة السر لقراءة المستند:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "كلمة السر خاطئة حاول مرة آخرى" + +#~ msgid "Document Password" +#~ msgstr "كلمة سر المستند" diff --git a/po/ar/okular_txt.po b/po/ar/okular_txt.po new file mode 100644 index 0000000..0a78f22 --- /dev/null +++ b/po/ar/okular_txt.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Abdalrahim G. Fakhouri , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-07-05 19:08+0300\n" +"Last-Translator: Abdalrahim G. Fakhouri \n" +"Language-Team: Arabic >\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "عبدالرحيم الفاخوري" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "abdilra7eem@yahoo.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "" + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/ar/okular_xps.po b/po/ar/okular_xps.po new file mode 100644 index 0000000..53a361a --- /dev/null +++ b/po/ar/okular_xps.po @@ -0,0 +1,60 @@ +# translation of okular_xps.po to Arabic +# translation of okular_xps.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Youssef Chahibi , 2007. +# zayed , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-17 12:03+0400\n" +"Last-Translator: zayed \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"X-Generator: KBabel 1.11.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "زايد السعيدي" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zayed.alsaidi@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "المراجعة" + +#~ msgid "XPS Backend" +#~ msgstr "نهاية خلفية لملفات XPS" + +#~ msgid "An XPS backend" +#~ msgstr "نهاية خلفية لملفات XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/ast/okular_chm.po b/po/ast/okular_chm.po new file mode 100644 index 0000000..e2aafde --- /dev/null +++ b/po/ast/okular_chm.po @@ -0,0 +1,40 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# enolp , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2019-05-22 02:54+0200\n" +"Last-Translator: enolp \n" +"Language-Team: Asturian \n" +"Language: ast\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Softastur" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "alministradores@softastur.org" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" diff --git a/po/ast/okular_fax.po b/po/ast/okular_fax.po new file mode 100644 index 0000000..59fe12d --- /dev/null +++ b/po/ast/okular_fax.po @@ -0,0 +1,33 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# enolp , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2019-05-22 02:55+0200\n" +"Last-Translator: enolp \n" +"Language-Team: Asturian \n" +"Language: ast\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Softastur" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "alministradores@softastur.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Nun pue cargase'l documentu" diff --git a/po/ast/okular_plucker.po b/po/ast/okular_plucker.po new file mode 100644 index 0000000..c8ad2fb --- /dev/null +++ b/po/ast/okular_plucker.po @@ -0,0 +1,33 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# enolp , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2019-05-22 02:53+0200\n" +"Last-Translator: enolp \n" +"Language-Team: Asturian \n" +"Language: ast\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Softastur" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "alministradores@softastur.org" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nome" diff --git a/po/ast/okular_xps.po b/po/ast/okular_xps.po new file mode 100644 index 0000000..3e785d9 --- /dev/null +++ b/po/ast/okular_xps.po @@ -0,0 +1,33 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# enolp , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2019-05-22 02:55+0200\n" +"Last-Translator: enolp \n" +"Language-Team: Asturian \n" +"Language: ast\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Softastur" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "alministradores@softastur.org" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisión" diff --git a/po/bg/okular.po b/po/bg/okular.po new file mode 100644 index 0000000..51dd68c --- /dev/null +++ b/po/bg/okular.po @@ -0,0 +1,5871 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007, 2008, 2009. +# Yasen Pramatarov , 2010, 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2013-09-23 22:50+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Bookmarks: -1,-1,-1,-1,-1,-1,74,-1,-1,-1\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Радостин Раднев,Красимир Арнаудов,Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "radnev@yahoo.com,krasi.arnaudov@gmail.com,zlatkopopov@fsa-bg.org" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular - универсална програма за разглеждане на документи" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2009 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Поддръжка (бивш)" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Много работа по рамките, ODT и FictionBook" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "KPDF разработка" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Създаде okular на основата на KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF разработка" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Украси за бележките" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Инструмент за избиране на таблици" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Подобрения в бележките" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Отиване на страница %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Отваряне на външен файл" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Изпълнение на \"%1\"..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Първа страница" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Предишна страница" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Следваща страница" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Последна страница" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Назад" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Напред" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Изход" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Начало на презентация" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Край на презентация" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Търсене..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Отиване на страница..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Звуков сигнал..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript скрипт" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Видео..." + +#: core/action.cpp:547 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Play movie" +msgstr "Видео..." + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "" + +#: core/action.cpp:551 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Pause movie" +msgstr "Видео..." + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Избор на помощна програма" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Намерена е повече от една помощна програма за файлов тип:
%1 " +"(%2).

Моля изберете коя да бъде използвана:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Отиване на страница %1" + +#: core/document.cpp:224 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "portrait C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "вертикално C5E" + +#: core/document.cpp:226 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "landscape C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "хоризонтално C5E" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 инча (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 мм (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Не е намерена приставка за обработка на този документ." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "премахване на бележките" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Документът се опитва да стартира външно приложение. От съображения за " +"сигурност Okular не позволява това." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Не е намерена програма, която да може да отвори файла от типа %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Грешка при отваряне на временния файл" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Грешка при преобразуването за печат" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Процесът за печат блокира" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Процесът за печат не може да се зареди" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Грешка при печат към файл" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Принтерът е в неподходящо състояние" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Грешка при откриване на файл за печат" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Няма файл за отпечатване" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Не е открита подходяща програма за печат. Уверете се, че програмата lpr на " +"CUPS е налична" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "\"%1\" не може да бъде отворен. Файлът не съществува." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Заглавие" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Тема" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Описание" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Автор" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Създател" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Производител" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Авторски права" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Страници" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Създаден" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Последна промяна" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Тип файл" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Категория" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Ключови думи" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Път до файла" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Големина на файла" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Размери на страницата" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "добавяне на бележка" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "премахване на бележка" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "настройки на бележка" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "превод на бележка" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "добавяне на бележка" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "редактиране на текст" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "редактиране съдържанието на бележка" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Неформатиран &текст..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument Text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Настройки на редактора" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Цветови режим:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Затваряне на съобщението" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Източник: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Шрифт по подразбиране:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Презареж&дане" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Позволявам" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Екран" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "До широчината на страницата" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Настройки за бележка" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Инструменти за бележки" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Инструменти за бележки" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Инструменти за бележки" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Инструменти за бележки" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Бележка" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Настройки за бележка" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&Цвят:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&Цвят:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Експериментален" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "&Избиране" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "Бележки" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Подсветяване" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Подчертаване" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Криволичещ" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Зачертаване" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Информация за произволен текст" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Бележка между редовете" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "&Отваряне на бележка" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Черта на ръка" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Права линия" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Правоъгълник" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Елипса" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Многоъгълник" + +#: part/annotationactionhandler.cpp:534 +#, fuzzy, kde-format +#| msgid "Geometrical shape" +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Геометрична форма" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Печат" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Бележки" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "добавяне на бележка" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Инструмент за създаване на бележки" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Шрифт:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Настройки за бележка" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Линия" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&Непрозрачност:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Страница %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Бележка" +msgstr[1] "%1 бележки" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Отваряне на бележка" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Изтриване" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Информация" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Запис на \"%1\"..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Външен вид" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Общи" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Автор:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Създаден" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Последна промяна" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Pop-up Note Properties" +msgstr "Информация за бележка" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "Информация за произволен текст" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Информация за бележка между редовете" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line Properties" +msgstr "Информация за линия" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +#| msgid "Sound Properties" +msgid "Polygon Properties" +msgstr "Информация за звука" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Информация за геометрия" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Stamp Properties" +msgid "Text Markup Properties" +msgstr "Информация за печат" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Информация за печат" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line Properties" +msgstr "Информация за линия" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Информация за произволен текст" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Информация за прикрепен файл" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Информация за звука" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Информация за видео" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Информация за бележка" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Последна промяна: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Поставяне на печат" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Цвят:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Непрозрачност:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Икона" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Коментар" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Помощ" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Вмъкване" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Клавиш" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Нов абзац" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Бележка" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Абзац" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Шрифт:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Цвят:" + +#: part/annotationwidgets.cpp:389 +#, fuzzy, kde-format +#| msgid "Align:" +msgid "&Align:" +msgstr "Подравняване:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Ляво" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Центрирано" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Дясно" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Одобрен" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Както е" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Поверителен" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Ведомствен" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Чернова" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Експериментален" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Окончателен" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "За коментар" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Публична версия" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Неодобрен" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Не е публична версия" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Продаден" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Свръх секретен" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Отметка" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Информация" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Печат" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "До широчината на страницата" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Линия" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Линия" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Без" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Дължина на водеща линия:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Дължина на разширения за водеща линия:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Запис във файл..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Тип:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Подсветяване" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Криволичещ" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Подчертаване" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Зачертаване" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Правоъгълник" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Елипса" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "Сивмол за прикрепен файл" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Графика" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Карфица" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Кламер" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Етикет" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Файл" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "Н/И" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Няма информация." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "&Name:" +msgid "Name:" +msgstr "&Име:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Описание:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "Символ за каре" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Без" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Затваряне на бележката" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Настройки" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Не е намерена програмата latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Грешка при обработката с LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Не е намерена програмата dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Възникна проблем при изпълнение на програмата \"latex\"." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Възникна проблем при изпълнение на програмата \"dvipng\"." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Една отметка" +msgstr[1] "" +"%1\n" +"\n" +"%2 отметки" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Отметки" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "&Търсене:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Само текущия документ" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Към тази отметка" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Преименуване на отметка" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Премахване на отметка" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Отваряне на документ" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Премахване на отметки" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "Номер на страница" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Изтекъл" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Тема" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Използване на паметта" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Информация" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "Настройки на прегледа" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "Е&кспортиране като" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Общи" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Къде искате да запишете %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Презареж&дане" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "Екран" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Позволявам" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Изчертаване на контур около &изображенията" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Изчертаване на контур около &връзките" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Смяна на &цветовете" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Предупреждение: това може да засегне скоростта на изчертаване." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Цветови режим:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Инвертиране на цветовете" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Промяна цвета на фона" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Промяна на тъмни и светли цветове" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Конвертиране в чернобял" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Цвят на документ:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Тъмен цвят:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Светъл цвят:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Праг:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Контраст:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Самоличност" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&Автор:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Забележка: информацията тук се използва само за коментари и прегледи. " +"Няма да бъде предавана без вашето знание." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "Инструмент за редактиране на бележки" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Потребителски текстов редактор" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs клиент" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx клиент" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Напишете командата с която да бъде стратират текстовия редактор.
\n" +"Можете да укажете и:\n" +"
    \n" +"
  • %f - име на файла
  • \n" +"
  • %l - ред от файла
  • \n" +"
  • %c - колона от файла
  • \n" +"
\n" +"Ако не сте посочили %f, тогава името на файла се добавя към командата." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Редактор" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Редактор:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Изберете редактора, който искате да се стратира, когато Okular иска да " +"отвори файл." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Команда:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Външен вид" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Показване на лен&тите за превъртане" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Връзка на &умалените копия със страницата" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Показване на по&дсказки" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, fuzzy, kde-format +#| msgid "Display document title in title bar" +msgid "Display document title in titlebar if available" +msgstr "Показване името на документа в заглавната лента" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, fuzzy, kde-format +#| msgid "Display document title in title bar" +msgid "When not displaying document title:" +msgstr "Показване името на документа в заглавната лента" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Цвят на фона:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Възможности на програмата" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Спазване на DRM ограниченията" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Презареждане на документа при промяна на файла" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Показване на диалог за избор на помощна програма" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Настройки на изгледа" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, fuzzy, kde-format +#| msgid "Overview columns:" +msgid "Overview &columns:" +msgstr "Колони:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Увеличение по подразбиране:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "До широчината на страницата" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "До височината на страницата" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "Минимизиране на използваната памет." + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Балансирано използване на паметта и скоростта. Предварително зареждане на " +"следващата страница (препоръчва се за системи с 256 МБ)." + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Пълно използване на паметта. Предварително зареждане на всички страници " +"(препоръчва се за системи с 512 МБ)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Натоварване на процесора" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "П&розрачност" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Използване на паметта" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Малко" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&Нормално (по подразбиране)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "&Агресивно" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Rendering" +msgstr "Подчертаване" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Text Antialias" +msgstr "Преход" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Graphics Antialias" +msgstr "Преход" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Text Hinting" +msgstr "Преход" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Текущ екран" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Стандартен екран" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Екран %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " секунда" +msgstr[1] " секунди" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Навигация" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Прелистване:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "След последната страница връщане в началото" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Навигация" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Цвят на фона:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Курсор на мишката:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Скриване със закъснение" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Винаги видим" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Винаги скрит" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Индиактор на &страниците" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Показване на &кратко резюме" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Преход" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Преход по подразбиране:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Щори вертикално" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Щори хоризонтално" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Поле в" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Поле извън" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Разтваряне" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Блестене долу" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Блестене вдясно" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Блестене вдясно-долу" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Произволен преход" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Заместване" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Разделяне хоризонтално навътре" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Разделяне хоризонтално навън" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Разделяне вертикално навътре" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Разделяне вертикално навън" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Изтриване надолу" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Изтриване надясно" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Изтриване наляво" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Изтриване нагоре" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Местоположение" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Екран:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "Изтриване на начертаното" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Име:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Вид:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgid "Pop-up Note" +msgstr "&Отваряне на бележка" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Бележка между редовете" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Черта на ръка" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Права линия" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Многоъгълник" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +#| msgid "Next Bookmark" +msgid "Text markup" +msgstr "Следваща отметка" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Геометрична форма" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Печат" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Инструмент за създаване на бележки" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Инструмент за редактиране на бележки" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&Цвят:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "До широчината на страницата" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgid "Create drawing tool" +msgstr "Инструмент за създаване на бележки" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Edit drawing tool" +msgstr "Инструмент за редактиране на бележки" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Неизвестна" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Вградени файлове" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&Изглед" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Име" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Описание" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Големина" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Създаден" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Последна промяна" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Запи&с като..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Изглед" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Не може да бъде зареден \"print preview part\"" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Предпечатен преглед" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Затваряне" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Търсене:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Търсен текст" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Следващ" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Прескачане до следващото съвпадение" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Предишен" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Прескачане до предишното съвпадение" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Поведение на търсене" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Чувствителен регистър" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "От текущата позиция" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Всички файлове" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "Информация за произволен текст" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line with Comment" +msgstr "Информация за линия" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "За коментар" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Геометрия" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "Подсветяване" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle with Comment" +msgstr "Криволичещ" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Underline text" +msgid "Underline with Comment" +msgstr "Подчертаване на текст" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Strike out text" +msgid "Strike Out with Comment" +msgstr "Зачертаване на текст" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Зачертаване" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line with Comment" +msgstr "Информация за линия" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Каре" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Прикрепен файл" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Звук" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Видео" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Екран" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Неизвестен" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Автор: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Къде искате да запишете %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "\"%1\" не може да бъде отворен за запис. Файлът не е записан." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Настройки на търсенето" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Чувствителен регистър" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Регулярен израз" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Търсене:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "от" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Увеличение" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Завъртане на&дясно" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Надясно" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Завъртане на&ляво" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Наляво" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Първоначална ориентация" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&Изглед" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Отр&язване на отстъпите" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Избиране на текст" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "До &широчината на страницата" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "До &височината на страницата" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "До &височината на страницата" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Режим на преглед" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Една страница" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Огледални страници" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Огледални страници (първата страница центрирана)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Широк" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "Б&ез прекъсване между страниците" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Разглеждане" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Увеличение" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &colors" +msgid "&Toggle Change Colors" +msgstr "Смяна на &цветовете" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Избиране на текст" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Избиране на текст" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "Избиране на таблица" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Инструменти за маркиране" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Произнасяне на документа" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Произнасяне на страницата" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Спиране на произнасянето" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Превъртане нагоре" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Превъртане надолу" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Превъртане страница нагоре" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Превъртане страница надолу" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Показване на формуляри" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Зареден е документ от една страница." +msgstr[1] " Зареден е документ от %1 страници." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Текст (1 знак)" +msgstr[1] "Текст (%1 знака)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Копиране в системния буфер" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Копирането забранено поради DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Произнасяне на текст" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Изображение (%1х%2 пиксела)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Запис във файл..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Изображението (%1х%2) е копирано в системния буфер." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Запис във файл..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Файлът не е записан." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Изображението (%1х%2) е записано във файла %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Копиране на текст" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Отиване до \"%1\"" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Търсене на \"%1\" с" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Настройки на уеб-препратки..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Към връзката" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "Звуков сигнал..." + +#: part/pageview.cpp:4179 +#, fuzzy, kde-format +#| msgid "Sound" +msgid "Stop Sound" +msgstr "Звук" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Копиране адреса на връзката" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Търсене на \"%1\" с" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Добре дошли" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "" +"Маркирайте желаната част от документа. За намаляване щракнете с десния бутон " +"на мишката." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "" +"Изчертайте правоъгълник около текста/изображението, което искате да копирате." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Маркиране на текст" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Изчертайте правоъгълник около текста/изображението, което искате да копирате." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Изчертайте правоъгълник около текста/изображението, което искате да копирате." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Нова бележка" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Текст на бележката:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "добавяне на бележка" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Бележка между редовете (изтеглете за да маркирате област)" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Подсветяване" + +#: part/pageviewannotator.cpp:1025 +#, fuzzy, kde-format +#| msgid "Green Freehand Line" +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Зелена черта на ръка" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Бележка между редовете (изтеглете за да маркирате област)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "" +"Изчертаване на многоъгълник (щракнете на първата точка, за да го затворите)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Чертане на правоъгълник" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Криволичещ" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Поставяне на печат" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Чертане на права линия" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Зачертаване на текст" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Подчертаване на текст" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Бележка между редовете (изтеглете за да маркирате област)" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "Подсветяване" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "добавяне на бележка" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Custom annotation name:" +msgstr "добавяне на бележка" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Файл" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Настройки" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Помощ" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Ориентация" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Отметки" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Лента с инструменти за преглед" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Умалени копия" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Бележки" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Документа съдържа вградени файлове. Щракнете тук за да ги видите или отидете на Файл -> Вградени файлове." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Предишна" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Към предишната страница" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Отиване на предишната страница на документа" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Следваща" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Към следващата страница" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Отиване на следващата страница на документа" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Начало на документа" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Отиване в началото на документа" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Край на документа" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Отиване в края на документа" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Преименуване на текущата отметка" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Предишна отметка" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Към предишната отметка" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Следваща отметка" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Към следващата отметка" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Настройки на Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Настройки на прегледа..." + +#: part/part.cpp:735 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Viewer Backends..." +msgstr "Настройване на помощните програми..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Настройки на ядрата" + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Относно ядрото" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Презареж&дане" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Презареждане текущия документ от диска." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Затваряне &лентата за търсене" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Номер на страница" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Произнасяне на страницата" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Показване на лента за &страниците" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Показване на лента за &страниците" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Показване на &навигационния панел" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Вградени файлове" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "Е&кспортиране като" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "П&резентация" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Внасяне на Postscript като PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Изтегляне на книги от Интернет..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Превключане към черен екран" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Изтриване на начертаното" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Настройки на бележките..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "Презентация" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Грешка при отваряне на %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Зареждането на %1 беше прекъснато." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Грешка при отваряне на %1. Причина: %2" + +#: part/part.cpp:1186 +#, fuzzy, kde-format +#| msgid "Configure Backends" +msgid "Configure Viewer Backends" +msgstr "Настройване на помощните програми" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Настройване на помощните програми" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Програмата \"ps2pdf\" не е открита. Оkular не може да импортира PS файлове." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf не е открита" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Импортиране на PS файла като PDF (може да отнеме известно време)..." + +#: part/part.cpp:1409 +#, fuzzy, kde-format +#| msgid "Moves to the end of the document" +msgid "Please enter the password to read the document:" +msgstr "Отиване в края на документа" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Password" +msgstr "Архив с документи" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Документа съдържа формуляри. Натиснете бутона за да работите с тях или " +"използвайте Изглед -> Показване на формуляри." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Печатането на документа не е разрешено." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Печатането на документа не е разрешено." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Изход от режим \"презентация\"" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Грешка при отваряне на %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "Б&ез прекъсване между страниците" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "Б&ез прекъсване между страниците" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Затваряне на документа" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Връзката сочи към операция от затворен документ, която не работи с вграден " +"визуализатор." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Връзката сочи към операция от затворена програма, която не работи с вграден " +"визуализатор." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Презареждане на документа..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Съдържание" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Към страница" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Страница:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Въведете ново име за отметката:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Преименуване на отметката" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename this Bookmark" +msgid "Remove this Bookmark" +msgstr "Преименуване на отметката" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "Запи&с като..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Временният файл не може да бъде отворен за запис." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Файлът не може да бъде записан в \"%1\". Пробвайте да го запишете в друга " +"директория." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgctxt "remove a collection of annotations from the page" +#| msgid "remove annotations" +msgid "User annotations" +msgstr "премахване на бележките" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "Б&ез прекъсване между страниците" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Файлът не може да бъде записан в '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular не може да копира %1 в посоченото местоназначение.\n" +"\n" +"Документът вече не съществува." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Файлът не може да бъде записан в \"%1\". Пробвайте да го запишете в друга " +"директория." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Край на презентация" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Добавяне на отметка" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Инструменти" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Печатането на документа не е разрешено." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Грешка при печат на документа. Непозната грешка. Моля, съобщете за грешка на " +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Грешка при печат на документа. Подробната грешка е \"%1\". Моля, съобщете за " +"грешка на bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Назад една стъпка" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Напред една стъпка" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"
%1." +msgstr "" +"Грешка! Не може да бъде създаден временен файл " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Грешка! Файлът %1 не може " +"да бъде отворен за разкомпресиране и няма да бъде зареден." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Грешката възниква ако нямате права за четене върху файла. Можете да " +"проверите собственост и права като щракнете с десния бутон върху файла в " +"Konqueror и изберете менюто \"Информация\"." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Грешка! Файлът %1 не може " +"да бъде разкомпресиран и няма да бъде зареден." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Грешката възниква ако файла е повреден. Ако искате да сте сигурни, " +"опитайте се да го разкомпресирате ръчно използвайки програма от командния " +"ред." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Няма отметки" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Редактиране" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Изглед" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Навигация" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Инструменти" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Главна лента с инструменти" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Инструменти за бележки" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Общи настройки" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Достъпност" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Помощ за достъпност" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Скорост" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Настройки на скоростта" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Настройки на прегледа" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Презентация" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Настройки на режима за презентация" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Настройки за бележка" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Настройки на редактора" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Търсене на следващ" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - Презентация" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Превключване на екрана" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Екран %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Изход от режим \"презентация\"" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Заглавие: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Страници: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Щракнете за начало" + +#: part/presentationwidget.cpp:505 +#, fuzzy, kde-format +#| msgctxt "pause the movie playback" +#| msgid "Pause" +msgctxt "For Presentation" +msgid "Pause" +msgstr "Пауза" + +#: part/presentationwidget.cpp:508 +#, fuzzy, kde-format +#| msgctxt "start the movie playback" +#| msgid "Play" +msgctxt "For Presentation" +msgid "Play" +msgstr "Изпълнение" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Има два начина за изход от режим \"Презентация\" - можете да натиснете " +"клавиша \"ESC\" или бутона \"Изход\", който се показва при поставяне на " +"мишката в горния десен ъгъл. Разбира се, можете да сменяте прозорците (Alt" +"+TAB по подразбиране)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Презентация" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Непознат файл" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Информация за %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Шрифтове" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Четене на информацията за шрифта..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Размер на страница" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Извличане на шрифта" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX виртуален" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Непознат" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Вграден" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Напълно вграден" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Не" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Да" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Да" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[н/и]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Непознат шрифт" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Вграден: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Име" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Тип" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Файл" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Страници" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Големина" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Предпечатен преглед" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Къде искате да запишете %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Грешка при отваряне на %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Грешка при отваряне на %1. Причина: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Въведете поне 3 букви, за да се филтрират страниците" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Чувствителен регистър" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Съвпадение на фразата" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Съвпадение на всички думи" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Съвпадение на коя да е дума" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Настройки на филтъра" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Няма бележки

За да създадете нова, натиснете F6 " +"или от менюто изберете Инструменти -> Преглед.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Групиране по страница" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Групиране по автор" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Показване на преглед само за текущата страница" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Непознат шрифт" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Непознат файл" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Няма информация." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Страници: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Информация" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Информация" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "Бележка" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "Архив с документи" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Показване само на страници с отметки" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Изпълнение" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Пауза" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Спиране" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "До&бавяне..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Редактиране..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Премахване" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Преместване на&горе" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Преместване на&долу" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Страница от документа която да бъде показана" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Стартиране на документа в режим на презентация" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Контрол \"Unique instance\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +#| msgid "Document to open. Specify '-' to read from stdin." +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Документ, който да бъде отворен. Посочете \"-\" за четене от stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "Не е открита частта на Okular." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Не е открита частта на Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Щракнете за отваряне на файл\n" +"Щракнете и задръжте за отваряне на скоро използван файл" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Щракнете за отваряне на файл или щракнете и задръжте за " +"отваряне на скоро използван файл" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +#| msgid "Next Page" +msgid "Next Tab" +msgstr "Следваща страница" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +#| msgid "Previous Page" +msgid "Previous Tab" +msgstr "Предишна страница" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Всички файлове" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Отваряне на документ" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Затваряне" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Прегледи" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Скриване на формуляри" + +#~ msgid "Expired" +#~ msgstr "Изтекъл" + +#~ msgid "&Review" +#~ msgstr "&Преглед" + +#~ msgid "Annotations author" +#~ msgstr "Автор на бележка" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Моля, въведете вашето името или инициали:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Показване на &навигационния панел" + +#~ msgid "Show Text" +#~ msgstr "Показване на текст" + +#~ msgid "Small Icons" +#~ msgstr "Малки икони" + +#~ msgid "Normal Icons" +#~ msgstr "Нормални икони" + +#~ msgid "Large Icons" +#~ msgstr "Големи икони" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Щракнете тук, за да изпозлвате текущия интрумент за маркиране\n" +#~ "Щракнете и задръжте, за да иберете друг инструмент" + +#~ msgid "Created: %1" +#~ msgstr "Създаден: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Разширения на линия" + +#~ msgid "Style" +#~ msgstr "Стил" + +#~ msgid "&Size:" +#~ msgstr "&Големина:" + +#~ msgid "Inner color:" +#~ msgstr "Вътрешен цвят:" + +#~ msgid "Name: %1" +#~ msgstr "Име: %1" + +#~ msgid "Size: %1" +#~ msgstr "Големина: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Разглеждане" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Увеличение" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Увеличение" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Избиране" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Из&биране на текст" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Избиране на &таблица" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Край на документа" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Без" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Документът трябва да бъде отворен в режим \"презентация\".\n" +#~ "Позволявате ли?" + +#~ msgid "Presentation Mode" +#~ msgstr "Презентация" + +#~ msgid "Allow" +#~ msgstr "Позволявам" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Позволение за режим \"презентация\"" + +#~ msgid "Do Not Allow" +#~ msgstr "Не" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Не позволявам режим \"Презентация\"" + +#~ msgid "Save &Copy As..." +#~ msgstr "Запис на &копие..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Достигнат е края на документа.\n" +#~ "Искате ли да продължите от началото?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Достигнато е началото на документа.\n" +#~ "Искате ли да продължите от края?" + +#~ msgid "Current maintainer" +#~ msgstr "Текуща поддръжка" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " сек" + +#~ msgid "Pencil color:" +#~ msgstr "Цвят на молива:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "хоризонтално DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "вертикално DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "хоризонтално DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "вертикално DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "хоризонтално DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "вертикално DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "хоризонтално DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "вертикално DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "хоризонтално DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "вертикално DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "хоризонтално DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "вертикално DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "хоризонтално DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "вертикално DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "хоризонтално DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "вертикално DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "хоризонтално DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "вертикално DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "хоризонтално DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "вертикално DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "хоризонтално DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "вертикално DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "хоризонтално DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "вертикално DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "хоризонтално DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "вертикално DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "хоризонтално DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "вертикално DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "хоризонтално DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "вертикално DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "хоризонтално DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "вертикално DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "хоризонтално DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "вертикално DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "хоризонтално DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "вертикално DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "хоризонтално DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "вертикално DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "хоризонтално DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "вертикално DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "хоризонтално DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "вертикално DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "хоризонтално Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "вертикално Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "хоризонтално DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "вертикално DLE" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "непознат размер хартия, хоризонтално" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "непознат размер хартия, вертикално" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Чертане" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Грешка при стартиране на услугата Jovie Text-to-Speech: %1" + +#~ msgid "Search Columns" +#~ msgstr "Търсене в колоните" + +#~ msgid "All Visible Columns" +#~ msgstr "Всички видими колони" + +#~ msgid "No document opened." +#~ msgstr "Не е отворен документ." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Не са намерени съвпадения за \"%1\"." + +#~ msgid "Search in progress..." +#~ msgstr "Търсене..." + +#~ msgid "Searching for %1" +#~ msgstr "Търсене на %1" + +#~ msgid "Identity Settings" +#~ msgstr "Настройки на самоличността" + +#~ msgid "Highlight Properties" +#~ msgstr "Информация за подсветяване" + +#~ msgid "Ink Properties" +#~ msgstr "Информация за мастило" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Анотация на текст" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Зелено мастило" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Подсветяване в жълто" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Подсветяване в жълто" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Права жълта линия" + +#~ msgid "Black Underlining" +#~ msgstr "Подчертаване с черно" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Подчертаване на текста с черна линия" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Елипса циан" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Елипса циан" + +#~ msgid "Ink" +#~ msgstr "Мастило" + +#~ msgid "Enable &background generation" +#~ msgstr "Генериране на &фон" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Скриване на формуляри" diff --git a/po/bg/okular_chm.po b/po/bg/okular_chm.po new file mode 100644 index 0000000..f4766e6 --- /dev/null +++ b/po/bg/okular_chm.po @@ -0,0 +1,60 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2009-09-05 20:52+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zlatkopopov@fsa-bg.org" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "Ядро CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Показване на помощни файлове за Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/bg/okular_comicbook.po b/po/bg/okular_comicbook.po new file mode 100644 index 0000000..49fa689 --- /dev/null +++ b/po/bg/okular_comicbook.po @@ -0,0 +1,59 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2009-09-05 21:00+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Грешка при отваряне на документа. Не е открит unrar." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Версията на unrar на системата ви не е подходяща за отваряне на документи с " +"комикси." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Непознат формат на комикс." + +#~ msgid "ComicBook Backend" +#~ msgstr "Ядро ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Показване на различни формати комикси" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bg/okular_djvu.po b/po/bg/okular_djvu.po new file mode 100644 index 0000000..58e3c68 --- /dev/null +++ b/po/bg/okular_djvu.po @@ -0,0 +1,136 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2009-09-05 21:02+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Красимир Арнаудов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "krasi.arnaudov@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Редактор" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Издател" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Том" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Вид на документа" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Неизвестен" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Компонентни файлове" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Неизвестен" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Една страница" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Няколко страници" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Индиректен" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Няколко страници (стар)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Индексиран (стар)" + +#~ msgid "DjVu Backend" +#~ msgstr "Ядро DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Ядро за DjVu на основата на DjVuLibre" + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Неизвестно" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Неизвестен" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Неизвестен" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Неизвестен" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Неизвестно" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Неизвестно" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Неизвестен" diff --git a/po/bg/okular_dvi.po b/po/bg/okular_dvi.po new file mode 100644 index 0000000..627d5b8 --- /dev/null +++ b/po/bg/okular_dvi.po @@ -0,0 +1,801 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2009-09-05 21:23+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров,Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com,zlatkopopov@fsa-bg.org" + +#: dviexport.cpp:117 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvipdfm' on your computer. This " +#| "program is essential for the export function to work. You can, however, " +#| "convert the DVI-file to PDF using the print function of Okular, but that " +#| "will often produce documents which print okay, but are of inferior " +#| "quality if viewed in Acrobat Reader. It may be wise to upgrade to a more " +#| "recent version of your TeX distribution which includes the 'dvipdfm' " +#| "program.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"Okular не може да открие програмата \"dvipdfm\" на компютъра ви. Тази " +"програма е от първостепенно значение за функцията \"експортиране\". Но вие " +"можете да конвертирате DVI-файла в PDF с функцията \"Отпечатване\" на " +"Okular, това често изработва документ отпечатващ се безпроблемно, но с по-" +"лошо качество при разглеждане с Acrobat Reader. Може би е по-добре да " +"инсталирате по-нова версия на TeX дистрибуцията включваща програмата " +"\"dvipdfm\".\n" +"Подсказка за объркания системен администратор: Okular използва променлива от " +"обкръжението PATH при търсене на програма." + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Външната програма \"dvipdfm\", използвана за експортиране на файла, " +"върна грешка. За по-подробно описание на грешката можете да погледнете " +"диалоговия прозорец с информация на документа, който се " +"намира в менюто \"Файл\"." + +#: dviexport.cpp:158 +#, fuzzy, kde-format +#| msgid "" +#| "

This DVI file refers to external graphic files which are not in " +#| "PostScript format, and cannot be handled by the dvips " +#| "program that Okular uses interally to print or to export to PostScript. " +#| "The functionality that you require is therefore unavailable in this " +#| "version of Okular.

As a workaround, you can use the File/" +#| "Export As-Menu to save this file in PDF format, and then use a " +#| "PDF viewer.

It is planned to add this functionality at a later date." +#| "

" +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"

DVI файлът отпраща към външни графични файлове които не са в " +"PostScript формат и не могат да бъдат обработени с програматаdvips която Okular използва за отпечатване или експортиране в PostScript. " +"Исканата от вас функционалност не е налична в тази версия на Okular.

Временно решение: можете да използвате менюто Файл/Експортиране " +"като за да запазите файла в PDF формат и да използвате програма за " +"разглеждане на PDF.

Предвидено е да се добави към програмата тази " +"липсваща функционалност.

" + +#: dviexport.cpp:166 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvips' on your computer. That " +#| "program is essential for the export function to work.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"Okular не може да открие програмата \"dvips\" на компютъра ви. Тази програма " +"е от първостепенно значение за функцията \"експортиране\".\n" +"Подсказка за объркания системен администратор: Okular използва променлива от " +"обкръжението PATH при търсене на програма." + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Външната програма 'dvips', използвана за експортиране на файла, върна " +"грешка. Можете да погледнете диалоговия прозорец информация " +"на документа, който се намира в менюто Файл за по-подробно описание на " +"грешката." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI файлът не започва с преамбюл." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI файлът съдържа грешната версия за DVI резултата за тази програма. " +"Подсказка: ако използвате система за въвеждане Omega, трябва да използвате " +"специална програма като oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "DVI файлът е повреден. Okular не намери постамбюл." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Постамбюлът не започва с командата POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Постамбюлът съдържа команда различна от FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Страницата %1 не започва с BOP команда." + +#: dviFile.cpp:380 +#, fuzzy, kde-format +#| msgid "" +#| "

The external program pdf2ps could not be started. " +#| "As a result, the PDF-file %1 could not be converted to PostScript. Some " +#| "graphic elements in your document will therefore not be displayed.

Possible reason: The program pdf2ps may not " +#| "be installed on your system, or cannot be found in the current search " +#| "path.

What you can do: The program pdf2ps " +#| "is normally contained in distributions of the ghostscript PostScript " +#| "interpreter system. If ghostscipt is not installed on your system, you " +#| "could install it now. If you are sure that ghostscript is installed, try " +#| "to use pdf2ps from the command line to check if it " +#| "really works.

PATH: %2

" +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Външната програма pdf2ps не може да бъде стартирана. " +"В резултат, PDF-файлът %1 не може да бъде конвертиран в PostScript. Някои " +"графични елементи в документа няма да бъдат показани.

Възможна " +"причина: Програмата pdf2ps не е инсталирана, или не е " +"открита в текущия път.

Какво можете да направите: Програмата " +"pdf2ps обикновени се съдържа в дистрибуции на ghostscript " +"PostScript интерпретатора. Ако ghostscipt не е инсталиран, можете да го " +"инсталирате сега. Ако сте сигурни че ghostscript е инсталиран, моля опитайте " +"да използвате pdf2ps от командния ред за да проверите дали " +"наистина функционира.

ПЪТ: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

PDF-файлът %1 не може да бъде конвертиран в PostScript. Някои " +"графични елементи в документа няма да бъдат показани.

Възможна " +"причина: Файлът %1 може да е повреден или може да не е PDF-файл. Това е " +"изхода от програмата pdf2ps която Okular използва:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, fuzzy, kde-format +#| msgid "" +#| "File not found: \n" +#| " %1" +msgid "File corruption. %1" +msgstr "" +"Файлът не е открит: \n" +" %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, fuzzy, kde-format +#| msgid "The special command '%1' is not implemented." +msgid "The specified file '%1' does not exist." +msgstr "Специалната команда '%1' не е имплементирана." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI кодът зададе знак от непознат шрифт." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI кодът отпраща към шрифт #%1, който предварително не е дефиниран." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Стекът не бе празен когато се получи команда ЕОР." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Стекът не бе празен когато се получи команда РОР." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI кодът отпраща към шрифт, който предварително не е дефиниран." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Получена е неправилна команда." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Възникна непозната грешка op-code %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Вграждане на %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Страница %1: PDF файлът %2 не може да бъде конвертиран в " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Страница %1: PostScript файлът %2 не е открит.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Данните за размера '%1' не могат да бъдат обработени." + +#: fontpool.cpp:203 +#, fuzzy, kde-format +#| msgid "" +#| "

Okular was not able to locate all the font files which are " +#| "necessary to display the current DVI file. Your document might be " +#| "unreadable.

" +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular не откри всички файлове с шрифтовете, необходими за " +"изобразяване на DVI файла. Документа ви може да не се чете.

" + +#: fontpool.cpp:270 +#, fuzzy, kde-format +#| msgid "" +#| "

There were problems running kpsewhich. As a result, some font " +#| "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#| "installed on your system, or it cannot be found in the current search " +#| "path.

What you can do: The kpsewhich program is normally " +#| "contained in distributions of the TeX typesetting system. If TeX is not " +#| "installed on your system, you could install the TeX Live distribution " +#| "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#| "to use the kpsewhich program from the command line to check if it really " +#| "works.

" +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Възникнаха проблеми при изпълнение на kpsewhich. В резултат, някои " +"файлове с шрифтове не могат да бъдат намерени, и е възможно документа да не " +"се чете.

Възможна причина: Програмата kpsewhich не е " +"инсталирана, или не е открита в текущия път.

Какво можете да " +"направите: Програмата kpsewhich обикновено се съдържа в дистрибуции на " +"TeX typesetting системата. Ако TeX не е инсталиран, можете да инсталирате " +"TeX Live (www.tug.org/texlive). Ако сте сигурни че TeX е инсталиран, моля " +"опитайте да използвате kpsewhich от командния ред за да проверите дали " +"функционира.

" + +#: fontpool.cpp:291 +#, fuzzy, kde-format +#| msgid "" +#| "

The font generation by kpsewhich was aborted (exit code %1, " +#| "error %2). As a result, some font files could not be located, and your " +#| "document might be unreadable.

" +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"

Генерирането на шрифтове с kpsewhich беше преъснато (изходен " +"код %1, грешка %2). В резултат, някои файлове с шрифтове не са намерени и е " +"възможно документът да не може да се прочете.

" + +#: fontpool.cpp:462 +#, fuzzy, kde-format +#| msgid "Currently generating %1 at %2 dpi" +msgid "Currently generating %1 at %2 dpi..." +msgstr "Текущо генериране на %1 с %2 dpi" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Генератор/Дата" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Файлът с шрифтовете не е открит" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "портрет" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "пейзаж" + +#: psgs.cpp:265 +#, fuzzy, kde-format +#| msgid "" +#| "The version of Ghostview that is installed on this computer does not " +#| "contain any of the Ghostview device drivers that are known to Okular. " +#| "PostScript support has therefore been turned off in Okular." +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Версията на Ghostview инсталирана на компютъра не съдържа какъвто и да е " +"Ghostview драйвер познат за Okular. Затова PostScript поддръжката в Okular " +"бе изключена." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Програмата Ghostview, която Okular използва за изобразяване на " +"PostScript графики, включени в този DVI файл, обикновено може да запише " +"резултата в различни формати. Подпрограмите които Ghostview използва за тези " +"задачи се наричат 'драйвери'; има един драйвер за всеки формат в който " +"Ghostview може да записва. Различни версии на Ghostview често имат различен " +"набор налични драйвери. Изглежда версията на Ghostview инсталирана на този " +"компютър не съдържа какъвто и да е драйвер познат за Okular." +"

Малко вероятно е стандартна инсталация на Ghostview да не съдържа " +"тези драйвери. Вероятно тази грешка насочва към сериозна проблем с " +"конфигурацията на Ghostview.

Ако искате да отстраните проблемите с " +"Ghostview, можете да използвате команадата gs --help за да " +"видите драйверите съдържащи се в Ghostview. Измежду всички, Okular може да " +"използва 'png256', 'jpeg' и 'pnm' драйвери. Имайте предвид, че Okular трябва " +"да бъде рестартиран, за да бъде достъпна поддръжката на PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"Това са 25 грешки. Последващи съобщения за грешка няма да бъдат показани." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Грешка в DVI файла '%1', страница %2. Color pop команадта е използвана " +"когато стека с цветове е празен." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Грешен параметър в epsf командата.\n" +"Очаква се число с плаваща запетая да следва %1 в %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Файлът не е открит: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Грешка в DVI файла '%1', страница %2. Грешка при интерпретиране ъгъла при " +"въртене на текст." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Специалната команда '%1' не е имплементирана." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "Файла с шрифтове %1 може да бъде отворен, но формата не се поддържа." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Файлът с шрифтове %1 е повреден, или не може да бъде отворен или прочетен." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType докладва грешка при задаване размера на знак за файл с шрифтове %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType не може да зареди glyph #%1 от файл с шрифтове %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType не може да представи glyph #%1 от файл с шрифтове %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glyph #%1 е празен." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glyph #%1 от файл с шрифтове %2 е празен." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType не може да зареди метрика за glyph #%1 от файл с шрифтове %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Грешка при отваряне на файл с шрифтове %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Знак %1 не е дефиниран в шрифт %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Неочакван %1 в PK файл %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Знакът %1 е прекалено голям във файла %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Грешен брой записани битове: знак. %1, шрифт %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Грешен pk файл (%1), твърде много битове" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Шрифтът има неквадратно съотношение на размера " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Не е открит шрифт %1, файл %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Грешна контролна сума за файл с шрифтове %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Не е разпознат форматът за файл с шрифтове %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Критична грешка.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Това вероятно означава, че или сте открили програмна грешка в Okular,\n" +"или DVI файлът, или помощните файлове (като файловете с шрифтове, \n" +"или виртуалните файловете с шрифтове) са наистина повредени.\n" +"Okular ще прекъсне след това съобщение. Ако смятате, че сте открили\n" +"програмна грешка, или че Okular би трябвало да се справи по-добре в тази " +"ситуация, \n" +"моля докладвайте проблема." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Грешен команден байт открит в VF макро списък: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Ядро DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Показване на файлове DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular разчита на kpsewhich програмата за да намери файловете с " +#~ "шрифтове на твърдия диск и да генерира PK шрифтове, ако е необходимо.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "В момента Okular генерира растерни шрифтове..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Прекъсва генерирането на шрифтове. Не правете това." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "В момента Okular генерира растерни шрифтове необходими за изобразяване на " +#~ "документа. За това се използват набор от външни програми като MetaFont. " +#~ "Можете да откриете резултата от тези програми по-късно в диалоговия " +#~ "прозорец." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular генерира шрифтовете. Моля изчакайте." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Прозорец за генериране на шрифт" + +#~ msgid "Abort" +#~ msgstr "Прекъсване" + +#~ msgid "What is happening here?" +#~ msgstr "Какво става тук?" + +#~ msgid "%v of %m" +#~ msgstr "%v от %m" + +#~ msgid "Please be patient" +#~ msgstr "Моля бъдете търпеливи" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Изнасяне на файла като" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Файлът %1 вече съществува.\n" +#~ "Искате ли да бъде презаписан?" + +#~ msgid "Overwrite File" +#~ msgstr "Презапис на файла" + +#~ msgid "Overwrite" +#~ msgstr "Презапис" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Използване на dvipdfm за експортиране на файла в PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "В момента Okular използва външната програма \"dvipdfm\", за да конверитра " +#~ "DVI-файла в PDF. Понякога това може да отнеме известно време защото " +#~ "dvipdfm трябва да генерира собствени растерни шрифтове. Моля, имайте " +#~ "търпение." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Изчакване dvipdfm да завърши..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Използване на dvips за експортиране на файла в PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular използва в момента външната програма 'dvips' за да конвертира DVI-" +#~ "файла в PostScript. Понякога това може да отнеме известно време защото " +#~ "dvips трябва да генерира собствени растерни шрифтове моля имайте търпение." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Изчакване на dvips да завърши..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Фукционалноста не е достъпна" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Повреден файл Okular не може да интерпретира DVI " +#~ "файла ви. Това обикновено е причинено от повреден файл." + +#~ msgid "DVI File Error" +#~ msgstr "DVI файлова грешка" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Не са открити всички файлове с шрифтовете" + +#~ msgid "Locating fonts..." +#~ msgstr "Намиране на шрифтове..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Проблем при намирането на шрифтове" + +#~ msgid "Font generation aborted" +#~ msgstr "Генерирането на шрифтове е прекъснато" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Изнасяне на %1 в PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Изнасяне на %1 в PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Списъкът с шрифтове е празен." + +#~ msgid "TeX Name" +#~ msgstr "TeX име" + +#~ msgid "Family" +#~ msgstr "Семейство шрифтове" + +#~ msgid "Zoom" +#~ msgstr "Мащабиране" + +#~ msgid "Type" +#~ msgstr "Вид" + +#~ msgid "Encoding" +#~ msgstr "Кодова таблица" + +#~ msgid "Comment" +#~ msgstr "Коментар" + +#~ msgid "TeX virtual" +#~ msgstr "TeX виртуален" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX метрика на шрифт" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/bg/okular_epub.po b/po/bg/okular_epub.po new file mode 100644 index 0000000..ec8c670 --- /dev/null +++ b/po/bg/okular_epub.po @@ -0,0 +1,55 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-23 10:01+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Грешка при отваряне на документа на EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Настройки на ядро EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Ядро EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Ядро за EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/bg/okular_fax.po b/po/bg/okular_fax.po new file mode 100644 index 0000000..c9584a9 --- /dev/null +++ b/po/bg/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-09-05 20:54+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Грешка при зареждане на документа" + +#~ msgid "Fax Backend" +#~ msgstr "Ядро за факсове" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Показване на факсове G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bg/okular_fictionbook.po b/po/bg/okular_fictionbook.po new file mode 100644 index 0000000..23ad181 --- /dev/null +++ b/po/bg/okular_fictionbook.po @@ -0,0 +1,81 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-23 09:56+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров,Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com,zlatkopopov@fsa-bg.org" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Документът не е валиден FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Грешка при отваряне на документ: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Документът не е валиден ZIP архив" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Невалидна структура на документа (липсва главната директория)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Не е открито съдържание в документа" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Невалиден XML документ: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Настройки на ядро FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Ядро FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Показване на книги FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bg/okular_ghostview.po b/po/bg/okular_ghostview.po new file mode 100644 index 0000000..23cbaf8 --- /dev/null +++ b/po/bg/okular_ghostview.po @@ -0,0 +1,92 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-09-05 20:42+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров,Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com,zlatkopopov@fsa-bg.org" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Използване шрифтовете на ОС" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Определя дали Ghostscript да използва шрифтовете на операционната система " +"или да се ограничи до вградените в документа шрифтове." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Общи настройки" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Използване шрифтовете на ОС" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Настройване ядрото на Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Версия на документа" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Ниво на езика" + +#~ msgid "PS Backend" +#~ msgstr "Ядро PostScript" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Показване на файлове на PostScript" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "На основата на библиотеката Spectre" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/bg/okular_kimgio.po b/po/bg/okular_kimgio.po new file mode 100644 index 0000000..6148021 --- /dev/null +++ b/po/bg/okular_kimgio.po @@ -0,0 +1,68 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009, 2010. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2010-01-31 19:45+0200\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Грешка при зареждане на документа: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Ядро за изображения" + +#~ msgid "A simple image backend" +#~ msgstr "Просто ядро за поддръжка на изображения" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Главна лента с инструменти" diff --git a/po/bg/okular_mobi.po b/po/bg/okular_mobi.po new file mode 100644 index 0000000..5003125 --- /dev/null +++ b/po/bg/okular_mobi.po @@ -0,0 +1,63 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-23 09:59+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Грешка при отваряне на документа на Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Тази книга е защитена с технология DRM и може да се показва само на " +"предназначено за целта устройство." + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Настройки на ядро Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Ядро Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Ядро за Mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/bg/okular_plucker.po b/po/bg/okular_plucker.po new file mode 100644 index 0000000..771d319 --- /dev/null +++ b/po/bg/okular_plucker.po @@ -0,0 +1,46 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-09-05 18:25+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Име" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Ядро за документи Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Показване на електронни книги Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bg/okular_poppler.po b/po/bg/okular_poppler.po new file mode 100644 index 0000000..54bfb3c --- /dev/null +++ b/po/bg/okular_poppler.po @@ -0,0 +1,223 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009, 2010, 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-07-23 10:03+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zlatkopopov@fsa-bg.org" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Засилване на тънките линии:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Не" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Плътно" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Форма" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Настройки на PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Отпечатване на бележките" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Включване на бележките в отпечатвания документ" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Включва на бележките в отпечатвания документ. Ако искате да отпечатате " +"оригиналния документ без бележките, изключете това." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Принудителна растеризация" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Растеризация в изображение преди печат" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Принудителна растеризация на всяка страница в изображение преди " +"отпечатването и. Това обикновено дава по-лоши резултати, но е полезно при " +"отпечатване на документи, които излизат неправилно." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Формат" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Шифрован" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Нешифрован" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Сигурност" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Да" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Оптимизиран" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Настройки на ядро PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "Ядро PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Показване на PDF-файлове" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Запазване на файлове с шифриране не се поддържа." + +#~ msgid "Unknown" +#~ msgstr "Неизвестно" + +#~ msgid "Unknown Date" +#~ msgstr "Неизвестна дата" + +#~ msgid "Unknown Encryption" +#~ msgstr "Неизвестно шифроване" + +#~ msgid "Unknown Optimization" +#~ msgstr "Неизвестна оптимизация" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Въведете парола за отваряне на документа:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Грешна парола. Опитайте отново:" + +#~ msgid "Document Password" +#~ msgstr "Парола на документа" diff --git a/po/bg/okular_txt.po b/po/bg/okular_txt.po new file mode 100644 index 0000000..5db13ca --- /dev/null +++ b/po/bg/okular_txt.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-23 10:25+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Ясен Праматаров" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "yasen@lindeas.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Настройки на ядро Txt" + +#~ msgid "Txt Backend" +#~ msgstr "Текстово ядро" + +#~ msgid "Txt backend." +#~ msgstr "Текстово ядро." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/bg/okular_xps.po b/po/bg/okular_xps.po new file mode 100644 index 0000000..a3b5a16 --- /dev/null +++ b/po/bg/okular_xps.po @@ -0,0 +1,58 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Zlatko Popov , 2007. +# Yasen Pramatarov , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-09-03 18:18+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Златко Попов" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "zlatkopopov@fsa-bg.org" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Ревизия" + +#~ msgid "XPS Backend" +#~ msgstr "Ядро XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Ядро XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/bg/org.kde.active.documentviewer.po b/po/bg/org.kde.active.documentviewer.po new file mode 100644 index 0000000..8cc94aa --- /dev/null +++ b/po/bg/org.kde.active.documentviewer.po @@ -0,0 +1,72 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Yasen Pramatarov , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2013-07-23 10:20+0300\n" +"Last-Translator: Yasen Pramatarov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Отметки" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Миниатюри" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Съдържание" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Отметки" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Не са открити резултати." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Четец на документи за Plasma Active, използващ Okular" + +#~ msgid "Reader" +#~ msgstr "Четец" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL-адрес на файла за отваряне" diff --git a/po/bs/okular.po b/po/bs/okular.po new file mode 100644 index 0000000..5bd567c --- /dev/null +++ b/po/bs/okular.po @@ -0,0 +1,5881 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2015-02-24 22:29+0100\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Dino Kraljušić,Samir Ribić,Vedran Ljubovic,Dino Babahmetovic" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"Dk@etf.ba,samir.ribic@etf.unsa.ba,vljubovic@smartnet.ba,dbabahmeto1@etf.unsa." +"ba" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, univerzalni preglednik dokumenata" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2009 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Bivši održavalac" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Mnogo posla na radnom okviru, pozadine za ODT i FictionBook" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "KPDF razvoj" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Kreirano Okularom iz KPDF baze podataka" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF razvoj" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Grafika za tumačenja" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Alat za izbor tabele" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Poboljšanja zabilješki" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Idi na stranu %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Otvori eksternu datoteku" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Izvrši '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Prva strana" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Prethodna strana" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Sljedeća strana" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Posljednja strana" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Nazad" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Naprijed" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Izlaz" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Počni prezentaciju" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Završi prezentaciju" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Traži..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Idi na stranu..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Sviraj zvuk..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript skripta" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Pokreni film..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Pokreni film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Zaustavu filn" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Pauziraj film" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Nastavi film" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Izbor pozadinskog programa" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Pronađeno je više pozadinskih programa za MIME tip:
%1 (%2)." +"

Molim odaberite koji će se koristiti:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Idi na stranu %1" + +#: core/document.cpp:224 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "portrait C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "uspravni C5E" + +#: core/document.cpp:226 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "landscape C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "položeni C5E" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Ne mogu pronaći dodatak koji može rukovati s dokumentom koji je proslijeđen." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "ukloni zabilješke" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokument pokušava izvršiti eksterni program i, za Vašu sigurnost, Okular to " +"ne dozvoljava." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Nije nađen nijedan program za otvaranje datoteke MIME tipa %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Ne mogu da otvorim privremenu datoteku" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Konverzija štampe nije uspjela" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Prekinut proces štampanja" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Ne mogu pokrenut proces štampanja" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Štampanje u datoteku nije uspjelo" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Štampanje je u nedozvoljenom stanju" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Ne mogu pronaći datoteku za štampanje" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Nema datoteke za štampanje" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Ne mogu da nađem pogodnu naredbu za štampanje. Obezbijedite da lpr iz CUPS‑a bude dostupna." + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Veličina stranice za štampu neispravna" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Ne mogu otvoriti '%1'. Datoteka ne postoji" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Naslov" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Tema" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Opis" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Autor" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Proizvođač" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Autorska prava" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Stranice" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Kreirano" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Izmijenjen" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME tip" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategorija" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Ključne riječi" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Putanja datoteke" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Veličina datoteke" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Veličina stranice" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "dodaj zabilješku" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "ukloni zabilješku" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "izmijeni svojstva zabilješkee" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "prevedi zabilješku" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "dodaj zabilješku" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "uredi tekst." + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "izmijeni sadržaj zabilješke" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "uredi sadržaj formulara" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "uredi listu iz izbora" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "uredi kombo iz izbora" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "uredi stanje dugmadi na formularu" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Čisti &tekst..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument tekst" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Opcije uređivača" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Mod boje:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Izvor: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Podrazumijevani font:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Učitaj &nanovo" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Dozvoli" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Ekran:" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Prilagodi po širini" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Svojstva zabilješke" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Alati zabilješki" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Alati zabilješki" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Alati zabilješki" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Alati zabilješki" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "%1 Zabilješka" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Svojstva zabilješke" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&Boja:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&Boja:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Eksperimentalno" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "&Alat izbora" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "Zabilješke" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlighter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Istaknuto" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Podvučeno" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Iskrivljeno" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Precrtano" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Svojstva kapice" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Ugrađena bilješka" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Iskočna poruku" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Slobodnoručna linija" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Prava linija" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Pravougaonik" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Poligon" + +#: part/annotationactionhandler.cpp:534 +#, fuzzy, kde-format +#| msgid "Geometrical shape" +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometrijski lik" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Pečat" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Zabilješke" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "dodaj zabilješku" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Kreiraj alat zabilješki" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Font:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Svojstva zabilješke" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Prilagodi po širini" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&Neprovidnost:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Stranica %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "%1 Zabilješka" +msgstr[1] "%1 Zabilješke" +msgstr[2] "%1 Zabilješki" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Otvori iskočnu poruku" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Obriši" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Osobine" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Snimi '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Izgled" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Opšte" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Kreirano" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Izmijenjen" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Osobine iskočne porukee" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "Svojstva kapice" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Svojstva ugrađene bilješke" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Osobine prave linije" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Osobine poligona zvuka" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Osobine geometrije" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Osobine tekstualnog markera" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Osobine pečata" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Osobine prostoručne linije" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Svojstva kapice" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Svojstva priložene datoteke" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Osobine zvuka" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Svojstva filma" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Svojstva zabilješke" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Izmjenjeno: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Stavi pečat" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Boja:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Neprovidnost:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Ikona" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Komentar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Pomoć" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Umetni" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Ključ" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Novi paragraf" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Bilješka" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragraf" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Font:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Boja:" + +#: part/annotationwidgets.cpp:389 +#, fuzzy, kde-format +#| msgid "Align:" +msgid "&Align:" +msgstr "Poravnanje:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Lijevo" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centar" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Desno" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Odobreno" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Kao u" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Povjerljivo" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Za odjeljenje" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Nacrt" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Eksperimentalno" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Završni" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Za komentar" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Za javnu objavu" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Nije odobreno" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Nije za javnu objavu" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Prodat" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Strogo povjerljivo" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Obilježivač" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informacija" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Simbol pečata" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "Prilagodi po širini" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Ništa" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Dužina prve linije:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Dužina produžetka vodeće linije:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Spremi u datoteku..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Vrsta:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Istaknuto" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Iskrivljeno" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Podvučeno" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Precrtano" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Pravougaonik" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "Simbol za priloženu datoteku" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafik" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Pribadača" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Spajalica" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Oznaka" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Datoteka" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/D" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Opis nije dostupan." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "&Name:" +msgid "Name:" +msgstr "&Ime:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Opis:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "Simbol kapice" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ništa" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Zatvori ovu bilješku" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcije" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Ova oznaka može sadržati LaTeX kod.\n" +"Kliknite ovdje za iscrtavanje." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Ne mogu naći latex program." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX crtanje neuspjelo" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Ne mogu naći dvipng program." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Problem je nastao tokom izvršenja komande 'latex'." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Problem je nastao tokom izvršenja komande 'dvipng'." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"%2 zabilješka" +msgstr[1] "" +"%1\n" +"\n" +"%2 zabilješke" +msgstr[2] "" +"%1\n" +"\n" +"%2 zabilješki" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Zabilješke" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "&Traži:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Samo trenutni dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Idi na ovu zabilješku" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Promijeni ime zabilješke" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Ukloni obilježivač" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Otvori dokument" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Ukloni zabilješke" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "Broj stranice" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Istekao" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Tema" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Zauzeće memorije" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Osobine" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "Konfiguriši preglednik" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "&Izvezi kao" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Opšte" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Gdje želite spremiti %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Učitaj &nanovo" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "Ekran:" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Dozvoli" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Crtaj liniju oko &Slika" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Crtaj liniju oko &linkova" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Promijeni &boje" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Upozorenje: ove opcije mogu imati loš uticaj na brzinu crtanja." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mod boje:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Izvrni boje" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Promijeni boju papira" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Promijeni tamne i svijetle boje" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Pretvori u crno-bijelo" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Boja papira:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Tamna boja:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Svijetla boja:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Prag:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitet" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&Autor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Napomena: ove informacije se koriste samo za komentare i prelede. " +"Informacije koje se ovdje nalaze neće se slati bez Vašeg znanja." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "Uredi alat zabilješki" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Vlastiti uređivač teksta" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs klijent" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx klijent" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Podesi komandu posebnog uređivača teksta.
\n" +"Takođe možete da stavite i nekoliko argumenata:\n" +"
    \n" +"
  • %f - ime datoteke
  • \n" +"
  • %l - red datoteke do kog treba doći
  • \n" +"
  • %c - kolona datoteke do koje treba doći
  • \n" +"
\n" +"Ako %f nije navedeno, ime datoteke će biti nadovezano na navedenu naredbu.." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Uređivač" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Uređivač:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Izaberite koji će se uređivač teksta pokrenuti kada Okular želi otvoriti " +"izvornu datoteku." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Naredba:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Izgled" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Prikaži &klizačke trake" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Poveži &sličice sa stranom" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Prikaži &savjete i info poruke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Prikaži naslov dokumenta u naslovu programa ako je moguće" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Kada ne prikazati naslov dokumenta:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Prikaži samo ime datoteke" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Prikaži punu stazu datoteke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Boja pozadine:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Osobine programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Otvoriti nove datoteke u &karticama" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Poštivanje DRM ograničenja" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Nanovo učitaj dokument na promjenu datoteke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Prikaži dijalog za izbor pozadine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Pregled opcija" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Osnovne &kolone:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Definiše koliko će trenutnog područja gledanja još biti vidljivo prilikom " +"pritika na Page Up/Down tastere." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Page Up/Down preklapanje:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Definiše podrazumijevani režim uvećanja za datoteke koje nisu prije bile " +"otvarane. \n" +"Za datoteke koje su ranije otvorene, primjenjuje se prethodno uvećanje." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Definiše podrazumijevani režim uvećanja za datoteke koje nisu prije bile " +"otvarane. \n" +"Za datoteke koje su ranije otvorene, primjenjuje se prethodno uvećanje." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Podrazumijevano uvećanje:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Prilagodi po širini" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Prilagodi po stranici" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automatsko uklapanje" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Koristi memoriju što je manje moguće. Ne koristite ništa ponovo. (Za sisteme " +"sa malo memorije.)" + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Dobar odnos između korištenja memorije i doprinosa brzini. Učitava sljedeću " +"stranicu i ubrzava pretragu. (Za sisteme sa 256MB memorije, tipično.)" + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Drži sve u memoriji. Učitava sljedeće stranice. Ubrzava Pretragu. (Za " +"sisteme sa više od 512MB memorije.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Učitava i čuva sve u memoriji. Prethodno učita sve stranice. (Koristiće " +"maksimum 50% ukupne memorijke ili vašu slobodnu memoriju, što je veće od " +"toga dvoje)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Korištenje CPU-a" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Omogući efekte providnosti" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Zauzeće memorije" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Malo" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&Normalno (podrazumjevano)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "&Agresivno" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, fuzzy, kde-format +#| msgid "&Greedy" +msgid "G&reedy" +msgstr "&Pohlepno" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Iscrtavanje" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Omogući tekstualno umekšavanje" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Omogući grafičko umekšavanje" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Omogući prelaze teksta" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Trenutni ekran" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Podrazumjevani ekran" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekran %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekunda" +msgstr[1] " sekunde" +msgstr[2] " sekundi" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigacija" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Napreduj svako:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Kruži posle zadnje strane" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Navigacija" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Boja pozadine:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Kursor miša:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Sakrij poslije" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Uvijek vidljivo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Uvijek skriveno" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Prikaži &indikator napretka" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Prikaži stranicu &sažetka" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Omogući prelaze" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Podrazumijevani prelaz:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Zakloni uspravni" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Zakloni vodoravni" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "U kutiju" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Iz kutije" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Rastvaranje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Svjetlucanje dolje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Svjetlucanje desno" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Svjetlucanje desno-dolje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Slučajni prelaz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Zamijeni" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Podjela vodoravna uklj." + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Podjela vodoravna isklj." + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Podjela uspravna uklj." + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Podjela uspravna isklj." + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Brisanje nadolje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Brisanje nadesno" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Brisanje nalijevo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Brisanje nagore" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Smještaj" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Ekran:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "Izbriši crteže" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Ime:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Vrsta:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Iskočna poruku" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Ugrađena bilješka" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Slobodnoručna linija" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Prava linija" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Poligon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Tekstualna zabilješka" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrijski lik" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Pečat" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Kreiraj alat zabilješki" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Uredi alat zabilješki" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&Boja:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "Prilagodi po širini" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgid "Create drawing tool" +msgstr "Kreiraj alat zabilješki" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Edit drawing tool" +msgstr "Uredi alat zabilješki" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Nepoznato" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Ugrađene datoteke" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&Pogled" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Ime" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Opis" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Veličina" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Napravljeno" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Izmijenjen" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Spremi kao..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Pogled" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Ne mogu da učitam dio za pregled pred štampanje" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Pregled prije štampe" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Zatvori" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Nađi:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Tekst za pretragu" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Sljedeći" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Skoči na sljedeće poklapanje" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Prethodni" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Skoči na prethodno poklapanje" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Podesi ponašanje pretrage" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Razlikuje velika i mala slova" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Sa trenutne stranice" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Sve datoteke" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "Svojstva kapice" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Straight Line Properties" +msgid "Straight Line with Comment" +msgstr "Osobine prave linije" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "Za komentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometrija" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Highlight text" +msgid "Highlight with Comment" +msgstr "Istaknuti tekst" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Squiggle text" +msgid "Squiggle with Comment" +msgstr "Iskrivljen tekst" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Underline text" +msgid "Underline with Comment" +msgstr "Podvučeni tekst" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Strike out text" +msgid "Strike Out with Comment" +msgstr "Precrtani tekst" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Precrtano" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Freehand Line Properties" +msgid "Freehand Line with Comment" +msgstr "Osobine prostoručne linije" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Caret" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Priložena datoteka" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Zvuk" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Ekran:" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Grafička kontrola" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Nepoznat" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Gdje želite spremiti %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Ne mogu otvoriti \"%1\" za pisanje. Datoteka nije spremljena." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opcije pretrage" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Razlikovanje malih i velikih slova" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regularni Izraz" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Traži:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "od" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Uvećaj" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rotiraj &desno" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Desno" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotiraj &lijevo" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Lijevo" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Originalna orjentacija" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&Pogled" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Skrati margine" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Označeni tekst" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Uklopi &Širinu" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Uklopi &Stranicu" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automatsko uklapanje" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "Uklopi &Stranicu" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Način prikaza" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Jedna strana" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Naspramne stranice" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Naspramne stranice (prva centrirana)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Pregled" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Neprekidno" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Razgledaj..." + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Uvećaj" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Preklopi promijene &boje" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Označeni tekst" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Označeni tekst" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "Izbor tabele" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Povećalo" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Alati označavanja" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Govori cijeli dokument" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Govori trenutnu stranicu" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Prekini izgovaranje" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Kliži prema gore" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Kliži prema dolje" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Kliži stranicu gore" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Kliži stranicu dolje" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Prikaži forme" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Učitan dokument od %1 stranice." +msgstr[1] " Učitan dokument od %1 stranice." +msgstr[2] " Učitan dokument od %1 stranica." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Tekst (%1 karakter)" +msgstr[1] "Tekst (%1 karaktera)" +msgstr[2] "Tekst (%1 karaktera)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopiraj u Clipboard" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopiraj i zabranjeno po DRM-u" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Izgovaranje teksta" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Slika (%1 x %2 piksela)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Spremi u datoteku..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Slika [%1x%2] kopirana u clipboard." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Spremi u datoteku..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Datoteka nije spremljena." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Slika [%1x%2] spremljena u datoteku %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopiraj tekst" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Idi na %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Traži „%1“ pomoću" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Podesi veb prečice..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Prati ovaj link" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Sviraj ovaj zvuk" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Zaustavi zvuk" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopiraj adresu linka" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Traži „%1“ pomoću" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Dobrodošli" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Izaberite područje za uvećanje. Desni klik za umanjenje." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Kliknuti da bi vidjeli uvećani prikaz." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Nacrtaj pravougaonik oko teksta/grafike za kopiranje." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Označite tekst." + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Nacrtajte pravougaonik oko tabele, kliknite blizu ivica da podijelite, " +"pritisnite Esc za brisanje." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Nacrtaj pravougaonik oko teksta/grafike za kopiranje." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nova tekstualna bilješka" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Tekst nove bilješke:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "dodaj zabilješku" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Ugrađena zabilješka teksta (vucite da izaberete zonu)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Istaknuti tekst" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Crtaj prostoručnu liniju" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Ugrađena zabilješka teksta (vucite da izaberete zonu)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Postavi iskočnu poruku" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Crtaj poligon (klikni na prvu tačku da se zatvori)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Crtaj pravougaonik" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Iskrivljen tekst" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Stavi pečat" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Crtaj pravu liniju" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Precrtani tekst" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Podvučeni tekst" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Ugrađena zabilješka teksta (vucite da izaberete zonu)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Istaknuto" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "dodaj zabilješku" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Custom annotation name:" +msgstr "dodaj zabilješku" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Datoteka" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Postavke" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Pomoć" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orijentacija" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Zabilješke" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Alatna traka preglednika" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Sličice" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Zabilješke" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Ovaj dokument sadrži ugniježdene datoteke. Kliknite ovdje da ih vidite ili idite do Datoteka->Ugniježđene " +"datoteke." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Prethodna" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Idi na prethodnu stranicu" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Prelazi na prethodnu stranicu dokumenta" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Sljedeća" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Pređi na sljedeću stranicu" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Prelazi na sljedeću stranicu dokumenta" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Početak dokumenta" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Pomijera na početak dokumenta" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Kraj dokumenta" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Pomijera na kraj dokumenta" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Preimenuj trenutnu zabilješku" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Prethodna zabilješka" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Idi na prethodnu zabilješku" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Sljedeća zabilješka" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Idi na narednu zabilješku" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Podešavanje Okulara..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Podešavanje preglednika..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Konfiguriši pozadinsku podršku pregledača..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Podesi pozadine.." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "O pozadini" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Učitaj &nanovo" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Ponovo učitaj trenutni dokument sa diska." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Zatvori traku za &pretragu" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Broj stranice" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Govori trenutnu stranicu" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Prikaži &traku stranica" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Prikaži &traku stranica" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Prikaži &Navigacijski Panel" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Ugrađene datoteke" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&Izvezi kao" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&rezentacija" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Uvezi PostScript kao PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Skini knjige s interneta..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Promijeni mod crnog ekrana" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Izbriši crteže" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Podesi zabilješke.." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reprodukuj/Pauziraj Prezentaciju" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Ne mogu otvoriti %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Učitavanje %1 je otkazano." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Ne mogu otvoriti %1. Razlog: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Konfiguriši pozadinsku podršku pregledača" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Podešavanje pozadina" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Nije pronađen program \"ps2pdf\", stoga Okular ne može importovati PS " +"datoteke koje ga koriste." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "nije pronađen ps2pdf" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Unosim PS datoteku kao PDF (ovo može potrajati)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Molim unesite lozinku da biste pročitali dokument:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Pogrešna lozinka. Pokušajte ponovo:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Lozinka dokumenta" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "Ovaj dokument ima XFA forme koje su trenutno nepodržane." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Ovaj dokument sadrži formulare. Kliknite na dugme da interagujete sa njima " +"ili koristite Pogled->Prikaži formulare." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Nije dozvoljeno štapanje ovog dokumenta." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Nije dozvoljeno štapanje ovog dokumenta." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Izađi iz prezentacijskog načina" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Ne mogu otvoriti %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&Neprekidno" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&Neprekidno" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +#| msgid "Do you want to save your annotation changes or discard them?" +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Želite li snimiti promjene zabilješki ili ih odbaciti?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Zatvori dokument" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Ovaj link pokazuje na radnju zatvaranja dokumenta koja ne radi kada se " +"koristi ugrađeni preglednik." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Ovaj link pokazuje na radnju izlaska iz programa koja ne radi kada se " +"koristi ugrađeni preglednik." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Ponovo učitavam dokumenat..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Sadržaj" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Idi na stranicu" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Stranica:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Unesi novo ime zabilješke:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Preimenuj zabilješki" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename this Bookmark" +msgid "Remove this Bookmark" +msgstr "Preimenuj zabilješki" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "&Spremi kao..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Ne mogu otovriti privremenu datoteku za spremanje." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Datoteka se ne može spremiti u '%1'. Pokušajte drugu lokaciju." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgctxt "Edit an form's text contents" +#| msgid "edit form contents" +msgid "Filled form contents" +msgstr "uredi sadržaj formulara" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgctxt "remove a collection of annotations from the page" +#| msgid "remove annotations" +msgid "User annotations" +msgstr "ukloni zabilješke" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&Neprekidno" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Datoteka nije spremljena u '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular ne može kopirati %1 na datu lokaciju.\n" +"Dokument više ne postoji." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "Datoteka se ne može spremiti u '%1'. Pokušajte drugu lokaciju." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Završi prezentaciju" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Dodaj zabilješku" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Alati" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Nije dozvoljeno štapanje ovog dokumenta." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Dokument se ne može štampati. Nepoznata greška. Molim prijavite na bugs.kde." +"org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Dokument se ne može štampati. Detaljna greška je \"%1\". Molimo prijavite " +"greške na bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Ide na mjesto na kojem ste bili prije." + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Ide na mjesto na kojem ste bili poslije." + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Greška s datotekom! Ne može se otvoriti privremena " +"datoteka %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Greška sa datotekom! Ne može se otvoriti datoteka " +"%1 za dekompresiju. Datoteka neće biti učitana." +"" + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Do ove greške obično dolazi ako nemate dovoljno dozvola za čitanje " +"datoteke. Vlasništvo i dozvole možete da provjerite ako kliknete desnom " +"tipkom miša na datoteku u menadžeru datoteka Delfin i izaberete karticu " +"Svojstva." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Greška sa datotekom! Ne može se dekompresovati datoteka " +"%1. Datoteka neće biti učitana." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Do ove greške obično dolazi kada je datoteka pokvarena. Ako želite da se " +"uvjerite, pokušajte da dekompresujete datoteku koristeći alate komandne " +"linije." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Nema zabilješki" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Izmijeni" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Pogled" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Kreni" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Alati" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Glavna alatna traka" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Alati zabilješki" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opšta podešavanja" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Pristupačnost" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Pomoć pri čitanju" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Performanse" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Podešavanje Performansi" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Konfiguriši preglednik" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Prezentacija" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Podešavanja za Mod Prezentacije" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Svojstva zabilješke" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opcije uređivača" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Nađi sljedeće" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Prezentacija" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Promijeni ekran" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekran %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Izađi iz prezentacijskog načina" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Naslov: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Stranice: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klikni za početak" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pauziraj" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reprodukuj" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Postoje dva načina da se izađe iz režima prezentacije. Možete pritisnuti " +"tipku ESC ili kliknuti na dugme za izlaz koje se pojavljuje kad pokazivač " +"miša dovedete u gornji desni ugao. Naravno, možete i kružiti kroz prozore " +"(podrazumijevano je Alt+TAB)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Prezentujem" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Nepoznata datoteka." + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Osobina" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fontovi" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Čitam informacije fonta..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Veličina strane" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Ekstraktuj font" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tip 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tip 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tip 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tip 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tip 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tip 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tip 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX-ova metrika fontova" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Nepoznat" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Ugrađeno (podskup)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Potpuno ugrađeno" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ne" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Da(podskup)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Da" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[nedostupno]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Nepoznat font" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Ugrađeno: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Ime" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tip" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Datoteka" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Stranice" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Veličina" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Pregled prije štampe" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Gdje želite spremiti %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Ne mogu otvoriti %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Ne mogu otvoriti %1. Razlog: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Upiši najmanje 3 slova za filtriranje stranica" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Razlikovanje malih i velikih slova" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Poklapanje fraze" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Traži sve riječi" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Poklapanje bilo koje riječi" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Podešavanja Filtera" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Nema podvlačenja

Da biste napravili novo " +"podvlačenje pritisnite F6 ili izaberite Alati->Pregled iz menija." + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Grupiši po stranici" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Grupiši po autoru" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Pokaži preglede samo za trenutnu stranicu" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Nepoznat font" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Nepoznata datoteka." + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Opis nije dostupan." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Stranice: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Osobine" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Informacija" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "%1 Zabilješka" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "Arhiva dokumenata" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Prikaži samo markirane strane" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Pokreni" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pauza" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stop" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Dodaj..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Izmijeni..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Ukloni" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Pomjeri &Gore" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Pomjeri &Dolje" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Stranica dokumenta za prikaz" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Pokreni dokument u prezentacijskom modu" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Pokreni dijalog za štampu" + +#: shell/main.cpp:78 +#, fuzzy, kde-format +#| msgid "Start with print dialog" +msgid "Start with print dialog and exit after printing" +msgstr "Pokreni dijalog za štampu" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Kontrola „jedinstvenog primjerka“" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Ne podiži prozor" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +#| msgid "Document to open. Specify '-' to read from stdin." +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Dokument za otvaranje. Navedite '-' za čitanje sa stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Greška: Ne može se otvoriti više od jednog dokumenta s --unique parametrom" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Greška: Ne možete otvoriti više od jednog dokumenta pomoću --presentation " +"prekidača" + +#: shell/okular_main.cpp:136 +#, fuzzy, kde-format +#| msgid "" +#| "Error: Can't open more than one document with the --presentation switch" +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Greška: Ne možete otvoriti više od jednog dokumenta pomoću --presentation " +"prekidača" + +#: shell/okular_main.cpp:142 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Greška: Ne može se otvoriti više od jednog dokumenta s --unique parametrom" + +#: shell/okular_main.cpp:148 +#, fuzzy, kde-format +#| msgid "" +#| "Error: Can't open more than one document with the --presentation switch" +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Greška: Ne možete otvoriti više od jednog dokumenta pomoću --presentation " +"prekidača" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "Ne mogu pronaći komponentu Okulara." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Već postoji jedna kopija programa Okular. Ova kopija neće biti jedinstvena." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Ne mogu pronaći komponentu Okulara." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Kliknite da otvorite datoteku\n" +"Kliknite i držite da otvorite skorašnju datoteku" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Kliknite da otvorite datoteka ili kliknite i držite da " +"izaberete skorašnju datoteku" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Sljedeća kartica" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Prethodna kartica" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Sve datoteke" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Otvori dokument" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Zatvori" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Recenzije" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Sakrij forme" + +#~ msgid "Expired" +#~ msgstr "Istekao" + +#~ msgid "&Review" +#~ msgstr "&Pregled" + +#~ msgid "Annotations author" +#~ msgstr "Autor zabilješke" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Upišite vaše ime ili inicijale:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Prikaži &Navigacijski Panel" + +#~ msgid "Show Text" +#~ msgstr "Prikaži tekst" + +#~ msgid "Small Icons" +#~ msgstr "Male ikone" + +#~ msgid "Normal Icons" +#~ msgstr "Normalne ikone" + +#~ msgid "Large Icons" +#~ msgstr "Velike ikone" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Kliknite za korištenje trenutnog alata za odabir\n" +#~ "Držite kliknuto za izbor drugog alata za odabir" + +#~ msgid "Created: %1" +#~ msgstr "Kreiran: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Produžeci linija" + +#~ msgid "Style" +#~ msgstr "Stil" + +#~ msgid "&Size:" +#~ msgstr "&Veličina:" + +#~ msgid "Inner color:" +#~ msgstr "Unutrašnja boja:" + +#~ msgid "Name: %1" +#~ msgstr "Ime: %1" + +#~ msgid "Size: %1" +#~ msgstr "Veličina: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Alat pregledanja" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Alat uvećanja" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Uvećaj" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Izbor" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Alat za označavanje teksta" + +#~ msgid "T&able Selection Tool" +#~ msgstr "&Alat za izbor tabele" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Povećalo" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Kraj dokumenta" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Ništa" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Dokument zahtijeva da bude pokrenut u prezentacijskom režimu.\n" +#~ "Da li dozvoljavate?" + +#~ msgid "Presentation Mode" +#~ msgstr "Prezentacijski režim" + +#~ msgid "Allow" +#~ msgstr "Dozvoli" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Dozvoli prezentacijski režim" + +#~ msgid "Do Not Allow" +#~ msgstr "Nemoj dozvoliti" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Zabrani prezentacijski ewžim" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Promjene zabilješki neće biti snimljene automatski. Koristite Datoteka-> " +#~ "Snimi kao...\n" +#~ "inače će vaše promjene biti izgubljene pri zatvaranju dokumenta" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Okular je interno snimio zabilješke.\n" +#~ "Možete izvesti anotirani dokument koristeći Datoteka -> Izvezi kao -> " +#~ "Dokument arhiva" + +#~ msgid "Save &Copy As..." +#~ msgstr "Snimi &Kopiju kao..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Vaše anotacije neće biti izvezene.\n" +#~ "Možete izvesti anotirani dokument koristeći Datoteka -> Izvezi kao -> " +#~ "Dokument arhiva" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Došao sam do kraja dokumenta.\n" +#~ "Želite li nastaviti od početka?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Došao sam do kraja dokumenta.\n" +#~ "nastaviti sa kraja?" + +#~ msgid "Current maintainer" +#~ msgstr "Trenutno održava" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Boja olovke:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "položeni DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "uspravni DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "položeni DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "uspravni DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "položeni DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "uspravni DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "položeni DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "uspravni DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "položeni DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "uspravni DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "položeni DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "uspravni DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "položeni DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "uspravni DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "položeni DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "uspravni DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "položeni DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "uspravni DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "položeni DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "uspravni DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "položeni DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "uspravni DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "položeni DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "uspravni DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "položeni DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "uspravni DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "položeni DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "uspravni DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "položeni DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "uspravni DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "položeni DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "uspravni DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "položeni DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "uspravni DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "položeni DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "uspravni DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "položeni DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "uspravni DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "položeni DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "uspravni DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "položeni DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "uspravni DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "položeni letter" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "uspravni letter" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "položeni legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "uspravni legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "položeni executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "uspravni executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "položeni Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "uspravni Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "položeni DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "uspravni DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "položeni folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "uspravni folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "nepoznata veličina položenog papira" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "nepoznata veličina uspravnog papira" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Promijeni mod za crtanje" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Pokretanje servisa za tekst‑u‑govor Jovie nije uspjelo: %1" + +#~ msgid "Search Columns" +#~ msgstr "Traži po kolonama" + +#~ msgid "All Visible Columns" +#~ msgstr "Sve vidljive kolone" diff --git a/po/bs/okular_chm.po b/po/bs/okular_chm.po new file mode 100644 index 0000000..2cdde77 --- /dev/null +++ b/po/bs/okular_chm.po @@ -0,0 +1,62 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2013-10-18 20:13+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Samir.ribic@etf.unsa.ba" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "Pozadina za CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Crtač za datoteke Windows pomoći" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/bs/okular_comicbook.po b/po/bs/okular_comicbook.po new file mode 100644 index 0000000..48c45f6 --- /dev/null +++ b/po/bs/okular_comicbook.po @@ -0,0 +1,60 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2013-10-18 20:23+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Ne mogu da otvorim dokument, unrar nije nađen." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "Verzija unrar na sistemu nije podesna za otvaranje ComicBooka." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Nepoznat format ComicBooka." + +#~ msgid "ComicBook Backend" +#~ msgstr "Pozadina za ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Crtač različitih formata stripova" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bs/okular_djvu.po b/po/bs/okular_djvu.po new file mode 100644 index 0000000..6e4c347 --- /dev/null +++ b/po/bs/okular_djvu.po @@ -0,0 +1,110 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-10-18 20:26+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Dino Kraljušić,Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Dk@etf.ba,samir.ribic@etf.unsa.ba" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Uređivač" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Izdavač" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Tom" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Vrsta dokumenta" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Nepoznat" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Komponentske datoteke" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Nepoznat" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Jedna strana" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Upakovano" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirektan" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Upakovano (staro)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indeksirano (staro)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu pozadina" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu pozadina bazirana na DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/bs/okular_dvi.po b/po/bs/okular_dvi.po new file mode 100644 index 0000000..860ba43 --- /dev/null +++ b/po/bs/okular_dvi.po @@ -0,0 +1,581 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2015-02-09 10:55+0100\n" +"Last-Translator: Samir Ribic \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Maida Kapić,Samir Ribić,Dino Babahmetovic" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Mk@etf.ba,samir.ribic@etf.unsa.ba,dbabahmeto1@etf.unsa.ba" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular ne može locirati program dvipdfm na vašem računaru. " +"Ovaj program je esencijalan da bi funkcija eksportovanja radila. Možete, u " +"svakom slučaju, konvertovati DVI-datoteku u PDF koristeći funkciju za " +"štampanje iz Okulara, ali to će često kreirati dokumente koji se ispravno " +"štampaju, ali imaju niži kvalitet prilikom prikaza u Acrobat Reader-u. Moglo " +"bi biti mudro nadograditi na noviju verziju vašu TeX distribuciju koja " +"obuhvata dvipdfmprogram.

Preporuka zbunjenom sistem " +"administratoru: Okular koristi PATH varijablu okruženja kada traži programe." +"

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"eksterni program \"dvipdfm\", koji je korišten za izvoz datoteke je " +"prijavio grešku. Možete pogledati u document info dialog " +"koju možete pronaći u meniju Datoteka za opširniji izvještaj o grešci." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Ova DVI datoteka se odnosi na vanjske grafičke datoteke koje nisu u " +"PostScript formatu, i ne mogu biti upravljane pomoću dvipsprogramom " +"koji Okular interno koristi za štampu ili eksportovanje na PostScript. " +"Tražena funkcionalnost zbog toga nije dostupna u ovoj verziji Okulatra." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular ne može locirati program dvipdfm na vašem računaru. " +"Ovaj program je esencijalan da bi funkcija eksportovanja radila.

Preporuka zbunjenom sistem administratoru: Okular koristi PATH " +"varijablu okruženja kada traži programe.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Vanjski program 'dvips', koji je korišten za izvoz datoteke, prijavio je " +"grešku. Za detaljniji opis greške pogledajte dijalog sa " +"informacijama o dokumentu koji možete naći u meniju 'Datoteka'." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI datoteka ne počinje sa permeabulom." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI datoteka sadrži pogrešnu verziju od DVI izlaza za ovaj program. Opomena: " +"ako koristite typesetting sistem Omega,morate koristiti poseban program, kao " +"što je oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"Dvi datoteka je jako oštećenja.Okular nije bio u mogućnosti da pronađe " +"postamble." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Postamble ne počinje sa Post naredbom." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Postambula sadrži neku drugu naredbu osim FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Stranica %1 ne počinje naredbom BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Vanjski program pdf2psne može biti pokrenut. Kao " +"rezultat, PDF datoteka %1 ne može biti konvertovana u PostScript. Neki " +"grafički elementi u vašem dokumentu zbog toga neće biti prikazani.

Mogući razlog:Program pdf2ps moguće da nije " +"instaliran na vaš sistem, ili ne može biti pronađen u tekućoj traženoj " +"putanji.

Šta možete učiniti:Programpdf2ps je " +"uobičajeno sadržan u distribuciji ghostscript-a PostScript-ovog interpreter " +"sistema. Ako ghostscript nije instaliran na vašem sistemu, možete ga " +"instalirati sada. Ukoliko ste sigurni da je ghostscript instaliran, " +"pokušajte koristiti pdf2ps iz komandne linije da provjerite " +"da li zaista radi.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

PDF datoteka %1 ne može da se pretvori u PostScript. Zbog ovoga neće " +"biti prikazani neki grafički elementi dokumenta.

Mogući razlozi: Datoteka je možda oštećena, ili možda uopšte nije PDF datoteka. Naredba " +"pdf2ps, koju je Okular upotrebio, ispisala je sledeće:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Datoteka oštećena. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Ne mogu sve PostScript datoteke biti uključene u vaš dokument. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Sve eksterne PostScript datoteke su uključene u vaš dokument." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Naznačena datoteka „%1“ ne postoji." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Tražili ste od Okulara da locira mjesto na DVI datoteci koje odgovara liniji " +"%1 u TeX datoteci %2. Čini se, u svakom slučaju, da DVI datoteka ne sadrži " +"potrebne izvorne informacije. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular nije bio u stanju da locira mjesto u DVI datoteci koje odgovara " +"liniji %1 u TeX-datoteci %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI izvorni kod koristi znak iz nepoznatog fonta." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI izvorni kôd koristi font #%1 koji nije prethodno definisan." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Stek nije bio prazan kada je pozvana naredba EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Stek je bio prazan kada je pozvana naredba POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI izvorni kod koristi font koji nije prethodno definisan." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Pozvana je nedozvoljena naredba." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Pronađen je nepoznat op-kod %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Ugrađujem %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Stranica %1: Ne mogu da pretvorim PDF datoteku %2 u " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Stranica %1: Ne mogu da nađem PostScript datoteku %2.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Ne mogu da raščlanim podatke o veličini papira „%1“." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular nije bio u stanju da locira sve font datoteke koje su " +"neophodne da se prikaže tekuća DVI datoteka. Vaš dokument može biti " +"nečitljiv.

PUTANJA: %1

%2" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Pojavili su se problemi prilikom izvršavanja kpsewhich. Kao " +"rezultat, neke font datoteke ne mogu biti locirane, i vaš dokument može biti " +"nečitljiv.
Mogući razlog: kpsewhich program možda nije " +"instaliran na vaš sistem, ili ne može biti pronađena tekuća tražena putanja." +"

PUTANJA: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Font generiran pomoću kpsewhich je napušten (izlazni kod %1, " +"greška %2). Kao rezultat, neke datoteke ne mogu biti locirane, i vaš " +"dokument može biti nečitljiv." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Trenutno generiram %1 u %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generator/datum" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Font nije pronađen" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "portret" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "pejzaž" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Verzija Ghostview-a koja je instalirana na ovaj računar ne sadrži ni jedan " +"Ghostview drajver uređaja koji su poznati Okularu. Postscript podrška je " +"zbog toga isključena u Okularu." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Za prikazivanje PostScript grafike uključene u ovu DVI datotekul " +"Okular interno koristi program GhostView, koji može da proizvede mnoge " +"različite formate na izlazu. Potprogrami koje GhostView koristi u ovu svrhu " +"nazivaju se „drajverima uređaja“, po jedan za svaki format koji GhostView " +"može da zapiše. Različita izdanja GhostViewa često imaju različite skupove " +"drajvera. Izgleda da izdanje GhostViewa instalirano na ovom računaru ne " +"sadrži nijedan drajver poznat Okularu.

Malo je " +"vjerovatno da ispravna instalacija GhostViewa ne sadrži nijedan drajver. " +"Stoga ova greška vjerovatno ukazuje na ozbiljne greške u postavi GhostViewa " +"na ovom računaru.

Ukoliko želite da otklonite probleme sa GhostViewom, " +"možete izvršiti naredbu gs --help da dobijete spisak drajvera " +"koje GhostView sadrži. Između ostalih, Okular može da koristi drajvere " +"png256, jpeg i pnm. Okular mora biti ponovo pokrenut da bi se ponovo " +"provjerila podrška za PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"To je napravilo 25 greÅ¡aka. Dalje poruke o greÅ¡kama neće biti ispisivane." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"GreÅ¡ka u DVI datoteci '%1',stranica %2. Boja pop naredbe izdaje kada je boja " +"stacka prazna." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Neispravan parametar u epsf posebnoj naredbi.\n" +"Očekivani float za pratiti %1 u %2." + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Datoteka nije pronađena:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"GreÅ¡ka u DVI datoteci '%1', stranica %2.Ne može se protumačiti ugao rotacije " +"u posebnom tekstu." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Posebna naredba '%1' nije realizovana." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Font datoteka %1 se može da otvoriti i čitati, ali njen format nije podržan." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Font datoteka %1 je ili pokvarena ili ne se može se otvoriti ili pročitati." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType je prijavio greÅ¡ku prilikom postavljanja veličine znakova za font " +"datoteku %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType ne može da učita glif #%1 iz font datoteke %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType ne može da obradi glif #%1 iz font datoteke %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glif #%1 je prazan." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glif #%1 iz font datoteke %2 je prazan." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType ne može da učita metriku za glif #%1 iz font datoteke %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Ne mogu da otvorim font datoteku %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Znak %1 nije definisan u fontu %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Neočekivan %1 u PK datoteci %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Znak %1 je previÅ¡e veliki u datoteci %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "PogreÅ¡an broj bitova je sačuvan: znak %1, font %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "LoÅ¡a pk datoteka (%1), previÅ¡e bita" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Font nema kockasti omjer " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Ne mogu da nađem font %1, datoteka %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Neslaganje kontrolne sume za datoteku fonta %1." + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Ne mogu da prepoznam format datoteke fonta %1." + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Kobna greÅ¡ka.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Ovo vjerovatno znači da ste ili naÅ¡li greÅ¡ku u Okularu, ili da su DVI " +"datoteke ili dopunske datoteke (poput datoteka fontova ili virtuelnih " +"fontova) ozbiljno oÅ¡tećene. Okular će obustaviti rad poslije ove poruke. Ako " +"mislite da ste pronaÅ¡li greÅ¡ku, ili da Okular treba bolje da se snađe u ovoj " +"situaciji, prijavite ovaj problem.." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "PogreÅ¡an komandni bit pronađen u VF makro listi: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Pozadina za DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Renderer DVI datoteka" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" diff --git a/po/bs/okular_epub.po b/po/bs/okular_epub.po new file mode 100644 index 0000000..f1c7bba --- /dev/null +++ b/po/bs/okular_epub.po @@ -0,0 +1,58 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:12+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "GreÅ¡ka pri otvaranju EPUB dokumenta." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Konfiguracija pozadine za EPUB" + +#~ msgid "EPub Backend" +#~ msgstr "Pozadina za EPUB" + +#~ msgid "An EPub backend" +#~ msgstr "Pozadina za EPUB" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/bs/okular_fax.po b/po/bs/okular_fax.po new file mode 100644 index 0000000..e91240d --- /dev/null +++ b/po/bs/okular_fax.po @@ -0,0 +1,48 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:16+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Ne mogu da učitam dokument" + +#~ msgid "Fax Backend" +#~ msgstr "Pozadina za faksove" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Pozadina za G4 Fax i G3 Fax dokumente" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bs/okular_fictionbook.po b/po/bs/okular_fictionbook.po new file mode 100644 index 0000000..c1a7d87 --- /dev/null +++ b/po/bs/okular_fictionbook.po @@ -0,0 +1,83 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 19:26+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokument nije pravilan FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Ne mogu da otvorim dokument: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokument nije pravilna ZIP arhiva" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Nepravilna struktura dokumenta (nedostaje glavni imenik)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "U dokumentu nema sadržaja" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Nepravilan XML dokument: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Konfiguracija pozadine za FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Pozadina za FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Crtač za FictionBook elektronske knjige" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bs/okular_ghostview.po b/po/bs/okular_ghostview.po new file mode 100644 index 0000000..64c6c7a --- /dev/null +++ b/po/bs/okular_ghostview.po @@ -0,0 +1,94 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:21+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Samir.ribic@etf.unsa.ba" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Koristi fontove platforme" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Određuje da li je GhostScriptu dozvoljeno da koristi sistemske fontove. Ako " +"nije, moći će da koristi samo fontove ugniježđene u dokumentu." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "OpÅ¡te postavke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Koristi fontove platforme" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "GhostScript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Postavke pozadine za GhostScript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Verzija dokumenta" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivo jezika" + +#~ msgid "PS Backend" +#~ msgstr "Pozadina za PostScript" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Crtač za PostScript datoteke." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Zasnovano na biblioteci Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/bs/okular_kimgio.po b/po/bs/okular_kimgio.po new file mode 100644 index 0000000..33c94a0 --- /dev/null +++ b/po/bs/okular_kimgio.po @@ -0,0 +1,70 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:28+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Ne mogu da učitam dokument: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Pozadina slike" + +#~ msgid "A simple image backend" +#~ msgstr "Jednostavna pozadina slike" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Glavna alatna traka" diff --git a/po/bs/okular_mobi.po b/po/bs/okular_mobi.po new file mode 100644 index 0000000..2edc1d0 --- /dev/null +++ b/po/bs/okular_mobi.po @@ -0,0 +1,66 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:17+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Samir.ribic@etf.unsa.ba" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "GreÅ¡ka pri otvaranju Mobipocket dokumenta." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Ova knjiga je zaÅ¡tićena DRM‑om i može se prikazati samo na naznačenom " +"uređaju." + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Konfiguracija pozadine za Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Pozadina za Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Pozadina za Mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/bs/okular_plucker.po b/po/bs/okular_plucker.po new file mode 100644 index 0000000..43552bc --- /dev/null +++ b/po/bs/okular_plucker.po @@ -0,0 +1,48 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 20:19+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Samir.ribic@etf.unsa.ba" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Ime" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Pozadina za Pluckerovi dokumente" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Crtač za Pluckerove e‑knjige" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/bs/okular_poppler.po b/po/bs/okular_poppler.po new file mode 100644 index 0000000..5d53436 --- /dev/null +++ b/po/bs/okular_poppler.po @@ -0,0 +1,204 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-10-18 20:29+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Dino KraljuÅ¡ić,Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Dk@etf.ba,samir.ribic@etf.unsa.ba" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Pojačaj tanke linije:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ne" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Čvrsto" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Lik" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF opcije" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Prikaži anotacije" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Uključi anotacije u Å¡tampani dokument" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Uključuje anotacije u Å¡tampani dokument. Ovo možete onemogućiti ako želite " +"prikazati izvorni neoznačeni dokument." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Forsiraj rasterizaciju" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasterizuje u sliku prije Å¡tampanja" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Forsira rasterizaciju svake strane u sliku prije nego Å¡to se odÅ¡tampa. Ovo " +"obično daje neÅ¡to loÅ¡ije rezultate, ali je korisno za Å¡tampanje dokumenata " +"koji inače izgledaju neispravno odÅ¡tampani." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Å ifrovano" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "NeÅ¡ifrovano" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sigurnost" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Da" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimizovano" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Konfiguracija PDF pozadine" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "PDF pozadina" + +#~ msgid "A PDF file renderer" +#~ msgstr "Prikazivač PDF datoteka" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Spremanje datoteka sa /Encrypt nije podržano." diff --git a/po/bs/okular_txt.po b/po/bs/okular_txt.po new file mode 100644 index 0000000..b1c9b8e --- /dev/null +++ b/po/bs/okular_txt.po @@ -0,0 +1,53 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-19 12:53+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosanski \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:23+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "Samir.ribic@etf.unsa.ba" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Txt pozadinska konfiguracija" + +#~ msgid "Txt Backend" +#~ msgstr "Txt pozadina" + +#~ msgid "Txt backend." +#~ msgstr "Txt pozadina." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/bs/okular_xps.po b/po/bs/okular_xps.po new file mode 100644 index 0000000..5cde770 --- /dev/null +++ b/po/bs/okular_xps.po @@ -0,0 +1,60 @@ +# Bosnian translation for kdegraphics +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the kdegraphics package. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-18 19:26+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Launchpad (build 17341)\n" +"X-Launchpad-Export-Date: 2015-02-15 06:05+0000\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Samir Ribić" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "samir.ribic@etf.unsa.ba" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revizija" + +#~ msgid "XPS Backend" +#~ msgstr "Pozadina za XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Pozadina za XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/bs/org.kde.active.documentviewer.po b/po/bs/org.kde.active.documentviewer.po new file mode 100644 index 0000000..31e61a5 --- /dev/null +++ b/po/bs/org.kde.active.documentviewer.po @@ -0,0 +1,75 @@ +# Bosnian translations for kde package. +# Copyright (C) 2012 This_file_is_part_of_KDE +# This file is distributed under the same license as the kde package. +# Samir Ribic , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: kde 49i410\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2013-01-15 12:41+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian\n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-01-16 05:42+0000\n" +"X-Generator: Launchpad (build 16420)\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Obilježivači" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Sličice" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Sadržaj" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Obilježivači" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Bez rezultata." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Pregledač dokumenata za Plasma Active koristeći Okular" + +#~ msgid "Reader" +#~ msgstr "Čitač" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Autorska prava 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL datoteke za otvaranje" diff --git a/po/ca/docs/okular/bookmark-management.png b/po/ca/docs/okular/bookmark-management.png new file mode 100644 index 0000000000000000000000000000000000000000..e0510169921013e9eeea9887d9077156741255fc GIT binary patch literal 107512 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%0D^%Q9ahoDHrs?Vq&ZP6AaU9I2P-FkRW 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 NrNtGX1!5ol{s%AO?}Y#W literal 0 HcmV?d00001 diff --git a/po/ca/docs/okular/configure-backends.png b/po/ca/docs/okular/configure-backends.png new file mode 100644 index 0000000000000000000000000000000000000000..eb67b1c0d90b984ffe1dbd94e5a3ad568c07bb20 GIT binary patch literal 39470 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 z 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%0AxW%;%(*2bS_)1^6ijb1@BfQNDM)iGBje zcrMn?)3GMCym%H%YCA!{dQVyQ@DY+r=`(rvy8E~Nt|pkBtSwXhoOWCK%?x*Y3UoC1 zE#@n|X_NP&R8Jm4<&2DJKsywo-SGh8KQM=GuR#-x>d==c;QPE;v1=CBfXBTgAMkNs zdh@TE`Z&l4)w^1|)tRFrZyEYP|y%u7!v3q?g|>5}fRXS1m1 zM@>f?q;Tp%J04dmNLX?Kf$mM$6RLF7RVw5%j3r40p~l7So#A*(yHS~-zZ?x6# zS(|3u4iHbR^~K&^f1E`Y!_IX(7i`-te%o{CvSBG_88Bb;j08}y0<&oZx9j7BmuLjm zQv8&yZb&Cy>vzfV5i6DuF;P!p!fr%93x05ntUnzxSuBj*GV2g&8e*;9r!x+munboa z-zTK-0OR38Ow!C%lfk{(CRX6EDx2xyPvC{eS(UR3=D5p3?yS*=q_+8E2@>Ygv4+JC zoaTYk70=SsBnV6z7sZj^TS5tf1*e!+zNd3-NE6#j$ zJkp4Mkr@OSbYR+~!J*q()U%(SI6^`h?f^i7L#VF}q9n7?)t2sBm;2Sw-@s5?&~Trj zL$E^x8QGu0pNZb*)lkn!_)C5liY+O!?s#AJ8t|C}N1sD4rChV`%Qu2C=Hcx~MiCs9hsQ?)-he4Fe-aSf{3V*D5p@U>Q583cZH0;>OTMQhj}(2ezdUq8 z*e?5IjWYS{`2K9RfP36TG4{vbtH+UZhJLIIFiu7W08J^e@&~jytQxzkKczfpq7m*e zm>RI<(y6U?B4{yRBAj7>c+W0GFD&<^GrgkeG94QNeo&(){nR9oK9d5}r12 z?V!ba%Txpc7~0O?{#BurO3NX!@%m*jj=O@dvm+B3AmjI46;x&CF=^UMdiptLa_|r! zdPGm5t+e>YqWv5h!P{oPvd~Mw^EO#O6T!{e$6U{pug7ur)iO?%%x)2B>6Bdib%{A_>d zT_NFfvp^|(>uKHQ5eZg}qi;U!8yCQ;TIZ^Irih9mr!k%aE=|V-jftXRAW-J=y#8B@X!}yQT7YWc2ELx zYx%n|<@VULSRFjQn|kWcFCFadYieprxT%Fo zAioUC{89~18^w*S#8g4=M|+lnMmrGBZEd44RVgxri=+#hA5Pjb$4j+Ho)Fg8rzz3h zEmI=aGB;Ok3ul#E>=SCflbSLAF9=$7ngcnlZ38NHj6qY$@PmqTF?lNa%Bz8f)_cC6 ziemEAYPr`$0=n2AmY9O%K}-cDt&Vx0s9dH)4b7nk(7@bN7tGS-r7jrg+ibi*gZPO1 zds$S#p%N_er41nIe^!j7nH!MP=M6Z@;a--K|8KYOnTOx^6r49nC}7cn;8IR=Z} zHNT+4T3g#Zdh5`g$RxE$66wPWQ6nS&CR)jTd?`GSWYN)QndM|k zqyIutWWdb{;KzvDYaRYeYPN_tZ1KAS(C5v7zX2EpeE9!?P958d`ScHmYWqF8C+u-# zkEOUxB(K&J7mI;?c$`FZ?=2lcSwQ~+m)OhQ-ym9>rdOx&A-1DWouf33cR%_Uo;jX+ z%(LUNpPN&%N679Q0iUU`0!o@LOHQvxj&r^3+41@LvWPi-!oO zbIAHcY&Z8U^rRfiY_zW21>6YkCK`MYh$*TTY#?Z}Tk+Vx7?uz#-(2abcXUF}ld22) zRY_HKz3{sMy+HqGxq(x#vJ6fWyPgY~ored`(bacuNjuFZTSIRVE*DBw4(FMp6pw~R ze9W6?*E?1jYS_%ZE?$tFhKXUb`@W?a4)SMUpYe6d`s}0!N*cCTf9F2Udz2T==qT?| zPw97=_Dhj%RnV_hnfXTV0U(RharNMn&Ld1*xxp9f*XwiO* zQ=~`1GUWpgG>|AbB*06-S38rG1a{`85a6K%6!r@N&RINY-$t@f_5SvnX(wm0^w+Da z-dxO!9hbM zn9;%Kn>6Ty{Ha)lTYJ-mNLnA;&h8`iCZzK9(mP3^0EVyUiKaqi%F17OL9fH+B_fmD zHc1_Khg2nYQN3I|kMEL$Kyt>kDFU8TTi)yj_o?3Yhv6=;3xXNgn;%`g2qkB~68Syd zN%pV(lwKt~rto_eBHrLC_USKBMh%s3t!>T~)M9SBku$6FEAh4;1sR;_O_k|x8TDi5 zN$V3Y<=Yh6_?|T|qo>h&^o`s0YL^4(>8!T%)j4(drJu6%Um(@*<^ng1(WxFxAKof; z(p!mor-_aA0`v&k5n?0>Ir$69O~m6af~|He;<*ociMYAEt{6Bmr~0Bd1bUqzWPQ?> zN{-p1F7w!k4lXxf7r9Ur2*CUMd*a*?*#2x`uel|W0|ZiqkocHQWgU09d2#NV=_dwD z06W3s4K*I~bNX}CmIVz6G(;A#t1rOKbOX70#RM5~_cgdv)Rv?b(;u^VmnWK^0H*yo z|LqJvSy1x>1@q*mIG~vpX&y&und*u{FzFASH^1Jf*%g0m7psOEexoLLIXsDSBt!E@ zxG#3ya;`^qj@l$74{kYEqelPE=YS>{+Q@oLU2HS+qWCnjid`s$QK%OS2{F@WTC^om1A$3lA2}CUH8gH{ zRx|lw5t?+9K$+@HsTAc@5?4haJ}>cT()&EH6+H*Mw0P{3TWLPh!7al^q~n z%Q~#ntkZ+05}8X5=J*WUZjV1C}wCM-QZJcIr`vJ3VWCPlPB*1Dv7mj=P zO&S$>3JdNcit1pLo?d+o)q_hD+;l>7bA1->aPLFU<10)#ritTP6jv*Oo_K9z9r&?$ z`Ppy=-7RK2T3h;vsrTn-jB=%YsIn}{6OdkS_8nOhU2mUy7n_v%VEvbAm=(JpPeC1r z$kX&NrxCa;y)>X~IHGfR`2)t!KH(SF&dPVs7~g8QlJU%_=-!_@Ee2Jh=Hs;$V(_0+ z++o@XzV4u{k`;c3h|#Okc3;{dd;Tp%WU0be{5dPft}`-`M=8Koy&oBGpn0t&Dt|2tCj*ZU#P?NMY271CZLopEr3kGkRg?gInL z8^nA-w~*RK&@*g*j`M!x;7Cp}FK$klCQhd(&5wf3)Ml)xG>Hgoeu|20r(km!f`bEA z-D+m>_-Isn=1|$wzaP!kSNYQ5<1nerWIkPj04>Fx;yS;Se(KmN?YLBT@i29T;Ce6v#!T{KYxO42C|Pmp1M6CsBKbn3(Z_4E19J&3;B+gknEQooC%wK=~NQMY&;P{s|ty0?zHy83aOh}Rwo zSREJiJZAWC>3&1m{$z#u0BT{ofer*3qtIu*dNaxko@xnbgaVm1#bw2JKyRos;@i?| zofni1fY)9RE8M=8sNy_Rt7KCQ0^Oyd3!&AFAfc=D*w!}6VJ!R$^h6FyGOwlZP^$@qLR(|A-&xu^rGAamN@6kyaA=OGQh<6&Il_h$B`e!=gy_Q@n|)PS6Qgvu=iXRe*Y*Nydx!qZx9 zdLyg!l>@fFOvtE_7}Oy}U#QnDk7I(Ux!jJV^QsKgKp+$@T?l8_;-AUC!NUWlWSvh) zC}_#8pMcL|Nln=LQLjDS6J4Ys3O9x)<1F>wx^ZGW;un0Qxq%1s{2Kn{_A(xLxfOtL zs6JIxQ~dIoY+}G!`DPy>)Bp|W!$hkX?Kw>p2-0^KHj-vD`~lWBvg0A>&9BV(tlCGB z-J-q=s1)N%#E75IJgrGNX=+wv3C?$5VH0Qfr z8?UaMHeF`!BWs>Z0oJ&?+awF}GCgs%mlNhR`l?G6dAl*hpQ~Tt4oXM_tp{HXN6$aw z$0T|2lWft^WkKn(kgfy3g0n(k`m9r2D}~XDUE;noq{KAM3@A*#2}aC>T#cTt9d@>- z>^k9r28t2`MOo%g=6OtdJmQ@8Y)GX>i)k)&vMmvh5zoX})>y6$0?qaJFnT zjTppYAeqm8q68c(vfosto&-EcZFphOJlh;R(3^}GK!@iQmV{E;-H1Y=CC1GS>K~7| z(}eB?zttLV9r}X<`Xv-8r$!IU@^1T_#Wdc9o6H2v2~_R#_z6%Wgo|J zzfjG)PN9EQni=2Lc$D`50ok4??PDZk(^Uly6fSp)c3Uph)7AtTZ6Dw#&2);r?7aDnukDWj|C-{+2`MX zzkd3NUMAvo(mM||AY6x{DFw7L>bzi*Tg_HkQ*-PC&K*(WADcL!2f7fL-E0u{dVFwe zD6@SENY?_PNn+bXrl|m-CcQOL|3#IF0GD0>fBmm&Z0K-_`Zkt5h8Nq`h~7q~uTy?C zs5w;x^rax<6XvGI_33R?10JxHicb~)eM_gtz;3^GVl8eMXM)b1+kj4ZWG_C(F&lgK)4rE-_ zT29z?0{e{(co7Pv9A**^SRxcrQ0X7R55xr4bG>MJ;RJZv=(oX5&*6pJ8OHWO`aciT zQ+;(I5D3Dk84ye}cr%%BDMkZE`x$ zyLFS;h>hGcIFv8JVaZ#1S5up<;73!NX*mzTQHaBf^3_xU+{TTCo1t~;hoJr4B1 z)?r$wHy*Q09S#^&2?$9;3`I7YFNPVN5xNOwVbHXiqbjdJal6-cw#BW!0jTD)=GyuA z$vh8>%TLzWivzgqCLk$4SSc-7L-Hs@2pV}$_HbE`F@|J$Hq7BKacG|4aO}rRTjeYh)mY=y z)KTQFD|#>Is$yA3r}af@kjaI?>9|e@iL)`BwE-iMQdlX~k+yKzMfeI$s0HbAcQN$C zz|cPCRMI1=I3PiC-VSX%uv*0Km&fwD$L)xzhB~b7fw@dNm^?Jqup_?Fc|gU@D)4d` zla5U;5~3cgtTWvaboW+t>-3OEHFe)yJ5ILVU{v>Qv>+W9-BAG(WzE9+Vz?#LoHqMg ze}m7`Q{W;ZCwt(f9vlU4#C+-x1OB}Vwl~{i z6`pH=s7#uv}JkXVYiXE9rZ#FsQDXnG~M-D6BVO1iz|sH_cYcYz4A= z@cW2Zt7a@X)aar7!+SOIXHKqu{2bS7aC7pLeKH4|=|->Fg!u5lg_!xwjf=N83%(%G zVC5GoW=JIU>zy{K^yZ3}R+9((U*gia3zqv4@NK$5^VWcqfqOcn+iLw*RYY^x%pQ6? zYtfsoOG%@5)R;2@BP@C&<(Lo5?tGlM;K(Fms^!S<-hUx$-HJ7bNkN{4lDC}ge)Ocj z$4J#NRAepCw_d(Mi<&O?gF-Vc_rs--LE;$1gjl2W5H~P0XMBrtFBBjP;O5}5<1YlZ z?~kmC9!fbi38OZ!R6_0@mh?^-mgURC)MDzqqR*a<=DmV5Kl1a~`^G-`&flC6EJ@7r zygz_0NnsDu#IInrmPyh|l*b*%^x^XL96zB>S zU5J;j&zB)yqfvM1!ci0e1s1@}{zGVD;^bE>E4nzK0>DOwu9T7p|I1(k&PphrIkUSG z@xQDp5nyz$JHBx=l$JKp$WL`r0Ce=J~vOCgS-Sd%fS4lasMGhenN|$$&bwxf0q! z720|Dlpxj1%d^qqFrRZ%u$rcpS3T+{5L6grtyVu@bYu&$Nk0DdaR)w66gw#&SCT3` ze24@3aKDs9{M(tKcbB?m-B`RCcfGns)q)SBL;v@f-@)MtY{RL_ZpGSmHa0zZN(=_@ z38fHV$QpnHcY;SvYgxD~Xzt&{N}tWk$G1J_Mc*AA-LysqcHNoPJGegE`}9}pDd6-2 zZv44RQ@o_aMJDtqG107^UM-DSn@kj&nD^`JFh+%FY90m#isj{RpZ+ra`xWT=^b-ob zYKw<=0Jv9hy9O5n1FVMDZ8w;G4}C_UFee}Z#v*`=^nnwCN89A#4>(UIP!jQ5z*j&3 z)HLrzbq@sczx64_y(N+8N=?8c@~2lnSIu0>9&v03q^J;B!BP%3wiNx^5@puEK)>og z$}IuOaBdF)AIk3IDNyI)eF*UXfA49CLTM_LAJeDXXED(^DIwV3mx|k@x3u!=Bo4jG zTu5`~58I?GQ{Qzl-Wmxwbsm|03YJ5M2Wdg;64l*W%X;s;0xF9B z_H><6P*CJMx(j;#=61IE#1;zUVHUJ(z5;D0?w^=x{31IIF|JH?}w&)sO8Sgu##cNkqcMLJk{|dYdx+@5zsAWAJ zBXgagB8n%NQN)*)RA$e#4TY_Z{H;X_2Sj6pd!GBXAq3*S`$lG~Wu(f$99XgkfY+KK zlexec_BMWm2zexS;hcB=j5HIf>8-pwG)cKn1_sYHzfK2W^8*qWG+a~)gfhM9isb<}?SOMp3f!<7JV59c_5F8Dt^ z-|?=8@$0Lr>*MmboQQ-?Zb8T&=mGEx zM3y#5OLQyRcv{Qsf%|`r07$Os^L=wPU#0UR;PQl-kjz61FcPR|01YGRlcoN>pg<*E z{1y>Crw59X`ec0p6tvARD9QLSui9A7O9E2RhY!*@1z;8Yj^21yfJ`E>Tc<1#oYM1CP^*mX-ex5%Vi>LQ_ zTMH<0Kei2DCCwXPi$n?U6Hu-u9sJl)0&r^|JaPBeEZ0_goF*C@m$Gpo;#LEMBaC0DYcenjls7d43PJND zAZ-982*B#~dMK_A!2jH({0DOlDJ)s9A#*b_Z^;xW$&GB$KZsUKQ~<-&+8r8Nj`{94 z$cHxU_ynky2fPp%N=t!IF@a6U;|3U4{ySg{z2D+lbrKd<+K)+Y3A+bR)3)M}ukZ?8 z%7MG*Rim`=_CaVzVe|gRUy9mw$b{lNJW^B4O1@qY^#tBfjSYwD25Ifj(ahwEdY#vx3V@RJmMY z0B!j(7|?5lO5mE_`=0^D4*+e=5DS2;A#f!E)aC!dR{vwkgTFjw=9LYU(MMJMFiSKR zXSG~nRSBpc*Gn814rBG(AEfW}MdRLjkGutPnQIO=mlrc#hSNbqYvwZ1l+)$d82g*+ zIdQ-k{+MGWa~4Di?s7fZScYB<>YL|~O17IvJ!3HYH z_Y}6_9B{Jnhjs5_f8~zwt4YHPTMXR!U9|HKVl2n<3djMsg$MY``nB7Zc8~2wommTK zo5!;#3JEB+I$L!|=MxYLm6G29Ewb6Xj%{mMZ?;{aDi6erH#Xi4gF;`37S46b@3N4n zp_@|iTaBBx3g~n6&X&wCYaVcjWHna7vAkYAUEk>1WO6H!TecbGwSfLnd+tu;zfUy zwWhA^V(9p+UtK+J5>##DTnOFtNwIF_+r`p&Z+UsCr>q{(yU{dn-Ef{Yo?M;0Yb*=@ z?NBxKsif=65iK5QNR=-}8;_llA(yGa=zY${pW=-@BRFfbCb?R0vO8+_r5vQg(b=oL zTK$>y`jR|S#zXs zkqkd}V)H+V^O9jGqN6KgXVj4pSb`CzKcy&zMl`=foo-89n(fBNaZrl55A@gH_cP&% zy5&=^k*a}Lb`8+CVl8}ocf#i{5kbajr>oexv$jw4mMc_|jvSjr%UdW_^X07gTjh6$8nr{q$afmrEcl??2Y_RoN8@;(G)h=owAhtrq;g|8_qPO-;qa9k~S?aQDOH7 zgzWp27lx|f<t$#a^s#Yi$#I0PMM(ocm&xDk77h#a>~JunO_>%;#ny2AFZ%=dqHJ z3JTR0G=jRDLLqIF=-TL(oAng9GfFj+RHkCOB>z$9nBvak3Vn8kPW9yWrIGQvx6wg2 zQ{TYgMyuJN@$WP9#;F0lTNDa5(SG8Wm$|Kc5|?v1t&#Pn(_gclnmdfMCO>^ro-3b- zd6KRq2^)4`2?B21jaSc)BL#WlErGA07WX&hbPI3jZ_UAW!H~A>O z`s1}P46mk1z-kVWe#UP5iaf0Wj=IDBiLKMSWYS=8^YZZgGbH+GCOwr46MXnvqD9m^ zRfL6OA|~y9hgz|I-Dot8TcT2<`eW+h>=iRjuo}q=JpgbL5HP4SnO-|5P1<5b&XjI; zkav7?8=y7}J{Jt*)UojefjXyd>{l)mX=X+p@i*Hi2!4jgwDUbL8JK6h@)B+6vZm>> zKWSz66hMXOMv~FpX^#+xCW>?Q7jm(HXT%^XJZ8a58J|HTb(xe9biUNUmI&SZBkIE2 zda0R_%b9v{{UQ`C3 z@iM-48CfvqR3EVFTpJ4}nlYLdg~YN1ZnMVTp-E2WM^DXs39_kdfW?zZ(Wdz-%2sXq z_+igBS8gN!u)!M9;+X#SM8sG>OvBk@`(#Uiw>)nzFDkKG_u^N90DjHazxaIm%@NTG zs?slA59&{F6g>z7xLvP$U+^r{3pc!G&F2*q7A`Ow9DP=wRPQVI&SGfG$Z-1+ zWlgok-Wz)(B#>B;cpFe`x6NhB*Kc1TYPWCv#>K=^cEra{V(y|Tc~B@FY`)yLLFo|d z%3r=69&r{B8PV%*1mO$q>`Fh1unU8Vc-#`2N>aBz2MDEk$01j+n~5vHDRqpW>yyiU zkYGNT8I?>lR*AG^zYQ~he!L2#y7Ql8@BiCi!s4e{%ST`0oM>oD905?bhFv3Fr{WMF zV8H>oJO=Pi{#qFkc+N++re+W^O-f`@;2GO%7DfX2Sduvho$Pd3+gaOmX+Z$W1mbA# z<0XSV{qr~)x-y7Cpdy(Z!Ls*RE`B%VY+BzK9s$sYI<}462qM}{)1cga9|RhIuKrDk zf&1D1`9VakAle6TV{m{Hx8$`dK7hpBch6hb3YRTl@{!c+boyP-h7}RM*MReCa(=iQ zyhk=?Wa^L?IFfFrYF@6&HbA1t!*`0O_9z~INbN7sgV(n;D7h;^M8x?uL=N+xj!m+X zDiSwaq#IYNRPd^qmy>k5s8b9+!2#WU3WUj=z+O`nv}tdXEvMQtx(o|-lQ&PB^}Ddu z{X$t&z>5sk8)4i(UH~`O5^vcir6npNuUqEfVhe>lFtYk1y{DQ zl;ZHn7YVTPDLSaO__p!T>++qES3)$RWSbpWs}eJ|5W=(ylFLJF*pZ^qmhxEzCxI)H zxz<8zM;B0(Jq_0%L;_xsH~j^=%dOAs?;2hw<|A3|UdTGPrHoaF)2cd@k{Gbg1^!CC z$=y`u@W2H(XlNTo zQ%`%Q%7J7dG=L1q5gyFFoFVc+FbbsgLjBt?tC3`5iQcj|D=uRQu7)!^l!yd~Z zM}oQJ%VJ>n{kQ{Qc@HX#xseVa*KQAW5O@FWaPEP?Kk<)qu|!tyJD|Vt5*v<&j$4EN z-i%{SUE_JAggv~`@$zyh_qRI_I6n4}=KB6Ao3f_SyT8=SaE7m_=%qGrb8Kg8=)Avq z`Gd87ByfM2?K|Fv-pEl<#C z*W}A&FJPEZdUISmRZR!Oq{)Jq6<0;B`=PQB8OB#X5Q$PrVQ|`$6@A z{q$l3*0q-aI%lBke5fEd^BWmulLvz`t>+vq5q08Y=YqoO6!_fUVLl49p8Pt{)hZHC zZyzc#53T&2WVeG$&d+-8gH$WEc1!*Ye2W)(?DE~t>612`;D#TSiVoK|*PX%SQze<; zOzm_a-JB)oQKto0JP@N~Uv?K1DkK37WgNEG`@;C>`1$!!Iii_QHMM4)yr!g@1;v^d zAvP}7ISGWb?)lV0uZCT@c5Fd!g1bJJ{Z%R`Lf`yO#?v%jiiKT1GMfjSKPyHT z_9*Ial0;+%!ygdU3=g$N+G5`-Pr2DGudN7Qy~h>^z;a)j=trfU%x*#|sX!T~8ebyn zJ=Y`7Pz{tDEIO{*Rv#&8sBA^}xNV}EN(^;e+}&00ARPY}26s`mk!Rp3N$Qi;6`^q= zz=7Ac2hvIAGQ|Ko_TQo>{v8Sf$BPc_6zC*3fPX*C{%=T6QZZm0(6j*lS0UWw;}k7R za+NQ$RQ@}*W=xGGZ?wP;dBtj!QxRZt`tE>+e%`jI;*|TeW@I<}Zwe`!YK|gpb>L&o;DQ}p(3`)P{%oY?A@eq* zAds<`2S$80%8dp0)NFGBE`SVR>EeaOTlNjEqbMuda_@$)+{@nMU;s=Zkp0ru2#~*_ z*ULp)U#(K=9yOGOYmVyt1$rX|7~!&sIT})mfh>D~TzvE9mZB_-H&bhk^BlA6Gm2mL zw$k?Qz?HaFuD3Ze+OXe!%>a|}qrNWvu$mJ1vN*wRpxeb`3Kcn6c@euIM43k47zza( zy5j{5=swF@Fisx}Tz!)wie>L|iv_+BC%m0Tku#RtlSED|Hfo%-X=^{h`V^jllAK)zjeiSH7o$m~o zeO91N!GJrU5Bk7JWN)2>+d^d)+ef2DoeXo=YQX!01VEviy5Khe>%i_p==AS$ss!BX zb+9URLfU~pUhf~i11kDjc=EkoKIGMY@x;lM2T|+D(KMWxm|C>PZojCTZ+KThj z@u_`I_q;l{$JAPs0%3wWD11=C*`QU z@Yz>Ft!d>OcSnIBzOoPM;D`8s*QUg7w2Lg4G-V`vSLDtv|)=UCOJC4T&d2qYelD)8wM>{>bZ6f znooK^cf5ZkxE?=TQ3Sa0Cb`uubV8P=J6iX5eh>IXJmdMPWus>fe9zhnpPSK&=m1XL8uTWBbzB`0}oQanUz2d`D+p_le&u=2u5VMCa4ie)ggc z(2AaPdvOm3go0nXunlu3hzc#;Brz{J3fHPmG`;VmrrmRg=E@VFadIjLTANou(;89Z z^3G1x{E@vX2(PVVyPtQb9Qga>eg4#7;Nw1yp@tKc%Z3b<`!O`Ay!h>Khx%J+ek96tn0>ICnnzY4-eB_$BG}$?E6O7O_<_FuNmKr(C7^ ztOYsINHkL&_0HsAM}qd|R4z9vg*$;?CsM4{X00+(89W@t;q7oWN4uw*Qte0)d$AI? z;+)=610-0$;4NM=1aVgR--#)^3n=c7rrvX<*1zfL?jx-4)y}bYJU`8*^_)gm;z_(m zxP{}J8`M0wG+%GWHtlEnF=9EzMC&~aC)zfg(?vOrj_dD;g|}XArbY*)P>xhO@>m|< z_gXle)^FUr*h=y=A`hOjs>0QaL@xopso>do@XQw>fxwgLB5kh#F(2=5bli1ngOlCX zSN`a+7mnRZEj|OKh}JpGniGEB^~7l!VVMnO5r1>hSsO*8!D9@ju9up2(7aHuE2qmf zJ}PD%_@_*(kRtgr6q-QIyIESel2Sl-x!4tgY&z&cAeE@>&V4Q$gN&~_kc7t1*s@HB zT-|q4(n}k!hSQ3mlg9=N=f87qGGTwdKaR3@HmMMIcF30FOv(Jr=SZekxh+@wYIs{5 zxOK}49w3A+f@ncxJh-l}KO#3Gy*H*mSJylHCySlua^B4GoI^T`r-k%A4>I6sH-5xg zCz-L#^l8FlYr%*;8)qVlIqq%P{h%4tQ@%gz=J$sdQv!dU`mV;AJ`6hCsODh2_r9niRhYqdA{%m2S75Xy+elb<-=3woD9 z5SH`{-*tXUC~i}*(sl7~cs)KWc@r5Hu3bw;w!O@*4z)?<*AzLUSQa^5ZwbF>3;IF3czXDhX%kMaAuL}F28Gi5oLr=yVjySP`RRiP_?mfWQz)u(K5IxVLNapL+_uwBvEALGR$8!i z^~HrF8l5TgeyGMpD%$4d4S}?qYRrs4Eq^!@%sVP4o?_+%MIml~xEz377%TEGKG`t| zG|Wy70^(`}S9>L6yrI>EL||81@tCac>S(^FhGB=O^wN6^f|(aR_x%#bz8lwV9qSp; zUtVVy>y3Tx3hPz5A6@ry;w4=cdCs$50!4*t=84I=n5%Z#BQ$KeIz;76q-gx~^bc8Ots!?Is{@%ncCT+S=#O2S}}4AHT%ri$6g+ z0yJmkFDkmD7du-6dF;JnIhF-au0xNbYM;5t6Kgs8OdT9Q4m`d@iX6|VT{k-hH6*)O(eFiURd7Oej5hGLq6V} z)i5k32Le2J9t#RD>~?;38~3MOwzX$VxZc;B?JR@NpS4^VuC8OnTbY(7qRVWZNNgpR zhPQ*7R|>s+{oVIN$c_10t^+tt_}qN~V@#{mSlQ$J$hMS`goTdbh>>`x($J(~L0qJfhd>9by@Yo{*&*G=(%rsYEcX0tv?h~dl7 zX2BB;zHD+s=_I|*^*`TVS0O*`E&u2j4XqeSKDoL$GrqB%@oKFrwRE*o4&!6tKUt+O z++!K+>1E{$?S|Y-eNSE5+NSj*)hOqSw5%qLSZ4gH)w*DRYz1T5FpzHRqc8W){lG-o zr)Kga9bGcL0FMr#&~+sBKSUgQ4M2HFARna^$b9H7oPgGKB$M(1iTygR6Q5r&akl_R z3Ob)rQqiI;Tez5tiq`A^#6!B_5n#-(RU_RsqrAUnS8+!gqNxZmyxMA}1A*31fo!)C zP7q3swKFMia*$SnnT{=t1Q$4ii>sRRL?hcNk*{c50XWg~`Y;ZF4FCT@rT>Ts=iA>> zi~u2_diLKZ(EP8TM%1wEx(madW~|^d2vtWERm#9brS$Q^!2>Py*JeWwWW|X)d?w(O zReRy7CLhzEb$eMH^vBVy*(z(5MgIUFUABZ*Kxz@gx*A$QD}#EmNDB=fDxQ{xmCn@i z*-yXZ;AlDZ5MiVi@pM?Yx$a>%kbyvaefW2ERpowmw$;$*=5(lO8Wu3Ykkq(i_x(^(unZlYGm7U#teE1<6qcdKF5^X)4>q-S^_d|^ zdz}^>AkMs@y-nneX@|3TlBg1HT4M198x9z>KkhrTwER}q8V3)B>&xI3E|*e3C&_;a zeJ0!~oMa?*{UD-L6HbCtS5-W{3Yw+X`rA391^<`HDou-k2*~S!NH)J+ql(>}!pHZ% z7ZQKVF3$eKoV>(2XCTux@S7MubQPYYAg$n3EyvxVs_rEq{KZ+pl9G1E+3TFVou`=i zL&_swxf8z(JO7#Vq6Ez6sOZsOGv#!r_fQh^x$$=wA3yx1Bp&`WO)rv#UymHHB|8ts z{CqQ7R05nlK!IUe$MI2dsfSBRH7L6gkAT4+LT>8=GmT#5(3gyi(Jfa;K(;h1OnojZ zxv#L$$~;8T)%N1P=LQ7sNTz?>=Vr?sZk!$~cCfT9oMdmjH7$65{*%7EX)FyOC|vp%SOXkE0D?T1J+?}`xm@%8<|P$qMTw(r3flnVAw!!k?5?b z6k2ZR(28fI+(YtF-n}m8SO1of;IvSYZJ)@IFS>HIcBr`jJuW|-sfd}W z$aTgkxUAl`4O*KCgW7~zy{q#*{N*g3I&{*%a3Rw-RdLn*?KJx8dQ3rk?$J_cbZMS# zQc{wutE;%8pa%S=c62_+FFGM}oK~67Z?GaFrmM$Qo81fBHPFe8Wf=%yZj)BDQW z%1Sx#%C)hb>oAXM25w&-R_nG=rXqoHSjv)Ckw9y{dl!LVsF`J7XgR#JmT(kWe`5m6Bc4SA zt=DgyKHfQ9r+AiN+EASHdSx-qC`FM#Or#@eP?NOS3~E0^|E}bVzCTRa2vS8(k>a^a zL~FMA!|BJ2-8H|5aO#=ZK}M(9)^u(avIf`WbZ1t+S&75%bjh)`-xoXeun&&ixW+az z8LG9>wLMw_oAyqfJACWT)o+=wHBlSe^~7Esb7%j4N>0AL&8ILDy`EJ1#a#9{86H+} zL)GLj^$oh}B*s_O*(&n0D2;F*vDI)hx!Pk;>lCooirpP|XFaR@!$Y^&Rel?>B4&p$_~^{Crir?}qcZ?SEmHE~Q6g=FRhniBE6h@F9$9 z7K2G1H2TzH)_PjdTZNXGk&$xLJ^%Vc{!DwiUHdvWA(W!}!aqoaC*+EAzsw z`c9{DN}{-!Cu_F2Cv5Rg_k=xpvxjo0>4>R1aqHi!M_a9mbP&-j2y)GqKsP(s!4IGvJzP%UW5XbG$eFtiD^F=V*t6Yg&@te8v1zBq@2}0m>&-L8VF9 zg`;RUvuDeF-fiL9DsC&J5P>;IKR3gB91VS~2!Xsa>*Hu1#HaAWxQ%kAq8D+=fRLZA z_h%)@P9aqyhe0Do)i;x?<#>@*#xsl=^E5u^iXV$H@yru(tmq*(3iR0TdIgq6HSBM2 z%p{{8*v(oV6l5BSNyt2FB=-+2n5%ON!EgBiXWnnx#_sp>E8Og*w1j@E=`=)4QIW2DM{0yr;WhQr)^=#k`khdW;QiB{+U|sRs%goE{~Eb+k#ps zVdIISuA#cwXRUa=FiB*p4@I|OtkQ}kkdWJ4{alPs3|^-R%#B$bQQNy^j-G-3er6`m zIxTx$2X)E13tqwr<7kDdjebu->hh}%i8va+oqFrEt%=eU>y|7g?B#}pbK^?Xl$%vF zh1mKSZq1!4<7<{i#7g?rLI#sGgj~_RIQ*WsaaSt*>?~c!aV9-^<+0$g+p6p!@AWeeKc7e2;GqPBNSIYj&hdpi^1IHBwo)(8!j*jt*>Rp;5|$ecv67kk;oE$0?fIB=-k;kuU-W}}al zI&vBw)th{Fg0J{K8aY*Ozb7kkwH0AAoLAU#v)j0L?E>HC6`1N%vQ@sRP(96O$^xjM za8^t-n(B0e^|$HoFQ4wDOkiVoN2IHlBZBV}?#);3%2oU}t9UvFD<0XkotbbFk14+! zaxaCt+p}b@S^~jtsd!!QHX7CLsp0ao@Fj4C>wp2jvyf`Ry^!hZ5(xoEAem5{TDl}7k8 zH=O$|r)8WsY@|l+n7xZp>!#~-Y8AHrhl)1OsB=i1y;s($Omz2bW-}e%O?btn8-2^h zl$dI@^I(tC`*w{R+{1qVz2he@A*~faItt|NE6}Z&XRoY8B-thnt{m@9G5dKrPB%!H z5a1E0<3DyXhKrR#idA)tI?@8p7b_$Oj+ML}Fv*dARdZG;1B)!Ri7Z*++A+S*YgBn~ zL#I!EG^gb9|aD=vA| zdKZ1Pv3I(Ri9GCvhAVXfPdk&@+|;)xz=dw<=SUvK_wE42ReEt5SqPY#%X>OzDcZ4H z5~5x+^b6F(z#*b*bZ(eHa~&`1OJ?SgfK``T4!WpR+PQ%3>IFlkX?VCYW-l{L1^cZq z^+?^g*wcHdd%=nQk<)Z-uE*I1;p|PXKCPE~`7Svo3AMD)=(XUpJGedE+-;p6ByKyB zvsu6dPU5v4i8t?_=XN!F`}TKB0H&F9>*hEV_kM$+$m`!vg}gU?X#1}Ze`yKSmY5z5 zS0(y$vt}b!ooOhaWLL0)nh8ddo?+esq302bKD*J3-W$FxXJJ?0q6t~a6FJS{^7IdNeR3h*qe zl6MK=__KWVSD2jB@XJ9ax=2wpD+e1BfxO)?Z=sn^u5qx=*>soA=-j=rq~sPwMFoYu z`u�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 literal 0 HcmV?d00001 diff --git a/po/ca/docs/okular/configure.png b/po/ca/docs/okular/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..d009aa6e453cd8056381c3d02b3ea17f6edf0b45 GIT binary patch literal 112117 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�KbXLN@~lOwLIc=7Op@hsQF<@S(+I0$7bE9 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 VbJs9YZq#H2$Vn-ED3kc){~s=>_^|*0 literal 0 HcmV?d00001 diff --git a/po/ca/docs/okular/index.docbook b/po/ca/docs/okular/index.docbook new file mode 100644 index 0000000..1301070 --- /dev/null +++ b/po/ca/docs/okular/index.docbook @@ -0,0 +1,4233 @@ + +KPDF"> + + +]> + + + + El manual de l'&okular; + + Albert Astals Cid

&Albert.Astals.Cid.mail;
+ + + Pino Toscano
pino@kde.org
+
+
+ &traductor.Antoni.Bella; + + &FDLNotice; + 5 de juny de 2020 + 1.11 (Aplicacions 20.08) + + + L'&okular; és un visor de documents universal del &kde; basat en el codi del &kpdf;. + + + KDE + okular + pdf + ps + postscript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + markdown + mobipocket + plucker + anotació + + + + Introducció + L'&okular; és un visor de documents universal del &kde; basat en el codi de l'aplicació &kpdf;. Tot i estar basat en el codi del &kpdf;, l'&okular; conté algunes característiques úniques, com ara el mode de resum, una millor implementació de la presentació i de les anotacions. + L'&okular; és compatible amb una gran quantitat de formats diferents com &PDF;, &PostScript;, Tiff, CHM, DjVU, Imatges XPS (png, jpg, &etc;), Open Document (ODT), Fiction Books, Comic Books, Plucker, EPub, Fax i Markdown. Per a tots els formats admesos i les seves característiques, vegeu &okular; Document Format Handlers. + + Finestra principal de l'&okular; + + + + + + Finestra principal de l'&okular; + + + + + + Ús bàsic + + Obrir fitxers + Per a veure qualsevol fitxer admès per l'&okular;, seleccioneu FitxerObre... , escolliu un fitxer admès en el diàleg i feu clic a Obre. El fitxer hauria de mostrar-se a la finestra principal. + + El nou document s'obrirà en una pestanya nova si s'ha marcat l'opció Obre els fitxers nous en pestanyes a la pàgina de configuració general. + Podeu tancar la pestanya fent clic amb el &BDR; a sobre seu. + El document prèviament tancat en una pestanya es pot tornar a obrir utilitzant l'element de menú &Ctrl;&Maj;TFitxerDesfés el tancament de la pestanya. + + Si ja heu obert fitxers abans a l'&okular;, hi podreu tenir accés seleccionant-los al menú FitxerObre recent. + L'&okular; és l'aplicació &kde; predeterminada per als fitxers &PDF; i &PostScript;, llançada en fer clic amb el &BER; sobre un tipus de fitxer en el gestor de fitxers. Per a obrir qualsevol fitxer en què el format sigui compatible amb l'&okular; utilitzeu Obre amb...&okular; des del menú contextual del gestor de fitxers. + Després de tenir obert un fitxer probablement el voldreu llegir i per tant, navegar a través seu. Aneu a la següent secció per a aprendre més sobre això. + + + Navegar + Aquesta secció descriu com navegar a través d'un document a l'&okular;. + Hi ha múltiples maneres de desplaçar-se per l'àrea de visualització. Una d'elles és utilitzant les tecles &Up; i &Down;. També podeu utilitzar la barra de desplaçament, la roda del ratolí o les tecles &PgUp; i &PgDn;. + També podeu utilitzar les tecles de navegació com vim, H per a passar a la part superior de la pàgina anterior, L per a passar a la part superior de la pàgina següent, J per a moure una línia cap avall, i K per a moure una línia cap amunt. + Una altra forma és mantenir premut el &BER; en qualsevol lloc del document mentre arrossegueu el ratolí en la direcció oposada a la que voleu moure. Aquest procediment només funciona si l'eina Navega està activada, la qual podeu seleccionar escollint EinesNavega. + + En veure un document en el Mode de presentació utilitzeu les tecles &Up; i &Down; per a canviar entre les pàgines o diapositives. El nombre i la posició de la diapositiva actual es mostren a la superposició de la cantonada superior dreta de la pantalla. + + Si voleu llegir un document amb diverses pàgines utilitzant la característica de desplaçament automàtic de l'&okular;. Inicieu el desplaçament automàtic amb &Maj;&Down; o &Maj;&Up;. A continuació, utilitzeu aquestes tecles per a fer augmentar o disminuir la velocitat de desplaçament. Podeu iniciar o aturar el desplaçament automàtic temporalment prement la tecla &Maj; -premeu qualsevol tecla per a desactivar aquesta funció-. + Una altra manera de navegar a través d'un document amb diverses pàgines és utilitzar el punter del ratolí. Arrossegueu la pàgina cap amunt o cap avall, continueu arrossegant fins i tot mentre abasteu la part inferior o superior de la pantalla i mireu. Quan creueu la vora d'una pàgina, el cursor del ratolí apareixerà a la part superior o inferior de la pantalla de nou i podeu continuar arrossegant. + La barra lateral que hi ha al costat esquerre de la pantalla permet dues formes més de navegar a través d'un document: + + + Si feu clic sobre una miniatura de pàgina l'àrea de visualització serà portada a aquesta pàgina. + + + Si el document conté una taula de continguts, en fer clic sobre un element contingut a la taula us portarà dins del document a la pàgina enllaçada amb aquest element. + + + Si el document conté capes, podeu controlar quines capes es mostraran marcant o desmarcant els elements a la llista Capes. + + + Si el document conté punts, activeu la vista de Punts i feu clic en ells per a anar a la pàgina associada. Els punts no només es mostren per al document actual, podeu canviar ràpidament als punts de tots els fitxers oberts recentment. + + + Si el document conté anotacions, activeu la vista de Anotacions i feu-hi clic per a veure les anotacions o seleccionar-los amb les tecles &Up; i &Down; i premeu &Intro; per a anar a la pàgina associada. + + + Alguns documents tenen enllaços. En aquest cas podreu fer clic sobre seu i la vista canviarà a la pàgina que enllaça. Si l'enllaç és a una pàgina web o algun altre document s'invocarà el gestor predeterminat del &kde; per a aquest format. Per exemple, en fer clic a un enllaç que apunta a https://www.kde.org s'obrirà la pàgina web al navegador web predeterminat del &kde;. + + Els enllaços interns del document només funcionaran quan s'utilitzi l'eina Navega. + + A més, podeu utilitzar les següents característiques per a moure-us ràpidament a llocs específics en el document: + + + Podeu anar al començament del document utilitzant &Ctrl;Inici o Vés Començament del document . + + + Podeu anar al final del document utilitzant &Ctrl;Fi o Vés Final del document . + + + Podeu anar endavant en el document utilitzant les tecles &Space; o &PgDn;. Per a anar a la pàgina següent del document utilitzeu el botó de la barra d'eines Pàgina següent o Vés Pàgina següent a la barra de menús. + + + Podeu anar enrere en el document utilitzant les tecles &Retro; o &PgUp;. Per a anar a la pàgina anterior del document utilitzeu el botó de la barra d'eines Pàgina anterior o Vés Pàgina anterior a la barra de menús. + + + Podeu tornar a les posicions en el document on heu estat en un ordre cronològic. Considerem &pex; que llegiu la frase Com es mostra a [15], «...», i coneixeu la referència de cerca ràpida [15]. De manera que feu clic sobre seu, i l'&okular; saltarà a la llista de referències. Utilitzant &Alt;&Maj;&Left; o Vés Enrere a la barra de menús tornareu a la posició exacta d'on veniu. + + + Podeu anar cap endavant en el document després dels salts enrere descrits anteriorment, utilitzant &Alt;&Maj;&Right; o Vés Endavant a la barra de menús. + + + Podeu anar a la següent coincidència en la cerca utilitzant les tecles F3 o &Intro; (quan el focus resti sobre el camp de text Cerca) o l'element de menú EditaCerca la següent o tornar a l'anterior coincidència utilitzant les tecles &Maj;F3 o &Maj;&Intro; (quan el focus resti sobre el camp de text Cerca) o l'element de menú Edita Cerca l'anterior . + + + + + Mode de presentació + El mode de presentació representa una altra manera de veure els documents a l'&okular;. Es pot activar a VisualitzaPresentació. Mostra el document pàgina per pàgina. Les pàgines es mostren amb el zoom a la pàgina, això vol dir que és visible tota la pàgina. + + Els documents &PDF; poden fins i tot especificar que sempre s'obrin en el mode de presentació. + + En el mode de presentació, disposareu d'una barra auxiliar situada a la part superior de la pantalla. Només cal moure el cursor del ratolí a la part superior de la pantalla perquè aparegui. + + Mode de presentació a l'&okular; + + + + + + Mode de presentació a l'&okular; + + + + Per a navegar entre les pàgines podeu utilitzar el &BER; (pàgina següent) i el &BDR; (pàgina anterior), la roda del ratolí, les icones de fletxa o la línia d'edició a la barra superior, o les tecles especificades a la secció Navegació. + Utilitzeu el botó Reprodueix/Pausa a la barra de dalt per a començar a reproduir la presentació o fer una pausa, com correspongui. + Podeu sortir del mode de presentació en qualsevol moment prement la tecla &Esc; o fent clic a la icona Surt a la barra superior. + També podeu dibuixar sobre la pàgina actual amb un llapis. Feu clic sobre la icona Commuta el mode de dibuix a la barra superior per a activar o desactivar la possibilitat per a dibuixar en el mode de presentació. Els dibuixos s'esborren automàticament en sortir del mode de presentació. ​​També podeu fer clic sobre la icona Esborra dibuixos per a eliminar els dibuixos en la pàgina actual. + El mode de presentació admet més d'una pantalla en una configuració multimonitor. Amb més d'una pantalla apareixerà un botó nou a la barra superior, amb la icona de la pantalla: es tracta d'una llista desplegable que permetrà moure la presentació a qualsevol de les pantalles disponibles. + El mode de presentació conté algunes opcions de configuració, trobareu la seva descripció en el capítol Configurar l'&okular;. + + + + Cerca inversa entre els editors de &latex; i l'&okular; + + La cerca inversa és una característica molt útil quan esteu escrivint un document de &latex;. Si tot és correcte, podeu fer clic a la finestra de l'&okular; amb el &BER; mentre premeu la tecla &Maj;. Després l'editor de &latex; carregarà el fitxer d'origen i saltarà al paràgraf adequat. + + La cerca inversa no pot funcionar a menys que: + + + El fitxer d'origen s'hagi compilat amb èxit. + L'&okular; conegui quin editor voleu utilitzar. + L'eina Navega ha d'estar activada, el que pot seleccionar mitjançant l'elecció, la qual podeu seleccionar escollint EinesNavega. + + + Amb aquesta característica de l'&okular;, el fer un clic del ratolí mentre premeu &Maj; al document &DVI; o &PDF; resultarà en obrir l'editor amb el document de &latex; corresponent i intentarà anar a la línia corresponent. Recordeu de dir-li a l'&okular; que utilitzi l'editor adequat, a l'element de menú ArranjamentConfigura l'Okular... (sobre la pàgina Editor). + + Per a més detalls sobre la configuració de l'editor, consulteu la secció corresponent d'aquest manual. + + + Configurant l'&okular; + + + + + + Configurant l'editor a l'&okular; + + Configurant l'editor a l'&okular; + + + + + + + Característiques avançades de l'&okular; + + Fitxers incrustats + Si el document actual conté alguns fitxers incrustats, quan l'obriu apareixerà una barra per sobre de la vista de pàgina perquè us adoneu dels fitxers incrustats. + + La barra de fitxers incrustats + + + + + + La barra de fitxers incrustats + + + + En aquest cas, podeu fer clic a l'enllaç en el text de la barra o escollir FitxerFitxers incrustats per a obrir el diàleg de fitxers incrustats. El diàleg us permetrà veure els fitxers incrustats i extreure'ls. + + + Formularis + Si el document actual conté formularis, quan l'obriu apareixerà una barra sobre la vista de pàgina on podreu activar els formularis. + + La barra de formularis + + + + + + La barra de formularis + + + + En aquest cas, podeu fer clic sobre Mostra els formularis a la barra o escolliu VisualitzaMostra els formularis per a introduir dades en els camps del formulari. + + + Signatures + Si el document actual conté signatures, quan l'obriu apareixerà una barra a sobre de la vista de pàgina. Aquest permetrà obrir el plafó Signatures. + + La barra de signatures + + + + + + La barra de signatures + + + + Emprant el plafó Signatures podreu inspeccionar la signatura del document i el seu certificat. + + El plafó de signatures + + + + + + El plafó de signatures + + + + + Aquesta característica només estarà disponible per als documents en &PDF;. Com a mínim haureu d'instal·lar la versió 0.51 de Poppler per a obtenir la majoria de la informació de la signatura, la versió 0.68 per a obtenir la informació de la ubicació/raó de la signatura i la versió 0.73 per a obtenir la informació del certificat de la signatura. + + + + Anotacions + L'&okular; permet revisar i anotar els vostres documents. + + Les anotacions a l'&okular; + + + + + + Les anotacions a l'&okular; + + + + L'&okular; conté dos tipus d'anotacions diferents: + Anotacions de text com Ressaltat groc i Subratllat negre per a fitxers amb text com, &pex;, &PDF;. + Anotacions gràfiques com Nota emergent, Nota en línia, Línia a mà alçada, Marcador fluorescent, Línia recta, Polígon, Segell, Subratllat, El·lipse i Màquina d'escriure per a tots els formats admesos per l'&okular;. + Utilitzant el menú contextual, ja sigui en la vista Anotacions de la barra lateral o en la finestra principal podeu obrir una Nota emergent per a qualsevol tipus d'anotació i afegir o editar els comentaris. + Les anotacions no es limiten únicament als fitxers &PDF;, les podeu utilitzar per a qualsevol format admès per l'&okular;. + L'&okular; conté la característica «arxivat de documents». Aquest és un format específic de l'&okular; per a aportar al document diverses metadades més relacionades amb ell (actualment només anotacions). Podeu desar un «arxiu de document» des del document obert escollint FitxerDesa com aArxiu de document de l'Okular des del selector Filtre. Els documents desats d'aquesta manera obtindran .okular com a extensió del nom de fitxer. Per a obrir un arxiu de document de l'&okular;, només cal obrir-lo amb &okular; com ho faríeu per exemple amb un document &PDF;. + També podeu desar les anotacions directament en els fitxers &PDF;. Podeu utilitzar Fitxer Desa per a desar-les al fitxer actual o Fitxer Desa com a... per a desar-les en un fitxer nou. + + A causa de les limitacions DRM (normalment amb documents &PDF;), afegir, editar o eliminar algunes propietats o eliminar les anotacions podria no ser possible. + + + Qualsevol acció sobre les anotacions (creació i eliminació de les anotacions, editar arbitràriament les propietats de l'anotació, tornar a ubicar les anotacions amb &Ctrl;+arrossega, i editar el contingut del text d'una anotació) es pot desfer o refer utilitzant l'element corresponent al menú Edita. També és possible desfer l'acció prement &Ctrl;Z i tornar-la a fer prement &Ctrl;&Maj;Z. + + Podeu configurar les propietats i l'aspecte predeterminat de cada eina d'anotació. Per a més detalls, consulteu la secció corresponent en aquest manual. + + Afegir anotacions + Per a afegir anotacions al document, haureu d'utilitzar el botó Anotacions ràpides a la barra d'eines principal de l'&okular; o activar la barra d'eines d'anotació. Això es fa seleccionant EinesAnotacions o prement F6. Quan es mostri la barra d'eines d'anotació, només caldrà prémer un dels botons o utilitzar les dreceres de teclat (tecles des d'1 fins a 9) per a iniciar la construcció d'aquesta anotació. + La barra d'eines d'anotació ajuda a fer anotacions amb dibuixos, formes i missatges de text. Podeu utilitzar la barra d'eines d'anotació per a marcar un document (&pex;, afegir línies, el·lipses, polígons, segells, ressaltats, subratllats, &etc;) La següent taula descriu exactament el que fa el conjunt de botons predeterminat de la barra d'eines d'anotació. + + + + + Botó + Nom de l'eina + Descripció + + + + + + + + + + + + + + + Marcador fluorescent + + + Per a ressaltar el text en el document amb una mica de color de fons determinat. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar l'inici del fragment de text ressaltat, després arrossegueu per a ressaltar-lo. + És possible definir el Tipus (Ressaltat, Giragonses, Subratllat o Barrat), el Color i l'Opacitat per al ressaltador. Simplement feu clic dret sobre el text ressaltat i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Subratllat + + + Per a subratllar el text. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar l'inici del fragment de text subratllat, després arrossegueu per a subratllar-lo. + És possible definir el Tipus (Ressaltat, Giragonses, Subratllat o Barrat), el Color i l'Opacitat per al subratllat. Simplement feu clic dret sobre el text subratllat i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Giragonses + + + Per a subratllar algun text amb una línia ondulada. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar l'inici del fragment de text subratllat, després arrossegueu per a subratllar-lo. + És possible definir el Tipus (Ressaltat, Giragonses, Subratllat o Barrat), el Color i l'Opacitat per al subratllat. Simplement feu clic dret sobre el text subratllat i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Barrat + + + Per a barrar algun text. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar l'inici del fragment de text subratllat, després arrossegueu per a subratllar-lo. + És possible definir el Tipus (Ressaltat, Giragonses, Subratllat o Barrat), el Color i l'Opacitat per al subratllat. Simplement feu clic dret sobre el text subratllat i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Màquina d'escriure + + + La màquina d'escriure té lletres opaques sobre un fons transparent, de manera que és útil per a omplir formularis no interactius. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar-la a la cantonada superior esquerra de la nota, després arrossegueu per a col·locar-la a la part inferior dreta. Introduïu el text de la nota, després feu clic a D'acord per a desar la nota, Cancel·la per a cancel·lar la nota introduïda o Neteja per a esborrar la nota. + És possible definir el Tipus de lletra i el Color del text per al text. Simplement feu clic dret sobre el text escrit i seleccioneu l'element del menú Propietats. + + + + + + + + + + + + + + Nota en línia + + + Per a dibuixar una nota en línia. La nota es mostrarà a la línia immediatament. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar-la a la cantonada superior esquerra de la nota, després arrossegueu per a col·locar-la a la part inferior dreta. Introduïu el text de la nota, després feu clic a D'acord per a desar la nota, Cancel·la per a cancel·lar la nota introduïda o Neteja per a esborrar la nota. + És possible definir el Color, l'Opacitat, el Tipus de lletra, l'Alineació i l'Amplada de la vora per a la nota. Simplement feu clic dret sobre la icona de la nota creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Nota emergent + + + Per a dibuixar una nota amb múltiples línies. La nota es podrà veure fent doble clic sobre una icona en el document. + Feu clic sobre el botó d'eina, feu clic sobre el lloc del document on s'ha d'afegir la nota emergent. Introduïu el text de la nota emergent i feu clic al botó Tanca aquesta nota a la cantonada superior dreta de la finestra emergent. + És possible definir el Color, l'Opacitat i la Icona de la nota. Simplement feu clic amb dret sobre la icona de la nota creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Línia a mà alçada + + + Per a dibuixar línies de forma lliure. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar l'inici de la línia, després arrossegueu per a dibuixar la línia. + És possible definir el Color, l'Opacitat i l'Amplada per a la línia. Simplement feu clic dret sobre la línia creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Fletxa (llista desplegable) + + + Per a marcar amb una fletxa. + Feu clic sobre el botó d'eina, feu clic amb el &BER; per a col·locar el punt inicial de la línia, després arrossegueu per a col·locar el punt final de la línia que serà i feu clic una vegada més. + És possible definir el Color i l'Opacitat, l'Amplada, el Començament de línia, el Final de línia, la Longitud de la línia principal i la Longitud de les extensions de la línia principal per a la línia. Simplement feu clic dret sobre la línia creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Línia recta (llista desplegable) + + + Per a marcar amb una línia. + Feu clic sobre el botó d'eina, feu clic amb el &BER; per a col·locar el punt inicial de la línia, després arrossegueu per a col·locar el punt final de la línia que serà i feu clic una vegada més. + És possible definir el Color i l'Opacitat, l'Amplada, el Començament de línia, el Final de línia, la Longitud de la línia principal i la Longitud de les extensions de la línia principal per a la línia. Simplement feu clic dret sobre la línia creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Rectangle (llista desplegable) + + + Per a dibuixar un rectangle al voltant d'alguna àrea escollida. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar la cantonada superior esquerra del rectangle, després arrossegueu per a col·locar la cantonada inferior dreta. + És possible definir el Tipus (Rectangle o El·lipse), el Color, l'Opacitat, l'Emplenat de forma (i el seu color) i l'Amplada per a la vora. Simplement feu clic dret sobre la vora creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + El·lipse (llista desplegable) + + + Per a dibuixar una el·lipse o un rectangle al voltant d'alguna àrea escollida. + Feu clic sobre el botó d'eina, feu clic amb el &BER; i manteniu-lo premut per a col·locar la cantonada superior esquerra de l'el·lipse rectangular circumscrita, després arrossegueu per a col·locar la cantonada inferior dreta. + És possible definir el Tipus (Rectangle o El·lipse), el Color, l'Opacitat, l'Emplenat de forma (i el seu color) i l'Amplada per a la vora. Simplement feu clic dret sobre la vora creada i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Polígon (llista desplegable) + + + Per a dibuixar una figura plana tancada de tres o més segments. La nota corresponent es pot veure fent doble clic a l'interior del polígon. + Feu clic sobre el botó d'eina, feu clic amb el &BER; per a col·locar el primer vèrtex del polígon, després arrossegueu per a col·locar el segon vèrtex. Continueu fins que dibuixeu tot el polígon fins al primer vèrtex. Feu clic dues vegades si voleu afegir alguna nota al polígon. Introduïu el text de la nota, després feu clic a D'acord per a desar la nota, Cancel·la per a cancel·lar la nota introduïda o Neteja per a esborrar la nota. + És possible definir el Color i l'Opacitat, l'Emplenat de forma (i el seu color) i l'Amplada per al polígon. Simplement feu clic dret sobre el polígon creat i seleccioneu l'element de menú Propietats. + + + + + + + + + + + + + + Segell + + + Per a marcar el text o la imatge amb algun segell predefinit. + Feu clic sobre el botó d'eina per a triar el segell des de la llista desplegable, després feu clic amb el &BER; per a col·locar el segell. + Un sol clic col·loca un segell quadrat (útil per a les icones). Per a afegir un segell rectangular podeu fer clic amb el &BER; i mantenir-lo premut per a col·locar el punt a la part superior esquerra, a continuació, arrossegueu per a col·locar-lo a la part inferior dreta. + És possible definir l'Opacitat i el Símbol de segell per al segell. Simplement feu clic dret sobre la icona del segell creat i seleccioneu l'element de menú Propietats. + + Aquesta característica és experimental. Els segells personalitzats inserits als documents &PDF; no són visibles en els lectors de &PDF; que no siguin l'&okular;. + + + + + + + Aquestes són les anotacions predeterminades que proporciona l'&okular;. Emprant la pàgina d'Anotacions del diàleg de configuració, podeu afegir les vostres pròpies anotacions, com ara segells personalitzats, marcatge de text o una forma geomètrica amb color interior per a destacar les regions, &etc; + + És possible afegir codi en &latex; dins del text de les anotacions. Afegiu $$codi$$ al text de l'anotació, on el codi serà qualsevol equació de &latex; vàlida, i seguiu les instruccions a la pantalla per a fer que es renderitzi mitjançant una distribució de &latex; instal·lada al sistema. + + És possible configurar les actuals opcions d'eina utilitzant la barra d'eines d'anotació. La següent taula descriu exactament el que fa el conjunt predeterminat de botons de configuració de la barra d'eines d'anotació. + + + + + Botó + Nom de l'opció + Descripció + + + + + + + + + + + + + + + Amplada de la línia + + + Feu clic sobre el botó d'eina per a triar l'amplada des de la llista desplegable. + + + + + + + + + + / + + + + + + + Color de l'anotació + + + Feu clic sobre el botó d'eina per a triar el color del text o la vora de l'anotació. Podeu triar un dels colors predefinits o fer clic sobre l'element Color personalitzat... per a obrir el diàleg de selecció del color. + + + + + + + + + + + + + + Color per a l'emplenat de l'anotació + + + Feu clic sobre el botó d'eina per a triar el color per a l'emplenat de l'anotació. Podeu triar un dels colors predefinits o fer clic sobre l'element Color personalitzat... per a obrir el diàleg de selecció del color. + + + + + + + + + + + + + + Opacitat de l'anotació + + + Feu clic sobre el botó d'eina per a triar el nivell d'opacitat des de la llista desplegable (el 100% és per a les anotacions opaques). + + + + + + + + + + + + + + Tipus de lletra de l'anotació + + + Feu clic sobre el botó d'eina per a obrir el diàleg de selecció del tipus de lletra. + + + + + + + + + + + + + + Configuració avançada per a l'actual eina d'anotació + + + Feu clic sobre el botó d'eina per a obrir el diàleg de configuració general per a l'anotació. + + + + + + A la barra d'eines predeterminada hi ha tres botons d'utilitat addicionals. + + + + + Botó + Descripció + + + + + + + + + + + + + + + Afegiu l'anotació actual al menú Anotacions ràpides a la barra d'eines principal. + + Podeu utilitzar les dreceres predeterminades des de &Alt;9 a &Alt;0 per a seleccionar les accions d'anotació ràpida en qualsevol moment que vulgueu, fins i tot amb la barra d'eines d'anotació oculta. + + + + + + + + + + + + + + + Quan està marcada, es mantindrà activa l'eina d'anotació actual després del seu ús. + + + + + + + + + + + + + + Oculta la barra d'eines d'anotació. + + + + + + En prémer &Maj;, podreu restringir l'angle de les anotacions de línia i polígon a passos de 15°, i la relació de les anotacions de forma (&pex;, Rectangle, El·lipse) a 1:1. També obtindreu un botó a la barra d'eines des de Configura les barres d'eines.... + El contingut del menú Anotacions ràpides es pot configurar utilitzant la pàgina Anotacions del diàleg de configuració de l'&okular;. Aquesta pàgina es pot obrir fent clic al botó Anotacions ràpides i després escollint Configura les anotacions... des del menú emergent. + + Activar la barra d'eines d'anotació farà canviar al mode Navega. + + Podeu aturar la construcció en qualsevol moment prement de nou el botó de l'anotació que esteu construint, o prement la tecla &Esc;. + La nova anotació construïda tindrà com a autor l'establert a la pàgina Anotacions en el diàleg de configuració de l'&okular;. La pàgina Anotacions també es pot utilitzar per a configurar el contingut de la barra d'eines d'anotació. + + + Eliminar anotacions + Per a eliminar una anotació, sols feu clic sobre seu amb el &BDR; i seleccioneu Suprimeix o seleccioneu una anotació utilitzant el &BER; i premeu la tecla ∇. + En eliminar l'anotació, es tancarà la seva finestra si estava oberta. + + Aquesta opció no es pot activar perquè el document no permet eliminar anotacions. + + + + Editar anotacions + Per a editar una anotació, feu clic amb el &BDR; i seleccioneu Propietats. Apareixerà un diàleg amb la configuració general de l'anotació (com el color i l'opacitat, autor, &etc;) i la configuració específica per a aquest tipus d'anotació. + + El diàleg de propietats de l'anotació + + + + + + El diàleg de propietats de l'anotació + + + + Per a moure una anotació, manteniu premuda la tecla &Ctrl;, moveu el punter del ratolí sobre seu i després comenceu-la a arrossegar amb el &BER;. + Si feu clic amb el &BER; en una anotació, serà seleccionada. Les nanses de redimensionar apareixeran al rectangle de selecció. Quan el cursor es mou sobre una de les 8 nanses de redimensionar que hi ha a les cantonades o a les vores, la forma del cursor canviarà per a indicar el mode de redimensionar. Feu clic a qualsevol altre lloc de l'anotació per a moure-la. Prement &Esc; o fent clic a una àrea fora de l'anotació es cancel·larà una selecció. + El canvi de mida només és aplicable als tipus d'anotació Nota inclosa, Màquina d'escriure, Segell i El·lipse. + + + Depenent dels permisos del document (en general amb documents &PDF;), algunes opcions poden restar desactivades. + + + + + Gestionar punts + L'&okular; conté un sistema de punts molt flexible. Desa la posició sobre la pàgina en un punt i permet definir més d'un punt per pàgina. + Per a gestionar els punts a l'&okular; podeu utilitzar la vista Punts de la Barra lateral, el menú de Punts o el menú contextual de la vista del document (feu clic amb el &BDR; per a obrir-lo). + + La vista Punts + Per a obrir la vista Punts feu clic sobre la pestanya Punts a la part superior de la Barra lateral. Si no es mostra la Barra lateral, feu clic sobre el botó Mostra la barra lateral que hi ha a la barra d'eines o en l'element de menú F7 ArranjamentMostra la barra lateral per a fer-lo visible. + + El menú contextual de la vista punts + + + + + + El menú contextual de la vista punts + + + + Podeu utilitzar la barra de filtres a la part superior de la vista Punts per a filtrar el contingut de la subfinestra de la llista de punts d'acord amb el text al quadre. + La subfinestra de llista permet veure la llista de punts d'un mode en arbre: cada document a la llista pot ser desplegat o plegat fent clic sobre la icona < o v al seu costat. + Feu clic sobre la icona sota la llista per a mostrar només aquells punts del document actual. + El menú que apareix en fer clic dret en un element d'un document, pot obrir el document, canviar el nom o suprimir l'element de la llista. Recordeu que l'eliminació d'un element del document condueix a l'eliminació de tots els punts en el document en qüestió. + El menú que apareix en fer clic dret en un punt individual us permetrà anar al punt, canviar-ne el nom o eliminar-lo. + El menú del clic dret als elements de la taula de contingut es pot utilitzar per a crear punts o anar al punt següent o anterior. + + + + + Opcions de la línia d'ordres + Tot i que és més probable que inicieu l'&okular; des del menú del &kde; o des d'una icona de l'escriptori, també es pot obrir a la línia d'ordres d'una finestra de terminal. Hi ha algunes opcions d'utilitat que estaran disponibles quan ho feu. + + Especificar un fitxer + Especificant el camí i el nom d'un fitxer en particular l'usuari podrà fer que l'&okular; obri el fitxer immediatament després d'iniciar-se. Aquesta opció es pot semblar al següent: + % okular + + + Per a documents &PDF;, el nom es pot indicar com nom_document#nom_destinació on nom_destinació serà una destinació concreta amb nom incrustada en el document. + + + + D'altres opcions a la línia d'ordres + Hi ha disponibles les següents opcions d'ajuda de la línia d'ordres + + + okular + Obre una pàgina amb el número indicat al document. okular + + + okular + Inicia el document en mode presentació. + + + okular + Inicia amb el diàleg d'impressió. + + + okular + Inicia amb el diàleg d'impressió i surt després d'imprimir. + + + okular + Control d'«Instància única». + + + okular + Permet prevenir l'elevació de la finestra de l'&okular; després de l'inici. + + + okular + Intenta trobar i ressaltar una cadena determinada en el document. Només funciona si només es proporciona un document com a argument de l'ordre okular. + + + + + + Ajustar la finestra a la pàgina + La característica d'ajustar la finestra a la pàgina canvia la mida de la finestra, de manera que és exactament de la mateixa mida que la pàgina en el factor de zoom actual. Si la pàgina no s'ajusta completament a la pantalla, la finestra s'engrandirà de manera que mostri la major part possible de la pàgina. + Es pot accedir a aquesta característica usant la drecera de teclat &Ctrl;J. + + + + + La barra de menús + + + El menú Fitxer + + + + &Ctrl;O Fitxer Obre... + + + Obre un fitxer admès o arxiu de document de l'&okular;. Si ja hi ha un fitxer obert, es tancarà. Per a obtenir més informació, vegeu la secció Obrir fitxers. + + + + + + Fitxer Obre recent + + + Obre un fitxer que es va utilitzar anteriorment des d'un submenú. Si ja hi ha un fitxer obert, es tancarà. Per a obtenir més informació, vegeu la secció sobre Obrir fitxers. + + + + + + Fitxer Importa un PostScript com a &PDF;... + + + Obre un fitxer &PostScript; i el converteix a &PDF;. + + + + + + &Ctrl;&Maj;T Fitxer Desfés el tancament de la pestanya + + + Torna a obrir l'últim document tancat. Aquesta acció només estarà activa si heu tancat algun document en una pestanya durant la sessió actual. + + + + + + Fitxer Obre la carpeta contenidora + + + Obre la carpeta que conté el document actual en el vostre gestor de fitxers preferit. Aquesta acció és especialment útil en el cas que hàgiu descarregat un fitxer &PDF; d'Internet que s'obrirà en l'&okular;. La ubicació d'aquest fitxer pot no ser clara o fàcil de trobar sense aquesta característica. + + + + + + &Ctrl;S Fitxer Desa + + + Desa el document incloent-hi tots els canvis (anotacions, format del contingut, &etc;) -sempre que el dorsal del document permeti desar els canvis-. Si el dorsal no ho admet, l'usuari tindrà l'opció de descartar els canvis o desar-los juntament amb el document en un arxiu de document de l'&okular;. + + + + + + &Ctrl;&Maj;S Fitxer Desa com a... + + + Desa el document sota un altre nom incloent-hi tots els canvis (anotacions, format del contingut, &etc;) -sempre que el dorsal del document permeti desar els canvis-. Si el dorsal no ho admet, l'usuari tindrà l'opció de descartar els canvis o desar-los juntament amb el document en un arxiu de document de l'&okular;. + + Cal tenir present que, per la forma en què això es du a terme, fins i tot si no hi ha canvis al fitxer, el nou fitxer no té per què ser una còpia exacta bit a bit del fitxer original (&pex;, pot tenir un codi SHA-1 diferent, &etc;) + + + + + + + F5 Fitxer Recarrega + + + Torna a carregar el fitxer actualment obert. + + + + + + &Ctrl;P Fitxer Imprimeix... + + + Imprimeix el document que es mostra. Cal tenir en compte que l'&okular; té algunes opcions específiques per a imprimir els &PDF;, les quals estan disponibles prement el botó Opcions +> +> i seleccionant Opcions del &PDF;. Utilitzeu aquestes opcions per a imprimir les vostres anotacions o configurar el mode de rasterització si teniu problemes amb imprimir símbols o necessiteu canviar el mode de l'escala. + + Les opcions del mode de l'escala només estan disponibles quan marqueu l'opció Força la rasterització. + + + + + + + Fitxer Vista prèvia d'impressió... + + + Mostra una vista prèvia de com quedarà el document que es mostra actualment imprès amb les opcions predeterminades. + + + + + + &Alt;Retorn Fitxer Propietats + + + Mostra informació bàsica sobre el document, com el títol, autor, data de creació, i detalls sobre els tipus de lletra utilitzats. La informació disponible dependrà del tipus de document. + + Pareu atenció a la informació sobre la substitució de fonts del tipus de lletra a la pestanya Tipus de lletra del diàleg Propietats. Molts dels problemes amb la representació dels tipus de lletra es poden resoldre instal·lant els tipus de lletra substituïts. + + + + + + Fitxer Fitxers incrustats... + + + Mostra els fitxers incrustats en el document, si el document en conté cap. Per a obtenir més informació, vegeu la secció sobre Fitxers incrustats. + + + + + + Fitxer Exporta com a... + + + Aquest element conté els formats d'exportació als quals es pot exportar el document actual. La primera entrada és per a tot tipus de documents i sempre és Text net.... + La segona entrada és Arxiu del document, la qual permet desar el document amb les vostres anotacions en un format d'arxiu específic de l'&okular;. D'aquesta manera, serà possible compartir amb facilitat els documents originals i les vostres anotacions amb altres usuaris de l'&okular; o treballar en col·laboració amb ells. + + + + + + Fitxer Comparteix + + + Aquest element conté els serveis que es poden utilitzar per a compartir el document actual amb altres persones o enviar-lo als vostres dispositius. Les entrades d'aquest submenú són controlades pel sistema. Depenen del format del document i dels connectors de KPurpose que hi ha instal·lats. + + + + + + &Ctrl;Q Fitxer Surt + + + Tanca l'&okular;. + + + + + + + El menú Edita + + + + + &Ctrl;Z Edita Desfés + + + Desfà l'última ordre d'edició de l'anotació (creació i eliminació de les anotacions, editar arbitràriament les propietats de l'anotació, tornar a ubicar les anotacions amb &Ctrl;+arrossega, i editar el contingut del text d'una anotació). + + + + + + &Ctrl;&Maj;Z Edita Refés + + + Refà l'últim pas desfet en editar les anotacions. + + + + + + + + &Ctrl;C Edita Copia + + + Copia el text seleccionat en el mode Selecció de text al porta-retalls. + + + + + + + + &Ctrl;A Edita Selecciona-ho tot + + + Selecciona tot el text (si el document en proporciona). Això només funciona en el mode Selecció de text. + + + + + + + + Eines Selecciona tot el text de la pàgina actual + + + Selecciona tot el text (si el document en proporciona) de la pàgina actual. + + + + + + + + &Ctrl;F Edita Cerca... + + + Mostra la barra de cerca a la part inferior de l'àrea de visualització que permet cercar una cadena en el document. + + + + + + F3 Edita Cerca la següent + + + Intenta trobar l'anterior cadena cercada al document. + + + + + + &Maj;F3 Edita Cerca l'anterior + + + Va a l'ocurrència anterior de la cadena de cerca en el document. + + + + + + + El menú Visualitza + + + + &Ctrl;&Maj;P Visualitza Presentació + + + Activa el mode de presentació. Per a obtenir més informació, vegeu la secció sobre el Mode de presentació. + + + + + &Ctrl;&Maj; F Visualitza Mode de pantalla completa + + + Activa el mode de pantalla completa. Cal tenir en compte que el mode de pantalla completa és diferent del mode de presentació i l'única peculiaritat del mode de pantalla completa que té és que oculta la decoració de la finestra, la barra de menús i barra d'eines. + + + + + &Ctrl;+ VisualitzaApropa + + + Augmenta l'ampliació de la vista del document. + + + + + + &Ctrl;- Visualitza Allunya + + + Disminueix l'ampliació de la vista del document. + + + + + Visualitza Zoom al 100% + + + Fa zoom sobre la imatge del document fins la mida real tal com es recomana als paràmetres del document. + + + + + Visualitza Ajusta a l'amplada de pàgina + + + Canvia l'ampliació de la vista del document a un valor fent que l'amplada de les pàgines sigui igual que la vista del document. + + + + + Visualitza Ajusta a la pàgina + + + Canvia l'ampliació de la vista del document a un valor fent visible una pàgina sencera. + + + + + Visualitza Encaixat automàtic + + + Canvia l'ampliació de la vista del document a un valor que, depenent de la relació de mida entre la pàgina i l'àrea de la vista, de forma automàtica o bé fa les pàgines d'una amplada igual que l'amplada de la vista del document (com ajusta a l'amplada), l'alçada de les pàgines igual que l'alçada de la vista del document (com ajusta a l'alçada), o tota la pàgina visible (com ajust de pàgina). + + + + + Visualitza Mode de vista + + + Aquest submenú permet escollir el mode de vista per a les pàgines. Les opcions possibles són: Pàgina individual (només una pàgina per a cada fila), Pàgines oposades (dues pàgines per fila, en un llibre d'estil), Pàgines oposades (Centra la primera pàgina) i Vista general (el nombre de columnes és l'especificat en la configuració de &okular;). + A més, podreu habilitar el mode Continu. En aquest mode, es mostraran totes les pàgines del document i podreu desplaçar-vos suaument per elles. En cas contrari, només es mostrarà una pàgina (o una fila de pàgines) alhora. + + + + + Visualitza Orientació + + + Aquest submenú permet canviar l'orientació de les pàgines del document. + + La rotació s'aplica a l'orientació de cada pàgina. + + Podeu seleccionar Orientació original per a restaurar l'orientació del document, descartant totes les rotacions aplicades manualment. + + + + + Visualitza Retalla la vista + + + Aquest submenú permet eliminar la vora blanca de les pàgines en visualitzar-les (element Retalla els marges) o retallar la vista a la selecció (element Retalla a la selecció). + El mode retalla a la selecció permet dibuixar una selecció sobre la pàgina renderitzada per tal de definir un quadre delimitador visible que s'aplicarà a totes les pàgines del document. Realitzant la selecció d'un petit quadre delimitador de retall s'imposarà la mida de dimensions mínimes (20% com a percentatge de la mida total de la pàgina). + El mode retalla els marges és persistent després de reiniciar l'&okular;. El mode retalla a la selecció s'oblida després de reiniciar l'&okular;. + En canviar l'&okular; des del mode retalla els marges al mode retalla a la selecció, la vista saltarà del mode retalla els marges a la interacció d'un quadre delimitador per a la selecció. + El mode de retall es pot desactivar seleccionant el mateix element del menú una altra vegada. + + + + + Visualitza Mostra/Oculta els formularis + + + Mostra o oculta la visualització dels camps de formulari del document. + + Aquest element de menú només s'activa si el document actual conté camps de formulari. + + + + + + + + + El menú Vés + + + + Vés Pàgina anterior + + + Visualitza la pàgina anterior del document. + + + + + Vés Pàgina següent + + + Visualitza la pàgina següent del document. + + + + + &Ctrl;&Home; Vés Començament del document + + + Va al començament del document. + + + + + &Ctrl;&End; Vés Final del document + + + Va al final del document. + + + + + &Alt;&Maj;&Left; Vés Enrere + + + Torna a la vista anterior del document. + + + + + &Alt;&Maj;&Right; Vés Endavant + + + Avança a la següent vista del document. Això només funciona si heu anat enrere abans. + + + + + &Ctrl;G Vés Vés a... + + + Obre un diàleg que permet anar a qualsevol pàgina del document. + + + + + + + El menú Punts + + + + &Ctrl;B Punts Afegeix/Elimina un punt + + + Afegeix o elimina un punt per a la posició actual. + + + + + Punts Reanomena el punt + + + Canvia el nom d'un punt per a la posició actual. + + + + + Punts Punt anterior + + + Va al punt anterior, o no fa res si no hi ha punts anteriors a l'actual. + + + + + Punts Punt següent + + + Va al punt següent, o no fa res si no hi ha punts després de l'actual. + + + + + Punts Sense punts + + + Es tracta d'una acció sempre desactivada que apareix en aquest menú només si el document actual no conté punts. En cas contrari aquí es mostrarà una llista de tots els punts. En fer clic sobre aquests punts se us permetrà anar directament a la posició associada. + + + + + + + El menú Eines + + + + &Ctrl;1 Eines Navega + + + El ratolí tindrà el seu comportament normal, &BER; per a arrossegar el document i seguir els enllaços i el &BDR; per a afegir punts i ajustar l'amplada. + + + + + &Ctrl;2 Eines Zoom + + + El ratolí funcionarà com una eina de zoom. En fer clic amb el &BER; i arrossegant el zoom de la vista a l'àrea seleccionada, en fer clic amb el &BDR; restaurarà el document de nou al zoom anterior. + + + + + &Ctrl;3 Eines Selecció d'àrea + + + El ratolí funcionarà com una eina de selecció d'àrea rectangular. En aquest mode fent clic amb el &BER; i arrossegant es dibuixarà una casella de selecció i proporcionarà l'opció de copiar el contingut seleccionat al porta-retalls, parlar el text seleccionat o transformar l'àrea seleccionada en una imatge i desant-la en un fitxer. + + + + + &Ctrl;4 Eines Selecció de text + + + El ratolí funcionarà com una eina de selecció de text. En aquest mode fent clic amb el &BER; i arrossegant es donarà l'opció de seleccionar el text del document. Després, només cal fer clic amb el &BDR; per a copiar-lo al porta-retalls o parlar la selecció. + + + + + &Ctrl;5 Eines Selecció de taula + + + Dibuixa un rectangle al voltant del text per a la taula, a continuació, utilitzeu el clic amb el &BER; per a dividir el bloc de text en files i columnes. Un clic del &BER; sobre una línia existent eliminarà i fusionarà les files o columnes adjacents. + + + + + &Ctrl;6 Eines Ampliador + + + Activa el mode ampliador per al punter del ratolí. Manteniu premut el &BER; per a activar el giny ampliador, moveu el punter per a moure-us a través del document. L'ampliador escala de cada píxel en el document a 10 píxels al giny ampliador. + + + + + F6 Eines Anotacions + + + Obre la barra d'eines d'anotació. La barra d'eines d'anotació permet afegir anotacions en el document que esteu llegint. Per a obtenir més informació, vegeu la secció sobre Anotacions. + + + + + Eines Pronuncia tot el document + + + Eines Pronuncia la pàgina actual + + + Eines Atura la pronunciació + + + Eines Atura/reprèn la pronunciació + + + Aquests elements permeten parlar tot el document o només la pàgina actual i aturar la parla utilitzant el servei de veu del sistema. Aquest servei és proveït per una biblioteca de les &Qt;, la qual embolcalla el distribuïdor de veu en &Linux; i els sistemes de veu nadius en les altres plataformes. És possible triar la veu actual mitjançant la pàgina de configuració Accessibilitat de l'&okular;. + Les accions de Parla... només estan disponibles si està disponible en el sistema el sistema de veu. + + + + + + + Els menús Arranjament i Ajuda + A part dels menús Arranjament i Ajuda comuns al &kde; que es descriuen en el capítol Menús comuns de la documentació Fonaments del &kde;, l'&okular; té aquestes entrades de menú específiques de l'aplicació: + + + + F7 Arranjament Mostra la barra lateral + + + Mostra o oculta la barra lateral. + + + + + Arranjament Mostra la barra de pàgines + + + Canvia mostrar o ocultar la barra de pàgina a la part inferior de l'àrea del document i oculta per a estalviar espai vertical a la finestra de l'&okular;. Recordeu que els números de pàgina es mostraran de totes maneres a la barra d'eines predeterminada. + + + + + Arranjament Configura els dorsals... + + + Obre la finestra Configuració del dorsal. + + + + + + + + Configurar els dorsals de l'&okular; + Podeu configurar els dorsals de l'&okular; escollint Arranjament Configura els dorsals.... Actualment, les opcions de configuració sols es proporcionen per als dorsals EPub, &PostScript;, FictionBook, Txt, Text en OpenDocument i &PDF;. + + El diàleg de configuració dels dorsals + + + + + + El diàleg de configuració dels dorsals + + + + Utilitzant les pàgines de configuració per als dorsals EPub, FictionBook, Mobipocket, Markdown, Txt i Text en OpenDocument podreu definir el tipus de lletra per a representar els documents en els formats corresponents. El botó Tria... en aquestes pàgines obre la finestra de configuració estàndard del &kde; per a tipus de lletres. Per als detalls, vegeu la documentació Fonaments del &kde;. + La descripció de les pàgines de configuració per als dorsals Markdown, &PostScript; i &PDF; la trobareu a continuació. + + Configuració del dorsal per a Markdown + Podeu configurar el renderitzat del dorsal Markdown de l'&okular; basat en Discount escollint Markdown des de la llista a la part esquerra del diàleg de configuració. Una opció configurable addicional és la següent. + + + + + Activa la formatació SmartyPants + + + Quan es marca aquesta opció, l'&okular; permetrà processar la formatació SmartyPants. Aquest format pot ser problemàtic en els textos tècnics a causa de substitucions no desitjades (&pex;, substitueix (C) amb un símbol de copyright). De manera predeterminada aquesta opció està marcada. + + + + + + + Configuració del dorsal per a &PostScript; + Podeu configurar el renderitzat del dorsal &PostScript; de l'&okular; basat en Ghostscript escollint Ghostscript des de la llista a la part esquerra del diàleg de configuració. L'única opció configurable és la següent. + + + + + Utilitza els tipus de lletra de la plataforma + + + Aquesta opció determina si el Ghostscript ha de poder utilitzar els tipus de lletra de la plataforma, si està sense marcar, només podrà utilitzar els tipus de lletra incrustats en el document. De manera predeterminada es troba marcada. + + + + + + + Configuració del dorsal per a &PDF; + Podeu configurar el renderitzat del dorsal &PDF; de l'&okular; basat en Poppler escollint &PDF; des de la llista a la part esquerra del diàleg de configuració. L'única opció configurable és la següent. + + + + + Millora les línies fines + + + El dibuix de les línies a l'&okular; està implementat en dos passos: generació del traçat de retall i omplert d'aquest traçat de retall. Quan la línia en el document original sigui inferior a un píxel aquest pas de la implementació podria causar problemes. Per a aquestes línies, el traçat de retall s'emplena amb el color de farciment que dependrà del gruix de la part de línia dins de l'àrea de tall. Si la part de la línia dins de l'àrea de tall es fa molt petita, la diferència entre la forma i el color de fons esdevindrà massa baixa perquè la línia es pugui reconèixer. Llavors les graelles d'aquestes línies es veuran poc agraciades. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Línia fina (vermella), el seu traçat de tall (línia discontínua) i límits dels píxels negres (línies negres contínues) + Mostra la línia fina amb un contrast baix + + + + + Per a millorar l'aspecte de les línies fines, l'&okular; implementa dues opcions. + La primera opció és Solid. Amb aquesta opció, l'&okular; ajusta el camí de retall i la posició de la línia de manera que el camí de retall i la línia estiguin en el mateix límit del píxel, &ead;, l'&okular; allargarà les línies fines a un píxel en el dispositiu de sortida. Aquest mode és similar a Millora les línies fines Adobe Reader. Si es tria aquesta opció, les línies fines sempre s'allargaran. + + + + + + + + Línia fina amb la millora Solid + + + Línia fina amb la millora Solid + + + + + La segona opció és Forma. Amb aquesta opció el camí del retall i la línia s'ajustaran també al límit del píxel, però la intensitat de la línia es corregirà en funció de la seva amplada. + + + + + + + + Línia fina amb la millora Forma + + + Línia fina amb la millora Forma + + + + + De manera predeterminada, les línies fines no es veuen millorades (opció No). + + + + + + + + Configurar l'&okular; + + Configuració general + Podeu configurar l'&okular; escollint Arranjament Configura l'&okular;.... El diàleg de configuració es divideix en sis seccions. En aquest capítol es descriuen detalladament les opcions disponibles. + + + General + + + Accessibilitat + + + Rendiment + + + Presentació + + + Anotacions + + + Editor + + + + El diàleg de configuració + + + + + + El diàleg de configuració + + + + Depenent dels dorsals instal·lats, l'element de menú Arranjament Configura els dorsals... podria estar activat. Aquest diàleg de configuració en particular conté les configuracions dels dorsals que es poden configurar. + + + General + + + Usa un desplaçament suau + + Si mostrar transicions animades en desplaçar amb la roda del ratolí i el teclat. + + + + Mostra les barres de desplaçament + + Indica si mostrar les barres de desplaçament per a la vista del document. + + + + Enllaça les miniatures a la pàgina + + Indica si la vista de miniatures sempre ha de mostrar la pàgina actual o no. + + + + Mostra els consells i els missatges d'informació + + Indica si es mostraran alguns missatges informatius durant l'inici, càrrega de fitxers, &etc; + + + + Si està disponible, mostra el títol del document en la barra de títol + + Indica si es mostrarà el títol del document a la barra de títol de la finestra de l'&okular;. Si no hi ha metadades per al títol en el document o aquest element està sense marcar, l'&okular; mostrarà el nom de fitxer del document. + + + + Quan no mostrar el títol del document + + Podeu escollir qualsevol de les dues opcions, Mostra sols el nom de fitxer o Mostra el camí complet del fitxer. + + + + Usa un color de fons personalitzat + + Permet triar el color del fons del document (el color que hi ha al voltant de la pàgina que es mostra). De manera predeterminada, s'utilitzarà el color del kit d'eines de les &Qt; quan aquesta opció estigui desmarcada. + + + + Obre els fitxers nous en pestanyes + + Per a obrir els documents nous en pestanyes. De manera predeterminada, les pestanyes restaran desactivades. + Les dreceres predeterminades per a canviar entre les pestanyes són &Ctrl;. (Pestanya següent) i &Ctrl;, (Pestanya anterior). + + + + Commuta a la pestanya existent si el fitxer ja està obert + + Si l'&okular; hauria de canviar a una pestanya si el fitxer ja està obert en lloc d'obrir una pestanya nova. De manera predeterminada, aquesta opció està inhabilitada. Només es podrà habilitar si s'habilita Obre els fitxers nous en pestanyes. + + + + Obeeix les limitacions DRM + + Indica si l'&okular; haurà d'obeir les restriccions DRM (Digital Rights Management). Les limitacions DRM s'utilitzen per a fer que sigui impossible realitzar certes accions amb els documents &PDF;, com copiar el contingut al porta-retalls. Cal tenir en compte que en algunes configuracions de l'&okular;, aquesta opció no està disponible. + + + + Actualitza el document en canviar el fitxer + + Indica si els fitxers oberts es comprovaran automàticament per a canvis i, si cal, actualitzar-los. + + + + Mostra el diàleg de selecció de dorsals + + Si l'&okular; ha de preguntar a l'usuari quin dorsal utilitzar en el cas que més d'un pugui obrir el fitxer. Si no està marcada, l'&okular; utilitzarà el dorsal amb la prioritat més alta. + + + + Direcció de lectura de dreta a esquerra + + Si s'ha d'utilitzar de manera predeterminada la direcció de la lectura de dreta a esquerra per als fitxers oberts. Pot ser útil per a alguns sistemes d'escriptura. + + + + Columnes de visió general + + Aquesta opció representa el nombre de columnes que s'utilitzen en el mode de vista general. + + + + Superposició Av/Re Pàg + + Aquí podeu definir el percentatge de l'àrea de visualització que haurà de ser visible després de pressionar les tecles &PgUp;/&PgDn;. + + + + Zoom predeterminat + + Aquesta opció especifica el mode de zoom predeterminat per als fitxers que mai s'han obert abans. Per als fitxers que ja s'han obert s'aplicarà el mode de zoom anterior. + + + + + + Accessibilitat + + + Dibuixa una vora al voltant dels enllaços + + Indica si es dibuixarà una vora al voltant dels enllaços. + + + + Canvia els colors + + Activa les opcions per al canvi de color. + + + + Inverteix els colors + + Inverteix els colors sobre la vista, &ead;, els objectes negres es mostraran en blanc. + + + + Canvia el color del paper + + Canvia el color del paper, &ead;, el rerefons del document. + + + + Canvia els colors foscos i els clars + + Canvia el color fosc i clar a la vostra preferència, el qual vol dir que el negre no es representarà com a negre sinó com el color fosc seleccionat i el blanc com el color clar seleccionat. + + + + Converteix a blanc i negre + + Converteix el document a blanc i negre. Podeu establir el llindar i el contrast. Ajustant el llindar a un valor major movent-lo cap a la dreta resultarà en l'ús de grisos més clars. + + + + Inverteix la lluminositat + + Inverteix la lluminositat de tots els colors. Els colors clars i foscos s'intercanviaran, però el to i la saturació no es veuran afectats. El contrast en les imatges generalment serà pitjor que a Inverteix la luma (sRGB lineal). + + + + Inverteix la luma (sRGB lineal) + + Inverteix la luma de tots els colors. La llum i la foscor s'intercanviaran, però el to i la saturació no es veuran afectats. El contrast en les imatges es conservarà millor que a Inverteix la lluminositat, però els gràfics i el marcatge de text en color generalment es veurà pitjor. Utilitza coeficients luma sRGB, però no correcció de la gamma. + + + + Inverteix la luma (Simètrica) + + Inverteix la luma de tots els colors. Utilitzant coeficients simètrics de la luma. La llum i la foscor s'intercanviaran, però el to i la saturació no es veuran afectats. Molt similar a Inverteix la lluminositat, però millorant el contrast en alguns casos. + + + + Desplaça a un to positiu + + Desplaça el to de tots els colors en 120 graus. Pot mitigar alguns problemes de contrast en gràfics amb color. + + + + Desplaça a un to negatiu + + Desplaça el to de tots els colors en 240 graus. Pot mitigar alguns problemes de contrast en gràfics amb color. + + + + Motor + + Permet escollir el motor de text a veu (TTS) que utilitzarà l'&okular;. De manera predeterminada és speechd TTS, però podreu utilitzar tots els idiomes i veus segons els sintetitzadors disponibles a la vostra plataforma. A &Linux;, s'utilitza de manera predeterminada el distribuïdor de veu per a determinar les veus disponibles. + + + + + + Rendiment + + + Activa els efectes de transparències + + Dibuixa les seleccions i d'altres gràfics especials utilitzant efectes de transparència. Si es desactiva l'opció per a dibuixar s'utilitzaran estils de farciment del contorn o opacs i s'augmentarà la velocitat de les seleccions. + + + + Ús de la memòria + + L'&okular; pot aconseguir millors resultats afinant l'ús de la memòria, depenent del vostre sistema i els vostres gustos. Com més memòria permeteu utilitzar, més ràpid es comportarà el programa. El perfil predeterminat és bo per a tots els sistemes, però podeu evitar que l'&okular; utilitzi més memòria de la necessària seleccionant un perfil «Baix», o permetre treure el màxim profit del vostre sistema utilitzant «Enèrgic». Utilitzeu el perfil «Màxim» per a precarregar totes les pàgines sense risc de sobreeixir la memòria del sistema (només s'utilitzarà el 50% de la memòria total o de la memòria lliure). + + + + Renderització + + Utilitzant aquest grup d'opcions podreu millorar la representació del text i de les imatges a l'&okular;. El resultat dependrà del dispositiu per a visualitzar el document. Els elements Activa l'antialiàsing de text i Activa l'antialiàsing de gràfics es poden utilitzar per a activar i desactivar el suavitzat espacial del text i les imatges en el document, segons correspongui. L'element Activa la correcció de lletres per text està destinat a ser un selector per a mostrar tipus de lletra. L'antialiàsing i la correcció de lletres canvien quan es visualitzen els documents, molts els voldreu ajustar a les vostres preferències. + + + + + + Presentació + + + Avança cada + + Activa l'avanç automàtic de pàgines per un període de temps donat. + + + + Repeteix després de l'última pàgina + + En navegar en el mode de presentació i anar més enllà de l'última pàgina apareixerà la primera pàgina. + + + + Navegació tàctil + + Permet ajustar la navegació per la pantalla tàctil tocant en la presentació emprant els tres valors possibles següents: + + + Toc a la banda esquerra/dreta per a anar enrere/endavant: En tocar la part esquerra (dreta) de la pantalla es farà que la presentació passi a la diapositiva anterior (següent). + + + Toc a qualsevol lloc per a anar endavant (predeterminat): En tocar a la pantalla, la presentació anirà a la següent diapositiva, sense importar on es toqui. + + + Desactivat: El tocar a la pantalla no farà res. + + + + + + Color del fons + + El color que emplenarà la part de la pantalla no coberta per la pàgina en el mode presentació. + + + + Cursor del ratolí + + Indica si el ratolí estarà sempre ocult, si es mostrarà sempre o si s'ocultarà després d'un petit temps d'inactivitat. + + + + Mostra l'indicador de progrés + + Indica si es mostrarà un cercle de progrés que mostri la pàgina actual i el nombre total de pàgines a la part superior dreta de la pantalla de presentació cada vegada que canvieu la pàgina. + + + + Mostra la pàgina de resum + + Indica si mostrar una pàgina de resum al començament de la presentació amb el títol, autor i el nombre de pàgines del document. + + + + Activa les transicions + + Utilitzeu aquesta casella de selecció per a activar o desactivar els efectes de transició entre les pàgines. + + + + Transició predeterminada + + L'efecte de transició entre pàgina i pàgina si el document no n'especifica cap. Establiu-ho a Transició aleatòria per a fer que l'&okular; triï a l'atzar un dels efectes disponibles. + + + + Emplaçament + + En aquesta secció podeu seleccionar la Pantalla a utilitzar per a mostrar la presentació. + Pantalla actual és la mateixa pantalla de la finestra de l'&okular; que inicia el mode de presentació. + Pantalla predeterminada és la pantalla marcada com a predeterminada a la configuració de «xinerama». + Pantalla 0, Pantalla 1, &etc; són les pantalles disponibles. + + + + Configuració de l'eina de dibuix + + Gestiona els colors del llapis utilitzat en dibuixar a les pàgines durant el mode de presentació. + + + + + + Anotacions + + La pàgina Anotacions del diàleg de configuració + + + + + + La pàgina Anotacions del diàleg de configuració + + + + + + Autor + + L'autor dels continguts afegit en un document. De manera predeterminada, és el nom de la pàgina Contrasenya i compte d'usuari del mòdul Detalls del compte a l'&systemsettings;. + + + + Eines d'anotació + + Aquesta subfinestra s'utilitza per a configurar la barra d'eines d'anotació. + Hi ha cinc botons (Afegeix, Edita, Elimina, Mou amunt i Mou avall) i un quadre de llista (el qual mostra el contingut de la barra d'eines d'anotació) que s'utilitza per a configurar la barra d'eines. + Si us cal afegir algun botó d'eina a la barra d'eines, feu clic al botó Afegeix. Podeu escollir el Nom, Tipus i Aparença de l'eina creada. + + Recordeu que les eines d'anotació a l'&okular; són altament configurables. Per exemple, podeu tenir dos botons de la mateixa eina però amb diferent color. No podeu restar indecís en escollir el conjunt de botons que s'adapti exactament al vostre flux de treball. + + Feu clic sobre algun element al quadre de llista i després feu clic al botó corresponent a la part dreta de la pàgina per a editar, eliminar, moure amunt o avall l'element. La drecera de teclat de l'eina (tecles des d'1 fins a 9) dependrà de la seva posició en la llista de la barra d'eines d'anotació. + + + + Usar segells personalitzats + + + Creeu la icona que voleu utilitzar per al vostre propi segell i deseu-lo en qualsevol format de gràfics admès per l'&okular; + Feu clic al botó Afegeix, seleccioneu el tipus Segell i introduïu un nom per al vostre segell. + Introduïu el camí complet a la vostra icona personalitzada a la llista desplegable del grup Símbol del segell + + + + + + + Editor + + + Editor + + Escolliu l'editor que voleu llançar quan l'&okular; vulgui obrir un fitxer font. Aquest és el cas quan el document conté referències als diversos punts (usualment nombre de fila i columna) de les fonts des de les quals fou generat. El format &DVI; admet de forma nativa afegir la informació sobre les fonts del document &latex; des del que fou generat. Existeix un sistema similar per als documents &PDF;, anomenat pdfsync, el qual emmagatzema aquesta informació extra en un fitxer extern anomenat després del fitxer &PDF; mateix (per exemple meu_document.pdfsync per a meu_document.pdf). + L'&okular; es distribueix amb opcions preconfigurades per als editors següents: &kate;, Kile, SciTE, el client &Emacs;, el client LyX, TeXstudio i TeXiFy IDEA. + + Per a utilitzar la cerca inversa a &kile;, haureu de compilar el vostre fitxer de &latex; amb la configuració Moderna. + + + + + Ordre + + Aquesta és l'ordre i els seus paràmetres per a invocar l'editor seleccionat amb el fitxer font del document real. + Aquest camp s'omplirà automàticament si utilitzeu un dels editors preconfigurats. En cas contrari, escolliu Editor de text personalitzat a la llista desplegable Editor i consulteu la documentació del vostre editor preferit per a trobar l'ordre adequada. + Podeu utilitzar els següents caràcters de comodí: + + + %f - el nom del fitxer + + + %l - la línia del fitxer a abastar + + + %c - la columna del fitxer a abastar + + + Si no s'especifica «%f», el nom del document serà adjuntat a l'ordre especificada. + + + + + + + Crèdits i llicència + + + Copyright del programa: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; mantenidor actual + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it desenvolupador del &kpdf; + + + + Copyright de la documentació: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; autor + Titus Laska titus.laska@gmx.de algunes actualitzacions i afegits + Pino Toscano pino@kde.org + + Traductor de la documentació: &credits.Antoni.Bella; +&underFDL; &underGPL; + + &documentation.index; + + + + diff --git a/po/ca/docs/okular/mainwindow.png b/po/ca/docs/okular/mainwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..49763dc551db0633c6d1812acbcdb58efe583b01 GIT binary patch literal 112812 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 + +]> + + + + +Manual d'usuari de l'Okular +YuriChornoivan Pàgina man de l'Okular. yurchor@ukr.net +14 de febrer de 2019 +Okular 1.7 +Aplicacions del KDE + + + +okular +1 + + + +okular +un visor universal de documents + + + +okular Opcions de l'Okular URL + + + +Descripció +L'okular té com a objectiu mostrar documents en formats diferents. + + + +Opcions de l'Okular + + + + + +Obre una pàgina determinada en el document. + + + + + + +Inicia el document en el mode presentació. + + + + + + +Inicia amb un diàleg d'impressió. + + + + + + +Inicia amb el diàleg d'impressió i surt després d'imprimir. + + + + + + +Control d'«Instància única». + + + + + + +Permet prevenir l'elevació de la finestra de l'Okular després de l'inici. + + + + + + +Cerca una cadena al text. + + + + + +Arguments + + + + +Una adreça del document a obrir. Per a un PDF, podeu indicar-ho com nom_document#nom_destinació, on nom_destinació serà una destinació concreta amb nom incrustada en el document. + + + + + +Comentaris +A l'IRC, irc.freenode.net #okular o mitjançant correu electrònic, okular-devel@kde.org o al lloc web, <https://okular.kde.org/>. + + + +Vegeu també + +Hi ha disponible documentació d'usuari més detallada des de help:/okular (introduïu aquest URL al &konqueror; o executeu khelpcenter help:/okular). +kf5options(7) +qt5options(7) +També hi ha més informació disponible al lloc web https://okular.kde.org/ + + + +Copyright +Copyright © 2002 Wilco Greven, Christophe Devriese +Copyright © 2004-2005 Enrico Ros +Copyright © 2005 Piotr Szymanski +Copyright © 2004-2012 Albert Astals Cid +Copyright © 2006-2009 Pino Toscano +Llicència pública general de GNU versió 2 <https://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/ca/docs/okular/presentation.png b/po/ca/docs/okular/presentation.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd67ec8f568dbadfc760ea59ccaadb560e68764 GIT binary patch literal 60119 zcmeFZbySq?{x3W})}w-$C{l`n3W5p>f`EY{AR$PXg$PP_j!B4uNJ)c8NeM`oMN3KN zNH<8sQ19pF*?XPeS?4|LoIif=KkwSJ+z;#lX72mCzVV6gH7>H!Vzit0Z6=XOwBpx9 z=9#=;SJ-e@NmiUH5;@=Qcx%$oXDB-olH`{`#G{n~n zR)ajmS5ikr{VZu&Mpt*>qXLJ;NISDpNK;djP}Z#5)$ld5n}}bz;Jr`QUNcp%r|S0i z3ZaGJ#|!G8Zhe*Ht{kq;Rr+F2EDT9DVgv7FVM1H>x5&P0hfLb7`$n2md4`485I>BT zTl?{!%V6U9R+;0GZ6+Rm^_cy_6m4GL-JfEt>GHat(%VAWHSk2+uCA^DHzz-M;Rp*rm_@T#!-zq50WwOJTL0&F@YgXk;y|jXAS&nRu&x zdGcC*0T%o7XBLhb1bPcvRfYL%NT@7R;tW}84jgZIy(PQl?ypVy(pLAHzYh!y2-!}> zjU_QXvlwe)b`echyVo##;qk}$uehf#+kGtdiSBj%Iahcs+gnFk((7iA{?(YPGyC2B{NkU3bVZ)@Rd4=z z#iZlP_L}JqZLjv+f0c7zG&^nN(#YhyhBW<_?Mm)eqw{@dAGOL-?z)JwdGwU|$}E?K z1P6@|-)IZ%I{dJ*UC4H3v^pj9$>g*3B+}!%%I~N-+GRdbQ6fBcjen$>1=lxqjEBn? zNq={;pN`Q9Zcf%VwRbVZi!)eY3#f!JFSic+TLxl|~c_T^e ztc)fF-Wu5!@k{M)m+>`sVuB;YYS3jwFs)%$d3oTdewDU_VqoxkT2EF^EHl%j-a_ry zwroo&+s-6O?s=2M;M}J){d2XkI*FZ~?{(cp&fadFbDV6Aw|chR-{nr78s+K#=DKgr ztbMmnT!vNUKFXVl6HI-p*Ad#@6J%?1Ls3zG=1p)2`B$>cag{K|>G{b@5ps8u?%GOL zE4}<0y_ArTJ!I-|W!_3klh86{QA@*LGu`Q>=vMj>iqba8hpmS=&Zt_b#PO3UPu^d< z>UrNUm3CG;uzBqBw{P#oSOaEKjk^NQ>eE~Fr5fMl?U#_Cud13OHu}QlPf_{-i@m9X zZ&YkW5@V@$zrQ>|P)_|^UaAxx8s0bdL11%31+{XFk{+#+9oeI56#pZwGGwBvd6~js zd$nd|srw7{N@D(Ud-Cgz`y#|#U2B@BSqpHEg;K>I+q4ANHN0Uo^FADVWs-h0{P~7&bo5wlH`X(8 zl`mebuL*uvAFEUOq>qk9Fw{hXZ^eFeIc!$Mu5h@T@6o0V$}=@zuC_MqTker7vp0C< z)SENL-Y^zgR7kt-dSo*jqsyZ;RNLb(?B{XqVtcH+NPbvZPnY4S?H$Gb!N7aJ=htr8 zvW3<5PV@BLBJF$kYTKUZMXovf;P4hVHiu8R3M2Ix@oOizxEvNs*aa;5|Gc=UMI#() zBA4}wT9BA$p*pFo%SmsP9ueTf)j}?fX=7w3H)aey<_>B*EO=s{izrXa^k}er^25G7 zdk1qba;O;X8edJRuBzLWIpgi$ zUbLhcFbkQ~-Utjn=<&WTljD7E!a$&+LCM#6S1pGj&)fw|{T9k_ZK7LV#$CNbCPuSv z8r4(uWU|#@q1SzedA0Oi=5rJMiNQ@rA`%?;yuRwBern3n(;?re`rDd5+UVHt&$k&? zv2w4>4JK-~Wh;#xwC>-tJoEJJda*4c%2;att;`no!n1*<6ZPG>s4s~$3>LK;`WIz< z9o{zCUU%9&Vf?worOhT{*RIi)wEInOl{9smAI)Ws?AuMhi{5@_e$&o8V{K_%+O3`~ zG!Z|DVdqZ`sIW_ybv@$w$qKaTg8@4nFl~@yYF?o9TD5 zg;ld+^z#!xbF#W`Ih&}y=b^1hcCT*rwYXblo%52jY3EW*QyzT2F~(#2GhniLqeh}Y zij?ZIV?MWP!<3h)Otg4rV(Fq~U*h7up65gC_wF%KpEyrPvGg@L9}-H9`xI(ab>&$n zYoV>;qUqr+`?mfQG5bbzJx!HEloA}L&+TyGHE6YJZ5(2;vC_M0Q`n>vq|vo>Q(kX{ z^``^(7l%77zC8wGX3~lDyIV8uj41w=%V+Iv9Kz#%dUZa1CM7t%Qd+ksu<9sYXTW^k zxs7bw;X%o%kG>(Un=<;$ksKypF4GpqX+y5w=(riWtgU19S` zZ+GC>;o>!*!o4{1;`U{yV=7hKR!i-d8+s4ZE7Y>hx2C469wF>9f4d zmNSt8yY)@0f3$2(iZh-q%d;3dynbPJx0h&50Izc}oSlQvUaA zzdrgYY2y2nJR7vBtB~)ZsuCSfoS)5D#qN)xIvRX=nqupi-u~0CLi7Y}MJ+7KhOWBX zk4&Ef9-uoNN~M=7dDP4%m_48Wp>M_eZS`mCpbvdL96tHWg%2BEGqi+`u8W)P+kAvW zIH4bNn^GycV^)JshsYh@rId2q&{A2wsi|n z0<-am3wv7pSdu6kZK@zU7V?CDdVf>6&eGOR{JZ|y@QN2Pl^)kVtoD0avJI6dApOzS z)XKZlMxEP)i$ZFRvvUDTySe3M7h>XPd4$Eks~^66vo87kCU;zcczN8?uU5|CX`eKs>Ym z{4@jc_3@ut9pWqLoBY3ifm@Zbmh@YBr)$BW?cca6QQnU`NZa1p{@?!n|M3m}^9%o% zJMo`|`p-iB*UbD+Jp3mf{u2-XYsdOeUi>F7{*xE~f6fd3OA?Zj6#Ln>&dyFMOYwNb zsPsZqh(ngc67_d>eAV*O!X8d#qkC=&QbP@im1SkIzL)vFq^u!bcp*1ri_oA|<)nAL z8t$EF`ser8w{PEqP5=D)^E3w}LLollVOjnD3Xe`jYo7grBQ0Zdx}lcu<;VnSTL*__ zF;;u8fPjS#C)SE!A={>8ZSvfAR)d`J!u@x-4$`~EYh<6r-w*tX7|WTg2s~#hVAlVq zggxYDvbcf4=wMx}6D_0Se6ZzM`_l5lm|OLw+OG}Tn=i1H;tIRvT zc=4jlm)o7Z)SziQ@{CS6V_`I#JmDF_G-D}fcZQ#lMB-fsUHgKzG=Il)XcQ5VtB;5X z;+qd2yjCB(_7D$WFRveWlIBW528_E3u};**`N@MG#nTO1BKpmrZJ3wGqurzzpk0_l@xlSy-Y@bL3Bz^HFl9eo0D7NNk;TU3a6L*nrF75a)09`soC# zWLu1Q9g}aj>Uw?J^?mh&t5>f=k$^riGu$MvuFm9IFf&F8ajxcTHToWU@mX(qz-;kB zcc$?ttoeiepF?a%GwII%`GTj%GW&wRef##1<>x20E_3J&Z9oqML>)w;MAcC?7nf>YuA?M*PEh+Yv zlfC63_A^bmzDVgH0lnJj5>NK@2i0uW?7246)H1E*Wb>hV+p%11V{S*@gVdXoj}TU* zqKv&vt|q3Yo{5v(o4=@i=Y^reWI&ISa<+y3#AEKfxz59q zK3*z)U!JU8Ssq(ykG>J!eK%e`Gx^&AT9)(tNzJ%-jfF8~dxc=y(3!0(tV^WO)4>9N zlVnpZMw$=jOW`3SBeRUVPt&U#Y@sY$*x1Oj$)%Ix@75H!T;vAnOVcp;}k^x%aZm)o{q4-0~qjJUm19Wp73zbv+i>#xE)#K74qb zp%8JYpWarVY1((1;}xsOa=5$j%Y5PaZckRbKVNHWFIVL7VLQ6nk0z*RPDBP62(%uk zJ0^0N^f=rNc8_doxA>;xeB|XtHG|9u>5XfRi7d{wwS+KG753eoyx4VGlH#y1g1r_V zpIM-+IHcS!KTheuk_D+-vDywN!H#fZ`pF-(7Xs^yxaKXJZx! zgPKSwMxOgWD;;K1=GfiOPZYn{quH2rw@BEY`iezJ;MDA;LpxAY%3kxeHzsQ3R|E-? z$6d8@=6eIm&f6uvsuWpSMA=|HeeYVLW-d0wp~qWkxpPl`W4a;bHtl^xa*%-ezLU4U z@a4~!<8E1<5s?jWqkPQv1u-#y749Zk=g=0ZM0de8lz8duqQc!X=Y)4XO z+bp#X_stlMv}R5g?9qB9%I2$SGvK`aU@0d8p_0)s$HU6DSvTs8VSA21HuKp>$`dV3 zDLSm9U+z~1+v~hNt(7_Bd(nIAtiZ9ON8gE%m+2h-Jmab056{Tp-{BI6VpAJ^17&V$ zzLKn&a*9Yc^Y?kIbz9BfU%!~WI8j!XXgZEJ#-;R#a34D+-fr>Tk+$w!rwo}|bLwtk zAhP+`v18-3hFJrVxG6WLbICv5xz3!Kj)@9>S#ZZNcUrL}O}~s&9~Jq97$+y^Vga`U zx`69MekWWjhq(@?GmO_IBua@F?AG7IrOt2Ano%Pyc;du~_(kz(qXGXj4@>E+s8a*D z%o8HbXefvoM}d)&iHQlW%9xo>FZPm6N@q@Q2l^6X<3{-XsXq;Qh`ik z+WS-d5mCUpuh0q4-NKtG7fSp#6R(d_8dw5 zquFCzDf1kOId45Ywre%xO`ojYINF$WkiP$PboZk}H&+C#C(HQ|d@WHjAwLx0{%zj8 z8C6O~VBo`C3sE!c&Kny2j9$#2BKNY*Y(bmkdyoFIL1)6SG z2%eq@G_9~kmY2n;$jO;>Ay!ceebr6G=Uc8=4mX~%p6H%fK#UeMTef=m``dh7zbDXv zI#6ck&&YZpdOcyDR+(3A<#p8WgoS&0GNoC0&N`h==uYF-E%Ia%bCZ z%g;1CYR{REOQ}FyUohe2K6-Sn!ZL4iwW(UuE{?mChZ_fiX?F@S0P%res*5#zt}!x^t3 zjO=C)u``*Eko4gccd+erVOKOwKX>jNvw+#PK=- zGz1aait(yf{?gc>AP_fn4{wv1nTZ<_SFiK9*6k@Hj3AIatKYnf9N_J(5HL;z@sqmQ z6N0krrL7CCAH+QoP9s=b2ITMKHES#QyI$4DtBJ9B7}^i1^`ys_OJ!Vkq!DkQDdk91 z&oUbT&e1|Mp5U`;w;76OJo~5-7hfAA@2Rt9^jC!Byika7Ap=qym-#Bc?Xzypl|33> zIqCD0eM;xv6}ax%vujtJa#AOCC{ae!j41I?lzzN*?EMGE4Lmps&lIF zP7*6xu}ge~&}^%o+Xn&51;zf}07Ge(zC`lU(4e7hA%o5#!-d7kN_K9c+T6-5d$?Z7 zj2bV`_Ysxun^42V>F9|^wZ8?#gF_DOa4|!iojH>V#3mJR_O&P*(L7_#OMma(vF34T z>jDkQs1f*KWxR-$j7Y^UsG!i7dUGH?x6e16qkr0uh3Yg%`2*&uM)fRw%}A8m>*tNR zMzJC*BZlM_z`x<);qk5_ig6LM%N0gG1J3-u$qK=-nHEEIQ1^WOhJ?1ubV6SK{{G4x z-|0l+?wzz>m#GYUD4bFD2qpysr71x`iRUsH}v!dfkHOW?lX(l=Y!XQZ7S5#GOtr`sbO>x zO~|7T{un}%7*+-gg>6s|n_KT^qKL`V84>ff`^9OccO3 z)|NdBTz6euJf5&|4Wivs{N1u!vyghE-o(g4@*BG znc(x*Ki{1y2?;bQJqBzjnX`m#=3w{cXqzn)Boe%g|R*3e%DX)@Mt;A_YiTI z%CrNGn=5rtfkc{9(jGOI78lQ)>vUb18jx33R<_(I;c!+}-DxZH4oe1K71jHL?LmT; z_jPoX9O4j%hkY|9Xp<(sem0~C&l`EO#?AoDdNPS~91C{B0K=_kKCtEIEac3uW-Yc0q#*HnW`d=HCcCynnf7u86ns@V?A$kg(2u`_%|8ir%GW3!wQlb#4rA9; zPP$WoMCkqLmtxfMtx|Y_)B46le0iOR-46l(b5kjm!nQyv#5JwoLLaA^dVKz|$JOHz6AH`P7ft{?iPDtiezbtokhJ3(t$}3oDe0jzzOS45=x`2##4Attg2*n+f!2MfPoa^iE>q8|cibqlr zi)&?A;9_fmZ1@SDvL9LILvQ=OCCHh4G(b6_1E1U<{_zO`evlL{?=+Q_=L#7OX;{u@ zl+qH|wL2Z~I{sb{Pv!YZc9HoKz@8k`!8vyM$m_b4yroL=^5h`R>EY{V#3lsRkV5_U z)#reoh-EViT3iq0H%7Kk3%$8aWW{XWZ0_6;ZhC1zhWznQZ~bo>+3SkE2duo6id}ZH z7kb_~v}1lqYeltp+}=3ss%`19s6+Yo9WVBjCVE;W+_EmI(I*2LU39$3^LpPI>ZoOY zz+wr(00$q<^@qD3(M$)yaAY)ywp${ub|5N5I#|C8aAB#7bwxSoE_1!MY{Wt9AWT(B z5ftGX(R9|*oqrR3i?-_RVaXkqA8~QhvMEy=$WQMmDk^qP6Z|`;A9!7;RuNFN#C^?h zb-37z*cbcs!Jo0iI}F)ng4K~uIhR1!36d6FPT=MrLj>=lNIG=4p(oNaSFaOrg`D3XzvPQOeT=94~UITv_ZBQ8N9ku$8~5$5$)ZDiPGlgeeAMqHuI@Fq7$v91VKg$e6()etgsU3+wf5#)```D|5Sr0Cw=xz z^Ft1XN;hV~LU+~>{?cNPgNE57X?j}+7%6jw8kTL|bBiePcZ=MDM92>F<-~28^k>L6 zh%*bF+)4VK5kb)Pcmdj^4RFvl~QyFyT13Gh-@CTR8N zcV~fXh}}fVkL_T}Admc(qpb?Diic<3*i{iQ5xGY}(V~ZZGSXrRq(BFz1Yz)Z*?3Cr1^qt|a3-0U|o-^qD;j%Ixvf^hI;OB>GDU$%G<`X3}8f-gyjQr!; zq0?Aagt(^B*Yz$k)Y-8W6tY7hGf$sBC5pH9*`LM5{5@XsJ5rQeQP>pRZUY?vXK+lm z5h;+rvb?Y`GZI^oe(fEPjx?@yhoEk4bTuND{O1|#`KhYQga(8#J_Eok`oQ4Vhmu5x z>DbM)laS}~pgp03x@ee>wcA69!+yCYenO$Fkr5HH{(?>bMPcLQNyems0mUBDEvLaK9`PvcKN>$jY>evxR`!!bWUPf((JpE;BghJo!n zC*$JcpiV*96CBG)`FR8!CZR`HCId@WcK+2kYVOhF$3bifDK4d@yN1QJ;N{Dg4p0R6 z@Is3uo0(y2^eQEGR(BR5sx0LWR;X@~eiPmZQkC#@tvp9g(76QL*-?>&rpit-MOJhE z9LEk56O$dW@hT}uz_Z$l$~jiX6A5}o3^)58F^!r}Oops1$}U`&k`ij=p(%QGd5Mb@ zdVlM@ObAJqXF2!9-Acq{_^Q+gwGTZl9=OzeqDntT(|NQy$oFX(fbRNCBk9Fv?ziMi_Y!SmQbm5;q zorJt)&?b=NgqOr(K@dgQEiNwN|BBww00NNY&h_&31#`l38;nqx^JpDsEAa3Asjb#M231mFaZhm5FY6|*KVaPF}CZa<9NI%ZS zC2aKj0+yqqBB5NDo2Pbm{K?t6V-TRS2us>o@dYr&2v zq1%)^dqYrDlnBtAYDiPik7h^P1n2VxN-?Ay`}s5Pa#Wy?k0QF&96g4g85kJqT4fl3 zh(h=b+nZA#qMBr)K!78sLVyHy!4+N46Un+X9?K>C;fI0}pb`e-mJO(-%%j?} z4JDvS6G$V>i6Ig>G0}*-iS3m?UwNLwmn%J-DB!kfe_Px7S8ds?!5iP_OKEiuVa(a{A7_MVOE8o&NHZP>#eB4Q5e@{o zEO~nvI%*)Fp(bdi$nsnldb>S%Bt)z{AX@h8?~J-P2BKR!LRWR@uL?t3OUMo%ZcOST z(n zSZKjRjHM~h-geOw<;ot_9;J;yWE!ucAc|J6=!{i##YT^=xRdYqa*6-FK)+_Y$Cb0| zH#;vlzI5(Xs(tw&K8;HuPVxEj=fMX0k8SEK8KKH2cBh8czf?|r{9bE&0WIwU*Tcrk zm)-_s{|uzCiWS}-EiXTu`Gz+q*nP~msJj*GcKvZ-I;+TJk1vDtDtmjyF!|>@UBj?y ztWsiorm0S94R8&VqchOWz`OX}&)AGS?#B)Y57{K z()88%euVHFcY@4000#MZdq=42%un&(qn;85|eeX166m4?+aQ^ zfXO$Ild0#sITZV0fV>xj!QtOlP6!q7g3bYY@c0E@JA_ie&W7#}GwNLQmUs}y;x`8b zR?7c)!6s4=O~@Mj_$=#98VDelMwat6R8yc9o-r|kpKM|eGy+8!F>_ueCx|vOlR^>Q!1=+Pw*?S)NB=VBqD? zeuQ6w4hyr!?>b>Zpr9XT+r4`?cg~-07d0M$$(Z(4C`f2qoe-a9I^E4*0mT_y&C}PH z5Ao_LEl{#BKwJ*=PgFGxvh~t*101n@=;=;(0Om;-dan_KY_c4LB1oMcGI#C3noETU z=WcMt*#v~FV%@R#=ro@`eS#D{AC4ya_U(@Cghmepb&s6T47`0kK@fX~;B&lmV7v8T zOw`9gm+da1*wbm?*3qVvB4)F-t=$h1>bvOa@Bi|+Eb1i(z_0fCK{eLoWAm3+3_RF6 zj_sL43E8mT-krYnT<7D68rEsQ{{!X>vSkSN2Ncs*$hgF513bf)4Acj0i@0-e7@LKW zbg=CK+?6okAO1>Uza|;t5?PtAw4ENTgNpqza^M+ZjP*Q6vkb9l)@7TRDC4F;hJ=1Ej3Sh~^HIxkO~`UB z`VX4b8QovqpuVR58mr?Eq*^iawuEh8Zl?mnw6?Z_<#9wnd{keW{Q^;NIN&UK*>1_B zWmaWmjH?-y?7(G5FezHNQw;|#+pVL5W!2SN@jN70D7)ua-02w4UKia!#}enInyOa^ zmKxee*pNQj435TFJT0^8E65l&Ia%40!0A}osHVla@h&kprWh|Ow5PTRJ5vaDdfVrr zFM7+lb*Wo4X`>=3N+8~rGP>MqbZFs5V&h{K4KANz(frt8io5|#gxpo0r2MEV^rEg0vyjbaXVLI# zY)$H;COOfMdOgEj!YI7qZUTC^LZ~?*(>t$$^D^3h0$|iLlxjF*yVNJLvfX2+%=v0& zP@)^DL&OHAiV{cO9`ExPv>ZiUIfA|nHU~gD4mGYik@otb9Z+Ge)6&-#d^@4~`9Vus zyz_8-u9~P1mj)F+QXXs#uq+$sT$&T(8y}3Q z#C^2sx(m&`+p6cwr6GXwjWu=OcjkC`GNP?+Bn-G<+v}?Zo^RQ+(b=JVo!@@!#0iXT zSVF}zG%{Va(5a;&v9!zwX5X#JtyBLv( z)O}eDJ=|=@M%IjnmQT0tH9v^*X%r}|E)MLaz`Ch~h>DxLQ5Lj^p56hjpjz6aaf9~w z90zozRzCtlBmQ-MzB2~F>zC_c;JLqR_wERF3+STgG3}U+!1*9zi*`!$U;K4Hufxa+ zIxbK8kzw0g(nLk_?>+5U>Rjs{| z_i|59k1mkUKooaY|9f1u?M4`wN9_O9%FASqoJPZHK%s~CXM#n-eZ6qr>lmi>=$+jO z`!X0mW3@4!w(h!ebHw6M`@@l=j3N$;xWQ@0tzf>MIx_<`Scp?L<%AW7sJU)AxlynB z{R@NEaY*!Nl|vWPck*EyjQZaY$0|dQAkV@;wQSTjJw$)1-AIII*La4og{=yD!Qk52 zpeK+@7l%_Sp~4c2L&grEQ~57A=AzFxJh`x+#XZEd;v9iha7X#n!B}+8!3T{R7y0^) z1`NtpmS^)<;Iv0v|3WA;*xM~!8DIDueu=Z2_g7sM#UJtAEu<030Q$hcfxAJc>6is> z?zuR$#if`)j_5fcb!Yd|ye$6qVhg);AivF2|15<}u`L@lH4=l32?rK7XzTQeG85L& zO3WD8e5d7eE{3*P3kHbx1%q5WO&@|SCQDGo#_(@OxCPB$lr2nbG-p!UzH99Unv8+S z01)XITOD6-@20e%2@|Xo9@El6c~Q(?I<~nMz{I0j5?lVsQyBUD$SP zbwa9vXO)?TUww^| z;Jt-AN7k?_Ybc=wdj^Ud+d#MB*&cPHi-&gjoz{M-tpbfX2jT~+NHeq))V^a&-=P}T zWAtDkEvw$z5-;R{kU`m2JcfCrz07W|#V|XCm!{++Zi3FLMYJQN;norQ9JLIT7}kvM z#-#w#g|*(^Asg0^j2O&wiBY2OBIzWtr`VIgK&I~}JI6C_?-f{E*F}{qOYR)E;-oJt zDXHFFh4OrCw`;-m8XBkX<5oEzK70T-K>KV$?T7zlXMa*1H;K{$h+>Fc2g)&Pa8>5S zVUkN>Z*={smmrByQ=hOU+e{C7b0}e8C^R&5zxA0K-nCC2ckx$0s2vFlb9KHPCVO)4 zXMI5ycR{zB=o<$kYC*&K;P(E#4$;?9*srRs-2+$ot*0js6o#O`k?_XjodpOZ)M01? zNt|W8<#=CAQ)z0lY;`g}livQx8Jna)Tu*wV{Q*phv=Tu8;-)LW1^+xQ%yz-XKOUBt=xLhRe9Q&}pQq3O}~Zu8`Z|3KCUUO zk$7RFL;H#A`O=X>^zoV~q5!e|LcF3|8l&GsGGdzuXI**#rXa>_?j<(}>j^?sJ6;>| z>(+v^;A33b!>4O_u`v%-6t7$FGD|6;*A4)!nNtl>3 zkm76WX33wfS0k7Zh7gXj5z{|_fmeQqS)m%VBSvnb28BZ$Xm2al^wfQc&*Z zO#-$@+$@zG1_cD~CmK-NIONnwN*_TS6}!ggUhd{VKzU7=cwD=O#GyE}M&)n&_bk9d z{AgPTJY8Q-6~HA6iWOwC+qXNQM4>`qJ*l@)!xYNJ^Eq%)p~90a&3a|We68X_(yrhfI131&5UIQvk z^icpV2-XgxnSHIM%td~@x^hq}2=^B+4X)0-Gf^#l^kZy-UQ=?93wv-QHcpZ&^TYf1 zmqZ`6IA8$IAaB0+uG_i$0A*X~Is4J+ai!ooJSN@OX5ZJ1{&N&7^s5}{O?`l2Ud&3C z6_60o1>J?I(d3n7wh33Q#Y@L_zrITFXB5$w#eX`!Pah+2J5g~f2Pye0gvGxrskZR; zg3ET2(euzrA|D5T5~BV&)86yoB?h`Fku4W&2kxnef_=x+0hzHAVsgEf10;v)2RB6p z%m+V+Veks`!25%J8Cblqy0zK<&NNK?va6q4pj{^V;eVkB*L{y;{KW=6nC%y)knKA$ zh|+hqXYc>u3x*&y{D4to*c|iKp+yh zTlfl7nO7PvR>D$^j*dn=+B8q}l-WOoYCef+=>T|;C>6*GYglGhzU8F}xP`~mXRBSu zN#Q)pEc3l97}=Tn3K^sID}a)V^TKG}v*x#Mj-Vh=!Ka+LxL^ahj5=1M5FC;6R|jYT z$6f{|6h#GwEr@~Mp1wZUV$k89k&g%1vc8(FEH9Z4y?Xg_^SIYFo%hYF0>bphe^px` znz^lSA>BA%)76bJ6cvSu(HAsOF@VnOpiLqCu;k>^+vhR6U;)(~Ap}Q;=lcl=8fDBm z7@gxR!vHx2<3?A07zYxJS`@@Al+ggCS!EVMH!)$dok76t0TSwRSQXJK?qTro;MG@H zH*OT#DZ(_{v8nCUT@3R8TQdpSOf8J%hfJK!J($-LXQ6~e!h=>(BQKKqLarr}{jBaU z(G_!#fB;+2cp~oGH(@dykTF(xZlB%iz=zDs$Fd z?B-1(YSHpm)rtX(biy}=$zg*r24X6t+~H9R;Sia}Bs+Ka^aNq52fjA7#*aq_BzWDk zuLP@R;{Svi47V#;UyW>o5jiy?|8U+8wo%J^CA=Dq*}s=Af&~F5CxHN!^9K)}GunCRjxJ1xaS?~1mIceXY>&&^%QTaI(hf3KtY9vv5FCO^TO{nz7W zqm`Mpr2QOol-;BYKC1w2(U%RV=iVNBLeE@%{8!K={Oi99&%Kdy>w-kxkbS|TF)iL} zg7(M`7l9_o4y5Iwb%QnpROJ7h2MU0#RP)jHk6f3UEMU1U5O5g!B(;ImU|3yC{1`iH;gCPsB{om6hH9bXuXO>|gjp=@P5JM5!oAiit{ zk-4NV7w^Cc>r6)7y+CMSm@$_ z4+Ok?L?I4L@7qtT(BlmTrC!JWWz+ie>awxnawQM#h}2Dc*dQ$md72=#AYd6j1Cyxn zgi#KykXNcCl+*FMWdRKt2?<^+Nmm!?Q&Fnzv1i?%IA87M{HxCkn zMx6dt13~ZD?2Xq-S zpdseI^wmTa@nIX9nxoQ3F%QnkiH@eD!0`w`8!N70zt6qMzHb!2iK1A-qlDgTF`}A2 zS5YniG1*s654t%V_*X?;B}4pfDZsb(VMuDl)FiLt92^KJ8|>~NcL@BfkN17R%A;;7 zDq`+{+F(xTvifNW?(yq359mqR8odUlWvDKY}>XDl3a8I#be z)hdi z4J3|7Kse$&dNc!>3EE!+wA_nMSIy@$lqZ$o5Bpki|sVTOB7Wrb{Kzu zo@`_xMjN5PpCL|p80Hd^HX7msj6^|-Vzq4kYS5lGQp93AOpFlqzPo$%^}bYyiy$DD zXvq*5@$P1(gT5H~L}MLp%T6B+eY+{5mLO+%Nhn7Z{%1H)cbEDx(Ysjf?obQn0V)a6 ze-JW8iIG$TH0@=|$^x0{?FhR16BZMp%s$gtx0;6g51KbbZ@X~y?Se3&aw@4CzgRwa z9?I{9{rlOF!#Dqnw(l?4fm^E5X-ZonV83WELI;6>8exlR^D0v_N*^2vVvfls6+)EE zF=)iZwEVz1h&Yki6_~`Pr`bTLsqP}n$})tajs0zN*biM{?|G{~aHsy&DHm}<=Y|9t zuDtZQE222KbF;`8M3?Y;G2`G`46MG7&w%Ogb=XGVYlo&7_hg$7DUM8H8mbDFIn2xd z%-2~Q_1n=LQS+x%#mwT2&Qa*NW3rO*IP0{2+LDYf|g2Ax3TtEqGh7jnH{ zgsdl8;qR)LA@YO2WM6krsT@0F+IxLTY>qfqWo^d1<;FW2bCE&Xz}q6k>k-ViHU#%uJ=fgPtuIF?2!ivOT>{3 zsO;WyNU=I&J>&}{Ez4#M`%GUkmyY+cfh26N7T?rsUWy!BfOqTl5iU02T(knu;eFwN zlyKTtR93Elv8y9E9&&dWP_baO3jR~+SX!-Q_DQm!QjFwR6 zAnWZUjMphFpS{oO^8NXT>xgdjU^@+T3-}DSE9yJy#v-ID`o6j!H#Frs%v4m(WA5uh zxDgs3Fuz7`%Avh9X@(R{cY^b<_TOh7J&eg@~Sp>O&^8^sIo5F2Mi5C^FcGj z0j@RcRCI#bs#zf-b!jj!qf%+_L;w5eyf<##a7_I8kg$ay$CZ{!XmJkBs3auiuPlv$ zt(lj-neN0_{2PIiIRTSvc8rpLc8K*?xe~`-n!&YgTMFXySwtLi3=V0m1+-qXTyYBP+R1$oWM`Dg@OTN5}8fjEx?d^#C_WP$NALCf&tBI0l-W~~Q}ErTei(QI-mD%SNX zIv8KcMtZ{m#X9cV-lnT6I*NfvViXK*Oauelf)>L^*+8&byN)fBTCv=9u!{8qT2#tUQ>8 zLR$sOizv7%#()rWM2jY*Dd$$4jMWLYj&wE~tQF^*CY&__qND%9KAp!Dx*c55sm-V| zQhA?Q%*3X~-iWdh&bT|Ph-P}7TTvG%jem}9?Eqb@)N0X^gf zWyn-{#MjgN$I`)uldn$J^%t!wJjLm8itX z_BvDG$)>Q&8-*Njst8fAhnf)@`Wqv|uE9L!gSF5FG8l)D{Km#fa?l$A>ec9=zryag zc`OxU5o^|Na4yD}DdrjI|6XT+p>zy=MAV{BRtgMpYW!l{{GtK_FOYC5q#xd2}Khhc`8`9RXh^YWN$N>ORAH4SQ+`o>vnNCJiH!`ex2+=Gr-wy{JxH5h} zC0wwm-FsHgKDO%ue-ENeddU%iaWQk*{xt3v=qV7B3RL|!UvK?+x`hkbjU_fA_q}4| z8->}Ho1N5_ZOK||C{3Cc^%m(^Ly|psl~C!cs{T}-xR47ia;J+Z*z&r+pwqLs2SoaL zdg2+H?|;9zBoU*`*~{-XI>5>HzbCT;n^4u!784P)jW`t4l7=}@$j&f)G*v1gb*}&z z>~#5Yt}pQJUdK_JxCNg6JSLk8$U~5hnt@jllUcS2adC@Kw=so^IgH`FYgNX9khF-i z&;LS!^>KcJEH0u`w1r&++u!`6)u9L<6cA)^;4SA4mw#Ce&-GhIE5fUz^;^E)s#^F# z^WBJveb;7}Yn=2ombY6hIO(@IeNR&Ud6Fhbo3*z0%7?hP>xTR+?n6$G{O?1ES@#z; z6AIG5-IjiSY2JO)?V*yDn_gUU>&g&}8?-EdZ0p0Vg)6}s-O;oV9Q`JIw`s#oHM}s2 zAU*Ii)mNSc&xaC4v^e+zYreF+;s`Qbk=O$BIfKsE@=GPP++AaN*hewZaiz0aKYp$2L9`d7{nOKEjk01v>cn;O12w`42_(SdU^x z_QoIC_^W8AxdXdlxh^WLTxjd8y!Ff@`CcQV5W5mX!z4{sup!;!KYhDMZ}e-44Cg&c z8!7pn+>or2Ir@YmKK?p;BgzcJ=i7U2RQGQ)5*wV9U;Pm07ppRPG@}5w1$nwKwOwoa z3Ab4qrzF}XuT)L?{u|tQ=fO>@N?>Tkp$6gDrPjMe#*oEng3b)t=r9WmZ9;k9wYl01 zAG=JNrq$j~RGekfAU%1*P*}I+TANAjStX6Oxcu6VWNE*)I29QqrlPbFtMjA$(rh01 zJ~kHIsv+xp;0pG|5!LS*DeEHt=DQk{V}tNrA$wQ83K!CRj5P)!}nC zdwqq?Q~ef{+_Vu5L1(GX z8W71qv!P8wC%x_}Cp}cUtj{V%|?s_-WAyn!(FJpt~|@>Dw{`@RG@y#OrE6d`NW-ZA43~?%W>K@TcK{6=UGBX_FumX zLgZ0{Z>-8#p}g-j>8J0hP*TjZ?;VxNzh6EQ*0EH~TYh2x?-Tm5jpMEf&1{ z>Jryom;P)&T~Rvu?ZTK?`?n6Sx*wy*@@A^=Hy47s@*l4y-D42ad6HES^7W^6i>Or* z+1c1z?tSO`>xVm|AHRLaKqr2|Z%tE(VA*moBYId`ykx-Lq<3BXk-Aj2-l?LJt%Eg~ z6oJviw=;2OhE9ZPNSbCPOA`|VBdd8Jw<36~p)R?Er_ER^<$k)SW7p9dnsu}_+t}$( z(iClaVZvPWw{r)-^m!KdqOL4INBx%0fp@p}I)YjGlpo8NQm`-UzV+9B!@k$uKFrhI z9XQJlYu#^kl%VRCHI_4!TYF}!9##K|qwY~LKSu_>wThpU53#6bnQHMXHfI_qEVy0N z(0-)iv+zqqC^%41No_fhsoF-+@aFD`ES`ZJyxwD~fA5T>#M9U1f0)oDaem+S{pIo0sBi5V5622~UB+e#(|r!tkG?i&QENJV zZ+RfcLVuEJY-r7NQj5;PN!4Ee-GWgc65BuP%5Sfh5*fUmX)M&bgT%TV_!lYJl^Az^ zydh%E=i+F5M(V2HQ!=7HP`rMheIUr5qD9<*z<2TfgmCY39 zHRc(PSVjz``wp9!9K71Nt;OqkMCYcWVp`>VfpGl*^_G)AyMH%kmvnF4Tjx-gvvK3} zg`A&1F|4*qPUj3e zANCAOhUD76!4MXs>|VzMjwebvU!Rjq^U-e%P|o3@_P7Cb7ttGwGDPm?{Z?wyX~9|f zccXF9sq*LRXtme9dVYIvJflhj6YJj`;c_ZIN;rDUOaJua|_2al5{H|FjahdR2iX>-a8O zY|PzgFiSK3qdZyU(HSXB#8^GkC^Ej2q`X?xP!(S?+Lo7=CjS}RGwOEalFx1BJI+j1 zhXm%UGY^(-^FAuyao^tmaE0($_I}ZVWTsOzF-ML`Go(b4C62LMG4kpB5?7gJG*%O- z!6$p*V^dZ&WYYh`)>{TdwT4~891E2Okw)q6ZVBlex}=){hDJbCWR#ZfWm-}lD+Q2xy9z3+YBSFUTVk7?!7Rj2x{Q9BeqtG4^$Cvx;Lia@a% zm=5t3cLBN{2p7-oWIY4JZ#MyXyZn7IkJ}-H^50{!S)wSJZSHV}_8EMA*?*R4tiF|M zMV9c0juM-^7EF0&`z^k^^#|O@;uopJAZSx6A%DewF&qG*~p8Xg5E#^x}b7I zOyqp;6NRDfl>0=YOOV|~Xx_knF;sW_(VUlZF##1(f_&av7G;((;on9@QGD?h?iuHf z%0-&Y@o{mhf^Q|KIjBG7@|WE|{kIx|$l65i1MZey@HhSM+R)3%+$`K@Kf@ zt}fj5i~1c_6i)X*^Jk)~Rtirq8$ecJQt`ayNL_Kpk4{YtcZ`3&Y{nr`?R>Y`o12XY zcrR{pG-%Y)3$S0Fah>7})#>$?zi##(0op&3!Cdlyc>>RORYTdqKeA6v>iXr}uhYKn znsfVT=oE0x7;`p=Sc+M)+NjtneR-wFGBK@c@x?9_-$+qA=#c!H653;|?d@*CzT;c(mSE2*r?O|h==Wx9#T-qo*c$E>)2w*%THjb!`wf99hcaC=|(VP;A~78g79Wk(tn z#U+K%wz6F}#Pf2)o*zzx1ai!R2^Z(BK(9<%SPP&5!q z1?1sH)92=tcs6TZgZ@X>E5NHzAphG7WH25KX!!w4d)G(+cgbEBoEecW1Yns(+N+w( zYx4j!Xtij-{9_kIBE^*wSmAkGF1nE1uPNcP%ZfKa3x-X;aH*9tl*J%oWkQ%(q}H^*otK^ zLfYPjLghssI)WOk!vUwDaZv9+W24nQid9OBo3Zg-1;ZuU)H)}>nr|eZ4+3Wsh-Pm= z4=;j2m)?(Eys9XZdHsXcGlZM`iopm`v&s8IjiVyxjjfV|y)zX)Qmqj+7sj>p@n2cn zEOlnNp6qGM8&Gy5_6&=jJucIZ7Y|=%CgzT(Bjg?EzpS&j>trjT?Dx>S=>EkqgPONG z99X+5EICv6_~v+nAPEeP-RcY$I5U;L1=EdF|7)>Vy&o@Z*;1J`?h1H1RApKL{bXk9 zXkZKxz;4YewWnzsC$6g%kMUc4fg1?haPNx!q_Ag&y;rBTT)VeB8eN;Z9nPjkV3Qh^ zr#klRTfxwa1S0-Oxi)X??GC|Ew#M37l%pvvNi|-WAMWgb>9OP&TOgBrA#)%A=jD?|cZK@NTGu>10T=+Fb zYwtqp;$0(;FK>yy;)o$z_QP=c-6^|K`CATqJ~xjo#cGKk8ma%;`iDxULXjSyTb1s7 zjsK@dYIXxWg{6IcEoC#OnYo>n@Fd1pmGRO>9hMnlG#!|$uWUQ+t?neo;nkQe@<+OeyIn9sv8c~k0muZup zV5h%I{mA-0l+ioRozDGxKT+`l+?9`oX=r`~;LqRrs*5AJ!o$E! z=3#^|>>KJ)35ITNj}8Lj`h0(ne*O;JE_y?@Zf`f9l+pjt(S> zgQ+~fQ3-4>nN(GcYGmJ_0i7{WbcO@mj2fR=U0{_%DlkEnxQ-g>(Tg@0`TBHP@dPg6 zTK;HpZSB#XqBzYn*D`|&wt|T49LqhgK!Q@&5z`J3lt__&C!JtEt)Q7|(RNh)k1C^` zL1%jNN7cm9mWIx;;f~8GF2Xf@EmUP6`_;K!0V8 zJj#ZAGtD`F&f+`&z*~r4bbxW_@@8$!9A_TFak~4Q1S+afT>ZL- z8(Tr-AExWgNjd&_5=EVY8ED<>Ss`ZHMCCu$=3?z%bd;5B)0C=O2J8x?is3)vkrzhd zVo`bi-so0`*WaXf(IZ#|jc#_sbo%C=$}iZUeEOVj)7+}ba=G>eb8SD5hhuYlRHTQP zAO~Bdz!2Z+is6FscjH~#*#2Tzn48FYWv`vz*c#k>Zzw*WyAiGp{Pf%QTin^-y{|SU zNda9Jj(T%o4poaQHl3V0oF;)^QfFbbCmjwo=j||ZQfSbi0)uKYo)`1j$;#B{!V|4d#hM(R`4v> zx`(uE>X z7nq($uh(+0GA_TJj%D3Fks#ZL%wew?p(KkBMmWzKHD0>Mtzb93*YOhDv{RmSO^F$2 z5i?BPFS>SV{OQrxdwdI<&iR`w+$DtqnYaaMj;3Pauz;~#?CA6wzR0>cG^VV?VNOR64o3p`eYVq)S!&a~z+ist~{ITA~HcDEBekFFhxBqPJUgxbVtnA(EWl zFFNfEz8(1bzI+QlN3USUdtXtb>Dmk+7OZ_E`NbwKSjTMFqlPHJXDtygNXn8NdJkL7 zXzRm*L2G;L1}hCKeL>*&HvwWd79Vrl?FeENpL@o`g&R~(-x8@Qh7Hn787mn_r~64) z(-+kaoST0u?9~up>z}kmyV5A;zj@9(ij%F$;oGT~sU^=-6*J`|I*|6qq(zQd+Kg?w#4JpU8NQizx*9C& z9|mk*1*1DQl(zq-EqWJ{+s&hp^yX&qtCb&)`fd$2wY?I|#|pY9fhdmc%wH1Qmmaz! zUkQtS`e!8|1hVwqPZGY$iKriromtq}-Mn*{?c>3bjmO@ZF455DvsG3ki=zB$TvzJR zr>Gz6?k!Yw8p))gE5KUEid9~~Nd}Z6f^O|pIAD2I@hTb5)a?!lYURIpo$c*zTi+A6#e@+^~ zGDe8(?nWA`5AbvFv_YqPFO?cv_>I-xJZGVsA`kEx&06;#axo}(nhp#Ns+ofA1H}!D z%J;VwHp~&Na`h~rjPK4Cs;cf29rz6PM;ET*8`!PRZU557FqEh^wm;(~D1pP@5X#WU z8_&tBNC#9yIp@fX& z@9b=yWa#z(+v&$8_#6AeP`gi#%L^Q4YpEXIYg=~XCs%Wsf3B4CRqU6TdgfHwxubTb&^GdgFg)@%Es?3P5clsa$nWgVrozCyr`|z;{rEHWHXKWga zUlo#ZqU)IBLbp3tQF@o;afn<;WeK@w&=B_*H4i;^dJbAdI9p;uY6FOX?+COfa<$+d zsVPofik&QBB!sdZT)ZS0q2P?-3?Sp1s9Z3gZ3&4d ziU$=qG~#3j7XQ3W=RZFD8z`>~YMdwz0wYRGpt?7>=ssOrBv;^6tWIxH3|z}ym!XSA zUy-_6j&dw4{G@jaT#y0)*g$>U^V6r7n+pht>+iSzp6UD+m62+5UxJpm#L8+6zy0%C$F#A~F2|~uhQ?l+h3{)0 z#fe@oT{e0R#UQL!ro>)D7UbC9O-TN4>H*|Hdr6|}o|H_KxZ4}VvG7BohG@BqNABk8 zrA+lLIdM`~7F62oF*Z$vmP{Sk0a+%+`>sDE=3CPDh*s3%PNYX7@IUBepd76j2>tokNyMyZ3-zZH%+?{`DX{GxwhWi2`-L>@evG@#qN>p;&Neo+9S8h&G z2GUwljZ5`&A9!)v^(>V@FWveoUCd_O`xJa$XlC;NnpXl|&Z*#m=^o%$7mU321&@XQ zhUH)WHI6gjjbf*)mmO+Zfm)S9>?oJ-mrlA4HT%bK#`^ABa6m(ioJbUyMTLr+Pp#kT z)F1`=#didvzBM|@P1ved5a78WlH$p)-Wo!FDm~;Da=fT*mc8!}pSdap^2H0qX{|il;T;dnP;Kg=6LW62CJN+()#!D(AKO`7NOqQ~^ggHq5d!rD*~VR9~LZ z8SGAsxprOk=ogyYWm%m~<%s>W{~$jsTz)dXYBVhZDDo4G2B1|I$iLhXt7M6I?G{o&%<_ElK?b@wz7pI-X?N5xsf zmod3=saAdbrEVqQ-fF!(oPDFP`5D9gD7#%lh^==wK~=4g__C>S#VYC8>{oWfI@LHG zgLuWTjeq{RllFY1p8Un#!0i1u^ZQ@=tZo!Nb2ay0X?O~bjh7H=t(t7ciIp%i8Q!AL)8{0@joInhfm4iER*)LoVco?am` zJv{Y9Bfc(F^Z*56YQ%5^&*p?42`&?$Bx=!-OtND_%zEfs+PIV&<1)DWn#J)1?A&}5 zmN`UBrR!lKP)>4doH5MTf1mmT+Z9N9B$T^;2!`UeyRECQRW8M^^;{oJ+vVd}$#Wv* zI&@%_HGKGU#kjI@SO%zzBwlB-BQA)=#5WAZd0lu`8v2D{l-#>@AsCwayvN7Q#OL1z zCn9W|9@HpwJxvD9;&ZSC3U>4)<760i-Jj_5NQxQY1cu!%{&+f+%+)vgt?Qw^2F6$H zU+CTghMTN|C7)SRF)J*BXU5sv))t!hG<4FbcIiRW(9lF+7MFv;Ks|Si?e)xzeRXzd z4;|=9EKjvTd?3VaqW=Qh;gX7$wk!DgbR+8;Jh%Q!>u8q`qpqRJQGTScI9Fb&2R!X4 z0Tt*iR{W9YHekYdoAB{AZdroH4tVco+MI6HRLx8dbR|E3=)9M*B{x^!?&|o$F=N7v z<)?EhPgjKPtDg7(yOLNV>%oZvOnf?Tix_>r#tsNBDH^R@vbo#b!iC@b0?kN;;rK%mK6Mn7}qr zwu;@j=*tWb=|90s^uJGX>{b2g%NK#M{Do7{9L#Q! z^R+rdPk(sqt@*|HUi0BL%f}Fk?*jXkf6*_u$^(_wApL58i%eY8ic~HPjn{^2g2}up zxjxK)y%gbsq==a&FLzW=?oE@gf6w3b`P9SiJ*oI=YPj?W=QNo+{oH!=ZfvA9+-I^$ zC5dXOR-1Ux#cuGb_fp$+wo99#37p^B=sI(0SYFyqeD#GL^8J$f0)0Ne3)~ilFqWW| zgo6QOR)P?eI9FURfM9z}6!+5(jsx)$G;+1xBIHb;a%1@AoYR4$!Uz|brHlg~n$)cy z43#~V&3qn~@>O>GC9tO7n-} zXSWL}M0}fJV!Z9IssZd2;-Z0tXp}I_B4q>g>u1PeC&_)zsmzm%RLuMY3l%VpY2C9P z!izAI&7OYm(fS=9CwL~AAvgM$O!&T_b8n3L9DbLGug%_%IZMWkE?diMp301GOD;#L zZS)uM^k($7;!jNcP{ohaiC6ucsO!Ynh0jOgjUS^_2RH9xCVaWU5aggHI`XYsR4vM&WJn zqfm&vJOyFI7Yig#9kNn_KXKGL@1haJ&>QJ`ZId-LN;g0Lc%Bz77RlaJ(Pe{)e(vvT z_y3yfY=T7d2m%@3Oynz!`kk3X@ysVy+DEVl6Md1mr-9PEpz1QdZxQWWro9QJ;$G&C zc5n(PLc3)#ux>+3pj(qxww&5E0>Tw}3&1zf`a5~P#B1`#aoaiszrUX|3G#%*gpZcX zKpmx;A4+CQvuBfHGUrY>0zpBX_t~JLadH2a2joSMwEbf@z2VxJN#eg*t?sj=n7@WdSxtSdmRz7<;5ipioDD<- zBP_fAU~SXL@9>(!Nfc%=;(ctYYA|&;7;E5cTlRC$-OB66c75i#chuB5N;Zay{R)aG zT05MYFaEkn?Y~ub414;NheR)iQASZwHsi0hY0&q>Gg1!~Uh#lbO`X)Xr}@g?Ccnk6pK^ zIz^ah4};&0+Gmszazs!L%FT2j3x{?L+lg;JH_V{9T3X?*dj3E{`D+~|w@_XQ4MrS5x zvk_gy^9=9_IIY*wypQR?{L(@}K`Cdvi+Fp2q&CbG+Dq0u8xTF#N&ITPS_Pe}VqpA_ z8GubK%mU& zA9DK(D(`MRG)7|IdRrzECMw8(@I*~DD`hf^wHLmVOZ;++!!6;LH<49pr%b`L$5afjVtv$g+Tba=Ksw zdsBi=_h8XWL1ET}*+N%gD^;@29=_ML^f&V=S1)@lABzt;kHv0jv+paw4ls@v(GOKW z^BkhXRq`Je;6MA;vhU%JkWW`;89w@e4{Q(YMp1k9kcLPK2JH;)S@pgibzh6TACB5) zp`YrPaqor37-=J!g> zkKWkvT+*W2k>ZA);u|doHwyInEN#5|>#E%DJ8#?39*ReoT{`N)dPxcC?@y??mdC1n z22Xgbz9O^zS*fApAtvA#c9m!=58<$UQ*H3(dj6*(`OtY2-BG_W8i<7PoiGQ5?xdp) z15aBeg2f<$$N11W;y|2Bx6xQ)8eCrlI{7y7u@DIFIdZsFKXaya1~oD2`$LQoIPHXY zg;|Cawap{w6D7rA7mVXg)#Ik{RtJ^lx}qN{0itE2&97r$^C?>0BYU|JbcWKPZ5Nl8 z?=GhjIX$8{3ajT){#?J~SpMd_*LBk^mw>(K-#AMso_MQSIy8~I_K)F1t$A=emF|2H zU5!kgX@;~}rFI{O)9Vxwn~0S;*RMvjm65q|IZRBlaL5v?P zWP?L?;i|e?&L>pGb;)bj4~k2tmOEU0|0x35E>8CpDv#S?_o9l9@nbdP(yqy&*U+T+{*cQ&aZ<{*525BSDBqUq=}x%Chjw^;*5Jz;H>uG651565%8C_T_;hhb#m zDV}~>tP_ki#(A%e9J2$b%goTxB&e2+e7IVu*zS5c!@7`}Widdi2YC z>-axW_*|mT%wRyNb+<)VGTKrxU``XR>L750bXiMXMmASg)U%S5JRdmcX5%0|9kOgn z1yoA3%o@$Du#r&xHenOel+Zd)%!zP^fR^3_dSeUv;!G!R5A}uN*JFCFO_4fw(Kb@r zHpv>Q1je887BBn681h0xs)ZS!dYYR%BH(%q!VVdYH2v3F4%`@5=!z0x#r`v*^&gTr z9GgA-?mDxQ-;?$#X>N8X#zbU5nU|bR?XW`0@5X9Rq)St91Tfa{(vzoqh8DwA;0rJL}dr*iyxLvJaa?7Sqyf46phPbNFWV;N$m4jW9&x-OKBQ_`a=I~Hu-<1N$<;%yq87!Cy=PjSg;QhYA^&Rc%Si**$YM?Tha74hADL`jH~R~p zzR=a}swORA(oe(AD8Bm(w%C>M%SNk(ui=|@bH()7h4x({pKa4TNq+>yA?!rGlO``P?)^=PajHCH_z zkAr7r5j_QM5v0Xo4P2#bC!eajn|bldelgO2YrHz~W+eFzzcbl|RGvqSYYDhoxf=|A zn8HC79ZuYprE8BHJraPZTa#K@-^h0Gr~E#fj@PeAzO_az=oN80dU2aWV5lSv;DaYO zN0AA+#6;JqOmU6oU;B@_yFOKiGHs~zzmnM!2%cDM866_lUo@}^?RH!^6uKNDmi@st zx@$79*Xza@?_>G;-Et5b5{U7=@4FQLt+ng>Di>OTZ~1cArg|;YU_Ozc|8Z6*DIKre zkyiB|0TWJk7v<;;Hltxejf**_ZYU!%e<)<3^Ef39>xPClrzJ*4Y4yLKd~ut~y`|_2 ztEKjCp%O-dl&vE6FN?~aOmsI^i%$5zV-RJZLKMjjC3ysbIV5%$+@v|x)lrDv*fpL0 zRV)<&5E-3;I6u);6Xz6pn@eF>lkSRF$leS81)VcvF5I%#x?b)4L{rxom6RZev4VKd z)|vl4&P~>hZ~7;XFqlP`i9uD9O`oFl%E(B(C2{l}|MS~fVhjwm54>mt0n`)5{7>}o zzA{x_F^dmdMa-0|?Gp@;(#e|KQ|)bCuu061lb+Cgv%Bsi4q}yjh>REMh%W$K8;(=hRTs`>?!6JxMv!k%nGlz|;S= zwQilUEO78uvrH)ysTO+;{?1;s{+!-i!#Dbb=%0Ek|6h1nnVTUrZR!8`QWr?=2xR26;wjDXipspyPG-zQFIHZQ zk&Vg8I0d?z>HRVQVdcHg{Y>#vH^#>ciDPM!rYx7+tSQ1r0e0qrVs_!v#fj@XuJ?`z zdJ%1T(HZuERZ-gpD_TWAaH3Ya6uTPuTMKVcOEV-vqU_?lqNWlV@O-^g{-6Fy- zKjF7|EuWp279Scecb8O_>_Mcc(!)aeMhh%@nq_vAlUCpt(oPb_vBQ$5c}E4233gA2 zazah;BCY8N>Pl@&a8@I5B8CJ`MA55>!TI;>yU7-%@Ci=)!R}HTvzOG=N(jYLvBtJ= zfj;Wj)qbfPqlVRZ``_u3@()^kKk}}*p0%`QyD)uPFZ|}`9_s_Ft&t)!U8&g`J`)rh z!RE`}t<`aCmluxKhn$8kGZVuV2V*p&Z4WstVPsnC(PqNcL2dU~!y>u`Ue+i#$K^k~ zpT^fGCRFF<=pGdlh2ucnbm^BM#Tps(27QN1wtuM$f#~M=Rm;f(?k?veoS_D!pFThM zaC_9}ac-f@3_d*U*iqFu(A*u5fF;+p)jzf82uCH#6TwMsiZWF;ZL^7P+@W(4zssb% zy!MijZrZFBvc36WQNE zTIE$K^U29gwAa92e(%-dZud`K+|wsP>*FQ#U0dTz*8>ws@|6x&YOI@$U5}s(ynU?_ z+L%+$mgY5LSXoqDZgS_qpV<~CSF@(nW`j7?Zz+8AQ)c`9j#dHwN1Kl(1|7hBxWh_n z|A-_wGh#Ny6p^KG!40f9^_E_VC$cF0A@TMi^qXVu6i#6#AfuoKN7ROU0cldiC!$AX z3dlhzDhl15l{QtGEo#nHPKI&_i-IXC2Jp|0E6^V1BJpA0pyOcK8wA$=OIjqP2nX5m z$$>XE#@YztPXxr`9Uo}QY6u%GNv%}js(*&}5oeeha|BxkL?jVp?dA47{q?WVw_NY{ zw`>E{2wIF~2LI{xa3~F2tW$D1A$Q~~S#WfUYCfCzJlsj-bL@4$0wrsv0BzGz!9>Ua zU?3Tii)RYfcVdU1u|0e`VT?TyHl>Z|V)x#wKjutd&=L6G1gDHtg}cjbCiGR^dIOHvVnZ$>6~839@+9L)vBVQM16rehO>&dQ?JVe_nGmMbMPHix~!wgP_;& zZSiu;BD$G@@it4TXvJjcT$!Yf94t=r)Fhsvuta_(@o) z1y*?t<@p=p$;ru|lx-IJyh~mMnyL8Nugq=iEhra6uJjGh1>WAr_Ot7K0A@B~-NS{k zU^cbGXCLv?hz+O>TaYI9uY-zo=6UE&y1UFWQX|PZ)fEr-qlw?_iz)E46wKeG43p+* zvw4DrV(VamjIO{p-P_88V*_SiS=3gu6sO^LPBOG16kr? z=YvAgo^`cJjF?9Sb1?)d&YV#UJY_4)tVt>`W&8&wq%bd-Ng_xgLD@-#^Py~)1cC*o z$?P^HCMqf_CKmi0Uj|?<@y(o?nP~t>EG8%Qnvxj>2VWfFyxo2#SqMCh$(cXUK}p5l z2iV8nvdu@o!hj;@!RH^oVt{Ztd3UzrYl#+*Y0Px_Oida{V|=<|IYeYq-1_3G$*eV!#~Yx14GFnldIHSnLZMJVvE}eQ zfH4l>+9E;z0R-G6BqRWah~EHH9#Dk#xO`i7ZTASH%;T&YP`L6~-Uqm`?0JEJVJbL5 zJ);zn2O$7V8#{ z%9@T-co<>W@6Fxa4*{YQU?SEsV({rx`JoJ|lvI}2rA~q_QX+zU18qgLT&bGe!_0XB z4xflfE* zNxKcTkxo+)hh;aH2|s>5cHm-)&>OIVI^=z#kewAmy~eRJVNtWbwDz}-rzsG)T$;=b zItg#8^Re9=O(T05Q(A@l{`tc@!)P{%7J%P@O4tp}LI|P!XmJJzib^(|jT3W76wAQx zyIr*dz;KLIte|qB0T>6sT?UMCEKkF=o-~{Z8~!x$V48pjs_&_O z93nYowwxoii1<@C{Okge#~MGzV^bgF4Gw_JObB(5<|X&We9Eu)C%QT0lTrZ1{I)E; zkBt8k>%uJyf8Hn!@vPhsZ5TTeFRh`-ju!<8`T)XnGAj#GYT!1Vop%7bp|dhm<2vv+ zI^KimsOW$LHmQ`{bUW6F`>NgGndfV)Stn#xGtPS4w7Jh8-la(vG@>Xyk#P{ToDmPd zDZUhvXz+=PvK-_~@9t&lAssVHQf6SW@%Q%^OiKW{4`E_r-t6sPy8!w)V`F3U^Yh;h z*}laF#P1DFlRKUU)Jzt!ZjK9Lm>_>U0J?x1ZHvH`7_kP*ZDp8Kyn%@z$I_}9XUgtQ z%NUP6-Wg)$EHajr%yGu?1Ha9n>l=j6uRqP>=>QS#Po&rs^|`?Jw5Md`&}AXCZX-Z&6W_mXSs^SbxiB+x4p3$7&QyKm(F4VlPd~f) zy%yxRp8O07HY_h@u*Z67%!!?>H*4>m^9~w51k<~ai6aCx!#)lMEmw#Md4LC8`TN%!~vPnC(1m8QtU~ zn9)C{k__+#IO%4bQGk&FK4|eOfMxOB!on*SSj*bE@}J9~o4u3+cQeVje&2W5!eK1G zEsJ_SThQ0MG6^n^r=_*+5j-5}s=l{nChoUCiF!f4q6*2QALeG*9Q`#@3OC_I9-RXO zMl&U*sPEsu1B`ntux5a=s(P}twA9qp6nO3~QVI!#Hyc2%1n>{mw4f;^q{jYkfy0G; zG_VHa1z!U9 zf%I?H-W;nK-*o!mg;whHA>Whb!MT21Y4NUWLHWseV{KZ`=1&=wH|q9`RiN}^l1DE~ ztyp3v^n%oevKsIC+wD}K7(V9Zk{F4HGZ0hCfD_l31}nyhCA;)W2@R*)6gNP&@%r*b-7w`+l!rpcvpivn41Crkw<4 zd2oLCqQeT1sZNOaw}{;~i-qw1tH(V^C{!y6RChsO7_r!_DkkwUVisC}FqMC88%$McFs0`+_Z)wwfcY$Oh(G_1JYDi`$0jLmbnJ(xVX5I0LM2##H1*hCDg^uSzm_FXLGnH zB6f;*sWI^D`xwt@v#{RIXmgY3^n}Sd>u2g{8yi=%?VziXJzb0JdUaH?`h3ec-B;pY znaG(_e1J#>K|K-}7*JI!6$QSEg$yD6UmM*FaxGqWy6%s$*B!TuJfiC7#rpOKm2%$p=bPWw z-Tb~er#7kBT{V0eW*Bb@S^^49{s$2KpiroH@7_fRtkHeDLVTlw(h#t~KH$rA8{Jc2 zQZA>K4E*z_*_M_&hCknWAf!A}onfe`Z~J*)V#*$hRb#H|9O+#$`1mPNRZ7kFs+MV3 z=ASLFRLyE_+T*R4#MYFhbejbmfQ6ZWSW#Pb%dLoZ@^Z z&bKiZ>2VeWe3?3~87w!&NW7?FdAa<^<@afwm5bKFwspR|(3oWtIb|%G+Uj1ZGdq9D zuQh2-IRXxOf$|*<0N@9|;&p}+$l2>_^rpKh=vSh{Kqe|&a64IfhH zwH78IQ-4C{?V103qc=1z4huwKY2siNvC@GZGYJ$=N_e^y4?jdD2+F&S4lr9KuXRvQ zFPy0O*VWvo56FqP%>TsM`iR@`T2(ir$@B>4atF8$BNG!6iNp$N16~B6P6ZGe0+eZi zKq!=$_|z&QP{A@s^Q%N_(01LM;_~wS%1ypXhyPdDw>0ay@RdTaDI%9SuGhX4;Np+v zqOcB4daS1~%t=rd1&`Ymjy3dlAKEj3tI1K?6iB?I(Y%mkgzB9 zTadP%bfswkG9&Y+3u^fi!*O9`dw%kR>^=I?8m;~=j<1O6GFRo}A|fF?LUm(~R>v!U zMoF!zX{9TkQa{pd_1V7Y-k+;3OXzox!6eJ5w-WU9J~dQ!NP9Q^=6UUok#bQDH5r)* zKo0-Vp{;_WIxkOj@Hbyjr` zV@f2z2$1G%_>rY|vdUey0|3NKd%fTqL=E(G#S6%Qga(BYl&5jzoIZ@UD;eMNK$DM` z7sQ$XCYg^5cSfx-F_h*DJ& zZe*a%;u0bc_W4d8)?7ccgEM(!{TY@`Tg0cQ`*WTCJrVpJ*k*C7&!%T9ip#A$?CQ%n zfK;+j0mQ=4{GC)@-eXAVW!Klx&|aa1fHArCF{J$asJ#}cn`IdmYL2uck4|MuHUjxs z?xI~o0Bg+oM2*OYjHe+Z%%Ln4+sc}j78a@D9;mP#h*~;QcS-$M6J}Qv z052_?wo~dXSn6xe5pSDKz7fWhQ~)r8p52i8`){|Q{tf>Zaq#P15BP%_Xl5p|6JkQe zJQWdJti73vRE|>JE3Y#Gv{)+Nzk#?8OCiP(LCwcf-_E*<&ea)JsI6W@elZk&@q1+@ zJ_OrnKiY!%*tPn*^;tKEMHs7Am)1GyI=zxRLQHzsg@`}tLPGin-1r4*xy`19^vJ9O zt@y}9&f;iYd$EpkcDFB#+@B;EHKf>u|5L{Xc~#Qsy;;T3)4^_T(ve`P&^1?4w*I5Z zrws4Iq_P`bjo?KaP7(+pUY6lX>IZaeDaptzBD}o4dAr1ioxtG1b$1jlV)3b5_~Vea z<6}=1m44t10eTcedwVWJ=WT88BXdF(l~elHoxhs`(9!b%_y_TGvFLFwQus3lv>Tff z|6Tq9otFZmuO@h9kPGKDK}8lIW>tZKym~#nMpWf$^^&&ohxc|vJVQ3CbXXq-ls+L~ z%B%hoG30x50J{zf@Zl%4_+CRVO>%vy++^GZCwCeNNwp+~rrg)XZs-oL7!K^UTw%3@ zR+yNpO0F52Igb))ELLo-`R`+MTAM{SG0JJ^T^c3n+2!Kx&3%4kJ)r2$B^V#dH7V&7 zNYgmsne!-=XU#iyBP<1#U1?{vuYhtkjniUeb^Hk@4X;57@A@AN0^)@LWl>#S9UBZd z!$1y$1#s#6`{Unh-KVf}Z=fWw;U&B5W)5>6L(1f6vOf)6Tm%dbkg4xdJPdyRbx^c# zofm1sVzc<-3`hzyB>YhT8Q`;vk&k;Vr>{=)W4-oz?FLCbqVdoM3IG2zNT*Ymhh)`* z?_u!(Ql`=nt~-@}VRY49Bao3Tvi@FfUDuR@ZwxEV44=3*K>ejZD#8Eq))oO_H zOAkx=I21o0lttYdo2eapY-7dvQoJkjryLZUPcAH(h7KFTYvjb~>mQzk)fRcsfOq-} zWZ`bkd6~KuX*JBuqU5r*+h}Ku$I_|9ou}kv<>}mHN--MoNs*;96#G$L0*^d}?WYeh zyQSwi#my2B$xLN?QaR&nY>ZHly7(!Rga0yS zx6s1a4w(F)Gryd;wJiVv8t}=>YuDpxx+mi2++b4ssFJ7as2K>$0N&Zi$Vdq^1Ma+6 z5?0dua2ne?pPwGV7d{yEF3TQ(V;cgaefJ zY2;=S+1FYTd}7~i%ku@S80RLauCD3QZn~qLB?8_o8()6B&bj$hvPNuir@$jd5ULby z`D$6To*NnBnLxlJ3;lF2r8Cuxea@wl z;CMD&k;sbGb(AnEH_L7HDT1b}UeL&19{OlSi#=gUKJ7bEVCgay1!4~|i=ZZF2!4?u z&hrKMh!-E!8*@;9{U9wdGUWYnz&-rKaN|8^c& zd)IzKGi4qkpl6M=5m61FX?wo(NwoaP_~wh?dp3*8G84I)jUmcQc#d*!(+0UqZP0tJ z7CCbdik!+iMnX|8$H?&2yJN3E_}q6_=UJ3Xpeh!V`szijO}sKEKh%5OBe)z{UzkE5 z577WSKiXdyZSen#z(qpH_x)kt-jKJ_y{0+1e73YtkA`b z{rXj0s|fI*MKt_65M$*wo__u}OB#7n+c!bH*1FhVL_;_*rCL!>=$6GR|B_-h_~weF zu2^G76w-QjC0qDLnA`8{PxGP3n2M1UQoN8Y`b5XJFt4_3NWZ}0mFIz<(yPtM8Y&;~ z=F>_Yi+41Gk%AkR%}#8Ufs1BoCqBm;wWu|rW6!k!StteX?B|~WwzgX%Ij6WgK~4by zVMME$zr}|aUKxivYul#X0iriR=b_Amb9i9jgGF+$_2Ky+KviILejaQ_VQ)rif7ibB zHVK*`1g5Z?z)dnNHtu*DIpdRX;UcFm*!g*TJR{B8Z)78>*fojv62^L@YE zo(+1y)y%KqWc<;8h6GPfX!46Xt5f2LATIxQq^cg}7%VVMTTH~RGwijUFKS8A;&l!` zZxy$0{z1cGPe+M$W`pK;RXJ5&27{5@Rm?*=|Ji;Er)_=Q?!t2;-dWO?*5Z@kx{?D= zLr2@>4f(nn>!Zvm!b20%wYINJ$dj4}5@16Ye&ZdGWdtDZECR6W0wO8H=^}gr0yc4$ zX}E}znWtiirwEsCNIyBC3iIYfKgbK-;1#aYxvY-nfNth9q}Gt0-e)s&zVhMrSc)t9U|=l$o&Stg%`GWNc;N4J}FSNsI3ygs`w;F+%lOl!8<`nF!- zi$4?X+Ke-L@1@&GkU6y98-whew=t{9#IrJR#WA!qGBN_Brmq1OzMLGIG^!>PIVYg4 zRJ9#pfk|q$BD|3f1R`j*>xZ14CF&>h1szy*}2rZLQ5em3i_w1c+~$p8yo3 z83EbeHDw{y^R+ylgWb0&7}Ta%?1^*1bF(%mWilbQ%e@82M63U$PTXtjs># zW8rv0l1gqXz{qmF)BeHwH%gU1q=!7^}l`t3T@d5V0I#2R~S6d6G@ zle>}oNdQ>|g3cj3d`Y`NO2Z_xXSDwHH$8~UMM=oY2M!A$Kv#BXvh9WpkXAKRMFyKz z@G;Q(mYx9l2*8DkCSaeM%tV0f`&)>){dC~CqK5cjJGY;L90e0b+Z7cRwY9ZCWD1mx zhK5KO#*o&>XdDHGkjVd(Ix-lxcAfh$(zIqrW{$)uau|!#itQA2H}puh8UfU*nD+hV z6ZPd+1xXiW+bkANk*mTRGM{Ncke&hmkI`}oiVon2qWGtlMX*U_76z-K6s7>Roj(m# z*K+|%Ujfw!ublJi1TBV?$RiTP;ax+S(1K-9YsHmki!a) zk_7Ml)9}^gPr1zQ_lL@|LQNa6jse6xkeQ)5ja(NOrl#yZ62xF#u@Hzh?WPKGG;qKo za(g7y^qU7nqyo-<1FXt|l9H_e|MBU=ojQ{wypM#j7DBWRz%&1UgA9F_6Mn%@n|P)# z=ElP@w*@Q|Pev5g*DqA+C3=Ub1+#1-W`y<|Ht>2e_$OY`HBehc40ea$Lntw&xkW{1 z7Z;zsjG4RuN{`X2fI`*Fn0P9!CrT{c-Q6F%p@4HS$BHu+6~*e-7>G^?LVmmY)Hq`G z0WtMxc6%Jv5-`_#tO2NH15D-nzkcRvYiozw3@N+iOoYS(St{2Id#n0L*-XLt-pio6 zIro0xal8TX2Y?E=gi~XEr|6Dd-J-<(Mt+i7Ce{SyqI-+2#oS@JGC6?I)X3D7LMS@| zHe9F3l07pRkY0K?nxBBc!Y-VR25n8idgUT!<9!yn3Tf$;q zkM$80-3LE{F`1Z{5VN!BXv%;5?94YP=w^I;e0q9%WMl*o;RYhrQZ8yLs>s|gFxYyO z*q%KY40do>PDi*h(COESv)BM%01|6JyX}WaonM`QRhECaIWMHFY^v6-84zfbJo|y? z?e)Lf`_8T?v#ndYMMMQeQHdrbNtT>xL?sG{2o^c#93?9#hzLr~ARy3Wp`gfx36PwN zP$bD2$rlAHkApWb3=Q4bO&K?ep@k8DuPqK#<{IDM+#L`uRp8G6i97 zYC51ru-cr={)?*F$f{{lT7mxX8AT>Etbuof*-9IaghjG2kudT!ZBEbRzR^+N`JQap zLf(rlTmgGEKqYy3c{LYCMn=3OB!z_s@OXT8HyV~yJ65z%1*gq|y9Z)t1Ur0Z_m8q9 zHt)c=zh!~&OhiNkc+QA=?R;MPWT240^r!V^2?rR_@-B)obq);-!dh=I9JPm)%>!@k zM9`2m$K_31&9LEOQ)TZ=CzCMKpF-CbQVuzx7HPAJsO z%&Zg#%z%@VQ+;e`C>eBUXGq%I1rkX8UN}kc@Ql;gQW-%Z$r;l;vp!%gkkD!icBz1h zT{6<(d=%`EqtgqUR$&`z4ID2RP=pQaNn-A6U@4-xfWzUuBu2Zs=wJOb=0O}rz&m%* z?}=NvYPJ}dIl}7uxcK;DwqJ>!$r>z|0bK~aA?X8897s7&)dZ&82b?AaYOJ=R10vru zTkgGq)B~;)ZZ0k%p`ku2o}&slb$kF7oGbwzGQW?drBCGtAcMaH%O?vPn@10K8{Z_p zSv=(^<&>=^kMUH>{B`e5P*6}<*hM2nx(1}GO^S9(X607KCHL(=mO4gc;s5vgpR?-! zSYgUGl1ukt$b$9{d}80aSb_x1`f=x}u}Vuz`}_O9zL%<+J-NOM(eozp+d2Tw0Q)Fi z^4HSTgg|7ve-j|0jm=F)z4QjEgyiJp*w_wD%HTTH?8^;zXR6WYh`R!J?-qd<0XGR^ z{ajGMN$+Si23x0t>&9WHGG~T%m8%UoA?%6;dF#J%J4;pAxZlbU z^EoJAF!|Nx1Y5HmtVQkm4>@(qOommP;M1#fs77|#F5q^twXl3vKEv>d{(b_1s9CmJ z@kQ5S%^}A9DETQcGW!L)^xw>a@eTZLbS;T&v?sICYV-dNDG_Xn(}^0aQP9yr4bj=z z2{C*hJ32VnBzyr8+qbm0mjQ+A>OPZy+mc}duFJYy@xDNhQZJr018P#R zpV`~r4-5G0Q|9>f+$eCzR$3*}QRzQ~~dbxV+~S;1M4zE-u0y{OrDN>X`>? z_m=VvoD3-a@IMAlw{DsEV}u5;TQ%UR7jI?e=%IC?m!)4 zXJ;oPBf}Y^5Z#g4WTf+zi}9^xM9u9*OeD`+`g|9Ggpi5n`ubxKA>g`$wFrD`Y6_-d z{74J@W;RMg7kM%@9-CmG;Q{N&;iAGmY}mlRTm{R=BPc4Z41z*?ZNIBCwzsumVL3Uh zP+x;R?Innpcb|kql&I*rgo*6J(sm5f zQ+7biYB$f#iZF8)#(J|r{DfuYKtln!o~xceKQ~u|hwtRGZxS#5^4-hwt%NfNHQJf$ z&%cbw(I)L)5c4uct?|4(sj3*A+xQyH;(md}`<>YUis>F{Gl+!+heennmG~}vfXt2YU+KS+r zfJeO*FnbW|pU5wPu@Ypy&w&(S9L5;x64LlP7jNJ#%_Gc7lGtsOY_njXOxBII)$qoJ zeU+gH6;y+!-L5tnsun&zBUe*_ngIqzn=?i}185R3W3T}N7Zxyk!CG;|xwAV<8L^ZF zJExNFJ*?e@5<#&j3B9fV5GbUc*q9Np2j-Ju?#@D9Mr?Ta`AgyXVzF2#`k?CzyzcRL zRaL^JqHG(%MC;7OOnKW+mLG;6w(8kZ8-3&EtN-DUR|>H;KYs~~oe$uh`Tq950XCxO z+}zxul?R#e9yCV2Wq$DJOj)@{(=x`z6{!46Ev{x|81`pRIJ|qRRDGcn4;l0#c9w}z=elkj#vo#-Q0HRUu2F2q`>V9-J;rP?`}_N~ zt08uX(}BQ!jGS$ScAF_$z$Ga*w!hrL$k*4Gt^p`tDCyuI0-Bd|ZGMEY+GA92IXW`; z1|@?t>b1p(nPd*W&S9&QlamJrVi(<$&Gt?EM+y5SXkFhQE<+NK*lkn>co{jbz~AZZ ze4|7PUm&*N{@TGN@nsYLH_1q4_wnw55tuE<=T(MYASlSl^d++Ko7)racm4kOa*~jP zp}9GbH!w)oY6_JMVuxed%bM^fp2h$_EVLUgE^5~Lv)FV!q}lOyDK1LB&h!W7+AG!h z1XyGbMINl$Uj@4YpCv0je3e^aNG*pJQ(oknSi8;~C`}N9Wq^^s2VS^9LQ5U1Dr(Nj7pD|4@h;q`P4CC?+oM4ZR)MCJpFo5?>5RtvOg; zUIzcGDJq?XaD`!%Em}f(^|xuSEURyS<*Z6=wXe5c0L~S%OXSdE?gJL zr&Iy3IDX^CVdo8Tu(1as(twIcNDAB^cNqWi<;!1?R^#&6 zNSWxhz9otkKC(DNM1+_y!v){R>H)W4YU%@b4%vbK?ylzz?J-*l;{1WYX#c-oa?)g&r4;CO1EB-?kxo*y>!xLje>Ljwk~b|@TFWynQL8hw2nPz zj3?A#0IQCI#}L%9f`XI*sWa{cPtIHndG`){jF;iXmEJj)z97B=!<5h8k_B@lmo3<60*#rz<62b9&;)>c&k+1Id&6bEf>N(o$ey6z*v7r8~H z-XDf@)cL$Iw2v=8c>F1HJkgAYy1xI{_dsy9t^;(I1lVoJhz3;2K+QTkZ+v-qN+y(U zZe;~2SH_Jz z%SqqZc(G@+OgTcLkr2W@aW( zqf2dIIlH3;&#j>$xGt@=yw$LbLgTybr9qJ+lO6GTA5sTuQ~$K6d(Eh zsuaAR{id%_vwSR!j88~d7qbJyDTJW}V=x>Xvq&R2)M%Nahv^z<#iPcyf-|IKwY z&Xo){B4D#aN=B9}?34*bAC0kSy~#pj1{2q4Y1_xTP-+ap0FKA^VB*A-z4ma)?s!&4 zvY40nR%KO{UBy&17*b6-3Tsh;6o;Bn%F4=$oDfbeWMvGOz{P>QA?>|$Ung(0X4E7P z^JrfzshNjb4&VaE3Naxep%WFCh=ha>oD-I}+R=b3WZ+yyp$yr){a&mXVB{6A8Bqv% z*cH4TgfibkeZg1c*p)zo*!CITI2bp;91IkEO@>C%1bhV{LN5R%4WU_J+w-(#zd0>I z0R=Mr_dm&0kO@{TQ$ul62!R%MIRm|x5eZ_w&o*@`cAERW0!hSvf633~1SCA&xAuSB zx7g1(?Ai{Nsy^@-E|8HOZDdITOW9`311cQelwD{D^!B=9pk3zClEbLEMra&w#}40l z_4#~+YGwCnso!;6J`T3F%ei`omR42^P^v=rySKLoahK`U?9vjc-Ce8Kcu@(Y`L9 z(G@7Mk(vd`9r4-#b32=_LIC1yo3qmj;%5h3gSWgTW10sc7p?xA7tQ}YPmY73~e#CNHTN{#7x4rj=fk6Zw5lnK{8zhfb zp+sLfXj^$@u(Mx#yq}?Z2cE~s&E;EN8SZ5@ES|d9pAY*5yx~IyfeZOiW^cp$8^=Fo zB>ZMi=J}>io(%zkCDn}^$IEWDRbcv+BqvP89EE#Rd z;z&(QMnaM(;$rFS%tsU&`+9n?jqp?cfeV{6ZFT{r?ctW; zcW$I05d@Q5=;lGymQ`5TzJ(H~hdxJHQ4uQgnFXk!Pp|a*a=b^tFwlEb8j0G_P--_5rDS;M)&54 zUG9k5cv*a(lFwM%!rQ$M4Yh^fqsHpu>?{VqL5f`E>F7v&ccr*Mrt_7;Y}vkyxW*AO z+t^m|CGfa5fQ)8t{u66vXKZW?e{o6td`6x1iswUQ1azy;-*wHgVsZcI_wUa$?oeJM z=ESXrTJ!OJhJAp$41(Q|4cJ*j*#eEq()|1&xB$H5Ih~OGSVYQ!v71{NX&6w9@CB&Wg&PuL5Yq$%OjiO9 zSM4PUY_pdI1~YG9?v{xExN68-4=?#CYn0#3zq-xfDZWS`KVf!Y(!l>}JHK1kINPH2 zpeQ#t;(P;zayQm|8H)5z_orvW$BDXC(_}u&@i}CQc&7|skD;XK1k?=ayWn+90z(Nn zOe5vtos4i=SJ8pCZ?49!W+i7r-@jM51I@)D{6rv`dLE(OzCArs4d zwy3w>qA67~TlX95FK6GIFm{?(I}VwABKuSkZ%XO9rp>txmM*@>`=j7)b_mgY4az-u zHNMllDMgGez>S_C0^b&(#D=@sFP}r4FX3CnJbGXNwY@;-Sr)N5AwcRj^Qhqd9TPjD z8L@;`-MMyT=AGa`@njDntlV%4p&5Z%@#yFXq7NLs5m&qo91*pPCh?H7e0rryIpHB|7^4z#nKt30 zP&7xMtMx)mM)&(Fd=36+^=M>&zjIkGy4BBQZg=OqlO||Im*?o)n^&qO0v#(739D$l z6#VWul_$@jrpAqgi!q8n0B1?LhcX?uAvWV27zi0x&3Ix>X zbjC|(+t)vdpe#eBr9OYKufSjg;uMLb?7>dY3;a-{L+5T1&o3-ERY3CSw#Si-^YcV+ z&A)BLR@9ojYL1~BjTT9V>p zHojZv6jHyjFq!LNx?~LwIXO8aJN1GEZ~~z^0K|Z2rgX|Y{JXq0YinIS^N_7l{IkKajE!nYW*Gv zCIRS$j#kupRz*WY!_Cdjc}-^oY?q3_T&i|Ap;nG5f|Qih#l?l6pWnFS3tvOvWdd?8 z9}t}zKHMWwJoEK(ydZ@1k7)Ed01b};`tkLx-J;Z*nlrWG6wu=5Q^(2nB+`&QXqO^4Mh_ev`G}LAt21rf7S08XJJ1EBE`IeC_rU2jm`me=@j)t>az1jS+wP^!XP2M!SML%oA>%04jH zHfkV4v8r?#Sd4VsZgy%Vy2R@(&~5LO&S(15?`@+otcX-&opRUZjDbpZbiG|t@5vJ< z@Ou4WU1@sSz{k&GDW}DeoRgX4@cyX!)&~=puh|8 zawJYcAq(ngp@i1>RQIB12OWVD&Ul-$jP5x=sN&;k&SHIWH*5(cmAz#DAXps-b=^%^ zT=~VBJ1Vw++k13dyd81Gj$ubR0_zFjex6>fuBnU3b=S4qis2GgqE0|NfDz~clqs%m zZUDwLx(+|7PjpEqD(=h%+sf94z00I#0KY2oI8=_t)ovn+vZd4WE`}(%ip)E#0{o;W|Qo*6mkYJz!0+(bk{ZLRoi0|*re1lyo9gCX@C+$O+y3DqtEWzlsbb!pGIddrF5A_PF()lhth>g zaKznC0rN9RaG0{PLKNB*{yX56sAy@ObhZnsmg5EOl9RItTOGsKR?e;c^`}Wlvh*BU zOfX5Qs({TdBGT?>c4a|A`^@I(g-;kp;59Jb(8;WLuXu(|R4?ePta;Z$X;xHpH%u0u zS@#WK%5Lf&z{JdtcN^5@m6=D>baZq>05O6IwamkZh?yKXC2OnKqFt|AePmy%55LWP zDF~2|+P&P`aO!74sHvA2%h`d4wIucEcjW^-#TFUqu#x9r<@m^soKSVVv%kL_{0b4} zGT?m&4Za5rP_`$DxSX5?-X4dEj=QC*1J${v=d@Rq*A*w*fBpIerniaWo&qWD&3=J% z&d}HGgI!^xF;7I}<={F%{P_9!AonzPch7CWKX`h0K<_d+0^Z(W!x=4~0f!Abz&Ifs z(K|KP-v0h)ESI(WfUrY>>$SIcOQOO^{^t!4Gq z4+b;opLP~!WM|7Ylw=*9A{xs<FS>-X1ut+GK(l2X?G-riLXO(>HXW=h}v6m@=?isqpl zkFdvi=`Y`uaiWtUssSk?Q$z)%Lb`^=nRQA|?dO20f;l8K{XioQ<8T<~Io0-cpS6e- z#Je2`4(Nv>q_3Pio#c(Nsj95>fFv>J>;Zr*U<;tV1>zuv9UMz7dSHgRpKF|$f zZ2EAx(0A{k_=xUQF^ImOkh>LUu?Da&1TWupL0@!wy0ix?L+5oWs^8v{af(~p+X{^V z)B%>2`C2VMP}@D_0yJ`34}V+YT_sYKGgKRmRlm747Xy}oSUM}5UI$fKRaI5(R%xMo zG9{sur{_LI_6!nZaGr!zc)lqL7tRCpUG+0|q`B6CiV=8ejQ-a@EexX1nqM=Bj@9Kg zbZS9y{m|A?;o_hXS&-C_9luej(`j~kA~QmZ1)7fM(#Xz5beO*gBO7wSe%{x`!dfb)jK-E9mRQI?9pnfrKJT> zZ2B))w=U)M=us=gH1Mj$!{|?|DZUrq2q&8D#v-}YZ^6Q!ubnt zfm8(HmYiosV=4xtUhiqrrZFgB9EaQ_pl50h)|!i9u=6L~GFx4`@ zF3%1((LdpNujPYCB#rV$`lZ$Z7vcNshRnML-P!hr=E!w8@vhOo+NlrRWe*M~z{eMR zyPan==e^0zKFkuZLO{HONJU5qMwk|F>w!RV&d|Tkutw4r3OvxC7fDBk$=KdELTW~x5FUQ>3>mHdbVPT!HK(mF{vhn?9Jk6D1+ zWK#*Oj`6SijoB{GwEQ)*Bd$X-p_|!JW&R!1TKiM zW2#C=TgYr=fwhB<+gHESNTvfwo`UczH0T8t%)FiI!a7lMW{pE8Wv-!lthWh&4VB`c2BNWeOXcQg;=yH4I1t<}Uu)ZN8fC&-`iVsw$!?mDDk zD83|I7h@9>UbS_Fr>^(mc2N4G+q`it01}o#9))<+*u=OW{nbpoyt;s?^Z01x7z_UK zP&%>eVYT10zy7(GMZKaq5ktWj7$)uCuAcE1j#JR(XH4e?s*o-6^MV`4?M)n)^ph6T zWo-v#r>b4ncsChe(|eMVYrMCQwZjydoGKEB40L|~4woUeNo*=XcDC>liiZD$fGarj6^h887SuXR$y?aV_7v?K|RE4WRiF)PS>&lZa zfS+#?JMW58)8oE8);Q>neMiNvX!#X!)E*KA!ZF$Dbna*+qYHJG!}TQ(}LgCN(x;*G!*L z`O_*YI0u2T0j(>9C>Tv0nMHZ-G-|SgWPqbN9DDxG5Y_eTM_E8F1FCo|dAu%(6pdCJ z)+3Cn%bfE%EFtX>PMAt47CGc zEb(@8Sd=7by!DZ8((N>nv^LIgp58Cb1nuBb6 z`ocF*wmNlvN#h1_FNg>TVr~ApzL$Ba>8Pka{;YRMUx3>nw~>9SM^(&5X=1+HB}($no1Ly0tn=~Vb_y7w11;q}_VNrLL9e@+ zjaT%x6-EK*^b#$DF&WM z{#k(})y03pt`TE|T%QZ0ck~xQK&8sTx@F%@$P8kJuK@z^!uwvOiuOK&vKgOoir0F^x9R0&PLh=7q0^OQDzz`7K36Nz5tzYvUFFKiT2~TVJK46MB!Or{L z>?oz+Crx1zL}W?b)F<^o%Vk0-8=HK^O(@<{PRJhFKSjlmuc6UV;0i~62M9tN0D1vC zJ9BecrU;RrV8cm>OWieG-=XlnBZYpa31~w%SM_hd>ViBkmbhY+s)3R+yyqSN8wdLE zvsd=(4DUuX{`||i=ouX?ZNynyaYm;ub*55KKQLVK-Hq|BFz-wQW&qTd$UG``MXP=h z({sIPWkhmxe&qMIrE?`R^k_I1CTRM)OW%?|MZ;-heJ8E%_~3s2UHqyoc}DJ608?AM zY^G{<8PIj$))&ELVj_`Cx~NW~`Fi$eTk8NXQg+R%e(#&k^2N^GM;U=zM$muRuRdCmN9g%^5Z!q@qz| z+Ds;#8kuRXM0Ozl`_41T5sA0s;R@uJjj*Efdsq}GUcaM-Mg;N^0M^Wah3{0CCnrcgC+McV4l;*s=Ovo4xA*i^Z}cmZUmRpcPG$SNK9)dNJx`rFB}FbPuce{EjLMH|QMVqEWw^xS zeK5u4D;(2|ik^yTOr9PCyaoV9(5$=!E!FUXE_1`SSRn-5jl8c#(+ShzZbA3&wKus8 zYv{U90YiZx`5>`7LYTFphU>Z6*+ot1qavH^o#;@pgd|#zn0pt}${fN&I`_ruLOOHK zIZddA+BZhT8LkJozofw_V7U&Nd7_h*vKZfmMn@}7x%{E%gpl2bBoCH_5Z3LqA7iqK_snuesd5^IHSK~x$WJz5%_j8$D` z_l4qc4k8E>lmv>;602+si(M75;m^q#wH;YoL$1DM*1avs|7>4J82vIN4 z-d%m~t9=y~cR;t|r}ikNQ9W&gRGulqBM`7YfIB#2A~y7vQ-!$^<*;JtNmqWga~9>n zJ?Q|s%mxp$4-+t%h^&y%3FZQHVr75VYs7&rD3!6dS9)&3&TE1eV038VK~{V2G+fnL zR6tTGR$6yETFchGuWDqfa=D}9gHn%XlqKiAQmRXS&3{1OI(j%fYBN}potpZ~?s&^? z6fn?yoho%!3GKe9%UW4(E~tBtl(Mpb^#oL{I zdISa){?g0eY4#ZkCWhiy-`1WTAp@|8918jQXtWcwqd>4-qor*&MI+4wgj(ketQsrh zYC(_Qzw{SCn3lc6gs8?{ww-jW0Br~q-trls@*V+YuyCM?YqnneMEfO*EY&*$=J>5& zpx^MAW9)N5K$P(xK@iIUhf&wiXf`hCS|)bSE3z=3`}VfXHqBFL*LU<@9i@7Pm+M+z zl5rKP>29O&tK@>So+aG_cV))`;)zW8`3Zd#@q%#MaUl(s_T9=S%9Mn4Loc4+MfN&! zrz@(Sfk5)=TTV@lH}Ifb*qw2RP1v=lLOwn|_Gh0z78N-F1qsENX@tpHFtP(l7~^Xa zzcGMt0DTHihmh#s!ov+Ilf8zN#(+zwa^qLv4J7%SC`t#m;j}M4_P7plHPqr5AdEvm zJ1d}L1{@h-K_PY^v=qyYzAL9o7f`UjI$5#nk=SP1WcH$dNXlID-h%qjuA}n9m7J%# zE1lYIkB?s8jA;hgsA6fY@O-pM+?>;!>%W_pk^O+CSB|a{6TG2D19(jy!o%o{yGPRM zJEavm;RXDMjkR@&%|4={NjYdt>466QQqaBBoBSQ7eio?c8Fz%&?#YsXB9Ez|#6~ow zJ;9`d=Q3mX#Q$;6{oN|@J(lGn&qmHuG4;Mr!=eb#CLf1A={ z%*N*9Kez`)zR zrg?!xf)e;yiIQr98U2~jA`p~Z6Xjcrb})6f#$yW1&0-Q>XGjjNSA!bR#mx;CpFl^^ zJO!O16ci(C(Pbs2rKl-I6tnx(%d6s6uV_MSnQI@@tmxvF@^|vHt>eb;vOVmdPTty~ zv8wQDaNzUfijrSbk{fc5;r~Z~9>QNB0fHCcJv5=1=(K=6JcU-Dg(j zcgA&@HOo?i#)|#a&I~{cplWxZn*mx4(Ay!fFicgkr<2)=$smU1gvWceM+>zr*Dr*i zH(fGBZbvjCx-J;sNSF{(J$sE%N(3b79oA~$DoD?&SoCahc^Od}0&`XhQw9Jmt$_3d z8U0Y@iEZXJvzl?6|_dgOG?in0Jbi<&r3%ub|o}b^k?Hz|Yf-_laH!2})TJ$XPr8%{+ zzyJoCyX(FOs~HM0P5PzI5`98g z{sXpUF-Jf~peB47Z7sW(cb+7k|Kc?1+2J_q4-#jl3NAGl1I(f8Lrz%y>Z1v&&hW9> zmvr8?J<~Y7fFqN8+d;Y$lV(bLB-+8q#;*S$J3bn2WzC`av0b-V$|OOajKaa-%8cZ( zd;7Y2z9zqj$lfBlol_5cAm}q82t=U7dR#la)CQMfZB8@1D7$fC_gL(+ zWwW|@zOzNN4fdt}k&7yQT$E+Vl+ivtTc%^H684AFZr|w|=IQ-Q=aO1e2-jt1o4%RA zP10=0y7C`?j9`ZLY@pDF`b=Zjm9m% z)#g5-#iAdNc32laRZ?yVS~R~T-kJY*EK1qu6m!K)OjYf&z9}wVDj}DBJ{GN>{WBIV zJZL=R zS%9sLY-9>@=vE6QDOsuI?-s|2Hpfh-`Nc~tyteA1p<1F(J!`n0!yNBjQ2zb?HfDSg zy{Mlo?QB$M7Wb<>pe?>S!Dvyn%%;9I^~|)}rg>*futQ1Qz<+%Zif3XHsG3gc+*4ut z2rL6Ktq$_6<5f^7!ra14Yl7S1W*?V!`R9rXcVyJT1{D46E;<_bdZGUTC879po;Wej zEo)`vb`W?2l@Z=(ERv*KY%KTWNjHLb2@Sdo8}rP$C#xw~`2!m$Ad|}YpqJz8PR_WM zh&N7wd%|Tsa?+-lU13l*a)^4}TKY-*ljCe)V@x^zS1{f~N%+TGH#z!csLsKu*#E&S z;jl6LIOr390&V~gN(6UXU`ap)tC6qCSV!Yn5*-~4xV8X*$B=CW1>56z!G)=P9qz{` zu5S*BH;EY@MEzD{%FK7nF8b6$BW`t>_M9b~M0B2O8vc@ENA1Ny)m0zeuk|W#ZER!g zUgzXWJ9RjIpDK#u33N=exK8_Mz5A5@s__sg2kaT~IYR#2@Tujt~$oxQ$ z%0SVPJkvPu7ynA0gmoWY!pv&J4LukmV#;!C0nb{ctf|j5$$MD6r%$6~8A`JH1)7qi z;l&3`&%1Xn6JN|pAb!x^IWRLj(Xr@Mca3S#{1NxG^`qZWmLtT}cUfw4dZ5iV@f8miM5^+7G& zc-Iz&)4fMshMh$?f~Q~SgfP=MMfY_DOsNq@_-LP1R8zqYt)gl8-Sl83T@EjKFA;ZKu>0q@uB|RO=76Gp?9ya9Tut5 zj=Uw^ntIVx9IK;C!cFX_$aGsKI!M3yjo#E)>P-BZ?B{E#lwE8&&&`UOnGbG+1=2VL;GCsU&h^*b$e;D`a!>@3i z8jKALdLiovKsw6kPaO-xYQ{V$mdij$?ERonhBG*8`SM=ZjCpzyHhM$8s=z8F#kt^_ z8J+lgP{G|w@3aJa6Su}{LT_u%Kq?Vxn+BW{nU2NA6qB!;PuS_!4dA~CZeBfMns$6) zBOz>{I>bX1;fZ3uTV$e04qNnsl4)saCD+2$~D(equSi=^D{UWwn$ zky&--UMuDcteRs zwmkDTUFo?KDW3sad{}4s9lm&0=$eu^j7)d)0gwaP>8-|4MhB$~)wTY_^T`J!6hW^h zF+3914+7F{j10t`?1f6ctHleZp?f>=CO#H1F@N=x4^*G+^0f)&knvwrn4ajarT3pk zkg6XiCYt&f7=haVaz^4q^VGT5ey+CW8;P9A;%0Srgdb&X)tj_G$8;cE6i&Wjc9Y>SR=PAq>28rkNmcC;K*!VUa4Ws2Dkgx20# zV8K24)weED16Of81~#I^$H!my-gtaAp3x&Z+spsQ`5d1!sUkXF-)HEn) zNG(+nC#2yO?QR_W5fO&6OdP*B1wcaoX`u6Ws3V610s|!v=ahXnbM^RTk`*$-QD*GC zwa{_w1Ex_93__eUE_=p&!>f@pY66%v`3&RFgFFv|TxMoTTz*c{wyr4gMOmv`#tvVj zFzJr4{-I{S@bAGNLGMw{$nQ{*$e5U33)j zO6|XEC)vH_(<`9j(|h?A_?;K?=4j#8{8MeIPJdHb9>2>v1JA7GAHP`Mw?vtyjx@v1 z0lr%C*{+&%76AYv>?6*BF545kP*CMF)XUjMB47xKUa{-K1M)aEby-2}$t zS%u>i%&u9!*VE@F{xitm27d%oAO~!)+!Cm37acqX%I8OqLKZ5)DO3CPO0hiEWNC|% znR`VCNioCE>FE3Pw_cX-YUk1kE-=m>rDDmf{ASlRSBlI3_1H4MBh;+$HIY7?XD#3Jm$qZJL&uaBNm! zc+C^xuU7WMwfneZ#@W<@5cm-5KNCksII1C(6K zk8+^&`}&%D&}xzi-3`;Q9(H|HMM0WA?88&iBp$iH869wWC^rGO2m+DFI~08Iln68~ z`d&Ok@MEzljfKD=ZX5vv+>-$wNd^sAq1O}}Jd1TPIg1rgD39*tj{>FaLf=C~7vUO)&Ac%ls+x=9FhMeGWJ!4o+IxHl-~kJ7`fopDng7nwxj6q5Vf3p<}P zUE%BACu!0A51dFH^g*Crs)oa3jrRc+B#i0f6qzUprC??XasfG^NHX0@Er&(9HfzKZ zq-tBM&^N1!@a_o?5`R;=fuJeYo2a1Rjt@~Q^;2rU5nu#?(Dxc`H|BvC1pUNxj(6=C z1(RNK*mJG_2HrSxNu*{%LD@)72s(|JV*de$)pc`=SQc;WvI0%y+An!^Ck6Pn zWeW0p3wZDt#uu)1GG)(d|0XdEKZz<|_+h&jNpD-R(KFEyx8}b$V@+9}4{C)NI$<{^W??2unKkej;T=Jh?GVsk`2mk*+ h{{K(o|IxFtFS&kuwXoVcL=!poau1a57u?hL`#;ptBANgI literal 0 HcmV?d00001 diff --git a/po/ca/okular.po b/po/ca/okular.po new file mode 100644 index 0000000..4d7ba36 --- /dev/null +++ b/po/ca/okular.po @@ -0,0 +1,5282 @@ +# Translation of okular.po to Catalan +# Copyright (C) 2003-2021 This_file_is_part_of_KDE +# +# Josep Ma. Ferrer , 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021. +# Albert Astals Cid , 2004, 2005, 2007. +# Sebastià Pla i Sanz , 2005. +# Manuel Tortosa , 2011. +# Antoni Bella Pérez , 2012, 2013, 2014, 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2021-02-14 12:34+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un visor universal de documents" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Mantenidor anterior" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Molta feina d'infraestructura, dorsal de l'ODT i el FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Desenvolupador" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Va crear l'Okular des del codi base del KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Desenvolupador del KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Gràfics de les anotacions" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Eina de selecció de taules" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Millores a les anotacions" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Vés a la pàgina %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Obre un fitxer extern" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Executa «%1»..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Primera pàgina" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Pàgina anterior" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Pàgina següent" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Última pàgina" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Enrere" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Endavant" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Surt" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Inicia la presentació" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Acaba la presentació" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Cerca..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Vés a la pàgina..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reprodueix un so..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reprodueix una pel·lícula..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Reprodueix una pel·lícula" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Atura la pel·lícula" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Fa pausa a la pel·lícula" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Continua la pel·lícula" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Selecció de dorsal" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"S'ha trobat més d'un dorsal per al tipus MIME:
%1 (%2).

Seleccioneu quin s'ha d'usar:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "La majoria de les pàgines són %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Vertical %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Apaïsada %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 polzades (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "La cerca continua des del començament" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "La cerca continua des de baix" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"No s'ha pogut trobar cap connector que pugui gestionar el document que " +"s'està manipulant." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Elimina les anotacions" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"El document està intentant executar una aplicació externa i l'Okular no ho " +"permet per a la vostra seguretat." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "" +"No s'ha trobat cap aplicació per a obrir el fitxer amb el tipus MIME %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "No s'ha pogut obrir un fitxer temporal" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Ha fallat la conversió d'impressió" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "El procés d'impressió ha fallat" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "No s'ha pogut iniciar el procés d'impressió" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Ha fallat la impressió a un fitxer" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "La impressora està en un estat no vàlid" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "No s'ha pogut trobar el fitxer a imprimir" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "No hi ha cap fitxer a imprimir" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"No s'ha pogut trobar cap binari adequat per a imprimir. Assegureu-vos que " +"està disponible l'executable «lpr» de CUPS" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "La mida d'impressió de la pàgina no és vàlida" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "No s'ha pogut obrir «%1». El fitxer no existeix." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Títol" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Assumpte" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Descripció" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creador" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Productor" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Pàgines" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Creat" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificat" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Tipus MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Paraules clau" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Camí al fitxer" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Mida del fitxer" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Mida de la pàgina" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Afegeix anotació" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Elimina anotació" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Modifica les propietats d'una anotació" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Tradueix una anotació" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "ajusta l'anotació" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Edita el text" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Edita el contingut d'una anotació" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Edita el contingut de formularis" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Edita la selecció de llista de formulari" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Edita la selecció de combinació de formulari" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Edita els estats de botó de formulari" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Text net..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Text en OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opcions d'impressió" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajusta a l'àrea imprimible" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Ajusta a la pàgina completa" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Mode d'escala:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Manca el tipus d'alerta" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "No tornis a mostrar aquest missatge" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Origen: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Tipus de lletra per &defecte:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Vermell" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Taronja" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Groc" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verd" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cian" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blau" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Blanc" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Gris" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Negre" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Amplada %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Amplada de la línia d'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Color de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Color per a l'emplenat de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacitat de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Tipus de lletra de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Afegeix l'anotació actual al menú d'anotacions ràpides (cap anotació " +"seleccionada)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Conserva la relació de forma a 1:1 o l'angle de línia a passos de 15° (No se " +"selecciona cap anotació)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Configuració avançada per a l'actual eina d'anotació (cap anotació " +"seleccionada)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Amplada de la línia d'anotació" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Amplada de la línia d'anotació (l'anotació actual no té amplada de línia)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Color de text d'anotació" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Color de vora d'anotació" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Color de l'anotació" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Color per a l'emplenat de l'anotació" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Color per a l'emplenat de l'anotació (l'anotació actual no té color " +"d'emplenat)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Tipus de lletra de l'anotació" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" +"Tipus de lletra de l'anotació (l'anotació actual no té tipus de lletra)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Conserva l'angle de línia a passos de 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Conserva la relació de forma a 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Conserva la relació de forma a 1:1 o l'angle de línia a passos de 15° (no " +"admès per l'anotació actual)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacitat de l'anotació" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Afegeix l'anotació actual al menú d'anotacions ràpides" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Configuració avançada per a l'actual eina d'anotació" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Color" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Color d'emplenat" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparent" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Color personalitzat..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Els segells inserits als documents PDF no són visibles als lectors de PDF " +"diferents de l'Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Funcionalitat experimental" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Selecció de color" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Anotacions" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Oculta" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Marcador fluorescent" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Subratllat" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Giragonses" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Barrat" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Màquina d'escriure" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota inclosa" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota emergent" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Línia a mà alçada" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Línia recta" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Fletxa" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "El·lipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polígon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Formes geomètriques" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Segell" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anotacions ràpides" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Selecciona una eina d'anotació de les anotacions ràpides" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Afegeix a les anotacions ràpides" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantén activa" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantén activa l'eina d'anotacions després de l'ús" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Conserva la relació i l'angle de les eines d'anotació" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Tipus de lletra" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Configuració de les anotacions" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Amplada de la línia" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacitat" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Pàgina %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anotació" +msgstr[1] "%1 anotacions" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Obre una nota emergent" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "Su&primeix" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propietats" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "De&sa «%1»..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "Aparen&ça" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&General" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Creat:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificat:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Propietats de les notes emergents" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Propietats de la màquina d'escriure" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Propietats de les notes incloses" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Propietats de les línies rectes" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Propietats dels polígons" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Propietats geomètriques" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Propietats del marcador de text" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Propietats del segell" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Propietats de la línia a ma alçada" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Propietats del cursor" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Propietats del fitxer adjunt" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Propietats del so" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Propietats de la pel·lícula" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Propietats de les anotacions" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificat: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Seleccioneu un símbol de segell personalitzat des d'un fitxer" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Seleccioneu un símbol de segell personalitzat" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Fitxers d'icona (*.ico *.png *.xpm *.svg *." +"svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "No s'ha pogut carregar el fitxer %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Fitxer no vàlid" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Color:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacitat:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icona:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Comentari" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Ajuda" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Inserció" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Tecla" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Paràgraf nou" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paràgraf" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Tipus de lletra:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Color del text:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Alinea:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Esquerra" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centre" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Dreta" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "A&mplada de la vora:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Aprovat" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Tal com és" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidencial" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departamental" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Esborrany" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Per a comentaris" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Per a divulgar públicament" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "No aprovat" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "No és per a divulgar públicament" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Venut" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Alt secret" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Punt" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informació" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"funcionalitat experimental.Els segells inserits en els " +"documents PDF no són visibles en lectors de PDF diferents de l'Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Símbol de segell:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Amplada:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Començament de línia:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Final de línia:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Quadrat" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Cercle" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamant" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Fletxa oberta" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Fletxa tancada" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Cap" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Punta" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Fletxa oberta dreta" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Fletxa tancada dreta" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Longitud de la línia principal:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Longitud de les extensions de la línia principal:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Activat" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Emplenat de forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipus:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Ressaltat" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Giragonses" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Subratllat" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Barrat" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "El·lipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Símbol de fitxer adjunt:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Gràfic" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Xinxeta" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Clip de paper" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiqueta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fitxer" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/D" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "No hi ha disponible cap descripció." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nom:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Descripció:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Símbol del cursor:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Cap" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Tanca aquesta nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcions" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Aquesta anotació pot contenir codi LaTeX.\n" +"Cliqueu aquí per a renderitzar." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "No s'ha pogut trobar l'executable «latex»." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Ha fallat la renderització LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "No s'ha pogut trobar l'executable «dvipng»." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Ha ocorregut un problema durant l'execució de l'ordre «latex»." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Ha ocorregut un problema durant l'execució de l'ordre «dvipng»." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"un punt" +msgstr[1] "" +"%1\n" +"\n" +"%2 punts" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Punts" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Cerca..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Només el document actual" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Vés a aquest punt" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Reanomena un punt" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Suprimeix el punt" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Obre el document" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Elimina els punts" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versió" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Número de sèrie" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emissor" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emès el" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Expira el" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Assumpte" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Clau pública" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Ús de la clau" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propietat" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valor" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Visor de certificats" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exporta..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "General" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emès per" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nom comú (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Correu electrònic" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organització (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emès a" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validesa" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Empremtes digitals" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Empremta digital SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Empremta digital SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detalls" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Dades del certificat:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "A on voleu desar aquest certificat?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Fitxer de certificat (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "No s'ha pogut exportar el certificat" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Vermell" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verd" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blau" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Groc" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Negre" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Blanc" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Dibuixa una vora al voltant de les &imatges" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Dibuixa una vora al voltant dels en&llaços" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Canvia els &colors" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Avís: aquestes opcions poden afectar negativament la velocitat del dibuixat." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mode de color:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverteix els colors" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Canvia el color del paper" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Canvia els colors foscos i els clars" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Converteix a blanc i negre" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Inverteix la lluminositat" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Inverteix la luma (sRGB lineal)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Inverteix la luma (Simètrica)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Desplaça a un to positiu" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Desplaça a un to negatiu" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Color del paper:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Color fosc:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Color clar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Llindar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Pronuncia" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitat" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota: La informació que s'usa aquí només és per a les anotacions. La " +"informació es desa en documents anotats, per tant, es transmetrà junt amb el " +"document." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Eines d'anotacions ràpides" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor de text personalitzat" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Client de l'Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Client del Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Indiqueu l'ordre de l'editor de text personalitzat a executar.
\n" +"Podeu afegir les següents variables de substitució:\n" +"
    \n" +"
  • %f - el nom del fitxer
  • \n" +"
  • %l - la línia del fitxer a on anar
  • \n" +"
  • %c - la columna del fitxer a on anar
  • \n" +"
\n" +"Si no s'especifica %f, llavors el nom del fitxer s'afegeix a l'ordre " +"especificada." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Seleccioneu l'editor que voleu executar quan l'Okular necessiti obrir un " +"fitxer de codi font." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Ordre:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Aparença" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Usa un desplaçament suau" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Mostra les &barres de desplaçament" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Enllaça les minia&tures a la pàgina" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Mostra els &consells i els missatges d'informació" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Si està disponible, mostra el títol del document en la barra de títol" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Quan no mostrar el títol del document:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Mostra sols el nom de fitxer" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Mostra el camí complet del fitxer" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usa un color de fons personalitzat" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Funcionalitats del programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Obre els fitxers nous en pes&tanyes" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Commuta a la pestanya existent si el fitxer ja està obert" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obeeix les limitacions DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Actualitza el document en canviar el fitxer" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Mostra el diàleg de selecció de dorsals" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Direcció de lectura de dreta a esquerra" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opcions de visualització" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Columnes de visió general:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Defineix quina part de l'àrea de visió actual romandrà visible en prémer les " +"tecles d'avançar/retrocedir pàgina." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Superposició Av &Pàg/Re Pàg:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defineix el mode de zoom per defecte per als fitxers que mai s'han obert " +"abans.\n" +"Per als fitxers que s'han obert prèviament s'aplica el zoom anterior." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defineix el mode de zoom per defecte per als fitxers que mai s'han obert " +"abans.\n" +"Per als fitxers que s'han obert prèviament s'aplica el zoom anterior." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Zoom pre&determinat:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Ajusta a l'amplada de pàgina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Ajusta a la pàgina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Encaixat automàtic" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Mantén l'ús de la memòria tant baix com sigui possible. No reutilitza res " +"(per a sistemes amb poca memòria)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un bon compromís entre l'ús de la memòria i la velocitat. Precarrega la " +"propera pàgina i accelera les cerques (normalment, per a sistemes amb 2GB de " +"memòria)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Ho manté tot en memòria. Precarrega les properes pàgines. Accelera les " +"cerques (per a sistemes amb més de 4GB de memòria)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carrega i ho manté tot en la memòria. Precarrega totes les pàgines (usarà un " +"màxim del 50% de tota la memòria o de la memòria lliure, el més gran dels " +"dos)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Ús de la CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Activa els efectes de &transparències" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Ús de la memòria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Baix" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (predeterminat)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Enèrgic" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Màxim" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Renderització" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Activa l'antialiàsing de text" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Activa l'antialiàsing de gràfics" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Activa la correcció de lletres per al text" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Pantalla actual" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Pantalla predeterminada" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " segon" +msgstr[1] " segons" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navegació" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avança cada:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Repeteix després de l'última pàgina" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navegació tàctil:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Toc a la banda esquerra/dreta per a anar enrere/endavant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Toc a qualsevol lloc per a anar endavant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Desactivat" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Color del fons:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Cursor del ratolí:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Oculta després d'un retard" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Sempre visible" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Sempre ocult" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Mostra l'indicador de &progrés" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Mostra la pàgina de res&um" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Activa les transicions" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transició per omissió:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Apaga verticalment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Apaga horitzontalment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Quadre cap endins" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Quadre cap enfora" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dilueix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Esvaïment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Lluentor cap a baix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Lluentor cap a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Lluentor cap a baix i a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transició aleatòria" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Substitueix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Divideix horitzontalment cap a l'interior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Divideix horitzontalment cap a l'exterior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Divideix verticalment cap a l'interior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Divideix verticalment cap a l'exterior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Esborrat cap a baix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Esborrat cap a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Esborrat cap a l'esquerra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Esborrat cap a dalt" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Emplaçament" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Pantalla:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuració de l'eina de dibuix" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Eina de dibuix: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Esborrador" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nom:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipus:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota emergent" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota inclosa" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Línia a mà alçada" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Línia recta" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polígon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Marcador de text" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geomètrica" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Segell" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Màquina d'escriure" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Eina de creació d'anotacions" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Eina d'edició d'anotacions" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Color:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Amplada de la &ploma:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Eina de creació de dibuixos" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Eina d'edició de dibuixos" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Desconeguda" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Fitxers incrustats" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Visualitza" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nom" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Descripció" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Mida" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Creat" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificat" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Desa com a..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Visualitza..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "No s'ha pogut carregar la part per a la vista prèvia d'impressió" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Vista prèvia d'impressió" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Tanca" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Cerca:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Text a cercar" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Següent" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Salta a la coincidència següent" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Anterior" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Salta a la coincidència anterior" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifica el comportament de la cerca" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Sensible a majúscules" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Des de la pàgina actual" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Cerca en teclejar" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Tots els fitxers" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Propietats de la signatura" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Línia recta amb comentari" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polígon amb comentari" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometria amb comentari" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Ressaltat amb comentari" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Giragonses amb comentari" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Subratllat amb comentari" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Barrat amb comentari" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Barrat" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Segell amb comentari" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Línia a ma alçada amb comentari" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Cursor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Adjunció de fitxer" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "So" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Pel·lícula" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Pantalla" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Giny" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Contingut enriquit" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Desconegut" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "A on voleu desar %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "No s'ha pogut obrir «%1» per a escriure-hi. El fitxer no s'ha desat." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opcions de cerca" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Distingeix entre majúscules i minúscules" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expressió regular" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "C&erca:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Capes" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "de" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom al 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Gira a la d&reta" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Dreta" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Gira a l'es&querra" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Esquerra" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientació original" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Re&talla la vista" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Re&talla els marges" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Retalla a la &selecció" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Ajusta a l'a&mplada de pàgina" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Ajusta a la &pàgina" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "Encaixat &automàtic" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Ajusta la fi&nestra a la pàgina" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Mode de &vista" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Pàgina i&ndividual" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Pàgines &oposades" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Pàgines oposades (¢ra la primera pàgina)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Vista &general" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continu" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Usa la direcció de lectura de dreta a esquerra" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Navega" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Commu&ta el canvi de colors" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selecció d'àrea" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selecció de &text" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selecció de t&aula" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "A&mpliador" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Eines de selecció" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Pronuncia tot el document" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Pronuncia la pàgina actual" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Atura la pronunciació" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Atura/reprèn la pronunciació" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Desplaçament amunt" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Desplaçament avall" + +# skip-rule: k-PageUp-1 +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Desplaça una pàgina amunt" + +# skip-rule: k-PageDown-1 +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Desplaça una pàgina avall" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Mostra els formularis" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " S'ha carregat un document d'una pàgina." +msgstr[1] " S'ha carregat un document de %1 pàgines." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Text (1 caràcter)" +msgstr[1] "Text (%1 caràcters)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copia al porta-retalls" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "La còpia està prohibida pel DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Pronuncia el text" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Imatge (%1 per %2 píxels)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Desa al fitxer..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "La imatge [%1x%2] s'ha copiat al porta-retalls." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Desa el fitxer" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Imatges (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "No s'ha desat el fitxer." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "La imatge [%1x%2] s'ha desat al fitxer %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copia el text" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Vés a «%1»" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Cerca «%1» amb" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configura les dreceres web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Segueix aquest enllaç" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Reprodueix aquest so" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Atura el so" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copia l'adreça de l'enllaç" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Cerca «%1» en aquest document" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Us donem la benvinguda" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Seleccioneu l'àrea de zoom. Feu clic amb el botó dret per a allunyar." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Clic per a veure la vista ampliada." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dibuixa un rectangle al voltant del text/gràfics a copiar." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Selecció de text" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Dibuixeu un rectangle al voltant de la taula, després cliqueu a prop de les " +"vores per a dividir-lo. Premeu «Esc» per a netejar-lo." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Dibuixa un rectangle al voltant de l'àrea de la pàgina que voleu mantenir " +"visible" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nota nova de text" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Text de la nota nova:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Apunta una anotació" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Insereix un nom personalitzat per a l'anotació:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Dibuixa una el·lipse (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Text ressaltat" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Dibuixa una línia a mà alçada" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Anotació de text inclosa (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Posa una nota emergent" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Dibuixa un polígon (cliqueu en el primer punt per a tancar-lo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Dibuixa un rectangle" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Text de giragonses" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Posa un símbol de segell" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Dibuixa una línia recta" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Text barrat" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Text subratllat" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" +"Anotació de màquina d'escriure (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Marcador fluorescent" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Afegeix una anotació preferida" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nom personalitzat d'anotació:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fitxer" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "A&rranjament" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "A&juda" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientació" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Punts" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra d'eines del visor" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniatures" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anotacions" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Aquest document conté anotacions o dades de formulari que s'han desat " +"internament amb una versió anterior de l'Okular. L'emmagatzematge intern " +"ja no funciona.
Deseu-ho a un fitxer per tal de moure-les si " +"voleu continuar editant el document." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files.
Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Aquest document té fitxers incrustats. Cliqueu aquí per a veure'ls o aneu a «Fitxer -> Fitxers incrustats»." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Anterior" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Vés a la pàgina anterior" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Va a la pàgina anterior del document" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Següent" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avança fins a la pàgina següent" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Va a la pàgina següent del document" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Començament del document" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Va al començament del document" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Final del document" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Va al final del document" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Reanomena el punt actual" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Punt anterior" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Va cap al punt anterior" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Punt següent" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Va cap al punt següent" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configura l'Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configura el visor..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configura els dorsals de visualització..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configura els dorsals..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Quant al dorsal" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Recarrega" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Recarregant el document actual des del disc." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Tanca la barra de &cerca" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Número de pàgina" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Selecciona tot el text de la pàgina actual" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Mostra la barra &lateral" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Mostra la barra de &pàgines" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Mostra el plafó de les &signatures" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Fitxers &incrustats" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xporta com a" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Compartei&x" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentació" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Obre la carpeta con&tenidora" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importa un PostScript com a PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obtingues llibres des d'Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Canvia al mode de pantalla negra" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Esborra el dibuix" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configura les anotacions..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reprodueix/pausa la presentació" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "No s'ha pogut obrir «%1» (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "S'ha cancel·lat la càrrega de %1." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "No s'ha pogut obrir %1. Motiu: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configura els dorsals de visualització" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configura els dorsals" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"No s'ha trobat el programa «ps2pdf», per tant, l'Okular no pot emprar-lo per " +"a importar fitxers PS." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "No s'ha trobat el ps2pdf" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Fitxers PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "S'està important el fitxer PS com a PDF (pot trigar una estona)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Introduïu la contrasenya per a llegir el document:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Contrasenya incorrecta. Torneu a provar-ho:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Contrasenya del document" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Aquest document té formularis XFA, els quals actualment no estan admesos." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Aquest document té formularis. Cliqueu al botó per a interactuar-hi, o useu " +"«Visualitza -> Mostra els formularis»." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Totes les característiques d'edició i interactives d'aquest document estan " +"desactivades. Deseu una còpia i torneu-la a obrir per a editar aquest " +"document." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Aquest document està signat digitalment." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Aquest document està signat digitalment. Hi ha hagut canvis des de la " +"darrera signatura." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Aquest document està signat digitalment. No s'ha pogut validar adequadament " +"alguna de les signatures." + +# skip-rule: ff-enter +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Aquest document requereix mostrar-se en pantalla completa.\n" +"Cal deixar el mode normal i entrar en el mode de presentació?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Petició de canvi del mode de visualització" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Entra en mode de presentació" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Denega la petició" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "No s'ha pogut obrir %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Hi ha canvis sense desar, i el fitxer «%1» l'ha modificat un altre programa. " +"Els vostres canvis es perdran, perquè el fitxer ja no es pot desar.
Voleu " +"continuar recarregant el fitxer?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "El fitxer ha canviat" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continua, recarregant" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interromp la recàrrega" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Hi ha canvis sense desar, i el fitxer «%1» l'ha modificat un altre programa. " +"Els vostres canvis es perdran, perquè el fitxer ja no es pot desar.
Voleu " +"continuar tancant el fitxer?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continua, tancant" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Interromp el tancament" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Voleu desar els canvis a «%1» o descartar-los?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Tanca el document" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Aquest enllaç apunta a una acció sobre un document tancat que no funciona " +"quan s'està emprant el visor incrustat." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Aquest enllaç apunta a una acció sobre una acció de sortida d'aplicació que " +"no funciona quan s'està emprant el visor incrustat." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "S'està recarregant el document..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contingut" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signatures" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Vés a la pàgina" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Pàgina:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Introduïu el nom nou del punt:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Reanomena aquest punt" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Elimina aquest punt" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Desa com a" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"El fitxer «%1» l'ha modificat un altre programa, i per tant, ja no es pot " +"desar." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"El document actual està protegit amb una contrasenya.
Per tal de desar-" +"lo, cal recarregar el fitxer. Es tornarà a preguntar la contrasenya i es " +"perdrà l'historial de desfer/refer.
Voleu continuar?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Desar - Avís" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "No s'ha pogut obrir el fitxer temporal per a desar." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Després de desar, el format actual del document requereix recarregar el " +"fitxer. Es perdrà l'historial de desfer/refer.
Voleu continuar?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"El fitxer no es pot desar a «%1». Intenteu desar-lo a una altra ubicació." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contingut dels formularis omplerts" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Anotacions de l'usuari" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Esteu a punt de desar els canvis, però el format actual del document no " +"permet desar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Avís" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Desa com a arxiu de document de l'Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Esteu a punt de desar els canvis, però el format actual del document no " +"permet desar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los. Feu clic a Continua per a desar el " +"document i descartar aquests elements." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Esteu a punt de desar els canvis, però el format actual del document no " +"permet desar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los. Feu clic a Continua per a desar, " +"però es perdran aquests elements, així com l'historial de desfer/refer." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continua" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continua, es perden els canvis" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "El fitxer no s'ha pogut desar a «%1». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"L'Okular no pot copiar %1 a la ubicació especificada.\n" +"\n" +"El document ja no existeix." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"El fitxer no es pot desar a «%1». Error: «%2». Intenteu desar-lo a una altra " +"ubicació." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expandeix tota la secció" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Redueix tota la secció" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expandeix-ho tot" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Redueix-ho tot" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Afegeix un punt" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Eines" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Impressió" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "No es permet imprimir aquest document." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"No s'ha pogut imprimir el document. Error desconegut. Si us plau, informeu a " +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"No s'ha pogut imprimir el document. L'error detallat és: «%1». Si us plau, " +"informeu a bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Aneu al lloc a on estàveu abans" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Aneu al lloc a on estàveu després" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Error de fitxer! No s'ha pogut crear el fitxer temporal " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Error de fitxer! No s'ha pogut obrir el fitxer " +"%1 per a descomprimir-lo. No es carregarà el fitxer." +"" + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Aquest error normalment passa quan no teniu permisos suficients per a " +"llegir el fitxer. Podeu comprovar el propietari i els permisos si feu un " +"clic dret al fitxer en el gestor de fitxers Dolphin, després trieu l'opció " +"«Propietats». i seleccioneu la pestanya «Permisos» a la finestra oberta." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Error de fitxer! No s'ha pogut descomprimir el fitxer " +"%1. No es carregarà el fitxer." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Aquest error normalment passa quan el fitxer està corromput. Si en voleu " +"estar segur, proveu de descomprimir a mà el fitxer amb les eines de la línia " +"d'ordres." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Sense punts" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "S'ha produït un problema en compartir el document: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Comparteix" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "El document s'ha compartit correctament" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Es pot trobar el document compartit a: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "E&dita" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "Vi&sualitza" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Vés" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Eines" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra d'eines principal" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barra d'eines d'anotació" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opcions generals" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibilitat" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Ajudes d'accessibilitat de lectura" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Rendiment" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Control del rendiment" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configura el visor" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentació" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opcions del mode de presentació" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Opcions de les anotacions" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opcions de l'editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Cerca la següent" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentació" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Canvia de pantalla" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Surt del mode de presentació" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Títol: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Pàgines: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Feu un clic per a començar" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pausa" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reprodueix" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Hi ha dues maneres de sortir del mode de presentació: podeu prémer tant la " +"tecla ESC com fent clic amb el botó de sortida que apareix quan el ratolí se " +"situa a la cantonada superior dreta. També podeu rodar les finestres («Alt-" +"Tab» per defecte)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "S'està efectuant una presentació" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Fitxer desconegut" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Propietats de %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Tipus de lletra" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "S'està llegint la informació del tipus de lletra..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Mides de les &pàgines" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extreu el tipus de lletra" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipus 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipus 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipus 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID tipus 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID tipus 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Mètrica de tipus de lletra del TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX gestionat pel FreeType" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Desconegut" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Incrustat (subconjunt)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Totalment incrustat" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Sí (subconjunt)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (se substitueix per %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Tipus de lletra desconegut" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Incrustat: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nom" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipus" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fitxer" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Pàgina" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Mida" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Vista prèvia de revisió" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "A on voleu desar aquesta revisió?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "No s'ha pogut desar el fitxer %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "No s'ha pogut visualitzar la revisió." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Introduïu un mínim de 3 lletres per a filtrar les pàgines" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Sensible a caixa" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Troba la frase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Troba totes les paraules" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Troba qualsevol paraula" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opcions de filtratge" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Sense anotacions

Per a crear anotacions noves " +"premeu «F6» o seleccioneu «Eines -> Anotacions» al menú.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Agrupa per pàgina" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Agrupa per autor" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Mostra només les anotacions de la pàgina actual" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Expandeix tots els elements" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Redueix tots els elements" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "La signatura és vàlida criptogràficament." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "La signatura no és vàlida criptogràficament." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Hi ha hagut un error d'inconsistència del resum." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "L'estructura CMS/PKCS7 de la signatura està mal formada." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "La signatura requerida no és present al document." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "No s'ha pogut verificar la signatura." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "El certificat és de confiança." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "L'emissor del certificat no és de confiança." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "L'emissor del certificat és desconegut." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "El certificat ha estat revocat." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "El certificat ha caducat." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "El certificat encara no s'ha verificat." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Problema desconegut amb el certificat o té les dades corrompudes." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algorisme desconegut" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipus desconegut" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Signatura digital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Sense repudiació" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Claus d'encriptatge" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Claus de desencriptatge" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Acord de claus" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Certificat de signatura" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL de signatura" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Només encripta" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "No s'ha especificat cap ús" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Signat per %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Data de signatura: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "No disponible" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Motiu: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Camp: %1 a la pàgina %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propietats" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "El document no s'ha modificat des que es va signar." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"La revisió del document que estava coberta per aquesta signatura no s'ha " +"modificat.\n" +"Tanmateix, hi ha hagut canvis posteriors al document." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"S'ha modificat el document d'una manera no permesa pel signatari anterior." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "No s'ha pogut completar la verificació de la integritat del document." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Estat de la validesa" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validesa de la signatura:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modificacions del document:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Informació addicional" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signat per:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Data de signatura:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Motiu:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Ubicació:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versió del document" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisió %1 de %2 del document" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Visualitza la versió signada..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Visualitza el certificat..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Mostra només les pàgines amb un punt" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reprodueix" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pausa" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Atura" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Afegeix..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Edita..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Elimina" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Mou am&unt" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Mou a&vall" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Eina de dibuix predeterminada %1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Ja hi ha una eina amb aquest nom. S'usarà la predeterminada" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nom duplicat" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Pàgina a mostrar del document" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Inicia el document en mode presentació" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Inicia amb el diàleg d'impressió" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Inicia amb el diàleg d'impressió i surt després d'imprimir" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Control d'«Instància única»" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "No elevis la finestra" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Cerca una cadena al text" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"Documents a obrir. Indiqueu «-» per a llegir de l'entrada estàndard (stdin)." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: No es pot obrir més d'un document amb el paràmetre --presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "No s'ha pogut trobar el component de l'Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Ja hi ha una instància única de l'Okular executant-se. Aquesta instància no " +"seria l'única." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "No s'ha pogut trobar el component Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Feu un clic per a obrir un fitxer\n" +"Feu un clic i manteniu-lo premut per a obrir un fitxer recent" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Feu un clic per a obrir un fitxer o feu un clic i manteniu-lo " +"premut per a seleccionar un fitxer recent" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Pestanya següent" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Pestanya anterior" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Desfés el tancament de la pestanya" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Tots els fitxers (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Tots els fitxers admesos (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Obre document" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirmació del tancament" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Tanca les pestanyes" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Esteu a punt de tancar %1 pestanyes. Esteu segur que voleu continuar?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Avisa quan s'intentin tancar múltiples pestanyes" + +#~ msgid "Reviews" +#~ msgstr "Revisions" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" diff --git a/po/ca/okular_chm.po b/po/ca/okular_chm.po new file mode 100644 index 0000000..17de259 --- /dev/null +++ b/po/ca/okular_chm.po @@ -0,0 +1,47 @@ +# Translation of okular_chm.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2020. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-07-29 15:34+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codificació no acceptada" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"La codificació d'aquest llibre electrònic encara no està acceptada. Si us " +"plau, obriu un informe d'error a https://bugs.kde.org per a afegir la " +"codificació" diff --git a/po/ca/okular_comicbook.po b/po/ca/okular_comicbook.po new file mode 100644 index 0000000..1bc3561 --- /dev/null +++ b/po/ca/okular_comicbook.po @@ -0,0 +1,63 @@ +# Translation of okular_comicbook.po to Catalan +# Copyright (C) 2008-2018 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008, 2015, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-08 21:25+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"No s'ha pogut obrir el document, no s'ha trobat el «unrar» ni el " +"«unarchiver»." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"La versió del «unrar» en el vostre sistema no és adequada per a obrir " +"ComicBooks." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Format ComicBook desconegut." + +#~ msgid "ComicBook Backend" +#~ msgstr "Dorsal de ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un renderitzador per a diversos formats de ComicBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca/okular_djvu.po b/po/ca/okular_djvu.po new file mode 100644 index 0000000..66b86fa --- /dev/null +++ b/po/ca/okular_djvu.po @@ -0,0 +1,99 @@ +# Translation of okular_djvu.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:34+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Impressor" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volum" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipus de document" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Desconegut" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Fitxers de component" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Desconegut" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Pàgina individual" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Agrupat" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirecte" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Agrupat (antic)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexat (antic)" diff --git a/po/ca/okular_dvi.po b/po/ca/okular_dvi.po new file mode 100644 index 0000000..31a6397 --- /dev/null +++ b/po/ca/okular_dvi.po @@ -0,0 +1,593 @@ +# Translation of okular_dvi.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-08-06 15:18+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

L'Okular no ha pogut trobar el programa dvipdfm a " +"l'ordinador. Aquest programa és essencial perquè funcioni la funció " +"exportar. Malgrat tot, podeu convertir el fitxer DVI a PDF usant la funció " +"d'impressió de l'Okular, però això molt sovint produeix documents que " +"s'imprimeixen bé, però són de qualitat inferior si es visualitzen amb " +"l'Acrobat Reader. Seria desitjable actualitzar-lo a una versió més recent " +"del TeX de la vostra distribució que inclogui el programa dvipdfm.

Consell per a l'administrador de sistema perplex: l'Okular usa la " +"variable PATH de l'intèrpret d'ordres quan cerca programes.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa extern «dvipdfm», el qual s'usa per a exportar el fitxer, ha " +"informat d'un error. Podeu cercar al diàleg d'informació del " +"document que trobareu al menú Fitxer per a un llistat detallat de " +"l'error." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Aquest fitxer DVI té referències a fitxers gràfics externs que no estan " +"en format PostScript, i no es poden manipular amb el programa dvips " +"que l'Okular usa internament per a imprimir o exportar a PostScript. La " +"funcionalitat que necessiteu no està disponible en aquesta versió de " +"l'Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

L'Okular no ha pogut localitzar el programa dvips a " +"l'ordinador. Aquest programa és essencial perquè funcioni la funció " +"d'exportació.

Consell per a l'administrador de sistema perplex: " +"l'Okular usa la variable PATH de l'intèrpret d'ordres quan cerca programes." + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa extern «dvip per as», el qual s'ha usat exportar el fitxer, " +"ha informat d'un error. Podeu cercar al diàleg d'informació del " +"document que trobareu al menú Fitxer per a un llistat detallat de " +"l'error." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "El fitxer DVI no s'inicia amb el preàmbul." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"El fitxer DVI conté la versió incorrecta de la sortida DVI d'aquest " +"programa. Consell: Si empreu el sistema de procés de tipografia Omega, heu " +"d'usar un programa especial, com l'«oxdvi»." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "El fitxer DVI està corrupte. L'Okular no ha pogut trobar el postàmbul." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "El postàmbul no comença amb l'ordre POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "El postàmbul conté una ordre diferent de FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La pàgina %1 no s'inicia amb l'ordre BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

No s'ha pogut iniciar el programa extern pdf2ps. Com " +"a resultat, el fitxer PDF %1 no s'ha pogut convertir a PostScript. Alguns " +"elements gràfics del document no es visualitzaran.

Un possible " +"motiu: el programa pdf2ps potser no està instal·lat en " +"el sistema, o no es troba al camí actual de cerca.

Què podeu fer: el programa pdf2ps normalment està en distribucions del " +"sistema de l'intèrpret PostScript. Si el ghostscript no està instal·lat en " +"el sistema, el podeu instal·lar ara. Si esteu segur que el ghostscript està " +"instal·lat, intenteu usar el pdf2ps des de la línia " +"d'ordres per a comprovar si realment funciona.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

El fitxer PDF %1 no s'ha pogut convertir a PostScript. Alguns " +"elements gràfics no es visualitzaran.

Un possible motiu: el " +"fitxer %1 podria estar fet malbé, o potser no és un fitxer PDF. Aquesta és " +"la sortida del programa pdf2ps que ha usat l'Okular:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "S'ha malmès el fitxer. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "No es poden incrustar tots els fitxers PostScript en el document. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"No es poden incrustar tots els fitxers PostScript externs en el document." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "El fitxer «%1» especificat no existeix." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Heu demanat a l'Okular que situï el punt en el fitxer DVI que correspon a la " +"línia %1 del fitxer TeX %2. Tanmateix, sembla que el fitxer DVI no conté la " +"informació del fitxer font necessària. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"L'Okular no ha pogut situar el punt en el fitxer DVI que correspon a la " +"línia %1 del fitxer TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "El codi DVI ha configurat un caràcter d'un tipus de lletra desconegut." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"El codi DVI fa referència al tipus de lletra #%1, el qual no s'ha definit " +"prèviament." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "La pila no estava buida quan s'ha trobat l'ordre EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "La pila estava buida quan s'ha trobat l'ordre POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"El codi DVI fa referència a un tipus de lletra que no s'ha definit " +"prèviament." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "S'ha trobat una ordre no permesa." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "S'ha trobat el codi %1 desconegut." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "S'està incrustant %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Pàgina %1: el fitxer PDF %2 no s'ha pogut convertir a " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Pàgina %1: no s'ha trobat el fitxer PostScript %2.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "La dada «%1» de la mida de paper no s'ha pogut analitzar." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

L'Okular no ha pogut localitzar tots els fitxers de tipus de lletra " +"necessaris per a mostrar el fitxer DVI actual. El document pot ser illegible." +"

CAMÍ: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Hi ha hagut problemes executant el kpsewhich. Com a " +"resultat, no s'han pogut localitzar alguns fitxers de tipus de lletra, el " +"document podria ser illegible.
Un possible motiu: El programa " +"kpsewhich potser no està instal·lat en el sistema, o no s'ha pogut " +"trobar en el camí de cerca actual.

CAMÍ: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"S'ha interromput la generació dels tipus de lletra per al kpsewhich (codi de sortida %1, error %2). Com a resultat, alguns fitxers de tipus " +"de lletra no es poden localitzar, i el document pot ser illegible." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Actualment s'està generant %1 a %2 ppp..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generador/Data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "No s'ha trobat el fitxer de tipus de lletra" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "vertical" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "apaïsat" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La versió del Ghostview que està instal·lada en aquest ordinador no conté " +"cap dels controladors de dispositiu del Ghostview reconeguts per l'Okular. " +"El funcionament del PostScript es desactivarà ara de l'Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

El programa Ghostview, el qual l'Okular usa internament per a mostrar " +"els gràfics PostScript que s'inclouen en aquest fitxer DVI, generalment és " +"capaç d'escriure la seva sortida en diversos formats. Els subprogrames que " +"el Ghostview usa per a aquestes tasques s'anomenen «controladors de " +"dispositiu». N'hi ha un per a cada format que el Ghostview és capaç " +"d'escriure. Les diferents versions del Ghostview sovint tenen diferents " +"conjunts de controladors de dispositiu disponibles. Sembla que la versió del " +"Ghostview que està instal·lada en aquest ordinador no conté cap dels controladors de dispositiu reconeguts per l'Okular.

Sembla improbable que una instal·lació normal del Ghostview no " +"contingui aquests controladors. Per tant, aquest error pot apuntar a una " +"greu desconfiguració de la instal·lació del Ghostview al vostre ordinador.

Si voleu arreglar el problema amb el Ghostview, podeu emprar l'ordre " +"gs --help per a mostrar la llista de controladors de " +"dispositiu continguts al Ghostview. Entre altres, l'Okular pot usar els " +"controladors «png256», «jpeg» i «pnm». Cal tenir en compte que cal tornar a " +"engegar l'Okular per a reactivar el funcionament amb el PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Hi ha 25 errors. No s'imprimiran més missatges d'error." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Error en el fitxer DVI «%1», pàgina %2. S'ha emès l'ordre «color pop» quan " +"la pila de color estava buida." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Paràmetre incorrecte a l'ordre especial «epsf».\n" +"S'esperava un flotant després de %1 a %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"No s'ha trobat el fitxer:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Error en el fitxer DVI «%1», pàgina %2. No s'ha pogut interpretar l'angle en " +"un gir especial de text." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "L'ordre especial «%1» no està implementada." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"El fitxer de tipus de lletra %1 s'ha pogut obrir i llegir, però el seu " +"format de tipus de lletra no està admès." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"El fitxer de tipus de lletra %1 està fet malbé, o no es pot obrir o llegir." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"El FreeType ha informat d'un error en establir la mida del caràcter al " +"fitxer de tipus de lletra %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot carregar el tipus #%1 del fitxer de tipus de lletra %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot representar el tipus #%1 del fitxer de tipus de lletra %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "El tipus #%1 està buit." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "El tipus #%1 del fitxer de tipus de lletra %2 està buit." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot carregar la mètrica del tipus #%1 del fitxer de tipus de " +"lletra %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "No es pot obrir el fitxer de tipus de lletra %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: El caràcter %1 no està definit al tipus de lletra %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 no esperat al fitxer PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "El caràcter %1 és massa gran, en el fitxer %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "" +"S'han emmagatzemat un nombre incorrecte de bits: car. %1, tipus de lletra %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Fitxer pk incorrecte (%1), massa bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "El tipus de lletra té una relació d'aspecte no quadrada " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "No s'ha trobat el tipus de lletra %1, al fitxer %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Error a la suma de verificació del fitxer de tipus de lletra %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "No es pot reconèixer el format del fitxer de tipus de lletra %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Error fatal.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Això probablement significa que, o bé heu trobat una errada a l'Okular,\n" +"o que el fitxer DVI, o els fitxers auxiliars (com ara els fitxers de tipus " +"de lletra, \n" +"o els fitxers de tipus de lletra virtuals) estaven fets malbé de mala " +"manera.\n" +"L'Okular s'aturarà després d'aquest missatge. Si penseu que heu trobat una \n" +"errada, o que l'Okular s'hauria de comportar millor en aquesta situació,\n" +"informeu del problema, si us plau." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "S'ha trobat una ordre de byte incorrecta a la llista VF de macros: %1" diff --git a/po/ca/okular_epub.po b/po/ca/okular_epub.po new file mode 100644 index 0000000..2866bf1 --- /dev/null +++ b/po/ca/okular_epub.po @@ -0,0 +1,59 @@ +# Translation of okular_epub.po to Catalan +# Copyright (C) 2008-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:42+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Error en obrir el document EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configuració del dorsal per a EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Dorsal EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Un dorsal per l'EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/ca/okular_fax.po b/po/ca/okular_fax.po new file mode 100644 index 0000000..044029f --- /dev/null +++ b/po/ca/okular_fax.po @@ -0,0 +1,37 @@ +# Translation of okular_fax.po to Catalan +# Copyright (C) 2008-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:38+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "No es pot carregar el document" diff --git a/po/ca/okular_fictionbook.po b/po/ca/okular_fictionbook.po new file mode 100644 index 0000000..8c61d4b --- /dev/null +++ b/po/ca/okular_fictionbook.po @@ -0,0 +1,84 @@ +# Translation of okular_fictionbook.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:42+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "El document no és un FictionBook vàlid" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "No es pot obrir el document: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "El document no és un arxiu ZIP vàlid" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Estructura no vàlida del document (el directori principal no existeix)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "No s'ha trobat contingut en el document" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Document XML no vàlid: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuració del dorsal per a FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Dorsal per al Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un renderitzador per a llibres electrònics FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca/okular_ghostview.po b/po/ca/okular_ghostview.po new file mode 100644 index 0000000..0754d87 --- /dev/null +++ b/po/ca/okular_ghostview.po @@ -0,0 +1,96 @@ +# Translation of okular_ghostview.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:40+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usa els tipus de lletra de la plataforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina si el Ghostscript ha de poder usar els tipus de lletra de la " +"plataforma. Si és negatiu, només podrà usar els tipus de lletra incrustats " +"en el document." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Paràmetres generals" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usa els tipus de lletra de la plataforma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuració del dorsal per a Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Versió del document" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivell del llenguatge" + +#~ msgid "PS Backend" +#~ msgstr "Dorsal PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un renderitzador de fitxers PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Basat en la biblioteca Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/ca/okular_kimgio.po b/po/ca/okular_kimgio.po new file mode 100644 index 0000000..d497333 --- /dev/null +++ b/po/ca/okular_kimgio.po @@ -0,0 +1,72 @@ +# Translation of okular_kimgio.po to Catalan +# Copyright (C) 2007-2017 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2009, 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-15 20:59+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "No es pot carregar el document: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Sembla que aquest document té un format incorrecte. Aquesta és la millor " +"aproximació de l'aparença proposada." + +#~ msgid "Image Backend" +#~ msgstr "Dorsal d'imatges" + +#~ msgid "A simple image backend" +#~ msgstr "Un dorsal d'imatges senzill" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra d'eines principal" diff --git a/po/ca/okular_markdown.po b/po/ca/okular_markdown.po new file mode 100644 index 0000000..e1abd61 --- /dev/null +++ b/po/ca/okular_markdown.po @@ -0,0 +1,56 @@ +# Translation of okular_markdown.po to Catalan +# Copyright (C) 2017-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Antoni Bella Pérez , 2017, 2020. +# Josep Ma. Ferrer , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:43+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Antoni Bella" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "antonibella5@yahoo.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Ha fallat en obrir el document" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Ha fallat en compilar el document Markdown." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Activa la formatació SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuració del dorsal per a Markdown" diff --git a/po/ca/okular_mobi.po b/po/ca/okular_mobi.po new file mode 100644 index 0000000..1b31fa0 --- /dev/null +++ b/po/ca/okular_mobi.po @@ -0,0 +1,55 @@ +# Translation of okular_mobi.po to Catalan +# Copyright (C) 2009-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2009, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:44+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Error en obrir el document Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Aquest llibre està protegit per DRM i només es pot visualitzar en el " +"dispositiu designat" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuració del dorsal per a Mobipocket" diff --git a/po/ca/okular_plucker.po b/po/ca/okular_plucker.po new file mode 100644 index 0000000..2b6ac50 --- /dev/null +++ b/po/ca/okular_plucker.po @@ -0,0 +1,48 @@ +# Translation of okular_plucker.po to Catalan +# Copyright (C) 2007-2008 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-03-15 14:56+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nom" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Dorsal per a documents Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un renderitzador per a llibres electrònics Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca/okular_poppler.po b/po/ca/okular_poppler.po new file mode 100644 index 0000000..9cc3370 --- /dev/null +++ b/po/ca/okular_poppler.po @@ -0,0 +1,193 @@ +# Translation of okular_poppler.po to Catalan +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2016, 2017, 2018, 2019. +# Antoni Bella Pérez , 2013, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:49+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Millora les línies fines:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Sòlid" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opcions del PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprimeix les anotacions" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Inclou les anotacions en el document imprès" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Inclou les anotacions en el document imprès. Podeu desactivar això si voleu " +"imprimir el document original sense anotacions." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Força la rasterització" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasteritza en una imatge abans d'imprimir" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Força la rasterització de cada pàgina en una imatge, abans d'imprimir-la. " +"Normalment, això dóna pitjors resultats, però és útil quan s'imprimeixen " +"documents que semblen imprimir-se incorrectament." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajusta a l'àrea imprimible" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Ajusta a la pàgina completa" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Res; imprimeix la mida original" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Mode d'escalat per a les pàgines impreses" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Mode d'escala:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Encriptat" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Sense encriptar" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Seguretat" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimitzat" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "S'està usant el Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Sestà usant el Poppler %1\n" +"\n" +"Construït contra el Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuració del dorsal per a PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "No disponible" diff --git a/po/ca/okular_tiff.po b/po/ca/okular_tiff.po new file mode 100644 index 0000000..a0fd2f4 --- /dev/null +++ b/po/ca/okular_tiff.po @@ -0,0 +1,31 @@ +# Translation of okular_tiff.po to Catalan +# Copyright (C) 2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-09 09:37+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" diff --git a/po/ca/okular_txt.po b/po/ca/okular_txt.po new file mode 100644 index 0000000..086dfb1 --- /dev/null +++ b/po/ca/okular_txt.po @@ -0,0 +1,54 @@ +# Translation of okular_txt.po to Catalan +# Copyright (C) 2013-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:50+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuració del dorsal per a txt" + +#~ msgid "Txt Backend" +#~ msgstr "Dorsal Txt" + +#~ msgid "Txt backend." +#~ msgstr "Dorsal Txt." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/ca/okular_xps.po b/po/ca/okular_xps.po new file mode 100644 index 0000000..aec5747 --- /dev/null +++ b/po/ca/okular_xps.po @@ -0,0 +1,60 @@ +# Translation of okular_xps.po to Catalan +# Copyright (C) 2007-2008 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-09 11:01+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisió" + +#~ msgid "XPS Backend" +#~ msgstr "Dorsal XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un dorsal per a l'XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/ca/org.kde.active.documentviewer.po b/po/ca/org.kde.active.documentviewer.po new file mode 100644 index 0000000..07deeb9 --- /dev/null +++ b/po/ca/org.kde.active.documentviewer.po @@ -0,0 +1,59 @@ +# Translation of org.kde.active.documentviewer.po to Catalan +# Copyright (C) 2012-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2012, 2016, 2018, 2019. +# Antoni Bella Pérez , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2020-07-29 16:05+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 20.04.3\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Obre..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Suprimeix el punt" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Apunta aquesta pàgina" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniatures" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Taula de contingut" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Punts" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Cerca..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "No s'ha trobat cap resultat." diff --git a/po/ca@valencia/okular.po b/po/ca@valencia/okular.po new file mode 100644 index 0000000..517d975 --- /dev/null +++ b/po/ca@valencia/okular.po @@ -0,0 +1,5275 @@ +# Translation of okular.po to Catalan (Valencian) +# Copyright (C) 2003-2021 This_file_is_part_of_KDE +# +# Josep Ma. Ferrer , 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021. +# Albert Astals Cid , 2004, 2005, 2007. +# Sebastià Pla i Sanz , 2005. +# Manuel Tortosa , 2011. +# Antoni Bella Pérez , 2012, 2013, 2014, 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2021-02-14 12:34+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un visor universal de documents" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Mantenidor anterior" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Molta faena d'infraestructura, dorsal de l'ODT i el FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Desenvolupador" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Va crear l'Okular des del codi base del KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Desenvolupador del KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Gràfics de les anotacions" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Eina de selecció de taules" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Millores a les anotacions" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Vés a la pàgina %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Obri un fitxer extern" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Executa «%1»..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Primera pàgina" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Pàgina anterior" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Pàgina següent" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Última pàgina" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Arrere" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Avant" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Ix" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Inicia la presentació" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Acaba la presentació" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Cerca..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Vés a la pàgina..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reprodueix un so..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reprodueix una pel·lícula..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Reprodueix una pel·lícula" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Atura la pel·lícula" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Fa pausa a la pel·lícula" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Continua la pel·lícula" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Selecció de dorsal" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"S'ha trobat més d'un dorsal per al tipus MIME:
%1 (%2).

Seleccioneu quin s'ha d'usar:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "La majoria de les pàgines són %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Vertical %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Apaïsada %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 polzades (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "La cerca continua des del començament" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "La cerca continua des de baix" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"No s'ha pogut trobar cap connector que puga gestionar el document que s'està " +"manipulant." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Elimina les anotacions" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"El document està intentant executar una aplicació externa i l'Okular no ho " +"permet per a la vostra seguretat." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "" +"No s'ha trobat cap aplicació per a obrir el fitxer amb el tipus MIME %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "No s'ha pogut obrir un fitxer temporal" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Ha fallat la conversió d'impressió" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "El procés d'impressió ha fallat" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "No s'ha pogut iniciar el procés d'impressió" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Ha fallat la impressió a un fitxer" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "La impressora està en un estat no vàlid" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "No s'ha pogut trobar el fitxer a imprimir" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "No hi ha cap fitxer a imprimir" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"No s'ha pogut trobar cap binari adequat per a imprimir. Assegureu-vos que " +"està disponible l'executable «lpr» de CUPS" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "La mida d'impressió de la pàgina no és vàlida" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "No s'ha pogut obrir «%1». El fitxer no existeix." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Títol" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Assumpte" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Descripció" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creador" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Productor" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Pàgines" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Creat" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificat" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Tipus MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Paraules clau" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Camí al fitxer" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Mida del fitxer" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Mida de la pàgina" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Afig anotació" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Elimina anotació" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Modifica les propietats d'una anotació" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Tradueix una anotació" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "ajusta l'anotació" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Edita el text" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Edita el contingut d'una anotació" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Edita el contingut de formularis" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Edita la selecció de llista de formulari" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Edita la selecció de combinació de formulari" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Edita els estats de botó de formulari" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Text net..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Text en OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opcions d'impressió" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajusta a l'àrea imprimible" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Ajusta a la pàgina completa" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Mode d'escala:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Falta el tipus d'alerta" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "No tornes a mostrar aquest missatge" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Origen: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Tipus de lletra per &defecte:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Roig" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Taronja" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Groc" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verd" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cian" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blau" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Blanc" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Gris" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Negre" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Amplària %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Amplària de la línia d'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Color de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Color per a l'emplenat de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacitat de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Tipus de lletra de l'anotació (cap anotació seleccionada)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Afig l'anotació actual al menú d'anotacions ràpides (cap anotació " +"seleccionada)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Conserva la relació de forma a 1:1 o l'angle de línia a passos de 15° (No se " +"selecciona cap anotació)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Configuració avançada per a l'actual eina d'anotació (cap anotació " +"seleccionada)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Amplària de la línia d'anotació" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Amplària de la línia d'anotació (l'anotació actual no té amplària de línia)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Color de text d'anotació" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Color de vora d'anotació" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Color de l'anotació" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Color per a l'emplenat de l'anotació" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Color per a l'emplenat de l'anotació (l'anotació actual no té color " +"d'emplenat)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Tipus de lletra de l'anotació" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" +"Tipus de lletra de l'anotació (l'anotació actual no té tipus de lletra)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Conserva l'angle de línia a passos de 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Conserva la relació de forma a 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Conserva la relació de forma a 1:1 o l'angle de línia a passos de 15° (no " +"admés per l'anotació actual)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacitat de l'anotació" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Afig l'anotació actual al menú d'anotacions ràpides" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Configuració avançada per a l'actual eina d'anotació" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Color" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Color d'emplenat" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparent" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Color personalitzat..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Els segells inserits als documents PDF no són visibles als lectors de PDF " +"diferents de l'Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Funcionalitat experimental" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Selecció de color" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Anotacions" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Oculta" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Marcador fluorescent" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Subratllat" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Giragonses" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Barrat" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Màquina d'escriure" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota inclosa" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota emergent" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Línia a mà alçària" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Línia recta" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Fletxa" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "El·lipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polígon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Formes geomètriques" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Segell" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anotacions ràpides" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Selecciona una eina d'anotació de les anotacions ràpides" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Afig a les anotacions ràpides" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantén activa" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantén activa l'eina d'anotacions després de l'ús" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Conserva la relació i l'angle de les eines d'anotació" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Tipus de lletra" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Configuració de les anotacions" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Amplària de la línia" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacitat" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Pàgina %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anotació" +msgstr[1] "%1 anotacions" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Obri una nota emergent" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "Su&primeix" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propietats" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Guar&da «%1»..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "Aparen&ça" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&General" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Creat:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificat:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Propietats de les notes emergents" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Propietats de la màquina d'escriure" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Propietats de les notes incloses" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Propietats de les línies rectes" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Propietats dels polígons" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Propietats geomètriques" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Propietats del marcador de text" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Propietats del segell" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Propietats de la línia a ma alçària" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Propietats del cursor" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Propietats del fitxer adjunt" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Propietats del so" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Propietats de la pel·lícula" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Propietats de les anotacions" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificat: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Seleccioneu un símbol de segell personalitzat des d'un fitxer" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Seleccioneu un símbol de segell personalitzat" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Fitxers d'icona (*.ico *.png *.xpm *.svg *." +"svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "No s'ha pogut carregar el fitxer %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Fitxer no vàlid" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Color:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacitat:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icona:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Comentari" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Ajuda" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Inserció" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Tecla" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Paràgraf nou" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paràgraf" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Tipus de lletra:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Color del text:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Alinea:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Esquerra" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centre" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Dreta" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "A&mplada de la vora:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Aprovat" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Tal com és" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidencial" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departamental" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Esborrany" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Per a comentaris" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Per a divulgar públicament" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "No aprovat" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "No és per a divulgar públicament" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Venut" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Alt secret" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Punt" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informació" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"funcionalitat experimental.Els segells inserits en els " +"documents PDF no són visibles en lectors de PDF diferents de l'Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Símbol de segell:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Amplària:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Començament de línia:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Final de línia:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Quadrat" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Cercle" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamant" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Fletxa oberta" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Fletxa tancada" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Cap" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Punta" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Fletxa oberta dreta" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Fletxa tancada dreta" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Longitud de la línia principal:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Longitud de les extensions de la línia principal:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Activat" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Emplenat de forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipus:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Ressaltat" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Giragonses" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Subratllat" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Barrat" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "El·lipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Símbol de fitxer adjunt:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Gràfic" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Xinxeta" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Clip de paper" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiqueta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fitxer" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/D" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "No hi ha disponible cap descripció." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nom:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Descripció:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Símbol del cursor:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Cap" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Tanca aquesta nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcions" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Aquesta anotació pot contindre codi LaTeX.\n" +"Cliqueu ací per a renderitzar." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "No s'ha pogut trobar l'executable «latex»." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Ha fallat la renderització LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "No s'ha pogut trobar l'executable «dvipng»." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Ha ocorregut un problema durant l'execució de l'ordre «latex»." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Ha ocorregut un problema durant l'execució de l'ordre «dvipng»." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"un punt" +msgstr[1] "" +"%1\n" +"\n" +"%2 punts" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Punts" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Cerca..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Només el document actual" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Vés a aquest punt" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Reanomena un punt" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Suprimeix el punt" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Obri el document" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Elimina els punts" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versió" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Número de sèrie" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emissor" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emés el" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Expira el" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Assumpte" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Clau pública" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Ús de la clau" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propietat" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valor" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Visor de certificats" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exporta..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "General" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emés per" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nom comú (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Correu electrònic" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organització (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emés a" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validesa" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Empremtes digitals" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Empremta digital SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Empremta digital SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detalls" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Dades del certificat:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "A on voleu guardar aquest certificat?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Fitxer de certificat (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "No s'ha pogut exportar el certificat" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Roig" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verd" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blau" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Groc" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Negre" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Blanc" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Dibuixa una vora al voltant de les &imatges" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Dibuixa una vora al voltant dels en&llaços" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Canvia els &colors" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Avís: aquestes opcions poden afectar negativament la velocitat del dibuixat." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mode de color:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverteix els colors" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Canvia el color del paper" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Canvia els colors foscos i els clars" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Converteix a blanc i negre" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Inverteix la lluminositat" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Inverteix la luma (sRGB lineal)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Inverteix la luma (Simètrica)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Desplaça a un to positiu" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Desplaça a un to negatiu" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Color del paper:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Color fosc:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Color clar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Llindar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Pronuncia" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitat" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota: La informació que s'usa ací només és per a les anotacions. La " +"informació es guarda en documents anotats, per tant, es transmetrà junt amb " +"el document." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Eines d'anotacions ràpides" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor de text personalitzat" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Client de l'Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Client del Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Indiqueu l'ordre de l'editor de text personalitzat a executar.
\n" +"Podeu afegir les següents variables de substitució:\n" +"
    \n" +"
  • %f - el nom del fitxer
  • \n" +"
  • %l - la línia del fitxer a on anar
  • \n" +"
  • %c - la columna del fitxer a on anar
  • \n" +"
\n" +"Si no s'especifica %f, llavors el nom del fitxer s'afig a l'ordre " +"especificada." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Seleccioneu l'editor que voleu executar quan l'Okular necessiti obrir un " +"fitxer de codi font." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Ordre:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Aparença" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Usa un desplaçament suau" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Mostra les &barres de desplaçament" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Enllaça les minia&tures a la pàgina" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Mostra els &consells i els missatges d'informació" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Si està disponible, mostra el títol del document en la barra de títol" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Quan no mostrar el títol del document:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Mostra sols el nom de fitxer" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Mostra el camí complet del fitxer" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usa un color de fons personalitzat" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Funcionalitats del programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Obri els fitxers nous en pes&tanyes" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Commuta a la pestanya existent si el fitxer ja està obert" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obeeix les limitacions DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Actualitza el document en canviar el fitxer" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Mostra el diàleg de selecció de dorsals" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Direcció de lectura de dreta a esquerra" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opcions de visualització" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Columnes de visió general:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Defineix quina part de l'àrea de visió actual romandrà visible en prémer les " +"tecles d'avançar/retrocedir pàgina." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Superposició Av &Pàg/Re Pàg:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defineix el mode de zoom per defecte per als fitxers que mai s'han obert " +"abans.\n" +"Per als fitxers que s'han obert prèviament s'aplica el zoom anterior." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defineix el mode de zoom per defecte per als fitxers que mai s'han obert " +"abans.\n" +"Per als fitxers que s'han obert prèviament s'aplica el zoom anterior." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Zoom pre&determinat:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Ajusta a l'amplària de pàgina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Ajusta a la pàgina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Encaixat automàtic" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Mantén l'ús de la memòria tant baix com siga possible. No reutilitza res " +"(per a sistemes amb poca memòria)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un bon compromís entre l'ús de la memòria i la velocitat. Precarrega la " +"propera pàgina i accelera les cerques (normalment, per a sistemes amb 2GB de " +"memòria)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Ho manté tot en memòria. Precarrega les properes pàgines. Accelera les " +"cerques (per a sistemes amb més de 4GB de memòria)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carrega i ho manté tot en la memòria. Precarrega totes les pàgines (usarà un " +"màxim del 50% de tota la memòria o de la memòria lliure, el més gran dels " +"dos)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Ús de la CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Activa els efectes de &transparències" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Ús de la memòria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Baix" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (predeterminat)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Enèrgic" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Màxim" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Renderització" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Activa l'antialiàsing de text" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Activa l'antialiàsing de gràfics" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Activa la correcció de lletres per al text" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Pantalla actual" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Pantalla predeterminada" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " segon" +msgstr[1] " segons" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navegació" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avança cada:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Repeteix després de l'última pàgina" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navegació tàctil:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Toc a la banda esquerra/dreta per a anar arrere/avant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Toc a qualsevol lloc per a anar avant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Desactivat" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Color del fons:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Cursor del ratolí:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Oculta després d'un retard" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Sempre visible" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Sempre ocult" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Mostra l'indicador de &progrés" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Mostra la pàgina de res&um" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Activa les transicions" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transició per omissió:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Apaga verticalment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Apaga horitzontalment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Quadre cap endins" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Quadre cap enfora" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dilueix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Esvaïment" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Lluentor cap a baix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Lluentor cap a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Lluentor cap a baix i a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transició aleatòria" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Substitueix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Divideix horitzontalment cap a l'interior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Divideix horitzontalment cap a l'exterior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Divideix verticalment cap a l'interior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Divideix verticalment cap a l'exterior" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Esborrat cap a baix" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Esborrat cap a la dreta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Esborrat cap a l'esquerra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Esborrat cap a dalt" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Emplaçament" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Pantalla:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuració de l'eina de dibuix" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Eina de dibuix: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Esborrador" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nom:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipus:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota emergent" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota inclosa" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Línia a mà alçària" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Línia recta" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polígon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Marcador de text" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geomètrica" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Segell" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Màquina d'escriure" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Eina de creació d'anotacions" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Eina d'edició d'anotacions" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Color:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Amplària de la &ploma:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Eina de creació de dibuixos" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Eina d'edició de dibuixos" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Desconeguda" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Fitxers incrustats" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Visualitza" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nom" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Descripció" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Mida" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Creat" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificat" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Guar&da com a..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Visualitza..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "No s'ha pogut carregar la part per a la vista prèvia d'impressió" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Vista prèvia d'impressió" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Tanca" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Cerca:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Text a cercar" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Següent" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Salta a la coincidència següent" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Anterior" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Salta a la coincidència anterior" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifica el comportament de la cerca" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Sensible a majúscules" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Des de la pàgina actual" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Cerca en teclejar" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Tots els fitxers" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Propietats de la signatura" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Línia recta amb comentari" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polígon amb comentari" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometria amb comentari" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Ressaltat amb comentari" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Giragonses amb comentari" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Subratllat amb comentari" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Barrat amb comentari" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Barrat" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Segell amb comentari" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Línia a ma alçària amb comentari" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Cursor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Adjunció de fitxer" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "So" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Pel·lícula" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Pantalla" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Giny" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Contingut enriquit" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Desconegut" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "A on voleu guardar %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "No s'ha pogut obrir «%1» per a escriure-hi. El fitxer no s'ha guardat." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opcions de cerca" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Distingeix entre majúscules i minúscules" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expressió regular" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "C&erca:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Capes" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "de" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom al 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Gira a la d&reta" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Dreta" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Gira a l'es&querra" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Esquerra" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientació original" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Re&talla la vista" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Re&talla els marges" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Retalla a la &selecció" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Ajusta a l'a&mplada de pàgina" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Ajusta a la &pàgina" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "Encaixat &automàtic" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Ajusta la fi&nestra a la pàgina" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Mode de &vista" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Pàgina i&ndividual" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Pàgines &oposades" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Pàgines oposades (¢ra la primera pàgina)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Vista &general" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continu" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Usa la direcció de lectura de dreta a esquerra" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Navega" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Commu&ta el canvi de colors" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selecció d'àrea" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selecció de &text" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selecció de t&aula" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "A&mpliador" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Eines de selecció" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Pronuncia tot el document" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Pronuncia la pàgina actual" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Atura la pronunciació" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Atura/reprén la pronunciació" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Desplaçament amunt" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Desplaçament avall" + +# skip-rule: k-PageUp-1 +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Desplaça una pàgina amunt" + +# skip-rule: k-PageDown-1 +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Desplaça una pàgina avall" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Mostra els formularis" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " S'ha carregat un document d'una pàgina." +msgstr[1] " S'ha carregat un document de %1 pàgines." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Text (1 caràcter)" +msgstr[1] "Text (%1 caràcters)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copia al porta-retalls" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "La còpia està prohibida pel DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Pronuncia el text" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Imatge (%1 per %2 píxels)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Guarda al fitxer..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "La imatge [%1x%2] s'ha copiat al porta-retalls." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Guarda el fitxer" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Imatges (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "No s'ha guardat el fitxer." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "La imatge [%1x%2] s'ha guardat al fitxer %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copia el text" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Vés a «%1»" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Cerca «%1» amb" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configura les dreceres web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Segueix aquest enllaç" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Reprodueix aquest so" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Atura el so" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copia l'adreça de l'enllaç" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Cerca «%1» en aquest document" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Vos donem la benvinguda" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Seleccioneu l'àrea de zoom. Feu clic amb el botó dret per a allunyar." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Clic per a veure la vista ampliada." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dibuixa un rectangle al voltant del text/gràfics a copiar." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Selecció de text" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Dibuixeu un rectangle al voltant de la taula, després cliqueu a prop de les " +"vores per a dividir-lo. Premeu «Esc» per a netejar-lo." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Dibuixa un rectangle al voltant de l'àrea de la pàgina que voleu mantindre " +"visible" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nota nova de text" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Text de la nota nova:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Apunta una anotació" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Insereix un nom personalitzat per a l'anotació:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Dibuixa una el·lipse (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Text ressaltat" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Dibuixa una línia a mà alçària" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Anotació de text inclosa (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Posa una nota emergent" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Dibuixa un polígon (cliqueu en el primer punt per a tancar-lo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Dibuixa un rectangle" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Text de giragonses" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Posa un símbol de segell" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Dibuixa una línia recta" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Text barrat" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Text subratllat" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" +"Anotació de màquina d'escriure (arrossegueu per a seleccionar una zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Marcador fluorescent" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Afig una anotació preferida" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nom personalitzat d'anotació:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fitxer" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "A&rranjament" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "A&juda" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientació" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Punts" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra d'eines del visor" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniatures" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anotacions" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Aquest document conté anotacions o dades de formulari que s'han guardat " +"internament amb una versió anterior de l'Okular. L'emmagatzematge intern " +"ja no funciona.
Guardeu-ho a un fitxer per tal de moure-les si " +"voleu continuar editant el document." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Aquest document té fitxers incrustats. Cliqueu ací per a veure'ls o aneu a «Fitxer -> Fitxers incrustats»." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Anterior" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Vés a la pàgina anterior" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Va a la pàgina anterior del document" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Següent" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avança fins a la pàgina següent" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Va a la pàgina següent del document" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Començament del document" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Va al començament del document" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Final del document" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Va al final del document" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Reanomena el punt actual" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Punt anterior" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Va cap al punt anterior" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Punt següent" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Va cap al punt següent" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configura l'Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configura el visor..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configura els dorsals de visualització..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configura els dorsals..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Quant al dorsal" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Recarrega" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Recarregant el document actual des del disc." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Tanca la barra de &cerca" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Número de pàgina" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Selecciona tot el text de la pàgina actual" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Mostra la barra &lateral" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Mostra la barra de &pàgines" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Mostra el plafó de les &signatures" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Fitxers &incrustats" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xporta com a" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Compartei&x" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentació" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Obri la carpeta con&tenidora" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importa un PostScript com a PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obtingues llibres des d'Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Canvia al mode de pantalla negra" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Esborra el dibuix" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configura les anotacions..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reprodueix/pausa la presentació" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "No s'ha pogut obrir «%1» (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "S'ha cancel·lat la càrrega de %1." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "No s'ha pogut obrir %1. Motiu: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configura els dorsals de visualització" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configura els dorsals" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"No s'ha trobat el programa «ps2pdf», per tant, l'Okular no pot emprar-lo per " +"a importar fitxers PS." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "No s'ha trobat el ps2pdf" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Fitxers PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "S'està important el fitxer PS com a PDF (pot trigar una estona)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Introduïu la contrasenya per a llegir el document:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Contrasenya incorrecta. Torneu a provar-ho:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Contrasenya del document" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Aquest document té formularis XFA, els quals actualment no estan admesos." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Aquest document té formularis. Cliqueu al botó per a interactuar-hi, o useu " +"«Visualitza -> Mostra els formularis»." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Totes les característiques d'edició i interactives d'aquest document estan " +"desactivades. Guardeu una còpia i torneu-la a obrir per a editar aquest " +"document." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Aquest document està signat digitalment." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Aquest document està signat digitalment. Hi ha hagut canvis des de la " +"darrera signatura." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Aquest document està signat digitalment. No s'ha pogut validar adequadament " +"alguna de les signatures." + +# skip-rule: ff-enter +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Aquest document requereix mostrar-se en pantalla completa.\n" +"Cal deixar el mode normal i entrar en el mode de presentació?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Petició de canvi del mode de visualització" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Entra en mode de presentació" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Denega la petició" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "No s'ha pogut obrir %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Hi ha canvis sense guardar, i el fitxer «%1» l'ha modificat un altre " +"programa. Els vostres canvis es perdran, perquè el fitxer ja no es pot " +"guardar.
Voleu continuar recarregant el fitxer?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "El fitxer ha canviat" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continua, recarregant" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interromp la recàrrega" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Hi ha canvis sense guardar, i el fitxer «%1» l'ha modificat un altre " +"programa. Els vostres canvis es perdran, perquè el fitxer ja no es pot " +"guardar.
Voleu continuar tancant el fitxer?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continua, tancant" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Interromp el tancament" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Voleu guardar els canvis a «%1» o descartar-los?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Tanca el document" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Aquest enllaç apunta a una acció sobre un document tancat que no funciona " +"quan s'està emprant el visor incrustat." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Aquest enllaç apunta a una acció sobre una acció d'eixida d'aplicació que no " +"funciona quan s'està emprant el visor incrustat." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "S'està recarregant el document..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contingut" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signatures" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Vés a la pàgina" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Pàgina:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Introduïu el nom nou del punt:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Reanomena aquest punt" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Elimina aquest punt" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Guarda com a" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"El fitxer «%1» l'ha modificat un altre programa, i per tant, ja no es pot " +"guardar." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"El document actual està protegit amb una contrasenya.
Per tal de " +"guardar-lo, cal recarregar el fitxer. Es tornarà a preguntar la contrasenya " +"i es perdrà l'historial de desfer/refer.
Voleu continuar?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Guardar - Avís" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "No s'ha pogut obrir el fitxer temporal per a guardar." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Després de guardar, el format actual del document requereix recarregar el " +"fitxer. Es perdrà l'historial de desfer/refer.
Voleu continuar?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"El fitxer no es pot guardar a «%1». Intenteu guardar-lo a una altra ubicació." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contingut dels formularis omplerts" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Anotacions de l'usuari" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Esteu a punt de guardar els canvis, però el format actual del document no " +"permet guardar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Avís" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Guarda com a arxiu de document de l'Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Esteu a punt de guardar els canvis, però el format actual del document no " +"permet guardar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los. Feu clic a Continua per a guardar " +"el document i descartar aquests elements." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Esteu a punt de guardar els canvis, però el format actual del document no " +"permet guardar els elements següents. Useu el format arxiu de document de " +"l'Okular per a conservar-los. Feu clic a Continua per a guardar, " +"però es perdran aquests elements, així com l'historial de desfer/refer." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continua" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continua, es perden els canvis" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "El fitxer no s'ha pogut guardar a «%1». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"L'Okular no pot copiar %1 a la ubicació especificada.\n" +"\n" +"El document ja no existeix." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"El fitxer no es pot guardar a «%1». Error: «%2». Intenteu guardar-lo a una " +"altra ubicació." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expandeix tota la secció" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Redueix tota la secció" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expandeix-ho tot" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Redueix-ho tot" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Afig un punt" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Eines" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Impressió" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "No es permet imprimir aquest document." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"No s'ha pogut imprimir el document. Error desconegut. Per favor, informeu a " +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"No s'ha pogut imprimir el document. L'error detallat és: «%1». Per favor, " +"informeu a bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Aneu al lloc a on estàveu abans" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Aneu al lloc a on estàveu després" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Error de fitxer! No s'ha pogut crear el fitxer temporal " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Error de fitxer! No s'ha pogut obrir el fitxer " +"%1 per a descomprimir-lo. No es carregarà el fitxer." +"" + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Aquest error normalment passa quan no teniu permisos suficients per a " +"llegir el fitxer. Podeu comprovar el propietari i els permisos si feu un " +"clic dret al fitxer en el gestor de fitxers Dolphin, després trieu l'opció " +"«Propietats». i seleccioneu la pestanya «Permisos» a la finestra oberta." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Error de fitxer! No s'ha pogut descomprimir el fitxer " +"%1. No es carregarà el fitxer." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Aquest error normalment passa quan el fitxer està corromput. Si en voleu " +"estar segur, proveu de descomprimir a mà el fitxer amb les eines de la línia " +"d'ordres." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Sense punts" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "S'ha produït un problema en compartir el document: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Comparteix" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "El document s'ha compartit correctament" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Es pot trobar el document compartit a: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "E&dita" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "Vi&sualitza" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Vés" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Eines" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra d'eines principal" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barra d'eines d'anotació" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opcions generals" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibilitat" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Ajudes d'accessibilitat de lectura" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Rendiment" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Control del rendiment" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configura el visor" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentació" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opcions del mode de presentació" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Opcions de les anotacions" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opcions de l'editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Cerca la següent" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentació" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Canvia de pantalla" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Ix del mode de presentació" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Títol: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Pàgines: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Feu un clic per a començar" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pausa" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reprodueix" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Hi ha dues maneres d'eixir del mode de presentació: podeu prémer tant la " +"tecla ESC com fent clic amb el botó d'eixida que apareix quan el ratolí se " +"situa a la cantonada superior dreta. També podeu rodar les finestres («Alt-" +"Tab» per defecte)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "S'està efectuant una presentació" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Fitxer desconegut" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Propietats de %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Tipus de lletra" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "S'està llegint la informació del tipus de lletra..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Mides de les &pàgines" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extreu el tipus de lletra" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipus 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipus 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipus 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID tipus 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID tipus 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Mètrica de tipus de lletra del TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX gestionat pel FreeType" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Desconegut" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Incrustat (subconjunt)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Totalment incrustat" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Sí (subconjunt)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (se substitueix per %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Tipus de lletra desconegut" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Incrustat: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nom" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipus" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fitxer" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Pàgina" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Mida" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Vista prèvia de revisió" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "A on voleu guardar aquesta revisió?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "No s'ha pogut guardar el fitxer %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "No s'ha pogut visualitzar la revisió." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Introduïu un mínim de 3 lletres per a filtrar les pàgines" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Sensible a caixa" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Troba la frase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Troba totes les paraules" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Troba qualsevol paraula" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opcions de filtratge" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Sense anotacions

Per a crear anotacions noves " +"premeu «F6» o seleccioneu «Eines -> Anotacions» al menú.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Agrupa per pàgina" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Agrupa per autor" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Mostra només les anotacions de la pàgina actual" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Expandeix tots els elements" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Redueix tots els elements" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "La signatura és vàlida criptogràficament." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "La signatura no és vàlida criptogràficament." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Hi ha hagut un error d'inconsistència del resum." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "L'estructura CMS/PKCS7 de la signatura està mal formada." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "La signatura requerida no és present al document." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "No s'ha pogut verificar la signatura." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "El certificat és de confiança." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "L'emissor del certificat no és de confiança." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "L'emissor del certificat és desconegut." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "El certificat ha estat revocat." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "El certificat ha caducat." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "El certificat encara no s'ha verificat." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Problema desconegut amb el certificat o té les dades corrompudes." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algorisme desconegut" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipus desconegut" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Signatura digital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Sense repudiació" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Claus d'encriptatge" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Claus de desencriptatge" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Acord de claus" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Certificat de signatura" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL de signatura" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Només encripta" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "No s'ha especificat cap ús" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Signat per %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Data de signatura: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "No disponible" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Motiu: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Camp: %1 a la pàgina %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propietats" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "El document no s'ha modificat des que es va signar." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"La revisió del document que estava coberta per aquesta signatura no s'ha " +"modificat.\n" +"Tanmateix, hi ha hagut canvis posteriors al document." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"S'ha modificat el document d'una manera no permesa pel signatari anterior." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "No s'ha pogut completar la verificació de la integritat del document." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Estat de la validesa" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validesa de la signatura:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modificacions del document:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Informació addicional" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signat per:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Data de signatura:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Motiu:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Ubicació:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versió del document" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisió %1 de %2 del document" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Visualitza la versió signada..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Visualitza el certificat..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Mostra només les pàgines amb un punt" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reprodueix" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pausa" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Atura" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Afig..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Edita..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Elimina" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Mou am&unt" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Mou a&vall" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Eina de dibuix predeterminada %1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Ja hi ha una eina amb aquest nom. S'usarà la predeterminada" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nom duplicat" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Pàgina a mostrar del document" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Inicia el document en mode presentació" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Inicia amb el diàleg d'impressió" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Inicia amb el diàleg d'impressió i ix després d'imprimir" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Control d'«Instància única»" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "No elevis la finestra" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Cerca una cadena al text" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"Documents a obrir. Indiqueu «-» per a llegir de l'entrada estàndard (stdin)." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: No es pot obrir més d'un document amb el paràmetre --presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Error: No es pot obrir més d'un document amb el paràmetre --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "No s'ha pogut trobar el component de l'Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Ja hi ha una instància única de l'Okular executant-se. Aquesta instància no " +"seria l'única." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "No s'ha pogut trobar el component Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Feu un clic per a obrir un fitxer\n" +"Feu un clic i manteniu-lo premut per a obrir un fitxer recent" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Feu un clic per a obrir un fitxer o feu un clic i manteniu-lo " +"premut per a seleccionar un fitxer recent" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Pestanya següent" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Pestanya anterior" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Desfés el tancament de la pestanya" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Tots els fitxers (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Tots els fitxers admesos (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Obri document" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirmació del tancament" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Tanca les pestanyes" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Esteu a punt de tancar %1 pestanyes. Esteu segur que voleu continuar?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Avisa quan s'intenten tancar múltiples pestanyes" diff --git a/po/ca@valencia/okular_chm.po b/po/ca@valencia/okular_chm.po new file mode 100644 index 0000000..e96dafd --- /dev/null +++ b/po/ca@valencia/okular_chm.po @@ -0,0 +1,47 @@ +# Translation of okular_chm.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2020. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-07-29 15:34+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codificació no acceptada" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"La codificació d'aquest llibre electrònic encara no està acceptada. Per " +"favor, obriu un informe d'error a https://bugs.kde.org per a afegir la " +"codificació" diff --git a/po/ca@valencia/okular_comicbook.po b/po/ca@valencia/okular_comicbook.po new file mode 100644 index 0000000..2c30774 --- /dev/null +++ b/po/ca@valencia/okular_comicbook.po @@ -0,0 +1,63 @@ +# Translation of okular_comicbook.po to Catalan (Valencian) +# Copyright (C) 2008-2018 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008, 2015, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-08 21:25+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"No s'ha pogut obrir el document, no s'ha trobat el «unrar» ni el " +"«unarchiver»." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"La versió del «unrar» en el vostre sistema no és adequada per a obrir " +"ComicBooks." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Format ComicBook desconegut." + +#~ msgid "ComicBook Backend" +#~ msgstr "Dorsal de ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un renderitzador per a diversos formats de ComicBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca@valencia/okular_djvu.po b/po/ca@valencia/okular_djvu.po new file mode 100644 index 0000000..66087a6 --- /dev/null +++ b/po/ca@valencia/okular_djvu.po @@ -0,0 +1,99 @@ +# Translation of okular_djvu.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:34+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Impressor" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volum" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipus de document" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Desconegut" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Fitxers de component" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Desconegut" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Pàgina individual" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Agrupat" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirecte" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Agrupat (antic)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexat (antic)" diff --git a/po/ca@valencia/okular_dvi.po b/po/ca@valencia/okular_dvi.po new file mode 100644 index 0000000..afc7186 --- /dev/null +++ b/po/ca@valencia/okular_dvi.po @@ -0,0 +1,593 @@ +# Translation of okular_dvi.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-08-06 15:18+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

L'Okular no ha pogut trobar el programa dvipdfm a " +"l'ordinador. Aquest programa és essencial perquè funcione la funció " +"exportar. Malgrat tot, podeu convertir el fitxer DVI a PDF usant la funció " +"d'impressió de l'Okular, però això molt sovint produeix documents que " +"s'imprimeixen bé, però són de qualitat inferior si es visualitzen amb " +"l'Acrobat Reader. Seria desitjable actualitzar-lo a una versió més recent " +"del TeX de la vostra distribució que incloga el programa dvipdfm.

Consell per a l'administrador de sistema perplex: l'Okular usa la " +"variable PATH de l'intèrpret d'ordres quan cerca programes.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa extern «dvipdfm», el qual s'usa per a exportar el fitxer, ha " +"informat d'un error. Podeu cercar al diàleg d'informació del " +"document que trobareu al menú Fitxer per a un llistat detallat de " +"l'error." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Aquest fitxer DVI té referències a fitxers gràfics externs que no estan " +"en format PostScript, i no es poden manipular amb el programa dvips " +"que l'Okular usa internament per a imprimir o exportar a PostScript. La " +"funcionalitat que necessiteu no està disponible en aquesta versió de " +"l'Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

L'Okular no ha pogut localitzar el programa dvips a " +"l'ordinador. Aquest programa és essencial perquè funcione la funció " +"d'exportació.

Consell per a l'administrador de sistema perplex: " +"l'Okular usa la variable PATH de l'intèrpret d'ordres quan cerca programes." + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa extern «dvip per as», el qual s'ha usat exportar el fitxer, " +"ha informat d'un error. Podeu cercar al diàleg d'informació del " +"document que trobareu al menú Fitxer per a un llistat detallat de " +"l'error." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "El fitxer DVI no s'inicia amb el preàmbul." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"El fitxer DVI conté la versió incorrecta de l'eixida DVI d'aquest programa. " +"Consell: Si empreu el sistema de procés de tipografia Omega, heu d'usar un " +"programa especial, com l'«oxdvi»." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "El fitxer DVI està corrupte. L'Okular no ha pogut trobar el postàmbul." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "El postàmbul no comença amb l'ordre POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "El postàmbul conté una ordre diferent de FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La pàgina %1 no s'inicia amb l'ordre BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

No s'ha pogut iniciar el programa extern pdf2ps. Com " +"a resultat, el fitxer PDF %1 no s'ha pogut convertir a PostScript. Alguns " +"elements gràfics del document no es visualitzaran.

Un possible " +"motiu: el programa pdf2ps potser no està instal·lat en " +"el sistema, o no es troba al camí actual de cerca.

Què podeu fer: el programa pdf2ps normalment està en distribucions del " +"sistema de l'intèrpret PostScript. Si el ghostscript no està instal·lat en " +"el sistema, el podeu instal·lar ara. Si esteu segur que el ghostscript està " +"instal·lat, intenteu usar el pdf2ps des de la línia " +"d'ordres per a comprovar si realment funciona.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

El fitxer PDF %1 no s'ha pogut convertir a PostScript. Alguns " +"elements gràfics no es visualitzaran.

Un possible motiu: el " +"fitxer %1 podria estar fet malbé, o potser no és un fitxer PDF. Aquesta és " +"l'eixida del programa pdf2ps que ha usat l'Okular:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "S'ha malmés el fitxer. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "No es poden incrustar tots els fitxers PostScript en el document. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"No es poden incrustar tots els fitxers PostScript externs en el document." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "El fitxer «%1» especificat no existeix." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Heu demanat a l'Okular que situe el punt en el fitxer DVI que correspon a la " +"línia %1 del fitxer TeX %2. Tanmateix, sembla que el fitxer DVI no conté la " +"informació del fitxer font necessària. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"L'Okular no ha pogut situar el punt en el fitxer DVI que correspon a la " +"línia %1 del fitxer TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "El codi DVI ha configurat un caràcter d'un tipus de lletra desconegut." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"El codi DVI fa referència al tipus de lletra #%1, el qual no s'ha definit " +"prèviament." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "La pila no estava buida quan s'ha trobat l'ordre EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "La pila estava buida quan s'ha trobat l'ordre POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"El codi DVI fa referència a un tipus de lletra que no s'ha definit " +"prèviament." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "S'ha trobat una ordre no permesa." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "S'ha trobat el codi %1 desconegut." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "S'està incrustant %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Pàgina %1: el fitxer PDF %2 no s'ha pogut convertir a " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Pàgina %1: no s'ha trobat el fitxer PostScript %2.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "La dada «%1» de la mida de paper no s'ha pogut analitzar." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

L'Okular no ha pogut localitzar tots els fitxers de tipus de lletra " +"necessaris per a mostrar el fitxer DVI actual. El document pot ser illegible." +"

CAMÍ: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Hi ha hagut problemes executant el kpsewhich. Com a " +"resultat, no s'han pogut localitzar alguns fitxers de tipus de lletra, el " +"document podria ser illegible.
Un possible motiu: El programa " +"kpsewhich potser no està instal·lat en el sistema, o no s'ha pogut " +"trobar en el camí de cerca actual.

CAMÍ: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"S'ha interromput la generació dels tipus de lletra per al kpsewhich (codi d'eixida %1, error %2). Com a resultat, alguns fitxers de tipus de " +"lletra no es poden localitzar, i el document pot ser illegible." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Actualment s'està generant %1 a %2 ppp..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generador/Data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "No s'ha trobat el fitxer de tipus de lletra" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "vertical" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "apaïsat" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La versió del Ghostview que està instal·lada en aquest ordinador no conté " +"cap dels controladors de dispositiu del Ghostview reconeguts per l'Okular. " +"El funcionament del PostScript es desactivarà ara de l'Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

El programa Ghostview, el qual l'Okular usa internament per a mostrar " +"els gràfics PostScript que s'inclouen en aquest fitxer DVI, generalment és " +"capaç d'escriure la seua eixida en diversos formats. Els subprogrames que el " +"Ghostview usa per a aquestes tasques s'anomenen «controladors de " +"dispositiu». N'hi ha un per a cada format que el Ghostview és capaç " +"d'escriure. Les diferents versions del Ghostview sovint tenen diferents " +"conjunts de controladors de dispositiu disponibles. Sembla que la versió del " +"Ghostview que està instal·lada en aquest ordinador no conté cap dels controladors de dispositiu reconeguts per l'Okular.

Sembla improbable que una instal·lació normal del Ghostview no continga " +"aquests controladors. Per tant, aquest error pot apuntar a una greu " +"desconfiguració de la instal·lació del Ghostview al vostre ordinador.

Si voleu arreglar el problema amb el Ghostview, podeu emprar l'ordre " +"gs --help per a mostrar la llista de controladors de " +"dispositiu continguts al Ghostview. Entre altres, l'Okular pot usar els " +"controladors «png256», «jpeg» i «pnm». Cal tindre en compte que cal tornar a " +"engegar l'Okular per a reactivar el funcionament amb el PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Hi ha 25 errors. No s'imprimiran més missatges d'error." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Error en el fitxer DVI «%1», pàgina %2. S'ha emés l'ordre «color pop» quan " +"la pila de color estava buida." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Paràmetre incorrecte a l'ordre especial «epsf».\n" +"S'esperava un flotant després de %1 a %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"No s'ha trobat el fitxer:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Error en el fitxer DVI «%1», pàgina %2. No s'ha pogut interpretar l'angle en " +"un gir especial de text." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "L'ordre especial «%1» no està implementada." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"El fitxer de tipus de lletra %1 s'ha pogut obrir i llegir, però el seu " +"format de tipus de lletra no està admés." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"El fitxer de tipus de lletra %1 està fet malbé, o no es pot obrir o llegir." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"El FreeType ha informat d'un error en establir la mida del caràcter al " +"fitxer de tipus de lletra %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot carregar el tipus #%1 del fitxer de tipus de lletra %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot representar el tipus #%1 del fitxer de tipus de lletra %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "El tipus #%1 està buit." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "El tipus #%1 del fitxer de tipus de lletra %2 està buit." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"El FreeType no pot carregar la mètrica del tipus #%1 del fitxer de tipus de " +"lletra %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "No es pot obrir el fitxer de tipus de lletra %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: El caràcter %1 no està definit al tipus de lletra %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 no esperat al fitxer PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "El caràcter %1 és massa gran, en el fitxer %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "" +"S'han emmagatzemat un nombre incorrecte de bits: car. %1, tipus de lletra %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Fitxer pk incorrecte (%1), massa bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "El tipus de lletra té una relació d'aspecte no quadrada " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "No s'ha trobat el tipus de lletra %1, al fitxer %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Error a la suma de verificació del fitxer de tipus de lletra %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "No es pot reconèixer el format del fitxer de tipus de lletra %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Error fatal.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Això probablement significa que, o bé heu trobat una errada a l'Okular,\n" +"o que el fitxer DVI, o els fitxers auxiliars (com ara els fitxers de tipus " +"de lletra, \n" +"o els fitxers de tipus de lletra virtuals) estaven fets malbé de mala " +"manera.\n" +"L'Okular s'aturarà després d'aquest missatge. Si penseu que heu trobat una \n" +"errada, o que l'Okular s'hauria de comportar millor en aquesta situació,\n" +"informeu del problema, per favor." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "S'ha trobat una ordre de byte incorrecta a la llista VF de macros: %1" diff --git a/po/ca@valencia/okular_epub.po b/po/ca@valencia/okular_epub.po new file mode 100644 index 0000000..d8776b3 --- /dev/null +++ b/po/ca@valencia/okular_epub.po @@ -0,0 +1,59 @@ +# Translation of okular_epub.po to Catalan (Valencian) +# Copyright (C) 2008-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:42+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Error en obrir el document EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configuració del dorsal per a EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Dorsal EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Un dorsal per l'EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/ca@valencia/okular_fax.po b/po/ca@valencia/okular_fax.po new file mode 100644 index 0000000..1218ad5 --- /dev/null +++ b/po/ca@valencia/okular_fax.po @@ -0,0 +1,37 @@ +# Translation of okular_fax.po to Catalan (Valencian) +# Copyright (C) 2008-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2008. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:38+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "No es pot carregar el document" diff --git a/po/ca@valencia/okular_fictionbook.po b/po/ca@valencia/okular_fictionbook.po new file mode 100644 index 0000000..f706e5b --- /dev/null +++ b/po/ca@valencia/okular_fictionbook.po @@ -0,0 +1,84 @@ +# Translation of okular_fictionbook.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:42+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "El document no és un FictionBook vàlid" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "No es pot obrir el document: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "El document no és un arxiu ZIP vàlid" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Estructura no vàlida del document (el directori principal no existeix)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "No s'ha trobat contingut en el document" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Document XML no vàlid: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuració del dorsal per a FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Dorsal per al Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un renderitzador per a llibres electrònics FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca@valencia/okular_ghostview.po b/po/ca@valencia/okular_ghostview.po new file mode 100644 index 0000000..94efd9a --- /dev/null +++ b/po/ca@valencia/okular_ghostview.po @@ -0,0 +1,96 @@ +# Translation of okular_ghostview.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:40+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usa els tipus de lletra de la plataforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina si el Ghostscript ha de poder usar els tipus de lletra de la " +"plataforma. Si és negatiu, només podrà usar els tipus de lletra incrustats " +"en el document." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Paràmetres generals" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usa els tipus de lletra de la plataforma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuració del dorsal per a Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Versió del document" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivell del llenguatge" + +#~ msgid "PS Backend" +#~ msgstr "Dorsal PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un renderitzador de fitxers PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Basat en la biblioteca Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/ca@valencia/okular_kimgio.po b/po/ca@valencia/okular_kimgio.po new file mode 100644 index 0000000..b50352c --- /dev/null +++ b/po/ca@valencia/okular_kimgio.po @@ -0,0 +1,72 @@ +# Translation of okular_kimgio.po to Catalan (Valencian) +# Copyright (C) 2007-2017 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2009, 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-15 20:59+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "No es pot carregar el document: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Sembla que aquest document té un format incorrecte. Aquesta és la millor " +"aproximació de l'aparença proposada." + +#~ msgid "Image Backend" +#~ msgstr "Dorsal d'imatges" + +#~ msgid "A simple image backend" +#~ msgstr "Un dorsal d'imatges senzill" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra d'eines principal" diff --git a/po/ca@valencia/okular_markdown.po b/po/ca@valencia/okular_markdown.po new file mode 100644 index 0000000..21674c1 --- /dev/null +++ b/po/ca@valencia/okular_markdown.po @@ -0,0 +1,56 @@ +# Translation of okular_markdown.po to Catalan (Valencian) +# Copyright (C) 2017-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Antoni Bella Pérez , 2017, 2020. +# Josep Ma. Ferrer , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:43+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Antoni Bella" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "antonibella5@yahoo.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Ha fallat en obrir el document" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Ha fallat en compilar el document Markdown." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Activa la formatació SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuració del dorsal per a Markdown" diff --git a/po/ca@valencia/okular_mobi.po b/po/ca@valencia/okular_mobi.po new file mode 100644 index 0000000..df2222a --- /dev/null +++ b/po/ca@valencia/okular_mobi.po @@ -0,0 +1,55 @@ +# Translation of okular_mobi.po to Catalan (Valencian) +# Copyright (C) 2009-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2009, 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:44+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Error en obrir el document Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Aquest llibre està protegit per DRM i només es pot visualitzar en el " +"dispositiu designat" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuració del dorsal per a Mobipocket" diff --git a/po/ca@valencia/okular_plucker.po b/po/ca@valencia/okular_plucker.po new file mode 100644 index 0000000..23e490d --- /dev/null +++ b/po/ca@valencia/okular_plucker.po @@ -0,0 +1,48 @@ +# Translation of okular_plucker.po to Catalan (Valencian) +# Copyright (C) 2007-2008 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-03-15 14:56+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nom" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Dorsal per a documents Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un renderitzador per a llibres electrònics Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ca@valencia/okular_poppler.po b/po/ca@valencia/okular_poppler.po new file mode 100644 index 0000000..22bc373 --- /dev/null +++ b/po/ca@valencia/okular_poppler.po @@ -0,0 +1,193 @@ +# Translation of okular_poppler.po to Catalan (Valencian) +# Copyright (C) 2007-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2016, 2017, 2018, 2019. +# Antoni Bella Pérez , 2013, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-29 15:49+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Millora les línies fines:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Sòlid" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opcions del PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprimeix les anotacions" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Inclou les anotacions en el document imprés" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Inclou les anotacions en el document imprés. Podeu desactivar això si voleu " +"imprimir el document original sense anotacions." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Força la rasterització" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasteritza en una imatge abans d'imprimir" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Força la rasterització de cada pàgina en una imatge, abans d'imprimir-la. " +"Normalment, això dóna pitjors resultats, però és útil quan s'imprimeixen " +"documents que semblen imprimir-se incorrectament." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajusta a l'àrea imprimible" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Ajusta a la pàgina completa" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Res; imprimeix la mida original" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Mode d'escalat per a les pàgines impreses" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Mode d'escala:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Encriptat" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Sense encriptar" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Seguretat" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimitzat" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "S'està usant el Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Sestà usant el Poppler %1\n" +"\n" +"Construït contra el Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuració del dorsal per a PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "No disponible" diff --git a/po/ca@valencia/okular_tiff.po b/po/ca@valencia/okular_tiff.po new file mode 100644 index 0000000..ab4f984 --- /dev/null +++ b/po/ca@valencia/okular_tiff.po @@ -0,0 +1,31 @@ +# Translation of okular_tiff.po to Catalan (Valencian) +# Copyright (C) 2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-09 09:37+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" diff --git a/po/ca@valencia/okular_txt.po b/po/ca@valencia/okular_txt.po new file mode 100644 index 0000000..9ad6cc5 --- /dev/null +++ b/po/ca@valencia/okular_txt.po @@ -0,0 +1,54 @@ +# Translation of okular_txt.po to Catalan (Valencian) +# Copyright (C) 2013-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2013. +# Antoni Bella Pérez , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-07-29 15:50+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuració del dorsal per a txt" + +#~ msgid "Txt Backend" +#~ msgstr "Dorsal Txt" + +#~ msgid "Txt backend." +#~ msgstr "Dorsal Txt." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/ca@valencia/okular_xps.po b/po/ca@valencia/okular_xps.po new file mode 100644 index 0000000..8543868 --- /dev/null +++ b/po/ca@valencia/okular_xps.po @@ -0,0 +1,60 @@ +# Translation of okular_xps.po to Catalan (Valencian) +# Copyright (C) 2007-2008 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-09 11:01+0100\n" +"Last-Translator: Josep Ma. Ferrer \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Josep Ma. Ferrer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "txemaq@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisió" + +#~ msgid "XPS Backend" +#~ msgstr "Dorsal XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un dorsal per a l'XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/ca@valencia/org.kde.active.documentviewer.po b/po/ca@valencia/org.kde.active.documentviewer.po new file mode 100644 index 0000000..4eb211d --- /dev/null +++ b/po/ca@valencia/org.kde.active.documentviewer.po @@ -0,0 +1,59 @@ +# Translation of org.kde.active.documentviewer.po to Catalan (Valencian) +# Copyright (C) 2012-2020 This_file_is_part_of_KDE +# This file is distributed under the license LGPL version 2.1 or +# version 3 or later versions approved by the membership of KDE e.V. +# +# Josep Ma. Ferrer , 2012, 2016, 2018, 2019. +# Antoni Bella Pérez , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2020-07-29 16:05+0200\n" +"Last-Translator: Antoni Bella Pérez \n" +"Language-Team: Catalan \n" +"Language: ca@valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Accelerator-Marker: &\n" +"X-Generator: Lokalize 20.04.3\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Obri..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Suprimeix el punt" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Apunta aquesta pàgina" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniatures" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Taula de contingut" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Punts" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Cerca..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "No s'ha trobat cap resultat." diff --git a/po/cs/okular.po b/po/cs/okular.po new file mode 100644 index 0000000..72690eb --- /dev/null +++ b/po/cs/okular.po @@ -0,0 +1,5206 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Lukáš Tinkl , 2010, 2011. +# Vít Pelčák , 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020. +# Tomáš Chvátal , 2012, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-01 16:49+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 20.08.0\n" +"X-Language: cs_CZ\n" +"X-Source-Language: en_US\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Lukáš Tinkl,Klára Cihlářová,Vít Pelčák,Marián Kyral,Tomáš Chvátal,David " +"Kolibáč" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"lukas@kde.org,koty@seznam.cz,vit@pelcak.org,mkyral@email.cz,tomas." +"chvatal@gmail.com,david@kolibac.cz" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, univerzální prohlížeč dokumentů" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Předchozí správce" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Mnoho práce na frameworku a podpůrných vrstvách ODT a FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Vývojář" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Vytvořil Okular ze základů KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Vývojář KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Grafická podoba poznámek" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Nástroj pro výběr tabulky" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Vylepšení poznámek" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Přejít na stranu %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Otevřít externí soubor" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Spustit '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "První strana" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Předchozí strana" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Následující strana" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Poslední strana" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Zpět" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Vpřed" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Ukončit" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Spustit prezentaci" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Ukončit prezentaci" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Najít..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Přejít na stranu..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Přehrát zvuk..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Skript JavaScriptu" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Přehrát film..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Přehrát film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Zastavit film" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Pozastavit film" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Pokračovat v přehrávání filmu" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Výběr implementace" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Bylo nalezeno více implementací zpracování MIME typu:
%1 " +"(%2).

Prosím vyberte, kterou si přejete použít:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Nejvíc stran je %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Na výšku %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Na šířku %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Pokračovat v hledání od začátku" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Pokračovat v hledání zdola" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Nebyl nalezen zásuvný modul vhodný pro zpracování zadaného dokumentu." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Odstranit poznámky" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokument se pokouší spustit externí aplikaci. Pro vaše bezpečí to Okular " +"nepovolil." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Nebyla nalezena žádná aplikace pro otevírání typu MIME %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Nelze otevřít dočasný soubor" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Tisková konverze selhala" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Proces tisku zhavaroval" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Proces tisku nemohl být zahájen" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Tisk do souboru selhal" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Tiskárna byla v nesprávném stavu" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Nelze najít soubor pro vytištění" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Soubor pro tisk nebyl zadán" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Nebyl nalezen vhodný program pro tisk. Ujistěte se, že je program CUPS lpr " +"dostupný" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Velikost stránky k tisku je neplatná" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Nelze otevřít \"%1\". Soubor neexistuje." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Název" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Předmět" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Popis" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Vytvořil" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Producent" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Strany" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Vytvořeno" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Změněno" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Typ MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategorie" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Klíčová slova" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Cesta k souboru" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Velikost souboru" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Velikost stran" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "přidat poznámku" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "odstranit poznámku" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "upravit vlastnosti poznámky" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "přeložit poznámku" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "upravit poznámku" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "upravit text" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "upravit obsah poznámky" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "upravit obsah formuláře" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "upravit položky seznamu" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "upravit výběr seznamu" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "upravit stavy tlačítek" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Obyčejný &text..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Možnosti tisku" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Vyplnit tisknutelnou oblast" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Přizpůsobit plné stránce" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Režim škálování:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Chybí typ upozornění" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Tuto zprávu již nezobrazovat" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Zdroj: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Výc&hozí písmo:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Šířka %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Tloušťka čáry poznámky" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Barva textu poznámky" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Barva okraje poznámky" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Barva poznámky" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Barva výplně poznámky" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Písmo poznámky" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Průhlednost poznámky" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Načíst nastavení pro současný nástroj pro poznámky" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Barva" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Barva výplně" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Vlastní barva..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Experimentální funkce" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Zvolte barvu" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "Poznám&ky" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Skrýt" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Zvýraznění" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Podtržené" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Vlnovka" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Přeškrtnuté" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Strojopisné" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Vložená poznámka" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Vyskakovací poznámka" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Čára od ruky" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Rovná čára" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Šipka" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Pravoúhelník" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Mnohoúhelník" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometrické tvary" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Razítko" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Rychlé poznámky" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Přidat do rychlých poznámek" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Ponechat aktivní" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Ponechat nástroj pro vytváření poznámek po použití aktivní" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Písmo" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Nastavení poznámek" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Šířka čáry" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Krytí" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Strana %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "1 poznámka" +msgstr[1] "%1 poznámky" +msgstr[2] "%1 poznámek" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Otevřít vyskakovací poznámku" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Smazat" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "V&lastnosti" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Uložit '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "Vz&hled" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Obecné" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Vytvořeno:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Změněno:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Vlastnosti vyskakovacích poznámek" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Vlastnosti vložené poznámky" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Vlastnosti čáry" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Vlastnosti mnohostěnu" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Vlastnosti geometrie" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Vlastnosti značek textu" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Vlastnosti razítka" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Vlastnosti čáry od ruky" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Vlastnosti kurzoru" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Vlastnosti přiloženého souboru" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Vlastnosti zvuku" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Vlastnosti videa" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Vlastnosti poznámky" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Změněno: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Ikony (*.ico *.png *.xpm *.svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Neplatný soubor" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Barva:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Neprůhledn&ost:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Ikona:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Komentář" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Nápověda" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Vložit" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Klíč" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nový odstavec" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Poznámka" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Odstavec" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Písmo:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Barva textu:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "Z&arovnat:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Vlevo" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Střed" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Vpravo" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Šíř&ka okraje:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Odsouhlasený" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Tak jak je" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Důvěrný" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Oddělení" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Koncept" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimentální" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Konečný" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Pro komentáře" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Pro veřejnost" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Neodsouhlasený" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ne pro veřejnost" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Prodáno" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Přísně tajné" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Záložka" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informace" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Symbol razítka:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "Šíř&ka:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Začátek řádku:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Konec řádku:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Čtverec" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Kolečko" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamant" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Otevřená šipka" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Uzavřená šipka" + +# žádné parametry funkce v inspektoru funkcí +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Nic" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Kaligrafický" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Povoleno" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Výplň tvaru:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Typ:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Zvýraznění" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Vlnovka" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Podtržené" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Přeškrtnuté" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Pravoúhelník" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graf" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Připínáček" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Svorka" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Značka" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Soubor" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Popis není dostupný." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Název:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Popis:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Nic" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Zavřít tuto poznámku" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Možnosti" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Tato poznámka může obsahovat kód LaTeX.\n" +"Klikněte zde pro renderování." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Nelze nalézt program latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX renderování selhalo" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Nelze nalézt program dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Během vykonávání příkazu 'latex' došlo k problému." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Během vykonávání příkazu 'dvipng' došlo k problému." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Jedna záložka" +msgstr[1] "" +"%1\n" +"\n" +"%2 záložky" +msgstr[2] "" +"%1\n" +"\n" +"%2 záložek" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Záložky" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Hledat..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Pouze aktuální dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Přejít na tuto záložku" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Přejmenovat záložku" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Smazat záložku" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Otevřít dokument" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Odstranit záložky" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Verze" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Sériové číslo" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Vydavatel" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Vydáno dne" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Platný do" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Předmět" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Veřejný klíč" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bitů)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Vlastnost" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Hodnota" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exportovat..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Obecné" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Vydal" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Obecné jméno (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-Mail" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organizace (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Vydáno pro" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Platnost" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Otisk SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Otisk SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Podrobnosti" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Červená" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Zelená" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Modrá" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Žlutá" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Černá" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Bílá" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Kresl&it okraj okolo obrázků" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Kres&lit okraj okolo odkazů" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Změnit &barvy" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Varování: tyto možnosti mohou negativně ovlivnit rychlost vykreslování." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Barevný režim:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Invertovat barvy" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Změnit barvu papíru" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Změnit tmavé a světlé barvy" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Převést na černobílou" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Obrátit jas" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Barva papíru:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Tmavá barva:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Světlá barva:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Práh:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Mluvené slovo" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Databáze" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identita" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Rychlé nástroje pro poznámky" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Vlastní textový editor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Klient Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Klient Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Zadejte příkaz pro zavolání vlastního textového editoru.
\n" +"Můžete přidat následující zástupce:\n" +"
    \n" +"
  • %f - název souboru
  • \n" +"
  • %l - řádek v souboru
  • \n" +"
  • %c - sloupec v souboru
  • \n" +"
\n" +"Pokud nebude %f zadáno, bude název souboru přidán na konec příkazu." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Vyberte editor, který si přejete spustit, když bude Okular chtít otevřít " +"zdrojový soubor." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Příkaz:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Vzhled" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Zobrazovat &rolovací panely" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Propoji&t miniatury se stránkou" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Zobrazovat rady a in&formativní zprávy" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Zobrazit název dokumentu v titulkovém pruhu, pokud je k dispozici" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Pokud není zobrazen nadpis dokumentu:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Zobrazit pouze název souboru" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Zobrazit celou cestu k souboru" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Používat vlastní barvu pozadí" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Funkce programu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "O&tevírat nové soubory v kartách" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "Ří&dit se DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "Znovu načíst dokument při změně soubo&ru" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Zobrazit dialog pro výběr podpůrná vrstvy" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Směr čtení zprava doleva" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Možnosti pohledu" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Přehledové sloup&ce:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Určuje, kolik ze současně zobrazené oblasti bude stále zobrazeno po stisku " +"kláves Page Up/Down." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Přesah Page Up/Down:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Určuje výchozí režim přiblížení pro soubory, které nikdy nebyly otevřeny.\n" +"Pro soubory, které již byly otevřeny, je použito předchozí přiblížení." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Určuje výchozí režim přiblížení pro soubory, které nikdy nebyly otevřeny.\n" +"Pro soubory, které již byly otevřeny, je použito předchozí přiblížení." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Výc&hozí přiblížení:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Přizpůsobit šířce" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Přizpůsobit straně" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automaticky vyplnit" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Udržuje použitou paměť na minimu, nevyužívá opětovně nic (pro systémy s " +"malou pamětí)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Dobrý kompromis mezi využitím paměti a zrychlením aplikace. Předem načítá " +"jednu stránku a urychluje hledání (typicky pro systémy s 2 GB paměti)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Udržuje vše v paměti. Předem načítá následující stránky, urychluje hledání " +"(pro systémy s více než 4 GB paměti)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Načte a uchová vše v paměti. Předem načte všechny stránky (použije maximálně " +"50 % celkové paměti, či volné paměti, dle jejich velikosti)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Využití CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Povoli&t efekty průhlednosti" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Spotřeba paměti" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Níz&ká" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mální (výchozí)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Agr&esivní" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Nenasytný" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Vykreslování" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Povolit antialiasing textu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Povolit antialiasing grafiky" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Povolit Text Hinting" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Aktuální obrazovka" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Výchozí obrazovka" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Obrazovka %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekunda" +msgstr[1] " sekundy" +msgstr[2] " sekund" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigace" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Posunout každých:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Smyčka za poslední stranou" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Ovládání dotekem" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Ťuknutí doleva/doprava pro posun zpět/vpřed" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Ťuknutí kamkoliv pro posun vpřed" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Zakázáno" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Barva pozadí:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Kurzor myši:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Skrytý po prodlevě" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Vždy viditelný" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Vždy skrytý" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Zobrazovat ukazatel &průběhu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Zobrazovat so&uhrnnou stránku" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Povolit přechody" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Výchozí přechod:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Vertikální zatmívačka" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Vodorovná zatmívačka" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Box dovnitř" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Box ven" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Rozpustit" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Blednutí" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Třpyt dolů" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Třpyt doprava" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Třpyt doprava dolů" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Náhodný přechod" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Nahradit" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Vodorovné rozdělení dovnitř" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Vodorovné rozdělení ven" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Svislé rozdělení dovnitř" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Svislé rozdělení ven" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Vyčistit dolů" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Vyčistit doprava" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Vyčistit doleva" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Vyčistit nahoru" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Umístění" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Obrazovka:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Nastavení nástroje pro kreslení" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Nástroj pro kresbu: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Guma" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Název:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Typ:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Vyskakovací poznámka" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Vložená poznámka" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Čára od ruky" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Rovná čára" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Mnohoúhelník" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Označování textu" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "geometrický tvar" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Razítko" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Strojopisné" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Nástroj pro vytváření poznámek" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Nástroj pro úpravu poznámek" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Barva:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Šířka &pera:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Vytvořit nástroj pro kreslení" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Upravit nástroj pro kreslení" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Neznámé" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Vložené soubory" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Pohled" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Jméno" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Popis" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Velikost" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Vytvořeno" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Změněno" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Uložit &jako..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "Po&hled..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Nelze načíst komponentu pro náhled před tiskem" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Náhled před tiskem" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Zavřít" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "Na&jít:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Text k vyhledání" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Následující" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Přejít na následující výskyt" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Předchozí" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Přejít na předchozí výskyt" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Změnit chování vyhledávání" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Rozlišovat velká/malá" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Z aktuální stránky" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Hledat při psaní" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Všechny soubory" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometrie" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Přeškrtnuté" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Kurzor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Soubor s přílohou" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Zvuk" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Obrazovka" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Widget" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rich Media" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Neznámý" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Kam si přejete uložit %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Nelze otevřít \"%1\" pro zápis. Soubor nebyl uložen." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Možnosti hledání" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Rozlišovat velikost písmen" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regulární výraz" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "Hl&edat:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Vrstvy" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "z" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zvětšení" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zvětšení na 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rotovat vp&ravo" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Doprava" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotovat v&levo" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Doleva" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Původní orientace" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Ořeza&t pohled" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Ořeza&t okraje" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Ořezat &podle výběru" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Přizpůsobit šíř&ce" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "&Přizpůsobit straně" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automaticky přizpůsobit" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Přizpůsobit ok&no straně" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Režim zobrazení" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Jedna &strana" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Protile&hlé strany" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Protilehlé strany (&Centrovat první stránku)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Přehled" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "Prů&běžně" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Procházet" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zvětšit" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Přepnou&t změnu barev" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Výběr obla&sti" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Výběr &textu" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Výběr t&abulky" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lupa" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Nástroje výběru" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Přečíst celý dokument" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Přečíst aktuální stránku" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Zastavit čtení" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Posunout nahoru" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Posunout dolů" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Posunout stránku nahoru" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Posunout stránku dolů" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Zobrazit formuláře" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "Načten dokument o %1 stránce." +msgstr[1] "Načten dokument o %1 stranách." +msgstr[2] "Načten dokument o %1 stranách." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Text (1 znak)" +msgstr[1] "Text (%1 znaky)" +msgstr[2] "Text (%1 znaků)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Zkopírovat do schránky" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopírování zakázáno DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Přečíst text" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Obrázek (%1 x %2 pixelů)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Uložit do souboru..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Obrázek (%1x%2) zkopírován do schránky." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Uložit soubor" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Obrázky (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Soubor neuložen." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Obrázek (%1x%2) uložen do souboru (%3)." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopírovat text" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Jít na %1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Vyhledat '%1' pomocí" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Nastavit webové zkratky..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Následovat tento odkaz" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Přehrát tento zvuk" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Zastavit zvuk" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopírovat adresu odkazu" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Vítejte" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Vyberte oblast pro zvětšení. Pravým kliknutím oddálíte." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Kliknutím zobrazíte zvětšený pohled" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "" +"Nakreslete obdélník okolo textu nebo obrázku, který si přejete zkopírovat." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Vybrat text" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Nakreslete obdélník okolo tabulky, poté klikněte na okraje pro rozdělení; " +"stiskem Esc zrušíte výběr." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Nakreslete obdélník okolo oblasti stránky, kterou chcete mít viditelnou" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nová textová poznámka" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Text nové poznámky:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Přidat poznámku do záložek" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Vložit vlastní název poznámky:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Nakreslit elipsu (přetažením vyberete zónu)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Zvýraznit text" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Nakreslit čáru od ruky" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Vkládaná textová poznámka (táhněte pro výběr zóny)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Vyskakovací poznámka" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Nakreslit mnohoúhelník (klikněte na první bod pro jeho uzavření)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Nakreslit obdélník" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Text s vlnovkou" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Umístit symbol razítka" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Nakreslit čáru" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Přeškrtnout text" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Podtrhnout text" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Zvýraznění" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Přidat oblíbenou poznámku" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Vlastní název poznámky:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Soubor" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Na&stavení" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "Nápo&věda" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "Orientace" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Záložky" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Nástrojový panel prohlížeče" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniatury" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Poznámky" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Tento dokument obsahuje vložené soubory. " +"Klikněte zde pro jejich zobrazení nebo jděte do Soubor -> Vložené " +"soubory." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Předchozí" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Přejít na předchozí stránku" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Přesune se na předchozí stranu v dokumentu" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Následující" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Posunout se na následující stránku" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Přesune se na následující stranu v dokumentu" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Začátek dokumentu" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Přesune se na začátek dokumentu" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Konec dokumentu" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Přesune se na konec dokumentu" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Přejmenovat současnou záložku" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Předchozí záložka" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Přejít na předchozí záložku" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Následující záložka" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Přejít na následující záložku" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Nastavit Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Nastavit prohlížeč..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Nastavit podpůrné vrstvy prohlížeče..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Nastavit podpůrné vrstvy..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "O podpůrné vrstvě" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Znovu načíst" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Obnovit současný dokument z disku." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Zavřít vy&hledávací panel" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Číslo strany" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Zobraz&it postranní panel" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Ukázat panel st&ránek" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Vložené soubory" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xportovat jako" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "S&dílet" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&rezentace" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Otevřít odpovídající s&ložku" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importovat Postscript jako PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Stáhnout knihy z Internetu..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Přepnout režim černé obrazovky" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Smazat kreslení" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Nastavit poznámky..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Přehrát/Pozastavit prezentaci" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Nelze otevřít '%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Načítání %1 bylo zrušeno." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Nelze otevřít %1. Důvod: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Nastavit podpůrné vrstvy prohlížeče" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Nastavit podpůrné vrstvy" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Program \"ps2pdf\" nebyl nalezen. Okular jej nemůže použít pro import PS " +"souborů." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf nenalezen." + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Soubory PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importuji PS soubor jako PDF (bude to nějakou dobu trvat)...." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Prosím, vložte heslo pro přečtení dokumentu:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Neplatné heslo. Prosím, zkuste znovu:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Heslo dokumentu" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"tento dokument obsahuje formuláře XFA, jenž momentálně nejsou " +"podporovány." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Tento dokument obsahuje formuláře. Klikněte na tlačítko pro práci s nimi, " +"nebo použijte Zobrazit -> Zobrazit formuláře." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "" + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Odepřít požadavek" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Nelze otevřít '%1'. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Soubor změněn" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "P&okračovat v opakování načítání" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Zavřít dokument" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Tento odkaz směřuje na činnost zavření dokumentu, což není ve vnořeném " +"prohlížeči použitelné." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Tento odkaz směřuje na činnost ukončení aplikace, což není ve vnořeném " +"prohlížeči použitelné." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Znovu načítám dokument..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Obsah" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Podpisy" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Přejít na stranu" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "S&trana:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Zadejte nový název záložky:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Přejmenovat tuto záložku" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Odstranit tuto záložku" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Uložit jako" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Uložit - varování" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Nelze otevřít dočasný soubor pro uložení." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Nelze uložit soubor do '%1'. Pokuste se jej uložit jinam." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Poznámky uživatele" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Varování" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Uložit jako archiv dokumentu Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Pokračovat" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Pokračovat se ztrátou změn" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Nelze uložit soubor do '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular nemůže zkopírovat %1 na zadané místo.\n" +"\n" +"Dokument již neexistuje." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Rozbalit celý úsek" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Svinout celý úsek" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Rozbalit vše" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Svinout vše" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Přidat záložku" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Nástroje" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Tisk" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Tisk tohoto dokumentu je zakázán." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Nelze vytisknout dokument. Neznámá chyba. Prosím nahlaste chybu na http://" +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Nelze vytisknout dokument. Podrobný popis chyby je \"%1\". Prosím nahlaste " +"chybu na http://bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Přejít na předchozí umístění" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Přejít na následující umístění" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Chyba v souboru. Nepovedlo se vytvořit dočasný soubor " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Chyba v souboru. Nepovedlo se otevřít soubor " +"%1 pro dekompresi. Soubor nebude načten." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Chyba v souboru. Nepovedlo se rozbalit soubor " +"%1. Nebude načten." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Tato chyba nastává typicky v případech, kdy je soubor poškozen. Pokud si " +"přejete být jisti, rozbalte soubor ručně pomocí nástrojů z příkazové řádky." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Žádné záložky" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Nastala chyba při sdílení dokumentu: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Sdílet" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Obrázek byl úspěšně sdílen" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "Ú&pravy" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "Po&hled" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "Pře&jít" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Nás&troje" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Hlavní panel nástrojů" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Nástrojová lišta pro poznámky" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Obecné volby" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Zpřístupnění" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Pomůcky pro zpřístupnění čtení" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Výkon" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Ladění výkonu" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Nastavit prohlížeč" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Prezentace" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Možnosti prezentačního režimu" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Volby poznámky" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Možnosti editoru" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Najít následující" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - Prezentace" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Přepnout obrazovku" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Obrazovka %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Ukončit prezentační režim" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Název: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Počet stran: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klikněte k zahájení" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pozastavit" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Přehrát" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Existují dva způsoby, jak opustit prezentační režim. Můžete stisknout " +"klávesu Esc nebo kliknout na ukončovací tlačítko, které se objeví po " +"umístění kurzoru myši do pravého horního rohu. Samozřejmě je také možné " +"použít přepínání oken pomocí Alt + TAB" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Probíhá prezentace" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Neznámý soubor" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Vlastnosti %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Písma" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Načítají se informace o písmech..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Velikosti strany" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extrahovat písmo" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Neznámý" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Vloženo (podmnožina)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Plně vloženo" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ne" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Ano (podmnožina)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Ano" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Neznámé písmo" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Vloženo: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Jméno" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Typ" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Soubor" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Strana" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Velikost" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Není možné uložit soubor %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Zadejte alespoň tři znaky pro filtrování stránek" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Rozlišovat velikost písmen" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Souhlasí fráze" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Souhlasí všechna slova" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Souhlasí některé ze slov" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Volby filtru" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Bez poznámek

Pro vytvoření nové poznámky stiskněte " +"F6 nebo vyberte Nástroje -> Poznámky v nabídce.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Seskupit podle stran" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Seskupit podle autora" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Zobrazit poznámky pouze pro aktuální stránku" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Rozbalit všechny prvky" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Sbalit všechny prvky" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Certifikát byl odvolán." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Certifikát vypršel." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Neznámý algoritmus" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Neznámý typ" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digitální podpis" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Zašifrovat klíče" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Dešifrovat klíče" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Podepsat certifikát" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Podepsat CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Pouze šifrovat" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Čas podepsání: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Nedostupný" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Příčina: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Pole: %1 na straně %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Vlastnosti" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Stav platnosti" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Další informace" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Podepsal(a):" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Čas podepsání:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Důvod:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Umístění:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Verze dokumentu" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Prohlížet certifikát..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Zobrazit pouze stránky se záložkou" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Přehrát" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pozastavit" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Zastavit" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "Přid&at..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Upravit..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "Odst&ranit" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Posunout nahor&u" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Posunout &dolů" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Výchozí nástroje pro kreslení #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Nástroj se zadaným názvem již existuje. Bude použit výchozí." + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Duplicitní název" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Stránka dokumentu, která se má zobrazit" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Spustit dokument v prezentačním režimu" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Spustit s dialogem tisku" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Kontrola \"Unikátní instance\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Nezdvihat okno" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Najít řetězec textu" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"Dokumenty k otevření. Zadejte '-' pro čtení ze standardního vstupu (stdin)." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Chyba: Nelze otevřít víz než jeden dokument s přepínačem --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Chyba: Nelze otevřít víz než jeden dokument s přepínačem --presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Chyba: Nelze otevřít víz než jeden dokument s přepínačem --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Chyba: Nelze otevřít víz než jeden dokument s přepínačem --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Chyba: Nelze otevřít víz než jeden dokument s přepínačem --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Nelze najít komponentu Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Jedna unikátní instance Okularu již běží. Tato instance nebude unikátní." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Nelze najít komponentu okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Kliknutím otevřete soubor\n" +"Kliknutím a podržením otevřete nedávný soubor" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Kliknutím otevřete soubor nebo kliknutím a podržením vyberete " +"nedávný soubor" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Následující karta" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Předchozí karta" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Vrátit zpět zavření karty" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Všechny soubory (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Všechny podporované soubory (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Otevřít dokument" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Potvrdit uzavření" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Zavřít karty" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"Chystáte se zavřít následující %1 karet. Opravdu si přejete pokračovat?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" diff --git a/po/cs/okular_chm.po b/po/cs/okular_chm.po new file mode 100644 index 0000000..df45327 --- /dev/null +++ b/po/cs/okular_chm.po @@ -0,0 +1,42 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vit Pelcak , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-06-03 22:13+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 20.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Nepodporované kódování" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Kódování tohoto ebooku zatím není podporováno. Prosím, nahlaste to na " +"https://bugs.kde.org pro přidání podpory." diff --git a/po/cs/okular_comicbook.po b/po/cs/okular_comicbook.po new file mode 100644 index 0000000..7ae0622 --- /dev/null +++ b/po/cs/okular_comicbook.po @@ -0,0 +1,47 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2011, 2019. +# Tomáš Chvátal , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-08-29 16:24+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 19.08.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl, Vít Pelčák,Marián Kyral" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org,vit@pelcak.org,mkyral@email.cz" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Nelze otevřít dokument, nebyl nalezen ani unrar ani unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Verze unraru přítomná ve vašem systému není vhodná pro otevírání knih " +"komiksů." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Neznámý formát knihy komiksů." diff --git a/po/cs/okular_djvu.po b/po/cs/okular_djvu.po new file mode 100644 index 0000000..7a1ed9a --- /dev/null +++ b/po/cs/okular_djvu.po @@ -0,0 +1,94 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2011-01-03 15:27+0100\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl,Marián Kyral" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org,mkyral@email.cz" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Vydavatel" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Svazek" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Typ dokumentu" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Neznámý" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Soubory komponent" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Neznámý" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Jedna strana" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Přiložený" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Nepřímo" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Přiložený (starý)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexovaný (starý)" diff --git a/po/cs/okular_dvi.po b/po/cs/okular_dvi.po new file mode 100644 index 0000000..0964d80 --- /dev/null +++ b/po/cs/okular_dvi.po @@ -0,0 +1,561 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010, 2011, 2013, 2014, 2019. +# Tomáš Chvátal , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-09-19 13:50+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 19.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl, Marián Kyral" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org,mkyral@email.cz" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular nenašel program dvipdfm na vašem počítači. Tento " +"program je nutný pro správné fungování exportu. Stále můžete převézt tento " +"DVI soubor na PDF pomocí tisku programu Okular. Takto vytvořený PDF " +"dokument lze většinou bez problému vytisknout, ale kvalita zobrazení v " +"programu Acrobat Reader bude nižší. Je proto rozumné aktualizovat na " +"nejnovější verzi systému TeX jenž již obsahuje program dvipdfm.

Rada pro popletené systémové administrátory: Okular prohledává cesty " +"uložené v systémové proměnné PATH.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Externí program 'dvipdfm', použitý na export souboru, ohlásil chybu. " +"Můžete se podívat do dialogu Informace o dokumentu, který " +"je v nabídce Soubor, na přesný výpis chyby." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Tento soubor DVI odkazuje na externí grafické soubory které nejsou ve " +"formátu PostScript a proto nemohou mýt zpracovány programem dvips. " +"Tento program Okular interně používá pro export do PostScriptu. Vámi " +"požadovaná funkcionalita tedy není v této verzi programu Okular dostupná." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular nenašel program dvips na vašem počítači. Tento " +"program je nutný pro správné fungování exportu.

Rada pro popletené " +"systémové administrátory: Okular prohledává cesty uložené v systémové " +"proměnné PATH.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Externí program 'dvips', použitý na export souboru, ohlásil chybu. " +"Můžete se podívat do dialogu Informace o dokumentu, který " +"je v nabídce Soubor, na přesný výpis chyby." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Soubor DVI nezačíná předmluvou." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI soubor obsahuje špatnou verzi DVI výstupu pro tento program. Rada: Pokud " +"používáte sázecí systém Omega, použijte speciální program, jako je oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "DVI soubor je vážně poškozen. Okular nenašel postambuli." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Patička nezačíná příkazem POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Patička obsahuje jiný příkaz než FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Strana %1 nezačíná příkazem BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Externí program pdf2ps nemůže být spuštěn. Proto " +"nemůže být PDF soubor %1 převeden do PostScriptu. Proto nemohou být některé " +"grafické prvky ve vašem dokumentu zobrazeny.

Možné důvody: " +"Program pdf2ps není nainstalován na vašem systému nebo " +"nebyl na zadaných místech nalezen.

Co můžete udělat: Program " +"pdf2ps je obvykle součástí distribuce Ghostscript, " +"interpreteru PostScriptu. Pokud není Ghostscipt na vašem systému " +"nainstalován, můžete jej nyní doinstalovat. Pokud si jste jisti, že je " +"Ghostscript nainstalován, vyzkoušejte spustit pdf2ps z " +"příkazové řádky, aby jste si ověřili, že opravdu funguje.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Soubor PDF %1 nemůže být zkonvertován do PostScriptu. Proto nemohou " +"být některé grafické prvky ve vašem dokumentu zobrazeny.

Možné " +"důvody: Soubor %1 může být poškozen nebo to není PDF soubor. Toto je " +"výstup použitého programu pdf2ps:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Soubor poškozen: %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Zadaný soubor '%1' neexistuje." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI kód použil znak z neznámého písma." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI kód odkazuje na písmo #%1, které nebylo definováno." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Zásobník nebyl prázdný v době, kdy byl nalezen příkaz EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Zásobník byl prázdný v době, kdy byl nalezen příkaz POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI kód odkazuje na písmo, které nebylo definováno." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Byla provedena neplatná instrukce." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Byl nalezen neznámý kód %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Vkládám %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Stránka %1: Soubor PDF %2 nemůže být zkonvertován do " +"PostScriptu.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Strana %1: hledaný řetězec %2 nebyl nalezen.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Údaje o velikosti papíru '%1' nelze zpracovat." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular nenašel všechna písma potřebná pro zobrazení DVI souboru. váš " +"dokument může být nečitelný.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Při spuštění programu kpsewhich nastal problém. V důsledku " +"toho, nebyly nalezeny některé soubory s písmy a váš dokument může být " +"nečitelný.
Možný důvod: Program kpsewhich není pravděpodobně " +"nainstalován ve vašem systému, nebo nebyl na zadaných místech nalezen.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Generování písma programem kpsewhich bylo přerušeno (návratový " +"kód %1, chyba %2). To znamená, že některá písma nebyla nalezena a váš " +"dokument může být nečitelný." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Aktuálně vytvářím %1 v %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Vytvořeno pomocí/Datum" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Soubor s písmem nenalezen" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "portrét" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "krajina" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Verze programu Ghostview nainstalovaná na tomto počítači neobsahuje žádný " +"ovladač zařízení podporovaný programem Okular. Podpora PostScriptu tedy bude " +"v Okularu vypnuta." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Program Ghostview, jenž Okular interně používá pro zobrazení " +"PostScript grafiky uložené v DVI file, podporuje výstup do mnoha programů. " +"Pomocné programy které Ghostview pro tuto úlohu používá se nazývají " +"'ovladače zařízení'; je zde jeden ovladač zařízení pro každý formát, jehož " +"zápis Ghostview podporuje. Různé verze programu Ghostview obsahují často " +"rozdílné sady ovladačů zařízení. Zdá se, že verze Ghostview nainstalovaná " +"na tomto počítači neobsahuje žádný ovladač zařízení " +"podporovaný touto verzí programu Okular.

Zdá se nepravděpodobné, že by " +"standardní instalace programu Ghostview tyto ovladače zařízení neobsahovala. " +"Dá se tedy předpokládat, že instalace programu Ghostview na vašem počítači " +"obsahuje závažné problémy v konfiguraci.

Jestliže si přejete vyřešit " +"problémy s programem Ghostview, použijte prosím příkaz gs --help pro zobrazení seznamu ovladačů zařízení obsažených ve vaší instalaci " +"programu Ghostview. Okular umí, mimo jiné, použít ovladače: 'png256', " +"'jpeg' a 'pnm'. Upozornění: Okular musí být restartován pro opětovné " +"povolení podpory PostScriptu.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"... což je dohromady 25 chyb. Další chybová hlášení nebudou vypisována." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Chyba v DVI souboru '%1' na stránce '%2'. Přístup k neexistující barvě." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Chybný parametr ve speciálním příkazu epsf.\n" +"Očekáváno racionální číslo %1 za %2." + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Soubor nenalezen:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Chyba v DVI souboru '%1' na stránce %2. Nelze interpretovat úhel otočení " +"textu." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Speciální příkaz '%1' není implementován." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Soubor s písmem %1 lze otevřít, ale jeho formát je neznámý a nepodporovaný." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "Soubor s písmem %1 je poškozen, nelze jej otevřít ani přečíst." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"Knihovna FreeType nahlásila chybu při nastavování šířky znaku pro písmo '%1'." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "Knihovna FreeType nemůže načíst znak č. %1 z písma '%2'." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "Knihovna FreeType nemůže zobrazit znak č. %1 z písma '%2'." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Znak č. %1 je prázdný." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Znak č. %1 z písma '%2' je prázdný." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "Knihovna FreeType nemůže načíst metriku pro znak č. %1 z písma '%2'." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Nelze otevřít soubor s písmem %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "Znak %1 není definován v písmu %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Neočekávaný %1 v PK souboru %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Znak %1 v souboru %2 je příliš veliký" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Uložen špatný počet bitů: znak %1, písmo %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Špatný pk soubor (%1) - příliš mnoho bitů" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Písmo má nečtvercový poměr " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Nelze najít písmo %1, soubor %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Chyba kontrolního součtu pro soubor s písmem %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Neznámý formát souboru s písmem %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Kritická chyba.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Toto pravděpodobně znamená, že jste buďto nalezli chybu v Okularu,\n" +"nebo byl soubor DVI či pomocné soubory (jako soubory písem,\n" +"nebo soubory virtuálních písem) jsou vážně poškozeny.\n" +"Okular se po této zprávě ukončí. Pokud věříte, že jste objevili\n" +"chybu, nebo že by se za těchto okolností měl Okular chovat lépe,\n" +"prosím nahlaste to." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Byl nalezen chybný příkazový bajt v seznamu VF maker: %1" diff --git a/po/cs/okular_epub.po b/po/cs/okular_epub.po new file mode 100644 index 0000000..0e5aff1 --- /dev/null +++ b/po/cs/okular_epub.po @@ -0,0 +1,43 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2011, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-20 10:27+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Klára Cihlářová" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "koty@seznam.cz" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Chyba při otevírání EPub dokumentu." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Nastavení podpůrné vrstvy EPub" diff --git a/po/cs/okular_fax.po b/po/cs/okular_fax.po new file mode 100644 index 0000000..319fecf --- /dev/null +++ b/po/cs/okular_fax.po @@ -0,0 +1,32 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-15 14:17+0100\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Vít Pelčák" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "vit@pelcak.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Nelze načíst dokument" diff --git a/po/cs/okular_fictionbook.po b/po/cs/okular_fictionbook.po new file mode 100644 index 0000000..151ef9f --- /dev/null +++ b/po/cs/okular_fictionbook.po @@ -0,0 +1,68 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-20 10:27+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokument není platný FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Nelze otevřít dokument: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokument není platným archivem ZIP" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Neplatná struktura dokumentu (chybí hlavní adresář)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Nenalezen žádný obsah v hlavním dokumentu" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Neplatný XML dokument: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Nastavení podpůrné vrstvy FictionBook" diff --git a/po/cs/okular_ghostview.po b/po/cs/okular_ghostview.po new file mode 100644 index 0000000..07091d9 --- /dev/null +++ b/po/cs/okular_ghostview.po @@ -0,0 +1,76 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2011, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2017-02-01 16:02+0100\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl,Marián Kyral,David Kolibáč" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org,mkyral@email.cz,david@kolibac.cz" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Používat systémová písma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Určuje, zda Ghostscript může používat systémová písma. Pokud není povoleno, " +"jsou použita pouze písma přiložená v dokumentu." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Obecná nastavení" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "Po&užívat systémová písma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Nastavení podpůrné vrstvy Ghostscriptu" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Verze dokumentu" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Úroveň jazyka" diff --git a/po/cs/okular_kimgio.po b/po/cs/okular_kimgio.po new file mode 100644 index 0000000..4237ade --- /dev/null +++ b/po/cs/okular_kimgio.po @@ -0,0 +1,40 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2010-06-07 16:36+0200\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Nelze načíst dokument: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" diff --git a/po/cs/okular_markdown.po b/po/cs/okular_markdown.po new file mode 100644 index 0000000..b5b6504 --- /dev/null +++ b/po/cs/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-08-29 16:25+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 19.08.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Vít Pelčák" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "vit@pelcak.org" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Dokument se nepovedlo otevřít" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Dokument Markdown se nepovedlo přeložit." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Povolit formátování SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Nastavení podpůrné vrstvy Markdown" diff --git a/po/cs/okular_mobi.po b/po/cs/okular_mobi.po new file mode 100644 index 0000000..77863af --- /dev/null +++ b/po/cs/okular_mobi.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-20 10:27+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Vít Pelčák" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "vit@pelcak.org" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Chyba při otevírání dokumentu Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Tato kniha je chráněna DRM a může být zobrazena pouze na určeném zařízení" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Nastavení podpůrné vrstvy Mobipocket" diff --git a/po/cs/okular_plucker.po b/po/cs/okular_plucker.po new file mode 100644 index 0000000..a614e4a --- /dev/null +++ b/po/cs/okular_plucker.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-07-29 13:44+0200\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Jméno" diff --git a/po/cs/okular_poppler.po b/po/cs/okular_poppler.po new file mode 100644 index 0000000..e280f55 --- /dev/null +++ b/po/cs/okular_poppler.po @@ -0,0 +1,191 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2010, 2011, 2013, 2014, 2017, 2019. +# Lukáš Tinkl , 2012. +# Tomáš Chvátal , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-11-14 09:42+0100\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 19.08.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl,David Kolibáč" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org,david@kolibac.cz" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Zvýraznit tenké čáry:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ne" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Plný" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Tvar" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF možnosti" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Tisknout poznámky" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Zahrnout poznámky do vytištěného dokumentu" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Zahrne poznámky ve vytištěném dokumentu. Pokud si přejete vytisknout původní " +"neanotovaný dokument, můžete tuto funkci vypnout." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Vynutit rasterizaci" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Před tiskem rasterizovat do obrázku" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Vynutí před tiskem každé strany její rasterizaci do obrázku. To obvykle vede " +"k o něco horším výsledkům, ale dá se to použít při tisku dokumentů, které se " +"netisknou v pořádku." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Vyplnit tisknutelnou oblast" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Přizpůsobit plné stránce" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Režim škálování:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formát" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Zašifrováno" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Nezašifrováno" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Bezpečnost" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Ano" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimalizováno" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Používám Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Používám Poppler %1\n" +"\n" +"Sestaveno s Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Nastavení podpůrné vrstvy PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Nedostupný" diff --git a/po/cs/okular_tiff.po b/po/cs/okular_tiff.po new file mode 100644 index 0000000..b4f30de --- /dev/null +++ b/po/cs/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# Vit Pelcak , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-21 13:41+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Vít Pelčák" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "vit@pelcak.org" diff --git a/po/cs/okular_txt.po b/po/cs/okular_txt.po new file mode 100644 index 0000000..dea39d6 --- /dev/null +++ b/po/cs/okular_txt.po @@ -0,0 +1,38 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Vit Pelcak , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 09:30+0200\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Vít Pelčák" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "vit@pelcak.org" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "TXT" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Nastavení podpůrné vrstvy TXT" diff --git a/po/cs/okular_xps.po b/po/cs/okular_xps.po new file mode 100644 index 0000000..9ffcad7 --- /dev/null +++ b/po/cs/okular_xps.po @@ -0,0 +1,33 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vít Pelčák , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2011-10-11 11:13+0200\n" +"Last-Translator: Vít Pelčák \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 1.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lukáš Tinkl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lukas@kde.org" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revize" diff --git a/po/cs/org.kde.active.documentviewer.po b/po/cs/org.kde.active.documentviewer.po new file mode 100644 index 0000000..c2c70a4 --- /dev/null +++ b/po/cs/org.kde.active.documentviewer.po @@ -0,0 +1,55 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Vit Pelcak , 2012, 2013, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2018-06-01 14:40+0100\n" +"Last-Translator: Vit Pelcak \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Lokalize 2.0\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Otevřít..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Smazat záložku" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Přidat stránku do záložek" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Náhledy" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Obsah" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Záložky" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Hledat..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Nenalezeny žádné výsledky." diff --git a/po/da/okular.po b/po/da/okular.po new file mode 100644 index 0000000..7fdfabb --- /dev/null +++ b/po/da/okular.po @@ -0,0 +1,5955 @@ +# Danish translation of okular +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Erik Kjær Pedersen , 2002, 2003, 2004, 2005, 2006. +# Erik K. Pedersen , 2005, 2008. +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2020. +# Anders Lund , 2009. +# Claus Christensen , 2012. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-07-27 23:20+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.04.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Erik Kjær Pedersen,Rune Rønde Møller,Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "erik@binghamton.edu,runermoeller@gmail.com,mschlander@opensuse.org" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, en universel dokumentfremviser" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Tidligere vedligeholder" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Masser af arbejde på arkitektur, ODF og FictionBook dokumentmotorerne" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Udvikler" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Skabte Okular fra KPDF-kodebasen" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF-udvikler" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Annotationsgrafik" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Værktøj til tabelmarkering" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Forbedringer af annotationer" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Gå til side %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Åbn ekstern fil" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Kør '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Første side" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Forrige side" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Næste side" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Sidste side" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Tilbage" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Frem" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Luk" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Start præsentation" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Afslut præsentation" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Find..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Gå til side..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Afspil lyd..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript-script" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Afspil film..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Afspil film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stop film" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Sæt film på pause" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Genoptag film" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Valg af dokumentmotor" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Mere end én dokumentmotor blev fundet for mimetypen:
%1 (%2)." +"

Markér den du vil benytte:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "De fleste sider er %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Stående %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Liggende %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 tommer (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Fortsætter søgning fra begyndelsen" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Fortsætter søgning fra bunden" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Kan ikke finde et plugin, der kan håndtere dokument som angives." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "fjern annotationer" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokumentet forsøger at køre et eksternt program og for din sikkerheds skyld, " +"vil Okular ikke tillade dette." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Intet program fundet til at åbne filer af mimetype %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Kunne ikke åbne midlertidig fil" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Konvertering af udskrift mislykkedes" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Udskriftsprocessen brød sammen" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Udskriftsprocessen kunne ikke starte" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Udskrift til fil mislykkedes" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Printeren var i ugyldig tilstand" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Kan ikke finde fil til udskrift" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Der var ingen fil at udskrive" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Kunne ikke finde en passende kørbar fil til udskrift. Sørg for at CUPS-" +"programmet lpr er tilgængeligt" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Sidens udskriftsstørrelse er ugyldig" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Kunne ikke åbne \"%1\". Filen findes ikke." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titel" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Emne" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Beskrivelse" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Forfatter" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Ophavsmand" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Producent" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Ophavsret" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Sider" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Oprettet" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Ændret" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Mimetype" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategori" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Nøgleord" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Filsti" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Filstørrelse" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Sidestørrelse" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "tilføj annotation" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "fjern annotation" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "ændr egenskaber for annotationer" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "oversæt annotation" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "justér annotation" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "redigér tekst" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "redigér annotationsindhold" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "redigér formularindhold" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "redigér listeformular-valg" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "redigér komboformular-valg" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "redigér formularknap-tilstande" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Klartekst..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument tekst" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Udskriftsindstillinger" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Tilpas muligt udskriftsområde" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Tilpas til hel side" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Skaleringstilstand:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Mangler alarmtype" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Vis ikke denne besked igen" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Kilde: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Stan&dard-skrifttype:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Red" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rød" + +#: part/annotationactionhandler.cpp:138 +#, fuzzy, kde-format +#| msgid "Orange" +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Orange" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Yellow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Gul" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgid "Green" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Grøn" + +#: part/annotationactionhandler.cpp:141 +#, fuzzy, kde-format +#| msgid "Cyan" +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cyan" + +#: part/annotationactionhandler.cpp:142 +#, fuzzy, kde-format +#| msgid "Blue" +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blå" + +#: part/annotationactionhandler.cpp:143 +#, fuzzy, kde-format +#| msgid "Magenta" +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, fuzzy, kde-format +#| msgid "White" +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Hvid" + +#: part/annotationactionhandler.cpp:145 +#, fuzzy, kde-format +#| msgid "Gray" +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Grå" + +#: part/annotationactionhandler.cpp:146 +#, fuzzy, kde-format +#| msgid "Black" +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Sort" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Bredde %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Indstillinger for kommentarer" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Kommentarværktøjer" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Kommentarværktøjer" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Kommentarværktøjer" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Kommentarværktøjer" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Kommentar" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Indstillinger for kommentarer" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Farve" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Udfyldningsfarve" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Brugerdefineret farve..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Eksperimentel funktion" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Vælg farve" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotationer" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Skjul" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Fremhævning" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Understregning" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Bølgelinje" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Overstreget" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Skrivemaskine" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Indlejret note" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Pop-op-note" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Frihåndslinje" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Lige linje" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Pil" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rektangel" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polygon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometriske form" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Frimærke" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Hurtige annotationer" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Vælg et annotationsværktøj fra de hurtige annotationer" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Føj til hurtige annotationer" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Hold aktiv" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Opret kommentarværktøj" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Skrifttype" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Indstillinger for annotationer" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Linjebredde" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Uigennemsigtighed" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Side %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotation" +msgstr[1] "%1 annotationer" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Åbn pop-op note" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Slet" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Egenskaber" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "%Gem \"%1\"..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Udseende" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Generelt" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Forfatter:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Oprettet:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Ændret:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Egenskaber for pop-op-noter" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Egenskaber for skrivemaskine" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Egenskaber for indlejrede noter" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Egenskaber for rette linjer" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Egenskaber for polygon" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Egenskaber for figurer" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Egenskaber for tekstopmærkning" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Egenskaber for frimærker" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Egenskaber for frihåndslinje" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Egenskaber for korrekturmærke" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Egenskaber for filbilag" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Egenskaber for lyd" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Film-egenskaber" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Egenskaber for annotationer" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Ændret: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Sæt et frimærkesymbol" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Ikonfiler (*.ico *.png *.xpm *.svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Kunne ikke indlæse filen %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Ugyldig fil" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Farve:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Uigennemsigtighed:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Ikon:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Kommentar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Hjælp" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Indsæt" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Tast" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nyt afsnit" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Note" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Afsnit" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Skrifttype:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Tekst&farve:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "J&ustér:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Venstre" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centreret" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Højre" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Kant&bredde:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Godkendt" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Som nuværende" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Fortrolig" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Ministeriel" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Udkast" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Eksperimentel" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Endelig" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Til kommentering" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Til offentlig udgivelse" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Ikke godkendt" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ikke til offentlig udgivelse" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Solgt" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Tophemmelig" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Bogmærke" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Information" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Frimærkesymbol:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Bredde:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Linjestart:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Linjeslutning:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Kvadrat" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Cirkel" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Ruder" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Åben pil" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Lukket pil" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Ingen" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Ende" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Højre åben pil" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Højre lukket pil" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Skråstreg" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Registerpunktlængde:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Længde af registerpunkts forlængerstykke:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Aktiveret" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Udfyldning af form:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Type:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Fremhævning" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Bølgelinje" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Understregning" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Overstreget" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rektangel" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Symbol for filbilag:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graf" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Tegnestift" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Papirclips" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Tag" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fil" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Ingen beskrivelse tilgængelig." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Navn:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Beskrivelse:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Symbol for korrekturmærke:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ingen" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Luk denne note" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Indstillinger" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Denne kommentar kan indeholde LaTeX-kode.\n" +"Klik her for at rendere." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Kan ikke finde den kørbare fil latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX-rendering mislykkedes" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Kan ikke finde den kørbare fil dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Der opstod et problem under kørsel af kommandoen \"latex\"." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Der opstod et problem under kørsel af kommandoen \"dvipng\"." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Et bogmærke" +msgstr[1] "" +"%1\n" +"\n" +"%2 bogmærker" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Bogmærker" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Søg..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Kun aktuelle dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Gå til dette bogmærke" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Omdøb bogmærke" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Fjern bogmærke" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Åbn dokument" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Fjern bogmærker" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Version" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Serienummer" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Udsteder" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Udstedt den" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Udløber den" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Emne" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Offentlige nøgle" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Brug af nøgle" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bit)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Egenskab" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Værdi" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Certifikatfremviser" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Eksportér..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Generelt" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Udstedt af" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Fælles navn (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-mail" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisation (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Udstedt til" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Gyldighed" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Fingeraftryk" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1-fingeraftryk" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256-fingeraftryk" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detaljer" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Certifikatdata:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Hvor vil du gemme dette certifikat?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Certifikatfil (*.cer)" + +#: part/certificateviewer.cpp:321 +#, fuzzy, kde-format +#| msgid "Unable to export certificate!" +msgid "Could not export the certificate" +msgstr "Kan ikke eksportere certifikatet!" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rød" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Grøn" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blå" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Gul" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Sort" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Hvid" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Tegn kant rundt om &billeder" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Tegn kant rundt om &link" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Skift &farver" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Advarsel: disse tilvalg kan påvirke tegnehastigheden meget dårligt." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Farvetilstand:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Invertér farver" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Skift papirfarve" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Skift mørke og lyse farver" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Konvertér til sort og hvidt" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Invertér lyshed" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Papirfarve:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Mørk farve:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Lys farve:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Grænseværdi:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Tale" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitet" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Opha&vsmand:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Bemærk: informationen her bruges kun til kommentarer og korrektur. " +"Informationen der indsættes her vil ikke overføres uden dit vidende." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Hurtige annotationsværktøjer" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Brugervalgt teksteditor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs-klient" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx-klient" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Indstil kommandoen for en brugerdefineret teksteditor der skal startes." +"
\n" +"Du kan også indsætte nogle makroer:\n" +"
    \n" +"
  • %f - filnavnet
  • \n" +"
  • %l - linjenummeret der skal navigeres til
  • \n" +"
  • %c - kolonnen der skal navigeres til
  • \n" +"
\n" +"Hvis %f ikke er angivet tilføjes filnavnet til kommandoen." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "Vælg den editor du vil bruge nÃ¥r Okular vil Ã¥bne en kildefil." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Kommando:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Udseende" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Vis rulle&bjælker" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Link &miniaturer til siden" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Vis &vink og info-beskeder" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Vis dokumenttitel i titellinjen hvis tilgængelig" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "NÃ¥r dokumenttitel ikke vises:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Vis kun filnavnet" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Vis fuld sti til filen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Anvend brugertilpasset baggrundsfarve" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Programegenskaber" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Åbn nye filer i &faneblade" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Adlyd DRM-begrænsninger" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Genindlæs dokument nÃ¥r filen ændres" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Vis dialog til valg af dokumentmotor" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Læseretning højre til venstre" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Visningsindstillinger" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Oversigtssøj&ler:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Bestemmer hvor meget af det aktuelle visningsomrÃ¥de der stadig vil være " +"synligt ved tryk pÃ¥ tasterne Page Up/Page Down." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Overlap ved &Page Up/Down:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Bestemmer standard zoomtilstand for filer der aldrig før er blevet Ã¥bnet.\n" +"For filer der har været Ã¥bnet før anvendes den forrige zoom." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Bestemmer standard zoomtilstand for filer der aldrig før er blevet Ã¥bnet.\n" +"For filer der har været Ã¥bnet før anvendes den forrige zoom." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Stan&dard-zoom:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Tilpas til bredden" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Tilpas side" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Autotilpas" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Holder hukommelsesforbruget sÃ¥ lavt som muligt. Genbrug ikke noget. (For " +"systemer med lidt hukommelse.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Et godt kompromis mellem hukommelsesforbrug og hastighedsforøgelse. " +"Forudindlæs næste side og gør søgninger hurtigere. (For systemer typisk med " +"2 GB hukommelse.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Holder alting i hukommelsen. Forudindlæs næste side og gør søgninger " +"hurtigere. (For systemer med mere end 4 GB hukommelse.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Indlæser og beholder alt i hukommelsen. Forudindlæsning af alle sider. " +"(Bruger maksimalt 50% af samlede hukommelse eller ledige hukommelse " +"afhængigt af hvad der er størst.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "CPU-forbrug" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Aktivér &gennemsigtighedseffekter" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Hukommelsesforbrug" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Lav" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (standard)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Aggr&essiv" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "G&rÃ¥dig" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rendering" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Aktivér antialias pÃ¥ tekst" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Aktivér antialias pÃ¥ grafik" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Aktivér tekst-hinting" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Nuværende skærm" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Standardskærm" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Skærm %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekund" +msgstr[1] " sekunder" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigering" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "GÃ¥ fremad hver:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "I løkke efter sidste side" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Touch-navigering:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Deaktiveret" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Baggrundsfarve:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Musemarkør:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Skjult efter forsinkelse" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Altid synlig" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Altid skjult" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Vis &fremgangsindikator" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Vis s&ammendragsside" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Aktivér overgange" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Standardovergang:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Lodrette forhæng" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Vandrette forhæng" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Boks ind" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Boks ud" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Opløs" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Fade" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Glitter nedad" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Glitter til højre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Glitter til højre nedad" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Tilfældig transition" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Erstat" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Opdel vandret ind" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Opdel vandret ud" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Opdel lodret ind" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Opdel lodret ud" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Tør ned" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Tør til højre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Tør til venstre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Tør opad" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Placering" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Skærm:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Konfiguration af tegneværktøj" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Tegneværktøj: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Viskelæder" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Navn:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Type:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Pop-op note" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Indlejret note" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "FrihÃ¥ndslinje" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Lige linje" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polygon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Tekstopmærkning" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrisk form" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Frimærke" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Skrivemaskine" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Opret annotationsværktøj" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Redigér annotationsværktøj" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Farve:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Penbredde:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Opret tegneværktøj" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Redigér tegneværktøj" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Ukendt" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Indlejrede filer" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Vis" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Navn" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Beskrivelse" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Størrelse" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Oprettet" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Ændret" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Gem &som..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Vis..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Kunne ikke indlæse forhÃ¥ndsvisningen for udskrivning" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "ForhÃ¥ndsvisning af udskrift" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Luk" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Find:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Søgetekst" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Næste" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Spring til næste træffer" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Forrige" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Spring til næste match" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Ændr søgeopførsel" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Versalfølsom" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Fra den aktuelle side" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Find mens du skriver" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Alle filer" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Signaturegenskaber" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Lige linje med kommentar" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polygon med kommentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometri med kommentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Figur" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Fremhæv med kommentar" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Bølgelinje med kommentar" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Understreg med kommentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Overstreg med kommentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Overstreget" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Frimærke med kommentar" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "FrihÃ¥ndslinje med kommentar" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Korrekturmærke" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Filbilag" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Lyd" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Skærm" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Kontrol" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rige medier" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Ukendt" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Forfatter: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Hvor vil du gemme %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Kunne ikke Ã¥bne \"%1\" til skrivning. Filen blev ikke gemt." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Søgeindstillinger" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Versalfølsom" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regulært udtryk" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Søg:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Lag" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "af" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom til 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rotér til &højre" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Højre" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotér til &venstre" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Venstre" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Oprindelig orientering" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Trim visning" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Trim margener" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Trim til &markering" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Tilpas til &bredden" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Tilpas si&de" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Autotilpas" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Tilpas vi&ndue til side" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Visningstilstand" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Enkelt &side" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "&ModstÃ¥ende sider" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "ModstÃ¥ende sider (¢rér første side)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Overblik" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Kontinuert" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Brug højre mod venstre-læseretning" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Gennemse" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Skift af farver &til/fra" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "OmrÃ¥de&markering" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Tekstmarkering" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "T&abelmarkering" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Forstørrelsesglas" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Markeringsværktøjer" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Oplæs hele dokumentet" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Oplæs nuværende side" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Stop oplæsning" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Sæt oplæsning pÃ¥ pause/genoptag" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Rul op" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Rul ned" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Rul side op" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Rul side ned" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Vis formularer" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Indlæste et et-siders dokument." +msgstr[1] " Indlæste et %1-siders dokument." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Tekst (1 tegn)" +msgstr[1] "Tekst (%1 tegn)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopiér til udklipsholderen" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "DRM forbyder kopiering" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Udtal tekst" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Billede (%1 gange %2 pixels)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Gem til fil..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Billede [%1x%2] kopieret til udklipsholderen." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Gem fil" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Billeder (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Fil ikke gemt." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Billede [%1x%2] gemt til filen %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopiér tekst" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "GÃ¥ til \"%1\"" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Søg efter \"%1\" med" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Indstil webgenveje..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Følge dette link" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Afspil denne lyd" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Stop lyd" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopiér link-adresse" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Søg efter \"%1\" i dette dokument" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Velkommen" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Vælg forstørrelsesomrÃ¥de. Højreklik for at formindske." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Klik for at se den forstørrede visning." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Tegn et rektangel omkring tekst/grafik til kopi." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Markér tekst" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Tegn et rektangel omkring tabellen og klik nær kanterne for at opdele. Tryk " +"Esc for at rydde." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Tegn et rektangel omkring det sideomrÃ¥de du vil holde synligt" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Ny tekstnote" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Notens tekst:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Sæt bogmærke ved annotation" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Tegn en ellipse (træk for at markere en zone)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Fremhæv tekst" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Tegn en frihÃ¥ndslinje" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Indlejret tekstkommentering (træk for at markere en zone)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Sæt en pop-op-note" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Tegn en polygon (klik pÃ¥ første punkt for at lukke den)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Tegn et rektangel" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Bølgelinje-tekst" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Sæt et frimærkesymbol" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Tegn en lige linje" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Overstreg tekst" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Understreg tekst" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Indlejret tekstkommentering (træk for at markere en zone)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Fremhævning" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Tilføj favoritannotation" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Change an annotation's size" +#| msgid "adjust annotation" +msgid "Custom annotation name:" +msgstr "justér kommentar" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fil" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Indstillinger" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Hjælp" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientering" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Bogmærker" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Fremviserværktøjslinje" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniaturer" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotationer" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Dette dokument har indlejrede filer. Klik " +"her for at se dem eller gå til Fil -> Indlejrede filer." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Forrige" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Gå til forrige side" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Går til den forrige side i dokumentet" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Næste" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Gå fremad til næste side" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Går til den næste side i dokumentet" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Dokumentets start" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Går til starten af dokumentet" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Dokumentets slutning" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Går til slutningen af dokumentet" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Omdøb det aktuelle bogmærke" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Forrige bogmærke" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Gå til forrige bogmærke" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Næste bogmærke" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Gå til næste bogmærke" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Indstil Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Indstil fremviser..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Indstil motorer for fremviseren..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Indstil dokumentmotorer..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Om dokumentmotor" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Genin&dlæs" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Genindlæs det aktuelle dokument fra disk." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Luk &find-bjælken" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Sidenummer" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Markér al tekst på aktuel side" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Vis s&idepanel" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Vis sidens &panel" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Vis &signaturpanel" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Indlejrede filer" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&Eksportér som" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "D&el" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&ræsentation" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Åbn inde&holdende mappe" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importér PostScript som PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Hent bøger fra Internettet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Skift sortskærmtilstand" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Slet tegning" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Indstil annotationer..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Afspil/pause præsentation" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Kunne ikke åbne \"%1\" (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Indlæsning af %1 er blevet annulleret." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Kunne ikke åbne %1. Årsag: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Indstil motorer for fremviseren" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Indstil dokumentmotorer" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Programmet \"ps2pdf\" blev ikke fundet, så Okular kan ikke importere PS-" +"filer ved hjælp af det." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf ikke fundet" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript-filer (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importerer PS-fil som PDF (dette kan tage noget tid)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Angiv venligst kodeordet for at læse dokumentet:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Forkert kodeord. Forsøg igen:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Adgangskode til dokument" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Dette dokument har XFA-formularer som i øjeblikket ikke er understøttet." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Dette dokument har formularer. Klik på knappen for at interagere med dem, " +"eller gå til Vis -> Vis formularer." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Dette dokument er digitalt signeret." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "This document is digitally signed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Dette dokument er digitalt signeret." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Dette dokument vil vises i fuldskærm.\n" +"Vil du forlade normal tilstand og gå i præsentationstilstand?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Anmoder om ændring af visningstilstand" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Gå i præsentationstilstand" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Afvis anmodning" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Kunne ikke åbne %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Fil ændret" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Fortsæt genindlæsning" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Afbryd genindlæsning" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Fortsæt lukning" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Afbryd lukning" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Vil du gemme dine ændringer af \"%1\" eller kassere dem?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Luk dokument" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Dette link peger til en 'luk dokument'-handling der ikke virker når du " +"bruger den indlejrede fremviser." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Dette link peger til en 'afslut program'-handling der ikke virker når du " +"bruger den indlejrede fremviser." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Genindlæser dokumentet..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Indhold" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signaturer" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Gå til side" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "S&ide:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Angiv det nye navn på bogmærket:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Omdøb dette bogmærke" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Fjern dette bogmærke" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Gem som" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Filen \"%1\" er blevet ændret af et andet program, hvilket betyder at den " +"ikke længere kan gemmes." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Gem - advarsel" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Kunne ikke åbne midlertidig fil til gemning." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Fil kunne ikke gemmes til '%1'. Prøv at gem den et andet sted." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Udfyldt formularindhold" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Brugerannotationer" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Advarsel" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Gem som Okular dokumentarkiv..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Fortsæt" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Fortsæt med tab af ændringer" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Filen kunne ikke gemmes til \"%1\". %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular kan ikke kopiere %1 til det angivne sted.\n" +"\n" +"Dokumentet eksisterer ikke mere." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Fil kunne ikke gemmes i \"%1\". Fejl: \"%2\". Prøv at gemme den et andet " +"sted." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Fold hele sektionen ud" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Fold hele sektionen sammen" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Fold alle ud" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Fold alle sammen" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Tilføj bogmærke" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Værktøjer" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Udskriv" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Udskrift af dokumentet tillades ikke." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Kunne ikke udskrive dokumentet. Ukendt fejl. Rapportér venligst til bugs.kde." +"org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Kunne ikke udskrive dokumentet. Den detaljerede fejl er \"%1\". Rapportér " +"til bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Gå til det sted du var før" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Gå til det sted du var efter" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Fil-fejl! Kunne ikke oprette midlertidig fil " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Fil-fejl! Kunne ikke åbne filen %1 til udpakning. Filen vil ikke blive indlæst." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Dette sker typisk, hvis ikke du har tilstrækkelige tilladelser til at " +"læse filen. Du kan tjekke ejerskab og tilladelser, hvis du højreklikker på " +"filen i filhåndteringen Dolphin, og vælger fanebladet 'Egenskaber'." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Fil-fejl! Kunne ikke udpakke filen %1. Filen vil ikke blive indlæst." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Denne fejl sker typisk hvis filen er ødelagt. Hvis du vil være sikker, " +"så forsøg at udpakke filen manuelt vha. kommandolinje-værktøjer." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Ingen bogmærker" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Der opstod et problem ved deling af dette dokument: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Del" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Dokumentet blev delt" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Du kan finde det delte dokument på: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Redigér" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Vis" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Gå" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Værk&tøjer" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Hovedværktøjslinje" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Annotationsværktøjslinje" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Generelle indstillinger" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Tilgængelighed" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Hjælpemidler til læsning" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Ydelse" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Finindstilling af ydelse" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Indstil fremviser" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Præsentation" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Indstillinger for præsentationstilstand" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Indstillinger for annotationer" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Editor-indstillinger" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Find næste" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - præsentation" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Skift skærm" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Skærm %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Forlad præsentationstilstand" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titel: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Sider: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klik for at begynde" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pause" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Afspil" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Der er to måder at afslutte præsentationstilstand. Du kan trykke på tasten " +"Esc, eller klikke med afslutningsknappen som vises når musen placeres i " +"øverste højre hjørne. Du kan naturligvis gå gennem vinduerne cyklisk " +"(normalt med Alt+Tabulator)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Viser en præsentation" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Ukendt fil" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1-egenskaber" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Skrifttyper" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Genindlæser skrifttypeinformation..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "S&idestørrelser" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Udpak skrifttype" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "Truetype" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "Truetype (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID Truetype" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID Truetype (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Ukendt" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Indlejret (delsæt)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Fuldt indlejret" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Nej" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Ja (delsæt)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Ja" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (erstatter med %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Ukendt skrifttype" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Indlejret: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Navn" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Type" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fil" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Side" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Størrelse" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Forhåndsvisning af revision" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Hvor vil du gemme denne revision?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Kunne ikke gemme filen %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Kunne ikke vise revision." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Indtast mindst 3 bogstaver for at filtrere sider" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Versalfølsom" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Match udtryk" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Match alle ord" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Match et ord" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Filterindstillinger" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Ingen kommentarer

For at oprette nye annotationer, " +"tryk på F6 eller vælg Værktøjer -> annotationer fra menuen.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Gruppér efter side" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Gruppér efter forfatter" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Vis kun annotationer for den aktuelle side" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Fold alle elementer ud" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Fold alle elementer sammen" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Signaturen er kryptografisk gyldig." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Signaturen er kryptografisk ugyldig." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Certifikatet er betroet." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Certifikatet er blevet sat ud af kraft." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Certifikatet er udløbet." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Ukendt skrifttype" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Ukendt type" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digital signatur" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Kryptér nøgler" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Afkryptér nøgler" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Nøgleaftale" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Signér certifikat" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Signér CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Kun kryptering" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Ikke tilgængelig" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Årsag: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Egenskaber" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Gyldighedsstatus" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Yderligere information" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signeret af:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Årsag:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Placering:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Dokumentversion" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Vis certifikat..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Vis kun sider med bogmærker" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Afspil" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pause" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stop" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Tilføj..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Redigér..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Fjern" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Flyt &op" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Flyt &ned" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Standard tegneværktøj #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Der findes allerede et værktøj med det navn. Bruger et standardnavn" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Duplikeret navn" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Side af dokumentet der skal vises" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Start i præsentationstilstand" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Start med udskriftsdialog" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Start med udskriftsdialog og afslut efter udskrift" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Kontrol af \"unik instans\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Hæv ikke vindue" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Find en streng i teksten" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Dokumenter der skal åbnes. Angiv \"-\" for at læse fra stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Fejl: Kan ikke åbne mere end ét dokument med flaget --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "Fejl: Kan ikke åbne mere end ét dokument med flaget --presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Fejl: Kan ikke åbne mere end ét dokument med flaget --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Fejl: Kan ikke åbne mere end ét dokument med flaget --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Fejl: Kan ikke åbne mere end ét dokument med flaget --find " + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Kan ikke finde Okular-komponenten: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Der kører allerede en unik Okular-instans. Denne instans vil ikke være den " +"unikke." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Kan ikke finde Okular-komponenten." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Klik for at åbne en fil\n" +"Klik og hold for at åbne en nylig fil" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klik for at åbne en fil eller Klik og hold for at åbne en " +"nylig fil" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Næste faneblad" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Forrige faneblad" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Fortryd luk faneblad" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Alle filer (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Alle understøttede filer (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Åbn dokument" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Bekræft lukning" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Luk faneblade" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Du er ved at lukke %1 faneblade. Vil du virkelig fortsætte?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Advar mig når jeg forsøger at lukke flere faneblade" + +#~ msgid "Reviews" +#~ msgstr "Korrektur" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Skjul formularer" + +#~ msgid "Expired" +#~ msgstr "Udløbet" + +#~ msgid "&Review" +#~ msgstr "&Korrektur" + +#~ msgid "Annotations author" +#~ msgstr "Kommentarens forfatter" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Skriv dit navn eller dine initialer:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Vis &navigationspanel" + +#~ msgid "Show Text" +#~ msgstr "Vis tekst" + +#~ msgid "Small Icons" +#~ msgstr "Små ikoner" + +#~ msgid "Normal Icons" +#~ msgstr "Normale ikoner" + +#~ msgid "Large Icons" +#~ msgstr "Store ikoner" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Klik for at benytte det aktuelle markeringsværktøj\n" +#~ "Klik og hold nede for at vælge et andet markeringsværktøj" + +#~ msgid "Created: %1" +#~ msgstr "Oprettet: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Linjeforlængerstykker" + +#~ msgid "Style" +#~ msgstr "Stil" + +#~ msgid "&Size:" +#~ msgstr "&Størrelse:" + +#~ msgid "Inner color:" +#~ msgstr "Indre farve:" + +#~ msgid "Name: %1" +#~ msgstr "Navn: %1" + +#~ msgid "Size: %1" +#~ msgstr "Størrelse: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Browserværktøj" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Zoomværktøj" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "&Selection Tool" +#~ msgstr "&Markeringsværktøj" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Markering" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Tekstmarkeringsværktøj" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Værktøj til t&abelmarkering" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Forstørrelsesglas" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Dokumentets slutning" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Ingen" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Dokumentet bad om at blive startet i præsentationstilstand.\n" +#~ "Vil du tillade det?" + +#~ msgid "Presentation Mode" +#~ msgstr "Præsentationstilstand" + +#~ msgid "Allow" +#~ msgstr "Tillad" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Tillad præsentationstilstand" + +#~ msgid "Do Not Allow" +#~ msgstr "Tillad ikke" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Tillad ikke præsentationstilstand" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Dine kommentarændringer vil ikke blev gemt automatisk. Brug Fil -> Gem " +#~ "som...\n" +#~ "ellers vil dine ændringer gå tabt når dokumentet lukkes" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Din kommentar gemmes internt af Okular.\n" +#~ "Du kan eksportere det kommenterede dokument med Fil -> Eksportér som -> " +#~ "Dokumentarkiv" + +#~ msgid "Save &Copy As..." +#~ msgstr "Gem &kopi som..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Din kommentar vil ikke blive eksporteret.\n" +#~ "Du kan eksportere det kommenterede dokument med Fil -> Eksportér som -> " +#~ "Dokumentarkiv" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Slutningen af dokumentet er nået.\n" +#~ "Fortsæt fra starten?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Starten af dokumentet er nået.\n" +#~ "Fortsæt fra bunden?" + +#~ msgid "Current maintainer" +#~ msgstr "Nuværende vedligeholder" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Blyantfarve:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "liggende DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "stående DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "liggende DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "stående DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "liggende DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "stående DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "liggende DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "stående DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "liggende DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "stående DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "liggende DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "stående DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "liggende DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "stående DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "liggende DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "stående DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "liggende DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "stående DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "liggende DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "stående DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "liggende DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "stående DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "liggende DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "stående DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "liggende DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "stående DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "liggende DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "stående DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "liggende DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "stående DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "liggende DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "stående DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "liggende DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "stående DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "liggende DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "stående DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "liggende DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "stående DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "liggende DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "stående DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "liggende DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "stående DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "Liggende letter" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "Stående letter" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "liggende legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "stående legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "liggende executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "stående executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "liggende Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "stående Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "liggende DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "stående DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "liggende folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "stående folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "ukendt liggende papirstørrelse" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "ukendt stående papirstørrelse" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Skift tegnetilstand" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Start af Jovie tekst-til-tale-tjeneste mislykkedes: %1" + +#~ msgid "Search Columns" +#~ msgstr "Søg i søjler" + +#~ msgid "All Visible Columns" +#~ msgstr "Alle synlige søjler" + +#~ msgid "No document opened." +#~ msgstr "Intet dokument at åbnet." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "Kan ikke åbne mere end ét dokument i den unikke Okular-instans." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Ingen træffere fundet for '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Søger..." + +#~ msgid "Searching for %1" +#~ msgstr "Søger efter %1" + +#~ msgid "Identity Settings" +#~ msgstr "Indstillinger for identitet" + +#~ msgid "Highlight Properties" +#~ msgstr "Egenskaber for fremhævning" + +#~ msgid "Ink Properties" +#~ msgstr "Egenskaber for blæk" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Tekstkommentar" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Grønt blæk" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Gul fremhævning" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Gul fremhævning" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Lige gul linje" + +#~ msgid "Black Underlining" +#~ msgstr "Sort understregning" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Understreg teksten med en sort linje" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Cyan-farvet ellipse" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Cyan-farvet ellipse" + +#~ msgid "Ink" +#~ msgstr "Blæk" + +#~ msgid "Enable &background generation" +#~ msgstr "Aktivér &baggrundsgenerering" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Skjul formularer" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Går til den første side i dokumentet" + +#~ msgid "Moves to the last page of the document" +#~ msgstr "Går til den sidste side i dokumentet" + +#~ msgid "You must set this name:" +#~ msgstr "Du skal skrive et navn her:" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Skifter mellem filsti og titel" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Overskriv" + +#~ msgid "Pages:" +#~ msgstr "Sider:" + +#~ msgid "Green Highlighter" +#~ msgstr "Grøn fremhævning" + +#~ msgid "okular" +#~ msgstr "okular" + +#, fuzzy +#~| msgid "&Properties" +#~ msgid "&Properties..." +#~ msgstr "&Egenskaber" + +#, fuzzy +#~ msgid "Pink Highlighter" +#~ msgstr "&Egenskaber" + +#, fuzzy +#~| msgid "Moves to the next page of the document" +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "Går til den næste side i dokumentet" + +#, fuzzy +#~| msgid "Fit to &Text" +#~ msgid "Fit &Text" +#~ msgstr "Tilpas til &tekst" + +#, fuzzy +#~| msgid "Advance every:" +#~ msgid "&Advanced" +#~ msgstr "Gå fremad hver:" + +#, fuzzy +#~ msgid "Contents:" +#~ msgstr "&Kontinuert" + +#~ msgid "Hide &Navigation Panel" +#~ msgstr "Skjul navigationspanel" + +#, fuzzy +#~| msgid "Page %1" +#~ msgid "page %1" +#~ msgstr "Side %1" + +#~ msgid "Show &search bar in thumbnails list" +#~ msgstr "Vis &søgelinje i miniaturelisten" + +#, fuzzy +#~| msgid "Speak Text" +#~ msgid "Free Text" +#~ msgstr "Udtal tekst" + +#, fuzzy +#~| msgid "Format" +#~ msgid "Form" +#~ msgstr "Format" + +#, fuzzy +#~| msgid "General" +#~ msgid "DlgGeneral" +#~ msgstr "Generelt" + +#~ msgid "Program Look" +#~ msgstr "Programmets udseende" + +#~ msgid "Reading Aids" +#~ msgstr "Læsehjælp" + +#, fuzzy +#~| msgid "Could not open %1" +#~ msgid "Click for Open %1" +#~ msgstr "Kunne ikke åbne %1" + +#, fuzzy +#~ msgid "contents:" +#~ msgstr "&Kontinuert" + +#, fuzzy +#~| msgid "Pages:" +#~ msgid "flags:" +#~ msgstr "Sider:" + +#~ msgid "&Watch file" +#~ msgstr "&Overvåg fil" + +#~ msgid "Clear filter" +#~ msgstr "Ryd filter" + +#~ msgid "Topic" +#~ msgstr "Emne" + +#~ msgid "Fit to Page &Width" +#~ msgstr "Tilpas til side&bredden" + +#~ msgid "&Two Pages" +#~ msgstr "&To sider" + +#~ msgid "Starting -- find text as you type" +#~ msgstr "Starter -- find tekst mens du skriver" + +#~ msgid "Security" +#~ msgstr "Sikkerhed" + +#~ msgid "Optimized" +#~ msgstr "Optimeret" + +#~ msgid "Unknown Encryption" +#~ msgstr "Ukendt kryptering" + +#~ msgid "Unknown Optimization" +#~ msgstr "Ukendt optimering" + +#~ msgid "unknown" +#~ msgstr "ukendt" + +#~ msgid "-" +#~ msgstr "-" + +#~ msgid "[none]" +#~ msgstr "[ingen]" + +#, fuzzy +#~ msgid "kpdf, a kde pdf viewer based on poppler" +#~ msgstr "kpdf, KDE's pdf-fremviser baseret på xpdf" + +#~ msgid "KPDF::Part" +#~ msgstr "KPDF::Part" + +#~ msgid "Converting from ps to pdf..." +#~ msgstr "Konverterer fra ps til pdf..." + +#~ msgid "" +#~ "You do not have ps2pdf installed, so kpdf cannot open postscript files." +#~ msgstr "" +#~ "Du har ikke ps2pdf installeret, så kpdf kan ikke åbne postscript-filer." + +#~ msgid "Text found: \"%1\"." +#~ msgstr "Tekst fundet: \"%1\"." + +#~ msgid "Text not found: \"%1\"." +#~ msgstr "Tekst ikke fundet: \"%1\"." + +#~ msgctxt "PDF v. " +#~ msgid "PDF v. %1" +#~ msgstr "PDF v. %1" + +#~ msgid "" +#~ "The margins you specified change the page aspect ratio. Do you want to " +#~ "print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that the aspect ratio is preserved?" +#~ msgstr "" +#~ "Marginerne du angav ændrer sidens proportion. Vil du udskrive med den " +#~ "ændrede proportion, eller vil du at marginerne indstilles så " +#~ "proportionen bevares?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Ændring af proportion" + +#~ msgid "Print with specified margins" +#~ msgstr "Udskriv med angivne marginer" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Udskriv med indstillede marginer som beholder proportionen" + +#~ msgid "Xpdf author" +#~ msgstr "Forfatter til Xpdf" + +#~ msgid "" +#~ "You are trying to overwrite \"%1\" with itself. This is not allowed. " +#~ "Please save it in another location." +#~ msgstr "" +#~ "Du forsøger at overskrive \"%1\" med sigselv. Dette er ikke tilladt. Gem " +#~ "den venligst et andet sted." diff --git a/po/da/okular_chm.po b/po/da/okular_chm.po new file mode 100644 index 0000000..6701ad1 --- /dev/null +++ b/po/da/okular_chm.po @@ -0,0 +1,60 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2008-03-26 12:53+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: LoKalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "CHM dokumentmotor" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "En dokumentmotor til Microsoft Windows hjælpefiler" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/da/okular_comicbook.po b/po/da/okular_comicbook.po new file mode 100644 index 0000000..64be183 --- /dev/null +++ b/po/da/okular_comicbook.po @@ -0,0 +1,58 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2008-12-16 18:28+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Kan ikke åbne dokument, unrar blev ikke fundet." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Versionen af unrar på dit system er ikke egnet til åbning af comicbook-filer." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Ukendt ComicBook-format." + +#~ msgid "ComicBook Backend" +#~ msgstr "ComicBook-motor" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Rendering af diverse tegneserieformater" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/da/okular_djvu.po b/po/da/okular_djvu.po new file mode 100644 index 0000000..6673496 --- /dev/null +++ b/po/da/okular_djvu.po @@ -0,0 +1,140 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008. +# Anders Lund , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2009-01-05 21:18+0100\n" +"Last-Translator: Anders Lund \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Udgiver" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Bind" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Dokumenttype" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Ukendt" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Komponentfiler" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Ukendt" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Enkelt side" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Bundtet" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirekte" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Bundtet (gammel)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indekseret (gammel)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVU dokumentmotor" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu-motor baseret på DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgid "A DjVu backend" +#~ msgstr "Dokumentmotor til DjVU" diff --git a/po/da/okular_dvi.po b/po/da/okular_dvi.po new file mode 100644 index 0000000..29bd884 --- /dev/null +++ b/po/da/okular_dvi.po @@ -0,0 +1,847 @@ +# translation of okular_dvi.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2008. +# Martin Schlander , 2008, 2009, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-03-09 16:17+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: dviexport.cpp:117 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvipdfm' on your computer. This " +#| "program is essential for the export function to work. You can, however, " +#| "convert the DVI-file to PDF using the print function of Okular, but that " +#| "will often produce documents which print okay, but are of inferior " +#| "quality if viewed in Acrobat Reader. It may be wise to upgrade to a more " +#| "recent version of your TeX distribution which includes the 'dvipdfm' " +#| "program.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"Okular kunne ikke lokalisere programmet 'dvipdfm' på din computer. Dette " +"program er essensielt for at eksportering virker. Du kan dog konvertere DVI-" +"filen til PDF ved hjælp af Okulars udskrivningsfunktionalitet, men dette " +"resulterer ofte i dokumenter der til trods for god udskriftskvalitet, " +"fremstår i dårlig kvalitet når det åbnes med Acrobat Reader. Det kan være en " +"fordel at opgradere til en nyere version af din TeX-distribution, der " +"inkluderer 'dvipdfm'-programmet.\n" +"Tip til systemadministrator: Okular bruger PATH-miljøvariblen når der ledes " +"efter programmer." + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Det eksterne program 'dvipdfm', der blev brugt til at eksportere filen, " +"rapporterede en fejl. Du har måske lyst til at se i dokumentinfo-" +"dialogen som du finder i Fil-menuen efter en præcis fejlrapport." + +#: dviexport.cpp:158 +#, fuzzy, kde-format +#| msgid "" +#| "This DVI file refers to external graphic files which are not in " +#| "PostScript format, and cannot be handled by the 'dvips' program that " +#| "Okular uses internally to print or to export to PostScript. The " +#| "functionality that you require is therefore unavailable in this version " +#| "of Okular." +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"DVI-filen refererer til eksterne grafikfiler som ikke er i PostScript-" +"formatet og som ikke kan behandles af programmet \"dvips\", som Okular " +"bruger internt til at udskrive eller eksportere til PostScript. " +"Funktionaliteten er derfor ikke tilstede i denne version af Okular." + +#: dviexport.cpp:166 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvips' on your computer. That " +#| "program is essential for the export function to work.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"Okular kunne ikke lokalisere programmet 'dvips' på dit system. Programmet er " +"essensielt for at eksporteringsfunktionen fungerer.\n" +". Tip til systemadministratoren: Okular bruger PATH-miljøvariablen når der " +"ledes efter programmer." + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Det eksterne program 'dvips', der blev brugt til at eksportere filen, " +"rapporterede en fejl. Du har måske lyst til at se i dokumentinfo-" +"dialogen som du finder i Fil-menuen efter en præcis fejlrapport." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI-filen starter ikke med præambelet." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI-filen indeholder den forkerte udgave af DVI-uddata til dette program. " +"Tip: Hvis du bruger typografisystemet Omega, skal du bruge et specielt " +"program som for eksempel oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "DVI-filen er beskadiget. Okular kunne ikke finde postambelet." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Postambelet begynder ikke med POST-kommandoen." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Postambelet indeholdt en anden kommando end FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Siden %1 begynder ikke med BOP-kommandoen." + +#: dviFile.cpp:380 +#, fuzzy, kde-format +#| msgid "" +#| "

The external program pdf2ps could not be started. " +#| "As a result, the PDF-file %1 could not be converted to PostScript. Some " +#| "graphic elements in your document will therefore not be displayed.

Possible reason: The program pdf2ps may not " +#| "be installed on your system, or cannot be found in the current search " +#| "path.

What you can do: The program pdf2ps " +#| "is normally contained in distributions of the ghostscript PostScript " +#| "interpreter system. If ghostscript is not installed on your system, you " +#| "could install it now. If you are sure that ghostscript is installed, try " +#| "to use pdf2ps from the command line to check if it " +#| "really works.

PATH: %2

" +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Det eksterne program pdf2ps kunne ikke startes. Som " +"en følge heraf kunne PDF-filen %1 ikke konverteres til PostScript. Nogle " +"grafiske elementer i dit dokument vil derfor ikke være synlige.

Mulig årsag: Programmet pdf2ps er muligvis ikke " +"installeret på dit system, eller også kan det ikke findes i søgestien.

Dette kan du gøre: Programmet pdf2ps findes " +"normalt i distributioner af Ghostscript PostScript fortolkersystemet. Hvis " +"Ghostscipt ikke er installeret på dit system, kan du installere det nu. Hvis " +"du er sikker på at Ghostscript er installeret, så forsøg at bruge " +"pdf2ps fra kommandolinjen for at konstatere at det virker.

STI: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

PDF-filen %1 kunne ikke konverteres til PostScript. Visse grafiske " +"elementer i dit dokument vil derfor ikke blive vist.

Mulig årsag: Filen %1 er måske defekt, eller er måske slet ikke en PDF-fil. Dette er " +"outputtet fra pdf2ps-programmet som Okular brugte:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Fil defekt. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Ikke alle PostScript-filer kunne indlejres i dit dokument. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Alle eksterne PostScript-filer blev indlejret i dit dokument." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Den angivne fil \"%1\" findes ikke." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Du har bedt Okular om at finde stedet i DVI-filen, som svarer til linje %1 i " +"TeX-filen %2. Det lader dog ikke til at DVI-filen indeholder den nødvendige " +"kildefil-information." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular kunne ikke finde stedet i DVI-filen som svarer til linje %1 i TeX-" +"filen %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI-koden satte et tegn fr en ukendt skrifttype." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"DVI-koden refererede til skrifttype #%1, som ikke tidligere har været " +"defineret." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Stakken var ikke tom da en EOP-kommando blev mødt." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Stakken var tom da en POP-kommando blev mødt." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"DVI-koden refererede til en skrifttype der ikke tidligere er blevet " +"defineret." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "En ugyldig kommando blev mødt." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Okular stødte på den ukendte op-kode %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Indlejrer %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Side %1: PDF-filen %2 kunne ikke konverteres til PostScript." +"
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Side %1: PostScript-filen %2 kunne ikke findes.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Papirstørrelsesdata '%1' kunne ikke fortolkes." + +#: fontpool.cpp:203 +#, fuzzy, kde-format +#| msgid "" +#| "Okular was not able to locate all the font files which are necessary to " +#| "display the current DVI file. Your document might be unreadable.\n" +#| "PATH: %1\n" +#| "kpswhich: %2" +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"Okular kunne ikke lokalisere alle filerne der skal bruges for at kunne " +"fremvise den aktuelle DVI-fil. Dit dokument kan fremstå ulæseligt.\n" +"Sti: %1\n" +"kpswhich: %2" + +#: fontpool.cpp:270 +#, fuzzy, kde-format +#| msgid "" +#| "There were problems running 'kpsewhich'. As a result, some font files " +#| "could not be located, and your document might be unreadable.\n" +#| "Possible reason: The kpsewhich program is perhaps not installed on your " +#| "system, or it cannot be found in the current search path.\n" +#| "PATH: %1\n" +#| "kpswhich: %2" +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"Der opstod nogle problemer ved kørsel af \"kpsewhich\". Derfor kunne nogle " +"skrifttype-filer ikke findes og dit dokument er måske ulæseligt.\n" +"Mulig årsag: Programmet kpsewhich er måske ikke installeret på dit system, " +"eller det kan ikke findes i den aktuelle søgesti.\n" +"Sti: %1\n" +"kpswhich: %2" + +#: fontpool.cpp:291 +#, fuzzy, kde-format +#| msgid "" +#| "The font generation by 'kpsewhich' was aborted (exit code %1, error %2). " +#| "As a result, some font files could not be located, and your document " +#| "might be unreadable." +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Skrifttypegenereringen af \"kpsewhich\" blev afbrudt (afslutningskode %1, " +"fejl %2). Som resultat heraf kan nogle skrifttypefiler ikke findes, og dit " +"dokument kan måske være ulæseligt." + +#: fontpool.cpp:462 +#, fuzzy, kde-format +#| msgid "Currently generating %1 at %2 dpi" +msgid "Currently generating %1 at %2 dpi..." +msgstr "Genererer %1 ved %2 dpi" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Producent/Dato" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Skrifttypefil ikke fundet" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "stående" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "liggende" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Versionen af Ghostview som er installeret på denne computer indeholder ikke " +"nogen af Ghostviews enhedsdrivere som Okular kender. PostScript-" +"understøttelse er derfor blevet slået fra i Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Ghostview-programmet som Okular bruger internt til at vise PostScript-" +"grafikkerne som er inkluderet i DVI-filen, er i almindelighed i stand til at " +"skrive dets output i en mangfoldighed af formater. Under-programmerne som " +"Ghostview bruger til disse opdager kaldes 'enhedsdrivere', der er en " +"enhedsdriver for hvert format som Ghostview kan skrive. Forskellige " +"versioner har ofte forskellige enhedsdrivere til rådighed. Det lader til at " +"den version af Ghostview som er installeret på denne computer ikke " +"indeholder nogen af de enhedsdrivere som Okular kender til.

Det " +"virker usandsynligt at en normal installation af Ghostview ikke ville " +"indeholde disse drivere. Denne fejl kan derfor tyde på en alvorlig fejl i " +"konfigurationen af Ghostview-installationen på din computer.

Hvis du " +"ønsker at løse problemet med Ghostview kan du bruge kommandoen gs --" +"help for at vise en liste over enhedsdrivere indeholdt i Ghostview. " +"Blandt andre kan Okular bruge driverne 'png256', 'jpeg' og 'pnm'. Bemærk at " +"Okular skal genstartes for at aktivere PostScript-understøttelse igen.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Der er vist 25 fejl. Der vil ikke blive vist flere fejlbeskeder." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Fejl i DVI-fil '%1', side %2. Farve-POP kommando forsøgt udført selvom " +"farvestakken er tom." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Misdannet parameter i epsf specialkommando.\n" +"Forventede at et flydende kommatal ville følge %1 i %2." + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Fil ikke fundet:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Fejl i DVI-fil '%1', side '%2. Kunne ikke fortolke vinkel i tekstrotering." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Kommandoen '%1' er ikke implementeret." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Skrifttypefilen %1 kunne åbnes og læses, men skrifttypeformatet er ikke " +"understøttet." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Skrifttypefilen %1 er ødelagt, eller også kunne den hverken åbnes eller " +"læses." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType rapporterede en fejl da tegnstørrelsen til skrifttypefilen %1 " +"skulle sættes." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType kunne ikke indlæse tegn #%1 fra skrifttypefilen %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType kunne ikke optegne tegn #%1 fra skrifttypefilen %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Tegn #%1 er tomt." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Tegn #%1 fra skrifttypefil %2 er tomt." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType kunne ikke indlæse størrelser for tegn #%1 fra skrifttypefilen %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Kan ikke åbne skrifttypefil %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Tegn %1 er ikke defineret i skrifttype %2." + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Uventet %1 i PK-filen %2." + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Tegnet %1 er for stort i filen %2." + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Forkert antal gemte bit: tegn %1, skrifttype %2." + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Ødelgt pk-fil (%1), for mange bit." + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Skrifttypen har ikke-kvadratisk aspektratio." + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Kan ikke finde skrifttypen %1, fil %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Tjeksummen for skrifttypefilen %1 er forkert sammensat." + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Kan ikke genkende formatet af skrifttypefilen %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Fatal fejl.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Dette betyder sandsynligvis at du enten har fundet en fejl i Okular,\n" +"eller at DVI-filen, tilbehørsfiler (såsom skrifttypefiler, \n" +"eller virtuelle skrifttypefiler) var meget defekte.\n" +"Okular vil afslutte efter denne besked. Hvis du tror du har fundet \n" +"en eller Okular burde opføre sig bedre i denne situation\n" +"så rapportér venligst problemet." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Forkert kommandobyte fundet i VF-makroliste: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI-motor" + +#~ msgid "A DVI file renderer" +#~ msgstr "Rendering af DVI-filer" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular afhænger af kpsewhich-programmet for at kunne lokalisere " +#~ "skrifttyper på din disk og for at kunne generere PK-skrifttyper.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular genererer bitmap-skrifttyper..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Afbryder skrifttype-genereringen. Gør ikke dette." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular er ved at generere bitmap-skrifttyper som er nødvendige for at " +#~ "vise dit dokument. Til dette bruger Okular et antal eksterne programmer, " +#~ "såsom MetaFont. Du kan finde output fra disse programmer senere i " +#~ "dokumentets infodialog." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular er i gang med at generere skrifttyper. Vent venligst." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Fremgangsdialog til skrifttypegenerering" + +#~ msgid "Abort" +#~ msgstr "Afbryd" + +#~ msgid "What is happening here?" +#~ msgstr "Hvad sker der her?" + +#~ msgid "%v of %m" +#~ msgstr "%v af %m" + +#~ msgid "Please be patient" +#~ msgstr "Vent venligst." + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Eksportér fil som" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Filen %1\n" +#~ "eksisterer. Vil du overskrive den?" + +#~ msgid "Overwrite File" +#~ msgstr "Overskriv fil" + +#~ msgid "Overwrite" +#~ msgstr "Overskriv" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Bruger dvipdfm til at eksportere filen til PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular bruger i øjeblikket det eksterne program 'dvipdfm' til at " +#~ "konvertere din DVI-fil til PDF. Somme tider kan dette vare et stykke tid " +#~ "da dvipdfm skal generere sine egne bitmap-skrifttyper. Vent venligst." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Venter på at dvipdfm skal afslutte..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Bruger dvips til at eksportere filen til PostScript." + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular bruger i øjeblikket det eksterne program 'dvips' til at konvertere " +#~ "DVI-filen til PostScript. Somme tider kan dette vare et stykke tid, da " +#~ "dvips skal generere sine egne bitmap-skrifttyper. Vent venligst." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Venter på at dvips skal afslutte..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funktionalitet ikke til rådighed" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Filen er ødelagt Okular kunne ikke fortolke din DVI-" +#~ "fil. Dette skyldes som regel en ødelagt fil." + +#~ msgid "DVI File Error" +#~ msgstr "DVI-fejl" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Ikke alle skrifttypefiler blev fundet." + +#~ msgid "Locating fonts..." +#~ msgstr "Lokaliserer skrifttyper..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Der opstod problemer ved kørslen af kpsewhich. Nogle " +#~ "skrifttypefiler kunne derfor ikke lokaliseres og dit dokument kan fremstå " +#~ "ulæseligt.

Mulig årsag: kpsewhich-programmet et muligvis " +#~ "ikke installeret på dit system, eller måske findes det ikke iden aktuelle " +#~ "søgesti.

Dette kan du gøre: kpsewhich programmet er normalt " +#~ "en del af distributioner af TeX typografisystemet. Hvis ikke TeX er " +#~ "installeret på dit system, kan du installere TeX Live distributionen (www." +#~ "tug.org/texlive). Hvis du ved at TeX er installeret, så prøv at bruge " +#~ "kpsewhich-programmet fra kommandolinjen for at sikre dig at det virker." + +#~ msgid "Problem locating fonts" +#~ msgstr "Problem med at finde skrifttyper" + +#~ msgid "Font generation aborted" +#~ msgstr "Skrifttypegenerering afbrudt" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Eksportér: %1 til PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Ekportér: %1 til PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Skrifttypelisten er i øjeblikket tom." + +#~ msgid "TeX Name" +#~ msgstr "TeX-navn" + +#~ msgid "Family" +#~ msgstr "Familie" + +#~ msgid "Zoom" +#~ msgstr "Forstør" + +#~ msgid "Type" +#~ msgstr "Type" + +#~ msgid "Encoding" +#~ msgstr "Tegnsæt" + +#~ msgid "Comment" +#~ msgstr "Kommentar" + +#~ msgid "TeX virtual" +#~ msgstr "Virtuel TeX" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX skrifttypesystem" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "Kunne ikke allokere hukommelse til en skrifttypestruktur" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "Ikke nok hukommelse til at indlæse DVI-filen." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Kunne ikke indlæse DVI-filen." + +#~ msgid "Checksum mismatch" +#~ msgstr "Tjeksum stemmer ikke overens" + +#~ msgid " in font file " +#~ msgstr " i skrifttypefil" + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Kunne ikke allokere hukommelse til makrotabel." + +#~ msgid "Virtual character " +#~ msgstr "Virtuelt tegn" + +#~ msgid " in font " +#~ msgstr " i skrifttype" + +#~ msgid " ignored." +#~ msgstr " ignoreret." + +#~ msgid "Fatal Error" +#~ msgstr "Fatal fejl" diff --git a/po/da/okular_epub.po b/po/da/okular_epub.po new file mode 100644 index 0000000..7c64135 --- /dev/null +++ b/po/da/okular_epub.po @@ -0,0 +1,55 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2008, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-10 19:28+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Fejl under åbning af EPub-dokumentet." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Konfiguration af EPub-motor" + +#~ msgid "EPub Backend" +#~ msgstr "EPub-motor" + +#~ msgid "An EPub backend" +#~ msgstr "En EPub-motor" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/da/okular_fax.po b/po/da/okular_fax.po new file mode 100644 index 0000000..7b80ea4 --- /dev/null +++ b/po/da/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-16 18:29+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Kan ikke indlæse dokument" + +#~ msgid "Fax Backend" +#~ msgstr "Fax-motor" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "A G3/G4 motor til fax-dokument" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/da/okular_fictionbook.po b/po/da/okular_fictionbook.po new file mode 100644 index 0000000..42c6b97 --- /dev/null +++ b/po/da/okular_fictionbook.po @@ -0,0 +1,93 @@ +# translation of okular_fictionbook.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2008, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-10 19:26+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokumentet er ikke gyldig FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Kan ikke åbne dokumentet: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokumentet er ikke et gyldigt ZIP-arkiv" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Ugyldig dokumentstruktur (hovedmappen mangler)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Intet indhold fundet i dokumentet" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Ugyldigt XML-dokument: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Konfiguration af FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Fiction Book-motor" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Rendering af FictionBook e-bøger" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Title" +#~ msgstr "Titel" + +#~ msgid "Author" +#~ msgstr "Forfatter" + +#~ msgid "Producer" +#~ msgstr "Producent" + +#~ msgid "Created" +#~ msgstr "Oprettet" diff --git a/po/da/okular_ghostview.po b/po/da/okular_ghostview.po new file mode 100644 index 0000000..5eff15c --- /dev/null +++ b/po/da/okular_ghostview.po @@ -0,0 +1,92 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008, 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-05-08 12:46+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Brug platformskrifttyper" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Bestemmer om Ghostscript skal tillades at bruge platformskrifttyper. Hvis " +"falsk, vil kun brug af skrifttyper indlejret i dokumentet blive tilladt." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Generelle indstillinger" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Benyt platformskrifttyper" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Indstilling af Ghostscript dokumentmotor" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumentversion" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Sprogniveau" + +#~ msgid "PS Backend" +#~ msgstr "PS-motor" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Rendering af PostScript-filer." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Baseret på Spectre-biblioteket." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/da/okular_kimgio.po b/po/da/okular_kimgio.po new file mode 100644 index 0000000..3627065 --- /dev/null +++ b/po/da/okular_kimgio.po @@ -0,0 +1,70 @@ +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2009, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2018-01-10 19:21+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Kunne ikke indlæse dokument: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Dette dokument lader til at være i forkert format. Dette er den bedste " +"tilnærmelse til dokumentets tilsigtede udseende." + +#~ msgid "Image Backend" +#~ msgstr "Billedmotor" + +#~ msgid "A simple image backend" +#~ msgstr "En simpel billedmotor" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Hovedværktøjslinje" diff --git a/po/da/okular_markdown.po b/po/da/okular_markdown.po new file mode 100644 index 0000000..f3646d1 --- /dev/null +++ b/po/da/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Martin Schlander , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-07-22 12:29+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "" + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "" diff --git a/po/da/okular_mobi.po b/po/da/okular_mobi.po new file mode 100644 index 0000000..714f30c --- /dev/null +++ b/po/da/okular_mobi.po @@ -0,0 +1,61 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-10 19:27+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Fejl under åbning af Mobipocket-dokument." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "Denne bog er beskyttet af DRM og kan kun vises på udvalgte enheder" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Konfiguration af Mobipocket-motor" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket-motor" + +#~ msgid "A mobipocket backend" +#~ msgstr "En mobipocket-motor" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/da/okular_plucker.po b/po/da/okular_plucker.po new file mode 100644 index 0000000..bf84c94 --- /dev/null +++ b/po/da/okular_plucker.po @@ -0,0 +1,46 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-03-27 12:10+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: LoKalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Navn" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Plucker Document-motor" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Rendering af Plucker e-bøger" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/da/okular_poppler.po b/po/da/okular_poppler.po new file mode 100644 index 0000000..d1cc1ba --- /dev/null +++ b/po/da/okular_poppler.po @@ -0,0 +1,225 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008. +# Martin Schlander , 2008, 2009, 2010, 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-07-10 20:18+0200\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Forbedr tynde linjer:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Nej" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Massiv" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Form" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF-indstillinger" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Udskriv kommentarer" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Medtag kommentarer i det udskrevne dokument" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Medtager kommentarer i det udskrevne dokument. Du kan deaktivere dette hvis " +"du vil udskrive det oprindelige ukommenterede dokument." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Påtving raster" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Konvertér til rasterbillede før udskrivning" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Påtvinger konvertering af hver side til et rasterbillede før udskrivning. " +"Dette medfører som regel dårligere resultater, men er nyttigt når man " +"udskriver dokumenter der ser ud til at udskrives fejlagtigt i forhold til " +"originaldokumentet." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Krypteret" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Ukrypteret" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sikkerhed" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Ja" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimeret" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Konfiguration af PDF-motor" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "PDF-motor" + +#~ msgid "A PDF file renderer" +#~ msgstr "Rendering af PDF-filer" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Gemning af filer med /Encrypt er ikke understøttet." + +#~ msgid "Unknown" +#~ msgstr "Ukendt" + +#~ msgid "Unknown Date" +#~ msgstr "Ukendt dato" + +#~ msgid "Unknown Encryption" +#~ msgstr "Ukendt kryptering" + +#~ msgid "Unknown Optimization" +#~ msgstr "Ukendt optimering" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Angiv adgangskoden for at læse dokumentet:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Forkert adgangskode. Prøv igen:" + +#~ msgid "Document Password" +#~ msgstr "Dokumentadgangskode" diff --git a/po/da/okular_txt.po b/po/da/okular_txt.po new file mode 100644 index 0000000..602af09 --- /dev/null +++ b/po/da/okular_txt.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-09 16:17+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Martin Schlander" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mschlander@opensuse.org" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Konfiguration af txt-motor" + +#~ msgid "Txt Backend" +#~ msgstr "Txt-motor" + +#~ msgid "Txt backend." +#~ msgstr "Txt-motor." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/da/okular_xps.po b/po/da/okular_xps.po new file mode 100644 index 0000000..85ff2ac --- /dev/null +++ b/po/da/okular_xps.po @@ -0,0 +1,58 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Rune Rønde Møller , 2008. +# Martin Schlander , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-16 18:29+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Rune Rønde Møller" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "runermoeller@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revision" + +#~ msgid "XPS Backend" +#~ msgstr "XPS dokumentmotor" + +#~ msgid "An XPS backend" +#~ msgstr "Dokumentmotor til XML Paper Specification formatet" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/da/org.kde.active.documentviewer.po b/po/da/org.kde.active.documentviewer.po new file mode 100644 index 0000000..d316c4a --- /dev/null +++ b/po/da/org.kde.active.documentviewer.po @@ -0,0 +1,72 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Martin Schlander , 2012. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2012-11-19 20:51+0100\n" +"Last-Translator: Martin Schlander \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Bogmærker" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniaturer" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Indholdsfortegnelse" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Bogmærker" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Ingen resultater fundet." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Dokumentfremviser til Plasma Active som bruger Okular" + +#~ msgid "Reader" +#~ msgstr "Læser" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Ophavsret 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL til filen der skal åbnes" diff --git a/po/de/docs/okular/annotation-properties.png b/po/de/docs/okular/annotation-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..051d0703391b46a8c3b981440f731e996f3165ae GIT binary patch literal 20683 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 z zY7jU%i>K>FcB17>ZHC;H#zEH-E9^eG-|TA^T(sv>KYZ(=<;3sb&N-xI!J|=i4Y{vd zlJIEcF@pC^`JCV0k#bj*+@qh zasoDs(mpeDSv%$foG?b=iNBOGjmaGUWWQQ3*4yp6d zaC?pF2bVFE;vc3x)pM;=_bzb}7)MT`l?*8;nmRJismp7aQ|`U_7Y||2SJ#Tbf-pL?d>LZRQC&p z)LCJ)&^}~Q7Hg?&T;XICOfsEPJf+Q9ILpSq;iu)neK}q)S=Xx3fwmQuWao(7zOwqH zioIOMR6g097V-k5|w!J_nl5%T*3(V|Xk2NOXRO8M=OAqyvXf z5~je@6Q&=zb`7X)*7C!b$#o^F!PS4-?7ZO}f~4$l;3b0W4leFs0u3ZZ<6Yl@H~wOb4GOEP!zmenOAiHnS<`?c3j1Rj*nc@lAFcQ6(Ev)%R^3 z*l-97dcLCId%6oXupsYI(Bp?&_(jiJDtZ&ne9K~C| zg=9#n1jNqAZ+8_h0`c2X(4=rD2GVl_O`-cj*B=KgLZE1`O?~dq2K3~(BgJ-JSHw!I zYddRI(Bkd{ePjq8hV&HHKHNPIE`Irvd~keO3o`SfFe^&d9U){e>o4`zTD0a%c5hOD zbTr)ITVV{G>Zwe%0DW*j4=JgqEYT0>sGt4QTGoZ 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 z zJ+=>`4DLhMkdGlNABsfs&62uy2O;Vm=v1YM$=&y2*AG)q`Kzp9x?XM_x*4 zJ{$LK!)T1HYjzydv^0KubBN}W|rHJ30xe(cGUHBrAM&6lz#?lPzzS^2 ztwmnk{3OtT@d$4`6cI*xFiojIgE;RU{;?p=WwDcTQFbh9wc|=-g;St?B4}Ub7Uqvf zT~2O5DxpWy?KzvyS7C=+v+^8k2l`z5`)mT9DmGSt%k*%tfkzld5}Z;ApZutiHOLUb zc+XuL{ka6){c3#ZlLlN-Im38_P97G({!z|jntuwweSpa!3^>vJsbITvn)A>=^{~Z} zr$-9@6pn@qG0EOJG%7f(U=}+5^uHq_m|B_s@5v81)GFV?HvI5XOkjg)8ETel*hl;i D5sV4~ literal 0 HcmV?d00001 diff --git a/po/de/docs/okular/configure-editor.png b/po/de/docs/okular/configure-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..79d7ac2b53313c2ffc31a08e372b6b053e64f47b GIT binary patch literal 40359 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

=0h5(B{3nNoRVx_*o--|;Q^yS>V*}B@ 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 Fe*lOWACv$9 literal 0 HcmV?d00001 diff --git a/po/de/docs/okular/index.docbook b/po/de/docs/okular/index.docbook new file mode 100644 index 0000000..f04cdc8 --- /dev/null +++ b/po/de/docs/okular/index.docbook @@ -0,0 +1,4229 @@ + +KPDF"> + + +]> + + + + Das Handbuch zu &okular; + + Albert Astals Cid

&Albert.Astals.Cid.mail;
+ + + Pino Toscano
pino@kde.org
+
+
+ BurkhardLück
lueck@hube-lueck.de
Übersetzung
+ + &FDLNotice; + 2020-06-05 + 1.11 (Anwendungen 20.08) + + + &okular; ist ein &kde;-Betrachter für alle Dokumente auf der Grundlage des &kpdf;-Quelltextes. + + + KDE + okular + pdf + ps + PostScript + tiff + djvu + dvi + chm + xps + ComicBook + Fictionbook + Markdown + mobipocket + Plucker + Anmerkung + + + + Einleitung + &okular; ist ein &kde;-Betrachter für alle Dokumente auf der Grundlage des Quelltextes von &kpdf;. &okular; hat im Vergleich zu &kpdf; jedoch zusätzliche Eigenschaften wie einen Übersichtmodus, einen verbesserten Präsentationsmodus und Unterstützung für Anmerkungen. + &okular; unterstützt eine große Zahl von Formaten wie &PDF;, &PostScript;, Tiff, CHM, DjVU, Images (png, jpg, &etc;) XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub, Fax und Markdown. Informationen über alle unterstützten Formate und deren Funktionen finden Sie auf der Seite &okular;-Dokumentformate. + + &okular;s Hauptfenster + + + + + + &okular;s Hauptfenster + + + + + + Grundlagen + + Dateien öffnen + Um eine Datei in &okular; anzusehen, wählen Sie DateiÖffnen ..., dann im Dialogfenster eine Datei in einem der unterstützten Formate und drücken Öffnen. Ihre Datei wird nun im Hauptfenster angezeigt. + + Das neue Dokument wird in einem neuen Unterfenster geöffnet, wenn Neue Dateien in neuen Unterfenstern öffnen im Einrichtungsdialog auf der Seite Allgemein aktiviert ist. + Sie können ein Unterfenster durch Klicken mit der &MMBn; darauf schließen. + Das in einem Unterfenster vorher geschlossene Dokument kann mit dem Menüeintrag &Ctrl;&Shift;TDatei Unterfenster wieder herstellen erneut geöffnet werden. + + Wenn Sie bereits vorher Dateien in &okular; geöffnet hatten, können Sie am schnellsten über das Menü DateiZuletzt geöffnete Dateien wieder darauf zugreifen. + &okular; ist das &kde;-Standardprogramm für &PDF;- und &PostScript;-Dateien. Wenn Sie im Dateiverwaltungsprogramm mit der &LMBn; auf eine Datei diese Typs klicken, wird sie in &okular; geöffnet. Möchten Sie auch andere Dateien öffnen, die von &okular; angezeigt werden können, wählen Sie Öffnen mit &okular; aus dem Kontextmenü in der Dateiverwaltung. + Nachdem Sie eine Datei geöffnet haben, wollen Sie sie vermutlich lesen und daher im Text blättern. Im nächsten Abschnitt lernen Sie mehr darüber. + + + Navigation + Dieser Abschnitt erklärt, wie Sie sich in &okular; in einem Dokument bewegen können. + Es gibt mehrere Möglichkeiten, im Dokument zu blättern. Sie können den Ansichtsbereich mit den Tasten &Up; und &Down; verschieben. Dazu können Sie auch die Bildlaufleisten, das Mausrad oder die Tasten &PgUp; und &PgDn; benutzen. + Benutzen Sie Navigationstasten wie im Programm vim, und zwar H um zum Anfang der vorherigen Seite und L um zum Anfang der nächsten Seite zu gehen. Mit J gehen Sie eine Zeile nach unten und mit K eine Zeile nach oben. + Außerdem können Sie mit der &LMBn; auf eine beliebige Stelle im Dokument drücken und durch Ziehen der Maus die Ansicht verschieben. Dies funktioniert aber nur, wenn Sie im Menü ExtrasDurchsuchen ausgewählt haben. + + Wird ein Dokument im Präsentationsmodus angezeigt, wechseln Sie mit den Tasten &Up; und &Down; zwischen den Seiten oder Folien. Die Seitenzahl und Position der aktuellen Seite im Dokument werden in der rechten oberen Ecke des Bildschirms als Symbol eingeblendet. + + Möchten Sie ein Dokument mit mehreren Seiten lesen, dann können Sie das automatische Blättern in &okular; aktivieren. Starten Sie es mit &Shift;&Down; oder &Shift;&Up;. Benutzen Sie dann diese Tasten, um die Geschwindigkeit des Blättern zu ändern. Mit der &Shift;-Taste können Sie das automatische Blättern vorübergehend anhalten und wieder starten. Drücken Sie auf eine beliebige andere Tasten, um diese Funktion abzuschalten. + Weiterhin gibt es die Möglichkeit, in einem mehrseitigen Dokument mit dem Mauszeiger zu blättern. Halten Sie dazu die linke Maustaste gedrückt und ziehen Sie dann den Mauszeiger nach oben oder unten und setzen diese Bewegung auch über den oberen oder unteren Rand des Bildschirms fort. Überschreiten Sie den Rand der Seite, erscheint der Mauszeiger wieder unten oder oben auf dem Bildschirm und Sie können das Blättern in der gewünschten Richtung fortsetzen. + In der Seitenleiste auf der linken Seite des Fensters haben Sie zwei weitere Möglichkeiten, sich im einem Dokument zu bewegen. + + + Wenn Sie auf ein Vorschaubild klicken, wird die zugehörige Seite angezeigt. + + + Wenn das Dokument ein Inhaltsverzeichnis hat, können Sie mit Klicken auf einen Eintrag die zugehörige Seite anzeigen. + + + Enthält ein Dokument, können Sie die angezeigten Ebenen durch aus- oder Abwahl der Elemente in der Ebenenliste bestimmen. + + + Enthält ein Dokument Lesezeichen, wechseln Sie zur Ansicht Lesezeichen. Klicken Sie dann auf die einzelnen Lesezeichen, um zur zugehörigen Seite zu gehen. Werden Lesezeichen nicht nur für das aktuelle Dokument angezeigt, können Sie schnell zu allen Lesezeichen in den kürzlich geöffneten Dateien wechseln. + + + Enthält ein Dokument Anmerkungen, wechseln Sie zur Ansicht Anmerkungen. Klicken Sie auf die Anmerkungen oder wählen Sie sie mit den Tasten &Up; oder &Down;, drücken dann die &Enter;taste, dann wird die zugehörige Seite angezeigt. + + + Enthält das Dokument Verknüpfungen, können Sie mit einem Klick darauf die verknüpfte Seite anzeigen lassen. Zeigt die Verknüpfung auf eine Webseite oder andere Dokumente, wird der das &kde;-Standardprogramm für dieses Format mit der verknüpften Datei gestartet. Klicken Sie zum Beispiel auf eine Verknüpfung zu https://www.kde.org, wird diese Webseite im Standard-Webbrowser des &kde;-Arbeitsumgebung geöffnet. + + Interne Verknüpfungen im Dokument funktionieren nur im Durchsuchen-Modus. + + Zusätzlich können Sie mit diesen Methoden schnell an bestimmte Stellen des Dokuments springen: + + + Zum Anfang eines Dokuments mit &Ctrl;Pos1 oder mit Gehe zu Anfang des Dokuments . + + + Zum Ende eines Dokuments mit &Ctrl;Ende oder mit Gehe zu Ende des Dokuments . + + + Weiter vorwärts im Dokument mit der &Space; oder mit der Taste &PgDn;. Zur nächsten Seite eines Dokuments kommen Sie mit Nächste Seite in der Werkzeugleiste oder mit Gehe zu Nächste Seite im Menü. + + + Zurück im Dokument mit der &Backspace; oder mit der Taste &PgUp;. Zur vorigen Seite eines Dokuments kommen Sie mit Vorige Seite in der Werkzeugleiste oder mit Gehe zu Vorige Seite im Menü. + + + Sie können zu Positionen im Dokument in zeitlicher Reihenfolge wieder zurückgehen. Angenommen Sie lesen den Satz wie in [15] gezeigt und Sie möchten sofort die Referenz [15] nachlesen. Also klicken Sie darauf und &okular; geht zur Referenzliste. Mit dem Kurzbefehl &Alt;&Shift;&Left; oder Gehe zu Zurück aus der Menüleiste gelangen Sie direkt wieder zur Ausgangsposition zurück. + + + Nachdem Sie wie vorher beschrieben zurückgegangen sind, können Sie mit dem Kurzbefehl &Alt;&Shift;&Right; oder Gehe zu Nach vorne aus der Menüleiste nach vorne gehen. + + + Zur nächsten Übereinstimmung beim Suchen gelangen Sie mit den Tasten F3 oder &Enter; (wenn das Eingabefeld Suchen den Fokus hat) oder mit dem Menüeintrag Bearbeiten Weitersuchen , zur vorherigen Übereinstimmung mit dem Kurzbefehl &Shift;F3 oder Bearbeiten Frühere suchen . + + + + + Präsentationsmodus + Der Präsentationsmodus ist eine andere Art, Dokumente in &okular; anzuzeigen. Diesen Modus können Sie mit AnsichtPräsentation einschalten. In diesem Modus wird das Dokument seitenweise angezeigt. Die Vergrößerung wird so eingestellt, dass die ganze Seite sichtbar ist. + + Es gibt auch &PDF;-Dokumente, die nur im Präsentationsmodus angezeigt werden können. + + Im Präsentationsmodus wird eine Werkzeugleiste am oberen Bildschirmrand angezeigt, wenn Sie den Mauszeiger dorthin bewegen. + + &okular; im Präsentationsmodus + + + + + + &okular; im Präsentationsmodus + + + + Zwischen den Seiten können Sie mit der &LMBn; (nächste Seite), mit der &RMBn; (vorige Seite), mit dem Mausrad, durch Klicken auf die Pfeilsymbole oder direkte Eingabe der Seitenzahl in der Leiste am oberen Rand des Fenster oder mit den Tasten aus dem Abschnitt Navigation blättern. + Benutzen Sie Anhalten/Wiedergeben in der oberen Leiste, um die Wiedergabe der Präsentation anzuhalten und wieder zu starten. + Sie können die Präsentation jederzeit mit der &Esc;-Taste oder mit einem Klick auf das Symbol Präsentationsmodus beenden in der Navigationsleiste oben in Fenster wieder verlassen. + Außerdem können Sie auf der angezeigten Seite Linien zeichnen. Klicken Sie auf das Symbol Zeichenmodus umschalten in der Werkzeugleiste, um diesen Modus ein- oder auszuschalten. Die Linien werden automatisch gelöscht, wenn Sie den Präsentationsmodus verlassen. Mit der Auswahl des Symbols Zeichnungen löschen in der Werkzeugleiste können Sie Ihre Linien auch auf der aktuell angezeigten Seite löschen. + Im Präsentationsmodus können Sie auch mehrere Bildschirme benutzen, sofern vorhanden und eingerichtet, Dann erscheint ein zusätzlicher Knopf in der Leiste am oberen Bildschirmrand mit dem Symbol eines Bildschirms. Hier können Sie einen der vorhandenen Bildschirme zur Anzeige der Präsentation wählen. + Der Präsentationsmodus hat einige Einstellungsoptionen, die Sie unter &okular; einrichten ... finden. + + + + Rückwärtssuche zwischen &latex;-Editoren und &okular; + + Die Rückwärtssuche ist beim Schreiben eines &latex;-Dokuments sehr hilfreich. Wenn alles richtig eingestellt ist, kann sie in &okular; durch Klicken mit der &LMB; und der &Shift;-Taste ausgeführt werden. Dann lädt der Editor lädt die &latex;-Quelldatei und springt zur entsprechenden Stelle. + + Die folgenden Voraussetzungen sind für die Rückwärtssuche notwendig: + + + Die Quelldatei wurde erfolgreich kompiliert. + Der Editor, den Sie verwenden möchten, muss in &okular; eingestellt werden. + Die inverse Suche funktioniert nur im Durchsuchen-Modus, den Sie im Menü ExtrasDurchsuchen einschalten können. + + + Mit dieser Funktion in &okular; wird mit einem Klick der &LMBn; und dem Gedrückthalten der &Shift;-Taste im &DVI;- oder &PDF;-Dokument das entsprechende &latex;-Dokument im Editor geöffnet und zur entsprechenden Zeile gesprungen. Hierzu muss der Editor in &okular; als Texteditor festgelegt werden (EinstellungenOkular einrichten ...Editor). + + Weitere Details zur Einrichtung des Editors finden Sie in diesem Kapitel des Handbuchs. + + + Einrichtung von &okular; + + + + + + Einrichtung des Editors in &okular; + + Einrichtung des Editors in &okular; + + + + + + + Weitergehende Funktionen von &okular; + + Eingebettete Dateien + Enthält das aktuelle Dokument eingebettete Dateien, wird beim Öffnen eine Leiste über dem Ansichtsfenster mit einem Hinweis auf diese eingebetteten Dateien angezeigt. + + Die Statusleiste für eingebettete Dateien + + + + + + Die Statusleiste für eingebettete Dateien + + + + Dann können Sie entweder auf die Verknüpfung im Text klicken oder im Menü DateiEingebettete Dateien wählen, um den Dialog für eingebettete Dateien zu öffnen. In diesem Dialog werden diese Dateien angezeigt und Sie können sie speichern. + + + Formulare + Enthält das aktuelle Dokument Formulare, wird beim Öffnen eine Leiste über dem Ansichtsfenster angezeigt, in der Sie die Formularfelder zur Eingabe aktivieren können. + + Die Formularleiste + + + + + + Die Formularleiste + + + + Dann können Sie entweder auf Formulare anzeigen klicken oder im Menü AnsichtFormulare anzeigen wählen, um Text in die Formularfelder einzugeben. + + + Signaturen + Enthält das aktuelle Dokument Signaturen, wird beim Öffnen eine Leiste über dem Ansichtsfenster angezeigt, in der Sie der Seitenleiste Signaturen öffnen können. + + Die Signaturleiste + + + + + + Die Signaturleiste + + + + In der Seitenleiste Signaturen können Sie die Signaturen und Zertifikate des Dokuments untersuchen. + + Die Signaturleiste + + + + + + Die Signaturleiste + + + + + Diese Funktion ist nur für &PDF;-Dokumente verfügbar. Für die meisten Signaturinformationen muss Poppler mindesten in Version 0.51 installiert sein. Mit Version 0.68 werden auch Ort und Grund der Signatur angezeigt und mit Version 0.73 Informationen über das Zertifikat der Signatur. + + + + Anmerkungen + In &okular; können Sie Anmerkungen zu einem Dokument hinzufügen. + + &okular;s Anmerkungen + + + + + + &okular;s Anmerkungen + + + + In &okular; gibt es zwei Arten von Anmerkungen: + Text-Anmerkungen wie der Gelbe Textmarker und Schwarz unterstrichen für Dateien mit Text wie ⪚ &PDF;-Dateien. + Grafik-Anmerkungen wie Notiz, Haftnotiz, Freihandlinie, Hervorhebung, Gerade Linie, Vieleck, Stempel, Unterstrichen, Ellipse und Textkommentar für alle von &okular; unterstützen Dateiformate. + Benutzen Sie das Kontextmenü in der Ansicht Anmerkungen in der Seitenleiste oder im Hauptfenster, um für jede Art von Anmerkungen eine Haftnotiz zu öffnen und Kommentare einzugeben oder zu ändern. + Anmerkungen können nicht nur für Dateien im &PDF;-Format eingegeben werden, sondern für alle Formate, die &okular; unterstützt. + &okular; kann „Dokumentarchive“ erstellen. Diese Archive haben ein eigenes nur von &okular; verwendetes Format und enthalten das Dokument sowie zugehörige Metadaten, zurzeit nur Anmerkungen. Um ein geöffnetes Dokument als Archiv zu speichern, wählen Sie DateiSpeichern unter und stellen Dokumentarchiv im Filter ein. Das Dokumentarchiv erhält die Dateierweiterung .okular. Ein Dokumentarchiv kann mit &okular; wie ⪚ eine &PDF;-Datei geöffnet werden. + &okular; kann Anmerkungen auch direkt in den &PDF;-Dateien speichern. Mit dem Menüeintrag Datei Speichern werden die Anmerkungen in der aktuellen Datei gespeichert oder mit Datei Speichern unter ... in einer neuen Datei. + + Bei Dateien mit DRM-Einschränkungen (⪚ häufig bei &PDF;-Dokumenten) ist es manchmal nicht möglich, Eigenschaften hinzuzufügen oder zu bearbeiten oder Anmerkungen zu entfernen. + + + Alle Aktionen für Anmerkungen (Erstellen, Löschen, Ändern beliebiger Eigenschaften, Verschieben mit &Ctrl;+&LMB; und Bearbeitung des Inhalts) können zurückgenommen oder wiederhergestellt werden. Benutzen Sie dazu die entsprechenden Einträge im Menü Bearbeiten. Außerdem können Sie auch die Kurzbefehle &Ctrl;Z für das Zurücknehmen und &Ctrl;&Shift;Z für das Wiederherstellen drücken. + + Sie können die Voreinstellungen der Eigenschaften und des Erscheinungsbilds jeder einzelnen Anmerkung ändern. Weitere Details dazu finden Sie in diesem Kapitel des Handbuchs. + + Anmerkungen hinzufügen + Um Anmerkungen zum Dokument hinzuzufügen, benutzen Sie die Knöpfe in den Schnell-Anmerkungen in der Hauptwerkzeugleiste von &okular; oder aktivieren Sie die Werkzeugleiste dafür, indem Sie entweder ExtrasAnmerkungen wählen oder die Taste F6 drücken. Drücken Sie dann einen der Knöpfe oder die Kurzbefehle von 1 bis 9 auf der Leiste, um mit dieser Anmerkung zu beginnen. + Diese Werkzeugleiste hilft Ihnen beim Anlegen von Anmerkungen für Zeichnungen, Objekte und Textdokumente. Sie können Markierungen ⪚ Linien, Ellipsen, Vielecke, Stempel, Hervorhebungen. Unterstreichungen &etc; in ein Dokument einfügen. Die folgende Tabelle beschreibt genau, wie die Standardanmerkungen funktionieren. + + + + + Knopf + Werkzeugname + Beschreibung + + + + + + + + + + + + + + + Hervorhebung + + + Hervorhebung von Text im Dokument mit der eingestellten Hintergrundfarbe. + Klicken Sie auf den Werkzeugknopf und dann mit der gedrückten &LMBn; auf den Beginn des hervorzuhebenden Textes, ziehen Sie dann, um den Text zu markieren. + Sie können den Typ (Hervorhebung, Schnörkel, Unterstrichen oder Durchgestrichen), Farbe und Deckkraft für eine Hervorhebung festlegen. Klicken Sie dazu mit der &RMBn; auf die Hervorhebung und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Unterstrichen + + + Unterstreichen von Text. + Klicken Sie auf den Werkzeugknopf und dann mit der gedrückten &LMBn; auf den Beginn des zu unterstreichenden Textes, ziehen Sie dann, um Text zu unterstreichen. + Sie können den Typ (Hervorhebung, Schnörkel, Unterstrichen oder Durchgestrichen), Farbe und Deckkraft für die Unterstreichung festlegen Klicken Sie dazu mit der &RMBn; auf den unterstrichenen Text und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Schnörkel + + + Unterstreichen von Text mit einer geschnörkelten Linie. + Klicken Sie auf den Werkzeugknopf und dann mit der gedrückten &LMBn; auf den Beginn des zu unterstreichenden Textes, ziehen Sie dann, um Text zu unterstreichen. + Sie können den Typ (Hervorhebung, Schnörkel, Unterstrichen oder Durchgestrichen), Farbe und Deckkraft für die Unterstreichung festlegen Klicken Sie dazu mit der &RMBn; auf den unterstrichenen Text und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Durchgestrichen + + + Durchstreichen von Text. + Klicken Sie auf den Werkzeugknopf und dann mit der gedrückten &LMBn; auf den Beginn des zu unterstreichenden Textes, ziehen Sie dann, um Text zu unterstreichen. + Sie können den Typ (Hervorhebung, Schnörkel, Unterstrichen oder Durchgestrichen), Farbe und Deckkraft für die Unterstreichung festlegen Klicken Sie dazu mit der &RMBn; auf den unterstrichenen Text und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Textkommentar + + + Textkommentare sind deckende Zeichen auf transparentem Hintergrund, damit können Sie zum Beispiel nicht interaktive Formulare ausfüllen. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann mit der &LMBn; für die obere linke Ecke der Notiz, halten den Mausknopf gedrückt und ziehen den Mauszeiger zur rechten unteren Ecke der Notiz. Geben Sie den Text für die Notiz ein, klicken Sie dann auf OK zum Speichern, auf Abbrechen zum Beenden der Eingabe oder auf Löschen, um den Text der Notiz zu löschen. + Sie können Schrift und Textfarbe für einen Textkommentar festlegen. Klicken Sie dazu mit der &RMBn; auf den Text und wählen den Menüeintrag Eigenschaften + + + + + + + + + + + + + + Haftnotiz + + + Eine Haftnotiz zeichnen. Die Notiz wird im Text angezeigt. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann mit der &LMBn; für die obere linke Ecke der Notiz, halten den Mausknopf gedrückt und ziehen den Mauszeiger zur rechten unteren Ecke der Notiz. Geben Sie den Text für die Notiz ein, klicken Sie dann auf OK zum Speichern, auf Abbrechen zum Beenden der Eingabe oder auf Löschen, um den Text der Notiz zu löschen. + Sie können Farbe, Deckkraft, Schrift, Ausrichtung und Rahmenbreite für eine Haftnotiz festlegen. Klicken Sie dazu mit der &RMBn; auf das Notizsymbol und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Notiz + + + Eine Notiz zeichnen. Die Notiz wird angezeigt, wenn Sie auf das Symbol der Notiz im Dokument doppelklicken. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann auf die Stelle im Dokument, an der Sie die Notiz einfügen möchten. Geben Sie den Text ein und klicken Sie dann auf den Knopf Diese Notiz schließen in der oberen rechten Ecke des Notizfensters. + Sie können Farbe, Deckkraft und Symbol für eine Notiz festlegen. Klicken Sie dazu mit der &RMBn; auf das Notizsymbol und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Freihandlinie + + + Freihandlinien zeichnen. + Klicken Sie auf den Werkzeugknopf und klicken Sie dann mit der &LMB; für den Start der Linie, halten die Maustaste gedrückt und ziehen, um die Linie zu zeichnen. + Sie können Farbe, Deckkraft und Breite für eine Linie festlegen. Klicken Sie dazu mit der &RMBn; auf die Linie und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Pfeil (Im Auswahlfeld) + + + Markierung mit einem Pfeil. + Klicken Sie auf den Werkzeugknopf und dann mit der &LMBn; auf den Startpunkt der Linie, führen den Mauszeiger zum Endpunkt und klicken dann noch einmal. + Sie können Farbe, Deckkraft, Breite, Linienanfang, Linienende, Länge der Führungslinie und Länge der Führungslinien-Erweiterung für eine gerade Linie festlegen. Klicken Sie dazu mit der &RMBn; auf die Linie und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Gerade Linie (Im Auswahlfeld) + + + Markierung mit einer Linie. + Klicken Sie auf den Werkzeugknopf und dann mit der &LMBn; auf den Startpunkt der Linie, führen den Mauszeiger zum Endpunkt und klicken dann noch einmal. + Sie können Farbe, Deckkraft, Breite, Linienanfang, Linienende, Länge der Führungslinie und Länge der Führungslinien-Erweiterung für eine gerade Linie festlegen. Klicken Sie dazu mit der &RMBn; auf die Linie und wählen den Menüeintrag Eigenschaften. + + + + + + + + + + + + + + Rechteck (Im Auswahlfeld) + + + Zeichnet ein Rechteck um einen ausgewählten Bereich. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann mit der &LMBn; auf die linke obere Ecke des Rechtecks, halten die Maustaste gedrückt und ziehen Sie zur unteren rechten Ecke und lassen Sie die Maustaste los. + Sie können Typ (Rechteck oder Ellipse, Deckkraft Farbfüllung, Farbe der Füllung und Breite für eine Ellipse festlegen. Klicken Sie dazu mit der &RMBn; auf das Ellipse und wählen den Menüeintrag Eigenschaften + + + + + + + + + + + + + + Ellipse (Im Auswahlfeld) + + + Zeichnet eine Ellipse oder ein Rechteck um einen ausgewählten Bereich. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann mit der &LMBn; auf die linke obere Ecke des umschreibenden Rechtecks der Ellipse, halten die Maustaste gedrückt und ziehen Sie zur unteren rechten Ecke und lassen Sie die Maustaste los. + Sie können Typ (Rechteck oder Ellipse, Deckkraft Farbfüllung, Farbe der Füllung und Breite für eine Ellipse festlegen. Klicken Sie dazu mit der &RMBn; auf das Ellipse und wählen den Menüeintrag Eigenschaften + + + + + + + + + + + + + + Vieleck (Im Auswahlfeld) + + + Zeichnet ein geschlossenes Vieleck mit drei oder mehr Segmenten. Die zugehörige Notiz kann durch Doppelklicken in das Vieleck angezeigt werden. + Klicken Sie auf den Werkzeugknopf, klicken Sie dann mit der &LMBn; auf den ersten Punkt des Vielecks und ziehen Sie zum zweiten Punkt und klicken Sie wieder mit der Maustaste. Führen Sie dies bis zum ersten Punkt fort, bis das Vieleck fertig ist. Geben Sie den Text für die Notiz ein, klicken Sie dann auf OK zum Speichern, auf Abbrechen zum Beenden der Eingabe oder auf Löschen, um den Text der Notiz zu löschen. + Sie können Farbe, Deckkraft. Farbfüllung, Farbe der Füllung und Linienbreite für ein Vieleck festlegen. Klicken Sie dazu mit der &RMBn; auf das Vieleck und wählen den Menüeintrag Eigenschaften + + + + + + + + + + + + + + Stempel + + + Text oder Bilder mit voreingestellten Stempeln markieren. + Klicken Sie auf den Werkzeugknopf, um einen Stempel aus dem Auswahlfeld auszuwählen und dann mit der &LMBn; um den Stempel zu platzieren. + Um Stempel als Quadrate zum Beispiele für Symbole einzufügen, klicken Sie einmal mit der &LMBn;, um den Einfügepunkt links-oben anzugeben. Möchten Sie einen Stempel als Rechteck einfügen, klicken Sie mit der &LMBn; für den Eckpunkt links-oben und ziehen mit gedrückter Maustaste bis zum Eckpunkt rechts-unten. + Sie können Deckkraft und Stempel-Symbol für einen Stempel festlegen. Klicken Sie dazu mit der &RMBn; auf das Symbol und wählen den Menüeintrag Eigenschaften. + + Dies ist eine experimentelle Funktion. Benutzerdefinierte Stempel in einem PDF-Dokument werden in anderen PDF.Anzeigeprogrammen als Okular nicht angezeigt. + + + + + + + Dies sind die Standard-Anmerkungen, die in &okular; enthalten sind. Auf der Seite Anmerkungen des Einrichtungsdialogs können Sie Ihre eigenen Anmerkungen wie benutzerdefinierte Stempel, Textmarkierungen oder geometrische Formen mit innerer transparenter Farbe zum Markieren von Bereichen &etc; erstellen. + + Sie können &latex;-Quelltext in Anmerkungen verwenden. Fügen Sie $$code$$ zum Text der Anmerkung hinzu. Dabei muss code ein beliebiger gültiger &latex;-Ausdruck sein. Folgen Sie den Anweisungen auf dem Bildschirm, um den Ausdruck mit der auf Ihrem System installierten &latex;-Distribution zu rendern. + + Sie können die Einstellungen für die aktuelle Anmerkung in der Anmerkungs-Werkzeugleiste selbst ändern. Die folgende Tabelle beschreibt die Funktion der Einrichtungs-Knöpfe in der Voreinstellung der Anmerkungs-Werkzeugleiste. + + + + + Knopf + Einstellungsname + Beschreibung + + + + + + + + + + + + + + + Linienbreite + + + Klicken Sie auf den Werkzeugknopf, um die Breite im Auswahlfeld einzustellen. + + + + + + + + + / + + + + + + + Anmerkungs-Farbe + + + Klicken Sie auf den Werkzeugknopf, um die Text- oder Umrandungsfarbe für Ihre Anmerkung auszuwählen. Sie können eine der vordefinierten Farben benutzen oder mit Benutzerdefinierte Farbe den Farbauswahldialog öffnen. + + + + + + + + + + + + + + Anmerkungs-Füllfarbe + + + Klicken Sie auf den Werkzeugknopf, um eine Füllfarbe für Ihre Anmerkung auszuwählen. Sie können eine der vordefinierten Farben benutzen oder mit Benutzerdefinierte Farbe den Farbauswahldialog öffnen. + + + + + + + + + + + + + + Anmerkungs-Deckkraft + + + Klicken Sie auf den Werkzeugknopf, um die Deckkraft für die Anmerkung im Auswahlfeld einzustellen. Der Wert 100 % ist für deckende Anmerkungen. + + + + + + + + + + + + + + Anmerkungs-Schriftart + + + Klicken Sie auf den Werkzeugknopf, um den Dialog zur Schriftauswahl zu öffnen. + + + + + + + + + + + + + + Erweiterte Einstellungen für die aktuelle Anmerkung + + + Klicken Sie auf den Werkzeugknopf, um den allgemeinen Einrichtungsdialog für Ihre Anmerkung zu öffnen. + + + + + + Es gibt auch drei Knöpfe in der voreingestellten Anmerkungs-Werkzeugleiste. + + + + + Knopf + Beschreibung + + + + + + + + + + + + + + + Fügt die aktuelle Anmerkung zu den Schnell-Anmerkungen in der Hauptwerkzeugleiste hinzu. + + Sie können die Standard-Kurzbefehle &Alt;9 bis &Alt;0 jederzeit für die Auswahl von Anmerkungen verwenden, sogar wenn die Anmerkungs-Werkzeugleiste ausgeblendet ist. + + + + + + + + + + + + + + + Ist diese Einstellung ausgewählt, bleibt die Anmerkung ist auch nach Benutzung aktiviert. + + + + + + + + + + + + + + Anmerkungs-Werkzeugleiste ausblenden. + + + + + + Mit der &Shift;-Taste können Sie den Winkel von Linien und Vielecken auf Stufen von 15° und das Seitenverhältnis ⪚ für Rechteck und Ellipse auf 1:1 beschränken. Einen Knopf für die Werkzeugleiste können Sie im Dialog Werkzeugleisten einrichten hinzufügen. + Der Inhalt der Schnell-Anmerkung kann im &okular;-Einrichtungsdialog auf der Seite Anmerkungen angepasst werden. Diese Seite öffnen Sie durch Klicken auf den Knopf Schnell-Anmerkungen und Auswahl von Anmerkungen einrichten ... aus dem Aufklappmenü. + + Durch Aktivierung der Werkzeugleiste wechseln Sie in den normalen Durchsuchen-Modus. + + Klicken Sie wieder auf den zugehörigen Knopf in der Werkzeugleiste oder drücken Sie die &Esc;-Taste, um die Eingabe der Anmerkung zu beenden. + Als Autor einer neu erstellten Anmerkung wird die Einstellung auf der Seite Anmerkungen in &okular;s Einrichtungsdialog verwendet. Auf dieser Seite können auch die Einträge in der Anmerkungs-Werkzeugleiste eingerichtet werden. + + + Anmerkungen löschen + Um Anmerkungen zu löschen, klicken Sie mit der &RMBn; darauf und wählen Sie dann Löschen oder wählen Sie die Anmerkung mit der &LMBn; und drücken dann die Taste ∇. + Wenn Sie eine Anmerkung entfernen, wird das zugehörige Fenster geschlossen, falls es geöffnet ist. + + Wenn es ein Dokument es nicht erlaubt, Anmerkungen zu entfernen, kann diese Einstellung ist nicht ausgewählt werden. + + + + Anmerkungen bearbeiten + Um eine Anmerkung zu bearbeiten, klicken Sie mit der &RMBn; darauf und wählen Eigenschaften Damit öffnen Sie einen Dialog mit allgemeinen Einstellungen (wie Farbe, Deckkraft, Autor &etc;) und spezielle Einstellungen für diesen Typ von Anmerkung. + + Der Eigenschaftsdialog für Anmerkungen + + + + + + Der Eigenschaftsdialog für Anmerkungen + + + + Um eine Anmerkung zu verschieben, halten Sie die &Ctrl;taste gedrückt, gehen mit dem Mauszeiger auf die Anmerkung und ziehen sie dann mit der &LMBn;. + Wenn Sie mit der &LMBn; auf eine Anmerkung klicken, wird sie ausgewählt. Symbole zur Größenänderung erscheinen auf dem Auswahlrechteck. Wird der Mauszeiger auf eines dieser 8 Symbole in den Ecken oder auf den Kanten bewegt, ändert sich das Symbol des Mauszeigers und zeigt damit den Modus zur Größenänderung an. Klicken Sie auf eine beliebige sonstige Stelle in der Anmerkung, um sie zu verschieben. Drücken Sie die Taste &Esc; oder klicken Sie außerhalb der Anmerkung, um die Auswahl abzuschalten. + Eine Größenänderung ist nur für die Anmerkungen Haftnotiz, Textkommentar, Stempel und Ellipse möglich. + + + Bei Dokumenten mit eingeschränkten Berechtigungen (typisch für &PDF;-Dokumente) kann die Änderung einiger Einstellungen nicht erlaubt sein. + + + + + Lesezeichenverwaltung + &okular; hat ein sehr flexibles System für Lesezeichen. &okular; speichert die Position des Lesezeichens auf der Seite und ermöglicht daher mehr als ein Lesezeichen je Seite. + Zur Verwaltung von Lesezeichen in &okular; verwenden Sie die Ansicht Lesezeichen in der Seitenleiste, das Lesezeichenmenü oder das Kontextmenü der Dokumentenansicht, das mit der &RMB; geöffnet wird. + + Lesezeichenansicht + Um die Ansicht der Lesezeichen zu öffnen, klicken Sie auf den Eintrag Lesezeichen über der Seitenleiste. Wenn die Seitenleiste nicht angezeigt wird, klicken Sie auf Seitenleiste in der Werkzeugleiste oder wählen Sie im Menü F7 EinstellungenSeitenleiste anzeigen + + Kontextmenü der Lesezeichenansicht + + + + + + Kontextmenü der Lesezeichenansicht + + + + Mit der Filterleiste in der Ansicht Lesezeichen kann der Inhalt der Lesezeichenliste entsprechend dem Text im Eingabefeld gefiltert werden. + In dieser Ansicht kann die Liste der Lesezeichen als Baumstruktur dargestellt werden: Die Lesezeichen für jedes Dokument in der Liste können durch Klicken auf die Symbole < oder v neben dem Dateinamen aus- oder eingeklappt werden. + Klicken Sie auf das Symbol unter der Liste, um nur die Lesezeichen im gerade geöffneten Dokument anzuzeigen. + Mit den Aktionen im Kontextmenü des Dokumenteintrags kann das Dokument geöffnet, der Eintrag umbenannt oder aus der Liste entfernt werden. Beachten Sie, dass mit dem Dokument auch alle zugehörigen Lesezeichen entfernt werden. + Im Kontextmenü der einzelnen Lesezeichen können Sie zum Lesezeichen springen, es umbenennen oder entfernen. + Im Kontextmenü des Inhaltsverzeichnisses und der Vorschaubilder finden Sie Aktionen, um ein Lesezeichen zu erstellen, zu entfernen und zum nächsten oder vorherigen Lesezeichen zu gehen. + + + + + Befehlszeilenoptionen + Auch wenn &okular; meistens vom &kde;-Menü oder über ein Arbeitsflächensymbol geöffnet wird, kann es von einer Befehlszeile in einem Terminalfenster gestartet werden. Es gibt hierbei einige nützliche Optionen. + + Angabe eines Dateinamens + Der Benutzer kann Pfad und Dateinamen einer Datei angeben, die dann beim Starten von &okular; geöffnet wird. Hierzu ein Beispiel: + % okular + + + Bei &PDF;-Dokumenten kann der Name in der Form document_name#named_destination angegeben werden. Dabei ist named_destination ein bestimmter benannter Bereich im Dokument. + + + + Weitere Befehlszeilenoptionen + Die folgenden Hilfe-Möglichkeiten sind über die Befehlszeile verfügbar + + + okular + Öffnet die angegebene Seite im Dokument. Auch über die Option okular verfügbar. + + + okular + Startet die Anzeige des Dokuments im Präsentationsmodus. + + + okular + Startet mit dem Druckdialog. + + + okular + Startet mit dem Druckdialog und wird nach dem Drucken beendet. + + + okular + Nur eine Instanz des Programms verwenden. + + + okular + Mit dieser Option startet &okular; minimiert in der Kontrollleiste. + + + okular + Sucht nach dem angegebenen Text im Dokument und hebt ihn hervor. Es funktioniert nur, wenn genau ein Dokument als Argument für den Befehl okular angegeben wird. + + + + + + Fenster auf Seite einpassen + Die Funktion „Fenster auf Seite einpassen“ vergrößert die Anzeige auf genau die gleiche Größe wie die Seite mit dem aktuellen Vergrößerungsfaktor. Passt die Seite nicht vollständig in das Fenster, dann wird das Fenster vergrößert, so dass der größtmögliche Teil der Seite angezeigt wird. + Diese Funktion erreichen Sie über den Kurzbefehl &Ctrl;J. + + + + + Die Menüleiste + + + Das Menü Datei + + + + &Ctrl;O Datei Öffnen ... + + + Öffnet eine unterstützte Datei oder ein &okular;-Dokumentarchiv. Vorher wird eine bereits geöffnete Datei geschlossen. Weitere Einzelheiten erfahren Sie im Abschnitt Dateien öffnen. + + + + + + Datei Zuletzt geöffnete Dateien + + + Öffnet eine der zuletzt geöffneten Dateien. Vorher wird eine bereits geöffnete Datei geschlossen. Weitere Einzelheiten erfahren Sie im Abschnitt Dateien öffnen. + + + + + + Datei PostScript als &PDF; importieren ... + + + Öffnet eine &PostScript;-Datei und wandelt sie in das &PDF;-Format um. + + + + + + &Ctrl;&Shift;T Datei Unterfenster wiederherstellen + + + Öffnet das zuletzt geschlossene Dokument erneut. Diese Aktion ist nur dann verfügbar, wenn Sie Dokumente in Unterfenstern während der aktuellen Sitzung geschlossen haben. + + + + + + Datei Ordner mit diesem Inhalt öffnen + + + Öffnet den Ordner mit dem aktuellen Dokument im Standard-Dateiverwaltungsprogramm. Diese Aktion ist dann besonders nützlich, wenn Sie eine &PDF;-Datei aus dem Internet heruntergeladen haben, die automatisch in Okular geöffnet wird. Ohne diese Funktion ist der Speicherort der Datei nicht immer einfach zu finden. + + + + + + &Ctrl;S Datei Speichern + + + Speichert das Dokument einschließlich aller Änderungen (Anmerkungen, Inhalt von Formularfeldern &etc;), wenn das Anzeigemodul für das Dokument diese Speicherung der Änderungen unterstützt. Können diese Änderungen im aktuellen Anzeigemodul nicht gespeichert werden, können Sie die Änderungen verwerfen oder sie zusammen mit dem Dokument im Format &okular;-Dokumentarchiv speichern. + + + + + + &Ctrl;&Shift;S Datei Speichern unter + + + Speichert das Dokument einschließlich aller Änderungen (Anmerkungen, Inhalt von Formularfeldern &etc;) unter einem neuen Namen, wenn das Anzeigemodul für das Dokument die Speicherung von Änderungen unterstützt. Können diese Änderungen im aktuellen Anzeigemodul nicht gespeichert werden, können Sie die Änderungen verwerfen oder sie zusammen mit dem Dokument im Format &okular;-Dokumentarchiv speichern. + + Wegen der Art der Implementierung muss die neue Datei auch ohne Änderungen keine bitweise Kopie der originalen Datei sein, sie kann ⪚ einen anderen SHA-1-Hash-Wert &etc; haben. + + + + + + + F5DateiNeu laden + + + Lädt die gerade geöffnete Datei erneut. + + + + + + &Ctrl;P Datei Drucken ... + + + Druckt das aktuell angezeigte Dokument. &okular; hat einige spezielle Einstellungen für den Druck von &PDF;-Dokumenten. Diese Einstellungen finden Sie, indem Sie auf Einstellungen +> +> im Druckdialog klicken und dann die Karteikarte &PDF;-Optionen auswählen. Hier können Sie den Druck der Anmerkungen oder die Rasterung einstellen, wenn es Probleme mit dem Druck einiger Symbole gibt oder Sie den Skalierungsmodus ändern möchten. + + Die Einstellungen zum Skalierungsmodus sind nur verfügbar, wenn Rasterung erzwingen ausgewählt ist. + + + + + + + Datei Druckvorschau ... + + + Zeigt eine Vorschau, wie das aktuelle Dokument mit den Standardeinstellungen gedruckt wird. + + + + + + &Alt;Eingabe Datei Eigenschaften + + + Zeigt einige grundlegenden Informationen über das Dokument, wie Titel, Autor, Datum der Erstellung und die verwendeten Schriften. Die angezeigten Informationen sind vom Typ des Dokuments abhängig. + + Beachten Sie die Informationen über Ersatz-Schriften auf der Karteikarte Schriftarten des Dialogs Eigenschaften. Viele Probleme beim Rendern von Schriften können Sie vermeiden, wenn Sie die ersetzten Schriften installieren. + + + + + + Datei Eingebettete Dateien ... + + + Zeigt die eingebetteten Dateien im Dokument an. Weitere Informationen dazu finden Sie im Kapitel Eingebettete Dateien. + + + + + + Datei Exportieren als + + + Dieser Menüeintrag enthält alle Formate, in die das geöffnete Dokument exportiert werden kann. Für alle Dokumente gibt es immer als ersten Eintrag das Format Einfacher Text .... + Der zweite Eintrag ist Dokumentarchiv. Damit können Dokumente zusammen mit den Anmerkungen in einen nur mit &okular; lesbaren Archivformat gespeichert werden. Dieses Archiv ermöglicht es, ein Dokument zusammen mit den Anmerkungen als eine Datei an andere Personen zu senden. + + + + + + Datei Veröffentlichen + + + In diesem Eintrag finden Sie den Dienst zur Veröffentlichung des aktuellen Dokuments oder zum Versand auf Ihre anderen Geräte. Die Einträge in diesem Untermenü hängen vom aktuellen Dokumentformat von den auf dem System installierten KPurpose-Modulen ab. + + + + + + &Ctrl; Q Datei Beenden + + + Beendet &okular;. + + + + + + + Das Menü Bearbeiten + + + + + &Ctrl;Z Bearbeiten Rückgängig + + + Nimmt den letzte Aktion zur Änderung einer Anmerkung zurück. Das betrifft das Erstellen und Löschen, beliebige Änderungen von Eigenschaften, das Verschieben durch Ziehen mit gedrückte &Ctrl;-Taste und Änderung am Text der Anmerkung. + + + + + + &Ctrl;&Shift;Z BearbeitenWiederherstellen + + + Wiederholt den zuletzt rückgängig gemachten Schritt bei der Bearbeitung von Anmerkungen. + + + + + + + + &Ctrl;C Bearbeiten Kopieren + + + Kopiert den ausgewählten Text im Modus Textauswahl in die Zwischenablage. + + + + + + + + &Ctrl;A Bearbeiten Alles auswählen + + + Wählt den gesamten Text aus, wenn es das Dokument zulässt. Das funktioniert nur im Modus Textauswahl. + + + + + + + + Bearbeiten Gesamten Text der aktuellen Seite auswählen + + + Wählt den gesamten Text der aktuellen Seite aus, wenn es das Dokument zulässt. + + + + + + + + &Ctrl; F Bearbeiten Suchen ... + + + Zeigt die Suchleiste unten im Anzeigebereich an, um nach einer Zeichenkette in Dokument zu suchen. + + + + + + F3 Bearbeiten Weitersuchen + + + Wiederholt die Suche nach der letzten Zeichenkette im Dokument. + + + + + + &Shift;F3 Bearbeiten Frühere suchen + + + Sucht nach der vorherigen Fundstelle des Suchtextes im Dokument. + + + + + + + Das Menü Ansicht + + + + &Ctrl;&Shift;P Ansicht Präsentation + + + Schaltet den Präsentationsmodus ein. Weitere Informationen dazu finden Sie im Kapitel Präsentationsmodus. + + + + + &Ctrl;&Shift;F Ansicht Vollbildmodus + + + Schaltet den Vollbildmodus ein. Im Unterschied zum Präsentationsmodus wird nur die Anzeige von Fensterdekoration, Menüleiste und Werkzeugleiste ausgeschaltet. + + + + + &Ctrl;+ Ansicht Vergrößern + + + Erhöht den Vergrößerungsfaktor der Ansicht des Dokuments. + + + + + + &Ctrl;- Ansicht Verkleinern + + + Verringert den Vergrößerungsfaktor der Ansicht des Dokuments. + + + + + Ansicht Auf 100 % vergrößern + + + Vergrößert die Anzeige auf die tatsächliche Größe, die durch die Parameter des Dokuments festgelegt wird. + + + + + Ansicht Seitenbreite + + + Ändert den Vergrößerungsfaktor der Ansicht des Dokuments, sodass die Seitenbreite in den Ansichtsbereich passt. + + + + + Ansicht Ganze Seite + + + Ändert den Vergrößerungsfaktor der Ansicht des Dokuments, sodass die ganze Seite in der Ansicht angezeigt wird. + + + + + Ansicht Automatisch einpassen + + + Ändert die Vergrößerung des angezeigten Dokuments abhängig vom Größenverhältnis zwischen der Seite und dem Anzeigebereich automatisch nach folgenden Regel: Entweder wird die Seitenbreite oder die Seitenhöhe oder die ganze Seite in den Ansichtsbereich eingepasst. + + + + + Ansicht Anzeigemodus + + + In diesem Untermenü können Sie den Anzeigemodus der Seiten einstellen. Sie haben folgende Auswahl: Einzelne Seiten, Gegenüberliegende Seiten (wie bei Büchern), Gegenüberliegende Seiten (erste Seite zentrieren) und Übersicht mit der Anzahl der Spalten, die im Einrichtungsdialog von &okular; eingestellt sind. + Außerdem können Sie den Modus Fortlaufend aktivieren. In diesem Modus werden alle Seiten des Dokuments fortlaufend angezeigt und Sie können ohne Sprünge durch das Dokument blättern. Ansonsten wird immer nur eine Seite oder eine Reihe von Seiten auf einmal gezeigt. + + + + + Ansicht Ausrichtung + + + In diesem Untermenü können Sie die Ausrichtung der Seiten des Dokuments ändern. + + Die Ausrichtung wird auf alle Seiten des Dokuments angewendet. + + Wählen Sie Ursprüngliche Ausrichtung, um alle geänderten Ausrichtungen wieder rückgängig zu machen. + + + + + Ansicht Ansicht stutzen + + + Mit den Einträgen in diesem Untermenü können Sie für die Anzeige den unbedruckten Rand der Seiten mit Ränder stutzen entfernen oder mit Auf Auswahl stutzen die Anzeige auf ein ausgewähltes Rechteck einschränken. + Im Modus Auf Auswahl stutzen können Sie ein Rechteck auf der angezeigten Seite auswählen, dieser Ausschnitt wird auch von allen anderen Seiten im Dokument angezeigt. Wählen Sie ein sehr kleines Rechteck aus, wird der Ausschnitt trotzdem mindestens 20 % der gesamten Seitengröße betragen. + Die Einstellung Ränder stutzen bleibt auch beim nächsten Start von &okular; erhalten, nicht aber die Einstellung für Auf Auswahl stutzen. + Wenn Sie von Ränder stutzen zum Modus Auf Auswahl stutzen wechseln, wird vor der Auswahl des Rechtecks der Modus Ränder stutzen abgeschaltet. + Der Modus zum Stutzen kann durch erneute Auswahl des Menüeintrags abgeschaltet werden. + + + + + Ansicht Formulare anzeigen/ausblenden + + + Schaltet die Anzeige von Formularfeldern im Dokuments ein oder aus. + + Dieser Menüeintrag ist nur aktiviert, wenn das geöffnete Dokument Formularfelder enthält. + + + + + + + + + Das Menü Gehe zu + + + + Gehe zu Vorige Seite + + + Zeigt die vorige Seite des Dokuments an. + + + + + Gehe zu Nächste Seite + + + Zeigt die nächste Seite des Dokuments an. + + + + + &Ctrl; &Home; Gehe zu Anfang des Dokuments + + + Geht zum Anfang des Dokuments. + + + + + &Ctrl; &End; Gehe zu Ende des Dokuments + + + Geht zum Ende des Dokuments. + + + + + &Alt;&Shift;&Left; Gehe zu Zurück + + + Geht zurück zur vorher angezeigten Seite des Dokuments. + + + + + &Alt;&Shift;&Right; Gehe zu Nach vorne + + + Geht weiter zur nächsten Ansicht des Dokuments. Dies ist nur möglich, wenn Sie bereits zu einer Seite zurückgegangen sind. + + + + + &Ctrl; G Gehe zu Gehe zu Seite ... + + + Öffnet einen Dialog, um zu einer bestimmten Seite des Dokuments zu gehen. + + + + + + + Das Menü Lesezeichen + + + + &Ctrl; B Lesezeichen +>Lesezeichen hinzufügen/entfernen + + + Fügt für die aktuelle Position ein Lesezeichen ein oder entfernt es. + + + + + Lesezeichen Lesezeichen umbenennen + + + Benennt das Lesezeichen an der aktuellen Position um. + + + + + Lesezeichen Vorheriges Lesezeichen + + + Geht zum vorherigen Lesezeichen. Wenn es vor dem aktuellen Lesezeichen keine weiteren Lesezeichen gibt, ist diese Aktion wirkungslos. + + + + + Lesezeichen Nächstes Lesezeichen + + + Geht zum nächsten Lesezeichen. Wenn es nach dem aktuellen Lesezeichen keine weiteren Lesezeichen gibt, ist diese Aktion wirkungslos. + + + + + Lesezeichen Keine Lesezeichen + + + Diesen Eintrag können Sie nicht auswählen, er wird immer dann angezeigt, wenn keine Lesezeichen im Dokument vorhanden sind. Anderenfalls finden Sie hier eine Liste aller Lesezeichen, klicken Sie auf einer dieser Einträge, um direkt zur entsprechenden Position im Dokument zu gehen. + + + + + + + Das Menü Extras + + + + &Ctrl; 1 Extras Durchsuchen + + + Die Maus hat das normale Verhalten, mit der &LMBn; verschieben Sie den Ansichtsbereich für das Dokument und folgen Verknüpfungen, mit der &RMBn; fügen Sie Lesezeichen ein und stellen die Ansicht auf die volle Seitenbreite ein. + + + + + &Ctrl;2 Extras Lupe + + + Die Maus arbeitet wie ein Vergrößerungswerkzeug. Klicken mit der &LMBn; und Ziehen vergrößert die Ansicht des ausgewählten Bereichs, Klicken mit der &RMBn; bringt Sie zur vorigen Ansicht zurück. + + + + + &Ctrl; 3 Extras Auswahl + + + Mit der Maus können Sie einen rechteckigen Auswahlbereich zeichnen. In diesem Modus können Sie durch Klicken mit der &LMBn; und Ziehen einen Bereich auswählen und ihn als Text oder Bild in die Zwischenablage kopieren, einen Text vorsprechen lassen oder ein Bild in einer Datei speichern. + + + + + &Ctrl; 4 Extras Textauswahl + + + Die Maus arbeitet als Auswahlwerkzeug für Text. In diesem Modus können Sie durch Klicken mit der &LMBn; und Ziehen einen Text auswählen. Klicken Sie dann mit der &RMBn;, um den Text in die Zwischenablage zu kopieren oder vorsprechen zu lassen. + + + + + &Ctrl; 5 Extras Tabellenauswahl + + + Ziehen Sie mit der Maus ein Rechteck um den Text für die Tabelle, klicken Sie dann mit der &LMBn; zur Aufteilung des Blocks in Zeilen und Spalten. Klicken Sie mit der &LMBn; auf vorhandenen Linien, um sie zu löschen und die angrenzenden Zeilen oder Spalten zu verschmelzen. + + + + + &Ctrl;6 Extras Lupe + + + Aktiviert den Lupenmodus für den Mauszeiger. Halten Sie die &LMB; gedrückt, um die Lupe zu aktivieren und verschieben Sie den Mauszeiger durch das Dokument. Die Lupe vergrößert jedes Pixel im Dokument um das Zehnfache. + + + + + F6 Extras Anmerkungen + + + Blendet die Werkzeugleiste für Anmerkungen ein. Mit dieser Werkzeugleiste können Sie Anmerkungen für das Dokument hinzufügen. Weitere Informationen dazu finden Sie im Kapitel Anmerkungen. + + + + + Extras Gesamtes Dokument vorlesen + + + Extras Aktuelle Seite vorlesen + + + Extras Vorlesen anhalten + + + Extras Vorlesen anhalten / fortsetzen + + + Mit diesen Menüeinträgen können Sie sich das gesamte Dokument oder nur die angezeigte Seite vorlesen lassen und das Vorlesen anhalten. Dazu wird der Sprachausgabedienst des Systems verwendet. Dies ist eine &Qt;-Bibliothek, die eine standardisierte Schnittstelle für Sprachausgabe zu speech-dispatcher unter &Linux; und zu den nativen Sprachausgabesystemen auf anderen Plattformen zur Verfügung stellt. Die Stimme für die Sprachausgabe können Sie auf der Einrichtungsseite Zugangshilfen von &okular; auswählen. + Die Aktionen Vorlesen sind nur dann aktiviert, wenn ein Sprachausgabedienst im System installiert ist. + + + + + + + Die Menüs Einstellungen und Hilfe + Außer den bekannten &kde;-Menüeinträgen Einstellungen und Hilfe, die im Kapitel Hilfe der &kde;-Grundlagen beschrieben werden, gibt es folgende spezielle Menüeinträge für &okular;: + + + + F7 Einstellungen Seitenleiste anzeigen + + + Zeigt die Seitenleiste an oder blendet sie aus. + + + + + Einstellungen Seitendarstellungsleiste anzeigen + + + Blendet die Anzeige der Seitendarstellungsleiste am unteren Rand des Dokumentbereichs ein oder aus. Die Seitenzahlen werden auch in der Standard-Werkzeugleiste angezeigt. + + + + + Einstellungen Anzeigemodule einrichten ... + + + Öffnet den Dialog Anzeigemodule einrichten. + + + + + + + + Einrichtung der Anzeigemodule von &okular; + Mit EinstellungenAnzeigemodule einrichten ... öffnen Sie einen Dialog für die Einrichtung einige Module, zu Zeit nur für EPUB, &PostScript;, FictionBook, Text, OpenDocument Text and &PDF;. + + Der Einrichtungsdialog für die Anzeigemodule + + + + + + Der Einrichtungsdialog für die Anzeigemodule + + + + Auf den Seiten für EPUB, &PostScript;, FictionBook, Mobipocket, Markdown, Text und OpenDocument Text können Sie die Schrift für das Rendern der Dokumente für diese Formate einstellen. Mit dem Knopf Auswählen öffnen Sie den bekannten &kde;-Schriftendialog, Weitere Informationen dazu finden Sie in der Dokumentation zu den &kde;-Grundlagen. + Im folgenden werden die Einstellungsseiten für die Module Markdown, &PostScript; und &PDF; beschrieben. + + Einrichtung des Markdown-Anzeigemoduls + Das &okular;-Anzeigemodul Markdown auf der Grundlage der Bibliothek Discount können Sie einstellen, in dem Sie Markdown in der Liste auf der linken Seite des Einrichtungsdialogs auswählen. Es gibt folgende Option: + + + + + SmartyPants-Formatierung aktivieren + + + Ist dies aktiviert, kann &okular; SmartyPants-Formatierung bearbeiten. Diese Formatierung ist manchmal in technischen Texten problematisch, wenn nicht nicht beabsichtige Ersetzungen vorgenommen werden, ⪚ wird (C) durch das Copyright-Symbol ersetzt. Diese Einstellung ist als Standard aktiviert. + + + + + + + Einrichtung des &PostScript;-Anzeigemoduls + Das &okular;-Anzeigemodul &PostScript; auf der Grundlage von Ghostscript können Sie einstellen, in dem Sie dies in der Liste auf der linken Seite des Einrichtungsdialogs auswählen. Es gibt nur eine Option: + + + + + Plattformspezifische Schriftarten verwenden + + + Diese Einstellung legt fest, ob Ghostscript auch plattformspezifische Schriften verwenden soll. Ansonsten werden nur im Dokument eingebettete Schriften benutzt. Diese Einstellung ist als Standard aktiviert. + + + + + + + Einrichtung des &PDF;-Anzeigemoduls + Das &okular;-Anzeigemodul &PDF; auf der Grundlage der Bibliothek Poppler können Sie einstellen, in dem Sie dies in der Liste auf der linken Seite des Einrichtungsdialogs auswählen. Es gibt nur eine Option: + + + + + Anzeige dünner Linien verbessern + + + Das Zeichnen von Linien in &okular; ist in zwei Schritten implementiert: Generierung und Füllung des Freistellungspfads. Beträgt die Breite einer Linie im ursprünglichen Dokument weniger als ein Pixel, kann dieses Verfahren zu Problemen führen. Für solche Linien wird der Freistellungspfad mit der Farbe gefüllt, die von der Breite des Linienteils im Freistellungspfad abhängt. Wird der Teil der Linie im Freistellungspfad sehr klein, kann der Kontrast zwischen der Form und der Hintergrundfarbe zu klein werden, um die Linie zu erkennen. Ein Gitter aus solchen Linien sieht dann sehr unschön aus. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dünne Linie (Rot), deren Freistellungspfad (Gestrichelt) und Pixelgrenzen (Schwarz) + Anzeige dünner Linien bei geringem Kontrast + + + + + Für die Verbesserung der Anzeige dünner Linien in &okular; gibt es zwei Einstellungen: + Mit der ersten Einstellung Einfarbig passt &okular;den Freistellungspfad und die Position der Linie so an, dass beide auf der selben Pixelgrenze liegen. &ie; &okular; verbreitert dünne Linien auf ein Pixel des Ausgabegeräts. Dieser Modus entspricht etwa der Einstellung Anzeige dünner Linien verbessern im Adobe Reader. Mit dieser Einstellung werden dünne Linien immer verbreitert. + + + + + + + + Dünne Linie mit der Einstellung Einfarbig + + + Dünne Linie mit der Einstellung Einfarbig + + + + + Mit der zweiten Einstellung Form wird der Freistellungspfad und die Linie ebenfalls an Pixelgrenzen angepasst, aber die Intensität der Linienfarbe wird entsprechend der Breite korrigiert. + + + + + + + + Dünne Linie mit der Einstellung Form + + + Dünne Linie mit der Einstellung Form + + + + + In der Voreinstellung mit der Option Nein bleibt die Anzeige dünner Linien unverändert. + + + + + + + + Einrichtung von &okular; + + Einstellungen + Mit Einstellungen&okular; einrichten ... öffnen Sie einen Dialog mit sechs Abschnitten. Dieses Kapitel beschreibt ausführlich alle vorhandenen Optionen. + + + Allgemein + + + Zugangshilfen + + + Leistung + + + Präsentation + + + Anmerkungen + + + Editor + + + + Der Einrichtungsdialog + + + + + + Der Einrichtungsdialog + + + + Für einige der installierten Anzeigemodule ist der Menüeintrag EinstellungenAnzeigemodule einrichten ... vorhanden. Damit öffnen Sie einen Dialog zur Einstellung des aktiven Anzeigemoduls. + + + Allgemein + + + Weichen Bildlauf verwenden + + Damit werden animierte Übergänge beim Blättern mit dem Mausrad oder der Tastatur verwendet, + + + + Bildlaufleisten anzeigen + + Schaltet die Anzeige der Bildlaufleisten an oder aus. + + + + Vorschaubilder mit der Seite verknüpfen + + Verbindet die Seitenanzeige mit der Anzeige der Vorschaubilder. + + + + Tipps und Infomeldungen anzeigen + + Zeigt beim Start Informationen über die geladene Datei an. + + + + Dokumenttitel in der Titelleiste anzeigen, falls verfügbar + + Legt fest, ob der Titel des aktuellen Dokuments in der Titelleiste vom &okular;-Fenster angezeigt wird. Wurden keine Metadaten für den Titel im Dokument gefunden oder ist diese Einstellung abgeschaltet, wird der Dateiname des Dokuments angezeigt. + + + + Wenn kein Dokumenttitel angezeigt wird + + Hier können Sie zwei Einstellungen wählen: Nur Dateinamen anzeigen oder Vollständigen Dateipfad anzeigen + + + + Benutzerdefinierte Hintergrundfarbe verwenden + + Ermöglicht die Auswahl von Farben für den Hintergrund des Dokuments, d. h. die Farbe um die angezeigte Seite. Als Voreinstellung wird die Farbe aus der &Qt;-Bibliothek benutzt, wenn diese Einstellung nicht aktiviert ist. + + + + Neue Dateien in Unterfenstern öffnen + + Ob neue Dokumente in Unterfenstern geöffnet werden. Dies ist in der Voreinstellung ausgeschaltet. + Die Standard-Kurzbefehle für das Wechseln zwischen Unterfenstern sind &Ctrl;. (Nächstes Unterfenster) und &Ctrl;, (Vorheriges Unterfenster). + + + + Zum vorhandenen Unterfenster wechseln, wenn die Datei bereits geöffnet ist. + + Legt fest, ob &okular; zu einem Unterfenster mit dem bereits geöffneten Dokument wechselt, anstatt das Dokument in einem neuen Unterfenster zu öffnen. Diese Einstellung ist als Standard nicht aktiviert und kann nur umgeschaltet werden, wenn Neue Dateien in Unterfenstern öffnen aktiviert ist. + + + + DRM-Beschränkungen beachten + + Wählen Sie, ob &okular; DRM (Digital Rights Management) beachten soll. DRM-Beschränkungen werden eingesetzt, um bestimmte Aktionen für &PDF;-Dokumente wie das Kopieren des Inhalts in die Zwischenablage unmöglich zu machen. In einigen Versionen von &okular; ist diese Option nicht vorhanden. + + + + Geänderte Dokumentdateien neu laden + + Überprüft automatisch, ob angezeigte Dateien auf dem Speichermedium geändert wurden. + + + + Auswahldialog für Anzeigemodule anzeigen + + Wenn es für die zu öffnende Datei mehrere Anzeigemodule gibt, erhalten Sie mit dieser Einstellung einen Auswahldialog für das Anzeigemodul. Ist diese Einstellung nicht aktiviert, benutzt &okular; das Anzeigemodul mit der höchsten Priorität. + + + + Leserichtung von rechts nach links + + Ob die Leserichtung von rechts nach links als Vorgabe beim Öffnen von Dateien verwendet wird. Diese Einstellung ist für einige Schriftsysteme hilfreich. + + + + Übersichtsspalten: + + Mit dieser Einstellung legen Sie die Anzahl der Spalten im Übersichtmodus fest. + + + + Überschneidung für die Tasten „Bild hoch/runter“ + + Mit diesem Wert kann eingestellt werden, wie viel Prozent des zurzeit dargestellten Anzeigebereichs noch sichtbar sind, nachdem eine der Tasten &PgUp;/&PgDn; gedrückt wurde. + + + + Standardvergrößerung + + Mit dieser Einstellung legen Sie die Vergrößerung für Dateien fest, die zum ersten Mal geöffnet werden. Alle bereits vorher geöffneten Dateien werden in der letzten benutzen Vergrößerungsstufe angezeigt. + + + + + + Zugangshilfen + + + Verknüpfungen umrahmen + + Zeichnet einen Rahmen um Verknüpfungen. + + + + Farben ändern + + Aktiviert die Optionen zur Änderung der Farben. + + + + Farben umkehren + + Vertauscht die Farben der Anzeige, &ie; schwarz wird als weiß dargestellt. + + + + Papierfarbe ändern + + Ändert die Papierfarbe, &ie; den Hintergrund des Dokuments. + + + + Helle und dunkle Farben ändern + + Ändert die helle und dunkle Farbe, das heißt schwarz wird nicht schwarz, sondern als dunkle Farbe und weiß als helle Farbe angezeigt. + + + + In Schwarzweiß umwandeln + + Wandelt die Farben im Dokument in Schwarzweiß um. Sie können Schwellwert und Kontrast einstellen. Mit einem höheren Schwellwert (rechts auf dem Schieberegler)wird ein helleres Grau verwendet. + + + + Helligkeit invertieren + + Invertiert die Helligkeit aller Farben. Helle und dunkle Farben werden vertauscht, aber Farbton und Sättigung bleiben unverändert. Der Kontrast in Bildern ist mit dieser Einstellung normalerweise schlechter als mit Luma invertieren (sRGB-Linear). + + + + Luma invertieren (sRGB-Linear) + + Invertiert die Luma (Luminanz) aller Farben. Helle und dunkle Farben werden vertauscht, aber Farbton und Sättigung bleiben unverändert. Der Kontrast in Bildern bleibt mit dieser Einstellung normalerweise besser erhalten als mit Helligkeit invertieren, aber bei farbenfrohen Grafiken oder Texten ist der Kontrast normalerweise schlechter. sRGB-Luma-Koeffizienten werden hier benutzt, aber keine Gamma-Korrektur. + + + + Luma invertieren (Symmetrisch) + + Invertiert die Luma (Luminanz) aller Farben und benutzt symmetrische Luma-Koeffizienten. Helle und dunkle Farben werden vertauscht, aber Farbton und Sättigung bleiben unverändert. Der Effekt ist ähnlich wie mit Helligkeit invertieren, aber der Kontrast bleibt in manchen Fällen besser erhalten. + + + + Farbton verstärken + + Verstärkt den Farbton aller Farben um 120 Grad. Das kann Kontrast-Probleme in farbenfrohen Bildern mildern. + + + + Farbton abschwächen + + Schwächt den Farbton aller Farben um 240 Grad. Das kann Kontrast-Probleme in farbenfrohen Bildern mildern. + + + + Modul + + Wählen Sie hier das Sprachausgabemodul (TTS), das von &okular; verwendet wird. Als Voreinstellung wird speechd TTS benutzt. Sie können jedoch alle Sprachen und Stimmen verwenden, die im Sprachausgabesystem des Rechners installiert sind. Unter &Linux; wird als Standard speech-dispatcher benutzt, um die verfügbaren Stimmen festzulegen. + + + + + + Leistung + + + Transparenzeffekte aktivieren + + Zeichnet die Auswahl und andere besondere Grafiken mit transparenten Effekten. Schalten Sie diese Option aus, um nur Umrisse zu verwenden, dadurch wird die Arbeitsgeschwindigkeit bei der Auswahl erhöht. + + + + Speicherausnutzung + + &okular; erreicht die beste Leistung durch Anpassung der Speichernutzung an Ihr System und Ihre Anforderungen. Je mehr Speicher Sie dem Programm zuweisen, desto schneller arbeitet es. Die Standardeinstellung ist für ein normales System richtig, aber mit der Einstellung ‚Gering‘ können Sie die Speichernutzung von &okular; einschränken oder mit der Einstellung ‚Aggressiv‘ die Leistung Ihres Systems voll ausnutzen. Mit der Einstellung „Gierig“ werden alle Seiten vorgeladen, aber der Hauptspeicher nicht vollständig belegt. Es werden maximal 50 % des gesamten oder freien Speichers benutzt. + + + + Rendern + + Mit diesen Einstellungen können Sie das Rendern und die Darstellung von Text und Grafik in &okular; verbessern. Das Ergebnis wird durch das für die Anzeige verwendete Gerät beeinflusst. Mit den Ankreuzfeldern Kantenglättung für Text aktivieren und Kantenglättung für Grafik aktivieren wird Kantenglättung oder Antialiasing von Text und Bildern in Dokumenten ein- und ausgeschaltet. Mit dem Eintrag Hinting für Text aktivieren wird das Hinting aktiviert. Kantenglättung und Hinting ändern die Anzeige von Dokumenten auf dem Bildschirm, optimieren Sie diese Einstellungen für Ihre Ansprüche. + + + + + + Präsentation + + + Weitergehen alle + + Zeigt automatisch nach der festgelegten Zeit die nächste Seite. + + + + Nach der letzten Seite von vorn beginnen + + Im Präsentationsmodus wird nach der letzten Seite die erste Seite angezeigt. + + + + Touch-Navigation + + Ermöglicht die Feinabstimmung der Touchscreen-Navigation durch Tippen auf eine Präsentation mit den folgenden drei möglichen Werten: + + + Links/Rechts tippen um zurück/vorwärts zu gehen: Durch Tippen auf die linke bzw. rechte Hälfte des Bildschirms wechselt die Präsentation zur vorherigen bzw. nächsten Seite. + + + Irgendwo tippen um vorwärts zu gehen (Standard). Mit Tippen auf den Bildschirm wechselt die Präsentation zur nächsten Seite, egal wo Sie auf den Bildschirm tippen. + + + Deaktiviert: Die Touch-Navigation ist abgeschaltet. + + + + + + Hintergrundfarbe + + Die Farbe für den Bereich des Bildschirms, der im Präsentationsmodus nicht von der Seite abgedeckt wird. + + + + Mauszeiger + + Hier können Sie einstellen, ob der Mauszeiger immer angezeigt oder ausgeblendet wird oder ob er nach kurzer Zeit ohne Mausbewegung ausgeschaltet wird. + + + + Fortschrittsanzeige einblenden + + Zeigt ein Fortschritts-Symbol als Kreis mit der aktuellen Seite und der Anzahl aller Seiten in der rechten oberen Ecke des Präsentationsfensters an. + + + + Zusammenfassung anzeigen + + Zeigt am Beginn einer Präsentation eine Seite mit Namen, Autor und Seitenzahl des Dokuments. + + + + Übergänge aktivieren + + Mit diesem Ankreuzfeld können Übergangseffekte zwischen Seiten ein- oder ausgeschaltet werden. + + + + Standardübergang + + Der Effekt für den Übergang zwischen den einzelnen Seiten, sofern er nicht durch das Dokument festgelegt. Stellen Sie Zufälliger Übergang ein, damit &okular; wahllos einen der vorhandenen Effekte benutzt. + + + + Platzierung + + In diesem Abschnitt können Sie den Bildschirm für die Anzeige der Präsentation auswählen. + Aktueller Bildschirm ist der Bildschirm des &okular;-Fensters, in dem die Präsentation gestartet wird. + Standard-Bildschirm ist der in der Xinerama-Einstellung als Standard vorgegebene Bildschirm. + Bildschirm 0, Bildschirm 1 &etc; bezeichnen die verfügbaren Bildschirme. + + + + Einrichtung des Zeichenwerkzeugs + + Einstellung der Farbe für den Zeichenstift im Präsentationsmodus. + + + + + + Anmerkungen + + Die Seite Anmerkungen im Einrichtungsdialog + + + + + + Die Seite Anmerkungen im Einrichtungsdialog + + + + + + Autor + + Der Autor der Anmerkungen zum Dokument. Als Voreinstellung wird der Name aus der Seite Passwort & Benutzerzugang des &systemsettings;-Kategorie Benutzerkontodetails verwendet. + + + + Anmerkungs-Werkzeuge + + In diesem Bereich kann die Werkzeugleiste für Anmerkungen eingerichtet werden. + Es gibt fünf Knöpfe (Hinzufügen, Bearbeiten, Entfernen, Nach oben, Nach unten) und ein Listenfeld mit dem Inhalt der aktuellen Werkzeugleiste mit Anmerkungen. Damit können Sie die Werkzeugleiste anpassen. + Brauchen Sie zusätzliche Knöpfe für Anmerkungen in der Werkzeugleiste, klicken Sie auf den Knopf Hinzufügen. Dann können Sie Name, Typ und Erscheinungsbild für den neuen Anmerkungstyp einstellen. + + Bitte denken Sie daran, dass die Werkzeuge für Anmerkungen vielfältig eingestellt werden können. Sie können zum Beispiel zwei Knöpfe für das selbe Werkzeug in verschieden Farben benutzen. Probieren Sie aus, welche Werkzeuge in den verschiedenen möglichen Einstellungen am besten für Ihre Arbeitsweise geeignet sind. + + Klicken Sie auf ein Element im Listenfeld und dann auf die entsprechenden Knöpfe auf der rechten Seite, um das Element zu bearbeiten, zu löschen, oder nach unten bzw. nach oben zu verschieben. Die Kurzbefehle der Elemente (Tasten von 1 bis 9) entsprechen der Position in der Liste. + + + + Benutzerdefinierte Stempel benutzen + + + Erstellen Sie ein Symbol, das Sie für Ihren eigenen Stempel benutzen möchten und speichern Sie ihn in einem beliebigen Grafikformat, das von &okular; unterstützt wird. + Klicken Sie auf den Knopf Hinzufügen, wählen Sie den Typ Stempel und geben Sie einen Namen ein. + Geben Sie den vollständigen Pfad zu Ihrem eigenen Symbol im Auswahlfeld im Abschnitt Stempel-Symbol ein. + + + + + + + Editor + + + Editor + + Wählen Sie hier den Editor aus, der zur Bearbeitung der Quelldatei des Dokuments gestartet wird. In einigen Dokumenten sind Verweise - normalerweise Zeilen- und Spaltennummer - auf die Quelldatei enthalten, aus der das Dokument generiert wurde. Im &DVI;-Format werden zum Beispiel Informationen über die &latex;-Quelltexte gespeichert. Ein ähnliches System namens pdfsync gibt es für &PDF;-Dokumente. Hier werden die zusätzlichen Informationen in einer eigenen Datei gespeichert, die nach der &PDF;-Datei benannt ist, zum Beispiel meindokument.pdfsync mit den Metadaten für das Dokument meindokument.pdf. + &okular; enthält Voreinstellungen für folgende Editoren: &kate;, Kile, SciTE, &Emacs;, LyX, TeXstudio und TeXiFy IDEA. + + Um die Rückwärtssuche in &kile; verwenden zu können, muss die &latex;-Datei mit der Einstellung Modern kompiliert werden. + + + + + Befehl + + Hier wird der Befehl und dessen Parameter zum Aufruf des gewählten Editors mit dem Quelltext des aktuellen Dokuments eingegeben. + Dieses Feld wird automatisch ausgefüllt, wenn Sie einen der voreingestellten Editoren benutzen. Ansonsten wählen Sie Benutzerdefinierter Texteditor im Auswahlfeld Editor und lesen die Dokumentation des Editors, um den richtigen Befehl einzutragen. + Die folgenden Platzhalter können benutzt werden: + + + %f - der Dateiname + + + %l - die anzuspringende Zeile in der Datei + + + %c - die anzuspringende Spalte in der Datei + + + Wenn %f nicht angegeben wird, wird der Dateiname automatisch an den Aufruf angehängt. + + + + + + + Danksagungen und Lizenz + + + Copyright des Programms: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Aktueller Betreuer + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it &kpdf;-Entwickler + + + + Copyright der Dokumentation: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Author + Titus Laska titus.laska@gmx.de Bearbeitung und Erweiterung + Pino Toscano pino@kde.org + + Übersetzung Burkhard Lücklueck@hube-lueck.de &underFDL; &underGPL; + + &documentation.index; + + + + diff --git a/po/de/docs/okular/mainwindow.png b/po/de/docs/okular/mainwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..4a7c8bfdac5c9a9d53cc67490fc103691892dd92 GIT binary patch literal 77668 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

hd5@80) z@g2kLxqXDlAW~jlsMgNfBsEAsKR-t2(L{&+>3uK5fj}s~g&URcZKDHBtq%&67y!q_ z#KzLijYh?!gk)xBZfj)A%lC7X-1T=Zp`7IBXLl$^?m+u@eKh{%D(*l}uhl3KHS?Kt zwREE!*65^LwOCOSB~VdOk<;^l6|OT#N4kY>wM z%4={1M&R}k+;|H|@CVNQxayYM7H@?^Hd|_}3NnwjRyoi9C6xW8a7L2fQ0a7evnLo` z+2a8_1cT}Vq7)1Tr$lUQ@tb{-ih#>N#7daUfQEuri#ekR|2$jhWULUrxa9pX8Rr1|CO;p7SS<8*k00Xoz82HENgls{y zX|4A3;mk#^&HZXB-sAPbBKU2Hlo+?Gfceo3x(J(R(!?k!23@sU&@-m-+XoN{2iTnIP-{9Jkrc_3rgPT{mrOw- zhWY%|Q;y1?xVT(!)M~DZsAp&pGiN*8>&`_DM9JyJ?&ljD9^L}7H6VMzlt!ujr*;o+ z?Z|k|ed=;gs8}9=W>J)!>#!W`lE|_gEeBkZIh6Hu^3&Xz{r=HWOxyc~&Ti;@DS!G~ zx(Ygaot7`#)ZbiMEVz7xh46nmf;P=(Xk@%`y4!b;gjJ+b_gmVvRcGu*V03cB-x%iZ zF*-TcSFyM!2to|9OhHgh0wG+pR{wOh{evd4Z{_&-V^pkGKaM+J8Z_&zr+nXi|Lj)f zY0oztzSW=(2sWJbh%7yC?wkL5B3HcxH3}jsqtI|zEeBq-+m&+e_(Cw~kJ6qY-&?#| z`kI-HVNxOZe2GvIS5d)y(;O%%5kS6NAImV1ng5XACikvm`d0^tVOZ~~vQ=1VV)?8ZdYp5Kr z>6GUgu_0Gba&mGSuWJloc+v6jMpjzgk8%Cr=M~Ur%k#e-&Z5#jd$YvVk7moX`WBzm z*gIU6E{C;ZMV`+d{Hmp$PZ1m3J>ELO0y6F2gw^_`hAVuwt+w6RCByBgaPw0qkJV~A$#St_0Ob~w_pv_Q887=P>?@RTXtsFp3W66kWUfLVOZU{_8D|zq3a?fufrbNlt6j}(53+YuUw)sQu1`~Ut?;WW ztbPkb#pgL)(&d)@dOleF)DpXITcd>3_Na&IM&>38C2Tfy_q_RC&wFamX7wvtBNXj2 zg1K{B`#Dix3)QEL-^?e?jK$`QHr5UA=ASnXu9F0d~X}0wTt#{A2nl~)& z@ASbrAIw6fHfCiJ3Z3kRN$|^)mv8y9cfxbn0GtI4cU36Z?S>K=oh$Cfw;VMt?<4H< zg^`p%Duh{UE}q(TzI*5}F|C8V1v zN>=j=^C#N0-I*t+$hxPdCYMh8to)GJ#W%&mkGo)UYr2E8OJi@YR8V)$MtM#dUk~qLUrTLnD+6+EK2v_9o|;rnM*$;?tSrjQ z%ZqY}M!XK6J7~A#hu1&~SEl}yot@q9*uvwu|2Hf-bKZX&{(dHL;|#9QqOqv`I};Nw zuhYly&dku@V9GeeX)na5XN;m5sp%hNUS3jAQ1M02adF|HhO7IFY25aI+1h0uZ}3o0 z*KOdK0RIif?p&3U;PCKXQ`VUD^l-&uQVI(3Ey_kD0Re#!EQZl|8dXZo`ckqdKxhL^ zQR^x?^)Vc1ny%@W9lxM^dV1a%?CBqDR8&-NWY+gytyfGL!GD`57*hF0sKjfPD{SiX zdB(a>qU4CMwWS!HzmU9{FA7D(I0&TYi>hT82LXe`>3D$giCQ@-Y_-~`X798+D3U)# zWciQdf9yweKEA$Ot{0?3i4|EYWhwNI1Unw;Buq@vR0MM0PghzE^9q&nr2toS30Nu1 z1I31~T9WkIO+TDpD%bQIP8Ir+YfS!QH6`rLF)+RFlFlnE)P(aC6co%WDEQ8bGykw? zjXL}n*Am5S9%|0o1pU>5vrOZ5Ykv12ixKfZ7)Z$2T!*JMtB)Vs1j{Z+z9BiEEal55 z9nKd6Z54;rv?Bod^ZuQbxbz)(0Ze+3+4}lc6@-qgvZF}O!@wS3O%Hzx3maH0B^CtD zmSVwdx8@cS@cR>qYuT7QwMuz_LPf4}uSN@xCzFrRKr(vZ-OXb%=+w*(QYTBTn_hg5 zM|$s88*P1yGnQ=RdHr)uR%S|6gCi?Cf$ltDa}f(0`4Kduadk`S4=|9RVc5@AXX z)j_=E&io)t#7WU7uwqcHw@|0o{$toQfavoD5Ydr*H~-Dg&mRFm1z4;~`(4=yoq8bq z0@T)#K&L4oAyMg<$z>k^WZ!C|Axxlo8NHkPQFpZ5ocQ*AK<+6jDW%(~+Z!7jU+iXj zS9?9X$!73Uh1mZ!4+Z|ejg5`7+gowKMgkscB!$h$c77o~DoT&bxercmeVD5@Lv-56 zl+)FmtbxrtrgV7#Z$!4MTh{jQ1onmVKGEnjhve#L-uM0zi!;m`Fp49o4O!xm8MvG_ z9Ur|wqWlfR9tve>6R9yC5#k)ji>|Uwg z4JVDW)4p>FK7FJ0rV3;}!@YM&S1Od{sXYhGA*=apSeHN2=I*XI@W$NVZAvD%m}t$K z?e+!u{O#b-Dcn$!J71i(K20cEbnWdgO@fxs#7@GX-60wHN{G9Sqw=~FhK!QZ6B zvoo7=-F8_+L(M|$uKcW#as^YZhXx1?Jff@xICCHlz7?d~s(nr*lkWa>1aeI_KN z5)#ZCs?{#1c=^4Wc?cr+M=1>47%jh|7PL-y=Jj0pA}V^^usHb;0(XP^ zY`M01vi8R?G4MhfP<;|Il15LB=e2H4pPnCXHm3(-F}ujaQ!6hD;~n;w`~gK9v&;Gp z9>;hpif!S;_uXxX6BB!_3YB>NzO|{7wzH}N1 z3Xv+X4t)b^TRb?BdRJ+a)9H$VDmw}dWU=u3R-H%%>n)vvh&&!_+9UygCSPtw{eBwL zYPPTcJs_U8UL%IKX9z`ziQD{Sb|#B;bdM@0xSVM7ukR1TsV6&PsmTA-(cl!9}n8e3<0L>Se2y%d`5{AR3!CJud-+Rh&Zuifvy^LQ`=^fi!Tawmc& zOi77}p;~nqQeWdE@a}8}6a&xG|2X8@YbUeQJ1@=1w_!L>f#Q1J1c>cjzzmFWfD z-`|fmazjQ&c0Ss?xj#|DAwaKA&BbCmVu`}?TF1|^d6UlbHR2M8QkYMzJGAfZ|R^DPs?eqy6QM!-ta#=?fLM^FoC{2^lXWnAPsn zLHG&s<;QzCgSM##yuSIHcvvLN$=~11;ZX6rfSyigi#o-*uh0>bFRh-*bK?jTh_Yc2 z$@dp{Mn>z*=V;B_p`oA<5D|q+W$J_$Jm*9HkHy;&X)N+@y^B#1$x9V_nG~XSJP9c)6O`ka52Ktiv=yFx366bHZMH|oh zfFcCw57A~KqGa|QZ0X+)h0PuL&GA;6tc(9y}TQda#87jq}$F9(k@T8-OJ-9*`+vy&F$u>Gu0Z!aH;X!<9bFFm)k)CgCUTnogIUf zo`QU`YLiApL~P^qRBlA04itZ0c&7UkZNOcQOnss`6RIh|%bP)_FtY)R&d1t*oH| z!D8iTuUqB`1yQoQJO!ZefbvXx`v>F&Ao6i-ZEb-qEfo&=;PP^;4d#b(%S(Z@Wjxbp8=|$Jmx@?7D$xd?tjlhEV4a^gG%RZ!y*VjB;6T2Ku|KAZMgc1NTEoa*8UK1QG|&5dr9`V)9|!CZTM3!}N#)1v z?U^bhH9P&<+}(NxYQ)-TnI@o?VpCEE!9kk5p1A>@AS#q6>eucxF6Z#=e6yBur^`Cw zjB!|eadU%%x6BwYE>)}dGm^$+ISc2wJ833BKt|3t_CWSpOt~$czgSfH@pq1J+W4`z zVfFb-JoVVcbqiNa`1Y{`XWw*R!91CCqIZQ?qD>I)On~tnSA* z(c^1<911=}(|>2KnDlBL4~~a;gPhM2BS4~;R940S{@7g^d z+2_i&H*HRSj?U^((X*5uyF8uuy*bk?bQV1lXw_rDk$|?%<#hBP@LnmGs!dqZo4fqp zrMJKnTC9Z;>`00gHf6-1feQ6T+?W>lq{i+>A3wO|si8%5u2(CY3*gL~5O@y!D2Tw- zy;V}twgLQg0C-Qx-1SH2g5p0|-L#CO-R#u6x|#{hJxpekeFYilx=p}!mu4$2E=kte@| z!Frc}7%o@LkD1?q^O2C1HSY3z_cfJ0Jcdjf6#J4Th8-hDy$%TA5}`1Mv)x*>o+^1P zxjJ18G!iHS&C3T^5XLLy2<%vK0wT{W2n;6rB|_k|H!KeL@EJb%Dlq2AC&7s#3ihYd zus)v_s>G(n2o_O?j-%b)9JO6Yi6_u&ih&xZRmM9p+JTxk% zx;LIp^0wy#%o9!5h7ae~s<&H^&<~-L++I(dr!6cAYioMkjt4!H`9oTRk=U2)ot>Qk zjU?mqxh>4I14Q#T0&fTy5$P7cE!8363Q(L<2>JMe%?lv6?XM5MF|)9|LqPaarV^Sa z3;~)y@T34syI=nkCor64Y0lBps{aZ5{q1+qMg%_3U(`@c`{xJbiMyO_B)TN#YbA{a zH|(DynqHgfRo08PncSW!*}`yu5EnUADN}3R!Ae{zw*mG+I8~!EwHthUU|=BIbRwsG7&6LXZy0avK|E$;p93IY z;DedhvRez8!vsADOpa*i=)(Jx`EQQJUO|V%A*Ih3NSeFjrmPw_XjBf|R@&%EH)e#$ z87Dngqj*J6|E7pFwX?yR0f(j!on{a8DX_$|IPA%T;0@5R&XP%GuRglIHT~S`6fhz#69mu6{vK*GzQB?GeCp@1-b(n^IWHmKQLV=6w2ZOgGjeDL#s%IPK7$I zh;tKfT{huFp{~G!<6g&$r#qMD11mwxE&hlGD>+$pgdVVKUL^I81jcT%0!)Xd40a6(yXTy z%Z&!iBtVG8#l@xC%?ZGQ16^?QyzIPcd$p%fT~lK;@?N=2BVNvAc&m)a*VVoQqD`an zCkNcs?!&eDa0XA};26Jop#j_aHVk4{H;EY<{!eDYpy4!HD4+QMU~>l~SrHKs<>7xf z6(X;l-JF`vUyxC>Onw;Sf20LoN`u{19P8frgex*jJ>t z(fDGx+6L+KGjkylql`e@>FMhbCPQPo>|0v`e#N)20mMA5KY zAn~L-udJsoC4SHNw_P-PiUqVDrrsPN1^}r*t_)ClT>t>!fBo_{{vsJ2!4IHdwyQwYrAd@q1zM>?U_li}@aKs~Ut3KnZ zk1?uOtT%+m3W3hY<#Lv_XTbL1!-q5hZ+tMP1K-Z&w{>9ld)rb0_cQaCWU;ZAM|KJ71OR7%uxFhW4`SHAUBqlfwmkw01y=%C(#}gifrJ6DRAuw<+ z{fP#DiUfd1iAvetsy76f?HYPu;o(DP>-qr3e0jQGYIcrXY_Mi=y}$@;+3aiYo5&Rh z&LzMESK4lh<>cfn?F>dD-$Jjiud|x3_y7-a_4jQl%-1MYT_3_qlUGQ<#ti1us5V8J zwqt!oEWa9N=>d9LuEGm{pb&dz9RuZ~N7P@xcj#{rA9Ua~u<$#BVM$QZlju{Ifcjb=VbGXWT$kf*j-PT~4Pf%FR{p%)c_Yo{W;CAC+M9rF)~} zJ)&EA8tj=QJ6mzde5Bq{e?k;sdjY)9zVDsmh*a3Tq_Rh~54vn0Xa;<-6mkXH%{K{^ zcXuvrFAIMv)ouTE{h9q@18I`sKX8C|UfK;Az%KQ!{e?P}hmtY~U^rt7(hN3&Cu^=;1aX5CjhAiDO{`@F_jrwy8B|(|8?YfU%#+=zvwnlxn$t*$r8z>bvL=GdD{qp73R1kRvyqTPwbA=i0@( ze2a^%kdP3iLXICPF$;rj)%UwIF!RJ@( z;VXD6V6J;};)A_79e_}4a=)b?&p&O1n^y8(?l*X zEIS;|hPxW<*f|WWe#L)*6pzFs;p1Druq6R4f5J45?W{ztidc@9=%s3APS-m<7+oL- z?5Dw?CiUWB1MopMlV1k#NJs1(JYDE=yq(Rb5xFv{^2K+G-3xvbSP-(dz+2GIO=bM zW%Khot?pAbstgbhSI2!N%kEo?#vlx(;%P;L*5P;(0l_VzDl;@F{cv^WPqt5a5zXxX?OmGd;TXw9kxQkn@Kixg! zLROu8;_?}cc7x90eZ*Oi16;^zCe)bSx8oB*5t z?)`gG;LDDe@|VgNDpt->DFNKk-F@?`=Koxd=hczHU2aaNqhVvlOcr+t&DgUzGbI2n z3xWM3Y(JC}w>-*Jzc(emb00e48vor2w$M2z%N1|$ z9&0cC4rXVq7MJKk>Op(c5rWN{7s}PQ%{{=x2}nj7>i9uf@d}RdCVLYwi1l>*vexJ# zn5lowvf1bn2=jjB%dr0UbNKzfC0>ZViEQxyk@eP5S#96$&%S#`wPDH-`TRJm)!QpS9OsG3Q)-m8unH z2TS32qBqX~+=@8A%94@TW<1RkDqXiZWvB|{`OG@&B1Ue|d1a~Wbx8Bp%a4x27^=rk! z#}|h*v$&Y~&&4@oQl8?WkX|Pm9d4lCO8*>(Y=a?YH_J^{;7&<~>oZV9Ynn|}M><%o zn4j#DK|8^rTmrAH?zp}+M@C9&+4H#V08TwzTKSmbo%(J`#`q)i_dA>MhZAq`o%xdk z0<7TxqgCxcs)o+OED=`-g2@ZP(!ug{RZDAR*a#gQVCI3uytV^{>b%gcQOFhO9v~A@ z{%(#8U}S($4A$6bDi)}9Hj1Ee+y1Sb@fk>H)M7GU`z@3U&PHVQUDj~%Rz+`=%eLjW z;q^)fR$ouFW2@6HF@Rc=eI|=|rW)mFvk6dDGug;pdK%KuzA zQL_rhudB@8^GY-5PPuvh)t}CLQhxw~C4+v=bW_hS5SDb)=Crhk0xJT}778Y&f&CQG z0!2wjM;-v_r-@oGiIh%j7LApDSfo1In(J>tC*}KSMUle!u+s7nLm}@qZw-)2sf!NR zCEdzyKuIfTrQ)`J8wR{xT-TWV==I2`>^9?Xy7-Ug1* z!@H=lRD#YY>}1FgqXO@zf6~PCit%STag5;S1OSv!@tP@THGVT_#1^gZaj$!5+6oDyfgt>AoU$PsRLpPp|7E0!nRveYs28_nmQy`je+h&ow{HDp@^~&&C;SP2D{{&^e4#(ACWZ0F;F^ z(RDk6X{3bMAt8H0S7j;v1j1JV%gir9V3Tta%$Z)bBmk^XL`8-0F{eqoNKLudvK4j^ z_O_5T|7FPv!7L$1z}X?|c*!B>WSObe+-8nL=?X+10P|?h9!%Rdp2X%Ip{0b5OH_0i zBpCN8B|_rjB!H2!Ox*-sI`C2PoMr+cmtjEzIg*?a5|kE{k}T%GA7f7@I5*3eV_5#Z zK_f4U#~{&;m1w`-sz@;>rGNeT(t2l>81VC3suk~RjtGp}+K0b49+-5f^+REUMlQ3* zv+oPGv^gVtYevANsa;)C59hC~8Dg+l0bnAT1=YQ)l~B~pPKZQD1$k4HCgI+pzR&((%o_63P)3@OsDA*e#akU!+m{SVds&AyxI8%H2Hu1#a_y- z$NB+~ncxl~S4=+r-3Ek0fz_&yzT#rTErUb()7Y%{-+voJ@*tzA$YFfnb$+x@eaDzz z`TB=fLEtqNms|Nbz_H)b7E(Z9p8~)f=+6Pn&ZvyAOhpP3a18IJ60||K8oUmubAI*r zwd`~g+-17#sH5k~kFMRd@wt;wN%dX3D2StfW&2W|hUwwmDCJqAK-5U##$g%$R;Qgn z18D4y6wSFy#dF@rClm)Nlv3|(t;29b`5a$>`Q|nad%P|iVJE;yE1V zqqGWYg%!v1gC3_+8c<|M^-QAdR=WQPU$~n38Mgu&jhZ%td_`S0uhrm=Z7tLtL z_gXzO&1CE~q`0^(1@WBxaW;F6Xa<01VS~06B`@#P{NCV8QU`V^@X!V6k8e4ia;Lwg z$$p=5!&^i|xx^YB5g1Qe^%q+n(iUYdid<>T&5D3oJVHaq+`c7EYr$dxCQZ(l7b$8PxuZ_fl%Nl1{ zdM;j&+r-5MoGJ_JP|mw$<<7aRgZaVFpLpNW;Qj-qFux}eMc-Mp`Ae?QXPxt^%m zImz5O{JfZKRT5{4@#zr*O1k@-P%^I2E$tJln;Mn0+3t%Ain{2jG#a7HNOIU z(Qu~vuFdAJ@MJk|n)SL2F27WBh0;uVb<6U|Q7tB|;`iUDwqV^8q_b*{hnjZkGYl8$ z^a^S$b-RZrIQu+$(FtF;dWH;}wudxCZCs7W*PmRll00S$X*oN5osHLSU?q@tI9gyh zSI=+N5X$)Bxt>_tlP}(1N?d1>HGGBI*6$R>V({a!UB>t7vq|Y3WJ5sj+*WOQ3KmBOn%as)(=G;P$*i)z zei_{CZ}cC;m9E8Cjv9$6;7Jn+!q+UIF=1LfGv^|LlAF%+EJnIsebz+N`dII|>lY9i zY!w>5d^g0xVK(umG_zNt=!F`NerYTg=WGYIziT?|;UA`>alqJ*l~UyxR&$ls%S=Cx z3KJChGMk3{3QOOe&xl!v0WM9zPEvKf|;fT#9CRGX|^T$j9 zNSO6=wnv>&1*+>4r3Rs~Qa0+xMhXenz0OaC>DkQ2RO%@zUl~eMi_7iJxYI{Hfq%(G z=w!9Z1&Y;nn{5@C_~vt$*yix|UcW|nevKkqpRY&<^pOvZ$8!+7n?VVoahAVEa!&T7 z;0LV6KV)Uy4}(o8US8h!?i02_;?HgW1aD^jo5L{Gw7I&|shVsMt{53b`dZUES!KPh z1y|zI$}+RT5k2Z%=N39yPQt)x^UK4FN_+HBg{RQ%eYW|lu+DwZza;(7WT={v=1@Wc z5mq#daYQN&z+MVEcx+PlU&#pewKZ@qOys_gNqv#_<*u)PI3xOVeIZ3UAMEsZ}sGytKv_&`Ss7Q8l46MWlOI zlP}Wf9;ZwY%NLQTX0DPwzteDEluUG4n?se$;^LvKLR#^}zQml+Z89$!@1kS;@J`YF zat1H&FFM5?f5!1B8T-XoV(ANOOPFnI>QbBU5pb`!Ftq5s8s0aE8-6~+F5!(MtfuB% zSFu(tz2#NCw6dZmze%7WZLLnt$?4jDFZH)I57WbdeSI=7oYXhC z$Ftfj@twV$^Y&-V2_)UAzL?D)S?&=Ndvepi)0|u>$)mOB(o8 z58_i56M$VNV`0WnP>|KdAHo#xPyWot$@wx&WS;Xi4%|?L(ZZA&GSi{wqy1J79O2s* z_hfOsu{bqk61^sC_q%ov3j1ly{tCl0BYwF~=Re(-hq9+t*renWKw(fFcNKYYbIs2q zbu)UYZq-5UQKpp{12wzn4b`6t|9*z-IokFu#0S=h^@V%I1H{QWd{C1l`)H!qT&{FV zWtZJ&8rN{qia5SYhQV$B^G)8B4_b<_9-*^8E~dj@NcAX=qaE9AQLFJJ&niV{ZdCGN zODd#BPyP3gh3zd3K6l2_LIhNqt(E%)RY~{F^3!o`aWt$1^Ad*A3;f$#zY2JffCE`i zvvKdgN68xQjOtbWIGO(p)iY(>a{HF-pp6OEUH{Ing`O#4QbK=5)K>MaKAt$~6Uc?x zGPgec_tq+{*Q)yh=PbXZ}{SA6x0P*a%<0dZpD7(#U2yJ#H|u(AASHn7lqb_fi%Y zfc$`4AcmSii&0sWy_(@`+<&ioVhov_Gv9$uVf~pAl}vn_jwdSQrf)zH0=%?K=)RZ= zj!mM(gx?xZR!LPyBCnnPZ0+@44{P&yofGFy?ZKRTcLI-%-!nO?Qmsb2I}ZnvL0Kpi zl7}1SC=ta&JgSSU@k>Ek>`!Q(^Kjpz+p~3@bwQ~-KwB2f%fgw zb6hDLy3+#sI}e%M2L|4nR?ed$LAmVab5`grZHyHKPncu^-xCSCcyTO#Z~rr*s`!Hm z1JDZCn~lg>(lTO*Yhnfsy^POVwhVFUi*?HTk zc+v9ukiP+YJL}IxX?#Gyn`2`rq0q%6{dd#Rb;U)&)E(MFR^#8N65WkC&JyQe-j$j{pHqOZtYS@RtAt^Rc77}Tb9{$_{%FdD_EnUOA< zwL43C)t>D5-=$OE7HTOr8umATIM!I{Pm1>GO#krqr|d`4b!`>o1ZkxslKb~PW=vNX zWdxqtB!AsCN5Uc%c$bud{?FDSqeZWo(V*a_-(uI9PwzC=j+RK@#)+5D^lkr;%U;?OI;i!-dVQPh`J-zWgQrMxf-$n|^)C>H^jyy` zbzr`2Gbj9Qe6)t+Y3(LmHCAeJ_((RLK`O~J9)=C?bOkdn+r@@UTGdC?v;XaxuT5-O z;Y*)X5ehRC69#W_QN&~qcGMk0Q(u^yGeMe}<*I!%;sRBev^3^ytaYT=?Ljz|6if|M3)}daDwsc+z@FnSfLITYs+6B;1VDnie6guTM4S z${L;KgRR37FN-_2Dc1gEVb1G$irpQ$G&wH8t8xs9&6Iz)U}_1h8&{$<5f)m-@me51 zXY|No`&<4tQX^?~LBz69$5DOINqMMZONT3JZ|^cR^%hagEk7 zF)$X!2g#9Wx+b>bGQ(p-g{#~>r*S2oU62&uM^Sg=NR_C5-{h<}# zt7xt9h!j25ty@jah<1_tKT8(1NRURWPD*~VVL+YzY<$I<$M26-U--zaf~#9{DqY-Y zn~Y8-H!X{{+-46uDA@mJxPh5fB~Qdg{Y?&9-!D-LvWoKCV46wAE!kc<4 z)r-5DRC%W}JnPj&tVf||r->~iMb0LVUus9)ba&mfQttT;+xWY_?M20W$l;ZLWmzEceAUVD6~!;P^+&`_?p)4=tMeVf3Ywc* zuRhMFk(&I*=*#1BI^IeX>(0y36b$_x5^^B;4PpY}lKzCok4)d`D82C+;*_kp5O+sI zj>6zmt%RwKu7iVVwrfW$+Fc-%XdHk{m-jrAa#ZIn9`K+g-`k%!kV?XqX8$lhKT;qU z&0o{yw$F^PK{YM|17`kq*fu6YwIgd8f0@fvJkinb)@beBCTnS>qM*NH{QWO{|7|i_ zO!eXZLeDkke3>z}v4mR!D);>#dA@hVT*%1WPYnI0G>pf);K?HI=8DQ&>aT zAx$L1SQ1>k`;*VD{fUN=Uw{xj%ah`g#9|!b1kWK<6HK^~g@ugGhw^xyjqX?!43Y~g zLBzg61wqBCh%Byexy*SIx1IXiv3#2I{(w7LFXK>B9=cSn5&6%BJpYiJ ztIYyQO8I@=a@bjKN!NH{V@!oM6 zRW{{Tqx{1`_up-LKlAgLFll?J`(lh8J|PS3-yOiUDI9yTqxh9SIh%M?nhtL0@V@F@ z7fK(4P5SmbvhV(LA1!(>WFszG-ZF3q-7?2FN}-$dSX;fgRUY$Y+U@#sm82M3!r5xX zvTI&<7Ue%bN)ucB#9+Vnm^%1fHUH;#j>Yck*+(L=&GNU&oWmP@;5D~otUI5*!T+Lhz)VW|brq~{BmN>=tNwwg;C^$in~S*lS)t|a9P3z%0`Ae1a`&S_N#&I$ zLfz$#P!VvIY zvGhY&q)!(|UgwG{>H9XK4LlG`?}^6qN_T5O@Ce<&uKmviWD~SB|p{%0RvmClb` zGTuZo2huuANA3~*FZ^M2qb6c7)SQD4d^lT*OV3PA`)~Jt^;cp>*Ip(MANlX9qMdyX z#4VCi|JMfEp7t6=TC)(;nLkKnqsI96>uJLe);VGuihewC1pFff@4IsF0BGvSVzO%I z8~?}2I+C3ca+lVvl3X5Z>sD0y}+28>2O;YTCHMU;Wr;jLRoCUYu-DToD3y^)h7qvEw_v}77rJxwDdaV4cnfYEF4 zBYpAmclr_E-~)#P=epV;)!BAfiHop`PidOT0&J$^?#3z=3!6pt0AS>zxRqAi(Q)&i z#S*U-K!1q4rpypNDU`*W*SckCSYr5HP)ScNGe>xlCTFy$R^?VkhV1QPyMB@@{%?Z) z4ZBanv!s{bDB>?d|Iul?t|(RH0oYE9SbA8-=jie#2AAaCq+Xk?slo48cz?GiJfVMa zGA%RAHXHx<|=w$Kl#!Nf_e2sqPwx)N6)A7*%bMv|sLbYED0J2lG(x=y)*=t>Ss;}X? zhmyRk-*@s=(DgczvHr?0GEZ^Qd_4B#m#SD7-VcgxNq!vjJnh%Twa42vM11D%l&`x_ zKkR8MUY64$_TaMFVXi_tsbtotyu7MhWw|f>m$<;5!Xu7CnD%oP@qTp4L*a_9^j(L< z{!@ko!TuskyT4ZrPp6#A^6{ec16?j{AVETY$h9V$DHXd=I!%!521#7+6M=dTBt~pf z>3-hr-;qk1hjh|z5xCuUbA1rR8{B*R81rWy`OAR}opu)9a-4;WL_POMmv ze;J_lw#D0q{e3|YI~x1!{wa61GAsMy)cotcxuaJu0D}0Sa7@4Br==Ec58aQtU&o-#d-J28Vu&O z)J(r*|D+Mc-v6)wf}{g`PJjQjf|4xoxyczA0-4jq6A!9xlXbPv9M3kx&$*J4`u6@> ziw8b@oz*t@gw(@Zg68zgqougbzrOs=!^lN+O<4k5?eg;*G*h-Sq4mnv0 zmO773x{gmgQ*6K;Qs&guX2dGCh=~idYQD$_6#VNvqcpLgp`;LbbrW^K?Wg;@O_!6< z&wLjhFN(&Xsn&6^gKz(7b81JZL8tgVeZb>u)Wx<2GiAy-5XYntv~P+oF?(UC7#q5QNuO zLWP3WzuI^8B*+M6La|g}?DD|?6LTo>X}7w)z<;NiTD^oB#M?x+N)_Fx{P-!f7`Yh5 z+)ir=bxE|pUJ*%PVO^5STM8)%DGVxj3vP^2ZHPWpU}5k|D%Ki8PD9oaz1?R-*zWl$ z;kH0PuCSyNJ~Jw@RI&L=I{HnF6n%09t7de$T#Kh%p35tWMC|e+3hK<2+Olu))Q&5| z8qu3oB2S3@T`m0FQXT~%O#IEkxuaQ;Tguhnz!dcGxpsgMH3Frs; zbKg^Lq$2Xxme#Ipr$D+9p|L@m8UE>k!|F}n)La^`_0wxOk|%j|nK$;-+UmktWOaryq`Av&{BOe)*c z2l3`=zUHkV$=Dk-Ywm?V2jw{GrFl9^%G&$ZJtD-16KZ#-4{8rrZY4;sa*r~DyfumI z(mj&3VIL4@qsPZ&D5{U^l*_E_W_$ByDLhzkCG)ZAH(5{A?N8ngrp7Tb9YCOJ>?P(I zs5O+^t~)oi%}lSnhbxwGx-KMKFa>Z~Mt|M}@x@?&GkIxS$xc zNj4rnwQ06kxpe-TmSvLNwy!){EVtU%lf>%dFxR8A_Pa5mvkRj#h~4c%sA79YlA*$O zOJ$`mzWoU4e%74pWh8g9OIw`a^-^2B=>lLVZ5lXSCfSa*X1be5UA1N}PV?1@Q^y^X z>=)1hd(+)D=eigjNe6_^<*kZY%Lai@UAPD+$+15^^ELFYTn>$jE(I@_fL*QJoX>6b zzTTPJ*2mNC`dqU?2TwSnAvubX8rYTNDzBC27m5hg2#_`2JXno6cqxj-S z?U~W6%Q0|awz^+Jbv0Z@5as6(DZwedrhV-KNLB*WGVZ*}pgZ2+xJXIE!8;}<#$Ed{ zyAkeaY8vv%u?RM3-S5YsBIreFsZ}zb||5S0BZ_wD}z1yAbdQsKJ4r7fAjY#fyVFcn(YN|0?og4ie#dv@fcHJ~X z#os1jYZ5qkxLH^{`3l&Jd=I;&Y^-jxPTt0{y)QfL)oR*8q)U}Ofv3CO+hXhZ;L!L- zhU2bq?R^;Q;Fx~qFqJwInKr6}G7Yo6f2GquLp-=jl{N~Ln-~4)3bWVV{05WmN!c<{{9^xA95G z$b>C-=&aXk1uc2ukeH_HOGWOgDAM1v;37{QccJher+FaTxZXm{-DLK7sI%kO+q9Hwytf$3elMs%TWzBxwaPPLYN4di#yX29F*;mNYWT zJwF8utUtr~UpW~-;+Ta+F&a!AZRM+1^cnZ)f$%F}PR#|6^9jCzh8=zP9H&D&mhGSE z*ZV=l$gOl7iNvcud1TSl_<>BVKxZ+bi2`nzjdAI zW_6(srovl!-ZjGNLJM)$@WRIf`|Ttfaob7X#CwZu?FNvo#a=2|v;Co;GN5e7@nau< zW3GFr?RPGbB(G?U9`>(qp5yP_nxj&1^nbk#G%BuG=ub;OppRwm=u&+^y+7iX^nB>) zN>RJdo%zf4;nTCcqE|99)YQ~Iquy=1r$gz6a{7HSLV&e_XVN;^oku1Qy zW#Eh{wO%_`lIuo}`vQ1~U}*AtrkdO2DP}~_ubXB46L4#+9@KA5Djh1nv`D^-8>yBi zk<{v;-AO6QT1q?CA!|jSOGcnJJQQMt`9VSdHgy7)wN$^%efB4A9)#*b7EKCS8(}fZ zQ)O!2$lrgC@iuo1r^*HlE=}6J3nMV6)p_h7fg#TNkO9?Ffi+i%;Ye|T8`mx^MU z&F-vK2J>HW?d|PNyH0(A>?eHFv@&J91jY|67N9@)IFX8ieY7PRU;fE|L?KQ5u4&Do zqT}J35MZR42>XxZx2K9oiFs|bI~Iej4i%I@9-GOu;qvI;<;e-BKIkA1j?j3!FY?dH zY<+b~);2UbQhOj0nMQUvxQ}aH+LlzS#Wo|I%kO2*X05(ll<+WU@=vxAiEV3W@ z*$*+OvInhki9Hf&)v-9KC>g&f+zn&?62tsb{=;PsS7FYI?tbmgN4y`X{I&R_^wI$w ztkhNvTnY~|q!d-&Igurt+o+x`K5b|xIvawH)BOicO~#SP6dWIaDp{>MeyX|tj3zPN zZWTXaqQA5@7(m27S+_OsLwclql!--LnInQ$RDH&O^6k91Rr|x=80G*H*0!>pqphCv zx$Ehoyj+O}G}6D5Sw9XA%A{_~9<4ZERcS6$kp9z1kkShwMdd;r{HD$7V@Z?EjA4t# zo$IboVWe}z!J+XYNx@sBs_N93WP?k7)c6j>U4{6f)HH@Qm3;)v7SaQG z>sSAVvtLe0Tryqs^pa=1RHOsFqMp!Eg?AQNMwh-s<%gqyqyQ1x=)GaT zb(Hu|&ww`h=Y3Jng$=4)+H@LzbdH@iUDh;1p4?vPz-9&Jw6_OZOmVqssj>t93PM5( zce77@$#{N`e9uT0Dw|;P_IYO&?R|vVGg9Is*BdMLe$?FPWvgt45iyLISoBX+VCq^W z05eCdIt>ABHI}2RTfawpy(v;I*>&cEyeHR#Gc!wiY3nTGXZ|NHWFu$PxA@%*F{OrQ zik{Itd@IX_lJJ`=wmX)XdXVMM!ya*5h56m`%aOhy(b2o2x4ehA3d!yowG@A-XzQM% zOeG9(o!OVkT(WvrB9*DfMQXFK_}pJ7YDGIBhlMM7lU6YNMdYrX+&^(k#eu_I-yG++ zM(5nzZx3`cJVrrROhEXJmmN3j%gV_91JS@YI!sQ&zx!2U^NXC~*e%+XA6a}2 zN0SM$qQMkH(+L4)+wwr4{L=$rCOYu|1%{YH-wYvh1=l(K6+umoCrYIel}8^2ZE(8V ziR-R+5{@>1RXuPsn_hD@t(Y<#{DBT7<+`n%z{l&e8CE$q4z9l=u^U!1rJdD6r@Xl` z1*e|B><$lGo6I5iJ=_>7lY8l^QeT@YQoR&$RO3wMHs+1f+WoI2aP8qQRUnu4Y?l4_ z!RC6g_Y#5nhkzR;SZd4$iEh1jh9pxTESEf z*OPg)tAph02uVH!K3trKq43-`zX8bB+Jp9SsPS!UW?f7$3QI=V48){{X69!-QrZE{yJ`7VO zx$RLVJvt%k71)kq!ooMe)sJM$dO|t^gq3Xd z8V=5B^PAAF*4tm|)YaG57&tjQ+S&}tv)!5;$yW}C{v3jXg>-dsAfxi*qYyMQbKpZj zU>+&bOb#V~sWHHX3}UITK;Z%g%dAWoBvSpN%r(a~?!REe?*mY&U>68YZ6 z%3qARF|)o5nq%aJiND{*&t1)sJ2xjZD9=rpoyK)B(~(};(ze(|eL=lxkNQjPK?E+Q<~lPf1+Z2D#z)^e_^7n;o_;Y-Eu{`vj^Q1msMv>%aoYmZIvb`7o{ z0gd3i{8P3nF9}k7Z(BEGU57$%+)%ZiWTs3!;oC%{|9@4oc{8v-IYwe~&a{H{VmW$d zuTIbF+uy?$y_U88|;oC&CaFO2?(!CLHl| z?E-VgYEK-dI81A|Rf@2wVK*$=jFs?npVltYn{+K5+n)(ur&vWl2UbLtL0jU*tW$=@ zSku_Rn9bo2D5)awZ+UU-8S9ZsENh`Y+!hO7W3JxUpP;(;n9rUGkm`s)3Z!&~vt`L` zx2HQnjvFT9Fhg+t1R763xC=-T@qvRF6EuZg8yDhP4X^-sfr!$cfOHz~cBSXx=GcP= z4{pAIX&NWzI}JHt7C;Lm;AvG%747`dB`Rak>PBWjg@G(Vu1b#KS;xHSuWj%$|&FQwABSj+E2TlZ-H{i$Y$Nv zW>LdRLB%X>#kj!Li4G`jC^`y3>GZP=GyB8-@+T{ExT8Na*Uq^o)@Wky*;-3c2c(H^ z?M*u#zLQLJ@`UFR#)J?AO(CX(^j zkz0hM`Q3|NBpb)$B0J1q_3|XgOr1{;)mHj0;{a&t#j31~yhTbtAS0Z3%T>MVzPpXv zRVV-POnbGUI{HEv9$mIl5ed8TsP;-g@X6xw+$q$^0d2~T<&)?uaODm`5U%MXFfPHX z6HhY&*Z$ed9HjrZZrqhuD`->r|J0$qS*F~&oOX)sc1Z9UCAH^M#V+;_`jOj}6eavh zf9|JKT#Xiy>a+zd&tdb+gNY328H-eimop9R(V`C zYoazrjdxd0#_GCouPVsA+(9}(e)KT3QM(w2kWj+JgdWJ!%kWZ{p+7kfgw|VHAUOis zH3uHHS$P_D)&1?Qk&yN?9LMkYkirSf%{yeeUfIyk4Ix%Ze4voL z@~Z9)n-ulrJ*k<1jqLRlhzGPs?&RjF`i@=w?7>fvrk2inAQy9&oE9}4`Q=U4#+`&F z$5krnE0Wgz#PgHC_KWV-QBlVaTNDdaS%KaK8bDpv!GcVftNjNKbooj+phj%QUbM1>1ELE%D&>F25B`lK0p!OA^MxGbUbk|;|2%LLuRNF09F|?K8Ss(exG3Q zjxm3wY(;0<9G0SlB|Tq^1LNeD8L9YwNm9ET))jgnPN> zD*}-_S6w|l*1?gri$S~}VOUtdC1dTb2k$ddcB2TTqUe2rImvZL4B4M+HPN|6gN~J9 zO*b%TFbc1qg%th}Hcm0OJQwcMUB)r(qDX5L{P@x%hs2t)%qH?}R-pQZMM58IOt1dN z_{TtT(mHgMPBop-`q)ru!4}p%^GLMtjfC` z72DSA*lr~^po5!)+p=XxCwYhcXe94Av6lPluF|ojxbpqqqXQqO(vK~BGOiWMQ1P^aGOw|_rxEpSq3p$ZVsGi47x!~Q^l5|H> zZYQMD@a_J*37qpA=9f;Jqj}Nihk&o%gE=WBj)z8Xs2;$1uYGZ{Cx39_0YrM8H!)0~ zK|#cPZGa3)pPwdwe1Iu054#-_^M)3ts;sDiSE+Zpzl@mP0HRGnQ2Inn7)$~^F%pNR zdoU$bg@Ozk+z4d`I0b3t z3Di7bby(ma1bP}Ma2(nLT(0UsddwNu!NCD>VUQ2o1#a~)SWdO|x-dW?tM=L+I~>p0 zUGfA~PA6Q`i0Xu1V)je?-g6AybHOOIxrc``Fesv0dOjt1Q zn~?;r00#xGgiy~;-KQ{x>vt_v(2TM8;{@pgoxBsrPnh+5L*74V$v!g-yuUb&yx>C; ze6G^+Km?U_ZLs~MpSAy1#CN=}etxMo@xKCGKHb@x(!_jGb2PR;88fIhTu2Ps3htXX zH=rU5G%S}p5k-PSSAR6^8$bx<-SN(<-`OGZc*AwF`zC$o>9!^)jvVb=`?R#6B0+>Y z(WdlMyBMLlJ8FcYMyhz@aP)e`;+o&?!M%Hp-(HehnK5puw!oE&tfni>G>g?UKwaAy z3ApCc?b3-SbJIltb(c=$t!i-LpX0(bwot$f3yT`uX>_ZqU;sHAd?g2Jk5=`u7q0pu zq;3J!Nse(j!*kRy?yRTh4K#yC@&cTv{Fi(d5*%C|R=JPtLDT^O|5P=riv<6^4`>Hg zowhp&9Tdn>kd>a=bTd>S_6LHB9>?*i3lvByudmMiokQgiaxRE8rN{-25;QE_>x^%L zd%gdlV6#er5f3ofDi|B;8xTMNQm<}Tr#_Ivgn@G&EHhTJtAm(n+Gb20RQ^~kmtH~m zGmWlk2*pAHj#ZhDb`a7-2;K|u)&xJ*Bu77(7Q_Ni0wQRtOD7;+eY8o0IaOv%fQC(?yZgHl01hRf zaA(&vk|9Zut5g&;ybkkr1m?jEsp;ta1zgUM5c9R*yH`wIj!f1M^gs%2yZvxul&;tW zQVD<~Taad@-?C`_a(CKsvp~&m#-{f2Xo}5fpVbNk%Gm>SBjqv)aO zf4Lezqg9l0{=EfaNM7%sPFTs2bId;OnG^ILTJ<5Y-x;{Jpr@!^v$#cI^QbrrD8je?|?wi>leWiJ6MxyC*N-4)rMYMZZx<8U;zz7Xz zL|=g0`GhG=yjCJOsm_l<^S!dV=Z!+s%;bY*0!{P&y5mUY1Q^)I5@AOrt?TgazOr)c z#SdrhYnN4G5>mdFJT;3k_K;*{U<`ctkb)3_+5Ih~0Yx#ZAl2Kl@@2v^t(cHnAWTQ# zVpjw)WdkhA3<>0m7LwQ~xVd8?{I4+}D^n@>yD{otvt3R1jnNcl2HAsR7)T4<0wFqG z7_fDRR3M?3(%R;jx_&juDF`s<56v$blwn*Konk(sj1LHEg}-3p2^eZO z43JqHD3&8b4Q7ec6$}K^vWQEoMG4KDd0A~GgM-o*m1~Bb!`m*v#{epdxj<~pZ@iK?$^eYg1 z0+oTR_m$=;N=?T-to=;DmoM6fo`VipIx^)Klz)YJBx9k)2l4@QAg?Di{7ORN2B?Fo zIG?R&QBYJmZqch(M<52xm^ECMk8l4Fj_`IT+!#TsZ}iW1<5hTkEwv)J`TjI75w9Wp zp+{QIgPd@UGEC~iwN4>fTgQLzMC*N?W}^545R{@y_clNb5__`S)SBM&RwgJmJCoQFC7*aS+o~a+%P{U zu3%mArM?i*M;P*$x*NZ3ym6SXaZycS&jNkEML1P0^M@OY?SVQl3L2^k!JO2!VnBNJ zi#W7Vzj+#4clv7zvEAB9T_R$}-=ktVMnL0Du>M$k#n@J@f39>$gCLb26rAQRD?#9I zyM1iM?HNX4%X$}G(XCyTw8C#FCg9qD#SjB>QdXdx$KrDK*IgSSn^#o3FA=&0u8CCB z4YkKOD06{nY}*Hn59w6QiTY14z_t)G%wP^KY!R9= zgI=BB#I1Q|=M(c^1*&M3`mY$Kr&^Q}S`)(=QTSi}WaobOdVha^I@mv+Yb9FKH3dYp z5aC~IpXK8YcE(<7if`-L- zEyKj->6~i0W2Ef=ASX!4HukRBPXD4#ep<~oxI;;P`h@c#=ha;#sC%&<=N0wmN%wzR zt!aR2{-4URN4(pA0>YDK?nvg%B`+egnT&^=&N1vx{;HVsbZuWh<${s~Meu~8%Vj=a zw<=x;s9U<{F^E~q~t+(l(2*D=9; zeE(Jhhkmd3Ul-JNZE$X?2fyVn_RYMh{{h4IX`zkT_>pqm_Zq*?7XTM_Zc8E_H`~)P*~1EB&0SCu9pKgiQosBpS#_!Ux>hWvcOPLMh4F4*!?2o z#`nEYhb*k#$bG5@lq(=0Jz-;u00tiPu53YshQ5V$<;5bZ((y7}0i>x~JWw!CwkqbP zI~xML3Gk#2XEfF}zl_}{$e1Cbw!8OeDg7{3neWV;^#0VWa9b>^DC*-0~Ikoc8baV^4r4$2?3iO9zlWBE15k+x^Pq#ca&#EPU5LGLPIA zG39|6H62Xt6cB#}nF4f0kE??~co-X(^PD=&^z)0l`$$l(kny(E%#{K0QTwS(n`q{-@AvSXc zf`>pigGTN6Oe!x7yVO>-R)wkWz*B%(3l#kPiQx3YqgLvc-U;y* zur7DsRT_OiJLb)8om>$OQ>?h*Y$QHk@ZCB*B}aPG?Dw$}X+Gh8g>qo&()R#S_GWb!0|CNup6>3E+D5=VjH`Kme) zXabIuAH*@NF!c*mSw*1g4)I2l2}gK*ylOg0f2UlM!^$HV_bY8``W%YfOcgV>k0Bo2 zGg6m$_38;1R}4%jO>#L>hMse8vfI^bfGURCL&@YJlvoi%v|~BVNJPHe`2fR>Z=s+R zgDZeg0C$)BjK%iP`(u+7@BoMwzOJ4g@ZCQ^puZ)6^&f99SBvRSrtilMR8+1JDv+m(ydGST0L| z;+cD?pl6c}up}bh0_XE7J|x1jxKLkihkQW#Q!u*?G9kOsQc}S_s8nl#Z9<`U zf`nGR+Ik*<&>!R4z!YJQ2Qvh7oQPV)uY6^MgrYH@&WD?5Sl0bK7`qSvS~TC~tW;e` zj3h^#w41CRd6<7r_7-pY?NqHMSrzfxEwrGU)}QJZW$+>4)4zWK*)*~eXCqX$d-!XX zYaI^Wm+If0b2%oC%S7Hinlf{ek`IfGeGQ7Nkg4gy_)*c9FNf1#KY*2Q1_A7u?hklO z@x73G-2+`E2t?t=5ha4{Jy%c<1a+m}#P={B^NSCO<8627)xr>M#Nh&}q8qN4@Jh3kOZAc7B=STeZZfaT1~Ja=WZp+0 zSm6nXSwhAa2vGqZ5O$%A>Kh!q3JD(>3riRT-~OJ<6?J}u`K&+T z+ow1AJ&cFaLHx6_K?@|j_#w)d(9G)E(Q;>gaDF zIyNwk72O^ACTgWB?aM&IRuOD|QMCl)8^y2>LXJVZ44!=uq;~8GmJ$C$Gz3I^up;fH zytp*GG7sH0kYxVk3%AocuwfS8Gqcd@>o0}$xS>F!H-tKQr5sy2T0T17qCI+Kme=>M zT-DMN_u51XvI0Yuv%DUMv}B|uZ|n`hI|0Ab)`ve%WtN@CbHtm{8?AcYI#Ea$@QQL?CGtJu;79~?#7qv?-H%4kwJB)|t z?0PARwM0X$qfu)&mmFr3qz%3TIr{Sh5eDfYPwyD!F&@Cm@23_%;kc*0q8w@gSzV==uv~`0WvsPCU`0+ z9c#?Mh=!qYpg6{54nj{6#Ho>$lsc`r+iyTrkw7%&IEJE^D4jLN00V{c@J94Yi$STB zg@vVZJu@E6d}(P3p(4;c|6-V}f!Y8Z4NQ0h4PXhlJVMhNgs*88oZXIk`ufCWapCz9 zOv8!k29P1JNrd*|K8#u%04aIMySS`Y0?y|=diBXEC|dZ}0}L*q_pfdWCJYX30HT6i z`J9D9kue)kRybFIk}hcF*wzrkDw>;{zcBXn>ynYh<(anUx4Cb0kernyuAmSW#X!cv zfgj%ZHMNq8RUWr>bq7(m=om~>b8D9R7>5ry3fJ9voR~E zN&QINT78^fUY{!8`q|_5Z5qEPx5AFGDWsmf`2W~?3#h90wtEx{6@!vgI#g0hq*Xwq zk(8E}mTpj_B}6*6NC`-HE8R$UcX!u)mgoEK82|gfj(5D{9M6Wm_gcU8#C+y6C*`BS zovr38rJ$<8=S#5=pG<1ts?$HG_Gamx$7me4!#6p`iS z)vn{g}FI%+evIh9&9^+hB?s>}2-d3a^=h(Kqq$@>@{0i82 zEzrn*YHMptJm%O(FF#CY+27xvE|yR>P}v}Xj*hM}L0`(k%G$CYZP1WlPV<^BOco@T zA&#Z@Y%LFjDzo%^3Q_(6*(V)+^}W1S36V3Kzu~T6(9ItH`HeJH$ni?VUM1rVb3gXt z1V`lqQ9X2SKHc_*6vc<;7*nCzwrY0KDLY3;F0CaRbhr*f5ZHuz} zV7>l1tta2QmyFj*F)+T5%C}zEVp=QFMkS?zkT`eG$t*_hD9~~ig3&rH1 z7jL(|s;u7`T@NerPl|JXx3+#+UtdoTA811zJtli`D3b}=D}5UvSME>58Q5TCH|I7{ z8iGwFlHO3_PssHRy7R8Fu`^R|x*PDlYk1n8uUN+$jU>t545L%jt?#ZUVjEqGa<*QT zQ)E*8Ht}pvTUWR4p_G*FZfwi2+0QjQ(@u^;TN}L@*t~IYusB#JnQw~|&*g0pUYx$g z$q9trM4O3YO}Dve&s!#g1vh(eXb_(BE!QJY3xTsx9Y+|GHT2YezN_g12S#h_hcH4i zhWN1@w!S2nI#}SqhIq`bMRPy};G0=}mU6JSWOXOe?Gzi;9AY?>N0XbI%b;8l3Ez73 z_MJYJOD=KS*d9Uk;F|pN+=zs$DU$c)St$q{kM<9{GY{Xs2G+S#X9|B?)n>nD6^7x3 zjYulCFeWVgS<&Ugob~>?zL`335#D zi$^dkjct+fm^}co%GScmAh*M{y1M$zev{nG%PSNlzCr(TIW8+Zn;Ad5;idCLwE(@+ zucjT9ZKpeMJnDo*a0v)RKxB2RQ%7rT0J&9!h{N321d1aYpV8aDnXtDJJt{hSd%FJC z+RX|wvOVNnlItp@Tc{R0 z1#TYiNN3_@oF?6pX&;IzH13DbDFNjHKR-VgX@<1MIF*PcH~;{`i}p3WUIV;;VRR<< zeSqQy**6>G0ak;3lYaBj$V|%{e{-!2T%!a~z?lIr;6uH0XPEKG-U$9L;xOSd`fwZd zS15lGD2Z2qWTeRzGu`Jj{jr^jGU6+;L-D_+#_@7=07>2#M;Lg7Z_x0*pQfxV zEHu{L#C@CV%r%dXf18-yCs8DDmM0s)BDUVvFHKFa=@ioIMp15xYxifTUSQhUK{t>R z{cBz_EQq`!2xusmK8`G)j7=^U+%9VC>X6iewKaJuPP6^PsZ9{6^~(5JW+V8k!EG*= zw4Cd{M)TWeWWIoI4`)I9aVVQu?cx<a;|i9gv5D8+Km3$o8L5JC+2tJTx#$D^8di8P;UR!8sKRdi(&4(( ztJAM6_tqDu1mCKv>O5k5PT3qO{faX9y?Qz`+`*rbgv1<%elHW6SidZJSFl?4uN?o) zlE%84@ZG0V1o>U|0(id}Qpn!&B>X#}$Z^;#t0NTR5cVTp7^-LAdG-R!12aIL_MG~^ z6D(Cg{_j@&d-=zobbf%l@$R#Y4BP?6*Fi`9+x^V z;mAhaPLpVuh+wYXI;}I7w?DsgQ)@RUk&tcu;d!ZJSgt_8LgSn9(Zhp@n!B0Le`%C{ zdqEn1dRCpWD)0d->XZK)stZ+u-SM$<=ZOs-0G1m{zqsWZACO9+xHCBz-|&Gi9G1s{ z+@+&Bh}LYpB)H+ueVL(LoH!oW zdLTn_>}M+%`g!dw%l;W>8aV=*Ut0`M#H%~Ya)~MmAVQfCtR!Vk=dc1mVo8(ZJFs~}=w=w`F# z5+x@C*Pu;{%Tg}~ZPa~}fe2MDL*twMG)(HPLJPyvZ^XRlSV9GLIpn$lH*?3+u=RG^Tz*0@0*w+)Q;+J+ahz!-&T{)HK=K; zws@sM-mnN<9~O+BFsc;k)=1B=@1q3V;wKK)XU0Eonk+DB7KMHxV9v2oMN937pMi-t zcXHfNO<17~TlE$bNV>+S|8p4*^IUC*oP54WR-3F5zDRuUpgYSG%G3^3a##@@VErjuNSC6oAIrBhVT0mwA!f_}=B$z|7SAF$ej(DUezbs* zm1W9aRA|@}exY9aZEX;q%pFq{zr^0b!pZsB9^++nC&#}BBOA{y2536eD|`YZiS#>T z6D%Y&Habtao%U}7U*vS-D2lC)KQLKit@EeCSkxOTkxdZ1;rv$oFN|ztW2U(Olz&9X zQbCXVP&Myz#YAoP%Xa+`G7OkViT=pb~mU}z(Y^RJqYvU;JV?15Y;0zfPv8r z7M4RF%XvYPM$(+%bRkJ`uu>)Hnvxu%T+F=BKY*bN5IYH$rlYijCet3 z6NZR$yRU*Gfh^xI4sNd=sDGNb*qXjp!OM48(;fi&?>~!H*enA0GcCiz!_y}M0s zb}@ooIC+@S_(oHvGkKzu;lTQsLT9<{iWEejf{ShOxa?+w>8t&}PVlIxsN!a11q6y& zyJ#|jPH_3>wvt=cI59B^Nn9px;*THlojY{qE{k&Laol!V`)$fZW6WV)dc=SQj&+qzGQvXvu<$;XJ;FYVI z8`usfc4`^wdL19cySwj*N=q9IZR4%p!f2U#U^)<84$t!La@XhhO2>TbBMb=%3F}AW zoZ^(hvnAPpQNV~7?`@f|-#rR0F6F(`t(iv0WJ6O^$-~dr(-$yFM?3fI@87>4ptC+P zz+3ezlkuSxYF=v4WqsTYv<$A=Z3z5*Mq9k?8{pCggGC}1=g4##yIIUyE{Ex>xw#IS zszye1wG|bcdog}+<1{SvS~4VdMd_KLWhGwn_VhHYi-U-;bG(9EoR;=DQ>9oR78M~J zelIjOmXMUR@l)0WrX~oK3KEY1L+N$9N;KXdQ=ZE=hl`my`BmU6e1c z{pLrQf1Em}E;^f~btjjSqz_3JI|dNL0%dGc5_L^2*%Q~*x0TaJ={gTnj*oCiNF=ST z3mOienR44M`%m1{g!2guo*HKHgVu4EV^*^^LNjkK%81rdiy3sm$_neig#-2S#lcdm zA|kzV>$Qe;b%#zx9@o)l+&1eHab-4|JXsYj)YSu#9Ly8VAr8BX*g>RxHFn$7Rm+2- zg#y{z{R?{ooa_E(DXNE1&Wu*CCs?%|6SG1cRV`YSd zv!k^Ri#>T_tE-!lY+u8TsfXI+#Iy}wtp1hAgv&~0KaA`0tv14m>uqtjn zn>PH-K%wgXkVGMh?Drw6LC=X~&zC-%wRwX>zrD4qEBNl(a94sl5C73DuGd|%tYOrD zNBO=TjK067wgjiP81|OrcCf5u0FARPnhjdRRJjb8OdX!EId!N3tuuV>t+BCjk?F*r zj^EGmnGS_FSR?rk43Mq6z82Kq+De|i`|QqZB{m%Gok30Bn1*9{o((74z^g+maT~jG z-Fv&haLiAUF(z#R9}C4Y zFDfjuapxXe%G$5`?|;Ta8CAn4cP_CPYBW@Lp?)yzOsJp8UlU3qw&Y8@(HKv}mR+HL zkh6KBRbsR3myn>9b+kT)_j4dp@I^V)Qmr8Lz-6;cff+H84_@(`<|}q%_~OOEY?gm)z!O z?tHnzspaJFOJIij z94rx`97ha7!8Qy4jYiOT25Q6IyLT@b4T0v(mLe6`Qfjquw~A z@Xzz`hDooUOQFhXqFrRHaZal z2C3vXlo^4JsRagrBqW)+l|XZd<#P%LN}DXW_Q9Z|0p1FPle6On;JX^a7_ey0r&m}+ zWM*xx9p=K;VpibO=TFMVJ)q-wu-*;~Dx0d{(8$QwK*9gdXRx5OU`V{%?9r-E+R7q7S~5CgaH|CV!Yl-9sDZWa=o% zMs3Y{dNgVG1QXvI{gq6X*CHk5NmAoPBQQtPq5@y1HXJYn&>BQcl+@BnE5haJ>VfLG zr{;2J4%}R(XJ+z~382S+`O>|i2>t?`g`njht#XM0p6cB2Wia7$1kk(&M3o)RPfHv4 zJzxHTQ68|{-k1Vi*Py6n5Ndb!e!2dl^PQelY4Cjs?-!d{>`E*Jt55I<`403tLSkas za$8f_$?*5|yax9y_L;@Y#62u>Uf$Enw^9;V{JOH4VQn?$PvrUT89si?f8opeG+DVs z{m(`t8~-Bl07FB;c{4R_Dz@1(ytD-2@ufN20B)m|eyM}c`9D`-(wKA`UAfF!Bu7|Y5kWdW(xvd=;i2*udp2-j^h;;7o8Vna0mXwsd)6o%p{v7S= zo1x{wTq?k(8k(DZ!KWP79T$7kaN!H?t_%dh^N|a5M>JTSY6XlvKRFIGTwt(L51ir} z_#v3MeKwkaX)?0E0V8}Z*hoe;T0s628w?ykI{hDM1GMX{mwSC7+i%ST4L>}CQ92RK z!{)$u7EIS@M$VDF4&XL}h2-OaHMln-l);k=3*M!rT;TCV@bwMLI`AsMptq%8K?&@-K>jpr^hGYK*&a@%Q`woiqJY}|9Fq}~kT68Le6k%=^c@8RktdMBD?kx-hk%*YX!pGoL9HB0L~0TsSijpLWqf#9P8q)8+K7?mGJv)m?(8_0ij$qbAjDSPwmF|L&d2C!9vQ7kl ztXBuI-Q3*JV9Zqyv{o>a+!!o0j_5ZYtZ-n1J_vZGK0q-wT!r2nrsY(@uPqrq!}5Gc z?CC`0iFwtL7f`*C$taBV!VHKo+`p?|>cyOxVoDLCsnd%YKNk-%k3WS_A>^Y zRcEP+fNuEFZisYV914z($ML=?NPqs{W) z5-mZ+Y?Wk=cDQAe!|7oS+{R+bI0K5AB@Q#_@VZ0km{&7icML~!D9+(Kj%K#g2mS)g zqakOi76Kd|%2BJC41ATpO!tFxF1Gfm6e(sa;IfmZEeWcc9(Kt%N3kqB&CMI@ZMs^m!BcKEv%~~*H&&|u5hS4?bqTToicI4gQJvlly zmZp$_p9;Cdwn{c_7H0bP_V!rV*ugq>(&pyo$lj;{2#kDx@%gp*iTO7HU!j*k%R*Mr zIOskt_YP>wJ-UZjmRVU@q50i={B6Mo!+mqUA|FrasP@{kFyDDplQa?c87*Au3|VxO zShags;w`B32)*-r)6WljH1j4_QA=4}ZD0GgW=j2#m0y=~CE3 zgY6MrAVeTb3}EskQ}F(cLh>Fw&xjZ_q&6_D?f?pVf*2cHB@m)m;26+K#lFr|DU{FE zZ}?6s4ie@N6(+&^33{IARQQ^jnlL&h1b2*Ab1Zy(>NC;c`yrclkDi_$)(K_k!ho@C z&?=7QQ7jT|*VtNo@w%iqyt74}VpUiUU82N;moW~97N_Va;W7P`KYk2~!# ztp=#vcYiJ;%9SXjT6-P&j~ z-1VH|;>O-K|E=r>yv6AKl_oIkbvoGYIox`ytgNM{S1+wRjg<48z`0LxtO6by*siO- z0;uT8pT_IZ;+mM4Y;J97ZN&3syO;)%2`G-`w&|Lgb<8vdaTJ-37x;?eKFqW1qf;p_ zn^z}PSsf~mIKD%STurgiM}JtU+^Uk4j%q< z{e1?dKe!EV3j7F3BcGiso^aIxUV&PbGtox~vgx#OL{Ci!A;M3=fdMrwWN8=>e<8pJ zii(OLY$G>^mzQ^Oh)pLg5f*PKLYhBVSR}v>(7)|#>G&KVX93Y$evHX@AWO3Ahp>f> z4Gk}^8lE(`7(jhV31m%RRbL{iv}|i@Lsk~xHN1|ykPBYrn2tP+=Xddoh#)`%Zjcs) z2=Jr6E+QfVZk&EGG56s)LVh0DUdX}^T3;s&=vlzD7NKXM_+5U=B)Gpig7qgaxbl|3 zp*QOP~~XSmC_*8)egBFQJ%W37kru{wLKs&8Cym@R$iAd~v>m#JE>E-1~>9Zxww zs-S$0cMZexa|-0o%uGz$z>Sq-KcZRB^gBH8tNCrWQ>2HpsfyX5k$t3;6}wy-7pES$ zWPP|yKYw=0CLPZU^LxwV-p46b#1mj6nrM+#`B|{Yuzs)fskpc}lqq0J<8P#@ruHD* z$nbf?VHRjZ=o$xiH5N|3gR)Z)tjsz!+GSG5>(MRUB(J?7AYfK|w;IX9@V3Bb+emYe zRwA}ZUQ-jyFRc7;-&yJ@W=M{L%1cde6TAMfw) z^8%9T`SOzlZ6Z9G&cM5bl@M)1Lto&X(p7@RUnn>!;zI2MlkD7r0-*#MMy2C* zG&FcYFBJ0a+YgJ+JuNMMa2KxpEc1jz9|2P?YMh$@`x6ooAp{f{c_Ea3VAWoG2R1SG zPEI=Tu*uWWz|DpY3BX~3UsHoC5aMeZ$)Y1~0em@ZQqsUrpI!tS;{mxk0?|~brl!Us zBJwRPEHv8hg908(dr4TtlT8Z+qHI@!;B|-+kj>!xsWDhl-0+-@ODE^|efCmrgoKyn z&^^935Eu2;T^>XAEc3DP{zs=y)o&WhD=&T5AQd6XT|jqYb*{tQsJquzdgr_d5Yg)g z8#BAaIzt7?s!6Z0!J$u~$EH!=P^20o{d^|NKoL5jg7;nSai2at`UI7Y zHjD_w9`f=&fTN8@I$9kBpIIaKX9lbp0-GV(AX_8dR3zv@vm*9rf!-|_r-KFvEb#UK zM9MKCs*Fv46Od(Hh=?K3qEvF*0M59^f#*?i^=#`pTZ**7ksqGCm2Ll^fxdpjsKbst zB1j-1NYcP|)BSr~LITC6rk(_4@J~ADs1a84%lhYSzrGF)56?%Ygs5~3`zY5IKEe%oK7AD$-&!r0dun7x;MME zrsm~L5SLhV7kaUOBjSoA`kxUIFa{E#RK>JlaHl)+J+7uyM@LBzB#VVj!z7k?B%O;V z-?p6?E;{JR{cda&$+oXr{rici2Nof51!2++m!Wg-5YSFsEUe%AAJNLHmNlZI0xx>g zAh2QM;nhQ+01s>CJwM^Ng~>k*DkWc`g9-+I4|E{P74NZ0!}>|Kflw5G&?uSMs~5NXytw^Xw>Q6gmzTdXadmZ# z<+X4J^YZRgJH-AZMTz%wWd(!|SkEg=>`~Hu15MrS+m>d(&A{PnyH|cTEsg#CpbS-< zSYV*_+Gtc(9M8<`tj9tI%f0MGXkZSdQ60dANz*K5veIv_acj5@t>w41w~%R{nvS=v zPq-N@eWUs4ItS|z*7F@vpP{TnXg6hh%ayjH?qB=bh}b}lyl!o$lY?Iq^1?^|3%Rj! z+hpYs+Nf4b*d^8<)*{=p+()wu0m-Q1jUF;PAO>C_`pr2Cg-e)oUTV^GEn5o>ZG}NygJjsQ zsD90YfyKat_CIGY90R!S6_i8mtnvA}6)@au?h0dhD9u`OiJYH)wzM5;WX@JE#{Za1 zKj0H}?H@c#LK*z}eb=v>b0n)o%N$qJc|8R}|}NrVyFjzd4=2+=00*MTd5DIF2;Uk&vIVb4|_? zg_;9Lslh~G|E?L4w3?VCX#}B{kYYj3%X=7aOD*RXhm&tXx7MGP1tgxl9KrvtF5pj+ z3G!GyfJ!)V1%JcWBg~&9eaIGGo**ZFtD-D?x;f6DQvb6I` z{hfG@DUI%EKkxFL{D$XCI;T|HB76_b26#qFKTKVgO_MKV@XF6;1NcV}+SsKfQApB< zU;?}oCJoR#vY$sAl2#V-I7|#&?ZMF=)~Z||`LtqRox1X{J%2&(k^le*gVa)WEu$W3 z8Hs~#{5mhA^-*EECYo~Ja8TPhP1Z?X;pVhn{|DOR2n-Z1NH2|m!y$bf03isYwISgC z8@jO3YBv-#{mu(I@811}-UnL1J8(sSsy;b6`5Zb;_~b7ysrdqmR&ij8FPF?p@}=%^ zXrY9j;X8&)BCP8_`hKd#4rzGtN*9uU+XyC#Xr-c|csREvG=zu$W*-6Ip5pj=02~Hy z@DWCC8rk|2f&TtNbYVEai;RhhSw@yAzX2l>LIkY%5F0+ehXKrQK-*iMYK6+v=|Rr! z%~HRA9mqT>;QJ;43%^i4Uz-FQ<8w zk)Uq92(<8!%^xeI-fl>}3 zHyMnUp;Fxf4G5VuSsGwyC$?~=@Xzkx)yk#ft|K7Ja} zPy!kWZj38ED(3XDFLCin{{;LUF&V*r-Iw0CI5iGUYlbIDxXkOC8Y&DPIJ&u(^_H+L z*Ocs*^-fn_yQUO|A-VZhd3pb!KK}L>mdv6e3t*gq8|M zX4h0zRjZ(}L!6t@6g6?Hi3zPPlwr!nW+Vn3u@wCL@ldjL0j2`XOTXk~8mPMU zKyww@MlYRzjL>z`sb|Q(A4@9#zR-AeF2=EPVZm~EjVc_ULOmhL!`CA~jzLsPit1R8 zR5)oJ3DemD_5(SyN1X-1o$n;%O;A< z`nV=~d*x~UFML({;?icOYqs^oIaJ6C3Sa4tp;Sj5lK(FfN3sf<+Jxm}ANx5=E`D6v zpVR8O&dPxfbF^%oZT)(CBCgpysqCJZJ^iMaoX_hCBBP^af7x50-+oXBs#2L2642fV zT<}J4S-Ev^Fs`BE-O2BHWLF*gfrGt{j!xomN)?mx{07vH@RKlZZ-?ss5^Rg&D=I4f zc4PDeMWlhp6Mz5uFHQG#R=ZvBBb78LC?K>%3_Q9VKxE?u+&X~J^hmXc0S&17jA($z zBAY)Doib=^n*E1HM<1X;HK6#k9X7O^JdWI$Y#^W>$ zKVs3rRfB6wTSBcXZ|b(caFR6eWQ;{LyJYht{4SBp8=VJdCs&?qdrtvc6g&CVZK#S$ zW~Nm~ciwY1|G|dTZ~o%wpW}pv=bZ`nKH|SMp=$L#PJ^H&?RRO?qGJocxMnJIvA) zpi@kje;s_YrjeeHkFT-cDOom+_#|S_U|u2#4KCIKM0hk{*k6_bc;LZ~+=X(LvjbYd zPKH9pE2#BBo?#ATw~z}D`tOKqFBCDtGBRIZMFTPgcG<{k4YVFWBO03SB+f2E!a{Ln z7gsxqpI1z0M19nWI(6a~C3U4dWmrviNaho2uco9|_X=0eX$9@65H7}2$=$f}c?W-( z8Ugev$9J(aNzu0ft&867AWMN^pV-WU3nI3hf`Y5>zIs1w4QJ>YtOgDPgK~ina2UXn zTC&eJ>eD6A1gWcUkcEJ$Y&E|ayRklDmuq&0{wp){QY5>cWl_oYH{_^S+qB{zn zi{nGXb#`7HOt^ykP_nyJZ8uESvD_9t&vA^qk7V+(tK89Op-t8HmBW*5z01WL?|L%& z$J|TSe;Hzs6}5$HTiv>K+3qZB*mVx&hTw-ir>O*r@7*`MK%t9}fJx21&+mc_+^V|= z35bZAfnbJ+G{d$F8iX59_}7fUC7`JSmg@|%6o|qAKvPew7iFNx3}>tctq+i4;zSE) zQg4CXnV)KXN~9}<&b4+gm{5QQv`w)I?(mmb1>*jeZ_nEd?-65E?h z6%GU>2E0kR&sos@B2>-zYW__ z^=e6<`na{Hdlq>LZ*+d6eodX@SV1GKC+%ym=&6l&QeC;!bL+#ftva1+nICX8dfO!S zP67LEi(T*BGaiu7_e!(lyCffW2@Rfi1*JfV45h3j3`2=8+^kZijg*=6uBu4_tf)6g|e;C;M zc%?X`LLjR^{*g6y1*Sd>@U8=E6rK=tbfUFO0vD%jz>S868QDhf+lP2&1;4>@cQHY1 z2Zry-fUp2wJ~KJ_QHXL1)`qnJn;#q+%7raD1>-5$_J9-ys6JA;RJ)$ZXZrk$TK8qq zTGc9oFOr$#)l$vU>UrIQyDSM&kz1a#3uFu|^u*$AJC^sXc3p9mtL@GQ%Mn4i^mxo2 z;APavTlGvkPTbVseL@c+48^mp-HCL89*~ zs%F+qfhUo;F|3&WA*~pWNAYhMaqKzu$Jj)ju$s3(1I;USHrh6R{UCd%X^nd#5D=2}iR#Yo z`Y+0*+FZ46gbBkDp`k*)IQ2-m4M4~#yRHBDQUm}NKwKGuZ8iq=inoO>gI_5;yvAk6 z!sN|Go9HL9xox%6QOppSV7HBJuTR1#Dt+MRpBB7UQ86(}-qTAnd$Gw3*}F~$ORXg= zIwd5;erileJihHx7}&egWL^OhvJK{b%&-Ck9rhHb-nMb$Wn|cd&_zfJW3GLzUg>x& zIaNE$H+>zLCg23okl6HkzAakvv)3JklfK3zeMO8yrMo-Fs|aiK>eN`+1#R8sxFlL2 z^%}ep`4nN_#yMqc5Axxk%fnKN1Rr6dRAg!l>2T84?c(^^=hj-@0CRM#+?tkpmb?0z zNow?t8>3DB!g(9?p$JpfvBWOb^|M!LQaIcHL3_CNu?SUMuQT~PHp984(`sR}wMLkG zfoIj549VD_`SfFq040}drXFBMdCsP9c{<3VW+b2LUCz^Vzy7j}d1DPkqlOE1rjheg zH9IMY(<%K~ri9#eU+7TJx{|FP&H^Jct^F&*zk&bvTg~-s55v%OYFfK1>TabIKh!af z^y@N~C+Upk6JEH>SZcp@88?+tFipODtniuO*f|Y#jTcTIJ{8N8cAf-Ia-=(czzYXqojr6q)JLY4(pmJDoM z15lWzShb)%@2GH^Hp#y^IFHYns12z0(4=fi*Pi05mC)oU=Hw$}1KRRl?pSjcfyVPfzwC%?_rM&veOlvNdt`O*#=QCM7Z zDFAgzAg5~ROu&BtTl!hh!%KiPc@*db{}qwd+Ma8j+1SX=HHRh}Y9Hu(K)5pjcAAJ! zn1N{lkQkVd%)o;VEv2e4DTe1|GBUCblt3pC8$Q_fo6A0bVgC@21p625+Kzm)#F`~# zUkTkp2&Bz|4`=byM1zhvTY`!As#5JAkGMC@2Z%dF`BU;qrq1xcg1$6KDLbBc1S5}O z-1^v^d=}0Gf$a_V@5M0cd;^;;ynKA{X)b*S1p|}O5^NCCzU zkU0Wnm>TG7juf|BB_U%Wli`I<)B=zc5D`a2R|DDWQ4d}jDQ1S!0aggvN2*{IffYJQ zXzXRkEsD)2NMZQfXEL)4<6ciFzY2{9^g)GTXy3`+9swReaHtwg>!I`RkM@?QONMkQ zf#T;I*`{*eWNEb{=z%~Py8SGanaX~PI+Q?q1M5CPrzcO}`;)$_E#WQ#bl(4{H5G2G zs#n|F+w)C3NAbZSI94%hRKV{M)7s<-$>vmWp}|@;k8Ckr^h~^fo;m&KxXbimeQ1!I7GS>d637 zIil_fm&s_=4ZP_9%6}BrV&agLk^(EqKRGmC9KO|6o_~3vMgdsV42Ut#YUlVqTE zO0peE9b*1|V9P0~yGEtuWkfO)f7ats`ix9-d9I+n5P19tef5|;4n(BJs0&R|VD<^^ zKR7R7VPT=^${!7|5aXyD~rLWKgW;dMa*=dWQ|@R4#JH6|(VJCJV!kOYyTV$!Ja0VE23+2waI zI*N>n>PnR+BYtY)16LK^O@40Z`->}3qavduSnOW_B#NAl4g;o_`x_J4g$#ftZyg*M zz=9K;!HW9FZ|GxX`r25C$ajYX1EBgv=E(l$Zn9feeIbVE_P2 z999K0PTenDpo2PI=`=Gx?*+96ETOlsoB^KQovkSVN_Qxl<3+LRdDxG&wW#85Zx(PmkE4`h>zvE<=$K z(ddHSeh8HRU~B}sc0_D!Y{-29INg$W00up@lF^g1vqJCQkwawChA3yfJ{kr7-$;26 zH*T>fH7K1X7sxg+9(jXj02`Pv-9bVCBo#z-2xhow$Z|5L`M55CKcJiG0fPV*kYIs9 z=L^uffYsl>D*UiZhb*^22Qoc3R}ZWXsA&K6^(iRW!rp#d`rcn?sW~}0p~)m<(e_BM zAlF%&1;w&SAbi0g%q=QXTx<0&g(#LDnJoJlu#!25v#^_qsM2OGk#Sji1j9N8VC_^&#{|bt5CH8_w6J z1hv18bZkw}44 z($Li81LV99XU8^ZS(?>IGaC(!#-4m@zmlaT?G;pLtg9r-){ahgWK@ZdjtUOCz zCG|AfWJqi!Wo6yK5`!79{0TD0ql~dxc7VVHH)%@UM*P_PY(uvp%A{XiogQ??0nxHFu!1TqkCSO}kU zD6;0$=b%tz2qB4<7F|`9g;&hpZLazZD@nyzl6$xN_8{r+K4ZI_VvdFKa~;Fs0+*?S z2YrPGX+_3upJDw7s@NzVr@-YvO;>qaOXQ>$m~^=lcXT+9Rq`Yho2Biec$~t)e?b=L zJizM7Ia5%IY%4!kRz>^&WzWnKiI^?Sg+?52{9p8(G!PH6j00TB|IU5R?)kpkfpEDJ zCk`fds_B(9m|41N?l@rWu`yiHc4^X%Wh-NqT60Ii;;X35YWa!tLYZ z@sLTJU0kAg9as_S6srn#evudmj{Rd^YE(3RzK#j^6Q+CG(4`^LE^y}+vo$2`?MsZh z?|}>fEFlVleja4h{w8TYH(#M2$Cbc@b~6;pb9hh+1I6W~IYIdp z-W76uvL6KuWg&N4t@KSSw9OQTeUeQ}f~XCT=~ZcIX#jU44BCJ#qzi!=ncl+}>Rb8B z;Q|Z?2pe2(=e&^BCPBr6E2})(<^)alQ5`he!O;mr9SeQW% zi;I$S1CKdB$C;L95Pg3p;NT34CKT_#Q*m4-cbUh!RT>nqi~>;#$|CFh?RCpirRVQ$H|30Fyg_ zavh-90R#(-=#VieqI?4p5;(oL&>%e{K^*wtzR;yxT2WV)YA>xOm2HJ-{tA#?L6|vcY|NE@;9+v#}}uT z?R%Oggz?Sabs2~HbrR7CFw9>kzoxB(;FKIHb*3& z@E`tyUsp7KF*#Z~yfYh|q6URDQ_lItR&h3NSL>fsLzK%ThYCy{sQm zb6@4!0I2~KBTb(qOe{Hl!*6-Xpehi6{#56qZD6AG9dN@70i;adaE4z6lp;A`fWTlx zKHCn6PQXpQFxcprq2^gR8F!1fl47j1>+H@q+!rSH?PC4*97iP>tMwKaIun*wtlGo7 zF>!T+4J@Tq2lEY8zE+iWfy}m+0daNWtM5wCajCz0ytvW)UO4}~e$voEX6nKEaEC+u z=^Gm(DFr13r2~KcSKSBg89&qI3^LFQ=Xt6Zj`;dqW>)YquE9{L1?r<4?jN;tUt?Y6 zI3VACrQ<&}UcRB*zO3LpAA+jcafv^FQMwtjeMKTR*FTCS^g#=WuXG$&ZF_MA$$jCg zY{p;NR=)N0^!WP+vhwr)shg!9Fdg@|3MAt{P^fvvAUPFxN?cDQA22NaJXT zjc`Wc{6*H;FWZUP(&cfbs?)aq#yvKsg?Uec_yyEik6X)UO#UW;quz%ZBMT!X`fsK+ zsYyskW_OO3PnggDkZqo5o>E?HY@Ct0oSmJvWS?T#4Fv2+50~m(uim;}{Rcu7VRk{A z*{<8iFE(nckYzx?Iq%rDZ@Dj)-=$0+r8prc#FV9Uu&!rm`R(Gg(XFlebWU@=^J1FW zh+jIjr^2)q-*u(fEvEY5uOP>zE#7O-9cF+T!<|&1!JC>nG@1vb`-Zw*-`VQxGXo8T z5M()4pt}6?hiHViGs7$L(1o{=<#Cn%=|bcz%E0x&&MgAg3ar4~;>zZrP7uqJCumQo z9yB!4E}U}UkZHPQ9@;#Jo&Gzv$h&0_uujxcD-t7$o=<**_*~-KH-Xwiw~-{1r>bWc zFV8ej4OpX=HH{u-XMT8OPD;Svz#eHM&{F+@n}pX;aHk^rUF0uvZHe|GeZ0C` zdu!%yF`9>?3x`Xn^M|MTsFQ^|17oF;S>@~8Rfi|lK~{l?2r;ws)Ggk#Hn!(8{T-;2 zQq+ur>%PGeX7z!SwVfRs7gzI$d8uCiN}KJdi9qL{KQG|4shsIK!LD4inLefEl8v1m z3}_a~wnQ|KWqVwBJA24{gvLKsZF(|q9(B6KOFK{F>gFpW8O*$hC0R%)N!|2XT_lSa z`3*R+f#_~JJNo^>Ym=OAC&dmMP7_X|SqD3)lLx4?C{)^A%pIH;rZ9eo7(Q@%XT+LG z#LkWrP7!P>xKF$;NHo(cnju!FU%GyH1 zv$&OHgl6|PkHi0r3$0fztc&B{y|i9^;p)1dkD8kYXG6P-v+4y-x0T{_l*_gpYI?(M zH<4pZ=%T&)i1T#b{1lyY?8B9dNnF%qe{pqXCR|0eL}MD4`Fxb#nb#fX!_Q>1wPdH{ zNIdI7ovrd#<@%`k*j28mJFhRe2HwxEj`tSWXQ`3(y?FRW!5(DPk32OGuN95kQ=!gh zAC^uv+&?;HKI_)2&;cG=DNYob>xI+Z$p~pR1vA-@IQ=6ANuzNeKYS?Z*#OJG($|ahN>I=S;)KcF3m-6XV@#x_CFV9ko+%KHGVIPbP#IsMhq7d7|y97tIg1 zoKXhxu0|b_Mn&V!^iTcdU)+OtgIDAU5%e4fa+()aQv@z-mX;Y{W2Yrg1Ob3zE)ntb z%aW=v?MMPe3gveA+|jX;yN^$kYMfW3A7l=o27dqe2wn((@GyM-`-jWVpCmF%Zg1(! zUQ~{oOh^mOYIkjj!258f+}d~}_}v+PK=k+w{(rl{8hcyIGV055(73;w(ECFF#+a=W zKcBX~n7xB)FDE?FfE+buS!xC%U&x;l z33Um!(lLhkL&_zIa0vseUPjK56x3BLSI6IcCPWAB#Ej%833_qxp_2qB!{5K^mr-pN$_{X`6MH7Fn z#t{m%){MBu{N7n4Ir$>)!t=lHz}0f`*eZL)&3%-VRj#wgZmkn*_gB`q(BDG$DnJ5FO?-!yCRO?F-7>{-@%+22B;pfN3oX|dpB>zhV0UiXfjmp;aQw3RfvHt(XVtmizhHUMX~f-miZ@tOUzwT$Swg5K6btV4 zcq9`qg=4dvS}!5~+!DzJcU&Az_}GrybSlp$tVf^d!%!hX%SBk7m~UMtE`$wGA`^#7 z6wzfr4^jk-Q;mr`~l{FM`AXU zE|TSS;h*0Mo%34 z$!rr;%i|tno1!NAFLpNi7M;HMRP-5kCqN*$KOh|GF{pSgH`O|HHF{-f(3#|l@p^rv z)Q5MxWJ-R&XMgYfW_!k)uGKl?e3&u*vv#P3sYBsa7_ES`htTzo(jAJfvTY~h|A)4} zjEcHz-+*B(KqUoX2tiO0Dd`T8QYqfW583CyoC8fauhL9YP zhIfx#*Zp75dOtlM9v8A?In4a_-e>RgJPy~=q?w*-o3jA!SIl>AeQ(*^W0l=WpN4-}<

XTcsr{`)crCs~BC;FDKS0pRp$LdEGW{{lMNK1(CG#l5H-BnTsu$GudQP-N(DI zw5d$;X@!}Uf%n;b&d$Bh1LL=l5sUTFNob=*>BSRdGUMVJRqtfSWiB>Xw{tYT?-3nk z6+7lI?80*T*xyJ~mR537E%z1sJ>DPJ&6sUHZ+Apx6py_egKa+yhHZ<}FM=L0DtV@39ex z(B0-qVk(f8Go(MsF?VE*c`;&^Tej2Sue2yWlARa6>S37DEiXcdmCao2Ip5iYNQ(E* zH3nvWu-;xfJ{mi(b{%cEmvwywiWv^{R5r!Bz0QA2sr6@l?PB^&ONkxfR`}7<9%s$@1)XKRiIVv_ zNcnoG&ZfaoE5@yk_5CN-QG79q+uW{O(L1Jno66O<^zi5y-xo);@2uGx>IS}jvAvLW z&QmT?pE0s|2HQ1;D)jkfor*;PC9B3B|NTHE>P)gpeS*(3q3JUN6K`CNkJHcP*+7@$ z>F4-M84&-iEA$Lqhmcu>NO==7oNqCohe+6>Eu}$HfJDdfrG}Gy7!*S{C`*o%Pr|-p zC2sA|Fgc^0Z1sy$W;`H_cJi4O4#G3l-St+hK{_Vme&bJv<*Q@~hB91C1_M2yEX z(fJAwb&t!A^*qmK!O-G`#HYUZA&|8oDxNuSRfmZ5L4!`26~{;`{nsbk4uvu3dGyw$ zR(c{H(_Ylb4Ra`6*Yp2+0hs9<>fCgFAVb&jb2?me-dv$XwY=tBa?M6hy=W9-VPk?OYiR*v-0i_TzEox^tGrp=x=D-1rN%@3~X=N6N+h z=KM_i=ESVn{8m(-Ff+$$ z1xo4L(=gDyYHthe^OFLr8_bM;OBOadEipM%?SF5>Dn)dgUN5sd&tIw6RNeH1&>u#P zcL~B6K^G*MT739mahuo676bR1*ji zJXQ~QqJ}iy9}5CST)0)wYE@_BOBr+TS)zmXjm*M71w6+2Zp#`BDzuQMU^f?~koUZc ztL86hLRWQ=6tMo@K}aS+VAnt8Ab>1SpHCqF1IX1Is@B|QabdF|Gj)EbO@aK@<*-dU z2P*?{|6xcXp>NV0_5Fwp?T8f7n=DQ?Xv6x+LINZdgJGk+>z3Cj@qz+DjUJVg&AU#_ z1M;E8ss8$x`k6`#y;O$Y(X^2)sD#x&+-gm~Brq7Nu5xy*Cy6Q1HvUC7r|8xySe%~8 zRPT778GZz*u)F1vxLYD-$vwVGfJdv3mONo%HYsk0Y$y~&_0K5wE>)a0SJyNQK*BIS zi;rZxSXrZ*NVvLqsf|5ceLv}a3gn7+agTIpjpuB@T07^_Qc>Lgs_B#RC@^QxhKM-G zO4udg-sGAFt%TU-vEzXec;b>BKUd4TsZRbOTppp`C!&L`7`-J&u0{z;NkydgoLvzA z*=~(6>4dS_aLe@G&(v0twzlT4`#;2U*6$SE-rj-jy_1ns&M7Xu;9o@Zz2h<;JaRhPW~d4Lke->jGf2gC*@2z} z4ZD}LO?Y!in9lrU_*xJSULXN5ud;`^l6@J~hK2iPDvcfj&)KWe?jv zKAK}?*2#?4kmjJ=4&#?4!6Z?C@p9!>qPu~tz%=^QNQp|D{rv2J-E%nn)@)hcK!WyJ zP;Ke@R#V`;m;QKbf+Eon`$T9=>bsnmf)A3ZW~z>bBqnfT?kVi%&5J~kv%i{m`8ZI3 zzl({R#AGK&#QPry({S$1%t-I!ufbho0gk}AS6cs0NVz0n# zKX=o()K??k7HTl7z+I8Ebb$1z9jxEbPL}YFOQ2>%AIt{8G*m(IZDiz7SCxq5_~{=R z-K!->O==`Sz4!;056)E3ay}q;j+csVe4~$Ny`6zL!k@hgZoW#YN3yeB@5W%LI{Mpm z7>NwR5et8W-?H6}GOXtkH=_v~<9lMGn3w$eyBUPhi#|XU_1U`M^X_*qEP>wVz3GFD zQ%==I4^GSZX;MCy$#}kMtRKDKA2pJoef}^5QC+AX!Oi6SEycJ&S)sh06wRYhXA_(W ziT%`)M%@~RFl~Zg{pU&s#^)*oxfJ#L&W-1jwt~9_goujy!^HM-ExC%bfZ{GbS8ST* zi+gRdWt!CaSI24>JwwkDfBT;as5JA-x(>fHu1OB@YKD~!c$tRQUlVyeEsYx8{{cmZ zEs!+zA4Jdo+6+9ut$rujs+P-oDP@E-qd}Hnc%z%XzH5~pD;t8=U<5mPATyVJU!b|`6#dAcH;8*%KnVU zUqzK&h#D;6P4WLa*{dZP{{=H&5kp1q7r`=>T_oI{P1i};rG_#sR#4PP5P}_j zpl)^I_u{4*{>8#;22m%v*V3@YF{w)Jvu+rtk;pW9=>0nBcAf+gLsxJ-%pqXCOuEw8ZCzH2LavPCLi4c0pJ*Xq_0HT*y|<*^u`h~sge~ZqRZ<#$N(U=U88*Z z^jGjF7go1LwI{ebk*!RCRmG1S>|Rp4Fws*VT`R8lxw;(MSIn9%O^c;eJs2$x2LD`V zLF{}`v-o8<)z4IdN3}(Ka*`3|{xQsswEYM>O6uykYgqo{kLOeKQ`Ae@GWv_hRUY;t zR(7(#jgQ9DWu<&YL~+e7&X)3OB5F_CY3${j%{!0Gh!5b5()x^BMf=g{4K1Uo7LKrV ztJsdCv8ro`L!|U;td^`6+5gsmeNXzkesr~`ybV^I6hoh{{st7(C9?{2Ic`PF$Gp^I zyqZW${IHbN6e;3w5g9X&`lIxIOsoVc0;eI$fa(%uMia)&Gfw?fv=l$_(I&z)keC;L zf8W%7#8k%YcKGNn&V>&@*Cv!eA@&1uSedg>0I{M7Wd^xieY;UUsqVldV3E7N`OM=~ zq=ZL2$UN(<&V zoyAYjny)R}l!Z2z*D}uU84k%m?)q$HORBR^Agrx`LJYeb&X( zT~VV1J#8k+oRKsH-V7#_I(H*?WV^D|BuZKpEQq?=kH@SlT2u|)9cs;g z{`L^l>hPo+`4m?8E$R8+OgrxqhF+SizqoRwJA8((~Jz5)E0VkFBbP?s*s=XGHBZ}m@gQ2`LR%Q zG+(qgxrRvIoOAvY?p^kpPkQL3M_}VUx48W>lP4@&pS$Lb+FlNNMx-G>p84Okr0$=ouHCWiX%!cl>0#$>-KzLvnK+G=hMn=-MaS_g+Xd%>|UjM7Uo(N(fSI?OgD`VClLUa{9n1s zSl}M=q#gNEL{vlTHevV4nrX*p!;%5snIH@+_EQVkoR@PspO7rc>QH?B%`+la@P>OP zM&P6cXvI2_LaEey9U7HMJ1O#d{{Jl$UY+bN3MddP4P>|suC>W`k1|pdlw(!JEcWlF%V2IEo2j%tR3eb zlt1Rb>6nQLs}c|3WwuiMN1QPcqHSlGWAp9ME|V{gF8R-o)USvXfcBCrSTcFt21WS zd#Zt1#{bQD+Q6_7%=Y2bK=q*TqyWa3gxu%!!VvK%{I*;@4)kC!Z_H-V<8-LeHa~3< z{wc-Zv(nW5{e#A%H$`U5E+X_^8D}??4^?Nd4l; zm}xc!SNP2!g7hq+27GA;0l65OW50;^D&eLw@JFPF4#JqX6Gc-y8wb?s8j;B7tKD2s8Kk6u#KKg=RyE9=kIFd)lXZq0`|DWEvJq z$_1!bz;!q+E;JUc1L{$(tP34kce4hgGj4atKP62P!MrB`jL& zkpfNMUyj+?IQpxWB6Gj9{^vFL6Nq$2^}!a0Kb_BkLznzuo#^pg4G2Mo|~oe`9P6 zdRaGQ+uv#?dz-G7tJE#{-sLg_I47wKDTYIJ!B=QqHwm_X!0GhUGsd<8e7o@|aINnZl}cHjcy-ER{70jS|KE`Rc$x9q9@gxWJmVtB89 zxwDQGaIg+Qyh>6auNS}g^@)XJ$xKW&5&wFBt9=bB;Y~e3erL0hI{`T)jOT1kKRlh& zW|RPN=Za%t2#;le4z65<|KJCHgoJfx0IiN1|H$sb&1AJzp5} z^9y(EHWA5Yjt&Xh?-|#6!cM_ zPAi98V^W9wBwe`DfE;E0$;GBFfsyA`c$2n~;+l-68-q#iX#{j`B!>??BELlm|Mp)@Ih z#J&=Yx3$cHBjP5A4Nbe$WFQmcIR0{X{B8!H#eV*L@Ka`b+~u^=9Jn)mEZ^V;o-+!~0ydKKnmW$kacN}gnuOg-mBZ@|YBA~LPyy9wet&(2vPOVvJH`tlWrT&$g z&P(60O*I&*7GwCf?$3;l#$bbI5i^#;P2Ue+SAno$yPlo2{Iu$Q9B*>fZ@S)rbHz8` zu3bdasbRvD_|n|DjTncuJA$IBB@fpv(ut@!VV_=*ruROO;6SF*WT;?@M&1sNU!HL| zuC2P$%Pvf%7}4rGPsYIHrxHUZ8eNs0+(K6W^Ck%9+-R zSB)jkKqQF`_uJdpR=WLMP1(tR#pUtC?orHm4N5pZM9Syvu602#l(aSj(v8TLDvC1n zJt|NEC!eS6`r-5FyB^Clq*RI2#~(hcvyWF)%#?kcEZn{oR4uMDy{TA)BXr{}az$e7 z@35s8mR}Y0l`!b67!jEqpA~JRLB?PX&jVcuTX&59!09_hVbxgslzYtBf{Umv;;1)$ z^BAyPXDLF{e*Vhjcr+yZTcBi(rrX`7SlKSksPRYjDmyH;rq<8D7@hWJe?J4EzA)C> z9KT{7>9J@f+x0Q(w}ix-?dq@L-||2HeN$cn*C+g406k$6N^0OCF3>gSS5YAr0OH6b z85`ZjDx}+P|5a>8=ueKhfx^o+j(q~;YbcYT48lI_F>3pu3~hRcAqjfOfZCwz$X?`< z%b9Oc*(lnrlf+=~l7df6%n4CA)MH7hA^tY8xtfuI!fO zDaqGm>f*rgJ8uZ<^3x55iaKIr4(6k>CTdhsop%`KuM=2%Hlfn}!%}EO8%jL6;cdq` zDxwmv42Y};ROpqFD@1jX84tVCj5TD9885uN;|uMtw8VUl08sApz^sfl%Rsl2aisI< z5|p$U;~`8WB`O-~L1L}1L-^R8!9;A0epH8OO(wT9cY(v?V1hkn@rJNHElhE(0%9y8 z;wrt*!3@0+GhR~HC%XYbDo|qUn=XtEPUKzCpZHMHK6+$ER(kDbKcz*zdj0C?lj3^V zUUvEP>M!`%Gj|dt*?>9OI?pt9qcdH^?wB;s@M`) zzp75XmnAgO`s4U$z0XhVC-2YkoPff6^)+(K;(_k|MCez@kfxOA{#tz#*P7KlJ`!t* zmijeF&{h~CX^~wCap_|hq$CWlPnU}T`Q0=*C$dT9UrWwPLl!XWEcUuuLpdg9K1_(C z-K&QFgQ1}W09Py?b0fKOAl&j9OXST*UFlpsYS!#IDh>DBAKW=b6Pfs|K(dZ|xjMdS z1$vU>N4t`63oD7>HxMd)U6s3YG776TC*0mu&`wa4KmP&-h$H)@D_>yX2yByH76pwull zU6JH+Bp81VNhCIyF#cAi>ucc|=z#gzQKDC+r|Uzcj}47%g5txJ004;!dQ5aovFLXwO0F-k%I3EJN9Na>wD7t)`t&{_mxS!s>X zM8OH)BPqYp?M3Q8+XX?5(FVTJWJ${v*F-}jGx4bQJrYUH#7(|N$lVCPmASdSAvfLB zv~D$6$baXK9@S&xegKzOF`KNWlGnw%Y zV>cxJXw~c&9+70w_Aj-w_iOJfoGK_#aA)`s8@=Eyp*N|~b{46uzW~!FoQ`4spgl|} zIZA0kv8fs5>Rb8b(KmIaeJB?rFRy-{uw@7#wVr4g2V<+1gtNhqZh(Xdre9g!_wfh_ zg!4o=2=;+7tNOiB1JEhizJDq*og4Y(UkzmVWjgjL(RK%0AB9N9%$YQMNsylR2)ZSR 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 literal 0 HcmV?d00001 diff --git a/po/de/docs/okular/man-okular.1.docbook b/po/de/docs/okular/man-okular.1.docbook new file mode 100644 index 0000000..c17844b --- /dev/null +++ b/po/de/docs/okular/man-okular.1.docbook @@ -0,0 +1,237 @@ + + +]> + + + + +Okular-Benutzerhandbuch +YuriChornoivan Okular-Benutzerhandbuch yurchor@ukr.net +2019-02-14 +Okular 1.7 +KDE-Anwendungen + + + +okular +1 + + + +okular +Ein Betrachter für alle Dokumente + + + +okular Okular-Optionen URL + + + +Beschreibung +okular zeigt Dokumente in verschiedenen Formaten an. + + + +Okular-Optionen + + + + + +Öffnet die angegebene Seite im Dokument. + + + + + + +Dokumentanzeige im Präsentationsmodus beginnen. + + + + + + +Startet mit dem Druckdialog. + + + + + + +Startet mit dem Druckdialog und wird nach dem Drucken beendet. + + + + + + +Nur eine Instanz des Programms verwenden. + + + + + + +Mit dieser Option startet Okular minimiert in der Kontrollleiste. + + + + + + +Sucht eine Zeichenkette im Text. + + + + + +Argumente + + + + +Die Adresse des zu öffnenden Dokuments. Bei PDF-Dokumenten kann der Name in der Form document_name#named_destination angegeben werden. Dabei ist named_destination ein bestimmter benannter Bereich im Dokument. + + + + + +Rückmeldung +Im IRC-Kanal #okular auf irc.freenode.net, über E-Mails an die Mailingliste okular-devel@kde.org oder im Internet auf der Seite <http://okular.kde.org/> + + + +Siehe auch + +Weitere ausführliche Dokumentation finden Sie unter help:/okular (geben Sie diese URL entweder im &konqueror; ein oder starten Sie khelpcenter help:/okular). +kf5options(7) +qt5options(7) +Weitere Informationen finden Sie auf der Webseite https://okular.kde.org/. + + + +Copyright +Copyright © 2002 Wilco Greven, Christophe Devriese +Copyright © 2004-2005 Enrico Ros +Copyright © 2005 Piotr Szymanski +Copyright © 2004-2012 Albert Astals Cid +Copyright © 2006-2009 Pino Toscano +Lizenz: GNU General Public License Version 2 <https://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/de/okular.po b/po/de/okular.po new file mode 100644 index 0000000..9a3360a --- /dev/null +++ b/po/de/okular.po @@ -0,0 +1,5849 @@ +# Stephan Johach , 2003, 2005. +# Stefan Winter , 2004, 2005, 2006. +# Thomas Reitelbach , 2005, 2007, 2008, 2009, 2010. +# Burkhard Lück , 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020. +# Stephan Johach , 2006. +# Frederik Schwarzer , 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2020. +# Panagiotis Papadopoulos , 2010, 2011. +# Johannes Obermayr , 2010. +# Michael Weghorn , 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-29 10:05+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, ein Betrachter für alle Dokumente" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004–2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004–2017 Albert Astals Cid\n" +"© 2006–2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Ehemaliger Betreuer" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" +"Viel Arbeit am Grundgerüst und den Anzeigemodulen für ODT und FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Entwickler" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Hat Okular auf Basis von KPDF aus der Taufe gehoben" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Entwickler von KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Design für Anmerkungen" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Tabellenauswahl" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Verbesserungen der Anmerkungen" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Gehe zu Seite %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Externe Datei öffnen" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "„%1“ ausführen ..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Erste Seite" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Vorherige Seite" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Nächste Seite" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Letzte Seite" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Zurück" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Vorwärts" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Beenden" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Präsentation starten" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Präsentation beenden" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Suchen ..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Gehe zu Seite ..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Klang abspielen ..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript-Skript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Film abspielen ..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Film abspielen" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Film anhalten" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Film anhalten" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Film wieder abspielen" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Anzeigemodul-Auswahl" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Mehr als ein Anzeigemodul für diesen MIME-Typ gefunden:
%1 " +"(%2).

Bitte wählen Sie aus, welches Modul benutzt werden soll:" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Die meisten Seiten haben das Format %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Hochformat %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Querformat %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 × %2 Zoll (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 × %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Suche vom Anfang an fortsetzen" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Suche wird vom Ende her fortgesetzt" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Es ist kein passendes Anzeigemodul für dieses Dokument verfügbar." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Anmerkungen entfernen" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dieses Dokument enthält eine Anforderung zum Ausführen eines externen " +"Programms. Aus Sicherheitsgründen wird diese Anforderung von Okular " +"ignoriert." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Kein Programm zum Öffnen des MIME-Typs %1 gefunden." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Die temporäre Datei kann nicht geöffnet werden." + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Die Druckumwandlung ist fehlgeschlagen." + +# Druckvorgang oder Druckprozess? +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Der Druckvorgang ist abgestürzt." + +# Druckvorgang oder Druckprozess? +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Der Druckvorgang lässt sich nicht starten." + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Das Drucken in eine Datei ist fehlgeschlagen." + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Der Drucker war in einem ungültigen Zustand." + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Die zu druckende Datei ist nicht auffindbar." + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Es gibt keine zu druckende Datei." + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Es kann keine passende Programmdatei für das Drucken gefunden werden. " +"Stellen Sie bitte sicher, dass die CUPS-Programmdatei „lpr“ verfügbar ist." + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Die Druckseitengröße ist ungültig" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "„%1“ kann nicht geöffnet werden. Die Datei existiert nicht." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titel" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Thema" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Beschreibung" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Erstellt von" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Ersteller" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Seiten" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Erstellt am" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Geändert am" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME-Typ" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategorie" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Schlüsselwörter" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Dateipfad" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Dateigröße" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Seitengröße" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Anmerkung hinzufügen" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Anmerkung entfernen" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Eigenschaften der Anmerkung bearbeiten" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Anmerkung verschieben" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "Anmerkung anpassen" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Text bearbeiten" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Inhalte von Anmerkungen bearbeiten" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Inhalte von Formularen bearbeiten" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Auswahl von Listenfelder bearbeiten" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Auswahl von Kombinationsfeldern bearbeiten" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Status von Formularknöpfen bearbeiten" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Einfacher &Text ..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument-Text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Druckeinstellungen" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Auf druckbaren Bereich anpassen" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Auf ganze Seite anpassen" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Skalierungsmodus:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Fehlender Warnungstyp" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Diese Meldung nicht mehr anzeigen" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Quelle: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Standardschrift:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rot" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Orange" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Gelb" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Grün" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cyan" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blau" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Weiß" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Grau" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Schwarz" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Breite %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1 %" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Anmerkungs-Linienbreite (Keine Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Anmerkungs-Farbe (Keine Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Anmerkungs-Füllfarbe (Keine Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Anmerkungs-Deckkraft (Keine Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Anmerkungs-Schriftart (Keine Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Fügt die aktuelle Anmerkung zu den Schnell-Anmerkungen hinzu (Keine " +"Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Seitenverhältnis auf 1:1 oder Linienwinkel 15°-Schritte beschränken (Keine " +"Anmerkung ausgewählt)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Erweiterte Einstellungen für die aktuelle Anmerkung (Keine Anmerkung " +"ausgewählt)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Anmerkungs-Linienbreite" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Anmerkungs-Linienbreite (Die aktuelle Anmerkung hat keine Linienbreite)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Anmerkungs-Textfarbe" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Anmerkungs-Umrandungsfarbe" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Anmerkungs-Farbe" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Anmerkungs-Füllfarbe" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "Anmerkungs-Füllfarbe (Die aktuelle Anmerkung hat keine Füllfarbe)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Anmerkungs-Schriftart" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Anmerkungs-Schriftart (Die aktuelle Anmerkung hat keine Schriftart)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Linienwinkel auf 15°-Schritte beschränken" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Seitenverhältnis auf 1:1 beschränken" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Seitenverhältnis auf 1:1 oder Linienwinkel 15°-Schritte beschränken (Von " +"der aktuellen Anmerkung nicht unterstützt)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Anmerkungs-Deckkraft" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Fügt die aktuelle Anmerkung zu den Schnell-Anmerkungen hinzu" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Erweiterte Einstellungen für die aktuelle Anmerkung" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Farbe" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Füllfarbe" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparent" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Benutzerdefinierte Farbe ..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Stempel in einem PDF-Dokument werden in anderen PDF.Anzeigeprogrammen als " +"Okular nicht angezeigt." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Experimentelle Funktion" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Farbauswahl" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Anmerkungen" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Ausblenden" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Hervorhebung" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Unterstrichen" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Schnörkel" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Durchstreichen" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Textkommentar" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Haftnotiz" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Notiz" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Freihandlinie" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Gerade Linie" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Pfeil" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rechteck" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Vieleck" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometrische Formen" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Stempel" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Schnell-Anmerkungen" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Wählen Sie eine Anmerkung aus den Schnell-Anmerkungen" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Zu Schnell-Anmerkungen hinzufügen" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Aktiviert lassen" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Die Anmerkung ist auch nach Benutzung aktiviert" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Seitenverhältnis und Winkel von Anmerkungen" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Schriftart" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Anmerkungs-Einstellungen" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Linienbreite" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Deckkraft" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Seite %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anmerkung" +msgstr[1] "%1 Anmerkungen" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "Notiz öff&nen" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Löschen" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Eigenschaften" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Speichern „%1“ ..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Erscheinungsbild" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Allgemein" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Erstellt:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Geändert:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Notiz-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Textkommentar-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Haftnotiz-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Linien-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Vieleck-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Form-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Textmarkierungs-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Stempel-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Freihandlinien-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Caret-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Eigenschaften des Dateianhangs" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Klang-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Film-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Anmerkungs-Eigenschaften" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Geändert: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Wählen Sie ein benutzerdefiniertes Stempelsymbol aus einer Datei" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Benutzerdefiniertes Stempelsymbol auswählen" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Symbol-Dateien (*.ico *.png *.xpm *.svg *." +"svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Die Datei %1 kann nicht geladen werden" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Ungültige Datei" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Farbe:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Deckkraft:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Symbol:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Kommentar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Hilfe" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Einfügen" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Taste" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Neuer Absatz" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Notiz" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Absatz" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Schrift:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Textfarbe:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Ausrichtung:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Links" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Mittig" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Rechts" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "&Rahmenbreite:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Freigegeben" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Wie vorliegend" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Vertraulich" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Abteilungsintern" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Entwurf" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimentell" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Endgültig" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Zum Kommentar" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Zur allgemeinen Veröffentlichung" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Nicht freigegeben" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Nicht zur allgemeinen Veröffentlichung" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Verkauft" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Streng geheim" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Lesezeichen" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Information" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Experimentelle FunktionStempel in einem PDF-Dokument werden in " +"anderen PDF.Anzeigeprogrammen als Okular nicht angezeigt." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Stempel-Symbol" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Breite:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Linienanfang:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Linienende:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Quadrat" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Kreis" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Raute" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Offener Pfeil" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Geschlossener Pfeil" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Kein" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Stumpfes Ende" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Offener Pfeil nach Rechts" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Geschlossener Pfeil nach Rechts" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Schrägstrich" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Länge der Führungslinie:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Länge der Führungslinien-Erweiterung:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Aktiviert" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Farbfüllung:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Typ:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Hervorhebung" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Schnörkel" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Unterstrichen" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Durchgestrichen" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rechteck" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Symbol für Dateianhang:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafik" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Reißzwecke" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Büroklammer" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Stichwort" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Datei" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/V" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Keine Beschreibung verfügbar." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Name:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Beschreibung:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Caret-Symbol:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Keines" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Diese Notiz schließen" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Einstellungen" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Diese Anmerkung kann LaTeX-Code enthalten.\n" +"Klicken Sie hier, um diesen zu verarbeiten." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Die ausführbare Datei „latex“ wurde nicht gefunden." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Verarbeitung des LaTeX-Codes ist fehlgeschlagen" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Ausführbare Datei dvipng kann nicht gefunden werden." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Bei der Ausführung des „latex“-Befehls ist ein Problem aufgetreten." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Bei der Ausführung des „dvipng“-Befehls ist ein Problem aufgetreten." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Ein Lesezeichen" +msgstr[1] "" +"%1\n" +"\n" +"%2 Lesezeichen" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Lesezeichen" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Suchen ..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Nur aktuelles Dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Zu diesem Lesezeichen gehen" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Lesezeichen umbenennen" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Lesezeichen entfernen" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Dokument öffnen" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Lesezeichen entfernen" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Version" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Seriennummer" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Aussteller" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Ausgestellt am" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Gültig bis" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Inhaber" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Öffentlicher Schlüssel" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Schlüssel-Verwendung" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 Bit)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Eigenschaft" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Wert" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Zertifikatsanzeige" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exportieren ..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Allgemein" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Ausgestellt von" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Allgemeiner Name (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-Mail" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisation (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Ausgestellt für" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Gültigkeit" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Fingerabdrücke" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1-Fingerabdruck" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256-Fingerabdruck" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Details" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Zertifikatsdaten:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Wo möchten Sie dieses Zertifikat speichern?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Zertifikatsdatei (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Das Zertifikat kann nicht exportiert werden" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rot" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Grün" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blau" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Gelb" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Schwarz" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Weiß" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "&Bilder umrahmen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "&Verknüpfungen umrahmen" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "&Farben ändern" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Warnung: diese Einstellungen können einen stark negativen Einfluss auf die " +"Darstellungsgeschwindigkeit haben." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Farbeinstellungen:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Farben umkehren" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Papierfarbe ändern" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Helle und dunkle Farben ändern" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "In Schwarzweiß umwandeln" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Helligkeit invertieren" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Luma invertieren (sRGB-Linear)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Luma invertieren (Symmetrisch)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Farbton verstärken" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Farbton abschwächen" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Papierfarbe:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Dunkle Farbe:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Helle Farbe:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Schwellwert:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Sprachausgabe" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Modul" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identität" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Hinweis: Diese Informationen werden nur für Anmerkungen verwendet. " +"Die Informationen werden in Dokumenten mit Anmerkungen gespeichert und mit " +"dem Dokument übertragen." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Schnell-Anmerkungen" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Benutzerdefinierter Texteditor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"

    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Legen Sie den Aufruf für einen benutzerdefinierten Texteditor fest.
\n" +"Dazu können auch einige Platzhalter verwendet werden:\n" +"
    \n" +"
  • %f – der Dateiname
  • \n" +"
  • %l – die anzuspringende Zeile in der Datei
  • \n" +"
  • %c – die anzuspringende Spalte in der Datei
  • \n" +"
\n" +"Wenn %f nicht angegeben wird, wird der Dateiname automatisch an den Aufruf " +"angehängt." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "Legen Sie den Editor fest, mit dem Okular Quelldateien öffnen soll." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Befehl:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Erscheinungsbild" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Weichen Bildlauf verwenden" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "&Bildlaufleisten anzeigen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "&Vorschaubilder mit der Seite verknüpfen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "&Tipps und Infomeldungen anzeigen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Dokumenttitel in der Titelleiste anzeigen, falls verfügbar" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Wenn kein Dokumenttitel angezeigt wird:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Nur Dateinamen anzeigen" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Vollständigen Dateipfad anzeigen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Benutzerdefinierte Hintergrundfarbe verwenden" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Programmfunktionen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Neue Dateien in Un&terfenstern öffnen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" +"Zum vorhandenen Unterfenster wechseln, wenn die Datei bereits geöffnet ist." + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&DRM-Beschränkungen beachten" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "Geänderte Dokumentdateien neu &laden" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Auswahldialog für Anzeigemodule anzeigen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Leserichtung von rechts nach links" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Ansichtseinstellungen" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Übersi&chtsspalten:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Legt fest, wieviel des aktuell sichtbaren Bereichs noch sichtbar ist, " +"nachdem eine der Tasten „Bild auf/ab“ betätigt wurde." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Überschneidung für die Tasten „Bild auf/ab“:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr " %" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Legt die Vergrößerung für Dateien fest, die zum ersten Mal geöffnet werden.\n" +"Alle bereits vorher geöffneten Dateien werden in der letzten benutzen " +"Vergrößerungsstufe angezeigt." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Legt die Vergrößerung für Dateien fest, die zum ersten Mal geöffnet werden.\n" +"Alle bereits vorher geöffneten Dateien werden in der letzten benutzen " +"Vergrößerungsstufe angezeigt." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Standardvergrößerung:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100 %" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Seitenbreite" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Ganze Seite" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automatisch einpassen" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Es wird so wenig Arbeitsspeicher wie möglich belegt. Es werden keine " +"Komponenten wiederverwendet. (Für Systeme mit wenig Arbeitsspeicher.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Ein Kompromiss zwischen Arbeitsspeicherbelegung und Geschwindigkeit. Die " +"nächste Seite wird im Voraus geladen und die Suche geht schneller. " +"(Typischerweise für Systeme mit 2 GB Arbeitsspeicher.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Alle Komponenten werden im Arbeitsspeicher gehalten. Nachfolgende Seiten " +"werden im Voraus geladen. Die Suche wird beschleunigt. (Für Systeme mit 4 GB " +"und mehr Arbeitsspeicher.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Alles wird geladen und im Speicher gehalten. Alle Seiten werden im Voraus " +"geladen. (Hierbei wird maximal die Hälfte Ihres Arbeitsspeichers oder Ihres " +"freien Speichers verwendet, je nachdem, welcher Wert größer ist.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "CPU-Ausnutzung" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "&Transparenzeffekte aktivieren" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Speicherbelegung" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Gering" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Normal (Voreinstellung)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Aggressiv" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Gierig" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rendern" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Kantenglättung für Text aktivieren" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Kantenglättung Grafik aktivieren" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Hinting für Text aktivieren" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Aktueller Bildschirm" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Standard-Bildschirm" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Bildschirm %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " Sekunde" +msgstr[1] " Sekunden" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigation" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Weitergehen alle:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Nach der letzten Seite von vorn beginnen" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Touch-Navigation" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Links/Rechts tippen um zurück/vorwärts zu gehen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Irgendwo tippen um vorwärts zu gehen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Deaktiviert" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Hintergrundfarbe:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Mauszeiger:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Nach Verzögerung ausblenden" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Immer sichtbar" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Immer ausgeblendet" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "&Fortschrittsanzeige einblenden" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "&Zusammenfassung anzeigen" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Übergänge aktivieren" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Standardübergang:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Vertikal einfliegen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Horizontal einfliegen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Rechtecküberblendung nach innen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Rechtecküberblendung nach außen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Auflösen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Überblenden" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Heruntertröpfeln lassen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Nach rechts tröpfeln lassen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Nach rechts unten tröpfeln lassen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Zufälliger Übergang" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Ersetzen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Horizontal nach innen teilen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Horizontal nach außen teilen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Vertikal nach innen teilen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Vertikal nach außen teilen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Nach unten auswischen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Nach rechts auswischen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Nach links auswischen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Nach oben auswischen" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Platzierung" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Bildschirm:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Einrichtung des Zeichenwerkzeugs" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Zeichenwerkzeug: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Radierer" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Name:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Typ:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Notiz" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Haftnotiz" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Freihandlinie" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Gerade Linie" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Vieleck" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Textmarkierung" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrische Form" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Stempel" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Textkommentar" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Anmerkungs-Werkzeug erstellen" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Anmerkungs-Werkzeug bearbeiten" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Farbe:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Stiftbreite:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Zeichenwerkzeug erstellen" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Zeichenwerkzeug bearbeiten" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Unbekannt" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Eingebettete Dateien" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Ansicht" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Name" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Beschreibung" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Größe" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Erstellt am" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Geändert am" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Speichern &unter ..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Ansicht ..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Die Druckvorschau-Komponente kann nicht geladen werden." + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Druckvorschau" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Schließen" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Suchen" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Suchtext" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Weiter" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Gehe zur nächsten Fundstelle" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Zurück" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Gehe zur vorherigen Fundstelle" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Suchverhalten ändern" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Groß-/Kleinschreibung beachten" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Von aktueller Seite" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Beim Eintippen suchen" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Alle Dateien" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Signatur-Eigenschaften" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Gerade Linie mit Kommentar" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Vieleck mit Kommentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Form mit Kommentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Form" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Hervorhebung mit Kommentar" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Schnörkel mit Kommentar" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Unterstrichener Text mit Kommentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Durchgestrichener Text mit Kommentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Durchstreichen" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Stempel mit Kommentar" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Freihandlinie mit Kommentar" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Caret" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Dateianhang" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Klang" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Bildschirm" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Bedienelement" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rich Media" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Unbekannt" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Wo soll %1 gespeichert werden?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" +"„%1“ kann nicht zum Schreiben geöffnet werden. Die Datei wurde nicht " +"gespeichert." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Sucheinstellungen" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Groß-/Kleinschreibung beachten" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regulärer Ausdruck" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Suchen:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Ebenen" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "von" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Skalierung" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Auf 100 % vergrößern" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "&Rechts drehen" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Rechts" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "&Links drehen" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Links" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Ursprüngliche Ausrichtung" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Ansicht stutzen" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Ränder s&tutzen" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Auf Auswahl &stutzen" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Seiten&breite" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Ganze &Seite" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automatisch einpassen" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Fenster auf Se&ite einpassen" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Anzeigemodus" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Einzelne &Seite" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "&Gegenüberliegende Seiten" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Gegenüberliegende Seiten (&erste Seite zentrieren)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Übersicht" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Fortlaufend" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Leserichtung von rechts nach links" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Durchsuchen" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "„Farben ändern“ umschalten" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Bereichsauswahl" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Textauswahl" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "&Tabellenauswahl" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lupe" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Auswahlwerkzeuge" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Gesamtes Dokument vorlesen" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Aktuelle Seite vorlesen" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Vorlesen anhalten" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Vorlesen anhalten / fortsetzen" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Nach oben" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Nach unten" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Eine Seite nach oben" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Eine Seite nach unten" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Formulare anzeigen" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Ein Dokument mit einer Seite ist geladen worden." +msgstr[1] " Ein Dokument mit %1 Seiten ist geladen worden." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Text (1 Buchstabe)" +msgstr[1] "Text (%1 Buchstaben)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "In die Zwischenablage kopieren" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopieren durch digitale Rechteverwaltung (DRM) verboten" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Text vorlesen" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Bild (%1 × %2 Pixel)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "In Datei speichern ..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Bild [%1 × %2] ist in die Zwischenablage kopiert worden." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Datei speichern" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Bilder (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Datei nicht gespeichert." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Bild [%1 × %2] ist in Datei (%3) gespeichert worden." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Text kopieren" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Gehe zu „%1“" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Nach „%1“ suchen mit" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Web-Kürzel einrichten ..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Verknüpfungsadresse aufrufen" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Diesen Klang abspielen" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Wiedergabe anhalten" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Verknüpfungsadresse kopieren" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Nach „%1“ im diesem Dokument suchen" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Willkommen" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Wählen Sie den zu vergrößernden Bereich. Ein Rechtsklick verkleinert." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Klicken Sie, um die vergrößerte Ansicht zu sehen." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Ziehen Sie mit der Maus ein Rechteck um den zu kopierenden Bereich." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Wählen Sie Text aus" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Ziehen Sie mit der Maus ein Rechteck um die Tabelle, klicken Sie dann zur " +"Aufteilung auf die nächsten Kanten, drücken Sie die Taste ESC zum Löschen." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Ziehen Sie mit der Maus ein Rechteck um den Bereich der Seite, der sichtbar " +"bleiben soll.." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Neue Textnotiz" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Text der neuen Notiz:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Lesezeichen für Anmerkung" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Geben Sie einen eigenen Namen für die Anmerkung an:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "" +"Ellipse zeichnen (Ziehen Sie mit der Maus, um einen Bereich auszuwählen)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Text hervorheben" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Eine Freihandlinie zeichnen" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "" +"Freitext-Anmerkung (Ziehen Sie mit der Maus, um einen Bereich auszuwählen)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Fügt eine Notiz ein" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "" +"Zeichnet ein Vieleck (Klicken Sie auf den ersten Punkt zum Abschließen)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Ein Rechteck zeichnen" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Verschnörkelter Text" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Positioniert einen Stempel" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Eine gerade Linie zeichnen" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Text durchstreichen" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Text unterstreichen" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" +"Textkommentar-Anmerkung (Ziehen Sie mit der Maus, um einen Bereich " +"auszuwählen)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Hervorhebung" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Bevorzugte Anmerkung hinzufügen" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Benutzerdefinierter Anmerkungsname:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Datei" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Einstellungen" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Hilfe" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "Aus&richtung" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Lesezeichen" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Anzeige-Werkzeugleiste" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Vorschaubilder" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anmerkungen" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Dieses Dokument enthält Anmerkungen und Formulardaten, die von einer " +"früheren Okular-Version intern gespeichert wurde. Die interne Speicherung " +"wird nicht länger unterstützt
. Bitte Speichern Sie das Dokument, " +"wenn Sie es weiter bearbeiten möchten." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files.
Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Dieses Dokument enthält eingebettete Dateien. Klicken Sie hier zur Anzeige oder rufen Sie den Menüeintrag " +"„Eingebettete Dateien“ aus dem Menü „Datei“ auf." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Vorherige Seite" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Zurück zur vorherigen Seite" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Geht zur vorherigen Seite des Dokuments" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Nächste Seite" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Weiter zur nächsten Seite" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Geht zur nächsten Seite des Dokuments" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Anfang des Dokuments" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Geht zum Anfang des Dokuments" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Ende des Dokuments" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Geht zum Ende des Dokuments" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Das aktuelle Lesezeichen umbenennen" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Vorheriges Lesezeichen" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Zum vorherigen Lesezeichen gehen" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Nächstes Lesezeichen" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Zum nächsten Lesezeichen gehen" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Okular einrichten ..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Betrachter einrichten ..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Anzeigemodule einrichten ..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Anzeigemodule einrichten ..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Über Anzeigemodul" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Neu &laden" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Lädt das aktuelle Dokument erneut vom Datenträger." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Suchleiste sch&ließen" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Seitenzahl" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Gesamten Text der aktuellen Seite auswählen" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Se&itenleiste anzeigen" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "&Seitendarstellungsleiste anzeigen" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "&Signaturbereich anzeigen" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Ein&gebettete Dateien" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xportieren als" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Veröffentlic&hen" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&Präsentation" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Ordner mi&t diesem Inhalt öffnen" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "PostScript als PDF &importieren ..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Bücher aus dem Internet holen ..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Schwarzschirm-Modus umschalten" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Zeichnung löschen" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Anmerkungen einrichten ..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Präsentation anhalten/wiedergeben" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "„%1“ kann nicht geöffnet werden (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Das Laden von %1 ist abgebrochen worden." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "%1 kann nicht geöffnet werden. Der Grund lautet: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Anzeigemodule einrichten" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Anzeigemodule einrichten" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Das Programm „ps2pdf“ kann nicht gefunden werden, daher kann Okular keine PS-" +"Dateien importieren." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf nicht gefunden" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript-Dateien (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "PS-Dateien werden als PDF importiert (kann eine Weile dauern) ..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Bitte geben Sie das Passwort zum Lesen des Dokuments ein:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Falsches Passwort, bitte versuchen Sie es erneut:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Dokument-Passwort" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Dies Dokument enthält XFA-Formulare, die zurzeit nicht unterstützt " +"werden." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Dieses Dokument enthält Formulare. Klicken Sie auf diesen Knopf, um sie zu " +"verwenden, oder rufen Sie den Menüeintrag „Formulare anzeigen“ aus dem Menü " +"„Ansicht“ auf." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Alle Bearbeitungs- und Interaktionsfunktionen für dieses Dokument sind " +"deaktiviert. Bitte speichern Sie eine Kopie und öffnen sie neu, um dieses " +"Dokument zu bearbeiten." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Dieses Dokument ist digital signiert." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Dieses Dokument ist digital signiert. Es gibt Änderungen seit dem letzten " +"Signieren." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Dieses Dokument ist digital signiert. Einige dieser Signaturen können nicht " +"auf Gültigkeit überprüft werden." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Dieses Dokument möchte im Vollbildmodus angezeigt werden.\n" +"Möchten Sie den normalen Modus verlassen und in den Präsentationsmodus " +"wechseln?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Anfrage zur Änderung des Anzeigemodus" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Präsentationsmodus starten" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Anfrage verweigern" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "„%1“ kann nicht geöffnet werden (%2)" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Es gibt ungespeicherte Änderungen, aber die Datei „%1“ wurde durch ein " +"anderes Programm geändert. Ihre Änderungen werden verworfen, da die Datei " +"nicht mehr gespeichert werden kann.
Möchten Sie fortfahren und die Datei " +"neu laden?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Datei geändert" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Neu Laden fortsetzen" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Neu Laden abbrechen" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Es gibt ungespeicherte Änderungen, aber die Datei „%1“ wurde durch ein " +"anderes Programm geändert. Ihre Änderungen werden verworfen, da die Datei " +"nicht mehr gespeichert werden kann.
Möchten Sie fortfahren und die Datei " +"schließen?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Schließen fortsetzen" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Schließen abbrechen" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Möchten Sie Ihre Änderungen an „%1“ speichern oder verwerfen?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Dokument schließen" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Diese Verknüpfung fordert das Schließen des Dokuments an. Dies ist unter " +"Verwendung des eingebetteten Betrachters nicht möglich." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Diese Verknüpfung fordert das Beenden des Programms an. Dies ist unter " +"Verwendung des eingebetteten Betrachters unmöglich." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Dokument wird neu geladen ..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Inhalt" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signaturen" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Gehe zu Seite" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Seite:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Geben Sie den Namen des Lesezeichens ein:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Diese Lesezeichen umbenennen" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Dieses Lesezeichen entfernen" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Speichern unter" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Die Datei „%1“ wurde durch ein anderes Programm geändert, daher kann sie " +"nicht mehr gespeichert werden." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Das aktuelle Dokument ist durch ein Passwort geschützt.
Um es zu " +"speichern, muss die Datei neu geladen werden. Das Passwort wird wieder " +"abgefragt und der Verlauf von Zurücknehmen/Wiederherstellen geht verloren." +"
Möchten Sie fortfahren?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Speichern - Warnung" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Die temporäre Datei kann nicht zum Speichern geöffnet werden." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Nach dem Speichern muss die Datei wegen des aktuellen Dokumentformats neu " +"geladen werden. Der Verlauf von Zurücknehmen/Wiederherstellen geht verloren." +"
Möchten Sie fortfahren?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Datei kann nicht in „%1“ gespeichert werden. Versuchen Sie einen anderen " +"Speicherort." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Ausgefüllte Inhalte von Formularen" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Benutzer-Anmerkungen" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Sie sind dabei, Änderungen zu speichern, aber die folgenden Elemente können " +"im aktuellen Dateiformat nicht gespeichert werden. Bitte benutzen Sie das " +"Format Okular-Dokumentarchiv, um diese Elemente zu behalten." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Warnung" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Als Okular-Dokumentarchiv speichern ..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Sie sind dabei, Änderungen zu speichern, aber die folgenden Elemente können " +"im aktuellen Dateiformat nicht gespeichert werden. Bitte benutzen Sie das " +"Format Okular-Dokumentarchiv, um diese Elemente zu behalten. Klicken " +"Sie auf Fortsetzen, um das Dokument zu speichern und dabei diese " +"Elemente zu verwerfen." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Sie sind dabei, Änderungen zu speichern, aber die folgenden Elemente können " +"im aktuellen Dateiformat nicht gespeichert werden. Bitte benutzen Sie das " +"Format Okular-Dokumentarchiv, um diese Elemente zu behalten. Klicken " +"Sie auf Fortsetzen, um das Dokument zu speichern, aber Sie werden " +"diese Elemente und den Verlauf von Zurücknehmen/Wiederherstellen verlieren." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Fortsetzen" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Fortsetzen und alle Änderungen verwerfen" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Datei kann nicht in „%1“ gespeichert werden. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular kann %1 nicht an das angegebene Ziel kopieren.\n" +"\n" +"Das Dokument ist nicht mehr vorhanden." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Datei kann nicht in „%1“ gespeichert werden. Fehler „%2“. Versuchen Sie " +"einen anderen Speicherort." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Gesamten Abschnitt ausklappen" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Gesamten Abschnitt einklappen" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Alle ausklappen" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Alle einklappen" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Lesezeichen hinzufügen" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Extras" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Drucken" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Es ist nicht erlaubt, dieses Dokument zu drucken." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Das Dokument kann aufgrund eines unbekannten Fehlers nicht gedruckt werden. " +"Bitte melden Sie das Problem unter http://bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Das Dokument kann nicht gedruckt werden. Die genaue Fehlermeldung lautet: " +"„%1“. Bitte melden Sie das Problem unter http://bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Geht zurück zur vorher angezeigten Stelle im Dokument" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Geht vor zur nächsten angezeigten Stelle im Dokument" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Dateifehler! Die temporäre Datei %1 kann nicht angelegt werden." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Dateifehler! Die temporäre Datei %1 kann nicht zum Dekomprimieren geöffnet werden. Die Datei wird " +"nicht geladen. " + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Typischerweise tritt dieses Problem auf, wenn Ihre Rechte nicht zum " +"Lesen der Datei ausreichen. Sie können Besitzer und Berechtigungen " +"überprüfen, indem Sie in der Dateiverwaltung Dolphin mit der rechten " +"Maustaste auf die Datei klicken und dann „Eigenschaften“ im Kontextmenü " +"aufrufen und zur Karteikarte „Berechtigungen“ im Dialog gehen." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Dateifehler! Die Datei %1 " +"kann nicht dekomprimiert werden. Sie wird nicht geladen." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Typischerweise tritt dieses Problem auf, wenn die Datei beschädigt ist. " +"Wenn Sie sicher sein möchten, versuchen Sie, die Datei mit Hilfe von " +"Befehlszeilen-Werkzeugen selbst zu dekomprimieren." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Keine Lesezeichen" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Beim Veröffentlichen des Dokuments ist ein Fehler aufgetreten: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Veröffentlichen" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Dokument erfolgreich veröffentlicht" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Sie finden das veröffentlichte Dokument unter: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Bearbeiten" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Ansicht" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Gehe zu" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "E&xtras" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Haupt-Werkzeugleiste" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Anmerkungs-Werkzeugleiste" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Allgemeine Einstellungen" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Zugangshilfen" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Zugangshilfen für das Lesen" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Leistung" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Leistungsverbesserung" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Betrachter einrichten" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Präsentation" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Einstellungen für den Präsentationsmodus" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Anmerkungs-Einstellungen" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Editor-Einstellungen" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Weitersuchen" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Präsentation" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Bildschirm wechseln" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Bildschirm %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Präsentationsmodus beenden" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titel: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Seiten: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klicken Sie, um zu beginnen" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Anhalten" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Wiedergeben" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Es gibt zwei Wege, den Präsentationsmodus zu verlassen. Sie können Esc " +"drücken oder auf das Symbol „Beenden“ drücken, das erscheint, wenn Sie den " +"Mauszeiger an den oberen Bildschirmrand bewegen. Sie können natürlich auch " +"das Fenster wechseln (die Voreinstellung dafür ist Alt+Tabulator)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Während einer Präsentation" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Unbekannte Datei" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1-Eigenschaften" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Schriftarten" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Schriftinformationen werden eingelesen ..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Seitengröße" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "Schrift &entpacken" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Typ 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Typ 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Typ 1C (OpenType)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Typ 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OpenType)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Typ 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Typ 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Typ 0C (OpenType)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OpenType)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtuell" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font-Metrik" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-bearbeitet" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Unbekannt" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Eingebettet (teilweise)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Vollständig eingebettet" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Nein" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Ja (teilweise)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Ja" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (ersetzt durch %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "entfällt" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Unbekannte Schrift" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Eingebettet: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Name" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Typ" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Datei" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Seite" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Größe" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Revisionsvorschau" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Wo möchten Sie diese Revision speichern?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Die Datei „%1“ lässt sich nicht speichern." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Die Revision kann nicht angezeigt werden." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Geben Sie mindestens drei Buchstaben zum Filtern der Seiten ein" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Groß-/Kleinschreibung beachten" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Ganzen Text finden" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Alle Wörter finden" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Beliebiges Wort finden" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Filter-Einstellungen" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Keine Anmerkungen

Um neue Anmerkungen einzufügen, " +"drücken Sie F6 oder wählen Sie Anmerkungen aus dem Menü Extras." +"
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Nach Seiten gruppieren" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Nach Autor gruppieren" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Nur Anmerkungen für die aktuelle Seite anzeigen" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Alle Elemente ausklappen" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Alle Elemente einklappen" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Die Signatur ist kryptografisch gültig." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Die Signatur ist kryptografisch ungültig." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Prüfsumme passt nicht" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Die Signaturstruktur CMS/PKCS7 ist ungültig." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Die angeforderte Signatur ist nicht in der Datei enthalten." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Die Signatur kann nicht überprüft werden." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Das Zertifikat ist vertrauenswürdig." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Der Aussteller des Zertifikats ist nicht vertrauenswürdig." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Der Aussteller des Zertifikats ist unbekannt." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Das Zertifikat wurde widerrufen." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Das Zertifikat ist abgelaufen." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Das Zertifikat wurde noch nicht überprüft." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Unbekanntes Problem mit dem Zertifikat oder ungültige Daten." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA-1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA-256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA-384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA-512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA-224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Unbekannter Algorithmus" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Unbekannter Typ" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digitale Signatur" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Nachweisbarkeit" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Schlüssel verschlüsseln" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Schlüssel entschlüsseln" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Schlüssel-Übereinkunft" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Zertifikat signieren" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL signieren" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Nur verschlüsseln" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Keine Verwendung angegeben" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Signiert von %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Signatur-Datum %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Nicht verfügbar" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Grund: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Feld: %1 auf Seite %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Eigenschaften" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Das Dokument wurde geändert, seit es signiert wurde." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Die Revision des Dokuments, das durch diese Signatur abgedeckt war, wurde " +"nicht bearbeitet.\n" +"Es wurden jedoch nachträgliche Änderungen am Dokument vorgenommen." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Das Dokument wurde auf eine Art geändert, die eine vorherige Signatur nicht " +"erlaubt ist." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" +"Die Überprüfung der Integrität des Dokuments kann nicht vollständig " +"durchgeführt werden." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Gültigkeitsstatus" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Gültigkeit der Signatur:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Änderungen am Dokument:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Zusätzliche Informationen" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signiert von:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Signatur-Datum:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Grund:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Ort:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Dokumentversion" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Dokumentversion %1 von %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Signierte Version anzeigen ..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Zertifikat ansehen ..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Nur Lesezeichen-Seiten anzeigen" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Abspielen" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pause" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Anhalten" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Hinzufügen ..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Bearbeiten ..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Entfernen" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Nach &oben" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Nach &unten" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Standard-Zeichenwerkzeug #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" +"Es gibt bereits ein Werkzeug mit diesem Namen. Es wird ein Standard-Name " +"verwendet." + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Name bereits vergeben" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Anzuzeigende Seite des Dokuments" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Dokumentanzeige im Präsentationsmodus beginnen" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Startet mit dem Druckdialog" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Startet mit dem Druckdialog und wird nach dem Drucken beendet" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Nur eine Instanz des Programms verwenden" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Fenster nicht nach vorn holen" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Sucht eine Zeichenkette im Text" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"Zu öffnende Dokumente. Mit „-“ wird aus der Standardeingabe (stdin) gelesen." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Fehler: Mit der Option „--unique“ kann nicht mehr als ein Dokument " +"gleichzeitig geöffnet werden." + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Fehler: Mit der Option „--presentation“ kann nicht mehr als ein Dokument " +"gleichzeitig geöffnet werden." + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Fehler: Mit der Option „--print“ kann nicht mehr als ein Dokument " +"gleichzeitig geöffnet werden" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Fehler: Mit der Option „--page kann nicht mehr als ein Dokument gleichzeitig " +"geöffnet werden" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Fehler: Mit der Option „--find“ kann nicht mehr als ein Dokument " +"gleichzeitig geöffnet werden" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Die Okular-Komponente wurde nicht gefunden: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Es läuft bereits eine einzigartig Instanz von Okular, aber das ist nicht " +"diese Instanz." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Die Okular-Komponente kann nicht gefunden werden." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Klicken Sie, um eine Datei zu öffnen.\n" +"Klicken und gedrückt halten, um eine kürzlich geöffnete Datei zu öffnen." + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klicken Sie, um eine Datei zu öffnen, oder klicken und halten Sie " +"gedrückt, um eine kürzlich geöffnete Datei zu öffnen." + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Nächstes Unterfenster" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Vorheriges Unterfenster" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Unterfenster wieder herstellen" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Alle Dateien (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Alle unterstützten Dateien (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Dokument öffnen" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Schließen bestätigen" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Unterfenster schließen" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"Sie sind dabei, die %1 Unterfenster zu schließen. Möchten Sie wirklich " +"fortfahren?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Beim Schließen mehrerer Unterfenster warnen" + +#~ msgid "Reviews" +#~ msgstr "Anmerkungen" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Formulare ausblenden" + +#~ msgid "Expired" +#~ msgstr "Abgelaufen" + +#~ msgid "&Review" +#~ msgstr "&Rezension" + +#~ msgid "Annotations author" +#~ msgstr "Autor der Anmerkungen" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Bitte geben Sie Ihren Namen oder Initialen ein:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "&Navigationsbereich anzeigen" + +#~ msgid "Show Text" +#~ msgstr "Text anzeigen" + +#~ msgid "Small Icons" +#~ msgstr "Kleine Symbole" + +#~ msgid "Normal Icons" +#~ msgstr "Normale Symbole" + +#~ msgid "Large Icons" +#~ msgstr "Große Symbole" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Klicken Sie, um das aktuelle Auswahlwerkzeug zu benutzen\n" +#~ "Klicken Sie auf den Pfeil, um ein anderes Auswahlwerkzeug einzustellen" + +#~ msgid "Created: %1" +#~ msgstr "Erstellt: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Führungslinien-Erweiterungen" + +#~ msgid "Style" +#~ msgstr "Stil" + +#~ msgid "&Size:" +#~ msgstr "Linien&breite:" + +#~ msgid "Inner color:" +#~ msgstr "Füllfarbe:" + +#~ msgid "Name: %1" +#~ msgstr "Name: %1" + +#~ msgid "Size: %1" +#~ msgstr "Größe: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Navigation" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Lupe" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Lupe" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Auswahl" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Textauswahl" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Tabellen&auswahl" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Lupe" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Ende des Dokuments" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Keines" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Das Dokument soll im Präsentationsmodus angezeigt werden, weil dies im " +#~ "Dokument angefordert wurde.\n" +#~ "Möchten Sie dies zulassen?" + +#~ msgid "Presentation Mode" +#~ msgstr "Präsentationsmodus" + +#~ msgid "Allow" +#~ msgstr "Zulassen" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Präsentationsmodus zulassen" + +#~ msgid "Do Not Allow" +#~ msgstr "Ablehnen" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Dokumentanzeige im Präsentationsmodus ablehnen" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Ihre Änderungen an den Anmerkungen werden nicht automatisch gespeichert. " +#~ "Benutzen\n" +#~ "Sie „Datei -> Speichern unter ...“ damit Ihre Änderungen nicht verloren " +#~ "gehen." + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Ihre Anmerkungen werden intern von Okular gespeichert.\n" +#~ "Sie können das Dokument inklusive der Anmerkungen mit „Datei -> " +#~ "Exportieren als -> Dokumentarchiv“ speichern." + +#~ msgid "Save &Copy As..." +#~ msgstr "&Kopie speichern unter ..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Ihre Anmerkungen werden nicht exportiert.\n" +#~ "Sie können das Dokument einschließlich der Anmerkungen mit „Datei -> " +#~ "Exportieren als -> Dokumentarchiv“ speichern." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Das Ende des Dokuments wurde erreicht.\n" +#~ "Am Anfang fortsetzen?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Anfang des Dokuments wurde erreicht.\n" +#~ "Am Ende fortsetzen?" + +#~ msgid "Current maintainer" +#~ msgstr "Aktueller Betreuer" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " Sekunden" + +#~ msgid "Pencil color:" +#~ msgstr "Stiftfarbe:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "Querformat DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "Hochformat DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "Querformat DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "Hochformat DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "Querformat DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "Hochformat DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "Querformat DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "Hochformat DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "Querformat DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "Hochformat DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "Querformat DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "Hochformat DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "Querformat DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "Hochformat DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "Querformat DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "Hochformat DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "Querformat DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "Hochformat DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "Querformat DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "Hochformat DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "Querformat DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "Hochformat DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "Querformat DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "Hochformat DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "Querformat DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "Hochformat DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "Querformat DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "Hochformat DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "Querformat DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "Hochformat DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "Querformat DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "Hochformat DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "Querformat DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "Hochformat DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "Querformat DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "Hochformat DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "Querformat DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "Hochformat DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "Querformat DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "Hochformat DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "Querformat DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "Hochformat DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "Letter-Querformat" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "Letter-Hochformat" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "Legal-Querformat" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "Legal-Hochformat" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "Executive-Querformat" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "Executive-Hochformat" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "Querformat Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "Hochformat Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "Querformat DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "Hochformat DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "Folio-Querformat" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "Folio-Hochformat" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "Ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "Tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "Unbekannte Querformat-Papiergröße" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "Unbekannte Hochformat-Papiergröße" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Zeichenmodus umschalten" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Das Starten des Sprachausgabedienstes Jovie ist fehlgeschlagen: %1" + +#~ msgid "Search Columns" +#~ msgstr "Spalten durchsuchen" + +#~ msgid "All Visible Columns" +#~ msgstr "Alle sichtbaren Spalten" + +#~ msgid "No document opened." +#~ msgstr "Kein Dokument geöffnet." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Es kann nicht mehr als ein Dokument in einer einzigartigen Instanz von " +#~ "Okular geöffnet werden." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Keine Übereinstimmung für „%1“." + +#~ msgid "Search in progress..." +#~ msgstr "Suche läuft ..." + +#~ msgid "Searching for %1" +#~ msgstr "Suche nach %1" + +#~ msgid "Identity Settings" +#~ msgstr "Einstellungen zur Identität" + +#~ msgid "Highlight Properties" +#~ msgstr "Hervorhebungs-Eigenschaften" + +#~ msgid "Ink Properties" +#~ msgstr "Farb-Eigenschaften" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Text-Anmerkung" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Grüner Stift" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Gelber Textmarker" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Gelber Textmarker" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Gerade gelbe Linie" + +#~ msgid "Black Underlining" +#~ msgstr "Schwarz unterstrichen" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Unterstreicht Text mit einem schwarzen Strich" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Cyan-farbene Ellipse" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Eine cyan-farbene Ellipse" + +#~ msgid "Ink" +#~ msgstr "Farbe" + +#~ msgid "Enable &background generation" +#~ msgstr "&Erzeugung im Hintergrund einschalten" + +#~ msgid "Reset Forms" +#~ msgstr "Formulare zurücksetzen" + +#~ msgid "latex failed." +#~ msgstr "„latex“ ist fehlgeschlagen." + +#~ msgid "dvipng failed." +#~ msgstr "„dvipng“ ist fehlgeschlagen." + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Geht zur ersten Seite des Dokuments" + +#~ msgid "You must set this name:" +#~ msgstr "Sie müssen diesen Namen festlegen:" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Schaltet zwischen Dateipfad und Titel um" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "Ü&berschreiben" + +#~ msgid "Pages:" +#~ msgstr "Seiten:" diff --git a/po/de/okular_chm.po b/po/de/okular_chm.po new file mode 100644 index 0000000..ab7fd60 --- /dev/null +++ b/po/de/okular_chm.po @@ -0,0 +1,59 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-09-15 10:10+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.04.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Nicht unterstützte Kodierung" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Die Kodierung diese E-Books wird derzeit noch nicht unterstützt. Bitte " +"schreiben Sie einen Fehlerbericht auf https://bugs.kde.org, um dies zu ändern" + +#~ msgid "CHM Backend" +#~ msgstr "Anzeigemodul für CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Darstellungsprogramm für Hilfedateien aus Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005–2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/de/okular_comicbook.po b/po/de/okular_comicbook.po new file mode 100644 index 0000000..0a1f8a2 --- /dev/null +++ b/po/de/okular_comicbook.po @@ -0,0 +1,58 @@ +# Burkhard Lück , 2008, 2013, 2018. +# Panagiotis Papadopoulos , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-15 05:56+0100\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Das Dokument lässt sich nicht öffnen, da das Programm unrar noch unarchiver " +"nicht gefunden wurde." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Mit der Version des Programms unrar auf Ihren System können keine Comic-" +"Books geöffnet werden." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Unbekanntes Comic-Book-Format." + +#~ msgid "ComicBook Backend" +#~ msgstr "Anzeigemodul für Comic-Book" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Ein Renderer für verschiedene Comic-Book-Formate" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/de/okular_djvu.po b/po/de/okular_djvu.po new file mode 100644 index 0000000..9476e2c --- /dev/null +++ b/po/de/okular_djvu.po @@ -0,0 +1,136 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-11-03 22:16+0100\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Bearbeiter" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Veröffentlicher" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Satz" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Dokumenttyp" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Unbekannt" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Komponenten-Dateien" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Unbekannt" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Einzelne Seite" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Gebündelt" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirekt" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Gebündelt (alt)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indiziert (alt)" + +#~ msgid "DjVu Backend" +#~ msgstr "Anzeigemodul für DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Anzeigemodul für DjVu auf der Basis von DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006–2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgid "A DjVu backend" +#~ msgstr "Ein Anzeigemodul für DjVu" diff --git a/po/de/okular_dvi.po b/po/de/okular_dvi.po new file mode 100644 index 0000000..8f5bcd1 --- /dev/null +++ b/po/de/okular_dvi.po @@ -0,0 +1,845 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2007, 2008, 2009, 2013, 2014, 2019. +# Frederik Schwarzer , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-08-22 08:11+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Das Programm dvipdfm kann nicht auf Ihrem System gefunden " +"werden, ist aber für die Export-Funktion erforderlich. Sie können die DVI-" +"Datei jedoch in eine PDF-Datei umwandeln, indem Sie die Druckfunktion " +"verwenden. Damit ergeben sich in der Regel gute Druckresultate, aber die " +"Anzeige im Acrobat Reader ist zumeist von geringer Qualität. Sie sollten " +"eine Aktualisierung Ihrer TeX-Distribution in Erwägung ziehen, die den " +"Befehl dvipdfm enthält.

Hinweis: Okular verwendet die " +"Umgebungsvariable „PATH“ für die Suche nach externen Programmen.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Das für den Export der Datei verwendete externe Programm „dvipdfm“ hat " +"einen Fehler gemeldet. Die genaue Fehlermeldung finden Sie im Dialog " +"Eigenschaften im Menü „Datei“." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Diese DVI-Datei verweist auf externe Grafikdateien, die nicht im " +"PostScript-Format vorliegen. Diese können nicht von dvips " +"verarbeitet werden, das Okular intern verwendet, um zu drucken oder nach " +"PostScript zu exportieren. Die von Ihnen benötigte Funktionalität ist daher " +"in dieser Version von Okular nicht verfügbar." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Das Programm dvips ist auf Ihrem System nicht verfügbar. Es " +"wird jedoch für die Export-Funktion benötigt.

Hinweis: Okular " +"verwendet die Umgebungsvariable „PATH“ für die Suche nach externen " +"Programmen.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Das externe Programm „dvips“, das zum Exportieren der Datei benutzt " +"worden ist, hat einen Fehler gemeldet. Eine ausführlichere " +"Fehlerbeschreibung finden Sie im Dialog Eigenschaften im " +"Menü „Datei“." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Die DVI-Datei hat einen ungültigen Vorspann." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"Die DVI-Datei enthält eine falsche Version von DVI-Daten für dieses " +"Programm. Hinweis: Falls Sie das Schriftsatzprogramm Omega benutzen, müssen " +"Sie ein spezielles Programm wie oxdvi verwenden." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"Die DVI-Datei ist beschädigt. Okular kann keinen gültigen Nachspann finden." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Der Nachspann (postamble) beginnt nicht mit dem POST-Befehl." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Der Nachspann enthält einen anderen Befehl als „FNTDEF“." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Seite %1 beginnt nicht mit dem BOP-Befehl." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Das externe Programm pdf2ps kann nicht gestartet " +"werden. Daher kann die PDF-Datei %1 nicht in PostScript konvertiert werden " +"und einige grafische Elemente im Dokument werden nicht angezeigt.

" +"Mögliche Ursache: Das Programm pdf2ps ist auf Ihrem " +"System nicht installiert oder im derzeitigen Suchpfad für Programme nicht zu " +"finden.

Lösungsvorschlag: Das Programm pdf2ps " +"wird normalerweise zusammen mit dem PostScript-Interpreter Ghostscript " +"ausgeliefert. Falls Ghostscript auf Ihrem System nicht installiert ist, " +"könnten Sie es nachinstallieren. Falls Ghostscript bereits installiert ist, " +"so rufen Sie pdf2ps bitte auf der Befehlszeile aus und " +"prüfen, ob dies funktioniert.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Die PDF-Datei %1 kann nicht zu PostScript umgewandelt werden. Einige " +"grafische Elemente in Ihrem Dokument werden daher nicht angezeigt.

Mögliche Ursache: Die Datei %1 könnte beschädigt oder keine " +"gültige PDF-Datei sein. Es folgt die Ausgabe des Programms pdf2ps, so wie es von Okular aufgerufen wurde:

%2 " + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Die Datei ist fehlerhaft. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"Nicht alle PostScript-Dateien können in das Dokument eingebettet werden. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Alle externen PostScript-Dateien wurden in das Dokument eingebettet." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Die angegebene Datei „%1“ existiert nicht." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Sie haben Okular angewiesen, die Stelle in der DVI-Datei zu suchen, die der " +"Zeile %1 in der TeX-Datei %2 entspricht. Offenbar enthält die DVI-Datei " +"nicht die dazu notwendigen Quelltextinformationen." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Die Stelle in der DVI-Datei, die der Zeile %1 in der TeX-Datei %2 " +"entspricht, wurde nicht gefunden." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "" +"In der DVI-Datei wird ein Zeichen einer unbekannten Schriftart gesetzt." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"In der DVI-Datei wird auf die Schriftart #%1 verwiesen, die jedoch vorher " +"nicht definiert wurde." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "" +"Der Stapelspeicher ist beim Auftreten des EOP-Befehls nicht leer gewesen." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Der Stapelspeicher ist beim Auftreten eines POP-Befehls leer gewesen." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"In der DVI-Datei wird auf eine Schriftart verwiesen, die vorher nicht " +"definiert wurde." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Ein ungültiger Befehl ist entdeckt worden." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Der unbekannte Befehlscode %1 ist entdeckt worden." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Einbetten von %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Seite %1: Die PDF-Datei %2 kann nicht in PostScript " +"umgewandelt werden.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Seite %1: Die PostScript-Datei %2 kann nicht gefunden " +"werden.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Die Daten zur Papiergröße „%1“ können nicht einlesen werden." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular kann nicht alle Schriftdateien finden, die zur Anzeige der DVI-" +"Datei nötig sind. Ihr Dokument ist möglicherweise nicht lesbar.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Bei der Ausführung von kpsewhich sind Probleme aufgetreten. " +"Daher können einige Schriftdateien nicht gefunden werden und Ihr Dokument " +"ist möglicherweise nicht lesbar.
Mögliche Ursache: Das Programm " +"kpsewhich ist möglicherweise auf Ihrem System nicht installiert " +"oder es kann nicht im aktuellen Suchpfad gefunden werden.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Das Erzeugen der Schriften durch kpsewhich ist abgebrochen " +"worden (Rückgabewert %1, Fehler %2). Infolgedessen können einige " +"Schriftdateien nicht gefunden werden. Ihr Dokument ist möglicherweise nicht " +"darstellbar." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "%1 wird mit %2 dpi erzeugt ..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Ersteller/Datum" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Schriftdatei nicht gefunden" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "Hochformat" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "Querformat" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Die auf Ihrem System installierte Version von Ghostview enthält keinen der " +"Okular bekannten Ghostview-Gerätetreiber. Die Unterstützung von PostScript " +"ist aus diesem Grund in Okular deaktiviert." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Das Programm Ghostview, das von Okular zur Darstellung von PostScript-" +"Grafiken wie sie in dieser DVI-Datei enthalten sind, verwendet wird, ist im " +"allgemeinen in der Lage, seine Daten in verschiedenen Formaten auszugeben. " +"Die Unterprogramme, die Ghostview für diesen Zweck benutzt, werden " +"Gerätetreiber genannt; Für jedes von Ghostview unterstützte Format gibt es " +"einen Gerätetreiber. Unterschiedliche Versionen von Ghostview enthalten oft " +"unterschiedliche Gerätetreiber. Anscheinend enthält die auf diesem Rechner " +"installierte Version keinen der Okular bekannten " +"Gerätetreiber.

Es ist unwahrscheinlich, dass eine normale Installation " +"von Ghostview keinen dieser Treiber enthält. Dies deutet auf eine grob " +"fehlerhafte Einrichtung der Ghostview-Installation auf Ihrem Rechner hin.

Wenn Sie die Probleme mit Ghostview beheben möchten, können Sie den " +"Befehl gs --help zur Anzeige der mit Ghostview " +"installierten Gerätetreiber verwenden. Unter anderem kann Okular die Treiber " +"„png256“, „jpeg“ und „pnm“ verwenden. Beachten Sie, dass Okular neu " +"gestartet werden muss, um die Unterstützung von PostScript wieder zu " +"aktivieren.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"Das waren 25 Fehlermeldungen. Es werden keine weiteren Fehler gemeldet." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Fehler in der DVI-Datei „%1“, Seite %2. Die Anweisung „color pop“ ist in " +"Verbindung mit einem leerem Farbenspeicher verwendet worden." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Fehlerhafter Parameter in EPSF Spezial-Befehl.\n" +"Es wird in %2 ein float nach %1 erwartet." + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Datei nicht gefunden:\n" +"%1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Fehler in der DVI-Datei „%1“, Seite %2. Die Winkelangabe der Textdrehung " +"kann nicht ausgewertet werden." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Die spezielle Anweisung „%1“ ist noch nicht implementiert." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Die Schriftdatei %1 kann geöffnet und eingelesen werden, aber das " +"Schriftformat wird nicht unterstützt." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Die Schriftdatei %1 ist fehlerhaft oder kann nicht geöffnet oder eingelesen " +"werden." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType hat einen Fehler beim Setzen der Zeichengröße in der Schrift %1 " +"gemeldet." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType kann das Zeichen #%1 aus der Schriftdatei %2 nicht laden." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"FreeType kann das Zeichen #%1 aus der Schriftdatei %2 nicht darstellen." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Das Zeichen #%1 ist leer." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Das Zeichen #%1 der Schriftdatei %2 ist leer." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType kann die Metrik für das Zeichen #%1 aus der Schriftdatei %2 nicht " +"einlesen." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Die Schriftdatei %1 lässt sich nicht öffnen." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: Zeichen %1 ist nicht definiert im Zeichensatz %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Unerwartetes %1 in PK-Datei %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Das Zeichen %1 in Datei %2 ist zu groß" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "" +"Es wurde eine inkorrekte Anzahl Bits gespeichert: Zeichen %1, Schrift %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Fehlerhafte PK-Datei (%1), zu viele Bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Schrift weist nicht-quadratische Proportion auf" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Die Schrift %1 aus Datei %2 wurde nicht gefunden." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Prüfsummen-Fehler in Schriftdatei %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Das Format der Schriftdatei %1 ist unbekannt" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Kritischer Fehler.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Das bedeutet wahrscheinlich, dass Sie entweder einen Fehler in Okular " +"gefunden haben\n" +"oder dass die DVI- oder die Hilfsdateien (wie z. B. Schriften oder virtuelle " +"Schriftdateien) fehlerhaft sind.\n" +"Okular bricht nach dieser Meldung ab. Wenn Sie glauben, dass Sie einen " +"Programmfehler\n" +"gefunden haben oder dass sich Okular in dieser Situation anders verhalten " +"sollte,\n" +"erstellen Sie bitte einen Problembericht." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Falsches Befehls-Byte in VF-Makroliste gefunden: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Anzeigemodul für DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Ein Renderer für DVI-Dateien" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular verwendet kpsewhich, um Schriftdateien auf Ihrem System " +#~ "zu finden und PK-Schriften zu erstellen, falls nötig.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular erzeugt gerade Bitmap-Schriften ..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "" +#~ "Bricht das Erzeugen der Schriften ab (sollte nach Möglichkeit vermieden " +#~ "werden)." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular erzeugt gerade Bitmap-Schriften, die zur Anzeige Ihres Dokuments " +#~ "benötigt werden. Dazu werden einige externe Programme, wie z. B. " +#~ "MetaFont, verwendet. Die Ausgaben dieser Programme finden Sie später im " +#~ "Dialog für Dokumentinformationen." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular erzeugt Schriften, bitte warten." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Fortschrittsanzeige zur Schriftartenerzeugung" + +#~ msgid "Abort" +#~ msgstr "Abbrechen" + +#~ msgid "What is happening here?" +#~ msgstr "Was geschieht hier?" + +#~ msgid "%v of %m" +#~ msgstr "%v von %m" + +#~ msgid "Please be patient" +#~ msgstr "Bitte haben Sie etwas Geduld" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Adobe PDF-Datei (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Datei exportieren als" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Eine Datei namens %1 existiert bereits.\n" +#~ "Soll sie überschrieben werden?" + +#~ msgid "Overwrite File" +#~ msgstr "Datei überschreiben" + +#~ msgid "Overwrite" +#~ msgstr "Überschreiben" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "dvipdfm wird zum Exportieren der Datei in das PDF-Format verwendet" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Das Programm „dvipdfm“ wird gerade von Okular ausgeführt, um Ihre DVI-" +#~ "Datei in das PDF-Format umzuwandeln. Das kann einige Zeit dauern, da " +#~ "dvipdfm eigene Schriftarten erzeugt. Bitte haben Sie etwas Geduld." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Warten auf dvipdfm ..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "dvips wird ausgeführt, um die Datei nach PostScript umzuwandeln" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Das externe Programm „dvips“ wird gerade ausgeführt, um Ihre DVI-Datei " +#~ "nach PostScript umzuwandeln. Dies kann einige Zeit dauern, da dvips " +#~ "eigene Schriftarten erzeugt. Bitte haben Sie etwas Geduld." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Warten auf dvips ..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funktionalität nicht verfügbar" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Beschädigte Datei: Okular kann die DVI-Datei nicht " +#~ "auswerten. Dies wird wahrscheinlich von einer fehlerhaften Datei " +#~ "verursacht." + +#~ msgid "DVI File Error" +#~ msgstr "DVI-Datei-Fehler" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Nicht alle Schriftdateien gefunden" + +#~ msgid "Locating fonts..." +#~ msgstr "Schriften werden gesucht ..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Bei der Ausführung von kpsewhich sind Fehler aufgetreten. Daher " +#~ "können einige Schriften nicht gefunden werden und Ihr Dokument erscheint " +#~ "möglicherweise unleserlich.

Mögliche Ursache: Vielleicht ist " +#~ "das Programm kpsewhich auf Ihrem System nicht installiert oder im " +#~ "derzeitigen „PATH“ nicht zu finden.

Lösungsvorschlag: Das " +#~ "Programm kpsewhich wird normalerweise gebündelt mit dem TeX-Satzsystem " +#~ "ausgeliefert. Falls TeX auf Ihrem System nicht installiert ist, könnten " +#~ "Sie TeX-Live nachinstallieren (www.tug.org/textlive). Falls TeX bereits " +#~ "installiert ist, so rufen Sie kpsewhich bitte auf der Befehlszeile aus " +#~ "und prüfen, ob dies funktioniert.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Fehler bei der Suche nach Schriften" + +#~ msgid "Font generation aborted" +#~ msgstr "Schriftenerzeugung abgebrochen" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Export: %1 nach PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Export: %1 nach PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Die Schriftartenliste ist derzeit leer." + +#~ msgid "TeX Name" +#~ msgstr "TeX-Name" + +#~ msgid "Family" +#~ msgstr "Familie" + +#~ msgid "Zoom" +#~ msgstr "Skalierung" + +#~ msgid "Type" +#~ msgstr "Typ" + +#~ msgid "Encoding" +#~ msgstr "Kodierung" + +#~ msgid "Comment" +#~ msgstr "Kommentar" + +#~ msgid "TeX virtual" +#~ msgstr "TeX virtuell" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX Font-Metrik" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "" +#~ "Eine Speicherzuweisung für eine Schrift-Struktur ist fehlgeschlagen." + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "Nicht genügend Arbeitsspeicher zum Laden des DVI-Dokuments." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Fehler beim Laden der DVI-Datei." + +#~ msgid "Checksum mismatch" +#~ msgstr "Prüfsummen-Fehler" + +#~ msgid " in font file " +#~ msgstr " in Schriftdatei " + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Speicherplatz für die Makrotabelle kann nicht reserviert werden." + +#~ msgid "Virtual character " +#~ msgstr "Virtuelles Zeichen " + +#~ msgid " in font " +#~ msgstr " in Schrift " + +#~ msgid " ignored." +#~ msgstr " ignoriert." + +#~ msgid "Fatal Error" +#~ msgstr "Kritischer Fehler" + +#~ msgid "KDVI: Information" +#~ msgstr "KDVI: Information" + +#~ msgid "" +#~ "This DVI file contains source file information. You may click into " +#~ "the text with the middle mouse button, and an editor will open the TeX-" +#~ "source file immediately." +#~ msgstr "" +#~ "Diese DVI-Datei enthält Quelltextinformationen. Sie können mit der " +#~ "mittleren Maustaste auf den Text klicken; daraufhin wird automatisch die " +#~ "TeX-Quelldatei geöffnet." + +#~ msgid "Do not show this message again" +#~ msgstr "Diese Meldung nicht mehr anzeigen" + +#~ msgid "Explain in more detail..." +#~ msgstr "Genauere Erklärung dazu ..." + +#~ msgid "" +#~ "File error. The specified file '%1' does not exist. " +#~ "KDVI already tried to add the ending '.dvi'." +#~ msgstr "" +#~ "Dateifehler! Die angegebene Datei %1 existiert " +#~ "nicht. KDVI hat bereits versucht, die Endung „.dvi“ hinzuzufügen." + +#~ msgid "File Error" +#~ msgstr "Dateifehler" + +#~ msgid "Could Not Find Reference" +#~ msgstr "Der Verweis ist nicht auffindbar" diff --git a/po/de/okular_epub.po b/po/de/okular_epub.po new file mode 100644 index 0000000..c95bb75 --- /dev/null +++ b/po/de/okular_epub.po @@ -0,0 +1,53 @@ +# Burkhard Lück , 2008, 2013. +# Frederik Schwarzer , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-14 17:35+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Fehler beim Öffnen des EPUB-Dokuments." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPUB" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul EPUB" + +#~ msgid "EPub Backend" +#~ msgstr "Anzeigemodul für EPUB" + +#~ msgid "An EPub backend" +#~ msgstr "Ein Anzeigemodul für EPUB" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/de/okular_fax.po b/po/de/okular_fax.po new file mode 100644 index 0000000..42a8b45 --- /dev/null +++ b/po/de/okular_fax.po @@ -0,0 +1,42 @@ +# Burkhard Lück , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-19 20:57+0100\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Dokument kann nicht geladen werden" + +#~ msgid "Fax Backend" +#~ msgstr "Anzeigemodul für Faxe" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Ein Anzeigemodul für G3/G4-Faxe" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/de/okular_fictionbook.po b/po/de/okular_fictionbook.po new file mode 100644 index 0000000..8657991 --- /dev/null +++ b/po/de/okular_fictionbook.po @@ -0,0 +1,94 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008, 2013. +# Frederik Schwarzer , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-14 17:34+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Das Dokument ist kein gültiges FictionBook-Dokument." + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Dokument kann nicht geöffnet werden: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Das Dokument ist kein gültiges ZIP-Archiv." + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Ungültige Dokumentstruktur (Basisordner fehlt)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Das Dokument hat keinen Inhalt." + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Ungültiges XML-Dokument: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Anzeigemodul für FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Ein Renderer für FictionBook-eBooks" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Title" +#~ msgstr "Titel" + +#~ msgid "Author" +#~ msgstr "Autor" + +#~ msgid "Producer" +#~ msgstr "Ersteller" + +#~ msgid "Created" +#~ msgstr "Erstellt am" + +#~ msgid "Creator" +#~ msgstr "Erzeuger" diff --git a/po/de/okular_ghostview.po b/po/de/okular_ghostview.po new file mode 100644 index 0000000..ffa315a --- /dev/null +++ b/po/de/okular_ghostview.po @@ -0,0 +1,120 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2007, 2008, 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-14 17:34+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Plattformspezifische Schriftarten verwenden" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Ist diese Einstellung aktiv, verwendet Ghostscript auch plattformspezifische " +"Schriften. Ansonsten werden nur im Dokument eingebettete Schriften benutzt. " + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Allgemeine Einstellungen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Plattformspezifische Schriftarten verwenden" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumentversion" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Sprach-Stufe" + +#~ msgid "PS Backend" +#~ msgstr "PS-Anzeigemodul" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Ein Renderer für PostScript-Dateien" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007–2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Entwickelt aus der Spectre-Bibliothek" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "Durch Kantenglättung wird das Ergebnis besser aussehen, aber die " +#~ "Darstellung wird langsamer sein." + +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "&Kantenglättung für Schriften" + +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "&Kantenglättung für Bilder" + +#~ msgid "" +#~ "Ghostscript is the basic renderer (the program which draws the " +#~ "picture)
\n" +#~ "In case of problems you might want to see its error messages" +#~ msgstr "" +#~ "Ghostscript ist der zugrundeliegende Renderer (das Programm, das das Bild " +#~ "zeichnet)
\n" +#~ "Falls es Probleme gibt, können dessen Fehlermeldungen hilfreich sein." + +#~ msgid "&Show Ghostscript messages in a separate box" +#~ msgstr "&Ghostscript-Meldungen in eigenem Fenster anzeigen" + +#~ msgid "Ghostscript Configuration" +#~ msgstr "Ghostscript-Einstellungen" + +#~ msgid "Additional parameters to Ghostscript" +#~ msgstr "Zusätzliche Parameter für Ghostscript" diff --git a/po/de/okular_kimgio.po b/po/de/okular_kimgio.po new file mode 100644 index 0000000..a137458 --- /dev/null +++ b/po/de/okular_kimgio.po @@ -0,0 +1,67 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2007, 2009, 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-26 21:07+0100\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Dokument %1 kann nicht geladen werden" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Dieses Dokument scheint ungültig zu sein. Es wird die beste Annäherung an " +"das beabsichtigte Erscheinungsbild des Dokuments angezeigt." + +#~ msgid "Image Backend" +#~ msgstr "Anzeigemodul für Bilder" + +#~ msgid "A simple image backend" +#~ msgstr "Ein einfaches Anzeigemodul für Bilder" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006–2007 Pino Toscano\n" +#~ "© 2006–2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Haupt-Werkzeugleiste" diff --git a/po/de/okular_markdown.po b/po/de/okular_markdown.po new file mode 100644 index 0000000..75fa54e --- /dev/null +++ b/po/de/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Burkhard Lück , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-06-25 06:38+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 18.12.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Öffnen des Dokuments fehlgeschlagen" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Das Markdown-Dokument kann nicht kompiliert werden." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "SmartyPants-Formatierung aktivieren" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul Markdown" diff --git a/po/de/okular_mobi.po b/po/de/okular_mobi.po new file mode 100644 index 0000000..8e9f822 --- /dev/null +++ b/po/de/okular_mobi.po @@ -0,0 +1,62 @@ +# Burkhard Lück , 2008, 2009, 2013. +# Panagiotis Papadopoulos , 2009. +# Frederik Schwarzer , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-14 17:32+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lueck@hube-lueck.de" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Fehler beim Öffnen des Mobipocket-Dokuments." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Dieses Buch ist durch DRM (Digitales Rechtemanagement) geschützt und kann " +"daher nur auf bestimmten Geräten angezeigt werden." + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Anzeigemodul für Mobipocket-Dateien" + +#~ msgid "A mobipocket backend" +#~ msgstr "Ein Anzeigemodul für Mobipocket-Dateien" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008–2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/de/okular_plucker.po b/po/de/okular_plucker.po new file mode 100644 index 0000000..c57fc4e --- /dev/null +++ b/po/de/okular_plucker.po @@ -0,0 +1,43 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-06-15 18:03+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KAider 0.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Name" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Anzeigemodul für Plucker-Dokumente" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Ein Renderer für Plucker eBooks" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/de/okular_poppler.po b/po/de/okular_poppler.po new file mode 100644 index 0000000..5da3c40 --- /dev/null +++ b/po/de/okular_poppler.po @@ -0,0 +1,291 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008, 2009, 2012, 2013, 2019. +# Panagiotis Papadopoulos , 2010. +# Frederik Schwarzer , 2012. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-08-05 14:41+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Anzeige dünner Linien verbessern:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Nein" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Einfarbig" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Form" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF-Optionen" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Anmerkungen drucken" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Anmerkungen in das gedruckte Dokument einfügen" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Fügt Anmerkungen in das gedruckte Dokument ein. Sie können dies " +"deaktivieren, wenn Sie das Originaldokument ohne Anmerkungen drucken möchten." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Rasterung erzwingen" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Vor dem Druck in ein Rasterbild umwandeln" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Dies erzwingt das Rastern jeder Seite zu einem Bild, bevor sie gedruckt " +"wird. Normalerweise ergeben sich dadurch schlechtere Ergebnisse; wenn ein " +"Dokument jedoch nicht fehlerfrei gedruckt wird, könnte diese Einstellung " +"hilfreich sein." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Auf druckbaren Bereich anpassen" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Auf ganze Seite anpassen" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "In Originalgröße drucken" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Skalierungsmodus für Druckseiten" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Skalierungsmodus:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Verschlüsselt" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Unverschlüsselt" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sicherheit" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Ja" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimiert" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Verwendet Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Verwendet Poppler %1\n" +"\n" +"Gebaut mit Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Nicht verfügbar" + +#~ msgid "PDF Backend" +#~ msgstr "PDF-Anzeigemodul" + +#~ msgid "A PDF file renderer" +#~ msgstr "Ein Renderer für PDF-Dateien" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005–2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Das Speichern von Dateien mit „/Encrypt“ wird nicht unterstützt." + +#~ msgid "Unknown" +#~ msgstr "Unbekannt" + +#~ msgid "Unknown Date" +#~ msgstr "Unbekanntes Datum" + +#~ msgid "Unknown Encryption" +#~ msgstr "Unbekannte Verschlüsselung" + +#~ msgid "Unknown Optimization" +#~ msgstr "Unbekannte Optimierung" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Bitte geben Sie das Passwort zum Lesen des Dokuments ein:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Falsches Passwort, bitte versuchen Sie es erneut:" + +#~ msgid "Document Password" +#~ msgstr "Dokument-Passwort" + +#~ msgid "" +#~ "The margins you specified are changing the page aspect ratio. Do you want " +#~ "to print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that aspect ratio is preserved?" +#~ msgstr "" +#~ "Die von Ihnen angegebenen Ränder ändern das Seitenverhältnis. Möchten Sie " +#~ "den Ausdruck mit dem neuen Seitenverhältnis durchführen, oder sollen die " +#~ "Ränder so angepasst werden, das das Seitenverhältnis beibehalten wird?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Änderung des Seitenverhältnisses" + +#~ msgid "Print with specified margins" +#~ msgstr "Mit angegebenen Rändern drucken" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Ränder anpassen und Seitenverhältnis beibehalten" + +#~ msgid "[none]" +#~ msgstr "[keine]" + +#~ msgctxt "not available" +#~ msgid "n/a" +#~ msgstr "N/V" + +#~ msgid "unknown" +#~ msgstr "Unbekannt" + +#~ msgid "Type 1" +#~ msgstr "Type 1" + +#~ msgid "Type 1C" +#~ msgstr "Type 1C" + +#~ msgctxt "OT means OpenType" +#~ msgid "Type 1C (OT)" +#~ msgstr "Type 1C (OT)" + +#~ msgid "Type 3" +#~ msgstr "Type 3" + +#~ msgid "TrueType" +#~ msgstr "TrueType" + +#~ msgctxt "OT means OpenType" +#~ msgid "TrueType (OT)" +#~ msgstr "TrueType (OT)" + +#~ msgid "CID Type 0" +#~ msgstr "CID Type 0" + +#~ msgid "CID Type 0C" +#~ msgstr "CID Type 0C" + +#~ msgctxt "OT means OpenType" +#~ msgid "CID Type 0C (OT)" +#~ msgstr "CID Type 0C (OT)" + +#~ msgid "CID TrueType" +#~ msgstr "CID TrueType" + +#~ msgctxt "OT means OpenType" +#~ msgid "CID TrueType (OT)" +#~ msgstr "CID TrueType (OT)" diff --git a/po/de/okular_tiff.po b/po/de/okular_tiff.po new file mode 100644 index 0000000..70120fe --- /dev/null +++ b/po/de/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Burkhard Lück , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-09-29 10:16+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Deutsches KDE-Übersetzerteam,Burkhard Lück" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kde-i18n-de@kde.org,lueck@hube-lueck.de" diff --git a/po/de/okular_txt.po b/po/de/okular_txt.po new file mode 100644 index 0000000..f98e529 --- /dev/null +++ b/po/de/okular_txt.po @@ -0,0 +1,51 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Frederik Schwarzer , 2013. +# Burkhard Lück , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-14 17:32+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Frederik Schwarzer" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "schwarzer@kde.org" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Text" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Einstellungen zum Anzeigemodul Text" + +#~ msgid "Txt Backend" +#~ msgstr "Anzeigemodul für Textformat" + +#~ msgid "Txt backend." +#~ msgstr "Anzeigemodul für Textformat." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/de/okular_xps.po b/po/de/okular_xps.po new file mode 100644 index 0000000..ff6df2d --- /dev/null +++ b/po/de/okular_xps.po @@ -0,0 +1,55 @@ +# Thomas Reitelbach , 2007. +# Burkhard Lück , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-03 22:22+0100\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Reitelbach" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tr@erdfunkstelle.de" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revision" + +#~ msgid "XPS Backend" +#~ msgstr "Anzeigemodul für XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Ein Anzeigemodul für XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006–2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/de/org.kde.active.documentviewer.po b/po/de/org.kde.active.documentviewer.po new file mode 100644 index 0000000..0c7c6e1 --- /dev/null +++ b/po/de/org.kde.active.documentviewer.po @@ -0,0 +1,84 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Frederik Schwarzer , 2012. +# Burkhard Lück , 2013, 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-06 11:41+0200\n" +"Last-Translator: Burkhard Lück \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 18.12.3\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Öffnen ..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Lesezeichen entfernen" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Ein Lesezeichen für diese Seite hinzufügen" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Vorschaubilder" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Inhaltsverzeichnis" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Lesezeichen" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Suchen ..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Keine Ergebnisse gefunden." + +#~ msgid "Document to open..." +#~ msgstr "Zu öffnendes Dokument ..." + +#~ msgid "Open Android..." +#~ msgstr "Android öffnen ..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Es wurden keine Dokumente gefunden. Legen Sie einige Dateien im " +#~ "Dokumentenordner Ihres Geräts ab, um mit dem Lesen zu beginnen." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Dokumentenbetrachter für „Plasma Active“, der Okular verwendet." + +#~ msgid "Reader" +#~ msgstr "Lesegerät" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Adresse (URL) der zu öffnenden Datei" diff --git a/po/el/okular.po b/po/el/okular.po new file mode 100644 index 0000000..d365aa4 --- /dev/null +++ b/po/el/okular.po @@ -0,0 +1,6045 @@ +# translation of okular.po to Greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007, 2008. +# Toussis Manolis , 2007, 2008, 2009. +# Spiros Georgaras , 2008. +# Dimitrios Glentadakis , 2010, 2011, 2012, 2013, 2014, 2015, 2016. +# Antonis Geralis , 2011. +# Stelios , 2012, 2014, 2017, 2019, 2020. +# Dimitris Kardarakos , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-28 16:11+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, ένας καθολικός προβολέας εγγράφων" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Προηγούμενος συντηρητής" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" +"Πολύ δουλειά στο πλαίσιο εργασίας, συστήματα υποστήριξης ODT και FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Προγραμματιστής" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Δημιουργία του Okular από τη βάση κώδικα του KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Προγραμματιστής του KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Γραφικά επισημάνσεων" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Εργαλείο επιλογής πίνακα" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Βελτιώσεις σημειώσεων" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Μετάβαση στη σελίδα %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Άνοιγμα εξωτερικού αρχείου" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Εκτέλεση '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Πρώτη σελίδα" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Προηγούμενη σελίδα" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Επόμενη σελίδα" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Τελευταία σελίδα" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Πίσω" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Μπροστά" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Τερματισμός" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Έναρξη παρουσίασης" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Τερματισμός παρουσίασης" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Αναζήτηση..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Μετάβαση στη σελίδα..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Αναπαραγωγή ήχου..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Σενάριο JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Αναπαραγωγή ταινίας..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Αναπαραγωγή ταινίας" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Διακοπή ταινίας" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Παύση ταινίας" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Συνέχιση ταινίας" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Επιλογή συστήματος υποστήριξης" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Βρέθηκαν παραπάνω από ένα σύστημα υποστήριξης για τον τύπο MIME:
" +"%1 (%2).

Παρακαλώ επιλέξτε ένα για χρήση:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Οι περισσότερες σελίδες είναι %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Πορτρέτο %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Τοπίο %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Συνέχιση της αναζήτησης από την αρχή" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Συνέχιση της αναζήτησης από το τέλος" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Αδυναμία εύρεσης ενός πρόσθετου για το χειρισμό του εγγράφου." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "διαγραφή σημειώσεων" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Το έγγραφο προσπαθεί να εκτελέσει μια εξωτερική εφαρμογή και για τη δική σας " +"ασφάλεια το Okular δεν το επιτρέπει." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Δε βρέθηκε εφαρμογή για το άνοιγμα αρχείων τύπου %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Αδύνατο το άνοιγμα ενός προσωρινού αρχείου" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Αποτυχία μετατροπής εκτύπωσης" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Η διεργασία εκτύπωσης κατέρρευσε" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Αδυναμία εκκίνησης της εκτύπωσης" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Αποτυχία εκτύπωσης σε αρχείο" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Ο εκτυπωτής ήταν σε μη έγκυρη κατάσταση" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Αδυναμία εύρεσης αρχείου για εκτύπωση" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Δεν υπάρχει αρχείο για εκτύπωση" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Αδυναμία εύρεσης ενός κατάλληλου δυαδικού για την εκτύπωση. Σιγουρευτείτε " +"ότι το δυαδικό CUPS lpr είναι διαθέσιμο" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Μη έγκυρο μέγεθος εκτύπωσης σελίδας" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Αδύνατο το άνοιγμα του \"%1\". Το αρχείο δεν υπάρχει." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Τίτλος" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Θέμα" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Περιγραφή" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Συγγραφέας" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Δημιουργός" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Παραγωγός" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Πνευματικά δικαιώματα" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Σελίδες" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Δημιουργήθηκε" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Τροποποιήθηκε" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Τύπος Mime" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Κατηγορία" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Λέξεις κλειδιά" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Διαδρομή αρχείου" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Μέγεθος αρχείου" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Μέγεθος σελίδας" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "προσθήκη σημείωσης" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "προσθήκη σημείωσης" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "τροποποίηση ιδιοτήτων σημείωσης" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "μετάφραση σημείωσης" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "προσαρμογή σημείωσης" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "επεξεργασία κειμένου" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "επεξεργασία περιεχομένου σημείωσης" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "επεξεργασία του περιεχομένου της φόρμας" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "επεξεργασία της λίστας επιλογών της φόρμας" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "επεξεργασία της λίστας επιλογών της φόρμας" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "επεξεργασία της κατάστασης των κουμπιών της φόρμας" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Απλό &κείμενο..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Κείμενο OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Επιλογές εκτύπωσης" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Εφαρμογή σε εκτυπώσιμη περιοχή" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Εφαρμογή σε πλήρη σελίδα" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Λειτουργία κλιμάκωσης:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Λείπει ο τύπος ειδοποίησης" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Να μην εμφανιστεί ξανά αυτό το μήνυμα" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Προέλευση: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Προκαθορισμένη γραμματοσειρά:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Κόκκινο" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Πορτοκαλί" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Κίτρινο" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Πράσινο" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Γαλάζιο" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Μπλε" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Φούξια" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Λευκό" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Γκρι" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Μαύρο" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Πλάτος %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Πλάτος γραμμής σημείωσης (Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Χρώμα σημείωσης (Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Χρώμα γέμισης σημείωσης (Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Αδιαφάνεια σημείωσης (Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Γραμματοσειρά σημείωσης (Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Να προστεθεί ο τρέχων σημείωση στο μενού γρήγορων σημειώσεων (Δεν έχει " +"επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Να περιοριστεί η αναλογία σχήματος στο 1:1 ή η γωνία γραμμής σε βήματα 15° " +"(Δεν έχει επιλεγεί σημείωση)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Προηγμένες ρυθμίσεις για το τρέχον εργαλείο σημειώσεων (Δεν έχει επιλεγεί " +"σημείωση)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Πλάτος γραμής σημειώσεων" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Πλάτος γραμής σημείωσης (Η τρέχουσα σημείωση δεν έχει πλάτος γραμμής)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Χρώμα κειμένου σημείωσης" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Χρώμα πλαισίου σημείωσης" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Χρώμα σημείωσης" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Χρώμα γεμίσματος σημείωσης" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Χρώμα γεμίσματος σημείωσης (Η τρέχουσα σημείωση δεν έχει χρώμα γεμίσματος)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Γραμματοσειρά σημείωσης" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Γραμματοσειρά σημείωσης (Η τρέχουσα σημείωση δεν έχει γραμματοσειρά)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Να περιοριστεί η γωνία γραμμής σε βήματα 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Να περιοριστεί η αναλογία σχήματος σε 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Να περιοριστεί η αναλογία σχήματος σε 1:1 ή η γωνία γραμμής σε βήματα 15° " +"(Δεν υποστηρίζεται από την τρέχουσα σημείωση)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Αδιαφάνεια σημείωσης" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Να προστεθεί η τρέχουσα σημείωση στο μενού γρήγορων σημειώσεων" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Προηγμένες ρυθμίσεις για το τρέχον εργαλείο σημειώσεων" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Χρώμα" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Χρώμα γέμισης" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Διαφανές" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Προσαρμοσμένο χρώμα..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Οι σφραγίδες που εισάγονται σε έγγραφα PDF δεν είναι ορατές σε άλλους " +"ναγνώστες PDF εκτός του Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Πειραματική λειτουργία" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Επιλογή χρώματος" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Σημειώσεις" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Απόκρυψη" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Τονισμός" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Υπογράμμιση" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Μουτζούρα" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Επιγράμμιση" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Γραφομηχανή" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Εμβόλιμη σημείωση" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Αναδυόμενη σημείωση" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Ελεύθερη γραμμή" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Ευθεία γραμμή" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Βέλος" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Ορθογώνιο" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Έλλειψη" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Πολύγωνο" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Γεωμετρικά σχήματα" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Σφραγίδα" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Γρήγορες σημειώσεις" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Επιλέξτε ένα εργαλείο σημειώσεων από τις γρήγορες σημειώσεις" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Προσθήκη στις γρήγορες σημειώσεις" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Να παραμείνει ενεργό" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Να παραμείνει ενεργό το εργαλείο δημιουργίας σημειώσεων μετά τη χρήση" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Να περιοριστεί η αναλογία και η γωνία των εργαλείων σημειώσεων" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Γραμματοσειρά" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Ρυθμίσεις σημειώσεων" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Πλάτος γραμμής" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Αδιαφάνεια" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Σελίδα %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Σημείωση" +msgstr[1] "%1 σημειώσεις" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "Ά&νοιγμα αναδυόμενης σημείωσης" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Διαγραφή" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Ιδιότητες" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Αποθήκευση '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Εμφάνιση" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Γενικά" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Συγγραφέας:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Δημιουργήθηκε:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Τροποποιήθηκε:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Ιδιότητες αναδυόμενης σημείωσης" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Ιδιότητες γραφομηχανής" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Ιδιότητες εμβόλιμης σημείωσης" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Ιδιότητες ευθείας γραμμής" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Ιδιότητες πολυγώνου" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Ιδιότητες γεωμετρίας" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Ιδιότητες σημάνσεων κειμένου" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Ιδιότητες σφραγίδας" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Ιδιότητες ελεύθερης γραμμής" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Ιδιότητες δείκτη" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Ιδιότητες συνημμένου αρχείου" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Ιδιότητες ήχου" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Ιδιότητες ταινίας" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Ιδιότητες σημείωσης" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Τροποποιήθηκε: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Επιλέξτε ένα προσαρμοσμένο σύμβολο σφραγίδας από το αρχείο" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Επιλογή προσαρμοσμένου συμβόλου σφραγίδας" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Αρχεία εικονιδίων (*.ico *.png *.xpm *.svg " +"*.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Αδυναμία φόρτωσης του αρχείου %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Μη έγκυρο αρχείο" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Χρώμα:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Αδιαφάνεια:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Εικονίδιο:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Σχόλιο" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Βοήθεια" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Εισαγωγή" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Πλήκτρο" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Νέα παράγραφος" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Σημείωση" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Παράγραφος" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Γραμματοσειρά:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Χρώμα &κειμένου:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Στοίχιση:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Αριστερά" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Κέντρο" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Δεξιά" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Πλάτος &περιθωρίου:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Εγκεκριμένο" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Ως είναι" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Εμπιστευτικό" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Τμηματικό" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Πρόχειρο" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Δοκιμαστικό" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Τελικό" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Προς σχόλιο" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Προς δημόσια κυκλοφορία" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Μη εγκεκριμένο" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Όχι προς δημόσια κυκλοφορία" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Πωλήθηκε" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Άκρως απόρρητο" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Σελιδοδείκτης" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Πληροφορίες" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"πειραματική λειτουργία.Οι σφραγίδες που εισάγονται σε έγγραφα " +"PDF δεν είναι ορατές σε άλλους αναγνώστες PDF εκτός του Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Σύμβολο σφραγίδας:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Πλάτος:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Έναρξη γραμμής:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Τέλος γραμμής:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Τετράγωνο" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Κύκλος" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Διαμάντι" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Άνοιγμα βέλους" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Κλειστό βέλος" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Κανένα" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Απόληξη" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Δεξί ανοιχτό βέλος" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Δεξί κλειστό βέλος" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Κάθετος" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Μήκος γραμμής αρχής:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Μήκος επεκτάσεων γραμμής αρχής:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Ενεργόποιημένο" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Γέμισμα σχήματος:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Τύπος:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Τονισμός" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Μουντζαλιά" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Υπογράμμιση" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Επιγράμμιση" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Ορθογώνιο" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Έλλειψη" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Σύμβολο συνημμένου αρχείου:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Γράφημα" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Πινέζα" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Συνδετήρας" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Ετικέτα" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Αρχείο" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "Μ/Δ" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Μη διαθέσιμη περιγραφή." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Όνομα:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Περιγραφή:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Σύμβολο δείκτη:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Κανένα" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Κλείσιμο αυτής της σημείωσης" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Επιλογές" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Αυτή η σημείωση μπορεί να περιέχει κώδικα LaTeX.\n" +"Κάντε κλικ εδώ για την αποτύπωση." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Δεν ήταν δυνατό να βρεθεί το εκτελέσιμο latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Αποτυχία αποτύπωσης LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Δεν ήταν δυνατό να βρεθεί το εκτελέσιμο dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Ένα πρόβλημα εμφανίστηκε κατά την εκτέλεση της εντολής 'latex'." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Ένα πρόβλημα εμφανίστηκε κατά την εκτέλεση της εντολής 'dvipng'." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Ένας σελιδοδείκτης" +msgstr[1] "" +"%1\n" +"\n" +"%2 σελιδοδείκτες" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Σελιδοδείκτες" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Αναζήτηση..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Μόνο τρέχον έγγραφο" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Μετάβαση σε αυτόν το σελιδοδείκτη" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Μετονομασία σελιδοδείκτη" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Αφαίρεση σελιδοδείκτη" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Άνοιγμα εγγράφου" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Αφαίρεση των σελιδοδεικτών" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Έκδοση" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Σειραϊκός αριθμός" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Εκδότης" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Εκδόθηκε την" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Λήγει την" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Υποκείμενο" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Δημόσιο κλειδί" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Χρήση κλειδιού" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Ιδιότητα" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Τιμή" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Προβολή πιστοποιητικού" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Εξαγωγή..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Γενικά" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Εκδόθηκε από" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Common Name(CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Ηλ. αλληλογραφία" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Οργανισμός(O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Εκδόθηκε σε" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Εγκυρότητα" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Αποτυπώματα" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1 αποτύπωμα" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256 αποτύπωμα" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Λεπτομέρειες" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Δεδομένα πιστοποιητικού:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Πού θέλετε να αποθηκεύσετε αυτό το πιστοποιητικό;" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Αρχείο πιστοποιητικού (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Αδυναμία εξαγωγής του πιστοποιητικού" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Κόκκινο" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Πράσινο" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Μπλε" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Κίτρινο" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Μαύρο" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Λευκό" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Εμφάνιση πλαισίου γύρω από τις ε&ικόνες" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Εμφάνιση πλαισίου γύρω από τους &δεσμούς" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Τροποποίηση &χρωμάτων" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Προειδοποίηση: αυτές οι επιλογές μπορούν να μειώσουν δραστικά την ταχύτητα " +"σχεδίασης." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Λειτουργία χρώματος:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Αντιστροφή χρωμάτων" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Τροποποίηση χρώματος χαρτιού" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Τροποποίηση σκοτεινών και φωτεινών χρωμάτων" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Μετατροπή σε ασπρόμαυρο" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Αντιστροφή χρωματικής έκτασης" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Αντιστροφή luma (sRGB γραμμικό)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Αντιστροφή luma (συμμετρικό)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Μετατόπιση θετικής απόχρωσης" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Μετατόπιση αρνητικής απόχρωσης" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Χρώμα χαρτιού:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Σκοτεινό χρώμα:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Φωτεινό χρώμα:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Κατώφλι:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Αντίθεση:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Ομιλία" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Μηχανή" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Ταυτότητα" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Συγγ&ραφέας:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Σημείωση: οι εδώ πληροφορίες χρησιμοποιούνται μόνο για σημειώσεις. Οι " +"πληροφορίες αυτές αποθηκεύονται σε έγγραφα με σημειώσεις και έτσι θα " +"μεταδοθούν μαζί με το έγγραφο." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Εργαλεία γρήγορων σημειώσεων" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Προσαρμοσμένος επεξεργαστής κειμένου" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "πελάτης Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "πελάτης Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Ορίστε την εντολή ενός προσαρμοσμένου επεξεργαστή κειμένου προς εκτέλεση." +"
\n" +"Μπορείτε να χρησιμοποιήσετε κάποιους αντικαταστάτες:\n" +"
    \n" +"

  • %f - το όνομα του αρχείου
  • \n" +"

  • %l - η γραμμή το αρχείου για μετάβαση σε αυτήν
  • \n" +"
  • %c - η στήλη του αρχείου για μετάβαση σε αυτήν
  • \n" +"
\n" +"
Αν δεν καθοριστεί το %f, τότε το όνομα αρχείου προστίθεται στο τέλος της " +"καθορισμένης εντολής." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Επεξεργασία" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Επεξεργαστής:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Επιλέξτε τον επεξεργαστή που επιθυμείτε όταν το Okular χρειάζεται να ανοίξει " +"ένα αρχείο πηγαίου κώδικα." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Εντολή:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Εμφάνιση" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Χρήση απαλής κύλισης" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Εμφάνιση &γραμμών κύλισης" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Σύνδεση των εικόνων ε&πισκόπησης με τη σελίδα" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Εμφάνιση &υποδείξεων και μηνυμάτων πληροφοριών" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Εμφάνιση τίτλου εγγράφου στη γραμμή τίτλου αν είναι διαθέσιμη" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Όταν δεν εμφανίζεται ο τίτλος εγγράφου:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Να εμφανίζεται το όνομα αρχείου μόνο" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Να εμφανίζεται η πλήρης διαδρομή του αρχείου" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Χρήση προσαρμοσμένου χρώματος φόντου" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Χαρακτηριστικά προγράμματος" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Άνοιγμα νέων αρχείων σε &καρτέλες" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Εναλλαγή σε υφιστάμενη καρτέλα αν το αρχείο είναι ήδη ανοιχτό" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Υπακοή στους περιορισμούς DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Επαναφόρτωση εγγράφου μετά από τροποποίηση του αρχείου" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Εμφάνιση διαλόγου επιλογής συστήματος υποστήριξης" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Κατεύθυνση ανάγνωσης από δεξιά προς αριστερά" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Επιλογές προβολής" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Στήλες &περίληψης:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Καθορίζει πόση από την τρέχουσα περιοχή προβολής θα εξακολουθεί να είναι " +"ορατή όταν πατάτε τα πλήκτρα Page Up/Down." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Σελίδα Πάνω/Κάτω επικάλυψη:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Καθορίζει την προκαθορισμένη λειτουργία εστίασης για αρχεία που δεν έχουν " +"ανοιχτεί ξανά.\n" +"Για αρχεία που έχουν ανοιχτεί ξανά εφαρμόζεται η προηγούμενη εστίαση." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Καθορίζει την προκαθορισμένη λειτουργία εστίασης για αρχεία που δεν έχουν " +"ανοιχτεί ξανά.\n" +"Για αρχεία που έχουν ανοιχτεί ξανά εφαρμόζεται η προηγούμενη εστίαση." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Προκαθορισμένη εστίαση:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Προσαρμογή στο πλάτος" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Προσαρμογή στη σελίδα" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Αυτόματη προσαρμογή" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Διατηρεί τη χρησιμοποιούμενη μνήμη όσο πιο χαμηλά γίνεται. Δεν " +"επαναχρησιμοποιεί τίποτα. (Για συστήματα με λίγη μνήμη.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Ένας καλός συνδυασμός μεταξύ χρήσης μνήμης και αύξησης ταχύτητας. Φορτώνει " +"από πριν την επόμενη σελίδα και επιταχύνει τις αναζητήσεις (Για συστήματα με " +"2GB μνήμης)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Διατηρεί τα πάντα στη μνήμη. Φορτώνει από πριν τις επόμενες σελίδες. " +"Επιταχύνει τις αναζητήσεις (Για συστήματα με περισσότερο από 4GB μνήμης.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Φορτώνει και διατηρεί τα πάντα στη μνήμη. Προφόρτωση όλων των σελίδων. (Θα " +"γίνει χρήση του 50% το πολύ όλης της μνήμης σας ή της ελεύθερης μνήμης σας, " +"όποια είναι μεγαλύτερη.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Χρήση επεξεργαστή" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Ενεργοποίηση εφέ &διαφάνειας" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Χρήση μνήμης" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Χαμηλή" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Κανονική (προκαθορισμένο)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Επιθ&ετική" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "Ά&πληστη" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Αποτύπωση" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Ενεργοποίηση εξομάλυνσης κειμένου" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Ενεργοποίηση εξομάλυνσης γραφικών" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Ενεργοποίηση υποδείξεων κειμένου" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Τρέχουσα οθόνη" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Προκαθορισμένη οθόνη" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Οθόνη %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " δευτερόλεπτο" +msgstr[1] " δευτερόλεπτα" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Πλοήγηση" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Προώθηση κάθε:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Επανάληψη μετά την τελευταία σελίδα" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Πλοήγηση επαφής:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Αγγίξτε στην αριστερή/δεξιά πλευρά για μετάβαση πίσω/εμπρός" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Αγγίξτε οπουδήποτε για μετάβαση εμπρός" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Απενεργοποιημεο" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Χρώμα φόντου:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Δρομέας ποντικιού:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Απόκρυψη μετά από καθυστέρηση" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Πάντα ορατός" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Πάντα αόρατος" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Εμφάνιση &προόδου" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Εμφάνιση σελίδας &περίληψης" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Ενεργοποίηση μεταβάσεων" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Προκαθορισμένη μετάβαση:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Κατακόρυφες γρίλιες" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Οριζόντιες γρίλιες" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Πλαίσιο προς τα μέσα" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Πλαίσιο προς τα έξω" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Διάλυση" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Ομαλή μετάβαση" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Λαμπύρισμα προς τα κάτω" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Λαμπύρισμα προς τα δεξιά" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Λαμπύρισμα προς κάτω δεξιά" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Τυχαία μετάβαση" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Αντικατάσταση" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Οριζόντια διαίρεση προς τα μέσα" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Οριζόντια διαίρεση προς τα έξω" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Κατακόρυφη διαίρεση προς τα μέσα" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Κατακόρυφη διαίρεση προς τα έξω" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Καθαρισμός προς τα κάτω" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Καθαρισμός προς τα δεξιά" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Καθαρισμός προς τα αριστερά" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Καθαρισμός προς τα πάνω" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Τοποθέτηση" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Οθόνη:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Διαμόρφωση εργαλείου σχεδίασης" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Εργαλείο σχεδίασης: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Γόμα" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "Ό&νομα:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Τύπος:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Αναδυόμενη σημείωση" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Εμβόλιμη σημείωση" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Ελεύθερη γραμμή" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Ευθεία γραμμή" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Πολύγωνο" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Σήμανση κειμένου" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Γεωμετρικό σχήμα" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Σφραγίδα" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Γραφομηχανή" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Εργαλείο δημιουργίας σημειώσεων" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Εργαλείο επεξεργασίας σημειώσεων" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Χρώμα:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Πάχος πένας:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Εργαλείο δημιουργίας σχεδίασης" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Εργαλείο επεξεργασίας σχεδίασης" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Άγνωστη" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Ενσωματωμένα αρχεία" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Προβολή" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Όνομα" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Περιγραφή" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Μέγεθος" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Δημιουργία" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Τροποποίηση" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Αποθήκευση ως..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "Π&ροβολή..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Αδυναμία φόρτωσης του τμήματος προεπισκόπησης εκτύπωσης" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Προεπισκόπηση εκτύπωσης" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Κλείσιμο" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Αναζήτηση:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Κείμενο προς αναζήτηση" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Επόμενο" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Μετάβαση στο επόμενο ταίριασμα" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Προηγούμενο" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Μετάβαση στο επόμενο ταίριασμα" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Τροποποίηση συμπεριφοράς αναζήτησης" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Διάκριση πεζών/κεφαλαίων" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Από τρέχουσα σελίδα" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Εύρεση καθώς πληκτρολογείτε" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Όλα τα αρχεία" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Ιδιότητες υπογραφής" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Ευθεία γραμμή με σχόλιο" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Πολύγωνο με σχόλιο" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Γεωμετρία με σχόλιο" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Γεωμετρία" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Τονισμός με σχόλιο" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Μουτζούρα με σχόλιο" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Υπογράμμιση με σχόλιο" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Επιγράμμιση με σχόλιο" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Επιγράμμιση" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Σφραγίδα με σχόλιο" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Ελεύθερη γραμμή με σχόλιο" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Δείκτης" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Συνημμένο αρχείο" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Ήχος" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Ταινία" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Οθόνη" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Γραφικό συστατικό" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Επαυξημένα πολυμέσα" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Άγνωστο" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Συγγραφέας: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Θέση αποθήκευσης του %1;" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Αδύνατη η εγγραφή του \"%1\". Το αρχείο δεν αποθηκεύτηκε." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Επιλογές αναζήτησης" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Διάκριση πεζών/κεφαλαίων" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regular Expression" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "Α&ναζήτηση:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Επίπεδα" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "από" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Εστίαση" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Εστίαση στο 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Περιστροφή &δεξιά" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Δεξιά" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Περιστροφή &αριστερά" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Αριστερά" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Αρχικός προσανατολισμός" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Κόψιμο προβολής" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Κόψιμο περιθωρίων" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Κόψιμο στην επιλογή" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Προσαρμογή στο &πλάτος" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Προσαρμογή σε&λίδας" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Αυτόματη προσαρμογή" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Προσαρμογή του παρα&θύρου στη σελίδα" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Κατάσταση &προβολής" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Μονή &σελίδα" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Αν&τικριστές σελίδες" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Αντικριστές σελίδες (&κεντράρισμα πρώτης σελίδας)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Επισκόπηση" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Συνεχής" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Χρήση κατεύθυνσης ανάγνωσης από δεξιά προς αριστερά" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Περιήγηση" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Εστίαση" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Ε&νεργοποίηση/απενεργοποίηση της επεξεργασίας των χρωμάτων" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Επιλογή επιφάνεια&ς" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Επι&λογή κειμένου" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Επιλογή πίν&ακα" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Μεγεθυντής" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Εργαλεία επιλογής" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Εκφώνηση ολόκληρου εγγράφου" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Εκφώνηση τρέχουσας σελίδας" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Σταμάτημα εκφώνησης" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Παύση/συνέχιση ομιλίας" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Κύλιση πάνω" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Κύλιση κάτω" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Κύλιση σελίδας πάνω" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Κύλιση σελίδας κάτω" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Εμφάνιση φορμών" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Φορτώθηκε ένα έγγραφο μιας σελίδας." +msgstr[1] " Φορτώθηκε ένα έγγραφο %1 σελίδων." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Κείμενο (1 χαρακτήρας)" +msgstr[1] "Κείμενο (%1 χαρακτήρες)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Αντιγραφή στο πρόχειρο" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Απαγόρευση αντιγραφής από DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Εκφώνηση κειμένου" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Εικόνα (%1 επί %2 εικονοστοιχεία)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Αποθήκευση σε αρχείο..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Η εικόνα [%1x%2] αντιγράφηκε στο πρόχειρο." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Αποθήκευση αρχείου" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Εικόνες (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Το αρχείο δεν αποθηκεύτηκε." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Εικόνα [%1x%2] αποθηκεύτηκε στο αρχείο %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Αντιγραφή κειμένου" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Μετάβαση στην %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Αναζήτηση για '%1' με" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Διαμόρφωση συντομεύσεων ιστού..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Ακολούθησε αυτό το δεσμό" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Αναπαραγωγή του ήχου" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Διακοπή του ήχου" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Αντιγραφή διεύθυνσης δεσμού" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Αναζήτηση για '%1' σε αυτό το έγγραφο" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Καλώς ήρθατε" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Επιλέξτε περιοχή εστίασης. Δεξί κλικ για σμίκρυνση." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Κάντε κλικ για να δείτε την προβολή μεγέθυνσης." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "" +"Σχεδιάστε ένα παραλληλόγραμμο γύρο από το κείμενο/γραφικό που θέλετε να " +"αντιγράψετε." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Επιλέξτε κείμενο" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Σχεδιάστε ένα παραλληλόγραμμο γύρο από τον πίνακα, έπειτα κάντε κλικ κοντά " +"στις ακμές για την κατανομή. Πατήστε Esc για καθαρισμό." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Σχεδιάστε ένα παραλληλόγραμμο γύρω από την περιοχή της σελίδας που θέλετε να " +"διατηρήσετε ορατή" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Νέα σημείωση κειμένου" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Κείμενο της νέας σημείωσης:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Προσθήκη σημείωσης στους σελιδοδείκτες" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Εισαγωγή προσαρμοσμένου ονόματος για τη σημείωση:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Σχεδίαση μιας έλλειψης (σύρετε για την επιλογή μιας ζώνης)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Τονισμός κειμένου" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Σχεδιασμός ελεύθερης γραμμής" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Σημείωση εμβόλιμου κειμένου (σύρετε για την επιλογή ζώνης)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Εισαγωγή αναδυόμενης σημείωσης" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Σχεδίαση ενός πολυγώνου (κλικ στο πρώτο σημείο για κλείσιμό του)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Σχεδίαση παραλληλόγραμμου" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Μουντζαλιά κειμένου" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Τοποθέτηση συμβόλου σφραγίδας" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Σχεδίαση ευθείας γραμμής" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Επιγράμμιση κειμένου" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Υπογράμμιση κειμένου" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Σημείωση γραφομηχανής (σύρετε για την επιλογή ζώνης)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Τονισμός" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Προσθήκη αγαπημένης σημείωσης" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Όνομα προσαρμοσμένης σημείωσης:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Αρχείο" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Ρ&υθμίσεις" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Βοήθεια" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "Προ&σανατολισμός" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Σελιδοδείκτες" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Γραμμή προβολέα" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Εικόνες επισκόπησης" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Σημειώσεις" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Το έγγραφο αυτό περιέχει σημειώσεις ή δεδομένα φορμών αποθηκευμένα εσωτερικά " +"από μια προηγούμενη έκδοση του Okular. Ο εσωτερικός χώρος αποθήκευσης δεν " +"υποστηρίζεται πλέον.
Αποθηκεύστε σε ένα αρχείο για να τα " +"μετακινήσετε αν θέλετε να συνεχίσετε την επεξεργασία του εγγράφου." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Το έγγραφο αυτό περιέχει ενσωματωμένα αρχεία. Κάντε κλικ εδώ για να τα δείτε ή μεταβείτε στο Αρχείο -> Ενσωματωμένα " +"αρχεία." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Προηγούμενο" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Μετάβαση στην προηγούμενη σελίδα" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Μετακινεί στην προηγούμενη σελίδα του εγγράφου" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Επόμενο" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Προώθηση στην επόμενη σελίδα" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Μετακινεί στην επόμενη σελίδα του εγγράφου" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Αρχή του εγγράφου" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Μετακινεί στην αρχή του εγγράφου" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Τέλος του εγγράφου" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Μετακινεί στο τέλος του εγγράφου" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Μετονομασία του τρέχοντος σελιδοδείκτη" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Προηγούμενος σελιδοδείκτης" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Μετάβαση στον προηγούμενο σελιδοδείκτη" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Επόμενος σελιδοδείκτης" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Μετάβαση στον επόμενο σελιδοδείκτη" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Διαμόρφωση του Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Διαμόρφωση προβολέα..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Διαμόρφωση συστημάτων υποστήριξης προβολέα..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Διαμόρφωση συστημάτων υποστήριξης..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Σχετικά με το σύστημα υποστήριξης" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Επαναφόρτωση" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Επαναφόρτωση του τρέχοντος εγγράφου από το δίσκο." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Κλείσιμο γραμμής &αναζήτησης" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Αριθμός σελίδας" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Επιλογή όλου του κειμένου στην τρέχουσα σελίδα" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Εμφάνιση πλευρ&ικής γραμμής" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Εμφάνιση γραμμής &σελίδας" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Εμφάνι&ση πίνακα υπογραφών" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Ενσωματωμένα αρχεία" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "Ε&ξαγωγή ως" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Δια&μοιρασμός" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "Πα&ρουσίαση" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Άνοιγμα περιέχον&τος φακέλου" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Εισαγωγή Postscript ως PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Λήψη βιβλίων από το διαδίκτυο..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Εναλλαγή λειτουργίας μαύρης οθόνης" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Σβήσιμο σχεδίων" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Διαμόρφωση σημειώσεων..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Αναπαραγωγή/παύση παρουσίασης" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Αδυναμία ανοίγματος του '%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Η φόρτωση του %1 ακυρώθηκε." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Αδυναμία ανοίγματος του %1. Αιτία: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Διαμόρφωση συστημάτων υποστήριξης προβολέα" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Διαμόρφωση συστημάτων υποστήριξης" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Το πρόγραμμα \"ps2pdf\" δε βρέθηκε, έτσι το Okular δε θα μπορεί να εισάγει " +"αρχεία PS με αυτό." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "Δε βρέθηκε το ps2pdf" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript αρχεία (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Εισαγωγή αρχείου PS ως PDF (μπορεί να διαρκέσει αρκετά)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Δώστε τον κωδικό πρόσβασης για να διαβάσετε το έγγραφο:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Λανθασμένος κωδικός πρόσβασης. Προσπαθήστε πάλι:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Κωδικός πρόσβασης εγγράφου" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Το έγγραφο αυτό περιέχει φόρμες XFA, οι οποίες προς το παρόν δεν " +"υποστηρίζονται." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Αυτό το έγγραφο περιέχει φόρμες. Κάντε κλικ στο κουμπί για την εμφάνισή " +"τους, ή χρησιμοποιήστε το Προβολή -> Εμφάνιση φορμών." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Όλη η επεξεργασία και οι διαδραστικές λειτουργίες για αυτό το έγγραφο έχουν " +"απενεργοποιηθεί. Αποθηκεύστε ένα αντίγραφοκαι αοίξτε ξανά για να " +"επεξεργαστείτε το έγγραφο." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Αυτό το έγγραφο έχει ωηφιακή υπογραφή." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Αυτό το έγγραφο έχει ωηφιακή υπογραφή. Έχουν γίνει αλλαγές από την τελευταία " +"υπογραφή." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Αυτό το έγγραφο έχει ψηφιακή υπογραφή. Ορισμένες από τις υπογραφές δεν " +"μπορούν να επαληθευθούν." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Αυτό το έγγραφο θέλει να εμφανίζεται σε πλήρη οθόνη.\n" +"Να γίνει μετάβαση από κανονική λειτουργία σε λειτουργία παρουσίασης;" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Αίτημα αλλαγής λειτουργίας προβολής" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Έίσοδος σε λειτουργία παρουσίασης" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Άρνηση αιτήματος" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Αδυναμία ανοίγματος του %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Υπάρχουν μη αποθηκευμένες αλλαγές και το αρχείο '%1' έχει τροποποιηθεί από " +"άλλο πρόγραμμα. Οι αλλαγές σας θα χαθούν, επειδή το αρχείο δεν είναι πλέον " +"δυνατόν να αποθηκευθεί.
Θέλετε να συνεχίσετε την επαναφόρτωση του αρχείου;" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Το αρχείο άλλαξε" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Συνέχεια επαναφόρτωσης" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Εγκατάλειψη επαναφόρτωσης" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Υπάρχουν μη αποθηκευμένες αλλαγές και το αρχείο '%1' έχει τροποποιηθεί από " +"άλλο πρόγραμμα. Οι αλλαγές σας θα χαθούν, επειδή το αρχείο δεν είναι πλέον " +"δυνατόν να αποθηκευθεί.
Θέλετε να συνεχίσετε το κλείσιμο του αρχείου;" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Συνέχεια κλεισίματος" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Εγκατάλειψη κλεισίματος" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Θέλετε να αποθηκεύσετε τις αλλαγές σας στο «%1» ή να τις απορρίψετε;" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Κλείσιμο εγγράφου" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Αυτός ο δεσμός ενεργοποιεί μία ενέργεια κλεισίματος εγγράφου η οποία δε " +"λειτουργεί όταν χρησιμοποιείτε τον ενσωματωμένο προβολέα." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Αυτός ο δεσμός ενεργοποιεί μία ενέργεια τερματισμού εφαρμογής η οποία δε " +"λειτουργεί όταν χρησιμοποιείτε τον ενσωματωμένο προβολέα." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Επαναφόρτωση του εγγράφου..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Περιεχόμενα" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Υπογραφές" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Μετακίνηση στη σελίδα" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Σελίδα:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Εισάγετε το νέο όνομα του σελιδοδείκτη:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Μετονομασία αυτού του σελιδοδείκτη" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Να διαγραφεί αυτός ο σελιδοδείκτης" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Αποθήκευση ως" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Το αρχείο '%1' έχει τροποποιηθεί από άλλο πρόγραμμα, το οποίο σημαίνει ότι " +"δεν είναι πλέον δυντό να αποθηκευθεί." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Το τρέχον έγγραφο προστατεύεται με κωδικό πρόσβασης.
Για αποθήκευση, " +"απαιτείται η επεναφόρτωση του αρχείου. Θα σας ζητηθεί και πάλι ο κωδικός " +"πρόσβασης και το ιστορικό αναίρεσης / ακυρώσεων αναίρεσης θα χαθεί.
Θέλετε να συνεχίσετε;" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Αποθήκευση - Προειδοποίηση" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Αδυναμία ανοίγματος του προσωρινού αρχείου για αποθήκευση." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Μετά την αποθήκευση, ο τρέχων τύπος εγγράφου απαιτεί την επαναφόρτωση του " +"αρχείου. Το ιστορικό αναίρεσης / ακυρώσεων αναίρεσης θα χαθεί.
Θέλετε " +"να συνεχίσετε;" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Αδυναμία αποθήκευσης αρχείου στο '%1'. Προσπαθήστε να το αποθηκεύσετε σε " +"άλλη τοποθεσία." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Περιεχόμενο συμπληρωμένης φόρμας" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Σημειώσεεις χρήστη" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Πρόκειται να αποθηκεύσετε αλλαγές, αλλά ο τρέχων τύπος αρχείου δεν " +"υποστηρίζει την αποθήκευση των ακόλουθων αντικειμένων. Χρησιμοποιήστε τον " +"τύπο Αρχείοθήκης εγγράφων Okular για να τα διατηρήσετε." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Προειδοποίηση" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Αποθήκευση ως αρχειοθήκη εγγράφων Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Πρόκειται να αποθηκεύσετε αλλαγές, αλλά ο τρέχων τύπος αρχείου δεν " +"υποστηρίζει την αποθήκευση των ακόλουθων αντικειμένων. Χρησιμοποιήστε τον " +"τύπο Αρχείοθήκης εγγράφων Okular για να τα διατηρήσετε. Έπειτα κάνετε " +"κλικ στο Συνέχεια για να αποθηκεύσετε το έγγραφο και να απορρίψετε " +"αυτά τα αντικείμενα." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Πρόκειται να αποθηκεύσετε αλλαγές, αλλά ο τρέχων τύπος αρχείου δεν " +"υποστηρίζει την αποθήκευση των ακόλουθων αντικειμένων. Χρησιμοποιήστε τον " +"τύπο Αρχείοθήκης εγγράφων Okular για να τα διατηρήσετε. Έπειτα κάνετε " +"κλικ στο Συνέχεια για να αποθηκεύσετε, αλλά θα χάσετε αυτά τα " +"αντικείμενα καθώς και το ιστορικό αναίρεσης / ακυρώσεων αναίρεσης." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Συνέχεια" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Συνέχεια με απώλεια αλλαγών" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Αδυναμία αποθήκευσης αρχείου στο '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Το Okular δεν μπορεί να αντιγράψει το %1 στην ορισμένη τοποθεσία.\n" +"\n" +"Το έγγραφο δεν υπάρχει πια." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Αδυναμία αποθήκευσης αρχείου στο '%1'. Σφάλμα: '%2'. Προσπαθήστε να το " +"αποθηκεύσετε σε άλλη τοποθεσία." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Επέκταση όλης της ενότητας" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Σύμπτυξη όλης της ενότητας" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Επέκταση όλων" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Σύμπτυξη όλων" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Προσθήκη σελιδοδείκτη" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Εργαλεία" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Εκτύπωση" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Η εκτύπωση αυτού του εγγράφου δεν επιτρέπεται." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Αδύνατη η εκτύπωση του εγγράφου. Άγνωστο σφάλμα. Παρακαλώ αναφέρετε το στο " +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Αδύνατη η εκτύπωση του εγγράφου. Το λεπτομερές σφάλμα είναι \"%1\". Παρακαλώ " +"αναφέρετέ το στο bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Μετάβαση στο σημείο που ήσασταν πριν" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Μετάβαση στο σημείο που ήσασταν μετά" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Σφάλμα Αρχείου! Δεν ήταν δυνατή η δημιουργία του " +"προσωρινού αρχείου %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Σφάλμα Αρχείου! Δεν ήταν δυνατό το άνοιγμα του αρχείου " +"%1 για αποσυμπίεση. Το αρχείο δε θα φορτωθεί." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Αυτό το σφάλμα κανονικά εμφανίζεται όταν δεν έχετε άδεια να διαβάσετε το " +"αρχείο. Μπορείτε να ελέγξετε τον ιδιοκτήτη και τις άδειες του αρχείου " +"κάνοντας δεξί κλικ πάνω του στο διαχειριστή αρχείων Dolphin, έπειτα " +"επιλέγοντας την επιλογή 'Ιδιότητες' και επιλέγοντας την καρτέλα 'Δικαιώματα' " +"στο ανοιχτό παράθυρο." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Σφάλμα Αρχείου! Δεν ήταν δυνατή η αποσυμπίεση του " +"αρχείου %1. Το αρχείο δε θα φορτωθεί." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Αυτό το σφάλμα κανονικά εμφανίζεται όταν το αρχείο είναι κατεστραμμένο. " +"Αν θέλετε να σιγουρευτείτε, προσπαθήστε να το αποσυμπιέσετε με χρήση " +"εργαλείων γραμμής εντολών." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Κανένας σελιδοδείκτης" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Παρουσιάστηκε πρόβλημα με το διαμοιρασμό του εγγράφου: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Διαμοιρασμός" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Το έγγραφο μοιράστηκε με επιτυχία" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Μπορείτε να βρείτε το κοινόχρηστο έγγραφο στο: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Επεξεργασία" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "Π&ροβολή" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Μετάβαση" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Ερ&γαλεία" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Κύρια γραμμή εργαλείων" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Γραμμή εργαλείων σημειώσεων" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Γενικές επιλογές" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Προσβασιμότητα" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Βοηθήματα προσβασιμότητας ανάγνωσης" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Επιδόσεις" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Ρύθμιση επιδόσεων" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Διαμόρφωση προβολέα" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Παρουσίαση" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Επιλογές παρουσίασης" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Ιδιότητες σημειώσεων" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Επιλογές επεξεργαστή" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Αναζήτηση επόμενου" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Παρουσίαση" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Εναλλαγή οθόνης" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Οθόνη %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Έξοδος από λειτουργία παρουσίασης" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Τίτλος: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Σελίδες: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Κάντε κλικ για να αρχίσετε" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Παύση" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Αναπαραγωγή" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Υπάρχουν δύο τρόποι εξόδου από τη λειτουργία παρουσίασης. Μπορείτε να " +"πατήσετε το πλήκτρο ESC ή να κάνετε κλικ στο κουμπί τερματισμού που " +"εμφανίζεται όταν το ποντίκι τοποθετηθεί στην πάνω δεξιά γωνία. Φυσικά " +"μπορείτε να μετακινείστε κυκλικά στα παράθυρα (Alt+TAB εξ ορισμού)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Γίνεται παρουσίαση" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Άγνωστο αρχείο" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Ιδιότητες" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Γραμματοσειρές" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Ανάγνωση πληροφοριών γραμματοσειράς..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Μεγέθη σελίδας" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "Ε&ξαγωγή γραμματοσειράς" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "Εικονικό TeX" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Μετρικό γραμματοσειράς TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "FreeType-χειριζόμενο TeX" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Άγνωστο" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Ενσωματωμένο (υποσύνολο)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Πλήρως ενσωματωμένο" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Όχι" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Ναι (υποσύνολο)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Ναι" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (αντικατάσταση με %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[μ/δ]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Άγνωστη γραμματοσειρά" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Ενσωματωμένο: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Όνομα" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Τύπος" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Αρχείο" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Σελίδα" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Μέγεθος" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Προεπισκόπηση αναθεώρησης" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Πού θέλετε να αποθηκεύσετε αυτήν την αναθεώρηση;" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Αδυναμία αποθήκευσης του αρχείου %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Αδυναμία προβολής αναθεώρησης." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Δώστε τουλάχιστον 3 γράμματα για να φιλτράρετε σελίδες" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Διάκριση πεζών/κεφαλαίων" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Ταίριασμα φράσης" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Ταίριασμα όλων των λέξεων" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Ταίριασμα οποιασδήποτε λέξης" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Επιλογές φίλτρων" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Χωρίς σημειώσεις

Για τη δημιουργία νέων σημειώσεων " +"πιέστε το F6 ή επιλέξτε Εργαλεία -> Σημειώσεις από το μενού.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Ομαδοποίηση ανά σελίδα" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Ομαδοποίηση ανά συγγραφέα" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Εμφάνιση σημειώσεων για την τρέχουσα σελίδα μόνο" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "επέκταση όλων των αντικειμένων" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Σύμπτυξη όλων των αντικειμένων" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Η υπογραφή είναι έγκυρα κρυπτογραφημένη." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Η υπογραφή δεν είναι έγκυρα κρυπτογραφημένη." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" +"Εμφανίστηκε ασυμβατότητα στο αποτέλεσμα της συνάρτησης κατακερματισμού." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Η δομή της υπογραφής CMS/PKCS7 είναι κακοδιατυπωμένη." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Η αιτούμενη υπογραφή δεν είναι παρούσα στο έγγραφο." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Αδυναμία επιβεβαίωσης της υπογραφής." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Το πιστοποιητικό είναι έμπιστο." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Ο εκδότης του πιστοποιητικού δεν είναι έμπιστος." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Ο εκδότης του πιστοποιητικού είναι άγνωστος." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Το πιστοποιητικό έχει ανακληθεί." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Το πιστοποιητικό έχει λήξει." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Το πιστοποιητικό δεν έχει ακόμη επιβεβαιωθεί." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Άγνωστο πρόβλημα με το πιστοποιητικό ή κατεστραμμένα δεδομένα." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Άγνωστος αλγόριθμος" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Άγνωστος τύπος" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Ψηφιακή υπογραφή" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Μη-αποποίηση" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Κρυπτογράφηση κλειδιών" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Αποκρυπτογράφηση κλειδιών" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Συμφωνία κλειδιώμ" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Υπογραφή πιστοποιητικού" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Υπογραφή CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Κρυπτογράφηση μόνο" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Δεν ορίσθηκε χρήση" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Αναθ. %1: Υπογραφή από %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Χρόνος υπογραφής: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Μη διαθέσιμη" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Αιτία: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Πεδίο: %1 στη σελίδα %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Ιδιότητες" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Το έγγραφο δεν έχει τροποποιηθεί από τότε που υπογράφηκε." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Η αναθεώρηση του εγγράφου που καλύπτεται από αυτήν την υπογραφή δεν έχει " +"τροποποιηθεί.\n" +"Ωστόσο έχουν συμβεί επόμενες αλλαγές στο έγγραφο." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Το έγγρσφο έχει τροποποιηθεί με τρόπο που δεν επιτρέπεται από έναν " +"προηγούμενο υπογράφοντα." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Αδυναμία ολοκλήρωσης της επιβεβαίωσης ακεραιότητας του εγγράφου." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Κατάσταση επιβεβαίωσης" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Επιβεβαίωση υπογραφής:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Τροποποιήσεις εγγράφου:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Πρόσθετες πληροφορίες" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Υπογραφή από:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Χρόνος υπογραφής:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Αιτία:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Θέση:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Έκδοση εγγράφων" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Αναθεώρηση εγγράφου %1 από %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Προβολή υπογεγγραμμένης έκδοσης..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Προβολή πιστοποιητικού..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Εμφάνιση μόνο σελίδων με σελιδοδείκτη" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Αναπαραγωγή" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Παύση" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Διακοπή" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Προσθήκη..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Επεξεργασία" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "Α&φαίρεση" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Μετακίνηση &πάνω" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Μετακίνηση &κάτω" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Προκαθορισμένο εργαλείο σχεδίασης #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" +"Υπάρχει ήδη εργαλείο με αυτό το όνομα. Θα γίνει χρήση του προκαθορισμένου" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Διπλό όνομα" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Σελίδα του εγγράφου προς εμφάνιση" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Έναρξη του εγγράφου σε λειτουργία παρουσίασης" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Έναρξη με το διάλογο εκτύπωσης" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Έναρξη με το διάλογο εκτύπωσης και έξοδος μετά την εκτύπωση" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Έλεγχος \"μοναδικής εκτέλεσης\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Όχι ανύψωση παραθύρου" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Εύρεση συμβολοσειράς στο κείμενο" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Έγγραφα για άνοιγμα. Καθορίστε το '-' για ανάγνωση από το stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Σφάλμα: Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων με τον διακόπτη --" +"switch" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Σφάλμα: Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων με τον διακόπτη --" +"presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Σφάλμα: Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων με τον διακόπτη --" +"print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Σφάλμα: Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων με τον διακόπτη --" +"page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Σφάλμα: Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων με τον διακόπτη --" +"find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Αδυναμία εύρεσης του συστατικού Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Υπάρχει ήδη μια μοναδική διεργασία Okular που εκτελείται. Η διεργασία αυτή " +"δεν θα είναι η μόνη." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Αδυναμία εύρεσης του συστατικού Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Κάντε κλικ για να ανοίξετε ένα αρχείο.\n" +"Κλικ και κράτημα για να ανοίξετε ένα πρόσφατο αρχείο" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Κλικ για να ανοίξετε ένα αρχείο ή Κλικ και κράτημα για να " +"επιλέξετε ένα πρόσφατο αρχείο" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Επόμενη καρτέλα" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Προηγούμενη καρτέλα" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Αναίρεση κλεισίματος καρτέλας" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Όλα τα αρχεία (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Όλα τα υποστηριζόμενα αρχεία (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Άνοιγμα εγγράφου" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Επιβεβαίωση κλεισίματος" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Κλείσιμο καρτελών" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Προτίθεσθε να κλείσετε %1 καρτέλες. Σίγουρα θέλετε να συνεχίσετε;" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Να προειδοποιούμαι όταν επιχειρώ να κλείσω πολλές καρτέλες" + +#~ msgid "Reviews" +#~ msgstr "Επιθεωρήσεις" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Απόκρυψη φορμών" + +#~ msgid "Expired" +#~ msgstr "Έληξε" + +#~ msgid "&Review" +#~ msgstr "Επι&θεώρηση" + +#~ msgid "Annotations author" +#~ msgstr "Συγγραφέας σημειώσεων" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Παρακαλώ εισάγετε το όνομά ή τα αρχικά σας:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Εμφάνιση πίνακα &Πλοήγησης" + +#~ msgid "Show Text" +#~ msgstr "Εμφάνιση κειμένου" + +#~ msgid "Small Icons" +#~ msgstr "Μικρά εικονίδια" + +#~ msgid "Normal Icons" +#~ msgstr "Κανονικά εικονίδια" + +#~ msgid "Large Icons" +#~ msgstr "Μεγάλα εικονίδια" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Κλικ για χρήση του τρέχοντος εργαλείου επιλογής\n" +#~ "Κλικ στο βέλος για επιλογή άλλου εργαλείου επιλογής" + +#~ msgid "Created: %1" +#~ msgstr "Δημιουργήθηκε: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Επεκτάσεις γραμμής" + +#~ msgid "Style" +#~ msgstr "Στυλ" + +#~ msgid "&Size:" +#~ msgstr "&Μέγεθος:" + +#~ msgid "Inner color:" +#~ msgstr "Εσωτερικό χρώμα:" + +#~ msgid "Name: %1" +#~ msgstr "Όνομα: %1" + +#~ msgid "Size: %1" +#~ msgstr "Μέγεθος: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Εργαλείο &περιήγησης" + +#~ msgid "&Zoom Tool" +#~ msgstr "Εργαλείο &μεγέθυνσης" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Εστίαση" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Επιλογή" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Εργαλείο επιλογής &κειμένου" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Εργαλείο επιλογής &πίνακα" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Μεγεθυντής" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Τέλος του εγγράφου" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Κανένα" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Το έγγραφο θα ανοίξει σε λειτουργία παρουσίασης γιατί αυτό ζητήθηκε από " +#~ "το αρχείο.\n" +#~ "Επιθυμείτε κάτι τέτοιο;" + +#~ msgid "Presentation Mode" +#~ msgstr "Λειτουργία παρουσίασης" + +#~ msgid "Allow" +#~ msgstr "Επίτρεψε" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Επίτρεψε τη λειτουργία παρουσίασης" + +#~ msgid "Do Not Allow" +#~ msgstr "Να μην επιτραπεί" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Να μην επιτραπεί η λειτουργία παρουσίασης" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Οι αλλαγές στις σημειώσεις σας δεν θα αποθηκευτούν αυτόματα. " +#~ "Χρησιμοποιήστε Αρχείο -> Αποθήκευση ως...\n" +#~ "διαφορετικά οι αλλαγές σας θα χαθούν όταν κλείσει το έγγραφο" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Οι σημειώσεις σας αποθηκεύτηκαν εσωτερικά από το Okular.\n" +#~ "Μπορείτε να εξαγάγετε το σχολιασμένο έγγραφο από το Αρχείο -> Εξαγωγή ως -" +#~ "> Αρχειοθήκη εγγράφων" + +#~ msgid "Save &Copy As..." +#~ msgstr "Αποθήκευση αντι&γράφου ως..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Οι σημειώσεις σας δε θα εξαχθούν.\n" +#~ "Μπορείτε να εξάγετε το σχολιασμένο έγγραφο από το Αρχείο -> Εξαγωγή ως -> " +#~ "Αρχειοθήκη εγγράφων" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Φτάσαμε στο τέλος του εγγράφου.\n" +#~ "Συνέχεια από την αρχή;" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Έφτασε η αρχή του εγγράφου.\n" +#~ "Συνέχεια από το τέλος;" + +#~ msgid "Current maintainer" +#~ msgstr "Τρέχων συντηρητής" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " δευτ." + +#~ msgid "Pencil color:" +#~ msgstr "Χρώμα μολυβιού:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "τοπίο DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "πορτρέτο DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "τοπίο DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "πορτρέτο DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "τοπίο DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "πορτρέτο DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "τοπίο DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "πορτρέτο DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "τοπίο DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "πορτρέτο DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "τοπίο DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "πορτρέτο DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "τοπίο DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "πορτρέτο DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "τοπίο DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "πορτρέτο DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "τοπίο DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "πορτρέτο DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "τοπίο DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "πορτρέτο DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "τοπίο DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "πορτρέτο DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "τοπίο DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "πορτρέτο DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "τοπίο DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "πορτρέτο DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "τοπίο DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "πορτρέτο DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "τοπίο DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "πορτρέτο DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "τοπίο DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "πορτρέτο DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "τοπίο DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "πορτρέτο DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "τοπίο DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "πορτρέτο DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "τοπίο DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "πορτρέτο DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "τοπίο DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "πορτρέτο DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "τοπίο DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "πορτρέτο DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "τοπίο letter" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "πορτρέτο letter" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "τοπίο legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "πορτρέτο legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "τοπίο executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "πορτρέτο executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "τοπίο Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "πορτρέτο Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "τοπίο DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "πορτρέτο DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "τοπίο folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "πορτρέτο folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "καθολικό" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "τοπίο άγνωστο μέγεθος χαρτιού" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "πορτρέτο άγνωστο μέγεθος χαρτιού" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Εναλλαγή λειτουργίας σχεδίασης" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Η εκκίνηση της υπηρεσίας Jovie Κείμενο-σε-ομιλία απέτυχε: %1" + +#~ msgid "Search Columns" +#~ msgstr "Στήλες αναζήτησης" + +#~ msgid "All Visible Columns" +#~ msgstr "Όλες τις ορατές στήλες" + +#~ msgid "No document opened." +#~ msgstr "Δεν ανοίχτηκε κανένα έγγραφο." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Αδυναμία ανοίγματος περισσότερων του ενός εγγράφων στη μοναδική διεργασία " +#~ "Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Δε βρέθηκαν ταιριάσματα για το '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Αναζήτηση σε εξέλιξη..." + +#~ msgid "Searching for %1" +#~ msgstr "Αναζήτηση για %1" + +#~ msgid "Identity Settings" +#~ msgstr "Ρυθμίσεις ταυτότητας" + +#~ msgid "Highlight Properties" +#~ msgstr "Ιδιότητες τονισμού" + +#~ msgid "Ink Properties" +#~ msgstr "Ιδιότητες μελανιού" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Σημείωση κειμένου" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Πράσινο μελάνι" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Κίτρινος τονισμός" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Κίτρινος τονισμός" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Ευθεία κίτρινη γραμμή" + +#~ msgid "Black Underlining" +#~ msgstr "Μαύρη υπογράμμιση" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Υπογράμμιση κειμένου με μαύρη γραμμή" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Κυανή έλλειψη" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Μια κυανή έλλειψη" + +#~ msgid "Ink" +#~ msgstr "Μελάνι" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A1" +#~ msgstr "τοπίο DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A1" +#~ msgstr "πορτρέτο DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A2" +#~ msgstr "τοπίο DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A2" +#~ msgstr "πορτρέτο DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A3" +#~ msgstr "τοπίο DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A3" +#~ msgstr "πορτρέτο DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A4" +#~ msgstr "τοπίο DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A4" +#~ msgstr "πορτρέτο DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A5" +#~ msgstr "τοπίο DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A5" +#~ msgstr "πορτρέτο DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A6" +#~ msgstr "τοπίο DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A6" +#~ msgstr "πορτρέτο DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A7" +#~ msgstr "τοπίο DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A7" +#~ msgstr "πορτρέτο DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A8" +#~ msgstr "τοπίο DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A8" +#~ msgstr "πορτρέτο DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO A9" +#~ msgstr "τοπίο DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO A9" +#~ msgstr "πορτρέτο DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B0" +#~ msgstr "τοπίο DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B0" +#~ msgstr "πορτρέτο DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B1" +#~ msgstr "τοπίο DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B1" +#~ msgstr "πορτρέτο DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B2" +#~ msgstr "τοπίο DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B2" +#~ msgstr "πορτρέτο DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B3" +#~ msgstr "τοπίο DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B3" +#~ msgstr "πορτρέτο DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B4" +#~ msgstr "τοπίο DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B4" +#~ msgstr "πορτρέτο DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B5" +#~ msgstr "τοπίο DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B5" +#~ msgstr "πορτρέτο DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B6" +#~ msgstr "τοπίο DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B6" +#~ msgstr "πορτρέτο DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B7" +#~ msgstr "τοπίο DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B7" +#~ msgstr "πορτρέτο DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B8" +#~ msgstr "τοπίο DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B8" +#~ msgstr "πορτρέτο DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B9" +#~ msgstr "τοπίο DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B9" +#~ msgstr "πορτρέτο DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DIN/ISO B10" +#~ msgstr "τοπίο DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DIN/ISO B10" +#~ msgstr "πορτρέτο DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "τοπίο letter" +#~ msgstr "τοπίο letter" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο letter" +#~ msgstr "πορτρέτο letter" + +#~ msgctxt "paper size" +#~ msgid "τοπίο legal" +#~ msgstr "τοπίο legal" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο legal" +#~ msgstr "πορτρέτο legal" + +#~ msgctxt "paper size" +#~ msgid "τοπίο executive" +#~ msgstr "τοπίο executive" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο executive" +#~ msgstr "πορτρέτο executive" + +#~ msgctxt "paper size" +#~ msgid "τοπίο C5E" +#~ msgstr "τοπίο C5E" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο C5E" +#~ msgstr "πορτρέτο C5E" + +#~ msgctxt "paper size" +#~ msgid "τοπίο Comm10E" +#~ msgstr "τοπίο Comm10E" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο Comm10E" +#~ msgstr "πορτρέτο Comm10E" + +#~ msgctxt "paper size" +#~ msgid "τοπίο DLE" +#~ msgstr "τοπίο DLE" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο DLE" +#~ msgstr "πορτρέτο DLE" + +#~ msgctxt "paper size" +#~ msgid "τοπίο folio" +#~ msgstr "τοπίο folio" + +#~ msgctxt "paper size" +#~ msgid "πορτρέτο folio" +#~ msgstr "πορτρέτο folio" + +#~ msgid "Enable &background generation" +#~ msgstr "Ενεργοποίηση δημιουργίας &φόντου" + +#~ msgid "Reset Forms" +#~ msgstr "Επαναφορά φορμών" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Μετακινείται στην πρώτη σελίδα του εγγράφου" + +#~ msgid "You must set this name:" +#~ msgstr "Πρέπει να ορίσετε αυτό το όνομα:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Αντικατάσταση" + +#~ msgid "Pages:" +#~ msgstr "Σελίδες:" + +#~ msgid "Green Highlighter" +#~ msgstr "Πράσινος τονισμός" diff --git a/po/el/okular_chm.po b/po/el/okular_chm.po new file mode 100644 index 0000000..06cddee --- /dev/null +++ b/po/el/okular_chm.po @@ -0,0 +1,66 @@ +# translation of okular_chm.po to Greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2007. +# Σπύρος Γεωργαράς , 2008. +# Stelios , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-05-04 10:32+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "manolis@koppermind.homelinux.org" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Μη υποστηριζόμενη κωδικοποίηση" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Η κωδικοποίηση αυτού του ηλεκτρονικού βιβλίου δεν υποστηρίζεται ακόμη. " +"Ανοίξτε μια αναφορά σφάλματος στο https://bugs.kde.org για να προστεθεί η " +"υποστήριξη" + +#~ msgid "CHM Backend" +#~ msgstr "Σύστημα υποστήριξης CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Αποτύπωση αρχείων βοήθειας των Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/el/okular_comicbook.po b/po/el/okular_comicbook.po new file mode 100644 index 0000000..4b16aca --- /dev/null +++ b/po/el/okular_comicbook.po @@ -0,0 +1,62 @@ +# translation of okular_comicbook.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2008. +# Toussis Manolis , 2008. +# Stelios , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-08-06 14:03+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Αδυναμία ανοίγματος εγγράφου, καθώς δε βρέθηκε το unrar ή το unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Η έκδοση του unrar στο σύστημά σας δεν είναι κατάλληλη για το άνοιγμα των " +"βιβλίων comic." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Άγνωστη μορφή ComicBook." + +#~ msgid "ComicBook Backend" +#~ msgstr "Σύστημα υποστήριξης ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Αποτύπωση διαφόρων μορφών βιβλίων κόμικ" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/el/okular_djvu.po b/po/el/okular_djvu.po new file mode 100644 index 0000000..51d0ffb --- /dev/null +++ b/po/el/okular_djvu.po @@ -0,0 +1,140 @@ +# translation of okular_djvu.po to Greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-09-08 11:03+0300\n" +"Last-Translator: Toussis Manolis \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Επεξεργαστής" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Εκδότης" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Τόμος" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Τύπος εγγράφου" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Άγνωστο" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Αρχεία συστατικού" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Άγνωστο" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Μονή σελίδα" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Δεμένο" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Έμμεσο" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Δεμένο (παλιό)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Με ευρετήριο (παλιό)" + +#~ msgid "DjVu Backend" +#~ msgstr "Σύστημα υποστήριξης του DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Σύστημα υποστήριξης DjVu βασισμένο στο DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgid "A DjVu backend" +#~ msgstr "Ένα σύστημα υποστήριξης του DjVu" diff --git a/po/el/okular_dvi.po b/po/el/okular_dvi.po new file mode 100644 index 0000000..8d07f05 --- /dev/null +++ b/po/el/okular_dvi.po @@ -0,0 +1,797 @@ +# translation of okular_dvi.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2007, 2008, 2009. +# Stelios <>, 2013. +# Dimitris Kardarakos , 2014. +# Dimitrios Glentadakis , 2016. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2016-06-04 06:49+0200\n" +"Last-Translator: Dimitrios Glentadakis \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Το Okular δεν μπόρεσε να εντοπίσει το πρόγραμμα dvipdfm στον " +"υπολογιστή σας. Αυτό το πρόγραμμα είναι σημαντικό για τη λειτουργία της " +"εξαγωγής. Μπορείτε ωστόσο να μετατρέψετε ένα αρχείο DVI σε PDF " +"χρησιμοποιώντας την εκτύπωση του Okular, αλλά τα παραγόμενα έγγραφα ενώ θα " +"εκτυπώνονται μια χαρά θα είναι κατώτερης ποιότητας όταν προβάλλονται στο " +"Acrobat Reader. Ίσως να είναι χρήσιμη η αναβάθμιση σε πιο πρόσφατη έκδοση " +"της διανομής σας TeX η οποία θα περιλαμβάνει και το πρόγραμμα dvipdfm.

Συμβουλή για τους διαχειριστές του συστήματος: Το Okular " +"χρησιμοποιεί τη μεταβλητή περιβάλλοντος PATH για την αναζήτηση των " +"προγραμμάτων.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Το εξωτερικό πρόγραμμα 'dvipdfm', το οποίο χρησιμοποιήθηκε κατά την " +"εξαγωγή του αρχείου, ανέφερε κάποιο σφάλμα. Ίσως θα πρέπει να δείτε το " +"διάλογο πληροφοριών του εγγράφου τον οποίο θα βρείτε στο " +"μενού αρχείο για μια ακριβή αναφορά του σφάλματος." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Αυτό το αρχείο DVI χρησιμοποιεί εξωτερικά αρχεία γραφικών που δεν είναι " +"σε μορφή PostScript, τα οποία και δεν μπορεί να διαχειριστεί το πρόγραμμα " +"dvips, το οποίο χρησιμοποιείται εσωτερικά από το Okular για " +"εκτύπωση ή εξαγωγή σε PostScript. Η λειτουργία που ζητήσατε δεν είναι " +"διαθέσιμη σε αυτή την έκδοση του Okular" + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Το Okular δεν μπόρεσε να εντοπίσει το πρόγραμμα dvips στον " +"υπολογιστή σας. Αυτό το πρόγραμμα είναι σημαντικό για τη λειτουργία της " +"εξαγωγής.

Συμβουλή για τους διαχειριστές του συστήματος: Το Okular " +"χρησιμοποιεί τη μεταβλητή περιβάλλοντος PATH για την αναζήτηση των " +"προγραμμάτων.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Το εξωτερικό πρόγραμμα 'dvips', το οποίο χρησιμοποιήθηκε για την εξαγωγή " +"του αρχείου, ανέφερε ένα σφάλμα. Για μια ακριβή αναφορά του σφάλματος, θα " +"πρέπει να κοιτάξετε το διάλογο πληροφοριών του εγγράφου τον " +"οποίο θα βρείτε στο μενού Αρχείο." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Το αρχείο DVI δεν ξεκινάει με το προοίμιο." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"Το αρχείο DVI περιέχει εσφαλμένη έκδοση εξόδου DVI για αυτό το πρόγραμμα. " +"Υπόδειξη: Αν χρησιμοποιείτε το σύστημα στοιχειοθέτησης Omega, θα πρέπει να " +"χρησιμοποιήσετε κάποιο ειδικό πρόγραμμα, όπως το oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"Το αρχείο DVI είναι κατεστραμμένο. Το Okular δεν μπόρεσε να εντοπίσει τον " +"επίλογο." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Ο επίλογος δεν αρχίζει με την εντολή POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Ο επίλογος περιέχει μία εντολή διαφορετική της FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Η σελίδα %1 δεν ξεκινά με την εντολή BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Το εξωτερικό πρόγραμμα pdf2ps δεν μπόρεσε να " +"εκκινήσει. Επομένως, το αρχείο PDF %1 δεν μπορεί να μετατραπεί σε " +"PostScript. Μερικά γραφικά στοιχεία του εγγράφου δε θα εμφανιστούν.

Πιθανή αιτία: Το πρόγραμμα pdf2ps μπορεί να μην " +"είναι εγκατεστημένο στο σύστημά σας, ή δεν μπορεί να βρεθεί στην τρέχουσα " +"διαδρομή αναζήτησης.

Τι μπορείτε να κάνετε: Το πρόγραμμα " +"pdf2ps περιέχεται συνήθως σε διανομές του συστήματος " +"ghostscript μεταγλώττισης PostScript. Αν το ghostscript δεν είναι " +"εγκατεστημένο στο σύστημά σας, μπορείτε να το εγκαταστήσετε τώρα. Αν είστε " +"σίγουρος-η ότι το ghostscript είναι εγκατεστημένο, παρακαλώ δοκιμάστε να " +"εκτελέσετε το pdf2ps από τη γραμμή εντολών για να " +"εξακριβώσετε αν αυτό λειτουργεί.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Το PDF αρχείο %1 δεν μπορεί να μετατραπεί σε PostScript. Μερικά " +"γραφικά στοιχεία του εγγράφου σας δε θα εμφανιστούν.

Πιθανή αιτία:" +" Το αρχείο %1 μπορεί να είναι χαλασμένο, ή να μην πρόκειται για ένα " +"αρχείο PDF. Αυτή είναι η έξοδος του προγράμματος pdf2ps που " +"χρησιμοποίησε το Okular:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Αλλοίωση αρχείου. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"Δεν μπόρεσαν να ενσωματωθούν στο έγγραφό σας όλα τα αρχεία PostScript. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Όλα τα εξωτερικά αρχεία PostScript ενσωματώθηκαν στο έγγραφό σας." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Το καθορισμένο αρχείο '%1' δεν υπάρχει." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Ζητήσατε από το Okular να εντοπίσει την τοποθεσία στο αρχείο DVI που " +"αντιστοιχείστη γραμμή %1 στο αρχείο TeX %2. Παρόλα αυτά, φαίνεται πώς το " +"αρχείο DVI δεν περιέχει τις απαραίτητες πληροφορίες του αρχείου πηγής." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Το Okular δεν μπόρεσε να εντοπίσει τη θέση στο αρχείο DVI που αντιστοιχεί " +"στη γραμμή %1 του αρχείου TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "Ο κώδικας DVI καθόρισε ένα χαρακτήρα μίας άγνωστης γραμματοσειράς." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"Ο κώδικας DVI αναφέρθηκε στη γραμματοσειρά #%1, η οποία δεν έχει " +"προηγουμένως οριστεί." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Η στοίβα δεν ήταν άδεια όταν παρουσιάστηκε η εντολή EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Η στοίβα ήταν άδεια όταν παρουσιάστηκε μία εντολή POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"Ο κώδικας DVI αναφέρθηκε σε μία γραμματοσειρά η οποία δεν έχει προηγουμένως " +"οριστεί." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Βρέθηκε μια άγνωστη εντολή." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Βρέθηκε ένας άγνωστος κωδικός %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Ενσωμάτωση του %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Σελίδα %1: Το αρχείο PDF %2 δεν μπόρεσε να μετατραπεί σε " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Σελίδα %1: Το αρχείο PostScript %2 ήταν αδύνατο να βρεθεί." +"
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Τα δεδομένα μεγέθους χαρτιού '%1' δεν ήταν δυνατό να αναλυθούν." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Το Okular δεν μπόρεσε να εντοπίσει όλα τα αρχεία γραμματοσειρών που " +"απαιτούνται για την εμφάνιση του τρέχοντος αρχείου DVI. Το έγγραφό σας " +"μπορεί να μην είναι αναγνώσιμο.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Υπήρξαν προβλήματα στην εκτέλεση του kpsewhich, με " +"αποτέλεσμα, κάποια από τα αρχεία γραμματοσειρών να μην εντοπιστούν και το " +"έγγραφο ενδεχομένως να μην μπορεί να διαβαστεί.
Πιθανή αιτία: Το " +"πρόγραμμα kpsewhich ίσως να μην είναι εγκατεστημένο στον υπολογιστή " +"σας, ή να μην μπορεί να εντοπιστεί στην τρέχουσα διαδρομή αναζήτησης.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Η δημιουργία γραμματοσειρών με το kpsewhich εγκαταλείφθηκε " +"(κωδικός εξόδου %1, σφάλμα %2). Ως αποτέλεσμα, μερικά αρχεία γραμματοσειρών " +"δε θα μπορέσουν να φορτωθούν και μπορεί το έγγραφό σας να μην είναι " +"αναγνώσιμο." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Δημιουργία της γραμματοσειράς %1 στα %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Δημιουργός/Ημερομηνία" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Το αρχείο γραμματοσειράς δε βρέθηκε" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "πορτραίτο" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "τοπίο" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Η έκδοση του Ghostview που είναι εγκατεστημένη σε αυτόν τον υπολογιστή δεν " +"περιέχει κανέναν από τους γνωστούς στο Okular οδηγούς συσκευών του " +"Ghostview. Για αυτό τον λόγο η υποστήριξη του PostScript απενεργοποιήθηκε " +"στο Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Το πρόγραμμα Ghostview, το οποίο χρησιμοποιεί εσωτερικά το Okular για " +"να εμφανίζει τα γραφικά PostScript που περιέχονται σε αυτό το αρχείο DVI, " +"συνήθως παρέχει τη δυνατότητα να γράψει την έξοδό του σε διάφορες μορφές. Τα " +"υποπρογράμματα που χρησιμοποιεί το Ghostview για αυτές τις εργασίες " +"ονομάζονται 'οδηγοί συσκευών'. Για κάθε υποστηριζόμενη μορφή εξόδου του " +"Ghostview υπάρχει και ο αντίστοιχος οδηγός συσκευής. Απ' ότι φαίνεται, η " +"έκδοση του Ghostview που έχετε εγκατεστημένη στον υπολογιστή σας δεν " +"περιέχει κανέναν από τους γνωστούς στο Okular οδηγούς " +"συσκευών.

Είναι απίθανο μία τυπική εγκατάσταση του Ghostview να μην " +"περιέχει αυτούς τους οδηγούς. Αυτό το σφάλμα λοιπόν οφείλεται σε κακή " +"εγκατάσταση του Ghostview στον υπολογιστή σας.

Αν θέλετε να διορθώσετε " +"τα προβλήματα με το Ghostview, μπορείτε να χρησιμοποιήσετε την εντολή " +"gs --help για να εμφανίσετε τη λίστα των οδηγών συσκευών " +"που περιέχονται στο Ghostview. Μεταξύ άλλων, το okular μπορεί να " +"χρησιμοποιήσει τους οδηγούς 'png256', 'jpeg' και 'pnm'. Σημειώστε ότι το " +"Okular θα πρέπει να επανεκκινηθεί για να επανενεργοποιηθεί η υποστήριξη του " +"PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"Σημειώθηκαν ήδη 25 σφάλματα. Από εδώ και πέρα δε θα εμφανίζονται μηνύματα " +"σφάλματος." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Σφάλμα στο αρχείο DVI '%1', σελίδα %2. Βρέθηκε εντολή χρώματος pop ενώ η " +"στοίβα χρώματος είναι άδεια." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Κακοδιατυπωμένη παράμετρος στην εντολή epsf.\n" +"Αναμένονταν ένας αριθμός κινητής υποδιαστολής να ακολουθεί το %1 στο %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Το αρχείο δε βρέθηκε: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Σφάλμα στο αρχείο DVI '%1', σελίδα %2. Δεν είναι δυνατός ο προσδιορισμός της " +"γωνίας στην εντολή περιστροφής." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Η ειδική εντολή '%1' δεν έχει υλοποιηθεί ακόμη." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Το αρχείο γραμματοσειράς %1 ανοίχτηκε και διαβάστηκε αλλά η μορφή του δεν " +"υποστηρίζεται." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Το αρχείο γραμματοσειράς %1 είναι χαλασμένο ή ήταν αδύνατο να ανοιχτεί ή " +"διαβαστεί." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"Το FreeType ανέφερε ένα σφάλμα κατά τον ορισμό του μεγέθους χαρακτήρα για το " +"αρχείο γραμματοσειράς %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"Το FreeType δεν μπορεί να φορτώσει τη γλυφή #%1 από το αρχείο γραμματοσειράς " +"%2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"Το FreeType δεν μπορεί να χρησιμοποιηθεί για την αποτύπωση της γλυφής #%1 " +"από το αρχείο γραμματοσειράς %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Η γλυφή #%1 είναι κενή." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Η γλυφή #%1 από το αρχείο γραμματοσειράς %2 είναι κενή." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"Το FreeType δεν μπόρεσε να φορτώσει πληροφορίες διαστάσεων για τη γλυφή #%1 " +"του αρχείου γραμματοσειράς %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Αδύνατο το άνοιγμα του αρχείου γραμματοσειράς %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: Ο χαρακτήρας %1 δεν είναι ορισμένος στη " +"γραμματοσειρά %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Μη αναμενόμενο %1 στο αρχείο PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Ο χαρακτήρας %1 είναι πολύ μεγάλος στο αρχείο %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Εσφαλμένος αριθμός αποθηκευμένων bit: χαρ %1. γραμματοσειρά %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Χαλασμένο αρχείο pk (%1), πάρα πολλά bit" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Η γραμματοσειρά έχει μη τετραγωνικό λόγο διαστάσεων" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Αδύνατη η εύρεση της γραμματοσειράς %1, αρχείο %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Το άθροισμα ελέγχου δεν ταιριάζει για το αρχείο γραμματοσειράς %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Δεν είναι δυνατό να αναγνωριστεί ο τύπος του αρχείου γραμματοσειράς %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Κρίσιμο σφάλμα.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Αυτό σημαίνει ότι βρήκατε ένα σφάλμα στο Okular, ή ότι το αρχείο\n" +"DVI, ή τα βοηθητικά του αρχεία (όπως αρχεία γραμματοσειρών, ή\n" +"εικονικών γραμματοσειρών) είναι κατεστραμμένα.\n" +"Το Okular θα τερματίσει μετά από αυτό το μήνυμα. Αν πιστεύετε ότι\n" +"βρήκατε ένα σφάλμα, ή ότι το Okular θα έπρεπε να διαχειριστεί\n" +"καλύτερα αυτή την κατάσταση, παρακαλώ αναφέρετε το πρόβλημα." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Εντοπίστηκε εσφαλμένη εντολή byte στη λίστα μακροεντολής VF: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Σύστημα υποστήριξης DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Ένας αποτυπωτής αρχείων DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Το Okular χρησιμοποιεί το πρόγραμμα kpsewhich για τον εντοπισμό " +#~ "αρχείων γραμματοσειρών στο σκληρό σας δίσκο και για τη δημιουργία " +#~ "γραμματοσειρών PK, αν αυτό απαιτείται.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Το Okular αυτή τη στιγμή δημιουργεί γραμματοσειρές bitmap..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Εγκατάλειψη της δημιουργίας γραμματοσειρών. Μη το κάνετε αυτό." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Το Okular δημιουργεί τις γραμματοσειρές bitmap που απαιτούνται για την " +#~ "εμφάνιση του εγγράφου σας. Για αυτό το Okular χρησιμοποιεί διάφορα " +#~ "εξωτερικά προγράμματα, όπως το MetaFont. Θα μπορέσετε να βρείτε την έξοδο " +#~ "αυτών των προγραμμάτων αργότερα στο διάλογο πληροφοριών του εγγράφου." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Το Okular δημιουργεί τις γραμματοσειρές. Παρακαλώ περιμένετε." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Διάλογος προόδου δημιουργίας γραμματοσειρών" + +#~ msgid "Abort" +#~ msgstr "Εγκατάλειψη" + +#~ msgid "What is happening here?" +#~ msgstr "Τι συμβαίνει εδώ;" + +#~ msgid "%v of %m" +#~ msgstr "%v από %m" + +#~ msgid "Please be patient" +#~ msgstr "Παρακαλώ να είστε υπομονετικοί" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Εξαγωγή αρχείου ως" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Το αρχείο %1\n" +#~ "υπάρχει. Επιθυμείτε την αντικατάστασή του;" + +#~ msgid "Overwrite File" +#~ msgstr "Αντικατάσταση αρχείου" + +#~ msgid "Overwrite" +#~ msgstr "Αντικατάσταση" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Χρήση του dvipdfm για την εξαγωγή του αρχείου σε PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Το Okular χρησιμοποιεί το εξωτερικό πρόγραμμα 'dvipdfm' για να μετατρέψει " +#~ "το DVI αρχείο σας σε PDF. Κάποιες φορές αυτό μπορεί να πάρει αρκετό χρόνο " +#~ "αφού το dvipdfm πρέπει να δημιουργήσει τις δικές του bitmap " +#~ "γραμματοσειρές. Παρακαλώ έχετε υπομονή." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Αναμονή για την ολοκλήρωση της εργασίας του dvipdfm..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Χρήση του dvips για την εξαγωγή του αρχείου σε PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Το Okular χρησιμοποιεί το εξωτερικό πρόγραμμα 'dvipdfm' για να μετατρέψει " +#~ "το DVI αρχείο σας σε PostScript. Κάποιες φορές αυτό μπορεί να πάρει " +#~ "αρκετό χρόνο αφού το dvipdfm πρέπει να δημιουργήσει τις δικές του bitmap " +#~ "γραμματοσειρές. Παρακαλώ έχετε υπομονή." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Αναμονή για τον τερματισμό του dvipdfm..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Το χαρακτηριστικό δεν είναι διαθέσιμο" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Κατεστραμμένο αρχείο Το Okular δεν μπόρεσε να " +#~ "μεταγλωττίσει το DVI αρχείο σας. Συνήθως αυτό οφείλεται σε ένα " +#~ "κατεστραμμένο αρχείο." + +#~ msgid "DVI File Error" +#~ msgstr "Σφάλμα DVI αρχείου" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Δε βρέθηκαν όλα τα αρχεία γραμματοσειρών" + +#~ msgid "Locating fonts..." +#~ msgstr "Εντοπισμός γραμματοσειρών..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Υπήρξαν προβλήματα κατά την εκτέλεση του kpsewhich. Σαν " +#~ "αποτέλεσμα, μερικά αρχεία γραμματοσειρών δεν εντοπίστηκαν και το έγγραφό " +#~ "σας μπορεί να είναι μη αναγνώσιμο.

Πιθανή αιτία: Το " +#~ "πρόγραμμα kpsewhich δεν είναι εγκατεστημένο στο σύστημά σας, ή δεν μπορεί " +#~ "να βρεθεί στο τρέχον path εκτέλεσης.

Τι μπορείτε να κάνετε: " +#~ "Το πρόγραμμα kpsewhich περιέχεται συνήθως σε διανομές του συστήματος " +#~ "τυπογραφίας TeX. Αν το TeX δεν είναι εγκατεστημένο στο σύστημά σας, " +#~ "μπορείτε να εγκαταστήσετε τη διανομή TeTeX (www.tug.org/texlive). Αν " +#~ "είστε σίγουροι ότι το TeX είναι εγκατεστημένο, παρακαλώ δοκιμάστε να " +#~ "εκτελέσετε το kpsewhich από τη γραμμή εντολών για να εξακριβώσετε αν αυτό " +#~ "λειτουργεί.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Πρόβλημα εντοπισμού γραμματοσειρών" + +#~ msgid "Font generation aborted" +#~ msgstr "Η δημιουργία γραμματοσειρών εγκαταλείφθηκε" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Εξαγωγή: %1 σε PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Εξαγωγή: %1 σε PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Η λίστα γραμματοσειρών είναι κενή προς το παρόν." + +#~ msgid "TeX Name" +#~ msgstr "Όνομα TeX" + +#~ msgid "Family" +#~ msgstr "Οικογένεια" + +#~ msgid "Zoom" +#~ msgstr "Εστίαση" + +#~ msgid "Type" +#~ msgstr "Τύπος" + +#~ msgid "Encoding" +#~ msgstr "Κωδικοποίηση" + +#~ msgid "Comment" +#~ msgstr "Σχόλιο" + +#~ msgid "TeX virtual" +#~ msgstr "Εικονικό TeX" + +#~ msgid "TeX Font Metric" +#~ msgstr "Πληροφορίες διαστάσεων γραμματοσειράς TeX" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/el/okular_epub.po b/po/el/okular_epub.po new file mode 100644 index 0000000..694810c --- /dev/null +++ b/po/el/okular_epub.po @@ -0,0 +1,58 @@ +# translation of okular_epub.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2008. +# Dimitrios Glentadakis , 2014. +# Dimitris Kardarakos , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-08 20:48+0200\n" +"Last-Translator: Dimitris Kardarakos \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Σφάλμα κατά το άνοιγμα του εγγράφου EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Σύστημα υποστήριξης του EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Ένα σύστημα υποστήριξης του EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/el/okular_fax.po b/po/el/okular_fax.po new file mode 100644 index 0000000..119db49 --- /dev/null +++ b/po/el/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Toussis Manolis , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-19 19:46+0200\n" +"Last-Translator: Toussis Manolis \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "manolis@koppermind.homelinux.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Αδυναμία φόρτωσης του εγγράφου" + +#~ msgid "Fax Backend" +#~ msgstr "Σύστημα υποστήριξης φαξ" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Ένα σύστημα υποστήριξης εγγράφων φαξ G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/el/okular_fictionbook.po b/po/el/okular_fictionbook.po new file mode 100644 index 0000000..be0e3db --- /dev/null +++ b/po/el/okular_fictionbook.po @@ -0,0 +1,82 @@ +# translation of okular_fictionbook.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Dimitris Kardarakos , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-08 20:48+0200\n" +"Last-Translator: Dimitris Kardarakos \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Το έγγραφο δεν είναι έγκυρο FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Αδύνατο το άνοιγμα του εγγράφου: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Το έγγραφο δεν είναι μία έγκυρη αρχειοθήκη ZIP" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Μη έγκυρη δομή εγγράφου (λείπει ο κύριος κατάλογος)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Το έγγραφο είναι κενό" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Μη έγκυρο αρχείο XML: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Σύστημα υποστήριξης Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Αποτύπωση βιβλίων FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/el/okular_ghostview.po b/po/el/okular_ghostview.po new file mode 100644 index 0000000..5f36fc8 --- /dev/null +++ b/po/el/okular_ghostview.po @@ -0,0 +1,94 @@ +# translation of okular_ghostview.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2008, 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-04-23 23:01+0300\n" +"Last-Translator: Toussis Manolis \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Χρήση γραμματοσειρών της πλατφόρμας" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Καθορίζει αν το Ghostscript θα επιτρέπεται να χρησιμοποιεί γραμματοσειρές " +"της πλατφόρμας, αν είναι ανενεργό επιτρέπεται η χρήση μόνο των ενσωματωμένων " +"γραμματοσειρών στο έγγραφο." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Γενικές ρυθμίσεις" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Χρήση των γραμματοσειρών της πλατφόρμας" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Ρυθμίσεις συστήματος υποστήριξης του Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Έκδοση του εγγράφου" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Επίπεδο γλώσσας" + +#~ msgid "PS Backend" +#~ msgstr "Σύστημα υποστήριξης PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Αποτύπωση αρχείων PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Βασισμένο στη βιβλιοθήκη Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/el/okular_kimgio.po b/po/el/okular_kimgio.po new file mode 100644 index 0000000..ef02340 --- /dev/null +++ b/po/el/okular_kimgio.po @@ -0,0 +1,73 @@ +# translation of okular_kimgio.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2007. +# Stelios , 2011, 2017. +# Dimitrios Glentadakis , 2011. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-16 10:30+0200\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "manolis@koppermind.homelinux.org" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Αδυναμία φόρτωσης του εγγράφου: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Αυτό το έγγραφο εμφανίζεται με λάθος μορφή. Εδώ είναι μια βέλτιστη " +"προσέγγιση της προτιθέμενης εμφάνισης του εγγράφου." + +#~ msgid "Image Backend" +#~ msgstr "Σύστημα υποστήριξης εικόνας" + +#~ msgid "A simple image backend" +#~ msgstr "Ένα απλό σύστημα υποστήριξης εικόνων" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Κύρια γραμμή εργαλείων" diff --git a/po/el/okular_markdown.po b/po/el/okular_markdown.po new file mode 100644 index 0000000..4138cdc --- /dev/null +++ b/po/el/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Stelios , 2017, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-08-06 14:07+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 18.12.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Stelios" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sstavra@gmail.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Αποτυχία ανοίγματος του εγγράφου" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Αποτυχία μεταγλώττισης του markdown εγγράφου." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Ενεργοποίηση SmartyPants διαμόρφωση" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης Markdown" diff --git a/po/el/okular_mobi.po b/po/el/okular_mobi.po new file mode 100644 index 0000000..5f8e8d6 --- /dev/null +++ b/po/el/okular_mobi.po @@ -0,0 +1,64 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Toussis Manolis , 2008, 2009. +# Dimitris Kardarakos , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-30 18:48+0300\n" +"Last-Translator: Dimitris Kardarakos \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "manolis@koppermind.homelinux.org" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Σφάλμα κατά το άνοιγμα του εγγράφου Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Το βιβλίο αυτό προστατεύεται από DRM και μπορεί να εμφανιστεί μόνο σε " +"καθορισμένες συσκευές" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Σύστημα υποστήριξης Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Ένα σύστημα υποστήριξης για το mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/el/okular_plucker.po b/po/el/okular_plucker.po new file mode 100644 index 0000000..8925f52 --- /dev/null +++ b/po/el/okular_plucker.po @@ -0,0 +1,46 @@ +# translation of okular_plucker.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-04-29 18:12+0300\n" +"Last-Translator: Toussis Manolis \n" +"Language-Team: greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Όνομα" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Σύστημα υποστήριξης εγγράφων Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Αποτύπωση βιβλίων Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/el/okular_poppler.po b/po/el/okular_poppler.po new file mode 100644 index 0000000..35f99a7 --- /dev/null +++ b/po/el/okular_poppler.po @@ -0,0 +1,230 @@ +# translation of okular_poppler.po to Greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Σπύρος Γεωργαράς , 2008. +# Dimitrios Glentadakis , 2011. +# Stelios , 2011, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-08-06 14:16+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Stelios" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, sstavra@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Εμπλουτισμός λεπτών γραμμών:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Όχι" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Συμπαγές" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Σχήμα" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Επιλογές PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Εκτύπωση σημειώσεων" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Να περιλαμβάνονται οι σημειώσεις στο εκτυπωμένο έγγραφο" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Περιλαμβάνονται σημειώσεις στο εκτυπωμένο έγγραφο. Μπορείτε να το " +"απενεργοποιήσετε αυτό αν θέλετε να εκτυπώσετε το αρχικό χωρίς σχολιασμό " +"έγγραφο." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Εξαναγκασμός χρωματικής περίπλεξης" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Χρωματική περίπλεξη εικόνας πριν την εκτύπωση" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Εξαναγκασμός χρωματικής περίπλεξης κάθε σελίδας σε μια εικόνα πριν την " +"εκτύπωσή της. Αυτό συνήθως αποδίδει χειρότερο αποτέλεσμα, αλλά είναι χρήσιμο " +"όταν κατά την εκτύπωση τα έγγραφα εμφανίζονται εσφαλμένα." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Εφαρμογή σε εκτυπώσιμη περιοχή" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Εφαρμογή σε πλήρη σελίδα" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Καμία: εκτύπωση αρχικού μεγέθους" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Λειτουργία κλιμάκωσης για τις εκτυπωμένες σελίδες" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Λειτουργία κλιμάκωσης:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF εκδ. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Τύπος αρχειοθέτησης" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Κρυπτογραφημένο" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Μη κρυπτογραφημένο" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Ασφάλεια" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Ναι" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Βελτιστοποιημένο" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Χρήση Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Χρήση Poppler %1\n" +"\n" +"Κατασκευή κατά Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Μη διαθέσιμο" + +#~ msgid "PDF Backend" +#~ msgstr "Σύστημα υποστήριξης PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Ένα πρόγραμμα αποτύπωσης αρχείων PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Η αποθήκευση αρχείων με /Encrypt δεν υποστηρίζεται." + +#~ msgid "Unknown" +#~ msgstr "Άγνωστο" + +#~ msgid "Unknown Date" +#~ msgstr "Άγνωστη ημερομηνία" + +#~ msgid "Unknown Encryption" +#~ msgstr "Άγνωστη κρυπτογράφηση" + +#~ msgid "Unknown Optimization" +#~ msgstr "Άγνωστη βελτιστοποίηση" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Παρακαλώ εισαγάγετε τον κωδικό για να διαβάσετε το έγγραφο:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Λανθασμένος κωδικός. Δοκιμάστε ξανά:" + +#~ msgid "Document Password" +#~ msgstr "Κωδικός πρόσβασης εγγράφου" diff --git a/po/el/okular_tiff.po b/po/el/okular_tiff.po new file mode 100644 index 0000000..d446a77 --- /dev/null +++ b/po/el/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Stelios , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-08-05 09:31+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Stelios" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sstavra@gmail.com" diff --git a/po/el/okular_txt.po b/po/el/okular_txt.po new file mode 100644 index 0000000..0dc8eb4 --- /dev/null +++ b/po/el/okular_txt.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Dimitris Kardarakos , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-08 21:34+0200\n" +"Last-Translator: Dimitris Kardarakos \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Δημήτρης Καρδαράκος" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "dimkard@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Διαμόρφωση συστήματος υποστήριξης txt" + +#~ msgid "Txt Backend" +#~ msgstr "Σύστημα υποστήριξης txt" + +#~ msgid "Txt backend." +#~ msgstr "Σύστημα υποστήριξης txt." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/el/okular_xps.po b/po/el/okular_xps.po new file mode 100644 index 0000000..26e6640 --- /dev/null +++ b/po/el/okular_xps.po @@ -0,0 +1,59 @@ +# translation of okular_xps.po to greek +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Spiros Georgaras , 2007. +# Toussis Manolis , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-09-08 11:06+0300\n" +"Last-Translator: Toussis Manolis \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Σπύρος Γεωργαράς, Τούσης Μανώλης" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sng@hellug.gr, manolis@koppermind.homelinux.org" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Αναθεώρηση" + +#~ msgid "XPS Backend" +#~ msgstr "Σύστημα υποστήριξης XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Ένα σύστημα υποστήριξης XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/el/org.kde.active.documentviewer.po b/po/el/org.kde.active.documentviewer.po new file mode 100644 index 0000000..2b20080 --- /dev/null +++ b/po/el/org.kde.active.documentviewer.po @@ -0,0 +1,81 @@ +# org.kde.active.documentviewer.po translation el +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Stelios , 2012, 2017, 2019. +msgid "" +msgstr "" +"Project-Id-Version: org.kde.active.documentviewer\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-07 08:33+0300\n" +"Last-Translator: Stelios \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 18.12.3\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Άνοιγμα..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Αφαίρεση σελιδοδείκτη" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Προσθέστε αυτήν τη σελίδα στους σελιδοδείκτες" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Εικόνες επισκόπησης" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Περιεχόμενα" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Σελιδοδείκτες" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Αναζήτηση..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Δεν βρέθηκαν αποτελεματα." + +#~ msgid "Document to open..." +#~ msgstr "Έγγραφο για άνοιγμα..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Δεν βρέθηκαν έγγραφα. Για να διαβάσετε, τοποθετήστε μερικά αρχεία στο " +#~ "φάκελο Documents (Έγγραφα) της συσκευής σας." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Προβολέας εγγράφων για το Plasma Active με χρήση του Okular" + +#~ msgid "Reader" +#~ msgstr "Πρόγραμμα ανάγνωσης" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL του αρχείου για άνοιγμα" diff --git a/po/en_GB/okular.po b/po/en_GB/okular.po new file mode 100644 index 0000000..fbc0279 --- /dev/null +++ b/po/en_GB/okular.po @@ -0,0 +1,5946 @@ +# translation of okular.po to British English +# Copyright (C) 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. +# +# Malcolm Hunter , 2003, 2004, 2005, 2006, 2008. +# Andrew Coles , 2004, 2005, 2009, 2010. +# Steve Allewell , 2014, 2015, 2016, 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-27 12:09+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, a universal document viewer" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Former maintainer" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Lots of framework work, ODT and FictionBook backends" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Developer" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Created Okular from KPDF codebase" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF developer" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Annotations artwork" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Table selection tool" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Annotation improvements" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Go to page %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Open external file" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Execute '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "First Page" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Previous Page" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Next Page" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Last Page" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Back" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Forward" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Quit" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Start Presentation" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "End Presentation" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Find..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Go To Page..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Play sound..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript Script" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Play movie..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Play movie" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stop movie" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Pause movie" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Resume movie" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Backend Selection" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Most pages are %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Portrait %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Landscape %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Continuing search from beginning" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Continuing search from bottom" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Can not find a plugin which is able to handle the document being passed." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "remove annotations" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "No application found for opening file of mimetype %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Could not open a temporary file" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Print conversion failed" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Printing process crashed" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Printing process could not start" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Printing to file failed" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Printer was in invalid state" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Unable to find file to print" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "There was no file to print" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "The page print size is invalid" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Could not open '%1'. File does not exist" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Title" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Subject" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Description" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Author" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creator" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Producer" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Pages" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Created" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modified" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Mime Type" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Category" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Keywords" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "File Path" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "File Size" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Page Size" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "add annotation" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "remove annotation" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "modify annotation properties" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "translate annotation" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "adjust annotation" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "edit text" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "edit annotation contents" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "edit form contents" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "edit list form choices" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "edit combo form selection" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "edit form button states" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Plain &Text..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument Text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Print Options" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Fit to printable area" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Fit to full page" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Scale mode:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Missing alert type" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Do not show this message again" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Source: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Default Font:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Red" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Orange" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Yellow" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Green" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cyan" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blue" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "White" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Grey" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Black" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Width %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Annotation line width (No annotation selected)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Annotation colour (No annotation selected)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Annotation fill colour (No annotation selected)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Annotation opacity (No annotation selected)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Annotation font (No annotation selected)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Advanced settings for the current annotation tool (No annotation selected)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Annotation line width" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Annotation line width (Current annotation has no line width)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Annotation text colour" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Annotation border colour" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Annotation colour" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Annotation fill colour" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "Annotation fill colour (Current annotation has no fill colour)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Annotation font" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Annotation font (Current annotation has no font)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Constrain line angle to 15° steps" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Constrain shape ratio to 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Annotation opacity" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Add the current annotation to the quick annotations menu" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Advanced settings for the current annotation tool" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Colour" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Fill Colour" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparent" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Custom Colour..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Experimental feature" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Select colour" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotations" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Hide" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Highlighter" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Underline" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Squiggle" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Strike Out" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Typewriter" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Inline Note" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Popup Note" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Freehand Line" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Straight line" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Arrow" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polygon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometrical shapes" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Stamp" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Quick Annotations" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Choose an annotation tool from the quick annotations" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Add to Quick Annotations" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Keep Active" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Keep the annotation tool active after use" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Constrain Ratio and Angle of Annotation Tools" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Font" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Annotation Settings" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Line width" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacity" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Page %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotation" +msgstr[1] "%1 Annotations" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Open Pop-up Note" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Delete" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Properties" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Save '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Appearance" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&General" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Author:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Created:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modified:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Pop-up Note Properties" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Typewriter Properties" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Inline Note Properties" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Straight Line Properties" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Polygon Properties" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Geometry Properties" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Text Markup Properties" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Stamp Properties" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Freehand Line Properties" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Caret Properties" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "File Attachment Properties" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Sound Properties" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Movie Properties" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Annotation Properties" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modified: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Select a custom stamp symbol from file" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Select custom stamp symbol" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Could not load the file %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Invalid file" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Colour:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacity:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icon:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Comment" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Help" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Insert" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Key" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "New paragraph" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Note" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragraph" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Font:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Text &colour:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Align:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Left" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centre" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Right" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Border &width:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Approved" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "As Is" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidential" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departmental" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Draft" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "For Comment" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "For Public Release" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Not Approved" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Not For Public Release" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Sold" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Top Secret" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Bookmark" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Information" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Stamp symbol:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Width:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Line start:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Line end:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Square" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Circle" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamond" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Open Arrow" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Closed Arrow" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "None" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Butt" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Right Open Arrow" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Right Closed Arrow" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Slash" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Leader line length:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Leader line extensions length:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Enabled" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Shape fill:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Type:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Highlight" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Squiggle" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Underline" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Strike out" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "File attachment symbol:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graph" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Push Pin" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Paperclip" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Tag" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "File" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "No description available." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Name:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Description:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Caret symbol:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "None" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Close this note" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Options" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"This annotation may contain LaTeX code.\n" +"Click here to render." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Cannot find latex executable." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX rendering failed" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Cannot find dvipng executable." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "A problem occurred during the execution of the 'latex' command." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "A problem occurred during the execution of the 'dvipng' command." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"One bookmark" +msgstr[1] "" +"%1\n" +"\n" +"%2 bookmarks" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Bookmarks" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Search..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Current document only" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Go to This Bookmark" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Rename Bookmark" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Remove Bookmark" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Open Document" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Remove Bookmarks" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Version" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Serial Number" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Issuer" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Issued On" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Expires On" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Subject" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Public Key" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Key Usage" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Property" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Value" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Certificate Viewer" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Export..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "General" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Issued By" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Common Name(CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "EMail" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisation(O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Issued To" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validity" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Fingerprints" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1 Fingerprint" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256 Fingerprint" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Details" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Certificate Data:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Where do you want to save this certificate?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Certificate File (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Could not export the certificate" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Red" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Green" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blue" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Yellow" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Black" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "White" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Draw border around &Images" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Draw border around &Links" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Change &colours" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Warning: these options can badly affect drawing speed." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Colour mode:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Invert Colours" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Change Paper Colour" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Change Dark & Light Colours" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Convert to Black & White" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Invert Lightness" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Invert Luma (sRGB Linear)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Invert Luma (Symmetric)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Shift Hue Positive" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Shift Hue Negative" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Paper colour:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Dark colour:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Light colour:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Threshold:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Speech" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Engine" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identity" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&thor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Quick annotation tools" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Custom Text Editor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs client" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx client" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Choose the editor you want to launch when Okular wants to open a source file." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Command:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Appearance" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Use smooth scrolling" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Show scroll&bars" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Link the &thumbnails with the page" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Show &hints and info messages" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Display document title in titlebar if available" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "When not displaying document title:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Display file name only" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Display full file path" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Use custom background colour" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Program Features" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Open new files in &tabs" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Switch to existing tab if file is already open" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obey DRM limitations" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Reload document on file change" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Show backend selection dialogue" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Right to left reading direction" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "View Options" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Overview &columns:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Page Up/Down overlap:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Default Zoom:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Fit Width" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Fit Page" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Auto Fit" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "CPU Usage" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Enable &transparency effects" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Memory Usage" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Low" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (default)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Aggr&essive" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "G&reedy" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rendering" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Enable Text Antialias" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Enable Graphics Antialias" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Enable Text Hinting" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Current Screen" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Default Screen" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Screen %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " second" +msgstr[1] " seconds" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigation" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Advance every:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Loop after last page" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Touch navigation:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Tap left/right side to go back/forward" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Tap anywhere to go forward" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Disabled" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Background colour:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Mouse cursor:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Hidden After Delay" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Always Visible" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Always Hidden" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Show &progress indicator" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Show s&ummary page" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Enable transitions" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Default transition:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Blinds Vertical" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Blinds Horizontal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Box In" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Box Out" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dissolve" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Fade" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Glitter Down" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Glitter Right" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Glitter Right-Down" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Random Transition" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Replace" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Split Horizontal In" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Split Horizontal Out" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Split Vertical In" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Split Vertical Out" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Wipe Down" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Wipe Right" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Wipe Left" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Wipe Up" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Placement" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Screen:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Drawing Tool Configuration" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Drawing Tool: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Eraser" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Name:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Type:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Pop-up Note" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Inline Note" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Freehand Line" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Straight Line" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polygon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Text markup" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrical shape" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Stamp" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Typewriter" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Create annotation tool" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Edit annotation tool" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Colour:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Pen Width:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Create drawing tool" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Edit drawing tool" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Unknown" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Embedded Files" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "View" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Name" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Description" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Size" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Created" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modified" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Save As..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&View..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Could not load print preview part" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Print Preview" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Close" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "F&ind:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Text to search for" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Next" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Jump to next match" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Previous" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Jump to previous match" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modify search behaviour" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Case sensitive" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "From current page" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Find as you type" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|All Files" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Signature Properties" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Straight Line with Comment" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polygon with Comment" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometry with Comment" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometry" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Highlight with Comment" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Squiggle with Comment" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Underline with Comment" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Strike Out with Comment" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Strike Out" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Stamp with Comment" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Freehand Line with Comment" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Caret" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "File Attachment" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Sound" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Movie" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Screen" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Widget" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rich Media" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Unknown" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Author: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Where do you want to save %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Could not open \"%1\" for writing. File was not saved." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Search Options" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Case Sensitive" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regular Expression" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "S&earch:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Layers" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "of" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom to 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rotate &Right" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Right" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotate &Left" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Left" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Original Orientation" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Trim View" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Trim Margins" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Trim To &Selection" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Fit &Width" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Fit &Page" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Auto Fit" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Fit Wi&ndow to Page" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&View Mode" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "&Single Page" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "&Facing Pages" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Facing Pages (&Centre First Page)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Overview" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continuous" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Use Right to Left Reading Direction" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Browse" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "&Toggle Change Colours" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Area &Selection" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Text Selection" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "T&able Selection" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Magnifier" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Selection Tools" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Speak Whole Document" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Speak Current Page" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Stop Speaking" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Pause/Resume Speaking" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Scroll Up" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Scroll Down" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Scroll Page Up" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Scroll Page Down" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Show Forms" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Loaded a one-page document." +msgstr[1] " Loaded a %1-page document." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Text (1 character)" +msgstr[1] "Text (%1 characters)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copy to Clipboard" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Copy forbidden by DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Speak Text" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Image (%1 by %2 pixels)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Save to File..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Image [%1x%2] copied to clipboard." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Save file" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Images (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "File not saved." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Image [%1x%2] saved to %3 file." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copy Text" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Go to '%1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Search for '%1' with" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configure Web Shortcuts..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Follow This Link" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Play this Sound" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Stop Sound" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copy Link Address" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Search for '%1' in this document" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Welcome" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Select zooming area. Right-click to zoom out." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Click to see the magnified view." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Draw a rectangle around the text/graphics to copy." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Select text" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Draw a rectangle around the page area you wish to keep visible" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "New Text Note" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Text of the new note:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Bookmark annotation" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Insert a custom name for the annotation:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Draw an ellipse (drag to select a zone)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Highlight text" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Draw a freehand line" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Inline Text Annotation (drag to select a zone)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Put a pop-up note" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Draw a polygon (click on the first point to close it)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Draw a rectangle" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Squiggle text" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Put a stamp symbol" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Draw a straight line" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Strike out text" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Underline text" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Typewriter Annotation (drag to select a zone)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Highlighter" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Add favourite annotation" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Custom annotation name:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&File" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Settings" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Help" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientation" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Bookmarks" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Viewer Toolbar" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Thumbnails" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotations" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Previous" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Go back to the Previous Page" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Moves to the previous page of the document" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Next" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Advance to the Next Page" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Moves to the next page of the document" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Beginning of the document" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Moves to the beginning of the document" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "End of the document" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Moves to the end of the document" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Rename the current bookmark" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Previous Bookmark" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Go to the previous bookmark" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Next Bookmark" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Go to the next bookmark" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configure Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configure Viewer..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configure Viewer Backends..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configure Backends..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "About Backend" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Reloa&d" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Reload the current document from disk." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Close &Find Bar" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Page Number" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Select All Text on Current Page" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Show S&idebar" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Show &Page Bar" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Show &Signatures Panel" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Embedded Files" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xport As" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "S&hare" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentation" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Open Con&taining Folder" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Import PostScript as PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Get Books From Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Switch Blackscreen Mode" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Erase Drawing" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configure Annotations..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Play/Pause Presentation" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Could not open '%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "The loading of %1 has been cancelled." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Could not open %1. Reason: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configure Viewer Backends" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configure Backends" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf not found" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript files (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importing PS file as PDF (this may take a while)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Please enter the password to read the document:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Incorrect password. Try again:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Document Password" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "This document has XFA forms, which are currently unsupported." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "This document is digitally signed." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"This document is digitally signed. There have been changes since last signed." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Request to Change Viewing Mode" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Enter Presentation Mode" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Deny Request" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Could not open %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "File Changed" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continue Reloading" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Abort Reloading" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continue Closing" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Abort Closing" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Do you want to save your changes to \"%1\" or discard them?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Close Document" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"This link points to a close document action that does not work when using " +"the embedded viewer." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Reloading the document..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contents" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signatures" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Go to Page" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Page:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Enter the new name of the bookmark:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Rename this Bookmark" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Remove this Bookmark" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Save As" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Save - Warning" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Could not open the temporary file for saving." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "File could not be saved in '%1'. Try to save it to another location." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Filled form contents" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "User annotations" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Warning" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Save as Okular document archive..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continue" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continue losing changes" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "File could not be saved in '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist any more." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expand whole section" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Collapse whole section" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expand all" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Collapse all" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Add Bookmark" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Tools" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Print" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Printing this document is not allowed." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Go to the place you were before" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Go to the place you were after" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"File Error! Could not create temporary file " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "No Bookmarks" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "There was a problem sharing the document: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Share" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Document shared successfully" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "You can find the shared document at: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Edit" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&View" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Go" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Tools" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Main Toolbar" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Annotation Toolbar" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "General Options" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibility" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Accessibility Reading Aids" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Performance" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Performance Tuning" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configure Viewer" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentation" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Options for Presentation Mode" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Annotation Options" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Editor Options" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Find Next" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentation" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Switch Screen" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Screen %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Exit Presentation Mode" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Title: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Pages: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Click to begin" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pause" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Play" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Giving a presentation" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Unknown File" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Properties" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fonts" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Reading font information..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Page Sizes" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extract Font" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Unknown" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Embedded (subset)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Fully embedded" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Yes (subset)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Yes" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (substituting with %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Unknown font" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Embedded: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Name" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Type" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "File" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Page" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Size" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Revision Preview" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Where do you want to save this revision?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Could not save file %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Could not view revision." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Enter at least 3 letters to filter pages" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Case Sensitive" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Match Phrase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Match All Words" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Match Any Word" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Filter Options" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Group by Page" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Group by Author" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Show annotations for current page only" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Expand all elements" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Collapse all elements" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "The signature is cryptographically valid." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "The signature is cryptographically invalid." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Digest Mismatch occurred." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "The signature CMS/PKCS7 structure is malformed." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "The requested signature is not present in the document." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "The signature could not be verified." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Certificate is Trusted." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Certificate issuer isn't Trusted." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Certificate issuer is unknown." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Certificate has been Revoked." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Certificate has Expired." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Certificate has not yet been verified." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Unknown issue with Certificate or corrupted data." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Unknown Algorithm" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Unknown Type" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digital Signature" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non-Repudiation" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Encrypt Keys" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Decrypt Keys" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Key Agreement" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Sign Certificate" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Sign CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Encrypt Only" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "No Usage Specified" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Signed By %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Signing Time: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Not Available" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Reason: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Field: %1 on page %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Properties" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "The document has not been modified since it was signed." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"The document has been modified in a way not permitted by a previous signer." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "The document integrity verification could not be completed." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Validity Status" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Signature Validity:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Document Modifications:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Additional Information" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signed By:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Signing Time:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Reason:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Location:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Document Version" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Document Revision %1 of %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "View Signed Version..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "View Certificate..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Show bookmarked pages only" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Play" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pause" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stop" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Add..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Edit..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Remove" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Move &Up" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Move &Down" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Default Drawing Tool #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "There's already a tool with that name. Using a default one" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Duplicated Name" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Page of the document to be shown" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Start the document in presentation mode" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Start with print dialogue" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Start with print dialogue and exit after printing" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "\"Unique instance\" control" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Not raise window" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Find a string on the text" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Documents to open. Specify '-' to read from stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Error: Cannot open more than one document with the --unique switch" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: Cannot open more than one document with the --presentation switch" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Error: Cannot open more than one document with the --print switch" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Error: Cannot open more than one document with the --page switch" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Error: Cannot open more than one document with the --find switch" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Unable to find the Okular component: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Unable to find the Okular component." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Click to open a file\n" +"Click and hold to open a recent file" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Click to open a file or Click and hold to select a recent file" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Next Tab" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Previous Tab" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Undo close tab" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "All files (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "All supported files (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Open Document" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirm Close" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Close Tabs" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "You are about to close %1 tabs. Are you sure you want to continue?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Warn me when I attempt to close multiple tabs" + +#~ msgid "Reviews" +#~ msgstr "Reviews" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Hide Forms" + +#~ msgid "Expired" +#~ msgstr "Expired" + +#~ msgid "&Review" +#~ msgstr "&Review" + +#~ msgid "Annotations author" +#~ msgstr "Annotations author" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Please insert your name or initials:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Show &Navigation Panel" + +#~ msgid "Show Text" +#~ msgstr "Show Text" + +#~ msgid "Small Icons" +#~ msgstr "Small Icons" + +#~ msgid "Normal Icons" +#~ msgstr "Normal Icons" + +#~ msgid "Large Icons" +#~ msgstr "Large Icons" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" + +#~ msgid "Created: %1" +#~ msgstr "Created: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Line Extensions" + +#~ msgid "Style" +#~ msgstr "Style" + +#~ msgid "&Size:" +#~ msgstr "&Size:" + +#~ msgid "Inner color:" +#~ msgstr "Inner colour:" + +#~ msgid "Name: %1" +#~ msgstr "Name: %1" + +#~ msgid "Size: %1" +#~ msgstr "Size: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Browse Tool" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Zoom Tool" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "&Selection Tool" +#~ msgstr "&Selection Tool" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Selection" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Text Selection Tool" + +#~ msgid "T&able Selection Tool" +#~ msgstr "T&able Selection Tool" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Magnifier" + +#~ msgid "Only for PDF documents" +#~ msgstr "Only for PDF documents" + +#~| msgid "None" +#~ msgid " None" +#~ msgstr " None" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" + +#~ msgid "Presentation Mode" +#~ msgstr "Presentation Mode" + +#~ msgid "Allow" +#~ msgstr "Allow" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Allow the presentation mode" + +#~ msgid "Do Not Allow" +#~ msgstr "Do Not Allow" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Do not allow the presentation mode" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" + +#~ msgid "Save &Copy As..." +#~ msgstr "Save &Copy As..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" + +#~ msgid "Current maintainer" +#~ msgstr "Current maintainer" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sec." + +#~ msgid "Pencil color:" +#~ msgstr "Pencil colour:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "landscape DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "portrait DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "landscape DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "portrait DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "landscape DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "portrait DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "landscape DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "portrait DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "landscape DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "portrait DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "landscape DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "portrait DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "landscape DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "portrait DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "landscape DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "portrait DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "landscape DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "portrait DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "landscape DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "portrait DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "landscape DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "portrait DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "landscape DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "portrait DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "landscape DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "portrait DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "landscape DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "portrait DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "landscape DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "portrait DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "landscape DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "portrait DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "landscape DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "portrait DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "landscape DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "portrait DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "landscape DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "portrait DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "landscape DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "portrait DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "landscape DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "portrait DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "landscape letter" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "portrait letter" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "landscape legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "portrait legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "landscape executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "portrait executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "landscape Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "portrait Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "landscape DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "portrait DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "landscape folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "portrait folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "unknown landscape paper size" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "unknown portrait paper size" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Toggle Drawing Mode" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Starting Jovie Text-to-Speech service Failed: %1" + +#~ msgid "Search Columns" +#~ msgstr "Search Columns" + +#~ msgid "All Visible Columns" +#~ msgstr "All Visible Columns" + +#~ msgid "No document opened." +#~ msgstr "No document opened." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "Can't open more than one document in the unique Okular instance." + +#~ msgid "No matches found for '%1'." +#~ msgstr "No matches found for '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Search in progress..." + +#~ msgid "Searching for %1" +#~ msgstr "Searching for %1" + +#~ msgid "Identity Settings" +#~ msgstr "Identity Settings" + +#~ msgid "Highlight Properties" +#~ msgstr "Highlight Properties" + +#~ msgid "Ink Properties" +#~ msgstr "Ink Properties" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Text Annotation" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Green Ink" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Yellow Highlighter" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Yellow Highlight" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Straight Yellow Line" + +#~ msgid "Black Underlining" +#~ msgstr "Black Underlining" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Underline the text with a black line" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Cyan Ellipse" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "A cyan ellipse" + +#~ msgid "Ink" +#~ msgstr "Ink" + +#~ msgid "Enable &background generation" +#~ msgstr "Enable &background generation" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Hide Forms" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Moves to the first page of the document" + +#~ msgid "Moves to the last page of the document" +#~ msgstr "Moves to the last page of the document" + +#~ msgid "You must set this name:" +#~ msgstr "You must set this name:" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Toggles between File Path and Title" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Overwrite" + +#~ msgid "Pages:" +#~ msgstr "Pages:" + +#~ msgid "Green Highlighter" +#~ msgstr "Green Highlighter" + +#, fuzzy +#~| msgid "&Properties" +#~ msgid "&Properties..." +#~ msgstr "&Properties" + +#, fuzzy +#~ msgid "Pink Highlighter" +#~ msgstr "&Properties" + +#, fuzzy +#~| msgid "Moves to the next page of the document" +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "Moves to the next page of the document" + +#, fuzzy +#~| msgid "Fit to &Text" +#~ msgid "Fit &Text" +#~ msgstr "Fit to &Text" + +#, fuzzy +#~| msgid "Advance every:" +#~ msgid "&Advanced" +#~ msgstr "Advance every:" + +#, fuzzy +#~ msgid "Contents:" +#~ msgstr "&Continuous" + +#~ msgid "Hide &Navigation Panel" +#~ msgstr "Hide &Navigation Panel" + +#, fuzzy +#~| msgid "Page %1" +#~ msgid "page %1" +#~ msgstr "Page %1" + +#~ msgid "Show &search bar in thumbnails list" +#~ msgstr "Show &search bar in thumbnails list" + +#, fuzzy +#~| msgid "Speak Text" +#~ msgid "Free Text" +#~ msgstr "Speak Text" + +#, fuzzy +#~| msgid "Format" +#~ msgid "Form" +#~ msgstr "Format" + +#, fuzzy +#~| msgid "General" +#~ msgid "DlgGeneral" +#~ msgstr "General" + +#~ msgid "Program Look" +#~ msgstr "Program Look" + +#~ msgid "Reading Aids" +#~ msgstr "Reading Aids" + +#, fuzzy +#~| msgid "Could not open %1" +#~ msgid "Click for Open %1" +#~ msgstr "Could not open %1" + +#, fuzzy +#~ msgid "contents:" +#~ msgstr "&Continuous" + +#, fuzzy +#~| msgid "Pages:" +#~ msgid "flags:" +#~ msgstr "Pages:" + +#~ msgid "&Watch file" +#~ msgstr "&Watch file" + +#~ msgid "Clear filter" +#~ msgstr "Clear filter" + +#~ msgid "Topic" +#~ msgstr "Topic" + +#~ msgid "Fit to Page &Width" +#~ msgstr "Fit to Page &Width" + +#~ msgid "&Two Pages" +#~ msgstr "&Two Pages" + +#~ msgid "Starting -- find text as you type" +#~ msgstr "Starting -- find text as you type" + +#~ msgid "Security" +#~ msgstr "Security" + +#~ msgid "Optimized" +#~ msgstr "Optimised" + +#~ msgid "Unknown Encryption" +#~ msgstr "Unknown Encryption" + +#~ msgid "Unknown Optimization" +#~ msgstr "Unknown Optimisation" + +#~ msgid "unknown" +#~ msgstr "unknown" + +#~ msgid "-" +#~ msgstr "-" + +#~ msgid "[none]" +#~ msgstr "[none]" + +#, fuzzy +#~ msgid "kpdf, a kde pdf viewer based on poppler" +#~ msgstr "kpdf, a kde pdf viewer based on xpdf" + +#~ msgid "KPDF::Part" +#~ msgstr "KPDF::Part" + +#~ msgid "Converting from ps to pdf..." +#~ msgstr "Converting from ps to pdf..." + +#~ msgid "" +#~ "You do not have ps2pdf installed, so kpdf cannot open postscript files." +#~ msgstr "" +#~ "You do not have ps2pdf installed, so kpdf cannot open postscript files." + +#~ msgid "Text found: \"%1\"." +#~ msgstr "Text found: \"%1\"." + +#~ msgid "Text not found: \"%1\"." +#~ msgstr "Text not found: \"%1\"." + +#~ msgctxt "PDF v. " +#~ msgid "PDF v. %1" +#~ msgstr "PDF v. %1" + +#~ msgid "" +#~ "The margins you specified change the page aspect ratio. Do you want to " +#~ "print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that the aspect ratio is preserved?" +#~ msgstr "" +#~ "The margins you specified change the page aspect ratio. Do you want to " +#~ "print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that the aspect ratio is preserved?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Aspect ratio change" + +#~ msgid "Print with specified margins" +#~ msgstr "Print with specified margins" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Print adapting margins to keep aspect ratio" + +#~ msgid "Xpdf author" +#~ msgstr "Xpdf author" + +#~ msgid "" +#~ "You are trying to overwrite \"%1\" with itself. This is not allowed. " +#~ "Please save it in another location." +#~ msgstr "" +#~ "You are trying to overwrite \"%1\" with itself. This is not allowed. " +#~ "Please save it in another location." diff --git a/po/en_GB/okular_chm.po b/po/en_GB/okular_chm.po new file mode 100644 index 0000000..2d91dd6 --- /dev/null +++ b/po/en_GB/okular_chm.po @@ -0,0 +1,63 @@ +# translation of okular_chm.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Steve Allewell , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-03-30 20:30+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.07.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Unsupported encoding" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" + +#~ msgid "CHM Backend" +#~ msgstr "CHM Backend" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "A Microsoft Windows help file renderer" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/en_GB/okular_comicbook.po b/po/en_GB/okular_comicbook.po new file mode 100644 index 0000000..4c8c3ef --- /dev/null +++ b/po/en_GB/okular_comicbook.po @@ -0,0 +1,60 @@ +# translation of okular_comicbook.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009. +# Steve Allewell , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-12-02 12:45+0000\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Cannot open document, neither unrar nor unarchiver were found." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"The version of unrar on your system is not suitable for opening comicbooks." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Unknown ComicBook format." + +#~ msgid "ComicBook Backend" +#~ msgstr "ComicBook Backend" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "A renderer for various comic book formats" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/en_GB/okular_djvu.po b/po/en_GB/okular_djvu.po new file mode 100644 index 0000000..93829c4 --- /dev/null +++ b/po/en_GB/okular_djvu.po @@ -0,0 +1,139 @@ +# translation of okular_djvu.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2009-03-02 00:18+0000\n" +"Last-Translator: Andrew Coles \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Publisher" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volume" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Type of document" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Unknown" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Component Files" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Unknown" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Single Page" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Bundled" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirect" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Bundled (old)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexed (old)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu Backend" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu backend based on DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgid "A DjVu backend" +#~ msgstr "A DjVu backend" diff --git a/po/en_GB/okular_dvi.po b/po/en_GB/okular_dvi.po new file mode 100644 index 0000000..1ce8ba1 --- /dev/null +++ b/po/en_GB/okular_dvi.po @@ -0,0 +1,773 @@ +# translation of okular_dvi.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009. +# Steve Allewell , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-06-29 13:08+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialogue which you will find in the File-Menu for a precise error " +"report." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialogue which you will find in the File-Menu for a precise error " +"report." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "The DVI file does not start with the preamble." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "The postamble does not begin with the POST command." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "The postamble contained a command other than FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "The page %1 does not start with the BOP command." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "File corruption. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Not all PostScript files could be embedded into your document. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "All external PostScript files were embedded into your document." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "The specified file '%1' does not exist." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "The DVI code set a character of an unknown font." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"The DVI code referred to font no. %1, which was not previously defined." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "The stack was not empty when the EOP command was encountered." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "The stack was empty when a POP command was encountered." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "The DVI code referred to a font which was not previously defined." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "An illegal command was encountered." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "The unknown op-code %1 was encountered." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Embedding %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Page %1: The PostScript file %2 could not be found.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "The papersize data '%1' could not be parsed." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Currently generating %1 at %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generator/Date" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Font file not found" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "portrait" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "landscape" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "That makes 25 errors. Further error messages will not be printed." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Error in DVIfile '%1', page %2. Colour pop command issued when the colour " +"stack is empty." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"File not found: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "The special command '%1' is not implemented." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "The font file %1 is broken, or it could not be opened or read." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType reported an error when setting the character size for font file %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType is unable to load glyph no. %1 from font file %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType is unable to render glyph no. %1 from font file %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glyph no. %1 is empty." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glyph no. %1 from font file %2 is empty." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType is unable to load metric for glyph no. %1 from font file %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Cannot open font file %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Character %1 not defined in font %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Unexpected %1 in PK file %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "The character %1 is too large in file %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Wrong number of bits stored: char. %1, font %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Bad pk file (%1), too many bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Font has non-square aspect ratio " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Cannot find font %1, file %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Checksum mismatch for font file %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Cannot recognise format for font file %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Fatal error.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Wrong command byte found in VF macro list: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI Backend" + +#~ msgid "A DVI file renderer" +#~ msgstr "A DVI file renderer" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular is currently generating bitmap fonts..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Aborts the font generation. Do not do this." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialogue." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular is generating fonts. Please wait." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Font Generation Progress Dialogue" + +#~ msgid "Abort" +#~ msgstr "Abort" + +#~ msgid "What is happening here?" +#~ msgstr "What is happening here?" + +#~ msgid "%v of %m" +#~ msgstr "%v of %m" + +#~ msgid "Please be patient" +#~ msgstr "Please be patient" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Export File As" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" + +#~ msgid "Overwrite File" +#~ msgstr "Overwrite File" + +#~ msgid "Overwrite" +#~ msgstr "Overwrite" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Using dvipdfm to export the file to PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Waiting for dvipdfm to finish..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Using dvips to export the file to PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Waiting for dvips to finish..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Functionality Unavailable" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." + +#~ msgid "DVI File Error" +#~ msgstr "DVI File Error" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Not All Font Files Found" + +#~ msgid "Locating fonts..." +#~ msgstr "Locating fonts..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Problem locating fonts" + +#~ msgid "Font generation aborted" +#~ msgstr "Font generation aborted" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Export: %1 to PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Export: %1 to PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "The fontlist is currently empty." + +#~ msgid "TeX Name" +#~ msgstr "TeX Name" + +#~ msgid "Family" +#~ msgstr "Family" + +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "Type" +#~ msgstr "Type" + +#~ msgid "Encoding" +#~ msgstr "Encoding" + +#~ msgid "Comment" +#~ msgstr "Comment" + +#~ msgid "TeX virtual" +#~ msgstr "TeX virtual" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX Font Metric" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "Could not allocate memory for a font structure" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "Not enough memory to load the DVI-file." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Could not load the DVI-file." + +#, fuzzy +#~ msgid "Checksum mismatch" +#~ msgstr "Checksum mismatch" + +#, fuzzy +#~ msgid " in font file " +#~ msgstr " in font file " + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Could not allocate memory for a macro table." + +#, fuzzy +#~ msgid "Virtual character " +#~ msgstr "Virtual character " + +#, fuzzy +#~ msgid " in font " +#~ msgstr " in font " + +#, fuzzy +#~ msgid " ignored." +#~ msgstr " ignored." + +#~ msgid "Fatal Error" +#~ msgstr "Fatal Error" diff --git a/po/en_GB/okular_epub.po b/po/en_GB/okular_epub.po new file mode 100644 index 0000000..d1e340b --- /dev/null +++ b/po/en_GB/okular_epub.po @@ -0,0 +1,56 @@ +# translation of okular_epub.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Steve Allewell , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-29 13:09+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Error while opening the EPub document." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "EPub Backend Configuration" + +#~ msgid "EPub Backend" +#~ msgstr "EPub Backend" + +#~ msgid "An EPub backend" +#~ msgstr "An EPub backend" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/en_GB/okular_fax.po b/po/en_GB/okular_fax.po new file mode 100644 index 0000000..b7bef12 --- /dev/null +++ b/po/en_GB/okular_fax.po @@ -0,0 +1,44 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Andrew Coles , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-03-02 00:29+0000\n" +"Last-Translator: Andrew Coles \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Andrew Coles" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "andrew_coles@yahoo.co.uk" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Unable to load document" + +#~ msgid "Fax Backend" +#~ msgstr "Fax Backend" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "A G3/G4 fax document backend" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/en_GB/okular_fictionbook.po b/po/en_GB/okular_fictionbook.po new file mode 100644 index 0000000..69965c7 --- /dev/null +++ b/po/en_GB/okular_fictionbook.po @@ -0,0 +1,81 @@ +# translation of okular_fictionbook.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Steve Allewell , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-29 13:09+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Document is not a valid FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Unable to open document: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Document is not a valid ZIP archive" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Invalid document structure (main directory is missing)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "No content found in the document" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Invalid XML document: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "FictionBook Backend Configuration" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Fiction Book Backend" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "A renderer for FictionBook eBooks" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/en_GB/okular_ghostview.po b/po/en_GB/okular_ghostview.po new file mode 100644 index 0000000..b3ac099 --- /dev/null +++ b/po/en_GB/okular_ghostview.po @@ -0,0 +1,92 @@ +# translation of okular_ghostview.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-04-12 14:30+0100\n" +"Last-Translator: Andrew Coles \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Use Platform Fonts" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "General Settings" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Use platform fonts" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Ghostscript Backend Configuration" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Document version" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Language Level" + +#~ msgid "PS Backend" +#~ msgstr "PS Backend" + +#~ msgid "A PostScript file renderer." +#~ msgstr "A PostScript file renderer." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Based on the Spectre library." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/en_GB/okular_kimgio.po b/po/en_GB/okular_kimgio.po new file mode 100644 index 0000000..512a228 --- /dev/null +++ b/po/en_GB/okular_kimgio.po @@ -0,0 +1,71 @@ +# translation of okular_kimgio.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008, 2009. +# Steve Allewell , 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-26 15:06+0000\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Unable to load document: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." + +#~ msgid "Image Backend" +#~ msgstr "Image Backend" + +#~ msgid "A simple image backend" +#~ msgstr "A simple image backend" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Main Toolbar" diff --git a/po/en_GB/okular_markdown.po b/po/en_GB/okular_markdown.po new file mode 100644 index 0000000..e419713 --- /dev/null +++ b/po/en_GB/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Steve Allewell , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-03-31 19:30+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.07.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Failed to open the document" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Failed to compile the Markdown document." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Enable SmartyPants formatting" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Markdown Backend Configuration" diff --git a/po/en_GB/okular_mobi.po b/po/en_GB/okular_mobi.po new file mode 100644 index 0000000..4536751 --- /dev/null +++ b/po/en_GB/okular_mobi.po @@ -0,0 +1,62 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Andrew Coles , 2009. +# Steve Allewell , 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-29 13:09+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Andrew Coles, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "andrew_coles@yahoo.co.uk, steve.allewell@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Error while opening the Mobipocket document." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"This book is protected by DRM and can be displayed only on designated device" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Mobipocket Backend Configuration" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket Backend" + +#~ msgid "A mobipocket backend" +#~ msgstr "A mobipocket backend" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/en_GB/okular_plucker.po b/po/en_GB/okular_plucker.po new file mode 100644 index 0000000..8dc63b3 --- /dev/null +++ b/po/en_GB/okular_plucker.po @@ -0,0 +1,45 @@ +# translation of okular_plucker.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-04-11 21:28+0100\n" +"Last-Translator: Malcolm Hunter \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Name" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Plucker Document Backend" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "A renderer for Plucker eBooks" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/en_GB/okular_poppler.po b/po/en_GB/okular_poppler.po new file mode 100644 index 0000000..0475eb3 --- /dev/null +++ b/po/en_GB/okular_poppler.po @@ -0,0 +1,231 @@ +# translation of okular_poppler.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009, 2010. +# Steve Allewell , 2014, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-03-24 19:53+0000\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.07.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter, Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk, steve.allewell@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Enhance thin lines:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solid" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Shape" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF Options" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Print annotations" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Include annotations in the printed document" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Force rasterisation" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasterise into an image before printing" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Forces the rasterisation of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Fit to printable area" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Fit to full page" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "None; print original size" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Scaling mode for the printed pages" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Scale mode:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Encrypted" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Unencrypted" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Security" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Yes" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimised" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Using Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "PDF Backend Configuration" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Not Available" + +#~ msgid "Select rasterization to enable this!" +#~ msgstr "Select rasterisation to enable this!" + +#~ msgid "PDF Backend" +#~ msgstr "PDF Backend" + +#~ msgid "A PDF file renderer" +#~ msgstr "A PDF file renderer" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Saving files with /Encrypt is not supported." + +#~ msgid "Unknown" +#~ msgstr "Unknown" + +#~ msgid "Unknown Date" +#~ msgstr "Unknown Date" + +#~ msgid "Unknown Encryption" +#~ msgstr "Unknown Encryption" + +#~ msgid "Unknown Optimization" +#~ msgstr "Unknown Optimisation" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Please enter the password to read the document:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Incorrect password. Try again:" + +#~ msgid "Document Password" +#~ msgstr "Document Password" diff --git a/po/en_GB/okular_tiff.po b/po/en_GB/okular_tiff.po new file mode 100644 index 0000000..e1dc3a9 --- /dev/null +++ b/po/en_GB/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Steve Allewell , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-09-26 14:09+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "steve.allewell@gmail.com" diff --git a/po/en_GB/okular_txt.po b/po/en_GB/okular_txt.po new file mode 100644 index 0000000..f011271 --- /dev/null +++ b/po/en_GB/okular_txt.po @@ -0,0 +1,49 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Steve Allewell , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-29 13:10+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Steve Allewell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "steve.allewell@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Txt Backend Configuration" + +#~ msgid "Txt Backend" +#~ msgstr "Txt Backend" + +#~ msgid "Txt backend." +#~ msgstr "Txt backend." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/en_GB/okular_xps.po b/po/en_GB/okular_xps.po new file mode 100644 index 0000000..06d15a9 --- /dev/null +++ b/po/en_GB/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to British English +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Malcolm Hunter , 2008. +# Andrew Coles , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-03-02 00:19+0000\n" +"Last-Translator: Andrew Coles \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Malcolm Hunter" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "malcolm.hunter@gmx.co.uk" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revision" + +#~ msgid "XPS Backend" +#~ msgstr "XPS Backend" + +#~ msgid "An XPS backend" +#~ msgstr "An XPS backend" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/en_GB/org.kde.active.documentviewer.po b/po/en_GB/org.kde.active.documentviewer.po new file mode 100644 index 0000000..5e006c0 --- /dev/null +++ b/po/en_GB/org.kde.active.documentviewer.po @@ -0,0 +1,80 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Steve Allewell , 2014, 2016, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-11 14:58+0100\n" +"Last-Translator: Steve Allewell \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.07.70\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Open..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Remove bookmark" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Bookmark this page" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Thumbnails" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Table of contents" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Bookmarks" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Search..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "No results found." + +#~ msgid "Document to open..." +#~ msgstr "Document to open..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Document viewer for Plasma Active using Okular" + +#~ msgid "Reader" +#~ msgstr "Reader" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL of the file to open" diff --git a/po/eo/okular.po b/po/eo/okular.po new file mode 100644 index 0000000..a844bd3 --- /dev/null +++ b/po/eo/okular.po @@ -0,0 +1,5783 @@ +# translation of okular.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2010-01-03 11:06+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, fuzzy, kde-format +#| msgid "okular, a universal document viewer" +msgid "Okular, a universal document viewer" +msgstr "okular, universala dokumentorigardilo" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Albert Astals Cid, Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Albert Astals Cid, Enrico Ros\n" +"(C) 2005 Piotr Szymanski" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Antaŭa prizorganto" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Multo da frama laboro, ODT kaj FictionBook internoj" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "KPDF programisto" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Kreis okular el la KDPF kodobazo" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF programisto" + +#: aboutdata.h:39 +#, fuzzy, kde-format +#| msgid "Annotations author" +msgid "Annotations artwork" +msgstr "Komenta aŭtoro" + +#: aboutdata.h:40 +#, fuzzy, kde-format +#| msgid "&Text Selection Tool" +msgid "Table selection tool" +msgstr "&Teksta elektilo" + +#: aboutdata.h:41 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation improvements" +msgstr "Notaj ecoj" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Iri al la paĝo %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Malfermi eksteran dosieron" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Ruli '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Unua paĝo" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Antaŭa paĝo" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Sekva paĝo" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Lasta paĝo" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Malantaŭen" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Antaŭen" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Forlasi" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Komenci prezenton" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Fini prezenton" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Trovi..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Iri al la paĝo..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Ludi sonon..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Ĝavoskripta Skripto" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Ludi filmon..." + +#: core/action.cpp:547 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Play movie" +msgstr "Ludi filmon..." + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "" + +#: core/action.cpp:551 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Pause movie" +msgstr "Ludi filmon..." + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Interna elekto" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Pli ol unu interno troviĝis por la mime-tipo:
%1 (%2).

Bonvolu elekti la unu uzendan:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Iri al la paĝo %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, fuzzy, kde-format +#| msgid "Can not find a plugin which is able to handle the passed document." +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Ne eblas trovi kromaĵon kiu kapablas trakti la dokumenton." + +#: core/document.cpp:3368 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Prezento" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, fuzzy, kde-format +#| msgid "" +#| "The document is trying to execute an external application and for your " +#| "safety okular does not allow that." +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"La dokumento provas ruli eksteran aplikaĵon, kaj por via sekureco, okular ne " +"permesas tion." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Neniu programo troviĝis por malfermi dosieron de mime-tipo %1." + +#: core/document.cpp:4258 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not open a temporary file" +msgstr "Ne eblis malfermi %1. Kialo: %2" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "" + +#: core/document.cpp:4270 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find file to print" +msgstr "Ne eblas trovi okular komponanton." + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not open '%1'. File does not exist" +msgstr "Ne eblis malfermi %1. Kialo: %2" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titolo" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Temo" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Priskribo" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Aŭtoro" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Kreinto" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Faristo" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Kopirajto" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Paĝoj" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Kreita" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Ŝanĝita" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Mime-tipo" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategorio" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Ĉefvortoj" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Dosiera vojo" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Dosiera grandeco" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Paĝgrandeco" + +#: core/documentcommands.cpp:65 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Komentado" + +#: core/documentcommands.cpp:110 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Prezento" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Notaj ecoj" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Teksta komentado" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "Komentado" + +#: core/documentcommands.cpp:328 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Elekti tekston" + +#: core/documentcommands.cpp:390 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Notaj ecoj" + +#: core/documentcommands.cpp:438 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Notaj ecoj" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Plata &teksto..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, fuzzy, kde-format +#| msgid "Open a document" +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Malfermi dokumenton" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Filter Options" +msgid "Print Options" +msgstr "Filtrila agordo" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Kolora moduso:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Fermi tiun mesaĝon" + +#: core/sourcereference.cpp:103 +#, fuzzy, kde-format +#| msgid "&Size:" +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "&Grandeco:" + +#: core/textdocumentsettings.cpp:37 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Font:" +msgstr "Defaŭlta transpaso:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Reŝa&rgi" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Permesi" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Ekrano" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Laŭ larĝo" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Notaj ecoj" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Notaj ecoj" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&Koloro:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&Koloro:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Eksperimenta" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "&Elektilo" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "&Annotations" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Emfazi" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Substreki" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Strekaĉi" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Trastreki" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Anstataŭigi" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Surlinia noto" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "&Malfermi ŝprucnoton" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Liniaj ecoj" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Rekta flava streko" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rektangulo" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipso" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Blua poligono" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Stampo" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Komentado" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Prezento" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Tiparo:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Notaj ecoj" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Linio" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Maldiafanec&o:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Paĝo %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Komentado" +msgstr[1] "%1 Komentadoj" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Malfermi ŝprucnoton" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Forigi" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Ecoj" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, fuzzy, kde-format +#| msgid "Save As..." +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Kon&servi '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Apero" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Ĝenerale" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Aŭtoro:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Kreita" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Ŝanĝita" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Pop-up Note Properties" +msgstr "Notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Typewriter Properties" +msgstr "Notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Surliniaj notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line Properties" +msgstr "Liniaj ecoj" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +#| msgid "Sound Properties" +msgid "Polygon Properties" +msgstr "Sonaj ecoj" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Geometriaj ecoj" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Stamp Properties" +msgid "Text Markup Properties" +msgstr "Stampaj ecoj" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Stampaj ecoj" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line Properties" +msgstr "Liniaj ecoj" + +#: part/annotationpropertiesdialog.cpp:138 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Caret Properties" +msgstr "Notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:141 +#, fuzzy, kde-format +#| msgid "Inline Note Properties" +msgid "File Attachment Properties" +msgstr "Surliniaj notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Sonaj ecoj" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Filmaj ecoj" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Notaj ecoj" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Ŝanĝita: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Almeti stampan simbolon" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Koloro:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Maldiafanec&o:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Piktogramo" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Komento" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Helpo" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Enmeti" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Klavo" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Nova paragrafo" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Noto" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragrafo" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Tiparo:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Koloro:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Maldekstre" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centrigita" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Dekstre" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Aprobita" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Ĉi tiel" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Konfida" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departementa" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Malneto" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Eksperimenta" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Fina" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Komentinda" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Publikinda" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Ne aprobita" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ne publikinda" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Vendita" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Sekretega" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Legosigno" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informo" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Stampa simbolo" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "Laŭ larĝo" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Linio" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Linio" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Neniu" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Ĉeflinia longo:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Ĉeflinia etendaĵa longo:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Konservi al la dosiero..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipo:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Emfazi" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle" +msgstr "Strekaĉi" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Substreki" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Trastreki" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rektangulo" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipso" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "Inline Note Properties" +msgid "File attachment symbol:" +msgstr "Surliniaj notaj ecoj" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafo" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "" + +#: part/annotationwidgets.cpp:748 +#, fuzzy, kde-format +#| msgid "Paper color:" +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Papera koloro:" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etikedo" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Dosiero" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Neniu priskribo havebla." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "Name" +msgid "Name:" +msgstr "Nomo" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Priskribo:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Caret symbol:" +msgstr "Stampa simbolo" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Neniu" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Close this note" +msgstr "Fermi tiun mesaĝon" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcioj" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Unu legosigno" +msgstr[1] "" +"%1\n" +"\n" +"%2 legosignoj" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Legosignoj" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "S&erĉi:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Nur la aktuala dokumento" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Iri al ĉi tiu legosigno" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Alinomi la legosignon" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Forigi la legosignon" + +#: part/bookmarklist.cpp:278 +#, fuzzy, kde-format +#| msgid "Open a document" +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Malfermi dokumenton" + +#: part/bookmarklist.cpp:280 +#, fuzzy, kde-format +#| msgid "Remove Bookmark" +msgid "Remove Bookmarks" +msgstr "Forigi la legosignon" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Size" +msgid "Serial Number" +msgstr "Paĝgrandeco" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Forpasinta" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Temo" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Memoruzo" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Ecoj" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "Agordi la rigardilon..." + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "E&ksporti kiel" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Ĝenerale" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Kie vi volas konservi %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Reŝa&rgi" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "Ekrano" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Permesi" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Streki borderon ĉirkaŭ la b&ildoj" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Streki borderon ĉirkaŭ la &ligoj" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, fuzzy, kde-format +#| msgid "Change &Colors" +msgid "Change &colors" +msgstr "Ŝanĝi la &kolorojn" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Averto: tiuj opcioj povas ege aflikti la rapidecon de desegno" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Kolora moduso:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inversigi la kolorojn" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, fuzzy, kde-format +#| msgid "Change paper color" +msgid "Change Paper Color" +msgstr "Ŝanĝi la paperan koloron" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, fuzzy, kde-format +#| msgid "Change dark and light colors" +msgid "Change Dark & Light Colors" +msgstr "Ŝanĝi la malhelan kaj helan kolorojn" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Konverti al nigra-blanka" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Papera koloro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Malhela koloro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Hela koloro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Sojlo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrasto:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identeco" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&Aŭtoro:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Noto: La jena informo estas uzata nur por komentoj kaj recenzoj. " +"Enmetita informo ne estas komunikita sen ke vi scias." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Quick annotation tools" +msgstr "Notaj ecoj" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs Kliento" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx Kliento" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Redaktilo" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Komando:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Aspekto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Montri la ru&lumskalojn" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Ligi la minia&turojn kun la paĝo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Montri la &indikojn kaj informomesaĝojn" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Fona koloro:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Programaj ebloj" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obei la DRM limigaĵojn" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Reŝargi la dokumenton dum dosiera ŝanĝo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Montri la internan elektofenestron" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Vidopcioj" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, fuzzy, kde-format +#| msgid "Overview columns:" +msgid "Overview &columns:" +msgstr "Superrigardaj kolumnoj:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Zoom:" +msgstr "Defaŭlta transpaso:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Laŭ larĝo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Laŭ paĝo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Gardas la memoruzon la plej malalte eble. Ne reuzas ion. (Por sistemoj kun " +"malgranda memoro.)" + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Bona kompromiso inter memoruzo kaj rapideco. Antaŭŝargas la sekvan paĝon kaj " +"plirapidigas la serĉadon. (Por sistemoj kun 256MB da memoro, komune.)" + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Gardas ĉion en memoro. Antaŭŝargas la sekvajn paĝojn. Plirapidigas la " +"serĉadon. (Por sistemoj kun pli ol 512MB da memoro.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Procezila uzo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Aktivigi la &travideblecajn efektojn" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Memoruzo" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Ma&lalta" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&Normala (defaŭlte)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "Perfort&a" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Rendering" +msgstr "Substreki" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "Enable Text Antialias" +msgstr "Defaŭlta transpaso:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "Enable Graphics Antialias" +msgstr "Defaŭlta transpaso:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "Enable Text Hinting" +msgstr "Defaŭlta transpaso:" + +#: part/dlgpresentation.cpp:33 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Defaŭlta transpaso:" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Apriora Ekrano" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekrano %1" + +#: part/dlgpresentation.cpp:49 +#, fuzzy, kde-format +#| msgid " sec." +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sek." +msgstr[1] " sek." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigado" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Antaŭeniri ĉiu:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Bukli post la lasta paĝo" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Navigado" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Fona koloro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Musa kursoro:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Kaŝita post prokrasto" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Ĉiam videbla" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Ĉiam kaŝita" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Montri &progresan indikilon" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Montri res&uman paĝon" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "Enable transitions" +msgstr "Defaŭlta transpaso:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Defaŭlta transpaso:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Malgrandigi vertikale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Malgrandigi horizontale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Enskatoli" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Elskatoli" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dissolvi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Trembrili malsupre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Trembrili dekstre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Trembrili dekstre-malsupre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Hazarada transpaso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Anstataŭigi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Endisigi horizontale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Eldisigi horizontale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Endisigi vertikale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Eldisigi vertikale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Forviŝi malsupre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Forviŝi dekstre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Forviŝi maldekstre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Forviŝi supre" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Enlokigo" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Ekrano:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, fuzzy, kde-format +#| msgid "Drawing" +msgid "Drawing Tool: %1" +msgstr "Desegnaĵo" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "Forigi la desegnaĵojn" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, fuzzy, kde-format +#| msgid "Name" +msgid "&Name:" +msgstr "Nomo" + +#: part/editannottooldialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Type:" +msgid "&Type:" +msgstr "Tipo:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgid "Pop-up Note" +msgstr "&Malfermi ŝprucnoton" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Surlinia noto" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgid "Straight Line" +msgstr "Rekta flava streko" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgid "Polygon" +msgstr "Blua poligono" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +#| msgid "Next Bookmark" +msgid "Text markup" +msgstr "Sekva legosigno" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Stampo" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgid "Typewriter" +msgstr "Anstataŭigi" + +#: part/editannottooldialog.cpp:104 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create annotation tool" +msgstr "Prezento" + +#: part/editannottooldialog.cpp:106 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Edit annotation tool" +msgstr "Notaj ecoj" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&Koloro:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "Laŭ larĝo" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create drawing tool" +msgstr "Prezento" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Edit drawing tool" +msgstr "Notaj ecoj" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Nekonata" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Enkorpigitaj dosieroj" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&Vidi" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nomo" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Priskribo" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Grandeco" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Kreita" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Ŝanĝita" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Kon&servi kiel..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Vidi" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Ne eblis ŝargi la printan antaŭrigardan komponanton" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Printa antaŭrigardo" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Fermi" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "Trov&i:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Serĉenda teksto" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Sekva" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Iri al la sekva rezulto" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Antaŭa" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Salti al la antaŭa kongruo" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifi la serĉan konduton" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Usklecodistinga" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "El nuna paĝo" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Ĉiuj dosieroj" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Signature Properties" +msgstr "Notaj ecoj" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line with Comment" +msgstr "Liniaj ecoj" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "Komentinda" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometrio" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "Emfazi" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle with Comment" +msgstr "Strekaĉi" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Underline with Comment" +msgstr "Substreki" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Strike out" +msgid "Strike Out with Comment" +msgstr "Trastreki" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Strike out" +msgid "Strike Out" +msgstr "Trastreki" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line with Comment" +msgstr "Liniaj ecoj" + +#: part/guiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Creator" +msgid "Caret" +msgstr "Kreinto" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Sono" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Filmo" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Ekrano" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Nekonata" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Aŭtoro: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Kie vi volas konservi %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Serĉaj opcioj" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Usklecodistinga" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regulesprimo" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "S&erĉi:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "el" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zomi" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, fuzzy, kde-format +#| msgid "Rotate Right" +msgid "Rotate &Right" +msgstr "Turni dekstre" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Dekstre" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Turni ma&ldekstren" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Maldekstre" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Origina orientiĝo" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&Vidi" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Teksta elektilo" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Laŭ &larĝo" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Laŭ &paĝo" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "Laŭ &paĝo" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Vida moduso" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Simpla paĝo" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Kontraŭaj paĝoj" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Center &first page" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Centrigi la &unuan paĝon" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Superrigardo" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Kontinua" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Foliumi" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Zomi" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &Colors" +msgid "&Toggle Change Colors" +msgstr "Ŝanĝi la &kolorojn" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Teksta elektilo" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Teksta elektilo" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "T&able Selection" +msgstr "Teksta elektilo" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Elektiloj" + +#: part/pageview.cpp:720 +#, fuzzy, kde-format +#| msgid "Open a document" +msgid "Speak Whole Document" +msgstr "Malfermi dokumenton" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Legi Aktualan Paĝon" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Ĉesu laŭtlegadon" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Rulumi supren" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Rulumi malsupren" + +#: part/pageview.cpp:759 +#, fuzzy, kde-format +#| msgid "Scroll Up" +msgid "Scroll Page Up" +msgstr "Rulumi supren" + +#: part/pageview.cpp:765 +#, fuzzy, kde-format +#| msgid "Scroll Down" +msgid "Scroll Page Down" +msgstr "Rulumi malsupren" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Montri la formularojn" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "" +" Ŝargis unupaĝan dokumenton. Ŝargis unupaĝan dokumenton. Ŝargis unupaĝan " +"dokumenton." +msgstr[1] " Ŝargis %1-paĝan dokumenton." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Teksto (1 signo)" +msgstr[1] "Teksto (%1 signoj)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopii al la poŝo" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopiado malpermesita de DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Paroli la tekston" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Bildo (%1 sur %2 rastrumeroj)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Konservi al la dosiero..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Bildo [%1x%2] kopiita al la poŝo." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Konservi al la dosiero..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Dosiero ne konservita." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Bildo [%1x%2] konservita en la dosiero %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopii la tekston" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Iru al '%1'" + +#: part/pageview.cpp:4135 +#, fuzzy, kde-format +#| msgid "Searching for %1" +msgid "Search for '%1' with" +msgstr "Serĉante %1" + +#: part/pageview.cpp:4149 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Configure Web Shortcuts..." +msgstr "Agordi la rigardilon..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Sekvi tiun ligon" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "Ludi sonon..." + +#: part/pageview.cpp:4179 +#, fuzzy, kde-format +#| msgid "Sound" +msgid "Stop Sound" +msgstr "Sono" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopii la ligan adreson" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Searching for %1" +msgid "Search for '%1' in this document" +msgstr "Serĉante %1" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Bonvenon" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Elektu zomozonon. Maldekstre klaku por zomi." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Tiru rektangulon ĉirkaŭ la teksto/grafikaĵoj kopiendaj." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Elekti tekston" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "Tiru rektangulon ĉirkaŭ la teksto/grafikaĵoj kopiendaj." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Tiru rektangulon ĉirkaŭ la teksto/grafikaĵoj kopiendaj." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nova teksta noto" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Teksto de la nova noto:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Bookmark annotation" +msgstr "Komentado" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Surlinia teksta komentado (eltiru por elekti zonon)" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Emfazi" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Surlinia teksta komentado (eltiru por elekti zonon)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Desegni poligonon (klaku sur la unua punkto por forfermi ĝin)" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Rektangulo" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Strekaĉi" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Almeti stampan simbolon" + +#: part/pageviewannotator.cpp:1039 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Rekta flava streko" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +#| msgid "Strike out" +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Trastreki" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Substreki" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Surlinia teksta komentado (eltiru por elekti zonon)" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "Emfazi" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Add favorite annotation" +msgstr "Komentado" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Custom annotation name:" +msgstr "Komentado" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Dosiero" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Agordo" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Helpo" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientiĝo" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Legosignoj" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, fuzzy, kde-format +#| msgid "Main Toolbar" +msgid "Viewer Toolbar" +msgstr "Ĉefa ilobreto" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniaturoj" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotations" +msgstr "Komentado" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Tiu dokumento enhavas enkorpigitajn dosierojn. Klaku tie por vidi ilin aŭ uzu Dosiero -> Enkorpigitaj " +"dosieroj." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Antaŭa" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Antaŭiri al la antaŭa paĝo" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Iras al la antaŭa paĝo de la dokumento" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Sekva" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Aliri al la sekva paĝo" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Iras al la sekva paĝo de la dokumento" + +#: part/part.cpp:668 +#, fuzzy, kde-format +#| msgid "Reloading the document..." +msgid "Beginning of the document" +msgstr "Reŝargante la dokumenton..." + +#: part/part.cpp:669 +#, fuzzy, kde-format +#| msgid "Moves to the next page of the document" +msgid "Moves to the beginning of the document" +msgstr "Iras al la sekva paĝo de la dokumento" + +#: part/part.cpp:673 +#, fuzzy, kde-format +#| msgid "Reloading the document..." +msgid "End of the document" +msgstr "Reŝargante la dokumenton..." + +#: part/part.cpp:674 +#, fuzzy, kde-format +#| msgid "Moves to the next page of the document" +msgid "Moves to the end of the document" +msgstr "Iras al la sekva paĝo de la dokumento" + +#: part/part.cpp:687 +#, fuzzy, kde-format +#| msgid "Reload the current document from disk." +msgid "Rename the current bookmark" +msgstr "Reŝargi la nunan dokumenton el la disko." + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Antaŭa legosigno" + +#: part/part.cpp:693 +#, fuzzy, kde-format +#| msgid "Go to the previous bookmarked page" +msgid "Go to the previous bookmark" +msgstr "Iri al la antaŭa legosignita paĝo" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Sekva legosigno" + +#: part/part.cpp:699 +#, fuzzy, kde-format +#| msgid "Go to the next bookmarked page" +msgid "Go to the next bookmark" +msgstr "Iri al la sekva legosignita paĝo" + +#: part/part.cpp:726 +#, fuzzy, kde-format +#| msgid "Configure okular..." +msgid "Configure Okular..." +msgstr "Agordi okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Agordi la rigardilon..." + +#: part/part.cpp:735 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Viewer Backends..." +msgstr "Agordi la internojn..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Agordi la internojn..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Pri la interno" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Reŝa&rgi" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Reŝargi la nunan dokumenton el la disko." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "&Fermi la trovobreton" + +#: part/part.cpp:791 +#, fuzzy, kde-format +#| msgid "Page Size" +msgid "Page Number" +msgstr "Paĝgrandeco" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Legi Aktualan Paĝon" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show scroll&bars" +msgid "Show S&idebar" +msgstr "Montri la ru&lumskalojn" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Montri la &navigan panelon" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Enkorpigitaj dosieroj" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&ksporti kiel" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&rezento" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, fuzzy, kde-format +#| msgid "&Import Postscript as PDF..." +msgid "&Import PostScript as PDF..." +msgstr "&Importi Postskripton kiel PDF" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Akiri librojn el la Interreto..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Ŝalti NigrEkranan Modon" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Forigi la desegnaĵojn" + +#: part/part.cpp:927 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Annotations..." +msgstr "Agordi la internojn..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "Prezento" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Ne eblis malfermi %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "" + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Ne eblis malfermi %1. Kialo: %2" + +#: part/part.cpp:1186 +#, fuzzy, kde-format +#| msgid "Configure Backends" +msgid "Configure Viewer Backends" +msgstr "Agordi la internojn" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Agordi la internojn" + +#: part/part.cpp:1268 +#, fuzzy, kde-format +#| msgid "" +#| "The program \"ps2pdf\" was not found, so okular can not import PS files " +#| "using it." +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"La programo \"ps2pdf\" ne troviĝis, do okular ne povas importi postskriptajn " +"dosierojn uzante ĝin." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf ne troviĝis" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importante postskriptan dosieron kiel PDF (tio eble daŭras)..." + +#: part/part.cpp:1409 +#, fuzzy, kde-format +#| msgid "Moves to the last page of the document" +msgid "Please enter the password to read the document:" +msgstr "Iras al la lasta paĝo de la dokumento" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Password" +msgstr "Malfermenda dokumento" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Tiu dokumento enhavas formularojn. Klaku sur la butono por interagi kun ili, " +"aŭ uzu Vidi -> Montri la formularojn." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Printado de tiu dokumento ne estas permesita." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Printado de tiu dokumento ne estas permesita." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Foriri el la prezenta moduso" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Ne eblis malfermi %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&Kontinua" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&Kontinua" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Fermi dokumenton" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Tiu ligo kaŭzas agon de fermado de dokumento kiu ne funkcias uzante la " +"enkorpigitan vidilon." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Tiu ligo kaŭzas agon de forlaso de dokumento kiu ne funkcias uzante la " +"enkorpigitan vidilon." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Reŝargante la dokumenton..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Enhavo" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Iri al la paĝo" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Paĝo:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Rename this Bookmark" +msgstr "Alinomi la legosignon" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Remove this Bookmark" +msgstr "Alinomi la legosignon" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "Kon&servi kiel..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "" + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Ne eblis konservi la dosieron en '%1'. Provu konservi ĝin aliloke." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Filled form contents" +msgstr "Notaj ecoj" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "User annotations" +msgstr "Prezento" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&Kontinua" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "File could not be saved in '%1'. %2" +msgstr "Ne eblis konservi la dosieron en '%1'. Provu konservi ĝin aliloke." + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular ne eblas kopii %1 al la specifigita loko.\n" +"\n" +"La dokumento ne plu ekzistas." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "Ne eblis konservi la dosieron en '%1'. Provu konservi ĝin aliloke." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Fini prezenton" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Aldoni legosignon" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Iloj" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Printado de tiu dokumento ne estas permesita." + +#: part/part.cpp:3221 +#, fuzzy, kde-format +#| msgid "Could not print the document. Please report to bugs.kde.org" +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "Ne eblis printi la dokumenton. Bonvolu raporti la cimon al bug.kde.org" + +#: part/part.cpp:3223 +#, fuzzy, kde-format +#| msgid "Could not print the document. Please report to bugs.kde.org" +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "Ne eblis printi la dokumenton. Bonvolu raporti la cimon al bug.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Iri al la loko kie vi estis antaŭe" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Iri al la loko kie vi estis poste" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Dosiera eraro! Ne eblis krei nedaŭran dosieron " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Dosiera eraro! Ne eblis malfermi la dosieron " +"%1 por ekstrakti. La dosiero ne estos ŝargita." +"" + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Konqueror file manager and then choose the " +#| "'Properties' menu." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Tiu eraro kutime okazas se vi ne rajtas legi la dosieron. Vi povas " +"kontroli la posedecon kaj permesojn per dekstra klako sur la dosiero en la " +"Konkeranto administrilo kaj elektante la 'Ecoj' menuon." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Dosiera eraro! Ne eblis ekstrakti la dosieron " +"%1. La dosiero ne estos ŝargita." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Tiu eraro kutime okazas kiam la dosiero estas korupta. Se vi volas " +"certiĝi, provu ekstrakti la dosieron manume, uzante komandliniajn ilojn." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Neniu legosigno" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Redakti" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Vidi" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Ek" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Iloj" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Ĉefa ilobreto" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotation Toolbar" +msgstr "Komentado" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Ĝenerala agordo" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Alirebleco" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Alireblecaj legadaj helpiloj" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Rendimento" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Rendimenta agordo" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Agordi la rigardilon..." + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Prezento" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opcioj por la prezenta moduso" + +#: part/preferencesdialog.cpp:50 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation Options" +msgstr "Notaj ecoj" + +#: part/preferencesdialog.cpp:51 +#, fuzzy, kde-format +#| msgid "Filter Options" +msgid "Editor Options" +msgstr "Filtrila agordo" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Trovi la sekvan" + +#: part/presentationwidget.cpp:169 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "Prezento" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Ŝalti ekranon" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekrano %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Foriri el la prezenta moduso" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titolo: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Paĝoj: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klaku por komenci" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Paŭzi" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Ludi" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Estas du maniere forlasi la prezentan moduson, vi povas aŭ premi la eskapan " +"klavon aŭ klaki la Forlasi butonon kiu aperas kiam vi metas la muson en la " +"supra dekstra angulo. Kompreneble vi povas rotacii la fenestrojn (Alt+Tab " +"defaŭlte)" + +#: part/presentationwidget.cpp:1609 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Fini prezenton" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Nekonata dosiero" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 ecoj" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Tiparoj" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Legante la tiparan informon..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Paĝa grando" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Ekstrakti tiparon" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipo 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipo 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tipo 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipo 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tipo 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tipo 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tipo 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeĤa PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeĤa virtuala" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeĤa tipara metriko" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Nekonata" + +#: part/propertiesdialog.cpp:332 +#, fuzzy, kde-format +#| msgid "Yes (subset)" +msgid "Embedded (subset)" +msgstr "Jes (subaro)" + +#: part/propertiesdialog.cpp:335 +#, fuzzy, kde-format +#| msgid "Embedded" +msgid "Fully embedded" +msgstr "Enkorpigita" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ne" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Jes (subaro)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Jes" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, fuzzy, kde-format +#| msgctxt "Unknown author" +#| msgid "Unknown" +msgid "Unknown font" +msgstr "Nekonata" + +#: part/propertiesdialog.cpp:390 +#, fuzzy, kde-format +#| msgid "Embedded" +msgid "Embedded: %1" +msgstr "Enkorpigita" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nomo" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipo" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Dosiero" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Paĝoj" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Grandeco" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Printa antaŭrigardo" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Kie vi volas konservi %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Ne eblis malfermi %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Ne eblis malfermi %1. Kialo: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Enmetu almenaŭ 3 literojn por filtri la paĝojn" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Usklecodistinga" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Kongrui frazon" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Kongrui ĉiujn vortojn" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Kongrui iun vorton" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Filtrila agordo" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Neniu noto

Por krei novajn notojn, premu F6 aÅ­ " +"elektu Iloj -> Recenzoj el la menuo.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Grupi laŭ paĝo" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Grupi laŭ aŭtoro" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Montri la recenzojn nur por la nuna paĝo" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Unknown author" +#| msgid "Unknown" +msgid "Unknown Algorithm" +msgstr "Nekonata" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Nekonata dosiero" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Neniu priskribo havebla." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Paĝoj: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Ecoj" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Informo" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "Komentado" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Version" +msgstr "Malfermenda dokumento" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Montri nur la legosignajn paĝojn" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Ludi" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Paŭzi" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Ĉesigi" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "&Edit..." +msgstr "&Redakti" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, fuzzy, kde-format +#| msgid "Wipe Down" +msgid "Move &Down" +msgstr "Forviŝi malsupre" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Montrenda paĝo de la dokumento" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Starti la dokumenton je prezenta moduso" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find the Okular component: %1" +msgstr "Ne eblas trovi okular komponanton." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find the Okular component." +msgstr "Ne eblas trovi okular komponanton." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Klaku por malfermi dosieron\n" +"Klaku kaj tenu por malfermi freŝdatan dosieron" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klaku por malfermi dosieron aŭ klaku kaj tenu por elekti " +"freŝdatan dosieron" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +#| msgid "Next Page" +msgid "Next Tab" +msgstr "Sekva paĝo" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +#| msgid "Previous Page" +msgid "Previous Tab" +msgstr "Antaŭa paĝo" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Ĉiuj dosieroj" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Malfermi dokumenton" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Fermi" + +#: shell/shell.cpp:606 +#, fuzzy, kde-format +#| msgid "" +#| "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Dosiero nomita \"%1\" jam ekzistas. Ĉu vi vere volas anstataŭigi ĝin?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Recenzoj" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Kaŝi la formularojn" + +#~ msgid "Expired" +#~ msgstr "Forpasinta" + +#~ msgid "&Review" +#~ msgstr "&Recenzi" + +#~ msgid "Annotations author" +#~ msgstr "Komenta aŭtoro" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Bonvolu enmeti vian nomon aŭ viajn inicialojn" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Montri la &navigan panelon" + +#~ msgid "Show Text" +#~ msgstr "Montri la tekston" + +#~ msgid "Small Icons" +#~ msgstr "Malgrandaj piktogramoj" + +#~ msgid "Normal Icons" +#~ msgstr "Normalaj piktogramoj" + +#~ msgid "Large Icons" +#~ msgstr "Grandaj piktogramoj" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Klaku por uzi la nunan elektilon\n" +#~ "Klaku kaj tenu por elekti alian elektilon" + +#~ msgid "Created: %1" +#~ msgstr "Kreita: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Liniaj etendaĵoj" + +#~ msgid "Style" +#~ msgstr "Stilo" + +#~ msgid "&Size:" +#~ msgstr "&Grandeco:" + +#~ msgid "Inner color:" +#~ msgstr "Ena koloro:" + +#~ msgid "Name: %1" +#~ msgstr "Nomo: %1" + +#~ msgid "Size: %1" +#~ msgstr "Grandeco: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Foliumilo" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Zomilo" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zomi" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Elektilo" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Teksta elektilo" + +#, fuzzy +#~| msgid "&Selection Tool" +#~ msgid "T&able Selection Tool" +#~ msgstr "&Elektilo" + +#, fuzzy +#~| msgid "Reloading the document..." +#~ msgid "Only for PDF documents" +#~ msgstr "Reŝargante la dokumenton..." + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Neniu" + +#, fuzzy +#~| msgid "" +#~| "The document is going to be launched on presentation mode because the " +#~| "file requested it." +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "La dokumento lanĉotas je prezenta moduso ĉar la dosiero petis tiel." + +#, fuzzy +#~| msgid "Exit Presentation Mode" +#~ msgid "Presentation Mode" +#~ msgstr "Foriri el la prezenta moduso" + +#~ msgid "Allow" +#~ msgstr "Permesi" + +#, fuzzy +#~| msgid "Exit Presentation Mode" +#~ msgid "Allow the presentation mode" +#~ msgstr "Foriri el la prezenta moduso" + +#~ msgid "Do Not Allow" +#~ msgstr "Ne permesi" + +#, fuzzy +#~| msgid "Start the document in presentation mode" +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Starti la dokumenton je prezenta moduso" + +#, fuzzy +#~| msgid "Save As..." +#~ msgid "Save &Copy As..." +#~ msgstr "Konservi kiel..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Fino de dokumento renkontiĝis.\n" +#~ "Daŭrigi el la komenco?" + +#, fuzzy +#~| msgid "" +#~| "End of document reached.\n" +#~| "Continue from the beginning?" +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Fino de dokumento renkontiĝis.\n" +#~ "Daŭrigi el la komenco?" + +#~ msgid "Current maintainer" +#~ msgstr "Nuna prizorganto" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Krajona koloro:" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Komuti la desegnan moduson" + +#, fuzzy +#~| msgid "Starting KTTSD Failed: %1" +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Lanĉo de KTTSD fiaskis: %1" + +#~ msgid "Search Columns" +#~ msgstr "Serĉi kolumnojn" + +#~ msgid "All Visible Columns" +#~ msgstr "Ĉiuj videblaj kolumnoj" + +#~ msgid "No document opened." +#~ msgstr "Neniu dokumento malfermata." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Neniu rezulto por '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Serĉante..." + +#~ msgid "Searching for %1" +#~ msgstr "Serĉante %1" + +#~ msgid "Identity Settings" +#~ msgstr "Identeca agordo" + +#~ msgid "Highlight Properties" +#~ msgstr "Emfazaj ecoj" + +#~ msgid "Ink Properties" +#~ msgstr "Inkaj ecoj" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Teksta komentado" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Verda inko" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Flava emfazilo" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Flava emfazo" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Rekta flava streko" + +#~ msgid "Black Underlining" +#~ msgstr "Nigra substreko" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Substreki la tekston per nigra linio" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Cejana elipso" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Cejana elipso" + +#~ msgid "Ink" +#~ msgstr "Inko" + +#~ msgid "Enable &background generation" +#~ msgstr "Aktivigi la &fonan generadon" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Kaŝi la formularojn" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Iras al la unua paĝo de la dokumento" + +#~ msgid "You must set this name:" +#~ msgstr "Vi devas indiki tiun nomon:" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "Overwrite" +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "Anstataŭigi" + +#~ msgid "Pages:" +#~ msgstr "Paĝoj:" + +#~ msgid "Green Highlighter" +#~ msgstr "Verda emfazilo" + +#~ msgid "okular" +#~ msgstr "okular" + +#~ msgid "&Properties..." +#~ msgstr "&Ecoj..." diff --git a/po/eo/okular_chm.po b/po/eo/okular_chm.po new file mode 100644 index 0000000..29e6b8b --- /dev/null +++ b/po/eo/okular_chm.po @@ -0,0 +1,60 @@ +# translation of okular_chm.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2007-11-09 17:45+0100\n" +"Last-Translator: Pierre-Marie Pédrot \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "CHM interno" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Vindoza helpdosiera rigardilo" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/eo/okular_comicbook.po b/po/eo/okular_comicbook.po new file mode 100644 index 0000000..8c3f31e --- /dev/null +++ b/po/eo/okular_comicbook.po @@ -0,0 +1,49 @@ +# Translation of okular_comicbook into esperanto. +# Axel Rousseau , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2009-11-15 12:06+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: pology\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Axel Rousseau" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "axel@esperanto-jeunes.org" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eo/okular_djvu.po b/po/eo/okular_djvu.po new file mode 100644 index 0000000..f802a4e --- /dev/null +++ b/po/eo/okular_djvu.po @@ -0,0 +1,140 @@ +# translation of okular_djvu.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2010-01-03 10:48+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Redaktilo" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Publikisto" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volumo" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipo de dokumento" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Nekonata" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Enhavaj dosieroj" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Nekonata" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Simpla paĝo" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Faska" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Nerekta" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Faska (malnova)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indeksita (malnova)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu interno" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu interno bazita sur DjVuLibre" + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgid "A DjVu backend" +#~ msgstr "DjVu interno" diff --git a/po/eo/okular_dvi.po b/po/eo/okular_dvi.po new file mode 100644 index 0000000..cceee44 --- /dev/null +++ b/po/eo/okular_dvi.po @@ -0,0 +1,814 @@ +# translation of okular_dvi.po to esperanto +# Esperantaj mesaĝoj por "kdvi" +# Copyright (C) 1998, 2007 Free Software Foundation, Inc. +# Wolfram Diestel , 1998. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2010. +# +# +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2010-01-03 10:56+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: dviexport.cpp:117 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvipdfm' on your computer. This " +#| "program is essential for the export function to work. You can, however, " +#| "convert the DVI-file to PDF using the print function of Okular, but that " +#| "will often produce documents which print okay, but are of inferior " +#| "quality if viewed in Acrobat Reader. It may be wise to upgrade to a more " +#| "recent version of your TeX distribution which includes the 'dvipdfm' " +#| "program.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"Okular ne trovis la programon 'dvipdfm' en via komputilo. Tiu programo estas " +"nepre necesa por la eksporta funkcio. Vi povas tamen konverti la DVI " +"dosieron al PDF uzante la presofunkcion de Okular, sed kvankam tio ofte " +"produktas dokumentojn bone legeblajn presite, tamen estas aĉajn en la " +"programo Acrobat-legilo. Eble aktualigu vian TeĤo-instalaĵon, kiu enhavas la " +"programon 'dvipdfm'.\n" +"Indiko por la konfuzita sistemestro: Okular uzas la mediovariablon PATH por " +"serĉi programojn." + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"La ekstera programo 'dvipdfm' uzata por eksporti la dosieron raportis " +"eraron. Vi povus rigardi la dokumentinforman fenestron en " +"la Dosiero menuo por ricevi detalan eraroprotokolon." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" + +#: dviexport.cpp:166 +#, fuzzy, kde-format +#| msgid "" +#| "Okular could not locate the program 'dvips' on your computer. That " +#| "program is essential for the export function to work.\n" +#| "Hint to the perplexed system administrator: Okular uses the PATH " +#| "environment variable when looking for programs." +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"Okular ne kapablis trovi la programon 'dvips' en via komputilo. Tiu programo " +"estas precipa por funkcigi la eksportadon.\n" +"Indiko al la perpleksa sistemestro: Okular uzas la PATH mediovariablon por " +"trovi programojn." + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"La ekstera programo 'dvips' uzata por eksporti la dosieron raportis " +"eraron. Vi povus rigardi la dokumentinforman fenestron en " +"la Dosiero menuo por ricevi detalan eraroprotokolon." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "La DVI dosiero ne komenciĝas per la antaŭteksto." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"La DVI dosiero enhavas la malĝustan version de la DVI eligo por tiu " +"programo. Indiko: Se vi uzas la formatsistemon Omega, vi bezonas uzi " +"specialan programon, kiel oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"La DVI dosiero estas ege koruptita. Okular ne eblis trovi la posttekston." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "La postteksto ne komenciĝas per la POST komando." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "La postteksto enhavas komandon alian ol FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La paĝo %1 ne komenciĝas per la BOP komando." + +#: dviFile.cpp:380 +#, fuzzy, kde-format +#| msgid "" +#| "

The external program pdf2ps could not be started. " +#| "As a result, the PDF-file %1 could not be converted to PostScript. Some " +#| "graphic elements in your document will therefore not be displayed.

Possible reason: The program pdf2ps may not " +#| "be installed on your system, or cannot be found in the current search " +#| "path.

What you can do: The program pdf2ps " +#| "is normally contained in distributions of the ghostscript PostScript " +#| "interpreter system. If ghostscipt is not installed on your system, you " +#| "could install it now. If you are sure that ghostscript is installed, try " +#| "to use pdf2ps from the command line to check if it " +#| "really works.

PATH: %2

" +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Troviĝis problemoj rulante pdf2ps. Tial, kelkaj tiparaj " +"dosieroj ne troveblis, kaj via dokumento eble ne legeblas.

Ebla " +"kialo: La pdf2ps programo ne estus instalata sur via sistemo, aŭ ne " +"troveblus ĉe la nuna serĉvojo.

Tion, kion vi povas fari: La " +"pdf2ps programo normale kunestas en la pakaĵoj de la ghostscript PostScript " +"formata sistemo. Se ghostscript ne estas instalata sur via sistemo, vi povus " +"instali la TeX Live distribuon (www.tug.org/texlive). Se vi estas certa, ke " +"ghostscript estas instalata, bonvolu provi la pdf2ps programon per la " +"komandlinio por kontroli, ke ĝi reale funkcias.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, fuzzy, kde-format +#| msgid "" +#| "File not found: \n" +#| " %1" +msgid "File corruption. %1" +msgstr "" +"Dosiero ne troviĝis:\n" +" %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, fuzzy, kde-format +#| msgid "The special command '%1' is not implemented." +msgid "The specified file '%1' does not exist." +msgstr "La speciala komando '%1' ne realiĝis." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "La DVI kodoprezento havas signon el nekonata tiparo." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "La DVI kodo referis al la tiparo #%1, kiu ne estis difinita antaŭe." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "La stako ne estis malplena kiam la EOP komando okazis." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "La stako estis malplena kiam POP komando okazis." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "La DVI kodo referis al tiparon kiu ne estis difinita antaŭe." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Malpermesita komando troviĝis." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "La nekonata opkodo %1 okazis." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Enkorpigante %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Paĝo %1: La PDF dosiero %2 ne konverteblis al postskripto." +"
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Paĝo %1: La PDF dosiero %2 ne troveblis.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "La papergranda datumo '%1' ne analizeblis." + +#: fontpool.cpp:203 +#, fuzzy, kde-format +#| msgid "" +#| "

Okular was not able to locate all the font files which are " +#| "necessary to display the current DVI file. Your document might be " +#| "unreadable.

" +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular ne trovis ĉiujn tiparojn necesajn por montri la nunan DVI " +"dosieron. Via dokumento povus esti nelegebla.

" + +#: fontpool.cpp:270 +#, fuzzy, kde-format +#| msgid "" +#| "

There were problems running kpsewhich. As a result, some font " +#| "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#| "installed on your system, or it cannot be found in the current search " +#| "path.

What you can do: The kpsewhich program is normally " +#| "contained in distributions of the TeX typesetting system. If TeX is not " +#| "installed on your system, you could install the TeX Live distribution " +#| "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#| "to use the kpsewhich program from the command line to check if it really " +#| "works.

" +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Troviĝis problemoj rulante kpsewhich. Tial, kelkaj tiparaj " +"dosieroj ne troveblis, kaj via dokumento eble ne legeblas.

Ebla " +"kialo: La kpsewhich programo ne estus instalata sur via sistemo, aŭ ne " +"troveblus ĉe la nuna serĉvojo.

Tion, kion vi povas fari: La " +"kpsewich programo normale kunestas en la pakaĵoj de la TeĤa formata sistemo. " +"Se TeĤo ne estas instalata sur via sistemo, vi povus instali la TeX Live " +"distribuon (www.tug.org/texlive). Se vi estas certa, ke TeĤo estas " +"instalata, bonvolu provi la kpsewich programon per la komandlinio por " +"kontroli, ke ĝi reale funkcias.

" + +#: fontpool.cpp:291 +#, fuzzy, kde-format +#| msgid "" +#| "

The font generation by kpsewhich was aborted (exit code %1, " +#| "error %2). As a result, some font files could not be located, and your " +#| "document might be unreadable.

" +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"

La Tipara generado per kpsewhich haltiĝis (fino kun %1 kodo, " +"eraro %2). Kelkaj tiparoj ne troveblas kaj via dokumento povas esti " +"nelegebla.

" + +#: fontpool.cpp:462 +#, fuzzy, kde-format +#| msgid "Currently generating %1 at %2 dpi" +msgid "Currently generating %1 at %2 dpi..." +msgstr "Aktuale kreante %1 per %2 punktoj/colo" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generilo/Dato" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Tipara dosiero ne troviĝis" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "vertikala formato" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "horizontala formato" + +#: psgs.cpp:265 +#, fuzzy, kde-format +#| msgid "" +#| "The version of Ghostview that is installed on this computer does not " +#| "contain any of the Ghostview device drivers that are known to Okular. " +#| "PostScript support has therefore been turned off in Okular." +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La instalata versio de Ghostview ĉe tiu komputilo ne enhavas iun ajn " +"Ghostview aparatan pelilon el tiuj, kiujn konas okular. Tial la postskripta " +"subteno malŝaltis en okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

La Ghostview programo, kiun okular uzas interne por montri la " +"postskriptajn grafikaĵojn kiuj ĉeestas en tiu DVI dosiero, ĝenerale kapablas " +"elskribi multajn formatojn. La subprogramojn kiujn uzas Ghostscript por tiuj " +"taskoj oni nomas 'aparataj peliloj'. Estas unu aparata pelilo po ĉiu formato " +"kiun Ghostview kapablas skribi. Malsamaj versioj de Ghostview ofte enhavas " +"malsamajn aparatajn pelilarojn. Ŝajne la instalata versio de Ghostview ĉe " +"tiu komputilo ne enhavas iun ajn aparatan pelilon el tiuj, " +"kiujn konas okular.

Estas malverŝajne ke normala instalaĵo de " +"Ghostview ne havus ilin. Tial, tiu eraro eble indikas gravan misagordon de " +"via Ghostview instalaĵo.

Se vi volas ripari la problemojn kun " +"Ghostview, vi povas uzi la komandon gs --help por montri la " +"liston de la peliloj enhavataj. Inter aliaj, okular povas uzi la 'png256', " +"'jpeg' kaj 'pnm' pelilojn. Notu ke okular bezonas relanĉiti por reebligi la " +"postskriptan subtenon.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Ĝis nun estis 25 eraroj. La pliaj eraroj ne montriĝos." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Eraro en la DVI dosiero '%1', paĝo %2. Kolora pop-komando okazis kiam la " +"kolora stako estis malplena." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Misformita parametro en la speciala komando epsf.\n" +"Atendis reelon sekvintan %1 en %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Dosiero ne troviĝis:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Eraro en la DVI dosiero '%1', paĝo %2. Ne eblis interpreti la angulon en la " +"teksta rotacio." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "La speciala komando '%1' ne realiĝis." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"La tipara dosiero %1 ne malfermeblis kaj legeblis, sed ĝia tipara formato ne " +"estas subtenata." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"La tipara dosiero %1 estas koruptita, aŭ ĝi ne malfermeblis aŭ legeblis." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType raportis eraron aplikante la signan grandecon por la tiparan " +"dosieron %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType ne kapablas ŝargi la signobildon #%1 el la tipara dosiero %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"FreeType ne kapablas bildigi la signobildon #%1 el la tipara dosiero %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "La signobildo #%1 estas malplena." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "La signobildo #%1 el la tipara dosiero %2 estas malplena." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType ne kapablas ŝargi la metraĵon por la signobildo #%1 el la fonta " +"dosiero %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Ne eblas malfermi la tiparan dosieron %1" + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "exFont_PK::operator[]: signo %1 ne estas difinita en tiparo %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Neatendita %1 en PK-dosiero %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "La signo %1 estas tro granda en dosiero %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Malĝusta nombro da bitoj konservitaj: signo %1, tiparo %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Malbona PK dosiero (%1), tro multaj bitoj" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Tiparo havas nekvadratan proporcion " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Ne eblas trovi la tiparon %1, en dosiero %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "La kontrolsumo ne kongruas pri la tipara dosiero %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Ne eblas rekoni la formaton de la tipara dosiero %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Neriparebla eraro.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Tio verŝajne signifas, ke vi trovis cimon en okular,\n" +"aŭ ke la DVI dosiero, aŭ iuj neĉefaj dosieroj (ekz. tiparoj aŭ virtualaj " +"tiparoj),\n" +"estas tre difektitaj.\n" +"Okular finos post tiu mesaĝo. Se vi kredas, ke vi trovis\n" +"cimon, aŭ ke okular devus konduti pli dece en tiu situacio\n" +"bonvolu raporti la problemon." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Malĝusta komanda bitoko troviĝis en VF-makro-listo: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI interno" + +#~ msgid "A DVI file renderer" +#~ msgstr "DVI dosiera rigardilo" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular bazas sur la kpsewhich programo por trovi la tiparajn " +#~ "dosierojn en via diskaparato kaj generi PK tiparojn, se bezonas.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular aktuale kreas rastrumajn tiparojn..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Haltigas la tiparan kreadon. Ne faru tion." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular aktuale kreas rastrumajn tiparojn bezonatajn por prezenti la " +#~ "dokumenton. Tiucele okular uzas kelkajn eksterajn programojn, kiel " +#~ "Metafont. Vi povas vidi la eligon de tiuj programoj poste en la " +#~ "dokumentinforma fenestro." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular estas kreanta tiparojn. Bonvolu atendi." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Progresa dialogo de la tipara generado" + +#~ msgid "Abort" +#~ msgstr "Ĉesi" + +#~ msgid "What is happening here?" +#~ msgstr "Kio okazantas tie ĉi?" + +#~ msgid "%v of %m" +#~ msgstr "%v el %m" + +#~ msgid "Please be patient" +#~ msgstr "Bonvolu pacienci" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|PDF (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Eksportu dosieron kiel" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "La dosiero %1 ekzistas.\n" +#~ "Ĉu vi volas anstataŭigi ĝin?" + +#~ msgid "Overwrite File" +#~ msgstr "Anstataŭigi la dosieron" + +#~ msgid "Overwrite" +#~ msgstr "Anstataŭigi" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Uzante 'dvipdfm' por eksporti la dosieron al PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular aktuale uzas la eksteran programon 'dvipdfm' por konverti vian DVI-" +#~ "dosieron al PDF. Kelkfoje tio povas daŭri iom longe, ĉar 'dvipdfm' " +#~ "bezonas krei siajn proprajn rastrotiparojn. Bonvolu pacienci." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Atendante la plenumon de dvipdfm..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|Postskripto (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Uzante 'dvips' por eksporti la dosieron al Postskripto" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular aktuale uzas la eksteran programon 'dvips' por konverti vian DVI-" +#~ "dosieron al Postskripto. Kelkfoje tio povas daŭri iom longe, ĉar 'dvips' " +#~ "bezonas krei siajn proprajn rastrotiparojn. Bonvolu pacienci." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Atendante la plenumon de dvips..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funkcio ne uzebla" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Dosiera koruptado Okular ne kapablis interpreti vian " +#~ "DVI dosieron. Tio estas plikaze pro koruptita dosiero." + +#~ msgid "DVI File Error" +#~ msgstr "DVI dosiera eraro" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Ĉiuj tiparaj dosieroj ne troviĝis" + +#~ msgid "Locating fonts..." +#~ msgstr "Serĉante tiparojn..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Problemo serĉante la tiparojn" + +#~ msgid "Font generation aborted" +#~ msgstr "Tipara generado ĉesis" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Eksporto: %1 al PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Eksporto: %1 al Postskripto" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "La tiparolisto aktuale estas malplena." + +#~ msgid "TeX Name" +#~ msgstr "TeĤa nomo" + +#~ msgid "Family" +#~ msgstr "Familio" + +#~ msgid "Zoom" +#~ msgstr "Zomi" + +#~ msgid "Type" +#~ msgstr "Tipo" + +#~ msgid "Encoding" +#~ msgstr "Kodoprezento" + +#~ msgid "Comment" +#~ msgstr "Komento" + +#~ msgid "TeX virtual" +#~ msgstr "TeĤa virtuala" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeĤa tipara metriko" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "Ne eblis atribui memoron por tipara strukturo" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "Ne sufiĉas la memoro por ŝargi la DVI dosieron." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Ne eblis ŝargi la DVI dosieron." + +#~ msgid "Checksum mismatch" +#~ msgstr "Kontrolsumo ne kongruas" + +#~ msgid " in font file " +#~ msgstr " en tipara dosiero " + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Ne eblis atribui memoron por makroo-tabelo." + +#~ msgid "Virtual character " +#~ msgstr "Virtu1ala signo " + +#~ msgid " in font " +#~ msgstr " en tiparo " + +#~ msgid " ignored." +#~ msgstr " ignorita." + +#~ msgid "Fatal Error" +#~ msgstr "Neriparebla eraro" diff --git a/po/eo/okular_epub.po b/po/eo/okular_epub.po new file mode 100644 index 0000000..a5cced6 --- /dev/null +++ b/po/eo/okular_epub.po @@ -0,0 +1,55 @@ +# Translation of okular_epub into esperanto. +# +# Axel Rousseau , 2009, 2010. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-03 10:56+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Axel Rousseau" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "axel@esperanto-jeunes.org" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Eraro dum malfermo de EPub dokumento" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "" + +#: generator_epub.cpp:33 +#, fuzzy, kde-format +#| msgid "EPub Backend" +msgid "EPub Backend Configuration" +msgstr "EPub interno" + +#~ msgid "EPub Backend" +#~ msgstr "EPub interno" + +#~ msgid "An EPub backend" +#~ msgstr "EPub interno" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/eo/okular_fax.po b/po/eo/okular_fax.po new file mode 100644 index 0000000..0683f1a --- /dev/null +++ b/po/eo/okular_fax.po @@ -0,0 +1,44 @@ +# Translation of okular_fax into esperanto. +# +# Axel Rousseau , 2009, 2010. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-03 10:57+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Axel Rousseau" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "axel@esperanto-jeunes.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Ne eblis ŝargi la dokumenton" + +#~ msgid "Fax Backend" +#~ msgstr "Faksa interno" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "G3/G4 faksa dokumenta interno" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eo/okular_fictionbook.po b/po/eo/okular_fictionbook.po new file mode 100644 index 0000000..8db4c5e --- /dev/null +++ b/po/eo/okular_fictionbook.po @@ -0,0 +1,99 @@ +# translation of okular_fictionbook.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-03 10:58+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "La dokumento ne estas valida FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Ne eblas malfermi la dokumenton: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "La dokumento ne estas valida ZIP arkivo" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Nevalida dokumenta strukturo (ĉefa dosierujo mankas)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Enhavo ne troviĝis en la dokumento" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Nevalida XML dokumento: %1" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook" +msgstr "FictionBook interno" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook Backend Configuration" +msgstr "FictionBook interno" + +#~ msgid "Fiction Book Backend" +#~ msgstr "FictionBook interno" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Rigardilo por FictionBook e-libroj" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Creator" +#~ msgstr "Kreinto" + +#~ msgid "Title" +#~ msgstr "Titolo" + +#~ msgid "Author" +#~ msgstr "Aŭtoro" + +#~ msgid "Producer" +#~ msgstr "Produktisto" + +#~ msgid "Created" +#~ msgstr "Kreita" diff --git a/po/eo/okular_ghostview.po b/po/eo/okular_ghostview.po new file mode 100644 index 0000000..265895c --- /dev/null +++ b/po/eo/okular_ghostview.po @@ -0,0 +1,105 @@ +# translation of okular_ghostview.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-03 10:59+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Uzi platformajn tiparojn" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Ĝeneralaj Agordoj" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Uzi platformajn tiparojn" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, fuzzy, kde-format +#| msgid "Ghostscript backend configuration" +msgid "Ghostscript Backend Configuration" +msgstr "Ghostscript interna agordo" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumenta versio" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Lingva nivelo" + +#~ msgid "PS Backend" +#~ msgstr "PS interno" + +#~ msgid "A PostScript file renderer." +#~ msgstr "PostScript dosiera rigardilo" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Bazata sur Spectre biblioteko." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "Glatigo plibonigas la aperon de la dokumento, tamen plidaŭrigas la " +#~ "bildigon." + +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "&Aktivigi la glitigon de tiparoj" + +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "&Aktivigi la glitigon de grafikaĵoj" diff --git a/po/eo/okular_kimgio.po b/po/eo/okular_kimgio.po new file mode 100644 index 0000000..39f8b5b --- /dev/null +++ b/po/eo/okular_kimgio.po @@ -0,0 +1,69 @@ +# translation of okular_kimgio.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# Axel Rousseau , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2009-12-06 20:20+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Ne eblis ŝargi la dokumenton: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Bilda interno" + +#~ msgid "A simple image backend" +#~ msgstr "Simpla bilda interno" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Ĉefa ilobreto" diff --git a/po/eo/okular_mobi.po b/po/eo/okular_mobi.po new file mode 100644 index 0000000..58d7ed2 --- /dev/null +++ b/po/eo/okular_mobi.po @@ -0,0 +1,54 @@ +# Translation of okular_mobi into esperanto. +# Axel Rousseau , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-11-15 12:06+0100\n" +"Last-Translator: Axel Rousseau \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: pology\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Axel Rousseau" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "axel@esperanto-jeunes.org" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "" + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/eo/okular_plucker.po b/po/eo/okular_plucker.po new file mode 100644 index 0000000..a0b4ce4 --- /dev/null +++ b/po/eo/okular_plucker.po @@ -0,0 +1,40 @@ +# translation of okular_plucker.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-11-27 23:18+0100\n" +"Last-Translator: Pierre-Marie Pédrot \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nomo" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eo/okular_poppler.po b/po/eo/okular_poppler.po new file mode 100644 index 0000000..16e921b --- /dev/null +++ b/po/eo/okular_poppler.po @@ -0,0 +1,216 @@ +# translation of okular_poppler.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-11-28 21:02+0100\n" +"Last-Translator: Pierre-Marie Pédrot \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ne" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solida" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Formo" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF opcioj" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Devigi la rastrumigon" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rastrumigi kiel bildon antaŭ ol printi" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Devigas la rastrumigon de ĉiu paĝo kiel bildo antaŭ ol printi ĝi. Tiu " +"ĝenerale donas iel pli malbonaj rezultojn, sed estas utila por printi " +"dokumentojn kiuj ŝajne ne printiĝas taŭge." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, fuzzy, kde-format +#| msgctxt "PDF v. " +#| msgid "PDF v. %1" +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Ĉifrita" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Malĉifrita" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sekureco" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Jes" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimumigita" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Unknown" +#~ msgstr "Nekonata" + +#~ msgid "Unknown Date" +#~ msgstr "Nekonata dato" + +#~ msgid "Unknown Encryption" +#~ msgstr "Nekonata ĉifraĵo" + +#~ msgid "Unknown Optimization" +#~ msgstr "Nekonata optimumigo" + +#, fuzzy +#~| msgid "Please insert the password to read the document:" +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Bonvolu tajpi la pasvorton por legi la dokumenton:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Malĝusta pasvorto. Bonvolu reprovi:" + +#~ msgid "Document Password" +#~ msgstr "Dokumenta pasvorto" diff --git a/po/eo/okular_xps.po b/po/eo/okular_xps.po new file mode 100644 index 0000000..11b7cd3 --- /dev/null +++ b/po/eo/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to esperanto +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Pierre-Marie Pédrot , 2007. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-11-09 17:33+0100\n" +"Last-Translator: Pierre-Marie Pédrot \n" +"Language-Team: esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Pierre-Marie Pédrot" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "pedrotpmx@wanadoo.fr" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revizio" + +#~ msgid "XPS Backend" +#~ msgstr "XPS interno" + +#~ msgid "An XPS backend" +#~ msgstr "XPS interno" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/es/docs/okular/configure.png b/po/es/docs/okular/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..fdeba4810112e221f5a10e7dc0ba0cc29b18289a GIT binary patch literal 66468 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 K(OltIAN~W_m54k5 literal 0 HcmV?d00001 diff --git a/po/es/docs/okular/embedded-files-bar.png b/po/es/docs/okular/embedded-files-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..be4cb91f928f875de864f6dfb6e40869dc748590 GIT binary patch literal 4657 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 +KPDF"> + + +]> + + + + Manual de &okular; + + Albert Astals Cid

&Albert.Astals.Cid.mail;
+ + + Pino Toscano
pino@kde.org
+
+
+ Rafael Rodríguez Martín
apt-drink@telefonica.net
Traductor
Javier Fdez. Retenaga
jfrtnaga@yahoo.es
Traductor
Javier Viñal
fjvinal@gmail.com
Traductor
+ + &FDLNotice; + 2020-06-05 + 1.11 (Aplicaciones 20.08) + + + &okular; es un visor universal de documentos para &kde; basado en el código de &kpdf;. + + + KDE + okular + pdf + ps + postscript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + markdown + mobipocket + plucker + Anotación + + + + Introducción + &okular; es un visor universal de documentos para &kde; basado en el código de &kpdf;. Sin embargo, a pesar de estar basado en el código de &kpdf; &okular; tiene algunas funcionalidades únicas, tales como modo continuo y reconocimiento mejorado de presentaciones y uso de anotaciones. + &okular; admite gran cantidad de formatos distintos, como &PDF;, &PostScript;, Tiff, CHM, DjVU, imágenes (png, jpg, &etc;) XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub, Fax y Markdown. Para ver todos los formatos reconocidos y sus características, consulte Manejadores de formatos de documentos de &okular;. + + Ventana principal de &okular; + + + + + + Ventana principal de &okular; + + + + + + Uso básico + + Abrir archivos + Para ver un archivo reconocido por &okular;, seleccione ArchivoAbrir... , elija un archivo en el cuadro de diálogo y pulse Abrir. El archivo se mostrará ahora en la ventana principal. + + El nuevo documento se abrirá en una nueva pestaña si está marcada la opción Abrir nuevos archivos en pestañas en la página de configuración general. + Puede cerrar la pestaña pulsando con el &MMB; sobre ella. + Puede volver a abrir el documento previamente cerrado en una pestaña usando el elemento del menú &Ctrl;&Shift;TArchivo Deshacer cierre de pestaña. + + Si ya ha abierto antes archivos en &okular;, puede acceder a ellos rápidamente seleccionándolos en el menú ArchivoAbrir reciente. + &okular; es la aplicación predeterminada de &kde; para archivos &PDF; y &PostScript; que se lanzará cuando pulse con el &LMB; en esos tipos de archivos en el administrador de archivos. Si quiere abrir algún archivo cuyo formato esté admitido por &okular; utilice Abrir con...&okular; desde el menú de contexto del administrador de archivos. + Una vez haya abierto un archivo, probablemente querrá leerlo u hojearlo. Vaya a la siguiente sección para ver cómo hacerlo. + + + Examinar + Esta sección describe cómo puede examinar un documento con &okular;. + Hay diversos modos de desplazarse por el área de visualización. Puede usar las teclas &Up; y &Down;. También puede utilizar la barra de desplazamiento, la rueda del ratón o las teclas &PgUp; y &PgDn;. + Usted también puede usar teclas de navegación estilo vim, H para moverse arriba de la página anterior, L para moverse abajo de la página siguiente, J para moverse una línea abajo, y K para moverse una línea arriba. + Otro modo consiste en mantener pulsado el &LMB; en cualquier parte del documento y desplazar el ratón en la dirección opuesta al lugar hacia donde quiera mover el documento. Este procedimiento solo funciona si está activada la herramienta de navegación. Puede hacerlo seleccionando Herramientas Explorar. + + Cuando se visualiza un documento en el Modo presentación use las teclas &Up; y &Down; para cambiar entre páginas o diapositivas. El número y la posición de la diapositiva actual se mostrarán en la superposición de la esquina superior derecha de la pantalla. + + Si quiere leer un documento con varias páginas emplee la característica de desplazamiento automático de &okular;. Inicie el desplazamiento automático con &Shift;&Down; o &Shift;&Up;. Puede iniciar o detener temporalmente el desplazamiento automático pulsando la tecla &Shift;; al pulsar cualquier otra tecla se desactiva esta característica. + Otro modo de navegar a través de un documento con varias páginas es utilizar el puntero del ratón. Arrastre la página arriba o abajo, continúe arrastrando incluso si alcanza la parte de abajo de la pantalla y más allá. Una vez que cruce el borde de una página, el cursor del ratón aparece arriba o abajo de la pantalla de nuevo y puede continuar arrastrando. + La barra lateral, en el lado izquierdo de la pantalla, le permite dos maneras más de navegar por el documento: + + + Si pulsa la miniatura de una página el área de visualización se desplazará a esta página. + + + Si el documento tiene un índice, pulsando en un elemento del índice se desplazará a la página a la que esté enlazado este elemento. + + + Si el documento contiene capas, puede controlar las que se deben mostrar marcando o desmarcando los elementos de la lista Capas. + + + Si el documento contiene marcadores, active la vista Marcadores y pulse sobre ellos para ir a la página asociada. Si los marcadores no se muestran para el documento actual, puede cambiar rápidamente a los marcadores en todos los archivos abiertos recientemente. + + + Si el documento tiene anotaciones, active la vista Anotaciones y pulse sobre las anotaciones o selecciónelas con las teclas &Up; y &Down; y pulse &Enter; para ir a la página asociada. + + + Algunos documentos contienen enlaces. En tal caso, puede pulsar en ellos y cambiará a la página a la que esté enlazado. Si se trata de un enlace a una página web o a cualquier otro documento, se llamará al manipulador predeterminado de &kde; para ese formato. Por ejemplo, al pulsar sobre un enlace que apunte a https://www.kde.org se abrirá la página web en el navegador por defecto de &kde;. + + Los enlaces internos del documento funcionan solo cuando se usa la Herramienta de navegación. + + También puede utilizar la función siguiente para desplazarse rápidamente a lugares concretos del documento: + + + Puede ir al inicio del documento utilizando &Ctrl;Inicio o Ir Inicio del documento . + + + Puede ir al final del documento utilizando &Ctrl;Fin o utilizando Ir Final del documento . + + + Puede avanzar en el documento utilizando &Space; o &PgDn;. Para ir a la siguiente página del documento use el botón de la barra de herramientas Siguiente página o Ir Siguiente página en la barra de menús. + + + Puede retroceder en el documento utilizando &Backspace; o &PgUp;. Para ir a la página anterior del documento emplee el botón de la barra de herramientas Página anterior o Ir Página anterior en la barra de menús. + + + Puede volver a las posiciones del documento de las que venía en orden cronológico. Considere, por ejemplo, que está leyendo la frase Como se muestra en [15]..., y que quiere saber rápidamente lo que dice la referencia [15]. Para ello, pulse sobre ella para que &okular; salte a la lista de referencias. Use luego &Alt;&Shift;&Left; o Ir Atrás en la barra de herramientas para volver a la posición exacta de la que venía. + + + Puede avanzar en el documento tras el salto atrás, como se ha descrito anteriormente, usando &Alt;&Shift;&Right; o Ir Adelante en la barra de herramientas. + + + Puede ir a la siguiente coincidencia mientras busca usando las teclas F3 o &Enter; (cuando el foco esté en el campo de texto Encontrar), o bien la opción de menú Editar Buscar siguiente . También puede retroceder a la coincidencia anterior usando las teclas &Shift;F3 o &Shift;&Enter; (cuando el foco esté en el campo de texto Encontrar), o bien la opción de menú Editar Buscar anterior . + + + + + Modo presentación + El modo presentación es otra manera de ver documentos en &okular;. Se puede activar en Ver Presentación . Esto muestra el documento página por página. Las páginas se muestran ajustadas, lo que quiere decir que se verá toda la página. + + En los documentos &PDF; puede incluso especificarse que se abran siempre en el modo de presentación. + + En el modo presentación dispone de un asistente en la parte superior de la pantalla. Solo tiene que mover el cursor del ratón a la parte superior de la pantalla para que aparezca. + + &okular; en modo de presentación + + + + + + &okular; en modo de presentación + + + + Para navegar por las páginas puede utilizar el &LMB; (página siguiente) y el &RMB; (página anterior), la rueda del ratón, los iconos de flechas que aparecerán al colocar el ratón en el extremo superior de la pantalla, o las teclas especificadas en la sección Navegación . + Utilice el botón Reproducir/Pausar de la barra superior para iniciar la reproducción de una presentación o para pausarla, respectivamente. + Puede salir en cualquier momento del modo de presentación utilizando la tecla &Esc; o pulsando en el icono Salir que aparecerá si desplaza el ratón al extremo superior de la pantalla. + También puede pintar en la página con un lápiz. Pulse sobre el icono Conmutar modo de dibujo en la barra superior para activar o desactivar la posibilidad de pintar en el modo de presentación. Los dibujos se borran automáticamente cuando se abandona el modo de presentación. También puede pulsar el icono Borrar dibujos para eliminar los dibujos de la página actual. + El modo de presentación admite más de una pantalla en configuración multimonitor. Si existe más de una pantalla, aparecerá un nuevo botón en la barra superior, con el icono de una pantalla: hay una caja desplegable que le permite mover la presentación a cualquiera de las pantallas disponibles. + El modo Presentación tiene algunas opciones de configuración, cuyo significado puede encontrar en Configurar &okular; . + + + + Búsqueda inversa entre editores de &latex; y &okular; + + La búsqueda inversa es una función que encontrará de gran utilidad cuando esté escribiendo un documento &latex;. Si todo está bien configurado, podrá hacer clic en la ventana de &okular; con el botón izquierdo del ratón mientras mantiene pulsada la tecla &Shift;. Tras esto, el editor carga el archivo fuente de &latex; y salta al párrafo correcto. + + La búsqueda inversa no funcionará a menos que: + + + El archivo fuente haya sido compilado con éxito. + &okular; sepa qué editor desea utilizar. + La herramienta de navegación tiene que estar activada. Puede hacerlo seleccionando HerramientasExplorar. + + + Con esta función de &okular;, un clic con el botón izquierdo del ratón mientras pulsa &Shift; en un documento &DVI; o &PDF; hará que el editor abra el documento &latex; asociado y trate de ir a la línea correspondiente. Recuerde que debe indicarle a &okular; el editor que va a usar mediante la opción del menú PreferenciasConfigurar Okular... (en la página Editor). + + Para más detalles sobre la configuración del editor, consulte la correspondiente sección de este manual. + + + Configuración de &okular; + + + + + + Configuración del editor en &okular; + + Configuración del editor en &okular; + + + + + + + Características avanzadas de &okular; + + Archivos empotrados + Si el documento actual tiene archivos empotrados, cuando los abra aparecerá una barra sobre la vista de la página para informarle sobre los archivos integrados. + + La barra de archivos empotrados + + + + + + La barra de archivos empotrados + + + + En este caso, puede pulsar sobre el enlace en el texto de la barra o elegir ArchivoArchivos empotrados para abrir el diálogo de archivos empotrados. Este diálogo le permite ver los archivos empotrados y extraerlos. + + + Formularios + Si el documento actual tiene formularios, cuando los abra aparecerá una barra sobre la vista de página donde puede activar los formularios. + + La barra de formularios + + + + + + La barra de formularios + + + + En este caso, puede pulsar sobre Mostrar formularios en la barra o elegir VerMostrar formularios para introducir datos en los campos del formulario. + + + Firmas + Si el documento actual tiene firmas, se mostrará una barra sobre la vista de la página tras abrir el documento. Le permite abrir el panel de Firmas. + + La barra de firmas + + + + + + La barra de firmas + + + + Puede usar el panel Firmas para inspeccionar la firma del documento y su certificado. + + El panel de firmas + + + + + + El panel de firmas + + + + + Esta función está disponible solo para documentos &PDF;. Necesita instalar al menos la versión 0.51 de Poppler para obtener más información sobre la firma, la versión 0.68 para obtener información sobre la ubicación o el motivo de la firma, o la versión 0.73 para obtener información sobre el certificado de la firma. + + + + Anotaciones + &okular; le permite revisar y hacer notas en los documentos. + + Anotaciones de &okular; + + + + + + Anotaciones de &okular; + + + + &okular; dispone de dos tipos distintos de anotaciones: + Anotaciones de texto como Resaltado amarillo y Subrayado negro para archivos de texto como, ⪚, &PDF;. + Las anotaciones gráficas como Nota emergente, Nota incrustada, Línea a mano alzada, Resaltador, Línea recta, Polígono, Sello, Subrayado, Elipse y Máquina de escribir para todos los formatos reconocidos por &okular;. + Al utilizar el menú de contexto bien en la vista Anotaciones de la barra lateral o en la ventana principal, puede abrir una Nota emergente para cualquier clase de anotación y añadir o editar comentarios. + Las anotaciones no se limitan solamente a archivos PDF, sino que pueden emplearse con cualquier formato que admita &okular;. + &okular; posee la función de «archivado de documentos». Este es un formato específico de &okular; para almacenar el documento más varios metadatos relacionados (en la actualidad solo anotaciones). Puede guardar un «archivo comprimido de documento» del documento abierto eligiendo ArchivoGuardar como y seleccionando Archivo de documento de Okular en el selector de Filtro. Los documentos que se guardan de esta manera tendrán la extensión .okular. Para abrir un archivo de documento de &okular;, ábralo con &okular; como si fuera ⪚ un documento &PDF;. + También puede guardar las anotaciones directamente en los archivos &PDF;. Puede usar Archivo Guardar para guardarlas en el archivo actual o Archivo Guardar como... para guardarlas en un nuevo archivo. + + Debido a restricciones por DRM (por lo general con documentos &PDF;), puede que no sea posible añadir o editar algunas propiedades o suprimir anotaciones. + + + Cualquier acción sobre anotaciones (creación y eliminación de anotaciones, edición de propiedades de anotaciones, reubicación de anotaciones con &Ctrl;+arrastrar y edición del texto contenido en una anotación) se puede deshacer o rehacer usando los elementos correspondientes del menú Editar. También se puede deshacer la acción pulsando &Ctrl;Z, o volver a hacer la acción deshecha pulsando &Ctrl;&Shift;Z. + + Puede configurar las propiedades predeterminadas y el aspecto de cada herramienta de anotación. Consulte la correspondiente sección de este manual. + + Añadir anotaciones + Para añadir anotaciones documento debe usar el botón Anotaciones rápidas de la barra de herramientas principal de &okular; o activar la barra de herramientas de comentarios. Esto se hace seleccionando Herramientas Anotaciones o pulsando F6. Una vez mostrada la barra de comentarios, solo hay que pulsar uno de sus botones o usar accesos rápidos de teclado (teclas desde 1 a 9) para comenzar la creación de esa anotación. + La barra de herramientas de anotaciones le ayuda a hacer anotaciones con dibujos, formas y mensajes de texto. Puede usar la barra de herramientas de anotaciones para marcar un documento (⪚, añadir líneas, elipses, polígonos, sellos, resaltados, subrayados, &etc;). La tabla siguiente describe lo que hace exactamente cada botón por omisión de la barra de herramientas de anotaciones. + + + + + Botón + Nombre de la herramienta + Descripción + + + + + + + + + + + + + + + Resaltador + + + Para resaltar texto del documento con un determinado color de fondo. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para situar el principio del fragmento de texto resaltado; arrastre a continuación para resaltarlo. + Es posible definir el Tipo (Resaltado, Garabato, Subrayado o Tachado), el Color y la Opacidad del resaltador. Pulse con el botón derecho sobre el texto resaltado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Subrayado + + + Para subrayar algún texto. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para situar el principio del fragmento de texto subrayado; arrastre a continuación para subrayarlo. + Es posible definir el Tipo (Resaltado, Garabato, Subrayado o Tachado), el Color y la Opacidad del subrayado. Pulse con el botón derecho sobre el texto subrayado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Garabato + + + Para subrayar texto usando una línea ondulada. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para situar el principio del fragmento de texto subrayado; arrastre a continuación para subrayarlo. + Es posible definir el Tipo (Resaltado, Garabato, Subrayado o Tachado), el Color y la Opacidad del subrayado. Pulse con el botón derecho sobre el texto subrayado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Tachado + + + Para tachar algún texto. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para situar el principio del fragmento de texto subrayado; arrastre a continuación para subrayarlo. + Es posible definir el Tipo (Resaltado, Garabato, Subrayado o Tachado), el Color y la Opacidad del subrayado. Pulse con el botón derecho sobre el texto subrayado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Máquina de escribir + + + La máquina de escribir muestra letras opacas sobre fondo transparente, por lo que es útil para rellenar formularios no interactivos. + Pulse el botón de la herramienta y luego haga clic con el &LMB; mientras lo mantiene pulsado para situar la esquina superior izquierda de la nota; arrastre a continuación para situar la esquina inferior derecha. Introduzca el texto de la nota y pulse Aceptar para guardar la nota, Cancelar para suprimir la inserción de la nota, o Borrar para borrar la nota. + Es posible definir el Tipo de letra y el Color del texto. Pulse con el botón derecho sobre el texto creado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Nota en línea + + + Para intercalar una nota. La nota se mostrará intercalada en el texto. + Pulse el botón de la herramienta y luego haga clic con el &LMB; mientras lo mantiene pulsado para situar la esquina superior izquierda de la nota; arrastre a continuación para situar la esquina inferior derecha. Introduzca el texto de la nota y pulse Aceptar para guardar la nota, Cancelar para suprimir la inserción de la nota, o Borrar para borrar la nota. + Es posible definir el Color, la Opacidad, el Tipo de letra, la Alineación y la Anchura del borde de la nota. Pulse con el botón derecho sobre el icono de la nota creada y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Nota emergente + + + Para dibujar una nota de varias líneas. La nota se podrá ver haciendo doble clic sobre un icono del documento. + Pulse el botón de la herramienta y luego vuelva a pulsar en el lugar del documento donde quiera añadir la nota emergente. Introduzca el texto de la nota emergente y a continuación pulse el botón Cerrar esta nota que hay en la esquina superior derecha de la ventana emergente. + Es posible definir el Color, la Opacidad y el Icono de la nota. Pulse con el botón derecho sobre el icono de la nota creada y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Línea a mano alzada + + + Para dibujar líneas a mano alzada. + Pulse el botón de la herramienta y haga clic con el &LMB; mientras lo mantiene pulsado para situar el inicio de la línea; arrastre a continuación para dibujar la línea. + Es posible definir el Color, la Opacidad y la Anchura de la línea. Pulse con el botón derecho sobre la línea creada y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Flecha (lista desplegable) + + + Para marcar con una flecha. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; para situar el punto inicial de la línea; arrastre a continuación para situar el punto final de la línea y vuelva a hacer clic una vez más. + Es posible definir el Color, la Opacidad, la Anchura, el Inicio de la línea, el Extremo de la línea, la Longitud de la línea principal y la Longitud de las extensiones de la línea principal de las líneas. Para ello, pulse con el botón derecho del ratón sobre la línea creada y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Línea recta (lista desplegable) + + + Para marcar con una línea. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; para situar el punto inicial de la línea; arrastre a continuación para situar el punto final de la línea y vuelva a hacer clic una vez más. + Es posible definir el Color, la Opacidad, la Anchura, el Inicio de la línea, el Extremo de la línea, la Longitud de la línea principal y la Longitud de las extensiones de la línea principal de las líneas. Para ello, pulse con el botón derecho del ratón sobre la línea creada y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Rectángulo (lista desplegable) + + + Para dibujar un rectángulo alrededor de un área determinada. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para posicionar la esquina superior izquierda del rectángulo; arrastre a continuación para situar la esquina inferior derecha de dicho rectángulo. + Es posible definir el Tipo (Rectángulo o Elipse), el Color, la Opacidad, el Relleno de la forma (además de su color) y la Anchura del borde. Para ello, pulse con el botón derecho del ratón sobre el borde creado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Elipse (lista desplegable) + + + Para dibujar una elipse o un rectángulo alrededor de un área determinada. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; mientras lo mantiene pulsado para posicionar la esquina superior izquierda del rectángulo que contendrá la elipse; arrastre a continuación para situar la esquina inferior derecha de dicho rectángulo. + Es posible definir el Tipo (Rectángulo o Elipse), el Color, la Opacidad, el Relleno de la forma (además de su color) y la Anchura del borde. Para ello, pulse con el botón derecho del ratón sobre el borde creado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Polígono (lista desplegable) + + + Para dibujar una figura plana cerrada de tres o más segmentos. La nota correspondiente se puede ver haciendo doble clic dentro del polígono. + Pulse el botón de la herramienta y haga clic a continuación con el &LMB; para situar el primer vértice del polígono; arrastre para situar el segundo vértice. Repita el proceso para dibujar todo el polígono hasta el primer vértice. Haga doble clic si desea añadir alguna nota al polígono. Introduzca el texto de la nota y pulse el botón Aceptar para guardar la nota, Cancelar para suprimir la inserción de la nota, o Borrar para borrar la nota. + Es posible definir el Color, la Opacidad, el Relleno de la forma (además de su color) y la Anchura del polígono. Para ello, pulse con el botón derecho del ratón sobre el polígono creado y seleccione la opción del menú Propiedades. + + + + + + + + + + + + + + Sello + + + Para marcar el texto o la imagen con una determinada forma predefinida. + Pulse el botón de la herramienta para escoger el sello en la lista desplegable y haga clic a continuación con el &LMB; para situar el sello. + Un único clic coloca un sello cuadrado (útil para iconos). Para añadir un sello rectangular puede pulsar con el &LMB; y sostenerlo para colocar el punto superior izquierdo, después arrástrelo para colocar el inferior derecho. + Es posible definir la Opacidad y el Símbolo del sello. Pulse con el botón derecho sobre el icono del sello creado y seleccione la opción del menú Propiedades. + + Esta funcionalidad es experimental. Los sellos personalizados insertados en documentos &PDF; no son visibles en otros lectores de &PDF; distintos de &okular;. + + + + + + + Estas son las anotaciones predeterminadas que proporciona &okular;. Usando la página de anotaciones del diálogo de configuración puede añadir sus propias anotaciones, como sellos personalizados, marcadores de texto o una forma geométrica con color interior para resaltar regiones, etc. + + Es posible añadir código &latex; al texto de las anotaciones. Por favor, añada $$código$$ al texto de la anotación, donde código es cualquier ecuación válida de &latex;, y siga las instrucciones que se muestran en la pantalla para hacer que se visualice usando la distribución de &latex; instalada en su sistema. + + Se pueden configurar las opciones de la herramienta actual usando la propia barra de anotaciones. La tabla siguiente describe exactamente lo que hace el conjunto predeterminado de botones de configuración de la barra de anotaciones. + + + + + Botón + Nombre de la opción + Descripción + + + + + + + + + + + + + + + Anchura de la línea + + + Pulse el botón de la herramienta para escoger la anchura de la lista desplegable. + + + + + + + + + / + + + + + + + Color de las anotaciones + + + Pulse el botón de la herramienta para escoger el color del texto o del borde de la anotación. Puede escoger uno de los colores predefinidos o pulsar la opción Color personalizado... para abrir el diálogo de selección de color. + + + + + + + + + + + + + + Color de relleno de las anotaciones + + + Pulse el botón de la herramienta para escoger el color relleno de la anotación. Puede escoger uno de los colores predefinidos o pulsar la opción Color personalizado... para abrir el diálogo de selección de color. + + + + + + + + + + + + + + Opacidad de las anotaciones + + + Pulse el botón de la herramienta para escoger el nivel de opacidad de la anotación en la lista desplegable (100% es para anotaciones opacas). + + + + + + + + + + + + + + Tipo de letra de las anotaciones + + + Pulse el botón de la herramienta para abrir el diálogo de selección de tipo de letra. + + + + + + + + + + + + + + Preferencias avanzadas para la herramienta de anotación actual + + + Pulse el botón de la herramienta para abrir el diálogo de configuración general de la anotación. + + + + + + Existen tres botones de utilidades adicionales en la barra de anotaciones por omisión. + + + + + Botón + Descripción + + + + + + + + + + + + + + + Añadir la anotación actual al menú Anotaciones rápidas de la barra de herramientas principal. + + Puede usar los accesos rápidos de teclado de &Alt;9 a &Alt;0 para seleccionar las acciones de anotación rápida cada vez que lo desee, incluso si está oculta la barra de anotaciones. + + + + + + + + + + + + + + + Si está marcada, mantener la herramienta de la anotación actual activa tras usarla. + + + + + + + + + + + + + + Ocultar la barra de herramientas de anotaciones. + + + + + + Al pulsar &Shift; puede limitar el ángulo de las anotaciones de línea y de polígono a pasos de 15°, y la proporción de las anotaciones de forma (como rectángulo o elipse) a 1:1. También puede obtener un botón de la barra de herramientas de Configurar barras de herramientas.... + El contenido del menú Anotaciones rápidas se puede configurar usando la Página de anotaciones del diálogo de configuración de &okular;. Esta página se puede abrir pulsando el botón Configurar anotaciones... en el menú emergente. + + Al activar la barra de herramientas de anotaciones le cambiará al modo de navegación. + + Puede detener la edición en cualquier momento pulsando de nuevo el botón de la anotación que está creando o la tecla &Esc;. + La nueva anotación que se cree, tendrá como autor al que designe en la Anotaciones página del diálogo de configuración de &okular;. La página Anotaciones también puede usarse para configurar el contenido de la barra de herramientas de anotaciones. + + + Borrar anotaciones + Para eliminar una anotación, pulse sobre ella con el &RMB; y seleccione Borrar o seleccione una anotación usando el &LMB; y pulse la tecla ∇. + Al borrar una anotación, su ventana se cerrará si estuviera abierta. + + Esta opción no puede ser activada porque el documento no permite borrar anotaciones. + + + + Editar anotaciones + Para editar una anotación, pulse sobre esta con el &RMB; y seleccione Propiedades. Se mostrará un diálogo con las preferencias generales (como color, opacidad, autor, &etc;) y las específicas para ese tipo de anotación. + + Diálogo de propiedades de la anotación + + + + + + Diálogo de propiedades de la anotación + + + + Para desplazar una anotación, mantenga pulsada la tecla &Ctrl; sitúe el puntero del ratón encima y comience a arrastrarlo con el &LMB;. + Haga clic con el &LMB; sobre una anotación para seleccionarla. En el rectángulo de selección aparecerán asas para cambiar su tamaño. Al situar el cursor sobre cualquiera de estas 8 asas que hay en las esquinas o en los bordes, su forma cambiará para indicar que está en el modo que permite cambiar el tamaño. Pulse en cualquier lugar de la anotación para moverla. Pulse &Esc; o haga clic fuera de la anotación para cancelar la selección. + El cambio de tamaño solo está disponible para las los tipos de anotaciones «Nota en línea», «Máquina de escribir», «Sello» y «Elipse». + + + Algunas opciones pueden esta desactivadas dependiendo de los permisos del documento (por lo general con documentos &PDF;). + + + + + Gestión de marcadores + &okular; posee un sistema de marcadores muy flexible. &okular; guarda la posición de la página en el marcador y le permite definir más de un marcador por página. + Para gestionar los marcadores de &okular; puede usar la vista Marcadores que hay en la Barra lateral, el menú Marcadores o el menú de contexto de la vista del documento (pulse con el &RMB; para abrirlo). + + La vista de marcadores + Para abrir la vista Marcadores, pulse la pestaña Marcadores existente en la parte superior de la Barra lateral. Si no se muestra la Barra lateral, pulse el botón Mostrar barra lateral de la barra de herramientas o la opción F7 PreferenciasMostrar barra lateral del menú principal para hacerla visible. + + Menú de contexto de la vista de marcadores + + + + + + Menú de contexto de la vista de marcadores + + + + Puede usar la barra de filtrado que hay en la parte superior de la vista de Marcadores para filtrar el contenido del panel de la lista de marcadores según el texto del cuadro. + El panel de lista permite ver la lista de marcadores en modo de árbol: cada documento de la lista se puede «plegar» o «desplegar» pulsando los iconos < o v que hay junto a él. + Pulse el icono que hay bajo la lista para mostrar solo los marcadores del documento actual. + El menú de contexto de los documentos se puede usar para abrirlos, cambiar su nombre o eliminarlos de la lista. Recuerde que la eliminación de un documento conlleva la eliminación de todos los marcadores de dicho documento. + Los menús de contexto de los marcadores individuales permiten ir al marcador, cambiar su nombre o eliminarlo. + Puede usar el menú que aparece al hacer clic con el botón derecho del ratón sobre los elementos de la tabla de contenido para crear marcadores o para ir a los marcadores anterior o siguiente. + + + + + Opciones de la línea de órdenes + Aunque &okular; se iniciará normalmente desde el menú de programas de &kde; o mediante un icono del escritorio, también se puede abrir desde la línea de órdenes de la ventana de terminal. Existen varias opciones útiles que puede usar cuando utilice este método. + + Especificar un archivo + Al especificar la ruta y el nombre de un determinado archivo, el usuario puede hacer que &okular; abra dicho archivo inmediatamente tras el inicio. Esta opción puede ser similar a lo siguiente: + % okular + + + Para documentos &PDF;, se puede especificar el nombre como nombre-del-documento#destino, donde destino es un nombre de destino determinado dentro del documento. + + + + Otras opciones de la línea de órdenes + Dispone de las siguientes opciones de ayuda en la línea de ordenes + + + okular + Abre la página con el número especificado en el documento. También está disponible usando okular + + + okular + Inicia el documento en el modo de presentación. + + + okular + Iniciar el diálogo de impresión. + + + okular + Iniciar con el diálogo de impresión y salir tras imprimir. + + + okular + Control de una única ejecución. + + + okular + Hace que &okular; impida que su ventana pase a primer plano tras el inicio. + + + okular + Trata de encontrar y resaltar una determinada cadena de texto en el documento. Solo funciona si se proporciona un único documento como argumento de la orden okular. + + + + + + Ajustar ventana a la página + La función «ajustar ventana a la página» cambia el tamaño de la ventana para que tenga exactamente el mismo tamaño que la página con el factor de ampliación actual. Si la página no cabe completamente en la pantalla, se agranda la ventana para que se muestre la mayor parte posible de la página. + Se puede acceder a esta función usando el acceso rápido de teclado &Ctrl;J. + + + + + La barra de menú + + + El menú Archivo + + + + &Ctrl;O Archivo Abrir... + + + Abrir un archivo permitido o un archivo comprimido de documento de &okular;. Si ya hay abierto un archivo, este se cerrará. Para más información, consulte la sección sobre Abrir archivos. + + + + + + Archivo Abrir reciente + + + Abre, desde un submenú, un archivo que ha sido utilizado con anterioridad. Si en ese momento se está mostrando otro archivo, este se cerrará. Para más información, consulte la sección sobre Abrir archivos. + + + + + + Archivo Importar PostScript como &PDF; + + + Abrir un archivo &PostScript; y convertirlo a &PDF;. + + + + + + &Ctrl;&Shift;T Archivo Deshacer cierre de pestaña + + + Volver a abrir el último documento cerrado. Esta acción solo está activa si ha cerrado alguna pestaña de documento durante la sesión actual. + + + + + + Archivo Abrir carpeta contenedora + + + Abrir la carpeta que contiene el documento actual en su gestor de archivos favorito. Esta acción resulta especialmente útil cuando haya descargado un archivo &PDF; de Internet que se abre en &okular;. Es posible que la ubicación de dicho archivo no resulte clara o fácil de encontrar sin esta funcionalidad. + + + + + + &Ctrl;S Archivo Guardar + + + Guarda el documento con todas las modificaciones (anotaciones, contenidos de formularios, &etc;), siempre que el motor del documento permita guardar dichos cambios. Si el motor no permite guardar los cambios, se ofrecerá al usuario la opción de descartarlos o de guardarlos junto al documento en un archivo comprimido de documento de &okular;. + + + + + + &Ctrl;&Shift;S Archivo Guardar como... + + + Guarda el documento con un nombre distinto junto a todas las modificaciones (anotaciones, contenidos de formularios, &etc;), siempre que el motor del documento permita guardar cambios. Si el motor no permite guardar los cambios, se ofrecerá al usuario la opción de descartarlos o de guardarlos junto al documento en un archivo comprimido de documento de &okular;. + + Tenga en cuenta que, debido al modo en que se se ha implementado esta función, incluso si no existen cambios en el archivo, no es necesario que el nuevo archivo sea una copia exacta bit a bit del archivo original (⪚, puede tener una comprobación SHA-1 diferente, &etc;). + + + + + + + F5 Archivo Volver a cargar + + + Vuelve a cargar el archivo actualmente abierto. + + + + + + &Ctrl;P Archivo Imprimir... + + + Imprime el documento que se muestra actualmente. Tenga en cuenta que &okular; tiene algunas opciones específicas para imprimir &PDF; que están disponibles tras pulsar el botón Opciones +> +> y escoger Opciones de &PDF;. Use estas opciones para imprimir las notas o para configurar el modo de rasterización si tiene problemas al imprimir algunos símbolos o si necesita cambiar el modo de escalado. + + Las opciones del modo escalado solo están disponibles tras marcar la opción Forzar rasterización. + + + + + + + Archivo Imprimir vista previa... + + + Muestra una vista previa de cómo quedará impreso el documento con las opciones predeterminadas. + + + + + + &Alt;Intro Archivo Propiedades + + + Muestra información básica sobre el documento, como su título, autor, fecha de creación y detalles sobre las tipografías empleadas. La información disponible depende del tipo de documento. + + Por favor, preste atención a la información sobre la sustitución de tipos de letra en la pestaña Tipos de letra del diálogo de Propiedades. Muchos problemas de visualización de tipos de letra se pueden resolver instalando los tipos de letra de sustitución + + + + + + Archivo Archivos empotrados... + + + Ver los archivos empotrados en el documento si existen. Para más información vea la sección Archivos empotrados. + + + + + + Archivo Exportar como + + + Este elemento contiene los formatos a los que se puede exportar el documento actual. La primera entrada para todo tipo de documentos es siempre Texto sin formato.... + La segunda entrada es Archivo comprimido de documento que le permite guardar el documento con sus anotaciones en un formato de archivo comprimido específico de &okular;. Mediante esto, es posible compartir con facilidad el documento original y sus anotaciones con otros usuarios de &okular; o trabajar con ellos conjuntamente. + + + + + + Archivo Compartir + + + Este elemento contiene los servicios que puede usar para compartir el documento actual con otras personas o enviarlo a otros dispositivos. Las entradas de este submenú están controladas por el sistema. Dependen del formato del documento actual y de los complementos de KPurpose instalados. + + + + + + &Ctrl;Q Archivo Salir + + + Cierra &okular;. + + + + + + + El menú Editar + + + + + &Ctrl;Z Editar Deshacer + + + Deshace la última orden de edición de anotaciones (creación y eliminación de anotaciones, edición de propiedades de anotaciones, reubicación de anotaciones con &Ctrl;+arrastrar y edición del texto contenido en una anotación). + + + + + + &Ctrl;&Shift;Z Editar Rehacer + + + Rehace el último paso deshecho al editar anotaciones. + + + + + + + + &Ctrl;C Editar Copiar + + + Copiar el texto seleccionado actualmente en el modo Selección de texto al portapapeles. + + + + + + + + &Ctrl;A Editar Seleccionar todo + + + Seleccionar todo el texto (si el documento lo proporciona). Solo funciona en el modo Selección de texto. + + + + + + + + Editar Seleccionar todo el texto de la página actual + + + Selecciona todo el texto (si el documento lo proporciona) de la página actual. + + + + + + + + &Ctrl;F Editar Buscar... + + + Muestra la barra de búsqueda en la parte inferior del área de visualización que le permite buscar una cadena en el documento. + + + + + + F3 Editar Buscar siguiente + + + Busca de nuevo la secuencia previamente buscada en el documento. + + + + + + &Shift;F3 Edit Buscar anterior + + + Vuelve a la anterior aparición de la cadena de búsqueda en el documento. + + + + + + + El menú Ver + + + + &Ctrl;&Shift;P Ver Presentación + + + Activa el modo Presentación. Para más información, consulte la sección sobre el Modo presentación. + + + + + &Ctrl;&Shift; F Ver Modo de pantalla completa + + + Activa el modo de pantalla completa. Tenga en cuenta que el modo de pantalla completa es diferente del modo presentación y tiene la particularidad de que oculta las decoraciones de las ventanas, la barra de menú y la barra de herramientas. + + + + + &Ctrl;+ Ver Acercar + + + Incrementa el tamaño de la vista del documento. + + + + + + &Ctrl;- Ver Alejar + + + Reduce el tamaño de la vista del documento. + + + + + Ver Ampliar al 100% + + + Amplía la imagen del documento a su tamaño real, como se indica en los parámetros del documento. + + + + + Ver Ajustar ancho + + + Cambia el tamaño de la vista del documento a un valor que haga que las páginas ocupen todo el ancho del espacio de la vista. + + + + + Ver Ajustar a la página + + + Cambia el tamaño de la vista del documento a un valor que haga que pueda ver al menos una página entera. + + + + + Ver Ajuste automático + + + Cambiar la ampliación de la vista del documento a un valor que, dependiendo de la relación de tamaño entre la página y el área de visión, hace automáticamente que la anchura de las páginas sea igual a la de la vista del documento (como ajustar al ancho), la altura de las páginas sea igual a la altura de la vista del documento (como ajustar a la altura), o bien que se ajuste a toda la página visible (como ajustar a la página). + + + + + Ver Modo de vista + + + Este submenú le permite elegir el modo de vista de las páginas. Las posibles opciones son: Página única (una sola página por fila), Páginas encaradas (dos páginas por fila, estilo libro), Páginas encaradas (primera página centrada) y Resumen (el número de columnas es el especificado en configuración de &okular;). + De forma adicional, puede activar el modo Continuo. En este modo se muestran todas las páginas del documento y puede desplazarse a través de ellas con suavidad. En caso contrario, solo se muestra una página cada vez (o una fila de páginas). + + + + + Ver Orientación + + + Este submenú le permite cambiar la orientación de las páginas del documento. + + El giro se aplica a la orientación de todas las páginas. + + Puede seleccionar Orientación original para restablecer la orientación del documento descartando todos los giros aplicados manualmente. + + + + + Ver Recortar vista + + + Este submenú le permite eliminar el borde blanco de las páginas al visualizarlas (opción Recortar márgenes) o recortar a la selección del área de visión (opción Recortar a la selección). + El modo recortar a la selección le permite dibujar una selección sobre la página visualizada para definir un rectángulo de recorte a aplicar a todas las páginas del documento. Si selecciona un rectángulo de recorte pequeño, se fuerza un tamaño de mínimas dimensiones (20% como porcentaje del tamaño total de la página). + El modo recortar márgenes persiste cada vez que inicie &okular;. El modo recortar a la selección se olvida cada vez que inicie &okular;. + Cuando cambia del modo recortar márgenes al modo recortar a la selección en &okular;, la vista sale del modo recortar márgenes para poder usar la selección de recorte rectangular. + El modo de recorte se puede desactivar seleccionando la misma opción del menú que se usa para activarla. + + + + + Ver Mostrar/Ocultar Formularios + + + Muestra o esconde la visualización de los campos de formulario del documento. + + Esta opción de menú se activa solo si el documento actual contiene campos de formulario. + + + + + + + + + El menú Ir + + + + Ir Página anterior + + + Muestra la página anterior del documento. + + + + + Ir Página siguiente + + + Muestra la página siguiente del documento. + + + + + &Ctrl;&Home; Ir Inicio del documento + + + Ir al inicio del documento. + + + + + &Ctrl;&End; Ir Final del documento + + + Ir al final del documento. + + + + + &Alt;&Shift;&Left; Ir Atrás + + + Va a la última página visitada del documento. + + + + + &Alt;&Shift;&Right; Ir Adelante + + + Avanza a la siguiente vista del documento. Esto solo funciona si ya ha retrocedido anteriormente. + + + + + &Ctrl;G Ir Ir a la página... + + + Abre un cuadro de diálogo que le permite ir a cualquier página del documento. + + + + + + + El menú Marcadores + + + + &Ctrl;B Marcadores Añadir/Quitar marcador + + + Añadir o eliminar un marcador para la posición actual. + + + + + Marcadores Cambiar nombre del marcador + + + Cambiar el nombre de un marcador para la posición actual. + + + + + Marcadores Marcador anterior + + + Ir al marcador anterior, o no hacer nada si no hay marcadores anteriores al actual. + + + + + Marcadores Marcador siguiente + + + Ir al siguiente marcador, o no hacer nada si no hay marcadores posteriores al actual. + + + + + Marcadores Sin marcadores + + + Esta opción está siempre desactivada y aparece en este menú solo si el documento actual no tiene marcadores. En caso contrario, se muestra aquí una lista con todos los marcadores. Si pulsa sobre estos marcadores podrá acceder directamente a la posición asociada. + + + + + + + El menú Herramientas + + + + &Ctrl;1 Herramientas Explorar + + + El ratón tendrá un comportamiento normal, el &LMB; para arrastrar el documento y seguir los enlaces y el &RMB; para añadir marcadores y ajustar la anchura. + + + + + &Ctrl;2 Herramientas Ampliar + + + El ratón puede trabajar como una herramienta de aumento. Pulsando el &LMB; y arrastrando puede aumentar la vista para ver el área seleccionada, pulsando el &RMB; se podrá ir a la anterior visualización del documento. + + + + + &Ctrl;3 Herramientas Selección de área + + + El ratón funcionará como herramienta de selección rectangular. En este modo, al pulsar el &LMB; y arrastrar se dibujará un cuadro de selección y tendrá la posibilidad de copiar el contenido seleccionado en el portapapeles, leer el texto seleccionado o transformar la región seleccionada en una imagen para guardarla en un archivo. + + + + + &Ctrl;4 Herramientas Selección de texto + + + El ratón puede funcionar como herramienta de selección. De este modo, pulsando el &LMB; y arrastrando tendrá la opción de copiar el texto del documento. A continuación, pulse con el &RMB; para copiarlo al portapapeles o leer la selección. + + + + + &Ctrl;5 Herramientas Selección de tabla + + + Dibuje un rectángulo alrededor del texto o de la tabla y haga después clic con el &LMB; para dividir el bloque de texto en filas y columnas. Un clic con el &LMB; sobre una línea existente la elimina y fusiona las filas o columnas adyacentes. + + + + + &Ctrl;6 Herramientas Lupa + + + Activa el modo lupa para el puntero del ratón. Pulse y mantenga el &LMB; para activar el elemento gráfico de la lupa; mueva el puntero para desplazarse por el documento. La lupa escala cada píxel del documento a 10 píxeles en el visor de la lupa. + + + + + F6 Herramientas Anotaciones + + + Abre la barra de anotaciones. La barra de herramientas de anotaciones le permite añadir anotaciones al documento que está leyendo. Para más información, por favor consulte la sección Anotaciones. + + + + + Herramientas Leer todo el documento + + + Herramientas Leer la página actual + + + Herramientas Detener la lectura + + + Herramientas Pausar/continuar la lectura + + + Estos elementos le permiten leer todo el documento o solo la página actual y detener la lectura usando el servicio de voz del sistema. Este servicio está proporcionado por una biblioteca de &Qt; que controla «speech-dispatcher» en &Linux;, y por sistemas de voz nativos en otras plataformas. Se puede escoger la voz actual usando la página de configuración de Accesibilidad de &okular;. + Las acciones Hablar... se activan solo si el sistema dispone de algún servicio de voz. + + + + + + + Los menús Preferencias y Ayuda + Además de los menús Preferencias y Ayuda comunes de &kde; que se describen en el capítulo Menú de la documentación de los fundamentos de &kde;, &okular; tiene estas entradas de menú específicas de la aplicación: + + + + F7 Preferencias Mostrar la barra lateral + + + Muestra u oculta la barra lateral. + + + + + Preferencias Mostrar barra de páginas + + + Conmuta la visualización de la barra de páginas en el área inferior del documento para ahorrar espacio vertical en la ventana de &okular;. Note que los números de página siempre se mostrarán en la barra de herramientas predeterminada. + + + + + Preferencias Configurar motores de programas... + + + Abre la ventana de Configuración del motor. + + + + + + + + Configuración de motores de &okular; + Puede configurar motores de &okular; mediante Preferencias Configurar motores... . En la actualidad solo se proporcionan opciones de configuración para los motores EPub, &PostScript;, FictionBook, Txt, texto de OpenDocument y &PDF;. + + El diálogo de configuración de motores + + + + + + El diálogo de configuración de motores + + + + Use las páginas de configuración para los motores EPub, FictionBook, Mobipocket, Markdown, texto sencillo y texto de OpenDocument para definir el tipo de letra a usar para mostrar los documentos en el correspondiente formato. El botón Escoger... de estas páginas abre la ventana estándar de &kde; para seleccionar el tipo de letra. Por favor, consulte la documentación de los principios básicos de &kde; para más detalles. + La descripción de las páginas de configuración de los motores Markdown, &PostScript; y &PDF; se puede encontrar a continuación. + + Configuración del motor Markdown + Puede configurar el motor de representación Markdown de &okular;, basado en Discount escogiendo Markdown en la lista que hay en la parte izquierda del diálogo de configuración. Dispone de la siguiente opción adicional que puede configurar. + + + + + Activar el formato SmartyPants + + + Cuando está marcada, esta opción permite a &okular; procesar el formato SmartyPants. Este formato puede ser problemático en textos técnicos por algunas sustituciones no deseadas (por ejemplo, sustituye (C) con el símbolo de copyright). Esta opción está marcada por omisión. + + + + + + + Configuración del motor &PostScript; + Puede configurar el motor de representación &PostScript; de &okular; basado en Ghostscript escogiendo Ghostscript en la lista que hay en la parte izquierda del diálogo de configuración. La única opción configurable es la siguiente. + + + + + Usar tipos de letra de la plataforma + + + Esta opción determina si se le debe permitir a Ghostscript que use los tipos de letra de la plataforma; si no está marcada, solo se permitirá el uso de los tipos de letra integrados en el documento. Esta opción está marcada por omisión. + + + + + + + Configuración del motor &PDF; + Puede configurar el motor de representación &PDF; de &okular; basado en Poppler escogiendo &PDF; en la lista que hay en la parte izquierda del diálogo de configuración. La única opción configurable es la siguiente. + + + + + Mejorar las líneas finas + + + El dibujo de líneas en &okular; se implementa en dos pasos: generación de la ruta de recorte y rellenado de dicha ruta. Cuando la línea del documento original tiene menos de un píxel de grosor, esta solución de dos pasos puede causar problemas. Para dichas líneas, la ruta de recorte se rellena con un color que depende del grosor de la parte de la línea que hay dentro del área de recorte. Si esta parte de la línea es muy pequeña, el contraste entre la forma y el color de fondo puede ser demasiado bajo para que la línea se pueda reconocer. En este caso, las cuadrículas de las líneas no se muestran de una forma agradable. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Línea fina (en rojo), su ruta de recorte (línea de trazos) y límites de píxeles (líneas negras sólidas) + Línea delgada mostrada en bajo contraste + + + + + &okular; contiene dos opciones para mejorar el aspecto de las líneas finas. + La primera opción es Sólida. Con esta opción, &okular; ajusta la ruta de recorte y la posición de la línea para que ambas estén en el mismo límite de píxeles; &ie;, &okular; agranda las líneas finas a un píxel en el dispositivo de salida. Este modo es similar a Mejorar líneas finas de Adobe Reader. Si se escoge esta opción, las líneas finas siempre se agrandarán. + + + + + + + + Línea delgada con realce Sólido + + + Línea delgada con realce Sólido + + + + + La segunda opción es Forma. Con esta opción, la ruta de recorte y la línea se ajustan también al límite de píxel, pero se corrige la intensidad de la línea según su grosor. + + + + + + + + Línea delgada con realce de Forma + + + Línea delgada con realce de Forma + + + + + Las líneas finas no se mejoran por omisión (opción No). + + + + + + + + Configuración de &okular; + + Configuración general + Puede configurar &okular; mediante Preferencias Configurar &okular;.... El diálogo de configuración está dividido en seis secciones. Este capítulo describe detalladamente las opciones disponibles. + + + General + + + Accesibilidad + + + Rendimiento + + + Presentación + + + Anotaciones + + + Editor + + + + El diálogo de configuración + + + + + + El diálogo de configuración + + + + En función de los motores de programa instalados, la opción de menú Configuración Configurar motores... puede estar activada. Este dialogo de configuración mantiene las configuraciones de los motores de programa que pueden ser configurados. + + + General + + + Usar desplazamiento suave + + Si se deben mostrar transiciones animadas al desplazarse usando la rueda del ratón y el teclado. + + + + Mostrar barras de desplazamiento + + Indica si mostrar barras de desplazamiento para la vista de documento. + + + + Enlazar las miniaturas con la página + + Indica si la vista de miniaturas debe mostrar siempre la página actual o no. + + + + Muestra consejos y mensajes de información + + Indica si se mostrarán mensajes informativos durante inicio, la carga de archivos, &etc; + + + + Mostrar el título del documento en la barra de título, si está disponible + + Indica si se muestra el título del documento actual en la barra de título de la ventana de &okular;. Si no se encuentran metadatos para el título en el documento, o si este elemento está sin marcar, &okular; muestra el nombre del archivo del documento. + + + + Cuándo no mostrar el título del documento + + Puede escoger entre dos opciones, Mostrar solo el nombre de archivo o Mostrar la ruta completa del archivo. + + + + Usar color de fondo personalizado + + Activa la selección del color de fondo del documento (el color que rodea a la página que se muestra). Por omisión se usa el color del conjunto de herramientas &Qt; si esta opción no está marcada. + + + + Abrir nuevos archivos en pestañas + + Indica si se deben abrir en pestañas los documentos nuevos. No se usan pestañas por omisión. + Los accesos rápidos de teclado predeterminados para cambiar entre pestañas son &Ctrl;. (Siguiente pestaña) y &Ctrl;, (Anterior pestaña). + + + + Cambiar a una pestaña existente si el archivo ya está abierto + + Indica si &okular; debe cambiar a una pestaña si el archivo ya está abierto en lugar de abrir una nueva pestaña. Esta opción está desactivada de forma predeterminada. Se puede cambiar solo si se ha activado Abrir nuevos archivos en pestañas + + + + Seguir las limitaciones DRM + + Indica si &okular; debe respetar las restricciones DRM (Digital Rights Management). Las limitaciones DRM se utilizan para impedir realizar determinadas acciones dentro de los documentos &PDF;, tales como la copia del contenido en el portapapeles. Advierta que en algunas configuraciones de &okular; está opción no está disponible. + + + + Volver a cargar el documento si cambia el archivo + + Indica si en los archivos abiertos debe comprobarse automáticamente si ha habido cambios y, de ser preciso, actualizarlos. + + + + Muestra el dialogo de selección del motor del programa + + Si &okular; debe preguntar al usuario que motor usar en caso de que haya más de uno disponible para abrir el archivo actual Si no está marcada, &okular; usará el motor de mayor prioridad. + + + + Dirección de lectura de derecha a izquierda + + Si se debe usar la dirección de lectura de derecha a izquierda de modo predeterminado en los archivos que se abran. Puede ser de utilidad para algunos sistemas de escritura. + + + + Columnas resumen + + Esta opción representa el número de columnas que se usan en el modo resumen. + + + + Solapamiento RePág/AvPág + + Aquí puede definir el porcentaje del área mostrada actualmente que debe continuar siendo visible tras pulsar las teclas &PgUp;/&PgDn;. + + + + Aumento predeterminado + + Estas opciones especifican el modo de zoom predeterminado para archivos que no se han abierto previamente. Para aquellos archivos que se abrieron con anterioridad se aplica el modo de zoom previo. + + + + + + Accesibilidad + + + Dibujar un borde alrededor de los enlaces + + Indica si se dibujará un borde alrededor de los enlaces. + + + + Cambiar colores + + Activa las opciones de cambio de color. + + + + Invertir colores + + Invierte los colores en la vista; &ie;, los objetos blancos se mostrarán como negros. + + + + Cambiar el color del papel + + Cambia el color del papel; &ie;, el fondo del documento. + + + + Cambiar la luminosidad y oscuridad de los colores + + Cambia los colores claro y oscuro, lo que significa que el negro no se presentará como negro sino como el color oscuro seleccionado y el blanco como el color claro elegido. + + + + Convertir a blanco y negro + + Convierte el documento a blanco y negro. Puede especificar el umbral y el contraste. La configuración del umbral a un valor mayor moviéndolo a la derecha, hará que se utilicen grises más claros. + + + + Invertir luminosidad + + Invierte la luminosidad de todos los colores. Los claros y los oscuros se intercambiarán, aunque la tonalidad y la saturación no se verán afectadas. El contraste de las imágenes suele ser peor que con Invertir luma (sRGB lineal). + + + + Invertir luma (sRGB lineal) + + Invierte la luma de todos los colores. Los claros y los oscuros se intercambiarán, aunque la tonalidad y la saturación no se verán afectadas. El contraste de las imágenes se preserva mejor que con Invertir luminosidad, aunque los gráficos y las marcas de texto a todo color suelen verse peor. Usa coeficientes de luma sRGB, pero sin corrección de gamma. + + + + Invertir Luma (simétrica) + + Invierte la luma de todos los colores usando coeficientes de luma simétricos. Los claros y los oscuros se intercambiarán, aunque la tonalidad y la saturación no se verán afectadas. Es muy similar a Invertir luminosidad, aunque el contraste puede ser mejor en algunos casos. + + + + Desplazar a tonalidad positiva + + Desplaza la tonalidad de todos los colores 120 grados. Puede mitigar algunos problemas de contraste en gráficos a todo color. + + + + Desplazar a tonalidad negativa + + Desplaza la tonalidad de todos los colores 240 grados. Puede mitigar algunos problemas de contraste en gráficos a todo color. + + + + Motor + + Le permite escoger el motor de habla (TTS) que usará &okular;. El predeterminado es speechd TTS, aunque puede usar todos los idiomas y voces disponibles en los sintetizadores existentes en su plataforma. En &Linux;, se usa «speech-dispatcher» por omisión para determinar las voces disponibles. + + + + + + Rendimiento + + + Activar efectos de transparencia + + Dibuja las selecciones y otros gráficos especiales utilizando efectos de transparencia. Si se desactiva la opción para dibujar se utilizarán contornos o estilos de relleno opacos, incrementándose la velocidad en las selecciones. + + + + Uso de memoria + + &okular; puede mejorar notablemente el rendimiento afinando el uso de la memoria, dependiendo de su sistema y sus gustos. Cuanta más memoria le permita utilizar, más rápido se comportará el programa. El perfil predeterminado es bueno para cualquier sistema. Aun así, puede impedir que &okular; utilice más memoria de la necesaria seleccionando el perfil «Bajo», o dejarle utilizar más seleccionando el «Agresivo». Use el perfil «Voraz» para precargar todas las páginas sin riesgo de que se colapse la memoria del sistema (solo se usará el 50% de la memoria total o de la memoria libre). + + + + Representación + + El uso de este grupo de opciones le permite mejorar la generación de texto e imágenes en &okular;. El resultado depende del dispositivo donde se muestre el documento. Las opciones Activar suavizado de bordes en el texto y Activar antialiasing en gráficos se pueden usar para activar o desactivar el antialiasing espacial del texto y de las imágenes del documento de forma proporcional. La opción Activar sugerencias del tipo de letra activa o desactiva las sugerencias del tipo de letra. El antialiasing y las sugerencias del tipo de letra modifican la forma en que se muestra el documento, por lo que deberá afinarlas según sus preferencias. + + + + + + Presentación + + + Avanzar cada + + Activa el avance automático de páginas para un periodo de tiempo dado. + + + + Bucle tras la última página + + Cuando el navegador esté en modo presentación y llegue a la última página, a continuación volverá a aparecer la primera. + + + + Navegación táctil + + Le permite afinar la navegación mediante mediante la pantallaç táctil al tocar en la presentación usando los tres siguientes valores posibles: + + + Tocar en los lados izquierdo/derecho para ir atrás/adelante: al tocar en la mitad izquierda o derecha de la pantalla, la presentación va a la diapositiva anterior o siguiente, respectivamente. + + + Tocar en cualquier lugar para ir adelante (predeterminado): al tocar en la pantalla, la presentación avanzará a la siguiente diapositiva, sin importar en qué parte de la pantalla ha tocado. + + + Desactivada: los toques en la pantalla no hacen nada. + + + + + + Color del fondo + + El color con el que se rellenará la parte de la pantalla que no esté cubierta por la página cuando se encuentre en modo presentación. + + + + Cursor del ratón + + Indica si el ratón estará siempre oculto, si se mostrará siempre o si se ocultará después de un pequeño tiempo de inactividad. + + + + Mostrar indicador de progreso + + Indica si cada vez que cambie de página se muestra un círculo de progreso que indique la página actual y el número total de páginas en la esquina superior izquierda de la pantalla de presentación. + + + + Mostrar página de índice + + Indica si se mostrará la página de índice al principio de la presentación con el título, autor y número de páginas del documento. + + + + Activar transiciones + + Use esta casilla para activar o desactivar los efectos de transición entre páginas. + + + + Transición predeterminada + + El efecto de transición entre página y página si no se ha especificado ninguna en el documento. Seleccione Transición aleatoria para hacer que &okular; elija al azar uno de los efectos disponibles. + + + + Colocación + + En esta sección puede elegir la Pantalla usada para mostrar la presentación. + Pantalla actual es la misma pantalla de &okular; en la que comienza el mod presentación. + Pantalla por defecto es la pantalla marcada por defecto en la configuración de xinerama. + Pantalla 0, Pantalla 1 &etc; son las pantallas disponibles. + + + + Configuración de la herramienta de dibujo + + Gestionar los colores del lápiz usado al dibujar en las páginas durante el modo de presentación. + + + + + + Anotaciones + + La página de anotaciones del diálogo de configuración + + + + + + La página de anotaciones del diálogo de configuración + + + + + + Autor + + El autor de los contenidos añadidos a un documento. Por omisión es el nombre de la página Contraseña & Usuario del módulo de &systemsettings; Detalles de la cuenta. + + + + Herramientas de anotaciones + + Este panel se usa para configurar su barra de herramientas de anotaciones. + Hay cinco botones (Añadir, Editar, Eliminar, Mover arriba, Mover abajo) y un cuadro de lista (que lista los contenidos de la barra de herramientas de anotaciones actual) que se usan para configurar la barra de herramientas. + Si usted necesita añadir algún botón de herramientas a la barra de herramientas pulse sobre el botón Añadir. Usted puede elegir el Nombre, el Tipo y la Apariencia de la herramienta creada. + + Por favor, recuerde que las herramientas de anotaciones en &okular; son altamente configurables. Por ejemplo, usted puede disponer de dos botones de la misma herramienta pero de distintos colores. No vacile en experimentar el elegir el conjunto de botones que se ajusten exactamente a su flujo de trabajo. + + Pulse sobre algún elemento en el cuadro de lista, a continuación pulse sobre el correspondiente botón en el lado derecho de la página a editar, elimine, mueva hacia arriba o abajo el elemento. El acceso rápido de teclado de la herramienta (teclas desde 1 a 9) depende de su posición en la lista de la barra de herramientas de anotaciones. + + + + Uso de sellos personalizados + + + Cree el icono que desee usar para su propio sello y guárdelo en cualquier formato gráfico permitido por &okular;. + Pulse el botón Añadir, seleccione el tipo Sello e introduzca un nombre para su sello. + Introduzca la ruta completa de su icono personalizado en la lista desplegable en el grupo Símbolo de sello. + + + + + + + Editor + + + Editor + + Elija el editor que desee emplear cuando &okular; quiera abrir un archivo fuente. Esta es la situación en la cual el documento contenga referencias a los diversos lugares (generalmente números de filas y columnas) de las fuentes desde las que fue generado. El formato &DVI; admite de modo nativo el añadido de información sobre las fuentes del documento &latex; a partir del que se generó. Un sistema similar existe para documentos &PDF; llamado pdfsync, el cual guarda esta información extra en un archivo externo nombrado después del propio archivo &PDF;, por ejemplo mi-documento.pdfsync para mi-documento.pdf). + &okular; se distribuye con preferencias preconfiguradas para los siguientes editores: &kate;, Kile, SciTE, el cliente &Emacs;, el cliente LyX, TeXstudio y TeXiFy IDEA. + + Para usar la búsqueda inversa en &kile; tendrá que compilar el archivo &latex; con la configuración Moderna. + + + + + Orden + + Esta es la orden y sus parámetros para llamar al editor seleccionado con el archivo fuente o el documento actual. + Este campo se rellenará automáticamente si usa uno de los editores preconfigurados. En caso contrario, elija Editor de texto personalizado en la lista desplegable Editor y consulte la documentación de su editor favorito para encontrar la orden correcta. + Puede usar los siguientes parámetros de sustitución: + + + %f - el nombre del archivo + + + %l - la línea del archivo a alcanzar + + + %c - la columna del archivos a alcanzar + + + Si no se especifica %f, se añadirá el nombre del documento a la orden especificada. + + + + + + + Créditos y licencia + + + Copyright del programa: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Encargado actual + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it Desarrollador de &kpdf; + + + + Copyright de la documentación: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Autor + Titus Laska titus.laska@gmx.de Algunas actualizaciones y adiciones + Pino Toscano pino@kde.org + + Traducido por Rafael Rodríguez Martín apt-drink@telefonica.net , Javier Fdez. Retenaga jfrtnaga@yahoo.es y por Javier Viñal fjvinal@gmail.com &underFDL; &underGPL; + + &documentation.index; + + + + diff --git a/po/es/docs/okular/man-okular.1.docbook b/po/es/docs/okular/man-okular.1.docbook new file mode 100644 index 0000000..cb0839b --- /dev/null +++ b/po/es/docs/okular/man-okular.1.docbook @@ -0,0 +1,237 @@ + + +]> + + + + +Manual del usuario de Okular +YuriChornoivan Página man de Okular. yurchor@ukr.net +2019-02-14 +Okular 1.7 +Aplicaciones de KDE + + + +okular +1 + + + +okular +un visor universal de documentos + + + +okular opciones de Okular URL + + + +Descripción +okular está pensado para mostrar documentos de diferentes formatos. + + + +Opciones de Okular + + + + + +Abre la página indicada del documento. + + + + + + +Inicia el documento en el modo de presentación. + + + + + + +Iniciar con el diálogo de impresión. + + + + + + +Iniciar con el diálogo de impresión y salir tras imprimir. + + + + + + +Controla una única ejecución. + + + + + + +Hace que Okular impida que su ventana pase al primer plano tras el inicio. + + + + + + +Buscar una cadena en el texto. + + + + + +Argumentos + + + + +La dirección del documento a abrir. Para PDF se puede indicar como nombre_del_documento#destino, donde destino es un determinado nombre de destino dentro del documento. + + + + + +Sugerencias y comentarios +En IRC (irc.freenode.net #okular), por correo electrónico (okular-devel@kde.org) o en la Web (<https://okular.kde.org/>). + + + +Vea también + +Dispone de documentación de usuario más detallada en help:/okular (introduzca esa URL en &konqueror; o ejecute khelpcenter help:/okular). +kf5options(7) +qt5options(7) +Dispone de más información en https://okular.kde.org/ + + + +Copyright +Copyright © 2002 Wilco Greven, Christophe Devriese +Copyright © 2004-2005 Enrico Ros +Copyright © 2005 Piotr Szymanski +Copyright © 2004-2012 Albert Astals Cid +Copyright © 2006-2009 Pino Toscano +Licencia: Pública General de GNU Versión 2 <https://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/es/okular.po b/po/es/okular.po new file mode 100644 index 0000000..a5a5448 --- /dev/null +++ b/po/es/okular.po @@ -0,0 +1,5735 @@ +# translation of okular.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020. +# Javier Viñal , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-27 13:36+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un visor universal de documentos" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004-2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004-2017 Albert Astals Cid\n" +"© 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Encargado anterior" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" +"Gran cantidad de trabajos en la infraestructura, motores ODT y FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Desarrollador" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Creó Okular a partir del código fuente de KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Desarrollador de KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Gráficos para las anotaciones" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Herramienta de selección de tablas" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Mejoras en las anotaciones" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Ir a la página %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Abrir archivo externo" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Ejecutar «%1»..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Primera página" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Página anterior" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Página siguiente" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Última página" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Atrás" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Adelante" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Salir" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Iniciar presentación" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Terminar presentación" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Encontrar..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Ir a la página..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reproducir sonido..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Guion JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reproducir película..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Reproducir película" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Detener película" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Pausar película" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Continuar película" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Selección de motor" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Se ha encontrado más de un motor para el tipo MIME:
%1 (%2)." +"

Seleccione cuál se debe usar:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "La mayoría de las páginas son %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Vertical %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Apaisado %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 pulgadas (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Continuar la búsqueda desde el principio" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Continuar la búsqueda desde el final" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"No se puede encontrar un complemento capaz de manejar el documento pasado." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "eliminar anotaciones" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"El documento ha intentado ejecutar una aplicación externa, aunque Okular no " +"lo ha permitido por motivos de seguridad." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "" +"No se ha encontrado ninguna aplicación para abrir archivos de tipo MIME %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "No se puede abrir un archivo temporal" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Ha fallado la conversión de la impresión" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "El proceso de impresión se ha bloqueado" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "No se puede iniciar el proceso de impresión" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Ha fallado la impresión en archivo" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "La impresora está en un estado no válido" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "No se ha podido encontrar el archivo donde imprimir" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "No existe el archivo donde imprimir" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"No se puede encontrar un binario apropiado para imprimir. Asegúrese de que " +"el binario lpr de CUPS está disponible" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "El tamaño de la página a imprimir no es válido" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "No se puede abrir «%1». El archivo no existe" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Título" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Asunto" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Descripción" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creador" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Productor" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Páginas" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Creado" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificado" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Tipo MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoría" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Palabras clave" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Ruta del archivo" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Tamaño del archivo" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Tamaño de la página" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "añadir anotación" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "eliminar anotación" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "modificar las propiedades de la anotación" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "traducir anotación" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "ajustar anotación" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "editar texto" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "editar contenido de la anotación" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "editar el contenido del formulario" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "editar la selección de una lista del formulario" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "editar la selección de la lista desplegable del formulario" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "editar el estado de los botones del formulario" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Texto plano..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Texto OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opciones de la impresión" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajustar al área imprimible" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Ajustar a la página completa" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de escalado:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Falta el tipo de alerta" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "No volver a mostrar este mensaje" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Origen: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Tipo &de letra por omisión:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rojo" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Naranja" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Amarillo" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verde" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cian" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Azul" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Blanco" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Gris" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Negro" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Anchura %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Anchura de la línea de la anotación (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Color de la anotación (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Color de relleno de la anotación (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacidad de la anotación (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Tipo de letra de la anotación (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Añadir la anotación actual al menú de anotaciones rápidas (ninguna anotación " +"seleccionada)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Restringir la proporción de la forma a 1:1 o el ángulo de la línea a pasos " +"de 15° (ninguna anotación seleccionada)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Preferencias avanzadas para la herramienta de anotación actual (ninguna " +"anotación seleccionada)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Anchura de la línea de la anotación" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Anchura de la línea de la anotación (la anotación actual no tiene anchura de " +"línea)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Color del texto de la anotación" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Color del borde de la anotación" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Color de la anotación" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Color de relleno de la anotación" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Color de relleno de la anotación (la anotación actual no tiene color de " +"relleno)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Tipo de letra de la anotación" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" +"Tipo de letra de la anotación (la anotación actual no tiene tipo de letra)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Restringir el ángulo de la línea a pasos de 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Restringir la proporción de la forma a 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Restringir la proporción de la forma a 1:1 o el ángulo de la línea a pasos " +"de 15° (no permitido por la anotación actual)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacidad de la anotación" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Añadir la anotación actual al menú de anotaciones rápidas" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Preferencias avanzadas para la herramienta de anotación actual" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Color" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Color de relleno" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparente" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Color personalizado..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Los sellos insertados en documentos PDF no son visibles en otros lectores " +"PDF distintos de Okular." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Funcionalidad experimental" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Seleccionar color" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Anotaciones" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Ocultar" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Resaltador" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Subrayado" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Garabato" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Tachado" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Máquina de escribir" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota en línea" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota emergente" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Línea a mano alzada" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Línea recta" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Flecha" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectángulo" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polígono" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Formas geométricas" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Sello" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anotaciones rápidas" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Escoger herramienta de anotación de las anotaciones rápidas" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Añadir anotaciones rápidas" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantener activa" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantener la herramienta de anotación activa tras usarla" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Restringir la proporción y el ángulo de las herramientas de anotación" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Tipo de letra" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Preferencias de la anotación" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Anchura de la línea" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacidad" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Página %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anotación" +msgstr[1] "%1 anotaciones" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "Abrir n&ota emergente" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Borrar" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propiedades" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Guardar «%1»..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Apariencia" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&General" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Creado:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificado:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Propiedades de la nota emergente" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Propiedades de la máquina de escribir" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Propiedades de la nota en línea" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Propiedades de la línea recta" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Propiedades del polígono" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Propiedades de la elipse" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Propiedades del marcador de texto" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Propiedades del sello" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Propiedades de la línea a mano alzada" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Propiedades del cursor" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Propiedades del archivo adjunto" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Propiedades del sonido" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Propiedades de la película" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Propiedades de la anotación" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificado: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Seleccionar un símbolo de sello personalizado de un archivo" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Seleccionar símbolo de sello personalizado" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Archivos de iconos (*.ico *.png *.xpm *.svg " +"*.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "No se ha podido cargar el archivo %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Archivo no válido" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Color:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacidad:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icono:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Comentario" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Ayuda" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Insertar" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Tecla" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nuevo párrafo" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Párrafo" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Tipo de letra:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Color del texto:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Alinear:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Izquierda" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centrar" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Derecha" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Anch&ura del borde:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Aprobado" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Tal cual" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidencial" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Interno" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Borrador" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Para comentar" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Para publicar" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "No aprobado" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Para no publicar" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Vendido" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Alto secreto" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Marcador" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Información" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Funcionalidad experimental.Los sellos insertados en documentos " +"PDF no son visibles en otros lectores PDF distintos de Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Símbolo de sello:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "Anch&ura:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Inicio de la línea:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Extremo de la línea:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Cuadrado" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Círculo" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamante" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Flecha abierta" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Flecha cerrada" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Ninguno" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Tapa" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Flecha abierta hacia la derecha" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Flecha cerrada hacia la derecha" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Longitud de la línea principal:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Longitud de las extensiones de la línea principal:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Activada" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Relleno de la forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipo:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Resaltar" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Garabato" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Subrayado" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Tachado" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectángulo" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Símbolo de archivo adjunto:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Gráfico" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Chincheta" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Clip" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiqueta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Archivo" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "n/d" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Sin descripción disponible." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nombre:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Descripción:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Símbolo de cursor:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ninguno" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Cerrar esta nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opciones" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Esta anotación puede contener código LaTeX.\n" +"Pulse aquí para interpretarlo." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "No se encuentra el ejecutable latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Falló la representación de LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "No se encuentra el ejecutable dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Ha ocurrido un problema durante la ejecución de la orden «latex»." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Ha ocurrido un problema durante la ejecución de la orden «dvipng»." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Un marcador" +msgstr[1] "" +"%1\n" +"\n" +"%2 marcadores" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Marcadores" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Buscar..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Solo el documento actual" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Ir a este marcador" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Cambiar nombre del marcador" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Borrar marcador" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Abrir documento" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Eliminar marcadores" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versión" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Número de serie" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emisor" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emitido el" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Expira el" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Asunto" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Clave pública" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Uso de la clave" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propiedad" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valor" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Visor de certificados" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exportar..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "General" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emitido por" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nombre común (NC)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Correo electrónico" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organización (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emitido para" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validez" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Huellas digitales" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Huella digital SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Huella digital SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detalles" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Fecha del certificado:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "¿Dónde quiere guardar este certificado?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Archivo de certificado (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "No se ha podido exportar el certificado" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rojo" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verde" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Azul" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Amarillo" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Negro" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Blanco" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Dibujar borde alrededor de las &imágenes" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Dibujar borde alrededor de los en&laces" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Cambiar &colores" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Atención: estas opciones pueden afectar gravemente a la velocidad de dibujo." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Modo de color:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Invertir colores" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Cambiar el color del fondo" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Cambiar colores oscuros y claros" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Convertir a blanco y negro" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Invertir luminosidad" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Invertir luma (sRGB lineal)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Invertir luma (simétrica)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Desplazar a tonalidad positiva" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Desplazar a tonalidad negativa" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Color del fondo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Color oscuro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Color claro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Umbral:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contraste:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Habla" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identidad" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota:: esta información solo se usa en anotaciones. La información se " +"guarda en documentos anotados, por lo que se transmitirá junto al documento." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Herramientas de anotaciones rápidas" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor de texto personalizado" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Cliente Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Cliente Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Establece la orden para lanzar un editor de texto personalizado.
\n" +"
También puede usar algunos parámetros de sustitución:\n" +"

    \n" +"

  • %f - el nombre del archivo
  • \n" +"

  • %l - la línea del archivo a alcanzar
  • \n" +"

  • %c - la columna del archivo a alcanzar
  • \n" +"

\n" +"
Si no se especifica %f, se añade el nombre del archivo a la orden." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Elija el editor que quiere lanzar cuando Okular necesite abrir un archivo de " +"código fuente." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Orden:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Apariencia" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Usar desplazamiento suave" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Mostrar &barras de desplazamiento" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Enla&zar las miniaturas con la página" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Mostrar &mensajes de ayuda y de información" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "" +"Mostrar el título del documento en la barra de título, si está disponible" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Cuándo no mostrar el título del documento:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Mostrar solo el nombre del archivo" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Mostrar la ruta completa del archivo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usar color de fondo personalizado" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Características del programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Abrir nuevos archivos en pes&tañas" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Cambiar a una pestaña existente si el archivo ya está abierto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obedecer las restricciones DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Volver a cargar el documento si cambia el archivo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Mostrar el diálogo de selección de motor" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Dirección de lectura de derecha a izquierda" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opciones de visualización" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Columnas del resumen:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Define qué porción del área de visión actual continuará siendo visible al " +"pulsar las teclas RePág y AvPág." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Solapamiento Re&Pág/AvPág:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Define el modo de ampliación por omisión para los archivos que no ha abierto " +"antes.\n" +"Para los archivos que ya se han abierto alguna vez se aplica la ampliación " +"usada con anterioridad." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Define el modo de ampliación por omisión para los archivos que no ha abierto " +"antes.\n" +"Para los archivos que ya se han abierto alguna vez se aplica la ampliación " +"usada con anterioridad." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "A&mpliación por omisión:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100 %" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Ajustar al ancho" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Ajustar a la página" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Ajuste automático" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Mantener la memoria usada tan bajo como sea posible. No reutilizar nada. " +"(Para sistemas con poca memoria)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Una buena relación entre uso de memoria y ganancia de velocidad. Precargar " +"la página siguiente y agilizar las búsquedas. (Para sistemas con 2 GB de " +"memoria, normalmente)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Mantener todo en memoria. Precargar las páginas siguientes. Agilizar las " +"búsquedas. (Para sistemas con más de 4 GB de memoria)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carga y mantiene todo en memoria. Precarga todas las páginas (usará como " +"máximo el 50% de la memoria total o de la memoria libre, la que sea mayor)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Uso de CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Activar efectos de &transparencia" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Uso de memoria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Bajo" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (predeterminado)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Agr&esivo" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "Vo&raz" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Representación" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Activar suavizado de bordes en el texto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Activar suavizado de bordes en los gráficos" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Activar sugerencias del tipo de letra" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Pantalla actual" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Pantalla predeterminada" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " segundo" +msgstr[1] " segundos" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navegación" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avanzar cada:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Volver a comenzar tras la última página" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navegación táctil:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Toque la parte izquierda/derecha para ir atrás/adelante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Toque en cualquier lugar para ir adelante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Desactivada" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Color del fondo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Puntero del ratón:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Ocultar tras un intervalo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Siempre visible" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Siempre oculto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Mostrar indicador de &progreso" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Mostrar página de s&umario" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Activar transiciones" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transición predeterminada:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Cortina vertical" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Cortina horizontal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Cuadro hacia dentro" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Cuadro hacia fuera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Disolver" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Desvanecer" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Destellos con barrido hacia abajo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Destellos con barrido hacia la derecha" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Destellos con barrido abajo a la derecha" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transición aleatoria" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Sustituir" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "División horizontal hacia dentro" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "División horizontal hacia fuera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "División vertical hacia dentro" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "División vertical hacia fuera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Barrido hacia abajo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Barrido hacia la derecha" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Barrido hacia la izquierda" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Barrido hacia arriba" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Posición" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Pantalla:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuración de la herramienta de dibujo" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Herramienta de dibujo: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Goma de borrar" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nombre:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipo:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota emergente" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota en línea" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Línea a mano alzada" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Línea recta" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polígono" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Marcador de texto" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geométrica" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Sello" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Máquina de escribir" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Herramienta para crear anotación" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Herramienta para editar la anotación" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Color:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Anchura del lá&piz:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Herramienta para crear dibujo" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Herramienta para editar dibujo" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Desconocida" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Archivos empotrados" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Ver" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nombre" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Descripción" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Tamaño" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Creado" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificado" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "G&uardar como..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Ver..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "No se puede cargar la parte de previsualización de impresión" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Vista previa de la impresión" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Cerrar" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Encontrar:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Texto a buscar" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Siguiente" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Ir a la siguiente coincidencia" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Anterior" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Ir a la anterior coincidencia" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modificar el comportamiento de la búsqueda" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Distinguir mayúsculas" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Desde la página actual" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Buscar al escribir" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Todos los archivos" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Propiedades de la firma" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Línea recta con comentario" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polígono con comentario" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Elipse con comentario" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Elipse" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Texto resaltado con comentario" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Texto garabateado con comentario" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Subrayado con comentario" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Texto tachado con comentario" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Tachado" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Sello con comentario" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Línea a mano alzada con comentario" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Cursor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Archivo adjunto" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Sonido" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Película" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Pantalla" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Elemento gráfico" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Medio enriquecido" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Desconocido" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "¿Dónde quiere guardar %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "No se puede abrir «%1» para escritura. El archivo no ha sido guardado." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opciones de búsqueda" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Distinguir mayúsculas" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expresión regular" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Buscar:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Capas" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "de" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Ampliación" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Ampliar al 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Gi&rar a la derecha" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Derecha" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Girar a la i&zquierda" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Izquierda" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientación original" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Recor&tar vista" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Recor&tar márgenes" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Recortar a la &selección" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Ajustar al &ancho" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Ajustar a la &página" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Ajuste automático" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Ajustar ve&ntana a la página" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Modo de &vista" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "&Página única" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Páginas &encaradas" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Páginas encaradas (¢rar la primera página)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Resumen" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continuo" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Usar dirección de lectura de derecha a izquierda" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Explorar" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "A&mpliar" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Conmu&tar cambiar colores" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selección de área" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selección de &texto" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selección de t&abla" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lupa" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Herramientas de selección" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Leer todo el documento" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Leer la página actual" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Detener lectura" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Pausar/continuar la lectura" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Desplazar arriba" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Desplazar abajo" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Desplazar página arriba" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Desplazar página abajo" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Mostrar formularios" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Se ha cargado un documento de una página." +msgstr[1] " Se ha cargado un documento de %1 páginas." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Texto (1 carácter)" +msgstr[1] "Texto (%1 caracteres)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copiar en el portapapeles" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Copia prohibida por DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Hablar texto" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Imagen (%1x%2 píxeles)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Guardar en archivo..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Imagen [%1x%2] copiada en el portapapeles." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Guardar archivo" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Imágenes (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Archivo no guardado." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Imagen [%1x%2] guardada en el archivo %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copiar texto" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Ir a «%1»" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Buscar «%1» con" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configurar los accesos rápidos Web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Seguir este enlace" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Reproducir este sonido" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Detener sonido" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copiar dirección del enlace" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Buscar «%1» en este documento" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Bienvenido" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Seleccione la zona de ampliación. Clic derecho para reducir." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Pulse para usar la lupa." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dibuje un rectángulo alrededor del texto o gráficos a copiar." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Seleccionar texto" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Dibuje un rectángulo alrededor de la tabla y pulse cerca de sus bordes para " +"dividirlo. Pulse Esc para borrarlo." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Dibuje un rectángulo alrededor del área de la página que desea mantener " +"visible" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nueva nota de texto" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Texto de la nueva nota:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Marcar la anotación" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Insertar un nombre personalizado para la anotación:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Dibujar una elipse (arrastre para seleccionar una zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Resaltar texto" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Dibujar una línea a mano alzada" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Anotación de texto en línea (arrastre para seleccionar una zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Colocar una nota emergente" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Dibujar un polígono (haga clic en el primer punto para cerrarlo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Dibujar un rectángulo" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Texto garabateado" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Poner un símbolo de sello" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Dibujar una línea recta" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Tachar texto" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Subrayar texto" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Anotación con máquina de escribir (arrastre para seleccionar una zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Resaltador" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Añadir anotación favorita" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nombre de anotación personalizado:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Archivo" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Preferencias" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "A&yuda" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientación" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Marcadores" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra de herramientas del visor" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniaturas" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anotaciones" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Este documento contiene anotaciones o datos de formulario que fueron " +"guardados internamente por una versión anterior de Okular. El almacenamiento " +"interno ya no se permite.
Por favor, guarde en un archivo para " +"poder moverlos si desea seguir editando el documento." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Este documento contiene archivos empotrados. Pulse aquí para verlos o vaya a «Archivo -> Archivos empotrados»." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Anterior" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Ir a la página anterior" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Va a la anterior página del documento" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Siguiente" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avanzar a la página siguiente" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Va a la siguiente página del documento" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Principio del documento" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Va al principio del documento" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Final del documento" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Va al final del documento" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Cambiar el nombre del marcador actual" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Marcador anterior" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Ir al marcador anterior" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Marcador siguiente" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Ir al marcador siguiente" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configurar Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configurar visor..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configurar los motores del visor..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configurar motores..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Acerca del motor" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Volver a cargar" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Volver a cargar el documento actual del disco." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Cerrar la barra de &búsqueda" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Número de página" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Seleccionar todo el texto de la página actual" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Mostrar la barra &lateral" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Mostrar la barra de &páginas" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Mostrar el panel de &firmas" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Archivos &empotrados" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xportar como" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Co&mpartir" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentación" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Abrir la carpeta con&tenedora" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importar PostScript como PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obtener libros de Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Cambiar al modo de pantalla negra" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Borrar dibujo" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configurar anotaciones..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reproducir/pausar presentación" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "No se ha podido abrir «%1» (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "La carga de %1 ha sido cancelada." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "No se puede abrir %1. Motivo: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configurar los motores del visor" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configurar motores" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"El programa «ps2pdf» no ha sido encontrado, de modo que Okular no puede " +"importar archivos PS usando este programa." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "No se ha encontrado el programa «ps2pdf»" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Archivos PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importando archivo PS como PDF (esto tardará un rato)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Por favor, introduzca la contraseña para leer el documento:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Contraseña incorrecta. Pruebe de nuevo:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Contraseña del documento" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Este documento contiene formularios XFA, que en la actualidad no están " +"permitidos." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Este documento contiene formularios. Pulse el botón para interactuar con " +"ellos, o use Ver -> Mostrar formularios." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Se han desactivado todas las funciones de edición y de interacción para este " +"documento. Guarde una copia y vuelva a abrirlo para poder editarlo." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Este documento está firmado digitalmente." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Este documento está firmado digitalmente. Se han producido cambios desde la " +"última firma." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Este documento está firmado digitalmente. Algunas de las firmas no se pueden " +"validar correctamente." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Este documento solicita mostrarse a pantalla completa.\n" +"¿Desea dejar el modo normal y entrar en el modo de presentación?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Solicitud de cambio del modo de visualización" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Entrar en el modo de presentación" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Denegar la solicitud" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "No se puede abrir %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Existen cambios sin guardar y el archivo «%1» ha sido modificado por otro " +"programa. Perderá los cambios porque ya no se puede guardar el archivo." +"
¿Desea continuar recargando el archivo?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Archivo modificado" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continuar recargando" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interrumpir la recarga" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Existen cambios sin guardar y el archivo «%1» ha sido modificado por otro " +"programa. Perderá los cambios porque ya no se puede guardar el archivo." +"
¿Desea continuar cerrando el archivo?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continuar cerrando" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Interrumpir el cierre" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "¿Desea guardar los cambios en «%1» o descartarlos?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Cerrar documento" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Este enlace apunta a una acción de cierre del documento que no funciona al " +"usar el visor empotrado." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Este enlace apunta a una acción de salida de la aplicación que no funciona " +"al usar el visor empotrado." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Volviendo a cargar el documento..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contenido" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Firmas" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Ir a la página" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Página:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Introduzca el nuevo nombre del marcador:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Cambiar el nombre de este marcador" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Eliminar este marcador" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Guardar como" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"El archivo «%1» ha sido modificado por otro programa, lo que significa que " +"ya no se puede guardar." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"El documento actual está protegido con contraseña.
Para poder " +"guardarlo, necesita volver a cargar el archivo. Se le volverá a solicitar la " +"contraseña y se perderá el historial de deshacer/rehacer.
¿Desea " +"continuar?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Guardar - Advertencia" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "No se puede abrir el archivo temporal para escritura." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Tras guardar, el formato del documento actual necesita que se vuelva a " +"cargar el archivo. El historial de deshacer/rehacer se perderá.
¿Desea " +"continuar?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"El archivo no se puede guardar en «%1». Intente guardarlo en otro lugar." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contenido del formulario relleno" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Anotaciones del usuario" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Está a punto de guardar los cambios, pero el formato de archivo actual no " +"permite guardar los siguientes elementos. Por favor, use el formato de " +"archivo comprimido de documento de Okular para preservarlos." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Advertencia" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Guardar como archivo comprimido de documento de Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Está a punto de guardar los cambios, pero el formato de archivo actual no " +"permite guardar los siguientes elementos. Por favor, use el formato de " +"archivo comprimido de documento de Okular para preservarlos. Pulse " +"Continuar para guardar el documento y descartar estos elementos." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Está a punto de guardar los cambios, pero el formato de archivo actual no " +"permite guardar los siguientes elementos. Por favor, use el formato de " +"archivo comprimido de documento de Okular para preservarlos. Pulse " +"Continuar para guardar, aunque perderá estos elementos y el historial " +"de deshacer/rehacer." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continuar" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continuar, perdiendo los cambios" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "No se puede guardar el archivo en «%1». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular no puede copiar %1 en la ubicación especificada.\n" +"\n" +"El documento ha dejado de existir." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"El archivo no se puede guardar en «%1». Error: «%2». Intente guardarlo en " +"otro lugar." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expandir toda la sección" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Contraer toda la sección" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expandir todo" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Contraer todo" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Añadir marcador" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Herramientas" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Imprimir" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "No se permite la impresión de este documento." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"No se puede imprimir el documento. Error desconocido. Informe del fallo a " +"bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"No se puede imprimir el documento. El error detallado es «%1». Informe del " +"fallo a bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Ir al sitio donde ha estado antes" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Ir al sitio donde ha estado después" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Error de archivo No se puede crear el archivo temporal " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Error de archivo No se puede abrir el archivo " +"%1 para descomprimirlo. El archivo no será " +"cargado." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Este error aparece típicamente cuando no tiene suficientes permisos para " +"leer el archivo. Puede comprobar su propiedad y sus permisos haciendo clic " +"sobre el archivo con el botón derecho del ratón en el gestor de archivos " +"Dolphin, escogiendo luego la opción «Propiedades» y seleccionando la pestaña " +"«Permisos» en la ventana que se abre." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Error de archivo No se puede descomprimir el archivo " +"%1. El archivo no será cargado." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Este error aparece típicamente cuando el archivo está dañado. Si quiere " +"asegurarse, intente descomprimir el archivo manualmente usando herramientas " +"en la línea de órdenes." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "No hay marcadores" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Ha ocurrido un problema al compartir el documento: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Compartir" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Documento compartido con éxito" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Puede encontrar el documento compartido en: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Editar" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Ver" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Ir" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Herramientas" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra de herramientas principal" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barra de herramientas de anotaciones" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opciones generales" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accesibilidad" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Ayudas de accesibilidad para lectura" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Rendimiento" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Ajuste del rendimiento" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configurar el visor" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentación" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opciones para el modo de presentación" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Opciones de las anotaciones" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opciones del editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Encontrar siguiente" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentación" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Cambiar pantalla" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Salir del modo de presentación" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Título: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Páginas: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Pulse para comenzar" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pausar" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reproducir" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Existen dos formas de salir del modo de presentación: puede pulsar la tecla " +"«Esc» o pulsar el botón para salir que aparece al situar el puntero del " +"ratón en la esquina superior derecha. En todo momento puede navegar a través " +"de las ventanas abiertas (Alt+Tab de forma predeterminada)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Terminar una presentación" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Archivo desconocido" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Propiedades de %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Tipos de letra" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Leyendo información sobre los tipos de letra..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Tamaños de las &páginas" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extraer tipo de letra" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipo 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipo 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tipo 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipo 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tipo 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tipo 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tipo 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Desconocido" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Empotrado (subconjunto)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Completamente empotrado" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Sí (subconjunto)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (sustituido con %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Tipo de letra desconocido" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Empotrado: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nombre" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipo" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Archivo" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Página" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Tamaño" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Vista previa de la revisión" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "¿Dónde quiere guardar esta revisión?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "No se ha podido guardar el archivo %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "No se puede ver la revisión." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Introduzca al menos 3 letras para filtrar páginas" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Distinguir mayúsculas" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Encontrar la frase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Encontrar todas las palabras" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Encontrar cualquier palabra" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opciones del filtro" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

No hay anotaciones

Pulse «F6» para crear nuevas " +"anotaciones o seleccione Herramientas -> Anotaciones en el menú." + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Agrupar por página" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Agrupar por autor" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Mostrar solo anotaciones de la página actual" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Expandir todos los elementos" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Contraer todos los elementos" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "La firma es criptográficamente válida." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "La firma es criptográficamente no válida." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Ha ocurrido una discordancia del compendio." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "La estructura de la firma CMS/PKCS7 no está bien formada." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "La firma solicitada no está presente en el documento." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "No se puede verificar la firma." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "El certificado es de confianza." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "El emisor del certificado no es de confianza." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "El emisor del certificado es desconocido." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "El certificado ha sido revocado." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "El certificado ha expirado." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Todavía no se ha verificado el certificado." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" +"Ha ocurrido un problema desconocido con el certificado o los datos están " +"dañados." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algoritmo desconocido" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipo desconocido" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Firma digital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "No rechazado" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Claves de cifrado" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Claves de descifrado" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Convenio de la clave" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Certificado de la firma" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL de la firma" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Solo cifrar" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Sin uso especificado" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Firmado por %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Hora de la firma: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "No disponible" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Motivo: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Campo: %1 en la página %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propiedades" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "El documento no se ha modificado desde que fue firmado." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"La revisión del documento que cubre esta firma no ha sido modificada;\n" +"no obstante, existen cambios posteriores en el documento." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"El documento ha sido modificado de un modo no permitido por el anterior " +"firmante." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "No se puede completar la verificación de integridad del documento." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Estado de validez" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validez de la firma:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modificaciones del documento:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Información adicional" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Firmado por:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Hora de la firma:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Motivo:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Localización:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versión del documento" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisión del documento %1 de %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Ver la versión firmada..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Ver el certificado..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Mostrar solo las páginas marcadas" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reproducir" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pausar" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Detener" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Añadir..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Editar..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "E&liminar" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "S&ubir" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "&Bajar" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Herramienta de dibujo #%1 por omisión" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Ya existe una herramienta con este nombre. Se usa uno por omisión." + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nombre duplicado" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Página del documento a mostrar" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Iniciar el documento en modo de presentación" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Iniciar con el diálogo de impresión" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Iniciar con el diálogo de impresión y salir tras imprimir" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Control de «sesión única»" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "No pasar la ventana a primer plano" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Buscar una cadena en el texto" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Documentos a abrir. Use «-» para leer de la entrada estándar." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Error: no se puede abrir más de un documento con el modificador --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: no se puede abrir más de un documento con el modificador --" +"presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Error: no se puede abrir más de un documento con el modificador --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Error: no se puede abrir más de un documento con el modificador --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Error: no se puede abrir más de un documento con el modificador --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "No se ha podido encontrar el componente Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Ya hay una única instancia de Okular en ejecución. Esta instancia no será la " +"única." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "No se ha podido encontrar el componente Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Pulse para abrir un archivo\n" +"Pulse y mantenga pulsado para abrir un archivo reciente" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Pulse para abrir un archivo, o pulse y mantenga para " +"seleccionar un archivo reciente" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Pestaña siguiente" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Pestaña anterior" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Deshacer el cierre de pestaña" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Todos los archivos (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Todos los archivos permitidos (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Abrir documento" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirmar el cierre" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Cerrar pestañas" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Está a punto de cerrar %1 pestañas. ¿Seguro que desea continuar?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Avisarme cuando intente cerrar múltiples pestañas" + +#~ msgid "Reviews" +#~ msgstr "Revisiones" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Ocultar formularios" + +#~ msgid "Expired" +#~ msgstr "Expirado" + +#~ msgid "&Review" +#~ msgstr "&Revisión" + +#~ msgid "Annotations author" +#~ msgstr "Autor de las anotaciones" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Introduzca su nombre o iniciales:" + +#~ msgctxt "Used in this context: 'Page sizes: Multiple'" +#~ msgid "Multiple" +#~ msgstr "Múltiple" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Mostrar el panel de &navegación" + +#~ msgid "Show Text" +#~ msgstr "Mostrar texto" + +#~ msgid "Small Icons" +#~ msgstr "Iconos pequeños" + +#~ msgid "Normal Icons" +#~ msgstr "Iconos normales" + +#~ msgid "Large Icons" +#~ msgstr "Iconos grandes" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Clic para usar la herramienta de selección actual\n" +#~ "Clic sobre la flecha para escoger otra herramienta de selección" + +#~ msgid "Created: %1" +#~ msgstr "Creado: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Extensiones de línea" + +#~ msgid "Style" +#~ msgstr "Estilo" + +#~ msgid "&Size:" +#~ msgstr "&Tamaño:" + +#~ msgid "Inner color:" +#~ msgstr "Color interno:" + +#~ msgid "Name: %1" +#~ msgstr "Nombre: %1" + +#~ msgid "Size: %1" +#~ msgstr "Tamaño: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Herramienta de &navegación" + +#~ msgid "&Zoom Tool" +#~ msgstr "Herramienta de &liación" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Ampliar" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Selección" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Herramienta de selección de &texto" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Herr&amienta de selección de tablas" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Lupa" + +#~ msgid "Only for PDF documents" +#~ msgstr "Solo para documentos PDF" + +#~| msgid "None" +#~ msgid " None" +#~ msgstr " Ninguno" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "El documento ha solicitado ser lanzado en modo de presentación.\n" +#~ "¿Desea permitirlo?" + +#~ msgid "Presentation Mode" +#~ msgstr "Modo de presentación" + +#~ msgid "Allow" +#~ msgstr "Permitir" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Permitir el modo de presentación" + +#~ msgid "Do Not Allow" +#~ msgstr "No permitir" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "No permitir el modo de presentación" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Los cambios en las notas no se guardarán automáticamente. Utilice " +#~ "«Archivo -> Guardar como...»\n" +#~ "o los cambios se perderán cuando cierre el documento" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Okular guarda internamente sus anotaciones.\n" +#~ "Puede exportar el documento con notas usando «Archivo -> Exportar como -> " +#~ "Archivo comprimido de documento»" + +#~ msgid "Save &Copy As..." +#~ msgstr "Guardar &copia como..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Las anotaciones no se exportarán.\n" +#~ "Puede exportar el documento con notas usando «Archivo -> Exportar como -> " +#~ "Archivo comprimido de documento»" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Se ha alcanzado el final del documento.\n" +#~ "¿Continuar desde el principio?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Se ha alcanzado el principio del documento.\n" +#~ "¿Continuar desde el final?" + +#~ msgid "Current maintainer" +#~ msgstr "Encargado actual" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " seg." + +#~ msgid "Pencil color:" +#~ msgstr "Color del lápiz:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "DIN/ISO A0 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "DIN/ISO A0 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "DIN/ISO A1 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "DIN/ISO A1 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "DIN/ISO A2 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "DIN/ISO A2 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "DIN/ISO A3 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "DIN/ISO A3 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "DIN/ISO A4 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "DIN/ISO A4 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "DIN/ISO A5 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "DIN/ISO A5 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "DIN/ISO A6 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "DIN/ISO A6 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "DIN/ISO A7 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "DIN/ISO A7 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "DIN/ISO A8 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "DIN/ISO A8 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "DIN/ISO A9 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "DIN/ISO A9 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "DIN/ISO B0 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "DIN/ISO B0 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "DIN/ISO B1 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "DIN/ISO B1 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "DIN/ISO B2 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "DIN/ISO B2 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "DIN/ISO B3 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "DIN/ISO B3 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "DIN/ISO B4 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "DIN/ISO B4 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "DIN/ISO B5 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "DIN/ISO B5 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "DIN/ISO B6 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "DIN/ISO B6 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "DIN/ISO B7 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "DIN/ISO B7 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "DIN/ISO B8 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "DIN/ISO B8 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "DIN/ISO B9 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "DIN/ISO B9 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "DIN/ISO B10 apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "DIN/ISO B10 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "letter apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "letter vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "legal apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "legal vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "executive apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "executive vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "Comm10E apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "Comm10E vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "DLE apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "DLE vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "folio apaisado" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "folio vertical" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "tamaño de papel desconocido apaisado" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "tamaño de papel desconocido vertical" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Cambiar modo de dibujo" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "El inicio del lector de texto Jovie ha fallado: %1" + +#~ msgid "Search Columns" +#~ msgstr "Buscar columnas" + +#~ msgid "All Visible Columns" +#~ msgstr "Todas las columnas visibles" + +#~ msgid "No document opened." +#~ msgstr "Ningún documento abierto." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "No se puede abrir más de un documento en la única instancia de Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "No se han encontrado coincidencias para «%1»." + +#~ msgid "Search in progress..." +#~ msgstr "Búsqueda en progreso..." + +#~ msgid "Searching for %1" +#~ msgstr "Buscando %1" diff --git a/po/es/okular_chm.po b/po/es/okular_chm.po new file mode 100644 index 0000000..028db0a --- /dev/null +++ b/po/es/okular_chm.po @@ -0,0 +1,62 @@ +# translation of okular_chm.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-02-23 00:50+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.12.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codificación no permitida" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"La codificación de este libro electrónico todavía no está permitida. Abra un " +"informe de error en https://bugs.kde.org para que se añada." + +#~ msgid "CHM Backend" +#~ msgstr "Motor CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Un visualizador de archivos de ayuda de Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/es/okular_comicbook.po b/po/es/okular_comicbook.po new file mode 100644 index 0000000..d44ac95 --- /dev/null +++ b/po/es/okular_comicbook.po @@ -0,0 +1,60 @@ +# translation of okular_comicbook.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2008, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-13 22:26+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"No se puede abrir el documento: no se han encontrado «unrar» ni «unarchiver»." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"La versión de «unrar» instalada en su sistema no es apropiada para abrir " +"libros de cómics." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Formato ComicBook desconocido." + +#~ msgid "ComicBook Backend" +#~ msgstr "Motor ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un visualizador de varios formatos de libros de cómics" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/es/okular_djvu.po b/po/es/okular_djvu.po new file mode 100644 index 0000000..58e2fad --- /dev/null +++ b/po/es/okular_djvu.po @@ -0,0 +1,136 @@ +# translation of okular_djvu.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-09-02 16:34+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Editor" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volumen" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipo de documento" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Desconocido" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Archivos componentes" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Desconocido" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Página única" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Empaquetado" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirecto" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Empaquetado (antiguo)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexado (antiguo)" + +#~ msgid "DjVu Backend" +#~ msgstr "Motor DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Motor DjVu basado en DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Desconocido" diff --git a/po/es/okular_dvi.po b/po/es/okular_dvi.po new file mode 100644 index 0000000..9d5671f --- /dev/null +++ b/po/es/okular_dvi.po @@ -0,0 +1,755 @@ +# translation of okular_dvi.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2009, 2013, 2014. +# Javier Viñal , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-05-16 12:17+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular no puede localizar el programa dvipdfm en su equipo. " +"Este programa es esencial para que funcione la función de exportar. No " +"obstante, puede convertir el archivo DVI a PDF usando la función de " +"impresión de Okular, aunque esto suele generar documentos que se imprimen " +"correctamente, serán de inferior calidad si se visualizan con Acrobat " +"Reader. Sería recomendable que se actualizara a una versión más reciente del " +"paquete TeX, que incluye el programa dvipdfm.

Consejo para el " +"administrador del sistema sorprendido: Okular usa la variable de entorno " +"PATH para buscar programas.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa externo «dvipdfm» que se ha usado para exportar el archivo " +"ha informado de un error. Tal vez quiera comprobarlo en el diálogo " +"de información del documento (que encontrará en el menú Archivo), " +"donde encontrará un informe más preciso sobre este error." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Este archivo DVI hace referencia a archivos gráficos externos que no " +"están en formato PostScript y que no pueden ser manejados por el programa " +"dvips que usa Okular internamente para imprimir o exportar a " +"PostScript. Por lo tanto, la funcionalidad que ha solicitado no está " +"disponible en esta versión de Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular no puede localizar el programa dvips en su equipo. " +"Este programa es esencial para que funcione la función de exportar.

Consejo para el administrador del sistema sorprendido: Okular usa la " +"variable de entorno PATH para buscar programas.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"El programa externo «dvips» que se ha usado para exportar el archivo ha " +"informado de un error. Tal vez quiera comprobarlo en el diálogo de " +"información del documento (que encontrará en el menú Archivo), " +"donde encontrará un informe más preciso sobre este error." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "El archivo DVI no comienza con el preámbulo." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"El archivo DVI contiene una versión equivocada de salida DVI para este " +"programa. Consejo: Si usa el sistema Omega, debería usar un programa " +"especial, como «oxdvi»." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"El archivo DVI está severamente dañado. Okular no ha sido capaz de encontrar " +"el postámbulo." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "El postámbulo no comienza con la orden POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "El postámbulo contiene una orden distinta de FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La página %1 no comienza con la orden BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

No se ha sido posible iniciar el programa externo pdf2ps. Como consecuencia, el archivo PDF %1 no se ha podido convertir a " +"PostScript, por lo que no se mostrarán algunos elementos gráficos del " +"documento.

Posible motivo: Tal vez el programa pdf2ps no esté instalado en su equipo, o no se puede encontrar en su ruta " +"de búsqueda actual.

¿Qué puede hacer?: Normalmente, el programa " +"pdf2ps está contenido en las distribuciones del sistema " +"intérprete de PostScript «ghostscript». Si ghostscript no está instalado en " +"su equipo, puede instalarlo ahora. Si está seguro de que ghostscript está " +"instalado, pruebe a usar pdf2ps desde la línea de órdenes " +"para comprobar que realmente funciona.

Ruta: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

El archivo PDF %1 no se ha podido convertir a PostScript, por lo que " +"algunos elementos gráficos de su documento no serán mostrados.

Posible motivo: Es probable que el archivo %1 esté dañado, o tal " +"vez no sea un archivo PDF. Esta es la salida del programa pdf2ps que ha usado Okular:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Archivo dañado. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"No todos los archivos PostScript se han podido incrustar en el documento. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"Todos los archivos PostScript externos se han incrustado en el documento." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "El archivo «%1» indicado no existe." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Le ha pedido a Okular que localice el lugar del archivo DVI que corresponde " +"a la línea %1 del archivo TeX %2. No obstante, parece que archivo DVI no " +"contiene la información de archivo de origen necesaria. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular no ha podido localizar el lugar del archivo DVI que corresponde a la " +"línea %1 del archivo TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "El código DVI establece un carácter de un tipo de letra desconocido." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"El código DVI hace referencia al tipo de letra #%1, que no ha sido definida " +"previamente." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "La pila no estaba vacía cuando se ha encontrado la orden EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "La pila estaba vacía cuando se ha encontrado una orden POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"El código DVI referencia un tipo de letra que no ha sido definido " +"previamente." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Se ha encontrado una orden ilegal." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Se ha encontrado el código de operación desconocido %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Empotrando %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Página %1: el archivo PDF %2 no puede ser convertido a " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Página %1: no se puede encontrar el archivo PostScript %2." +"
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "No se puede analizar el dato «%1» del tamaño del papel." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular no ha sido capaz de localizar todos los archivos de tipos de " +"letra necesarios para mostrar el archivo DVI actual. Es posible que el " +"documento no sea legible.

Ruta: %1

" +"%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Ha ocurrido algún problema al ejecutar kpsewhich. Por ello, " +"no ha sido posible localizar algunos archivos de tipos de letra, por lo que " +"el documento puede resultar ilegible.
Posible motivo: es posible que el " +"programa kpsewhich no esté instalado en su sistema, o que no se " +"pueda encontrar en la ruta de búsqueda actual.

Ruta: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"La generación del tipo de letra por kpsewhich ha sido " +"interrumpida (código de salida %1, error %2). Como resultado, algunos " +"archivos de tipos de letras no se pueden localizar, por lo que su documento " +"puede ser ilegible." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Generando ahora %1 a %2 ppp..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generador/fecha" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Archivo de tipo de letra no encontrado" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "retrato" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "paisaje" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La versión de Ghostview que hay instalada en este equipo no contiene ninguno " +"de los controladores de dispositivo Ghostview que son conocidos por Okular. " +"Por lo tanto, la implementación de PostScript ha sido desactivada en Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

El programa Ghostview (que Okular usa internamente para mostrar los " +"gráficos PostScript incluidos en este archivo DVI) es, por lo general, capaz " +"de escribir su salida en diversos formatos. Los subprogramas que Ghostview " +"usa para estas tareas se denominan «controladores de dispositivos». Existe " +"un controlador de dispositivo para cada formato que Ghostview es capaz de " +"escribir. Distintas versiones de Ghostview tienen a menudo diferentes juegos " +"de controladores de dispositivos. Parece que la versión de Ghostview que " +"está instalada en su equipo no contiene ninguno de los " +"controladores de dispositivo que son conocidos por Okular.

No es " +"probable que una instalación normal de Ghostview no contenga estos " +"controladores. Por lo tanto, este error puede apuntar a una severa " +"desconfiguración de su instalación de Ghostview.

Si desea solucionar " +"los problemas relacionados con Ghostview, puede usar la orden gs --" +"help para mostrar la lista de controladores de dispositivo que " +"contiene Ghostview. Entre otros, Okular puede usar los controladores " +"«png256», «jpeg» y «pnm». Tenga en cuenta que será necesario reiniciar " +"Okular para reactivar el soporte de PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Ha alcanzado 25 errores. No se mostrarán más mensajes de error." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Error en el archivo DVI «%1», página %2. Se ha encontrado una orden de color " +"POP cuando la pila de color estaba vacía." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Parámetro mal formado en la orden especial «epsf».\n" +"Se esperaba un número en coma flotante tras %1 en %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Archivo no encontrado: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Error en el archivo DVI «%1», página %2. No se puede interpretar el ángulo " +"en la orden especial de rotación de texto." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "La orden especial «%1» no está implementada." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"El archivo de tipo de letra %1 se puede abrir y leer, pero su formato de " +"tipo de letra no está implementado." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"El archivo de tipo de letra %1 es defectuoso, o no se puede abrir o leer." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType ha notificado un error al establecer el tamaño de carácter para el " +"archivo de tipo de letra %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType no puede cargar el glifo #%1 del archivo de tipo de letra %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"FreeType no puede generar la imagen del glifo #%1 del archivo de tipo de " +"letra %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "El glifo #%1 está vacío." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "El glifo #%1 del archivo de tipo de letra %2 está vacío." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType no puede cargar la métrica para el glifo #%1 del archivo de tipo de " +"letra %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "No se puede abrir el archivo de tipo de letra %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Carácter %1 no definido en el tipo de letra %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 no esperado en el archivo PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "El carácter %1 es demasiado grande en el archivo %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Número incorrecto de bits almacenados: carácter %1, tipo de letra %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Archivo PK incorrecto (%1): demasiados bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "El tipo de letra no tiene una proporción de aspecto cuadrado " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "No se puede encontrar el tipo de letra %1, archivo %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "" +"La suma de verificación no concuerda para el archivo de tipo de letra %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "No se puede reconocer el formato del archivo de tipo de letra %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Error fatal.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Es probable que esto indique que ha encontrado un fallo en Okular, o\n" +"que el archivo DVI (o algún archivo auxiliar, como los archivos de tipo de\n" +"letra, o los archivos virtuales de tipo de letra) está severamente dañado.\n" +"Okular se cerrará tras mostrar este mensaje. Si cree que ha encontrado\n" +"un fallo, o piensa que Okular debería comportarse mejor en esta situación,\n" +"por favor, informe del problema." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Byte de orden incorrecto encontrado en la lista de macros VF: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Motor DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Un visualizador de archivos DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular confía en el programa kpsewhich para localizar archivos " +#~ "de tipos de letra en su disco duro y para generar tipos de letra PK, si " +#~ "es necesario.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular está generando actualmente tipos de letra de mapa de bits..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Interrumpe la generación de tipos de letra. No haga esto." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular está generando actualmente tipos de letra de mapas de bits que son " +#~ "necesarios para mostrar el documento. Para ello, Okular usa cierto número " +#~ "de programas externos, como MetaFont. Más adelante podrá encontrar la " +#~ "salida producida por estos programas en el diálogo de información del " +#~ "documento." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular está generando tipos de letra. Espere un momento." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Diálogo de progreso de la generación de tipo de letra" + +#~ msgid "Abort" +#~ msgstr "Interrumpir" + +#~ msgid "What is happening here?" +#~ msgstr "¿Qué está ocurriendo?" + +#~ msgid "%v of %m" +#~ msgstr "%v de %m" + +#~ msgid "Please be patient" +#~ msgstr "Por favor, sea paciente" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Formato de documento portable (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Exportar archivo como" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "El archivo %1\n" +#~ "ya existe. ¿Desea sobrescribirlo?" + +#~ msgid "Overwrite File" +#~ msgstr "Sobrescribir archivo" + +#~ msgid "Overwrite" +#~ msgstr "Sobrescribir" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Usando «dvipdfm» para exportar el archivo a PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular está usando actualmente el programa externo «dvipdfm» para " +#~ "convertir su archivo DVI a PDF. Algunas veces esto puede tardar cierto " +#~ "tiempo debido a que «dvipdfm» necesita generar sus propios tipos de letra " +#~ "de mapa de bits. Por favor, espere un momento." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Esperando que «dvipdfm» termine..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Usando «dvips» para exportar el archivo a PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular está usando actualmente el programa externo «dvips» para convertir " +#~ "su archivo DVI a PostScript. Algunas veces esto puede tardar cierto " +#~ "tiempo debido a que «dvips» necesita generar sus propios tipos de letra " +#~ "de mapa de bits. Por favor, espere un momento." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Esperando que «dvips» termine..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funcionalidad no disponible" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Archivo dañado. Okular no puede interpretar el " +#~ "archivo DVI. Lo más probable es que el archivo esté dañado." + +#~ msgid "DVI File Error" +#~ msgstr "Error de archivo DVI" + +#~ msgid "Not All Font Files Found" +#~ msgstr "No se han encontrado todos los archivos de tipos de letra" + +#~ msgid "Locating fonts..." +#~ msgstr "Localizando tipos de letra..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Ha ocurrido algún problema al ejecutar kpsewhich. Como " +#~ "consecuencia, no se ha podido localizar algunos archivos de tipos de " +#~ "letra, por lo es posible que su documento no sea legible.

Posible motivo: Tal vez el programa «kpsewhich» no esté " +#~ "instalado en su equipo, o no se puede encontrar en su ruta de búsqueda " +#~ "actual.

¿Qué puede hacer?: Normalmente, el programa " +#~ "«kpsewhich» está contenido en las distribuciones del sistema TeX. Si TeX " +#~ "no está instalado en su equipo, puede instalar la distribución TeX Live " +#~ "(www.tug.org/texlive). Si está seguro de que TeX está instalado, pruebe a " +#~ "usar el programa «kpsewhich» desde la línea de órdenes para comprobar que " +#~ "realmente funciona.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Problema localizando tipos de letra" + +#~ msgid "Font generation aborted" +#~ msgstr "Generación de tipos de letra interrumpida" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Exportar: %1 a PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Exportar: %1 a PostScript" diff --git a/po/es/okular_epub.po b/po/es/okular_epub.po new file mode 100644 index 0000000..beab682 --- /dev/null +++ b/po/es/okular_epub.po @@ -0,0 +1,57 @@ +# translation of okular_epub.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ignacio Poggi , 2008. +# Eloy Cuadra , 2008, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-26 14:50+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra,Ignacio Poggi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net,ignaciop.3@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Ha ocurrido un error mientras se accedía al documento EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configuración del motor EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Motor EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Un motor EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/es/okular_fax.po b/po/es/okular_fax.po new file mode 100644 index 0000000..ce60a16 --- /dev/null +++ b/po/es/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-26 21:37+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "No se puede cargar el documento" + +#~ msgid "Fax Backend" +#~ msgstr "Motor de fax" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Un motor de documentos de fax G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/es/okular_fictionbook.po b/po/es/okular_fictionbook.po new file mode 100644 index 0000000..464feae --- /dev/null +++ b/po/es/okular_fictionbook.po @@ -0,0 +1,81 @@ +# translation of okular_fictionbook.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 13:12+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "No es un documento FictionBook válido" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "No se puede abrir el documento: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "El documento no es un archivo ZIP válido" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Estructura de documento no válida (falta la carpeta principal)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "El documento no tiene contenido" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Documento XML no válido: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuración del motor de FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Motor de FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un visualizador de e-libros FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/es/okular_ghostview.po b/po/es/okular_ghostview.po new file mode 100644 index 0000000..047565d --- /dev/null +++ b/po/es/okular_ghostview.po @@ -0,0 +1,93 @@ +# translation of okular_ghostview.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2009, 2011. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2011-06-13 15:07+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usar tipos de letra de la plataforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina cuándo se le debe permitir a Ghostscript usar los tipos de letra " +"de la plataforma; si es falso, solo se le permitirá usar los tipos de letras " +"incrustados en el documento." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Preferencias generales" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usar tipos de letra del sistema" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuración del motor Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Versión del documento" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivel de lenguaje" + +#~ msgid "PS Backend" +#~ msgstr "Motor PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un visualizador de archivos PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Basado en la biblioteca Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/es/okular_kimgio.po b/po/es/okular_kimgio.po new file mode 100644 index 0000000..0b7c6f7 --- /dev/null +++ b/po/es/okular_kimgio.po @@ -0,0 +1,70 @@ +# translation of okular_kimgio.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2009, 2017. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-20 20:13+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "No se puede cargar el documento: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Parece que este documento está mal formado. Esta es la mejor aproximación " +"del aspecto previsto del documento." + +#~ msgid "Image Backend" +#~ msgstr "Motor de imagen" + +#~ msgid "A simple image backend" +#~ msgstr "Un sencillo motor de imagen" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra de herramientas principal" diff --git a/po/es/okular_markdown.po b/po/es/okular_markdown.po new file mode 100644 index 0000000..1b4300d --- /dev/null +++ b/po/es/okular_markdown.po @@ -0,0 +1,55 @@ +# Spanish translations for okular_markdown.po package. +# Copyright (C) 2017 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Automatically generated, 2017. +# Eloy Cuadra , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_markdown\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-04-07 12:44+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 18.12.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "No se ha podido abrir el documento" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "La compilación del documento Markdown ha fallado." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Activar el formato SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuración del motor para Markdown" diff --git a/po/es/okular_mobi.po b/po/es/okular_mobi.po new file mode 100644 index 0000000..4fcc62b --- /dev/null +++ b/po/es/okular_mobi.po @@ -0,0 +1,66 @@ +# translation of okular_mobi.po to Español +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Miguel Angel Quesada Fernandez , 2008. +# Ignacio Poggi , 2009. +# Eloy Cuadra , 2009, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-26 14:51+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra,Miguel Ángel Quesada Fernández,Ignacio Poggi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net,kesadalive@gmail.com,ignaciop.3@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Se ha producido un error al abrir el documento Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Este libro está protegido por DRM y únicamente puede ser mostrado en los " +"dispositivos designados" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuración del motor Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Motor Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Un motor mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/es/okular_plucker.po b/po/es/okular_plucker.po new file mode 100644 index 0000000..7106e7a --- /dev/null +++ b/po/es/okular_plucker.po @@ -0,0 +1,46 @@ +# translation of okular_plucker.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-03-26 19:17+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nombre" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Motor de documentos Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un visualizador de e-libros Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/es/okular_poppler.po b/po/es/okular_poppler.po new file mode 100644 index 0000000..648293b --- /dev/null +++ b/po/es/okular_poppler.po @@ -0,0 +1,229 @@ +# translation of okular_poppler.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008, 2009, 2010, 2012, 2013, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-01-12 22:34+0100\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 18.12.0\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Mejorar las líneas finas:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solid" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opciones PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprimir comentarios" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Incluir comentarios en el documento impreso" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Incluye las notas en el documento impreso. Puede desactivar esto si desea " +"imprimir el documento original sin comentar." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Forzar conversión a imagen" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Convertir en una imagen antes de imprimir" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Fuerza la conversión de cada página en una imagen antes de imprimirla. " +"Normalmente suele producir peor resultado, pero puede ser de utilidad cuando " +"algunos documentos se imprimen incorrectamente." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajustar al área imprimible" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Ajustar a la página completa" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Ninguno; imprimir con el tamaño original" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Modo de escalado para las páginas impresas" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de escalado:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Cifrado" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "No cifrado" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Seguridad" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Sí" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimizado" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Usando Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Usando Poppler %1\n" +"\n" +"Compilado con Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuración del motor PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "No disponible" + +#~ msgid "Select rasterization to enable this!" +#~ msgstr "Seleccione la conversión a imagen para activar esto." + +#~ msgid "PDF Backend" +#~ msgstr "Motor PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Un visualizador de archivos PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "No está permitido guardar archivos con /Encrypt." + +#~ msgid "Unknown" +#~ msgstr "Desconocido" + +#~ msgid "Unknown Date" +#~ msgstr "Fecha desconocida" + +#~ msgid "Unknown Encryption" +#~ msgstr "Cifrado desconocido" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optimización desconocida" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Introduzca la contraseña para leer el documento:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Contraseña incorrecta. Pruebe de nuevo:" + +#~ msgid "Document Password" +#~ msgstr "Contraseña del documento" diff --git a/po/es/okular_tiff.po b/po/es/okular_tiff.po new file mode 100644 index 0000000..b09aadd --- /dev/null +++ b/po/es/okular_tiff.po @@ -0,0 +1,30 @@ +# Spanish translations for okular_tiff.po package. +# Copyright (C) 2020 This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Automatically generated, 2020. +# Eloy Cuadra , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_tiff\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-13 15:27+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" diff --git a/po/es/okular_txt.po b/po/es/okular_txt.po new file mode 100644 index 0000000..1248109 --- /dev/null +++ b/po/es/okular_txt.po @@ -0,0 +1,51 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2013. +# Javier Viñal , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-07-24 16:42+0200\n" +"Last-Translator: Javier Viñal \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuración del motor de texto" + +#~ msgid "Txt Backend" +#~ msgstr "Motor de texto" + +#~ msgid "Txt backend." +#~ msgstr "Motor de texto." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/es/okular_xps.po b/po/es/okular_xps.po new file mode 100644 index 0000000..948886f --- /dev/null +++ b/po/es/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to Spanish +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-08-10 11:33+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Eloy Cuadra" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "ecuadra@eloihr.net" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisión" + +#~ msgid "XPS Backend" +#~ msgstr "Motor XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un motor XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/es/org.kde.active.documentviewer.po b/po/es/org.kde.active.documentviewer.po new file mode 100644 index 0000000..02f48a7 --- /dev/null +++ b/po/es/org.kde.active.documentviewer.po @@ -0,0 +1,84 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Eloy Cuadra , 2012, 2016, 2018, 2019. +# Javier Viñal , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-06 14:42+0200\n" +"Last-Translator: Eloy Cuadra \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.07.80\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Abrir..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Eliminar marcador" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Marcar esta página" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniaturas" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Tabla de contenido" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Marcadores" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Buscar..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "No se ha encontrado ningún resultado." + +#~ msgid "Document to open..." +#~ msgstr "Documento a abrir..." + +#~ msgid "Open Android..." +#~ msgstr "Abrir Android..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "No se han encontrado documentos. Para comenzar a leer, sitúe archivos en " +#~ "la carpeta Documentos de su dispositivo." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Visor de documentos para Plasma Active que usa Okular" + +#~ msgid "Reader" +#~ msgstr "Lector" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Derechos de autor, 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL del archivo a abrir" diff --git a/po/et/docs/okular/man-okular.1.docbook b/po/et/docs/okular/man-okular.1.docbook new file mode 100644 index 0000000..79a70ea --- /dev/null +++ b/po/et/docs/okular/man-okular.1.docbook @@ -0,0 +1,289 @@ + + +]> + + + + +KDE kasutaja käsiraamat +YuriChornoivan Okular man page. yurchor@ukr.net +2013-03-09 +KDE töökeskkond + + + +okular +1 + + + +okular +universaalne dokumentide näitaja + + + +okular Qt võtmed KDE võtmed Okulari võtmed URL + + + +Kirjeldus +okular on mõeldud eri vormingutes dokumentide näitamiseks. + + + +Üldised võtmed + + + + +Abiteate näitamine võtmete kohta. + + + + + +Qt spetsiifiliste võtmete näitamine. + + + + + +KDE spetsiifiliste võtmete näitamine. + + + + + +Kõigi võtmete näitamine. + + + + + +Teabe näitamine autori kohta. + + + + + +Versiooniteabe näitamine. + + + + + +Litsentsiteabe näitamine. + + + + + +Võtmete lõpp. + + + + + +Okulari võtmed + + + + +Määratud lehekülje avamine dokumendis. + + + + + +Dokumendi avamine esitlusrežiimis. + + + + + +Käivitamine trükkimisdialoogiga. + + + + + +"Unikaalse isendi" kontroll. + + + + + +Võimaldab vältida Okulari akna esiletoomist käivitamise järel. + + + + + +Argumendid + + + + + Avatava dokumendi aadress. PDF-dokumentide puhul võib määrata kujul dokumendi_nimi#nimega_sihtkoht, kus nimega_sihtkoht on konkreetne dokumenti põimitud nimega sihtkoht. + + + + + +Tagasiside +IRC-s irc.freenode.net #okular või e-postiga okular-devel@kde.org või veebis <http://okular.kde.org> + + + +Vaata ka +Põhjalikumat kasutaja dokumentatsiooni pakub help:/okular (kirjuta see &URL; &konqueror;i või käivita käsuga khelpcenter help:/okular). + + +Autoriõigus +Autoriõigus © 2002: Wilco Greven, Christophe Devriese +Autoriõigus © 2004-2005: Enrico Ros +Autoriõigus © 2005: Piotr Szymanski +Autoriõigus © 2004-2012: Albert Astals Cid +Autoriõigus © 2006-2009: Pino Toscano +Litsents: GNU Üldine Avalik Litsents, versioon 2 <http://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/et/okular.po b/po/et/okular.po new file mode 100644 index 0000000..fd2fb7c --- /dev/null +++ b/po/et/okular.po @@ -0,0 +1,5848 @@ +# translation of okular.po to Estonian +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# Marek Laane , 2003-2009. +# Peeter Russak , 2005. +# Marek Laane , 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2019, 2020. +# Mihkel Tõnnov , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-10-15 14:19+0200\n" +"Last-Translator: Mihkel Tõnnov \n" +"Language-Team: Estonian <>\n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.08.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "qiilaq69@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Universaalne dokumentide näitaja Okular" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002: Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005: Enrico Ros\n" +"(C) 2005: Piotr Szymanski\n" +"(C) 2004-2017: Albert Astals Cid\n" +"(C) 2006-2009: Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Endine hooldaja" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Palju tööd raamistiku kallal, ODT ja FictionBooki taustaprogrammid" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Arendaja" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Lõi KPDF-i koodi põhjal Okulari" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF-i arendaja" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Annotatsioonide kunstiline külg" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Tabelivaliku tööriist" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Annoteerimise täiustamine" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Liigu leheküljele %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Ava väline fail" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Käivita '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Esimene lehekülg" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Eelmine lehekülg" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Järgmine lehekülg" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Viimane lehekülg" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Tagasi" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Edasi" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Välju" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Käivita esitlus" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Lõpeta esitlus" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Otsi..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Liigu leheküljele..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Esita heli..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScripti skript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Esita video..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Esita film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Peata film" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Paus filmis" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Jätka filmi näitamist" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Taustaprogrammi valik" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Leiti rohkem kui üks MIME tüübile sobiv taustaprogramm:
%1 " +"(%2).

Palun vali, millist kasutada:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Enamik lehekülgi on %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Püstpaigutusega %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Rõhtpaigutusega %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 tolli (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Otsingu jätkamine algusest" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Otsingu jätkamine lõpust" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Pluginat töödeldud dokumenti käsitlemiseks ei leitud." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Eemalda annotatsioonid" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokument üritab käivitada välist rakendust, kuid sinu turvalisuse huvides ei " +"luba Okular seda teha." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Ei leitud rakendust, millega avada faili MIME tüübiga %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Ajutise faili avamine nurjus" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Trükkimiseks teisendamine nurjus" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Trükkimisprotsessi tabas krahh" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Trükkimisprotsessi käivitamine nurjus" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Salvestamine faili nurjus" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Printer oli vales olekus" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Trükkimiseks ei leitud faili" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Polnud ühtegi faili trükkida" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Sobivat binaarfaili trükkimiseks ei leitud. Kontrolli, kas CUPS-i lpr " +"binaarfail on ikka saadaval" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Lehekülje trükisuurus on vigane" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "\"%1\" avamine nurjus. Faili ei ole olemas." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Pealkiri" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Teema" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Kirjeldus" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Looja" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Generaator" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Autoriõigus" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Lehekülgi" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Loodud" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Muudetud" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME tüüp" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategooria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Võtmesõnad" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Faili asukoht" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Faili suurus" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Lehekülje suurus" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Lisa annotatsioon" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Eemalda annotatsioon" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Muuda annotatsiooni omadusi" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Tõlgi annotatsioon" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "Kohanda annotatsiooni" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Muuda teksti" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Muuda annotatsiooni sisu" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Muuda vormi sisu" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Muuda loendivormi valikuid" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Muuda liitvormi valikut" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Muuda vorminupu olekut" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Liht&tekst..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument-tekstidokument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Trükkimisvalikud" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Sobitamine trükitava alaga" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Sobitamine kogu lehele" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Skaleerimisrežiim:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Puuduv hoiatuse tüüp" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Rohkem ei näidata" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Allikas: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Vaikimisi font:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Punane" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Oranž" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Kollane" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Roheline" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Tsüaan" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Sinine" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Valge" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Hall" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Must" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Jämedus %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Annotatsiooni joone jämedus (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Annotatsiooni värv (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Annotatsiooni täitevärv (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Annotatsiooni läbipaistmatus (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Annotatsiooni font (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Lisa valitud annotatsioon eelmääratud annotatsioonitööriistade menüüsse " +"(annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Kujundi proportsioonide piiramine 1 : 1 suhtega või joone suuna piiramine " +"15° sammudega (annotatsiooni pole valitud)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Valitud annotatsioonitööriistade täpsemad seadistused (annotatsiooni pole " +"valitud)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Annotatsiooni joone jämedus" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Annotatsiooni joone jämedus (pole valitud annotatsioonil kasutatav)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Annotatsiooni teksti värv" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Annotatsiooni äärise värv" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Annotatsiooni värv" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Annotatsiooni täitevärv" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "Annotatsiooni täitevärv (pole valitud annotatsioonil kasutatav)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Annotatsiooni font" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Annotatsiooni font (pole valitud annotatsioonil kasutatav)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Joone suuna piiramine 15° sammudega" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Kujundi proportsioonide piiramine 1 : 1 suhtega" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Kujundi proportsioonide piiramine 1 : 1 suhtega või joone suuna piiramine " +"15° sammudega (pole valitud annotatsioonil kasutatav)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Annotatsiooni läbipaistmatus" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" +"Lisa praegune annotatsioon eelmääratud annotatsioonitööriistade menüüsse" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Valitud annotatsioonitööriista täpsemad seadistused" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Värv" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Täitevärv" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Läbipaistev" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Kohandatud värv ..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"PDF-dokumenti lisatud templid on kõigist PDF-i näitajatest näha ainult " +"Okularis." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Eksperimentaalne võimalus" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Värvi valimine" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotatsioonid" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Peida" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Esiletõstmine" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Allajoonimine" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Laineline joon" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Läbikriipsutamine" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Kirjutusmasin" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Reasisene märkus" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Hüpikmärkus" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Vabakäejoon" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Sirgjoon" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Nool" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Ristkülik" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellips" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Murdjoon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geomeetriakujundid" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Tempel" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Eelmääratud annotatsioonitööriistad" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Vali eelmääratud annotatsioonitööriist" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Lisa eelmääratud annotatsioonitööriistade hulka" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Hoia aktiivne" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Annoteerimistööriist hoitakse pärast kasutamist aktiivsena" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Annotatsioonitööriistade proportsioonide ja nurkade piiramine" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Font" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Annotatsiooni seadistused" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Joone jämedus" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Läbipaistmatus" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Lehekülg %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotatsioon" +msgstr[1] "%1 annotatsiooni" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Ava hüpikmärkus" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Kustuta" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Omadused" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Salvesta '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Välimus" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "Ül&dine" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Loodud:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Muudetud:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Hüpikmärkuse omadused" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Kirjutusmasina omadused" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Reasisese märkuse omadused" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Sirgjoone omadused" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Murdjoone omadused" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Geomeetriaomadused" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Tekstimärgendi omadused" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Templi omadused" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Vabakäejoone omadused" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Kursori omadused" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Kaasatud faili omadused" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Heli omadused" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Video omadused" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Annotatsiooni omadused" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Muudetud: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Kohandatud templi sümboli valimine failist" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Kohandatud templi sümboli valimine" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Ikoonifailid (*.ico *.png *.xpm *.svg *." +"svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Faili %1 laadimine nurjus" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Vigane fail" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "Vä&rv:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Lä&bipaistmatus:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Ikoon:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Kommentaar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Abitekst" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Lisand" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Võti" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Uus lõik" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Märkus" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Lõik" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Font:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Teksti vä&rv:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Joondus:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Vasakule" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Keskele" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Paremale" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Piir&de laius:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Heakskiit" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Nagu on" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Konfidentsiaalne" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Osakonnasisene" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Mustand" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Eksperimentaalne" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Lõplik" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Ootab kommentaare" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Avaldamiseks" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Heakskiiduta" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Pole avaldamiseks" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Müüdud" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Ülisalajane" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Järjehoidja" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Info" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Eksperimentaalne võimalus.PDF-dokumenti lisatud templid on " +"kõigist PDF-i näitajatest näha ainult Okularis." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Templi sümbol:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Laius:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Joone algus:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Joone lõpp:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Ruut" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Ring" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Romb" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Avatud nool" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Suletud nool" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Puudub" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Tala" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Paremale avatud nool" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Paremale suletud nool" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Kaldkriips" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Juhtjoone pikkus:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Juhtjoone laiendite pikkus:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Lubatud" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Kujundi täide:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tüüp:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Esiletõst" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Laineline joon" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Allajoonimine" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Läbikriipsutamine" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Ristkülik" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellips" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Kaasatud faili sümbol:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Diagramm" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Knopka" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Kirjaklamber" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Lipik" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fail" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "-" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Kirjeldus puudub." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nimi:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Kirjeldus:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Kursori sümbol:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Puudub" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Sulge see märkus" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Valikud" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"See annotatsioon võib sisaldada LaTeXi koodi.\n" +"Klõpsa siia selle renderdamiseks." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "LaTeXi täitmisfaili ei leitud." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeXi renderdamine nurjus" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Dvipng täitmisfaili ei leitud." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Käsu 'latex' täitmisel tekkis probleem." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Käsu 'dvipng' täitmisel tekkis probleem." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Üks järjehoidja" +msgstr[1] "" +"%1\n" +"\n" +"%2 järjehoidjat" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Järjehoidjad" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Otsi ..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Ainult aktiivne dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Liigu sellele järjehoidjale" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Nimeta järjehoidja ümber" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Eemalda järjehoidja" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Ava dokument" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Eemalda järjehoidjad" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versioon" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Seerianumber" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Väljaandja" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Välja antud" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Aegub" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Allkirjastaja" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Avalik võti" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Võtme kasutus" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2-bitine)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Omadus" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Väärtus" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Sertifikaadinäitaja" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Ekspordi ..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Üldine" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Väljaandja" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Üldnimi (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-post" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisatsioon (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Välja antud" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Kehtivus" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Sõrmejäljed" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1 sõrmejälg" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256 sõrmejälg" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Üksikasjad" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Sertifikaadi andmed:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Kuhu see sertifikaat salvestada?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Sertifikaadifail (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Sertifikaati ei õnnestunud eksportida" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Punane" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Roheline" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Sinine" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Kollane" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Must" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Valge" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "&Piltide ümber joonistatakse piirded" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "&Viitade ümber joonistatakse piirded" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Värvide &muutmine" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Hoiatus: need valikud võivad oluliselt mõjutada esitamise kiirust." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Värvirežiim:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Värvid vahetatakse" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Paberi värvi muutmine" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Tumeda ja heleda värvi muutmine" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Teisendamine mustvalgeks" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Heleduse inversioon" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Luma (lineaarne sRGB) inversioon" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Luma (sümmeetriline) inversioon" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Positiivne tooninihe" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Negatiivne tooninihe" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Paberi värv:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Tume värv:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Hele värv:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Lävi:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Kõne" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Mootor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identiteet" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "&Autor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Märkus: seda kasutatakse ainult annotatsioonide puhul. Teave " +"salvestatakse annoteeritud dokumenti ja nii liigub see edasi koos " +"dokumendiga." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Eelmääratud annotatsioonitööriistad" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Kohandatud tekstiredaktor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacsi klient" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyxi klient" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Siin saab määrata käsu, millega käivitatakse kohandatud tekstiredaktor." +"
\n" +"Kasutada saab ka mõningaid kohatäitjaid:\n" +"
    \n" +"
  • %f - failinimi
  • \n" +"
  • %l - avatav rida failis
  • \n" +"
  • %c - avatav veerg failis
  • \n" +"
\n" +"Kui %f on määramata, lisatakse määratud käsule failinimi." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Redaktor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Redaktor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "Vali redaktor, mille soovid käivitada, kui Okular avab lähtefaili." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Käsk:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Välimus" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Sujuva kerimise kasutamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Kerimis&ribade näitamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Pisipil&tide linkimine leheküljega" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Vi&hjete ja infoteadete näitamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Võimaluse korral dokumendi pealkirja näitamine tiitliribal" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Kui ei näidata dokumendi pealkirja:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Ainult failinime näitamine" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Faili täieliku asukoha näitamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Kohandatud taustavärvi kasutamine" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Programmi omadused" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "&Uute failide avamine kaartidel" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Olemasolevale kaardile lülitumine, kui fail on juba avatud" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "DRM-i &piirangute arvestamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Dokument laaditakse faili muutmisel uuesti" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Taustaprogrammi valimise dialoogi näitamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Paremalt vasakule lugemise suund" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Vaatevalikud" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Üle&vaateveerud:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Määrab, kui palju aktiivsest vaatealast jääb näha Page Up/Down klahvi " +"kasutamisel." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Page Up/Down jätab näha:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Määrab vaikesuurenduse varem avamata failidele.\n" +"Varem avatud failide korral kasutatakse viimast suurendustaset." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Määrab vaikesuurenduse varem avamata failidele.\n" +"Varem avatud failide korral kasutatakse viimast suurendustaset." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Vaikimisi suuren&dus:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Mahutatakse laiusele" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Mahutatakse leheküljele" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automaatne mahutamine" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Hoiab mälukasutuse võimalikult väiksena. Midagi ei puhverdata. (Vähese " +"mäluga masinatele.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Asjalik kompromiss mälukasutuse ja kiiruse vahel. Järgmine lehekülg " +"laaditakse juba eelnevalt, otsimine on kiirem. (Tüüpiliselt 2 GB mäluga " +"masinatele.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Kõik puhverdatakse mälus. Järgmised leheküljed laaditakse juba eelnevalt. " +"Otsingud on kiiremad. (Enam kui 4 GB mäluga masinatele.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Kõige laadimine ja hoidmine mälus. Kõigi lehekülgede eellaadimine. (Kasutab " +"maksimaalselt 50% sinu kogumälust või vabast mälust vastavalt sellele, kumb " +"on suurem.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Protsessori koormus" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Lä&bipaistvusefektide lubamine" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Mälukasutus" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Madal" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Normaalne (vaikimisi)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Agressiivne" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "A&hne" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Renderdamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Teksti antialiase lubamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Graafika antialiase lubamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Teksti varjundamise lubamine" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Aktiivne ekraan" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Vaikimisi ekraan" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekraan %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekund" +msgstr[1] " sekundit" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Liikumine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Edasiliikumise intervall:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Viimase lehekülje järel alustatakse uuesti algusest" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Puutega liikumine:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Koputus vasakule/paremale servale liigub tagasi/edasi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Koputus kuhu iganes liigub edasi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Keelatud" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Taustavärv:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Hiirekursor:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Peidetakse viivituse järel" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Alati nähtav" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Alati peidetud" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "&Edenemisnäidiku näitamine" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "&Kokkuvõtte näitamine" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Üleminekute lubamine" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Vaikeüleminek:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Segunemine püstiselt" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Segunemine rõhtsalt" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Kastina sissepoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Kastina väljapoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Hägustumine" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Hääbumine" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Säbrutus alla" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Säbrutus paremale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Säbrutus alla ja paremale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Juhuslik üleminek" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Asendamine" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Jagamine rõhtsalt sissepoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Jagamine rõhtsalt väljapoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Jagamine püstiselt sissepoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Jagamine püstiselt väljapoole" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Pühkimine alla" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Pühkimine paremale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Pühkimine vasakule" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Pühkimine üles" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Asetus" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Ekraan:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Joonistamistööriista seadistamine" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Joonistamistööriist: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Kustutaja" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nimi:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tüüp:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Hüpikmärkus" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Reasisene märkus" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Vabakäejoon" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Sirgjoon" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Murdjoon" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Tekstimärgend" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geomeetriakujund" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Tempel" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Kirjutusmasin" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Annoteerimistööriista loomine" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Annoteerimistööriista muutmine" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Värv:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Pliiatsi laius:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr "%" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Joonistamistööriista loomine" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Joonistamistööriista muutmine" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Tundmatu" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Põimitud failid" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Näita" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nimi" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Kirjeldus" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Suurus" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Loodud" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Muudetud" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Sal&vesta kui..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Näita ..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Trükkimise eelvaatluse komponendi laadimine nurjus" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Trükkimise eelvaatlus" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Sulge" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "Ots&ing:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Otsitav tekst" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Järgmine" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Hüppamine järgmisele sobivusele" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Eelmine" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Hüppamine eelmisele sobivusele" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Otsingu käitumise muutmine" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Tõstutundlik" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Alates aktiivsest leheküljest" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Otsimine kirjutamise ajal" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Kõik failid" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Allkirja omadused" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Sirgjoon kommentaariga" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Murdjoon kommentaariga" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geomeetria kommentaariga" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geomeetria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Esiletõstmine kommentaariga" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Teksti allajoonimine lainelise joonega ja kommentaariga" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Teksti allajoonimine kommentaariga" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Teksti läbikriipsutamine kommentaariga" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Läbikriipsutus" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Tempel kommentaariga" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Vabakäejoon kommentaariga" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Kursor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Kaasatud fail" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Heli" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Video" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Ekraan" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Vidin" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Multimeedia" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Tundmatu" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Kuhu salvestada %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "\"%1\" avamine kirjutamiseks nurjus. Faili ei salvestatud." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Otsimisvalikud" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Tõstutundlik" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regulaaravaldis" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Otsing:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Kihid" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "/" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Suurendus" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Suurendus 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Pöö&ra paremale" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Paremale" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Pööra vasaku&le" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Vasakule" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Algne orientatsioon" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Vaate kär&pimine" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Kär&bi veeriseid" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Kärbi &valikule" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Ma&hutatakse laiusele" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Mah&utatakse leheküljele" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automaatne mahutamine" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "So&bita aken leheküljega" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Vaaterežiim" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Ük&s lehekülg" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Kõr&vutised leheküljed" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Kõrvutised leheküljed (esimene lehekül&g tsentreeritakse)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Ülevaa&de" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Pidev" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Paremalt vasakule lugemise suund" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "Si&rvimine" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "S&uurendus" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Värvide &muutmise lülitamine" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Ala&valik" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Tekstivalik" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Ta&belivalik" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Suurendaja" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Valikutööriistad" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Loe kogu dokument ette" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Loe aktiivne lehekülg ette" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Lõpeta ettelugemine" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Kõne pausile/pausilt ära" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Keri üles" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Keri alla" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Keri lehekülg üles" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Keri lehekülg alla" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Vormide näitamine" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "Laaditi üheleheküljeline dokument." +msgstr[1] "Laaditi %1-leheküljeline dokument." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Tekst (1 märk)" +msgstr[1] "Tekst (%1 märki)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopeeri lõikepuhvrisse" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "DRM keelab kopeerimise" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Loe tekst ette" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Pilt (%1 x %2 pikslit)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Salvesta faili..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Pilt [%1x%2] kopeeriti lõikepuhvrisse." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Faili salvestamine" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Pildid (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Faili ei salvestatud." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Pilt [%1x%2] salvestati faili %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopeeri tekst" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Liigu leheküljele %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Otsi '%1', kasutades" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Seadista veebikiirklahve..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Ava see link" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Esita see heli" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Peata heli" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopeeri lingi aadress" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "'%1' otsimine selles dokumendis" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Tere tulemast" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Vali suurendusala. Paremklõpsuga saab vähendada." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Klõpsa suurendatud vaate nägemiseks." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Tõmba hiirega ristkülik ala ümber, mida soovid kopeerida." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Vali tekst" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Tõmba hiirega ristkülik tabeli ümber ja klõpsa siis jagamiseks servade " +"juures; puhastamiseks vajuta Esc." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Tõmba ristkülik ala ümber, mida soovid nähtaval hoida" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Uus tekstimärkus" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Uue märkuse tekst:" + +# Originaal on ajuvaba. Tegemist on annotatsioonide autori nime küsiva dialoogi tiitliga - näidatakse annotatsiooni lisamisel juhul, kui Okulari seadistuses on vaikimisi määratud nimi ära kustutatud. +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Annotatsioonide autori nimi" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Sisesta nimi, mida lisatavate annotatsioonide juures näidata:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Ellipsi joonistamine (vali lohistades ala)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Teksti esiletõstmine" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Vabakäejoone tõmbamine" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Reasisene tekstiannotatsioon (vali lohistades ala)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Hüpikmärkuse asetamine" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Joonista murdjoon (selle sulgemiseks klõpsa esimesel punktil)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Ristküliku joonistamine" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Teksti allajoonimine lainelise joonega" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Aseta templi sümbol" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Sirgjoone tõmbamine" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Teksti läbikriipsutamine" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Teksti allajoonimine" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Kirjutusmasina annotatsioon (vali lohistades ala)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Esiletõstmine" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Lemmikannotatsiooni lisamine" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Kohandatud annotatsiooni nimi:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fail" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Seadistused" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Abi" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientatsioon" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Järjehoidjad" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Näitaja riba" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Pisipildid" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotatsioonid" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"See dokument sisaldab annotatsioone või vormiandmeid, mis on seesmiselt " +"salvestatud Okulari varasema versiooniga. Seesmine salvestamine ei ole " +"enam toetatud.
Palun salvesta faili nende liigutamiseks, kui soovid " +"jätkata dokumendi redigeerimist." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Sel dokumendil on põimitud faile. Klõpsa " +"nende vaatamiseks siia või vali menüüst Fail -> Põimitud failid." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Eelmine" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Liikumine eelmisele leheküljele" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Liigub dokumendi eelmisele leheküljele" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Järgmine" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Liikumine järgmisele leheküljele" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Liigub dokumendi järgmisele leheküljele" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Dokumendi algus" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Liigub dokumendi algusse" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Dokumendi lõpp" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Liigub dokumendi lõppu" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Aktiivse järjehoidja nime muutmine" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Eelmine järjehoidja" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Liikumine eelmisele järjehoidjale" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Järgmine järjehoidja" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Liikumine järgmisele järjehoidjale" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Okulari seadistamine..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Näitaja seadistamine..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Näitaja taustaprogrammide seadistamine" + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Taustaprogrammide seadistamine..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Taustaprogrammi info" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Laa&di uuesti" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Aktiivse dokumendi taaslaadimine kettalt." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Sul&ge otsinguriba" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Leheküljenumber" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Vali kogu aktiivse lehekülje tekst" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Külgr&iba näitamine" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Le&heküljeriba näitamine" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Allkir&jade paneeli näitamine" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Põimitud failid" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&Eksport" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Jaga" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&Esitlus" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Ava s&isaldav kataloog" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Impordi PostScript PDF-ina..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Hangi raamatuid internetist..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Lülitu ekraanipimendamise režiimi" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Kõrvalda joonistus" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Seadista annotatsioone..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Esita/peata esitlus" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "\"%1\" avamine nurjus (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "%1 laadimine katkestati." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "%1 avamine nurjus. Põhjus: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Näitaja taustaprogrammide seadistamine" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Taustaprogrammide seadistamine" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Programmi \"ps2pdf\" ei leitud, mistõttu Okular ei saa selle abil importida " +"PS-faile." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "Programmi ps2pdf ei leitud" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript-failid (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "PS-faili importimine PDF-ina (see võib võtta veidi aega)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Palun anna dokumendi lugemiseks vajalik parool:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Vigane parool. Proovi uuesti:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Dokumendi parool" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "Dokumendis esineb XFA vorme, mis on praegu toetamata." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Selles dokumendis on vormid. Klõpsa nupule nende kasutamiseks või vali " +"menüüst Vaade -> Näita vorme." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Kõik selle dokumendi redigeerimis- ja interaktiivsed toimingud on keelatud. " +"Palun salvesta koopia ja ava see uuesti dokumendi muutmiseks." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "See dokument on digitaalselt allkirjastatud." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"See dokument on digitaalselt allkirjastatud, aga seda on pärast viimast " +"allkirjastamist muudetud." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"See dokument on digitaalselt allkirjastatud, aga mõnda allkirja polnud " +"võimalik valideerida." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"See dokument soovib enda näitamist täisekraanis.\n" +"Kas lahkuda tavalisest režiimist ja minna esitlusrežiimi?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Vaaterežiimi muutmise soov" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Mine esitlusrežiimi" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Lükka soov tagasi" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "%1 avamine nurjus. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Leidub salvestamata muudatusi ja faili \"%1\" on muutnud mingi teine " +"programm. Sinu muudatused lähevad kaotsi, sest faili ei saa enam salvestada. " +"
Kas tõesti jätkata faili taaslaadimist?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Faili on muudetud" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Jätka taaslaadimist" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Loobu taaslaadimisest" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Leidub salvestamata muudatusi ja faili \"%1\" on muutnud mingi teine " +"programm. Sinu muudatused lähevad kaotsi, sest faili ei saa enam salvestada. " +"
Kas tõesti jätkata faili sulgemisega?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Jätka sulgemisega" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Loobu sulgemisest" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Kas salvestada muudatused failis \"%1\" või unustada need?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Sulge dokument" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"See viit osutab dokumendi sulgemise toimingule, mida ei saa kasutada " +"põimitud näitajas." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"See viit osutab rakendusest väljumise toimingule, mida ei saa kasutada " +"põimitud näitajas." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Dokumendi taaslaadimine..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Sisu" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Allkirjad" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Liikumine leheküljele" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Lehekülg:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Järjehoidja uus nimi:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Muuda järjehoidja nime" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Eemalda see järjehoidja" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Salvesta kui " + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Faili '%1' on muutnud mingi teine programm, mis tähendab, et seda ei saa " +"enam salvestada." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Aktiivne dokument on parooliga kaitstud.
Salvestamiseks tuleb fail " +"uuesti laadida. Sinu käest küsitakse uuesti parooli ja sinu tagasivõtmiste " +"ja uuestitegemiste ajalugu läheb kaotsi.
Kas jätkata?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Salvestamine - hoiatus" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Ajutise faili avamine salvestamiseks nurjus." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Salvestamise järel nõuab aktiivse dokumendi vorming faili taaslaadimist. " +"Seinu tagasivõtmiste ja uuestitegemiste ajalugu läheb kaotsi.
Kas " +"jätkata?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Faili salvestamine asukohta \"%1\" nurjus. Proovi salvestada mõnda teise " +"asukohta." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Täidetud vormide sisu" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Kasutaja annotatsioonid" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Oled muudatusi salvestamas, kuid praegune failivorming ei toeta järgmiste " +"elementide salvestamist. Palun kasuta nende säilitamiseks Okulari " +"dokumendiarhiivi vormingut." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Hoiatus" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Salvesta Okulari dokumendiarhiivina ..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Oled muudatusi salvestamas, kuid praegune failivorming ei toeta järgmiste " +"elementide salvestamist. Palun kasuta nende säilitamiseks Okulari " +"dokumendiarhiivi vormingut. Klõpsa Jätka dokumendi salvestamiseks " +"ja nende elementide hülgamiseks." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Oled muudatusi salvestamas, kuid praegune failivorming ei toeta järgmiste " +"elementide salvestamist. Palun kasuta nende säilitamiseks Okulari " +"dokumendiarhiivi vormingut. Klõpsa Jätka salvestamiseks, kuid " +"siis kaotad nii need elemendid kui ka tagasivõtmiste ja uuestitegemiste " +"ajaloo." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Jätka" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Jätka muudatusi kaotades" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Faili salvestamine asukohta \"%1\" nurjus. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular ei saa kopeerida dokumenti %1 määratud asukohta.\n" +"\n" +"Dokumenti ei ole enam olemas." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Faili salvestamine asukohta \"%1\" nurjus. Tõrge: '%2'. Proovi salvestada " +"mõnda teise asukohta." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Keri kogu sektsioon lahti" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Keri kogu sektsioon kokku" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Keri kõik lahti" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Keri kõik kokku" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Lisa järjehoidja" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Tööriistad" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Trükkimine" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Seda dokumenti ei ole lubatud trükkida." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Dokumendi trükkimine nurjus. Tundmatu viga. Palun anna sellest teada " +"aadressil bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Dokumendi trükkimine nurjus. Täpne viga on \"%1\". Palun anna sellest teada " +"aadressil bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Liigub eelmisesse asukohta" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Liigub järgmisse asukohta" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Faili viga! Ei õnnestunud luua ajutist faili " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Faili viga! Faili %1 " +"avamine lahtipakkimiseks nurjus. Faili ei laaditud." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"See viga juhtub tavaliselt siis, kui sul ei ole õigust faili lugeda. " +"Faili omanikku ja õigusi saad kontrollida, kui klõpsad failihalduris Dolphin " +"failile hiire parema nupuga ja valid kontekstimenüüst 'Omadused' ning " +"avanenud aknas kaardi 'Õigused'." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Faili viga! Faili %1 " +"lahtipakkimine nurjus. Faili ei laaditud." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"See viga juhtub tavaliselt siis, kui fail on vigane. Kui soovid seda " +"kontrollida, proovi fail lahti pakkida käsureatööriistade abil." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Järjehoidjaid pole" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Dokumendi jagamisel tekkis probleem: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Jagamine" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Dokumendi jagamine oli edukas" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Jagatud dokumendi leiab aadressilt %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Redigeerimine" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Vaade" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Liikumine" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Tööriistad" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Peamine tööriistariba" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Annotatsioonide tööriistariba" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Üldised valikud" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Hõlbustus" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Lugemise hõlbustusvahendid" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Jõudlus" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Jõudluse häälestamine" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Näitaja seadistamine" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Esitlus" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Esitlusrežiimi valikud" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Annoteerimise valikud" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Redaktori valikud" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Otsi järgmine" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - esitlus" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Vaheta ekraani" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Ekraan %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Välju esitlusrežiimist" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Pealkiri: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Lehekülgi: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klõpsa alustamiseks" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Paus" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Esita" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Esitlusrežiimist saab väljuda kahel viisil: kas vajutades klahvi Esc või " +"klõpsates väljumisnupupule, mis ilmub nähtavale, kui viid hiire ülemisse " +"paremasse nurka. Mõistagi saab aknaid läbi kerida (vaikimisi " +"klahvikombinatsiooniga Alt+TAB)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Esitluse näitamine" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Tundmatu fail" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 omadused" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fondid" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Fondiinfo lugemine..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Lehekülgede suurused" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Paki font lahti" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeXi virtuaalne" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeXi fondimeetrika" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType'i käsitluses" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Tundmatu" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Põimitud (alamhulk)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Täielikult põimitud" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ei" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Jah (alamhulk)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Jah" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (asenduseks %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[-]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Tundmatu font" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Põimitud: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nimi" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tüüp" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fail" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Lehekülg" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Suurus" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Versiooni eelvaatlus" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Kuhu see versioon salvestada?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Faili %1 salvestamine nurjus." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Versiooni näitamine nurjus." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Kirjuta lehekülgede filtreerimiseks vähemalt 3 tähte" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Tõstutundlik" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Väljendi sobivus" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Kõigi sõnade sobivus" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Suvalise sõna sobivus" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Filtri valikud" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Annotatsioonid puuduvad

Uue annotatsiooni " +"loomiseks vajuta F6 või vali menüükäsk Tööriistad -> Annotatsioonid.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Rühmitamine lehekülgede kaupa" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Rühmitamine autorite kaupa" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Ainult aktiivse lehekülje annotatsioonide näitamine" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Keri kõik elemendid lahti" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Keri kõik elemendid kokku" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Allkiri on krüptograafiliselt kehtiv." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Allkiri ei ole krüptograafiliselt kehtiv." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Esines räsi kokkusobimatus." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Allkirja CMS/PKCS7 struktuur on moondunud" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Nõutud allkirja dokumendis ei leidu." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Allkirja ei saa kontrollida." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Sertifikaat on usaldusväärne." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Sertifikaadi väljaandja ei ole usaldusväärne." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Sertifikaadi väljaandja on tundmatu." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Sertifikaat on tühistatud." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Sertifikaat on aegunud." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Sertifikaati ei ole veel kontrollitud." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Tundmatu probleem sertifikaadiga või rikutud andmed." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Tundmatu algoritm" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tundmatu tüüp" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digitaalne allkiri" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Salgamise vääramine" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Võtmete krüptimine" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Võtmete lahtikrüptimine" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Võtme leping" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Sertifikaadi allkirjastamine" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL-i allkirjastamine" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Ainult krüptimine" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Kasutus pole määratud" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Vers. %1: Allkirjastanud %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Allkirjastamisaeg: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Pole teada" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Põhjus: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Väli: %1 leheküljel %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Omadused" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Dokumenti ei ole pärast allkirjastamist muudetud." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Dokumendi versiooni, mida see allkiri hõlmab, ei ole muudetud;\n" +"kuid dokumendis on tehtud hiljem muudatusi." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Dokumenti on muudetud viisil, mida eelmine allkirjastaja ei ole lubanud." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Dokumendi terviklikkuse kontrolli ei saanud lõpetada." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Kehtivuse olek" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Allkirja kehtivus:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Dokumendi muudatused:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Lisateave" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Allkirjastaja:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Allkirjastamisaeg:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Põhjus:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Asukoht:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Dokumendi versioon" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Dokumendi versioon %1 / %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Vaata allkirjastatud versiooni ..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Vaata sertifikaati ..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Ainult järjehoidjates olevate lehekülgede näitamine" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Esita" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Paus" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Peata" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "Lis&a..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Muuda..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Eemalda" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Liiguta ü&les" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Liiguta &alla" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Vaikimisi joonistamistööriist nr %1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Selle nimega tööriist on juba olemas. Kasutatakse vaikevarianti" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Topeltnimi" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Näidatav dokumendi lehekülg" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Dokumendi avamine esitlusrežiimis" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Käivitamine trükkimisdialoogiga" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Käivitamine trükkimisdialoogiga ja väljumine pärast trükkimist" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "\"Unikaalse isendi\" kontroll" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Akent esile ei tooda" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Stringi leidmine tekstis" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Avatavad dokumendid. '-' korral loetakse standardsisendist." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Tõrge: võtit --unique kasutades ei saa avada üle ühe dokumendi korraga" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Tõrge: võtit --presentation kasutades ei saa avada üle ühe dokumendi korraga" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Tõrge: võtit --print kasutades ei saa avada üle ühe dokumendi korraga" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Tõrge: võtit --page kasutades ei saa avada üle ühe dokumendi korraga" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Tõrge: võtit --find kasutades ei saa avada üle ühe dokumendi korraga" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Okulari komponendi leidmine nurjus: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Okulari unikaalne isend juba töötab. Käesolev isend ei oleks unikaalne." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Okulari komponendi leidmine nurjus." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Klõpsa faili avamiseks\n" +"Klõpsa ja hoia nuppu all viimati kasutatud faili avamiseks" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klõpsa faili avamiseks või klõpsa ja hoia nuppu all viimati " +"kasutatud faili avamiseks" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Järgmine kaart" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Eelmine kaart" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Võta kaardi sulgemine tagasi" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Kõik failid (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Kõik toetatud failid (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Ava dokument" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Sulgemise kinnitus" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Sulge kaardid" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Kavatsed sulgeda %1 kaarti. Kas tõesti jätkata?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Hoiatus, kui ma proovin sulgeda palju aknaid" + +#~ msgid "Reviews" +#~ msgstr "Annotatsioonid" + +#, fuzzy +#~| msgid "V%1" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "V%1" + +#~ msgid "Hide Forms" +#~ msgstr "Peida vormid" + +#~ msgid "Expired" +#~ msgstr "Aegunud" + +#~ msgid "&Review" +#~ msgstr "&Annotatsioon" + +#~ msgid "Annotations author" +#~ msgstr "Annotatsiooni autor" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Palun sisesta oma nimi või initsiaalid:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Liikumispa&neeli näitamine" + +#~ msgid "Show Text" +#~ msgstr "Näita teksti" + +#~ msgid "Small Icons" +#~ msgstr "Väikesed ikoonid" + +#~ msgid "Normal Icons" +#~ msgstr "Tavalised ikoonid" + +#~ msgid "Large Icons" +#~ msgstr "Suured ikoonid" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Klõpsa aktiivse valikutööriista kasutamiseks\n" +#~ "Klõpsa noolele mõne teise valikutööriista valimiseks" + +#~ msgid "Created: %1" +#~ msgstr "Loodud: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Joone laiendid" + +#~ msgid "Style" +#~ msgstr "Stiil" + +#~ msgid "&Size:" +#~ msgstr "&Suurus:" + +#~ msgid "Inner color:" +#~ msgstr "Sisevärv:" + +#~ msgid "Name: %1" +#~ msgstr "Nimi: %1" + +#~ msgid "Size: %1" +#~ msgstr "Suurus: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "S&irvimistööriist" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Suurendustööriist" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Suurendus" + +#~ msgid "&Selection Tool" +#~ msgstr "&Valikutööriist" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Valik" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Tekstivaliku tööriist" + +#~ msgid "T&able Selection Tool" +#~ msgstr "T&abelivaliku tööriist" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Suurendaja" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Dokumendi lõpp" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Puudub" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Dokument käivitatakse esitlusrežiimis, sest fail nõuab seda.\n" +#~ "Kas lubada seda?" + +#~ msgid "Presentation Mode" +#~ msgstr "Esitlusrežiim" + +#~ msgid "Allow" +#~ msgstr "Luba" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Esitlusrežiimi lubamine" + +#~ msgid "Do Not Allow" +#~ msgstr "Ära luba" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Esitlusrežiimi ei lubata" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Annotatsioonide muudatusi ei salvestata automaatselt.\n" +#~ "Vali Fail -> Salvesta kui... või muudatused lähevad dokumendi sulgemisel " +#~ "kaotsi" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Okular salvestab sinu annotatsioonid sisemiselt.\n" +#~ "Annoteeritud dokumendi võib eksportida menüükäsuga Fail -> Eksport -> " +#~ "Dokumendiarhiiv" + +#~ msgid "Save &Copy As..." +#~ msgstr "Salvesta &koopia..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Sinu annotatsioone ei ekspordita.\n" +#~ "Annoteeritud dokumendi võib eksportida menüükäsuga Fail -> Eksport -> " +#~ "Dokumendiarhiiv" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Jõuti dokumendi lõppu.\n" +#~ "Kas jätkata algusest?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Jõuti dokumendi algusesse.\n" +#~ "Kas jätkata lõpust?" + +#~ msgid "Current maintainer" +#~ msgstr "Praegune hooldaja" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Pliiatsi värv:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "rõhtpaigutusega DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "püstpaigutusega DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "rõhtpaigutusega DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "püstpaigutusega DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "rõhtpaigutusega DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "püstpaigutusega DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "rõhtpaigutusega DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "püstpaigutusega DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "rõhtpaigutusega DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "püstpaigutusega DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "rõhtpaigutusega DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "püstpaigutusega DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "rõhtpaigutusega DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "püstpaigutusega DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "rõhtpaigutusega DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "püstpaigutusega DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "rõhtpaigutusega DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "püstpaigutusega DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "rõhtpaigutusega DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "püstpaigutusega DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "rõhtpaigutusega DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "püstpaigutusega DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "rõhtpaigutusega DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "püstpaigutusega DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "rõhtpaigutusega DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "püstpaigutusega DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "rõhtpaigutusega DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "püstpaigutusega DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "rõhtpaigutusega DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "püstpaigutusega DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "rõhtpaigutusega DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "püstpaigutusega DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "rõhtpaigutusega DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "püstpaigutusega DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "rõhtpaigutusega DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "püstpaigutusega DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "rõhtpaigutusega DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "püstpaigutusega DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "rõhtpaigutusega DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "püstpaigutusega DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "rõhtpaigutusega DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "püstpaigutusega DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "rõhtpaigutusega Letter" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "püstpaigutusega Letter" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "rõhtpaigutusega Legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "püstpaigutusega Legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "rõhtpaigutusega Executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "püstpaigutusega Executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "rõhtpaigutusega Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "püstpaigutusega Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "rõhtpaigutusega DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "püstpaigutusega DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "rõhtpaigutusega Folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "püstpaigutusega Folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "Ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "Tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "tundmatu rõhtpaigutusega paberisuurus" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "tundmatu püstpaigutusega paberisuurus" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Joonistamisrežiimi lülitamine" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Jovie teksti ettelugemise teenuse käivitamine nurjus: %1" + +#~ msgid "Search Columns" +#~ msgstr "Otsinguveerud" + +#~ msgid "All Visible Columns" +#~ msgstr "Kõik nähtavad veerud" + +#~ msgid "No document opened." +#~ msgstr "Ühtki dokumenti pole avatud." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Okulari unikaalse isendi kasutamisel ei saa avada üle ühe dokumendi " +#~ "korraga." + +#~ msgid "No matches found for '%1'." +#~ msgstr "'%1' sobivusi ei leitud." + +#~ msgid "Search in progress..." +#~ msgstr "Käib otsimine..." + +#~ msgid "Searching for %1" +#~ msgstr "%1 otsimine" + +#~ msgid "Identity Settings" +#~ msgstr "Identiteediseadistused" + +#~ msgid "Highlight Properties" +#~ msgstr "Esiletõstmise omadused" + +#~ msgid "Ink Properties" +#~ msgstr "Tindi omadused" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Tekstiannotatsioon" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Roheline tint" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Kollane esiletõstmine" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Kollane esiletõstmine" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Kollane sirgjoon" + +#~ msgid "Black Underlining" +#~ msgstr "Must allajoonimine" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Jooni tekst alla musta joonega" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Tsüaanvärvi ellips" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Tsüaanvärvi ellips" + +#~ msgid "Ink" +#~ msgstr "tint" + +#~ msgid "Enable &background generation" +#~ msgstr "Tausta &genereerimise lubamine" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Peida vormid" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Liigub dokumendi esimesele leheküljele" + +#~ msgid "Moves to the last page of the document" +#~ msgstr "Liigub dokumendi viimasele leheküljele" + +#~ msgid "You must set this name:" +#~ msgstr "Vajalik on määrata järgmine nimi:" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Faili asukoha ja nime lülitamine" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Kirjuta üle" + +#~ msgid "Pages:" +#~ msgstr "Lehekülgi:" + +#~ msgid "Activate to ignore file-specific page-durations" +#~ msgstr "Sisselülitamisel eiratakse failipõhiseid lehekülje kestusi" + +#~ msgid "s" +#~ msgstr "s" + +#~ msgid "Green Highlighter" +#~ msgstr "Roheline esiletõstmine" + +#~ msgctxt "Annotation tool" +#~ msgid "Pink Ink" +#~ msgstr "Roosa tint" + +#, fuzzy +#~| msgid "Highlight" +#~ msgid "Pink Highlighter" +#~ msgstr "Esiletõst" + +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "Vajaliku plugina laadimine dokumendi vaatamiseks nurjus." + +#~ msgid "Security" +#~ msgstr "Turvalisus" + +#~ msgid "Optimized" +#~ msgstr "Optimeeritud" + +#~ msgid "Unknown Encryption" +#~ msgstr "Tundmatu krüpto" + +#~ msgid "Unknown Optimization" +#~ msgstr "Tundmatu optimeerimine" + +#~ msgid "" +#~ "The margins you specified change the page aspect ratio. Do you want to " +#~ "print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that the aspect ratio is preserved?" +#~ msgstr "" +#~ "Määratud veerised muudavad lehekülje proportsiooni. Kas soovid trükkida " +#~ "lehekülje muudetud proportsiooniga või kohandada veeriseid, nii et " +#~ "proportsioon säiliks?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Proportsiooni muutmine" + +#~ msgid "Print with specified margins" +#~ msgstr "Trükkimine määratud veeristega" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Trükkimine proportsiooni säilitades ja veeriseid kohandades" diff --git a/po/et/okular_chm.po b/po/et/okular_chm.po new file mode 100644 index 0000000..d1477cb --- /dev/null +++ b/po/et/okular_chm.po @@ -0,0 +1,62 @@ +# translation of okular_chm.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-02-22 16:06+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.08.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@starman.ee" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Toetamata kodeering" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Selle e-raamatu kodeering ei ole veel toetatud. Et see lisataks, esita palun " +"vastav soov KDE vigade jälgimise süsteemis http://bugs.kde.org" + +#~ msgid "CHM Backend" +#~ msgstr "CHM taustaprogramm" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Microsoft Windowsi abifailide renderdaja" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007: Piotr Szymański\n" +#~ "© 2008: Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/et/okular_comicbook.po b/po/et/okular_comicbook.po new file mode 100644 index 0000000..31dc779 --- /dev/null +++ b/po/et/okular_comicbook.po @@ -0,0 +1,57 @@ +# translation of okular_comicbook.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2008, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-11-09 21:05+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.08.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Dokumendi avamine nurjus, ei leitud ei programmi unrar ega unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "Sinu süsteemi programmi unrar versioon ei sobi koomiksite avamiseks." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Tundmatu koomiksivorming." + +#~ msgid "ComicBook Backend" +#~ msgstr "Koomiksite taustaprogramm" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Mitmete koomiksivormingute renderdaja" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008: Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/et/okular_djvu.po b/po/et/okular_djvu.po new file mode 100644 index 0000000..c3faf42 --- /dev/null +++ b/po/et/okular_djvu.po @@ -0,0 +1,139 @@ +# translation of okular_djvu.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-12-01 17:51+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@starman.ee" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Toimetaja" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Kirjastaja" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Köide" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Dokumendi tüüp" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Tundmatu" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Osafailid" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Tundmatu" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Üks lehekülg" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Köidetud" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Kaudne" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Köidetud (vana)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indekseeritud (vana)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu taustaprogramm" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu taustaprogramm, mille aluseks on DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008: Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgid "A DjVu backend" +#~ msgstr "DjVu taustaprogramm" diff --git a/po/et/okular_dvi.po b/po/et/okular_dvi.po new file mode 100644 index 0000000..7ff0880 --- /dev/null +++ b/po/et/okular_dvi.po @@ -0,0 +1,781 @@ +# translation of okular_dvi.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +# Marek Laane , 2009, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-07-18 05:17+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular ei leidnud sinu masinast programmi dvipdfm. See " +"programm on eksportimiseks absoluutselt vajalik. Sellegipoolest saad " +"teisendada DVI-faili PDF-iks Okulari trükkimisfunktsiooni abil, kuid peab " +"arvestama, et see võib tekitada küll väljatrüki jaoks piisava, kuid Acrobat " +"Readeri jaoks inetu väljanägemisega kujutise. Targem oleks uuendada TeXi " +"versiooni, mis sisaldaks ka dvipdfm programmi.

Abiks algajale " +"süsadminnile: Okular kasutab shelli PATH-muutujat programmide otsimisel." + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Väline prorgramm 'dvipdfm', mida kasutati faili eksportimiseks, teatas " +"veast. Võib-olla soovid heita pilgu dokumendi info " +"dialoogile, mille leiad menüüst Fail, nägemaks vea täpset kirjeldust." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Selles DVI-failis on viited välistele graafikafailidele, mida ei leidu " +"PostScript-vormingus ja mida seetõttu ei saa kasutada programm dvips, mida Okular pruugib seesmiselt PostScript-failide trükkimisel või " +"sellesse vormingusse salvestamisel. Seepärast ei ole see funktsionaalsus, " +"mida soovisid, Okulari praeguses versioonis lihtsalt saadaval." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular ei leidnud arvutist programmi dvips. See programm on " +"eksportimiseks hädavajalik.

Abiks algajale süsadminnile: Okular " +"kasutab shelli PATH-muutujat programmide otsimisel.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Väline programm 'dvips', mida kasutati faili eksportimiseks, teatas " +"veast. Võib-olla soovid sa heita pilgu dokumendi info " +"dialoogile, mille sa leiad menüüst Fail, nägemaks vea täpset kirjeldust." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI-fail ei alga preambulaga." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI-fail sisaldab selle rakenduse jaoks vale versiooniga DVI väljundit. " +"Vihje: kui sa kasutad ladumissüsteemi Omega, siis peaksid sa kasutama ka " +"spetsiaalset rakendust, näiteks oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "DVI-fail on täiesti katki. Okular ei suutnud leida postambulat." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Postambula ei alga käsuga POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Postambula sisaldas muud käsku kui FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Leht %1 ei alga BOP-käsuga." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Programmi pdf2ps käivitamine nurjus. Seepärast ei " +"olnud võimalik teisendada PDF-faili %1 PostScript-failiks. Võib juhtuda, et " +"mõningaid dokumendi elemente ei kuvata.

Võimalikud põhjused: " +"programm pdf2ps ei ole vahest süsteemi paigaldatud või siis " +"ei leitud seda kehtivalt otsinguteelt.

Mida teha: programm " +"pdf2ps leidub tavaliselt ghostscripti PostScripti " +"interpraatori paketis. Kui ghostscipt ei ole paigaldatud, võiksid seda teha. " +"Kui oled aga kindel, et ghostscript on paigaldatud, püüa palun kasutada " +"programmi pdf2ps käsurealt ja kontrollida, kas see ikka " +"töötab.

OTSINGUTEE: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

PDF-faili %1 teisendamine PostScript-failiks nurjus. Võib juhtuda, et " +"mõningaid dokumendi elemente ei kuvata.

Võimalik põhjus: fail " +"%1 võib olla katki või ei ole see üldse PDF-fail. See on Okulari kasutatud " +"programmi pdf2ps väljund:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Fail on riknenud. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Sinu dokumenti ei saa põimida kõiki PostScript-faile. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Kõik välised PostScript-failid põimiti sinu dokumenti." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Määratud faili '%1' ei ole olemas." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Sa tahad, et Okular leiaks koha DVI-failis, mis vastab reale %1 TeXi failis " +"%2. Tundub siiski, et see DVI-fail ei sisalda vajalikku infot lähtefaili " +"kohta. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular ei leidnud kohta DVI-failis, mis vastaks reale %1 TeXi failis %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI kood määras tundmatu fondi sümboli." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI koodis on viide fondile #%1, mis on eelnevalt määratlemata." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Pinu ei olnud tühi, kui tuvastati EOP käsk." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Pinu oli tühi, kui tuvastati POP käsk." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI koodis on viide fondile, mis on eelnevalt määratlemata." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Tuvastati lubamatu käsk." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Tuvastati tundmatu opkood %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "%1 põimimine" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Lehekülg %1: PDF-faili %2 ei saa teisendada PostScript-" +"failiks.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Lehekülg %1: PostScript-faili %2 ei leitud.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Paberisuuruse andmete '%1' parsimine nurjus." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular ei leidnud kõiki fondifaile, mis on vajalikud käesoleva DVI-" +"faili näitamiseks. Seetõttu võib dokument olla loetamatu.

OTSINGUTEE: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Tekkis probleeme programmi kpsewhich käivitamisel. Seepärast " +"ei leitud mõningaid fondifaile ja sinu dokument ei pruugi olla loetav.
Võimalikud põhjused: programm kpsewhich ei ole vahest süsteemi " +"paigaldatud või siis ei leitud seda kehtivalt otsinguteelt.

OTSINGUTEE: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Fondi genereerimine kpsewhich'iga katkes (väljuti koodiga %1, " +"viga %2). Seepärast ei suudetud tuvastada mõningaid fondifaile ning dokument " +"ei pruugi olla loetav." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Parasjagu tekitatakse %1 %2 dpi juures..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Autor/Kuupäev" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Fondifaili ei leitud" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "püstpaigutus" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "rõhtpaigutus" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Sinu arvutile paigaldatud Ghostview versioonis ei ole ühtegi Ghostview " +"seadmedraiverit, mida Okular ära tunneks. Seepärast lülitab Okular nüüd " +"PostScripti toetuse välja." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Programm Ghostview, mida Okular kasutab seesmiselt antud DVI-faili " +"kaasatud PostScript-graafika näitamiseks, suudab üldiselt kirjutada oma " +"väljundi mitmes vormingus. Alamprogramme, mida Ghostview selleks kasutab, " +"nimetatakse 'seadmedraiveriteks' ja igale vormingule, mida ghostview oskab " +"kirjutada, on just üks seadmedraiver. Ghostview erinevatel versioonidel on " +"erinev valik seadmedraivereid. Paistab aga, et sinu arvutisse paigaldatud " +"Ghostview versioon ei sisalda mitte ühtegi seadmedraiverit, " +"mida Okular ära tunneks.

On äärmiselt väheusutav, et üks tavaline " +"Ghostview neid draivereid ei sisaldaks. See võib osutada Ghostview väga " +"vigasele paigaldusele sinu arvutis.

Kui soovid seda probleemi " +"parandada, võiksid anda käsu gs --help, mis näitab " +"Ghostview seadmedraiverite nimekirja. Muu hulgas võib Okular kasutada " +"draivereid 'png256', 'jpeg' ja 'pnm'. Pane tähele, et PostScripti toetuse " +"taasrakendamiseks tuleb Okular sulgeda ja taaskäivitada.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Siin on juba 25 viga. Rohkem veateateid ei näidata." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Viga DVI-failis '%1' leheküljel %2. Anti värvi pop-käsk, samas kui värvipinu " +"on tühi." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Vigane parameeter epsf erikäsus.\n" +"Oodati ujukomaarvu järgnemist %1-le %2-s" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Faili ei leitud: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Viga DVI-failis \"%1\" leheküljel %2. Teksti pöördenurga interpreteerimine " +"nurjus." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Erikäsk '%1' ei ole rakendatud." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "Fondifaili %1 võib küll avada, aga selle vorming ei ole toetatud." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "Fondifail %1 on katki või ei saa seda avada ega lugeda." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "FreeType andis teada veast, kui määras fondifailile %1 sümbolisuurust." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType ei suutnud avada fondifaili %2 glüüfi #%1." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType ei suutnud teisendada fondifaili %2 glüüfi #%1." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glüüf #%1 on tühi." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glüüf #%1 fondifailist %2 on tühi." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType ei suutnud avada fondifaili %2 glüüfi #%1 meetrikat." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Fondifaili %1 avamine nurjus." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Sümbol %1 pole defineeritud fondis %2 " + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Ootamatu %1 PK-failis %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Sümbol %1 on liiga suur failis %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Vale arv bitte salvestatud: sümbol %1, font %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Halb pk-fail (%1), liiga palju bitte" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Fondil ei ole ruudukujuline kõrguse/laiuse suhe" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Ei leitud fondi %1 faili %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Fondifaili %1 kontrollsumma ei klapi" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Fondifaili %1 vormingut ei tuntud ära" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Saatuslik viga.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"See tähendab tavaliselt, et sa kas leidsid vea Okularis\n" +"või on DVI-fail või abifailid (näiteks fondifailid \n" +"või virtuaalsed fondifailid) põhjalikult katki.\n" +"Okular lõpetab töö pärast seda teadet. Kui sa arvad, et \n" +"leidsid vea või et Okular peaks sellises olukorras paremini käituma,\n" +"saada palun vearaport." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Vale käsubait VF makro nimekirjas: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI taustaprogramm" + +#~ msgid "A DVI file renderer" +#~ msgstr "DVI-faili renderdaja" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006: Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular kasutab fontide tuvastamisel sinu kõvakettal ja vajaduse korral " +#~ "PK-fontide tekitamiseks programmi kpsewhich.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular tekitab parajasti pikselrasterfonte..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Katkestab fontide tekitamise. Ära tee seda." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular tekitab parajasti pikselrasterfonte, mis on vajalikud sinu " +#~ "dokumendi näitamiseks. Selleks kasutab Okular mõningaid väliseid " +#~ "programme, nagu MetaFont. Sa võid vaadata nende programmide väljundit " +#~ "hiljem dokumendi info dialoogist." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular tekitab fonte. Palun oota." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Fondi genereerimise edenemise dialoog" + +#~ msgid "Abort" +#~ msgstr "Katkesta" + +#~ msgid "What is happening here?" +#~ msgstr "Mis siin toimub?" + +#~ msgid "%v of %m" +#~ msgstr "%v/%m" + +#~ msgid "Please be patient" +#~ msgstr "Palun ole kannatlik" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Faili eksportimine" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Fail %1\n" +#~ "on juba olemas. Kas kirjutada see üle?" + +#~ msgid "Overwrite File" +#~ msgstr "Faili ülekirjutamine" + +#~ msgid "Overwrite" +#~ msgstr "Kirjuta üle" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Dvipdfm kasutamine faili eksportimisel PDF-i" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular kasutab välist programmi 'dvipdfm' sinu DVI-faili teisendamisel " +#~ "PDF-i. Mõnikord võtab see kaua aega, kuna dvipdfm peab tekitama oma " +#~ "pikselrasterfondid. Varu kannatust." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Ootamine, kuni dvipdfm lõpetab..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Dvips kasutamine faili eksportimisel PostScripti" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular kasutab välist programmi 'dvips' sinu DVI-faili teisendamisel " +#~ "PostScripti. Mõnikord võtab see kaua aega, kuna dvips peab tekitama oma " +#~ "pikselrasterfondid. Varu kannatust." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Ootamine, kuni dvips lõpetab..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funktsionaalsus pole saadaval" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Faili viga Okular ei suutnud tõlgendada sinu DVI-" +#~ "faili. Enamasti on selle põhjuseks riknenud fail." + +#~ msgid "DVI File Error" +#~ msgstr "DVI-faili viga" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Kõiki fondifaile ei leitud" + +#~ msgid "Locating fonts..." +#~ msgstr "Fontide otsimine..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Probleem fontide tuvastamisel" + +#~ msgid "Font generation aborted" +#~ msgstr "Fontide tekitamine katkestati" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Eksport: %1 PDF-i" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Eksport: %1 PostScripti" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Fontide nimekiri on praegu tühi." + +#~ msgid "TeX Name" +#~ msgstr "TeXi nimi" + +#~ msgid "Family" +#~ msgstr "Perekond" + +#~ msgid "Zoom" +#~ msgstr "Suurendus" + +#~ msgid "Type" +#~ msgstr "Tüüp" + +#~ msgid "Encoding" +#~ msgstr "Kodeering" + +#~ msgid "Comment" +#~ msgstr "Kommentaar" + +#~ msgid "TeX virtual" +#~ msgstr "TeXi virtuaalne" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX fondimeetrika" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "Mälu eraldamine fondistruktuurile nurjus" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "DVI-faili laadimiseks napib mälu." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "DVI-faili ei suudetud laadida." + +#~ msgid "Checksum mismatch" +#~ msgstr "Kontrollsumma ei klapi" + +#~ msgid " in font file " +#~ msgstr " fondifailis " + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Napib mälu makrode tabeli jaoks." + +#~ msgid "Virtual character " +#~ msgstr "Virtuaalset sümbolit " + +#~ msgid " in font " +#~ msgstr " fondis " + +#~ msgid " ignored." +#~ msgstr " ignoreeriti." + +#~ msgid "Fatal Error" +#~ msgstr "Saatuslik viga" + +#~ msgid "" +#~ "This DVI file contains source file information. You may click into " +#~ "the text with the middle mouse button, and an editor will open the TeX-" +#~ "source file immediately." +#~ msgstr "" +#~ "See DVI-fail sisaldab lähtefaili infot. Kui sa klõpsad tekstile hiire " +#~ "keskmise nupuga, avatakse redaktoris koheselt TeXi lähtefail." + +#~ msgid "Do not show this message again" +#~ msgstr "Seda teadet rohkem ei näidata" + +#~ msgid "Explain in more detail..." +#~ msgstr "Selgita täpsemalt..." + +#~ msgid "" +#~ "File error. The specified file '%1' does not exist. " +#~ "KDVI already tried to add the ending '.dvi'." +#~ msgstr "" +#~ "Faili viga. Osutatud faili '%1' ei ole olemas. KDVI " +#~ "juba proovis lisada laiendit '.dvi'." + +#~ msgid "File Error" +#~ msgstr "Faili viga" + +#~ msgid "Could Not Find Reference" +#~ msgstr "Viidet ei leitud" diff --git a/po/et/okular_epub.po b/po/et/okular_epub.po new file mode 100644 index 0000000..bca58b2 --- /dev/null +++ b/po/et/okular_epub.po @@ -0,0 +1,56 @@ +# translation of okular_epub.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2008, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-02 23:19+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Viga EPubi dokumendi avamisel." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "EPubi taustaprogrammi seadistamine" + +#~ msgid "EPub Backend" +#~ msgstr "EPubi taustaprogramm" + +#~ msgid "An EPub backend" +#~ msgstr "EPubi taustaprogramm" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008: Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/et/okular_fax.po b/po/et/okular_fax.po new file mode 100644 index 0000000..1b4bd10 --- /dev/null +++ b/po/et/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-01 18:03+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Dokumendi laadimine nurjus" + +#~ msgid "Fax Backend" +#~ msgstr "Faksi taustaprogramm" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "G3/G4 faksidokumendi taustaprogramm" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008: Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/et/okular_fictionbook.po b/po/et/okular_fictionbook.po new file mode 100644 index 0000000..e052c8d --- /dev/null +++ b/po/et/okular_fictionbook.po @@ -0,0 +1,96 @@ +# translation of okular_fictionbook.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-02 23:19+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokument ei ole korrektne FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Dokumendi avamine nurjus: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokument ei ole korrektne ZIP-arhiiv" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Vigane dokumendistruktuur (peakataloog puudub)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Dokumendis ei leitud sisu" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Vigane XML-dokument: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "FictionBooki taustaprogrammi seadistamine" + +#~ msgid "Fiction Book Backend" +#~ msgstr "FictionBooku taustaprogramm" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "FictionBooki e-raamatute renderdaja" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008: Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Creator" +#~ msgstr "Looja" + +#~ msgid "Title" +#~ msgstr "Pealkiri" + +#~ msgid "Author" +#~ msgstr "Autor" + +#~ msgid "Producer" +#~ msgstr "Valmistaja" + +#~ msgid "Created" +#~ msgstr "Loodud" diff --git a/po/et/okular_ghostview.po b/po/et/okular_ghostview.po new file mode 100644 index 0000000..fea10a2 --- /dev/null +++ b/po/et/okular_ghostview.po @@ -0,0 +1,124 @@ +# translation of okular_ghostview.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +# Marek Laane , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-04-13 21:17+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Platvormi fontide kasutamine" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Määrab, kas Ghostscript peab kasutama platvormi fonte. Kui pole sisse " +"lülitatud, on lubatud ainult dokumenti põimitud fontide kasutamine." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Üldised seadistused" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Süsteemi fontide kasutamine" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Ghostscripti taustaprogrammi seadistus" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumendi versioon" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Keele tase" + +#~ msgid "PS Backend" +#~ msgstr "PS-i taustaprogramm" + +#~ msgid "A PostScript file renderer." +#~ msgstr "PostScript-failide renderdaja." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008: Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Loodud Spectre teegi põhjal." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "Antialias muudab välimuse ilusamaks, kuid tulemuse saavutamiseks kulub " +#~ "rohkem aega" + +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "&Fontide antialiase lubamine" + +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "Graa&fika antialiase lubamine" + +#~ msgid "" +#~ "Ghostscript is the basic renderer (the program which draws the " +#~ "picture)
\n" +#~ "In case of problems you might want to see its error messages" +#~ msgstr "" +#~ "Renderdamiseks (näidatava kujutise joonistamiseks) on kasutusel " +#~ "Ghostscript
\n" +#~ "Kui tekib probleeme, on võimalik näha veateateid" + +#~ msgid "&Show Ghostscript messages in a separate box" +#~ msgstr "&Ghostscripti teateid näidatakse eraldi kastis" + +#~ msgid "Ghostscript Configuration" +#~ msgstr "Ghostscripti seadistamine" + +#~ msgid "Additional parameters to Ghostscript" +#~ msgstr "Ghostscripti lisaparameetrid" diff --git a/po/et/okular_kimgio.po b/po/et/okular_kimgio.po new file mode 100644 index 0000000..747a4a9 --- /dev/null +++ b/po/et/okular_kimgio.po @@ -0,0 +1,71 @@ +# translation of okular_kimgio.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007. +# Marek Laane , 2009, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2019-11-09 21:07+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.08.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "qiilaq69@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Dokumendi laadimine nurjus: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Dokument tundub olevat moonutatud. Me pakume parimat arusaama, kuidas võiks " +"dokument välja näha algse kavatsuse kohaselt." + +#~ msgid "Image Backend" +#~ msgstr "Piltide taustaprorgramm" + +#~ msgid "A simple image backend" +#~ msgstr "Lihtne piltide taustaprogramm" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009: Albert Astals Cid\n" +#~ "© 2006-2007: Pino Toscano\n" +#~ "© 2006-2007: Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Peamine tööriistariba" diff --git a/po/et/okular_markdown.po b/po/et/okular_markdown.po new file mode 100644 index 0000000..77149bd --- /dev/null +++ b/po/et/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Marek Laane , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-11-09 21:10+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "qiilaq69@gmail.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Dokumendi avamine nurjus" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Markdowni dokumendi kompileerimine nurjus" + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "SmartyPantsi vorminduse lubamine" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Markdowni taustaprogrammi seadistus" diff --git a/po/et/okular_mobi.po b/po/et/okular_mobi.po new file mode 100644 index 0000000..a726bec --- /dev/null +++ b/po/et/okular_mobi.po @@ -0,0 +1,63 @@ +# translation of okular_mobi.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2009, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-06-02 23:20+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Viga Mobipocketi dokumendi avamisel." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Seda raamatut kaitseb DRM ning seda saab näha ainult spetsiaalsetes seadmetes" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Mobipocketi taustaprogrammi seadistamine" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket taustaprogramm" + +#~ msgid "A mobipocket backend" +#~ msgstr "Mobipocketi taustaprogramm" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009: Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/et/okular_plucker.po b/po/et/okular_plucker.po new file mode 100644 index 0000000..b8b97c1 --- /dev/null +++ b/po/et/okular_plucker.po @@ -0,0 +1,46 @@ +# translation of okular_plucker.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-05-26 17:21+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nimi" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Pluckeri dokumendi taustaprogramm" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Pluckeri e-raamatute renderdaja" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008: Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/et/okular_poppler.po b/po/et/okular_poppler.po new file mode 100644 index 0000000..13c90b3 --- /dev/null +++ b/po/et/okular_poppler.po @@ -0,0 +1,245 @@ +# translation of okular_poppler.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +# Marek Laane , 2009, 2010, 2012, 2014, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-11-09 21:13+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.08.1\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "qiilaq69@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Peente joonte täiendamine:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ei" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Ühtlane" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Kuju" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF-i valikud" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Annotatsioonide trükkimine" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Annotatsioonide kaasamine trükitud dokumenti" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Annotatsioonide kaasamine trükitud dokumenti. Selle võib jätta märkimata, " +"kui soovid trükkida algupärast annoteerimata dokumenti." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Rasterdamine jõuga" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasterdamine pildiks enne trükkimist" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Sunnib peale kõigi lehekülgede rasterdamise pildiks enne nende trükkimist. " +"See annab tavaliselt mõnevõrra kehvema tulemuse, aga on abiks dokumentide " +"trükkimisel, mida muidu ei õnnestu korrektselt trükkida." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Sobitamine trükitava alaga" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Sobitamine kogu lehele" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Puudub: trükitakse algsuuruses" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Trükitavate lehtede skaleerimisrežiim" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Skaleerimisrežiim:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Vorming" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Krüptitud" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Krüptimata" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Turvalisus" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Jah" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimeeritud" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Kasutusel on Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Kasutusel on Poppler %1\n" +"\n" +"Ehitatud Poppler %2 peale" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "PDF-i taustaprogrammi seadistamine" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Pole saadaval" + +#~ msgid "PDF Backend" +#~ msgstr "PDF-i taustaprogramm" + +#~ msgid "A PDF file renderer" +#~ msgstr "PDF-faili renderdaja" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008: Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Failide salvestamine krüptimisega ei ole toetatud." + +#~ msgid "Unknown" +#~ msgstr "Tundmatu" + +#~ msgid "Unknown Date" +#~ msgstr "Tundmatu kuupäev" + +#~ msgid "Unknown Encryption" +#~ msgstr "Tundmatu krüpto" + +#~ msgid "Unknown Optimization" +#~ msgstr "Tundmatu optimeerimine" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Palun anna dokumendi lugemiseks vajalik parool:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Vigane parool. Proovi uuesti:" + +#~ msgid "Document Password" +#~ msgstr "Dokumendi parool" + +#~ msgid "" +#~ "The margins you specified are changing the page aspect ratio. Do you want " +#~ "to print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that aspect ratio is preserved?" +#~ msgstr "" +#~ "Määratud veerised muudavad lehekülje proportsiooni. Kas soovid trükkida " +#~ "lehekülje muudetud proportsiooniga või kohandada veeriseid, nii et " +#~ "proportsioon säiliks?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Proportsiooni muutmine" + +#~ msgid "Print with specified margins" +#~ msgstr "Trükkimine määratud veeristega" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Trükkimine proportsiooni säilitades ja veeriseid kohandades" diff --git a/po/et/okular_txt.po b/po/et/okular_txt.po new file mode 100644 index 0000000..9439f69 --- /dev/null +++ b/po/et/okular_txt.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-07-18 05:17+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@smail.ee" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Txt-i taustaprogrammi seadistamine" + +#~ msgid "Txt Backend" +#~ msgstr "Txt-i taustaprogramm" + +#~ msgid "Txt backend." +#~ msgstr "Txt-i taustaprogramm." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013: Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/et/okular_xps.po b/po/et/okular_xps.po new file mode 100644 index 0000000..df55c96 --- /dev/null +++ b/po/et/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to Estonian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2007-2008. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-08-04 23:27+0300\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marek Laane" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bald@starman.ee" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Versioon" + +#~ msgid "XPS Backend" +#~ msgstr "XPS-i taustaprogramm" + +#~ msgid "An XPS backend" +#~ msgstr "XPS-i taustaprogramm" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007: Brad Hards\n" +#~ "© 2007: Jiri Klement\n" +#~ "© 2008: Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/et/org.kde.active.documentviewer.po b/po/et/org.kde.active.documentviewer.po new file mode 100644 index 0000000..9bbde3b --- /dev/null +++ b/po/et/org.kde.active.documentviewer.po @@ -0,0 +1,77 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marek Laane , 2012, 2016, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-11-09 21:17+0200\n" +"Last-Translator: Marek Laane \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.08.1\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Ava ..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Eemalda järjehoidja" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Pane see lehekülg järjehoidjatesse" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Pisipildid" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Sisukord" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Järjehoidjad" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Otsi ..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Tulemusi ei leitud." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Ühtegi dokumenti ei leitud. Lugemise alustamiseks paiguta vähemalt mõned " +#~ "dokumendid oma seadme kataloogi Dokumendid." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Okulari kasutav Plasma Active'i dokumendinäitaja" + +#~ msgid "Reader" +#~ msgstr "Lugeja" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Autoriõigus 2012: Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Avatava faili URL" diff --git a/po/eu/okular.po b/po/eu/okular.po new file mode 100644 index 0000000..dcbe947 --- /dev/null +++ b/po/eu/okular.po @@ -0,0 +1,5548 @@ +# Translation for okular.po to Euskara/Basque (eu). +# Copyright (C) 2003-2018, Free Software Foundation. +# Copyright (C) 2019-2020, This file is copyright: +# This file is distributed under the same license as the okular package. +# KDE euskaratzeko proiektuko arduraduna . +# +# Translators: +# Marcos , 2003, 2005, 2006. +# Ion Gaztañaga , 2005. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2011, 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-27 23:08+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.08.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos,Ion Gaztañaga,Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org,igaztanaga@gmail.com,xalba@euskalnet.net" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, dokumentu erakusle unibertsal bat" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Aurreko mantentzailea" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Azpiegituran lan asko, ODT eta FictionBook bizkarraldekoak" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Garatzailea" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Okular sortu zuen KPDFren sorburu-oinarritik abiatuta" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF garatzailea" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Idatzoharren artelana" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Taula hautatzeko tresna" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Idatzoharretan hobekuntzak" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Joan %1 orrialdera" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Ireki kanpoko fitxategia" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Exekutatu '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Aurreneko orrialdea" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Aurreko orrialdea" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Hurrengo orrialdea" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Azken orrialdea" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Atzera" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Aurrera" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Irten" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Hasi aurkezpena" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Amaitu aurkezpena" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Aurkitu..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Joan orrialdera..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Jo soinua..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript script-a" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Jo filma..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Jo filma" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Gelditu filma" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Eten filma" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Berrekin filma" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Bizkarraldekoaren hautapena" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Bizkarraldeko bat baino gehiago aurkitu da MIME motarentzako:
" +"%1 (%2).

Hautatu zein erabili:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Orri gehienak %1 dira." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Erretratua %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Paisaia %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Bilaketa hasieratik jarraitzea" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Bilaketa bukaeratik jarraitzea" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Ezin da aurkitu pasatu den dokumentua erabiltzeko gauza den pluginik." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Kendu idatzoharrak" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokumentua kanpoko aplikazio bat exekutatzen saiatzen ari da, eta zure " +"segurtasunerako, Okular-ek ez du hau onartzen." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Ez da %1 MIME motako fitxategia irekitzeko aplikaziorik aurkitu." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Ezin izan da aldi baterako fitxategia ireki" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Inprimaketa bihurketak huts egin du" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Inprimatzeko prozesua kraskatu egin da" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Inprimatzeko prozesua ezin izan da abiatu" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Fitxategira inprimatzea huts egin du" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Inprimagailua egoera baliogabean zegoen" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Ezin aurkitu inprimatu beharreko fitxategia" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Ez zegoen inprimatu beharreko fitxategirik" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Ezin izan da inprimatzeko bitar egokirik aurkitu. Ziurtatu CUPSen lpr " +"bitarra eskuragarri dagoela" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Orriaren inprimatze neurria baliogabea da" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Ezin da '%1' ireki. Fitxategia ez dago" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Izenburua" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Gaia" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Azalpena" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Egilea" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Sortzailea" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Ekoizlea" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Orrialdeak" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Sortua" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Aldatua" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME mota" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategoria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Gako-hitzak" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Fitxategiaren bidea-izena" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Fitxategi-neurria" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Orri-neurria" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "gehitu idatzoharra" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "kendu idatzoharra" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "aldatu idatzoharren propietateak" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "itzuli idatzoharra" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "doitu idatzoharra" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "editatu testua" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "editatu idatzoharraren edukia" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "editatu inprimakiaren edukia" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "editatu inprimakiko zerrendaren aukerak" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "editatu inprimakiko konbinatuaren hautapena" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "editatu inprimakiko botoiaren egoerak" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Testu arrunta..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument testua" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Inprimatze aukerak" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Egokitu azalera inprimagarrira" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Egokitu orri osora" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Eskalatze modua:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Alerta mota falta da" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Ez berriz erakutsi mezu hau" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Sorburua: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Letra-tipo &lehenetsia:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Gorria" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Laranja" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Horia" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Berdea" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Zian" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Urdina" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Zuria" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Grisa" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Beltza" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Zabalera %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%%1" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Idatzohar lerroaren zabalera (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Idatzoharraren kolorea (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Idatzohar betegarriaren kolore (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Idatzoharraren opakutasuna (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Idatzoharraren letra-tipoa (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Gehitu uneko idatzoharra idatzohar azkarren menura (Ez da idatzoharrik " +"hautatu)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Mugatu formaren proportzioa 1:1-era edo lerroaren angelua 15ºko urratsetara " +"(Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Uneko idatzohar tresnaren ezarpen aurreratuak (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Idatzohar lerroaren zabalera" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Idatzohar lerroaren zabalera (Ez da idatzoharrik hautatu)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Idatzohar testuaren kolorea" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Idatzohar ertzaren kolorea" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Idatzoharren kolorea" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Idatzohar betegarriaren kolorea" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Idatzohar betegarriaren kolorea (Uneko idatzoharraren betegarriak ez dauka " +"kolorerik)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Idatzoharraren letra-tipoa" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Idatzoharraren letra-tipoa (Uneko idatzoharrak ez dauka letra-tiporik)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Mugatu lerroaren angelua 15ºko urratsetara" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Mugatu formaren proportzioa 1:1-era" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Mugatu formaren proportzioa 1:1-era edo lerroaren angelua 15ºko urratsetara " +"(Uneko idatzoharrak ez du onartzen)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Idatzoharraren opakutasuna" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Gehitu uneko idatzoharra idatzohar azkarren menura" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Uneko idatzohar tresnaren ezarpen aurreratuak" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Kolorea" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Betegarriaren kolorea" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Gardena" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Norberak finkatutako kolorea..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"PDF dokumentuetan txertatutako zigiluak ez dira ikusiko Okular ez beste PDF " +"irakurleetan." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Ezaugarri esperimentala" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Hautatu kolorea" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Idatzoharrak" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Ezkutatu" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Nabarmentzailea" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Azpimarra" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Zirrimarra" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Marratua" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Idazmakina" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Lerro barruko oharra" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Ohar gainerakorra" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Esku hutsezko lerroa" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Lerro zuzena" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Gezia" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Laukizuzena" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipsea" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Poligonoa" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Forma geometrikoak" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Zigilua" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Idatzohar azkarrak" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Hautatu idatzohar-tresna bat idatzohar-azkarren artetik" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Gehitu idatzohar azkarretara" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantendu aktibo" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantendu idatzohar-tresna aktibo erabili ondoren" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Idatzohar-tresnen proportzioaren eta angeluaren muga" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Letra-tipoa" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Idatzoharren ezarpenak" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Lerro zabalera" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opakutasuna" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "%1 orria" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Idatzohar" +msgstr[1] "%1 idatzohar" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Ireki ohar gainerakorra" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Ezabatu" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propietateak" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Gorde '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Itxura" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Orokorra" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Egilea:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Sortze-data:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Aldatze-data:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Ohar gainerakorren propietateak" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Idazmakinaren propietateak" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Lerro barruko oharraren propietateak" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Marra zuzenaren propietateak" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Poligonoaren propietateak" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Geometriaren propietateak" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Testu marken propietateak" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Zigiluaren propietateak" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Esku hutsezko lerroaren propietateak" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Kurtsorearen propietateak" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Fitxategi eranskinaren propietateak" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Soinuaren propietateak" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Filmaren propietateak" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Idatzoharren propietateak" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Aldatua: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Hautatu norberak finkatutako zigilu ikur bat fitxategitik" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Hautatu norberak finkatutako zigilu ikurra" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Ikono fitxategiak (*.ico *.png *.xpm *.svg " +"*.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Ezin izan da zamatu %1 fitxategia" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Fitxategi baliogabea" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Kolorea:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opakutasuna:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Ikonoa:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Iruzkina" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Laguntza" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Txertatu" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Tekla" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Paragrafo berria" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Oharra" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragrafoa" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Letra-tipoa:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Testuaren &kolorea:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Lerrokatu:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Ezkerrera" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Erdian" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Eskuinera" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Ertzaren &zabalera:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Onartua" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Dagoen bezala" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Isilpekoa" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Sailekoa" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Zirriborroa" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Esperimentala" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Amaierakoa" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Iruzkinetarako" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Publikoki ateratzeko" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Onartu gabea" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ez da publikoki ateratzeko" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Saldua" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Sekretu gorenekoa" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Laster-marka" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informazioa" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Eginbide esperimentala.PDF dokumentuetan txertatutako zigiluak " +"ez dira ikusiko Okular ez beste PDF irakurleetan." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Zigiluaren ikurra:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Zabalera:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Lerro hasera:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Lerro bukaera:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Karratua" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Zirkulua" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamantea" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Irekitako gezia" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Itxitako gezia" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Bat ere ez" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Muturra" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Eskuinera irekitako gezia" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Eskuinera itxitako gezia" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra zeiharra" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Lerro nagusiaren luzera:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Lerro nagusiaren hedapenen luzera:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Gaituta" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Formaren betegarria:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Mota:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Nabarmendu" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Zirrimarra" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Azpimarra" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Marratu" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Laukizuzena" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipsea" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Fitxategi eranskinaren ikurra:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafikoa" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Txintxeta" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Paper-klipa" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiketa" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fitxategia" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "E/E" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Ez dago azalpen erabilgarririk." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Izena:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Azalpena:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Kurtsorearen ikurra:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Bat ere ez" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Itxi ohar hau" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Aukerak" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Idatzohar honek LaTeX kodea izan dezake.\n" +"Klik egin hemen errendatzeko." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Ezin aurkitu latex exekutagarria." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX errendatzea huts egin du" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Ezin aurkitu dvipng exekutagarria." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Arazo bat gertatu da 'latex' komandoa exekutatu bitartean." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Arazo bat gertatu da 'dvipng' komandoa exekutatu bitartean." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Laster-marka bat" +msgstr[1] "" +"%1\n" +"\n" +"%2 laster-marka" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Laster-markak" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Bilatu..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Uneko dokumentua soilik" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Joan laster-marka honetara" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Berrizendatu laster-marka" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Kendu laster-marka" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Ireki dokumentua" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Kendu laster-markak" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Bertsioa" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Serie-zenbakia" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Jaulkitzailea" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Noiz jaulkia" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Noiz iraungi" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Gaia" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Gako publikoa" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Gakoaren erabilera" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bit)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propietatea" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Balioa" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Ziurtagiri erakuslea" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Esportatu..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Orokorra" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Nork jaukia" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Izen arrunta (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-posta" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Erakundea(O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Nori jaulkia" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Baliozkotasuna" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Hatz-markak" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1 hatz-marka" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256 hatz-marka" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Zehaztasunak" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Ziurtagiriaren data:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Non gorde nahi duzu ziurtagiri hau?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Ziurtagiri fitxategia (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Ezin izan da ziurtagiria esportatu" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Gorria" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Berdea" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Urdina" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Horia" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Beltza" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Zuria" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Marraztu ertza &irudien inguruan" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Marraztu ertza &esteken inguruan" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Aldatu &koloreak" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Abisua: aukera hauek marrazketa-abiaduran eragin kaltegarria izan dezakete." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Kolore modua:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Alderantzikatu koloreak" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Aldatu paperaren kolorea" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Aldatu kolore ilunak eta ar&giak" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Bihurtu &zuri-beltzera" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Alderantzikatu argitasuna" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Alderantzikatu luma (sRGB lineala)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Alderantzikatu luma (simetrikoa)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Tonu aldaketa positiboa" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Tonu aldaketa negatiboa" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Paperaren kolorea:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Kolore iluna:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Kolore argia:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Atalasea:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrastea:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Hizketa" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motorra" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Nortasuna" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "&Egilea:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Oharra: hemengo informazioa soilik idatz-oharretarako erabiltzen da. " +"Informazioa oharren dokumentuetan gordetzen da, eta horrela transmitituko da " +"dokumentuarekin batera." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Idatzohar azkarretarako tresna" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Norberak finkatutako editorea" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs bezeroa" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx bezeroa" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Ezarri komandoa jaurti beharreko norberak finkatutako testu editorera." +"
\n" +"Leku marka gutxi batzuk ere ipini ditzakezu:\n" +"
    \n" +"
  • %f - fitxategi-izena
  • \n" +"
  • %l - heldu beharreko fitxategiko lerroa
  • \n" +"
  • %c - heldu beharreko fitxategiko zutabea
  • \n" +"
\n" +"%f ez bada zehazten, fitxategi-izena eransten zaio zehaztutako komandoari." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editorea" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editorea:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Aukeratu Okularrek sorburu fitxategi bat ireki nahi duenean jaurti nahi " +"duzun editorea." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Komandoa:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Itxura" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Erabili kiribiltze leuna" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Erakutsi &labaintzeko-barrak" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Estekatu koadro &txikiak orriarekin" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Erakutsi &argibideak eta informazio-mezuak" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Azaldu dokumentuaren titulua titulu-barran" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Dokumentu titulurik azaltzen ez duenean:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Azaldu fitxategi-izena soilik" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Azaldu fitxategiaren bide-izen osoa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Erabili norberak finkatutako atzealdeko kolorea" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Programaren eginbideak" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Ireki fitxategi berriak fi&txetan" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Aldatu existitzen den fitxara fitxategia jada irekita dagoenean" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Men egin DRMren mugei" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Birzamatu dokumentua fitxategia aldatzean" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Erakutsi bizkarraldeko hautapenerako elkarrizketa-koadroa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Eskuinetik ezkerrera irakurtze noranzkoa" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Ikuspegiaren aukerak" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Ikuspegi orokorraren &zutabeak:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Zehazten du unean ikusten den azaleraren zenbateko zatia ikusiko den Orri " +"Gora/Orri Behera sakatzean." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Orri Gora/Behera gainezartzea:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Aurrez inoiz ireki gabeko fitxategien zoom modu lehenetsia zehazten du.\n" +"Aurrez ireki diren fitxategiekin aurreko zooma erabiltzen da." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Aurrez inoiz ireki gabeko fitxategien zoom modu lehenetsia zehazten du.\n" +"Aurrez ireki diren fitxategiekin aurreko zooma erabiltzen da." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Zoom &lehenetsia:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "% 100" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Doitu zabalera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Doitu orrialdea" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Doitu automatikoki" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Erabilitako memoria ahalik apalen mantentzen du. Ez berrerabili ezer ez " +"(memoria urriko sistementzat)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Memoria erabilera eta abiadura irabazkinaren arteko oreka on bat. Aurre-" +"zamatu hurrengo orria eta bizkortu bilaketak. (2GB memoria duten " +"sistementzat)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Dena memorian mantentzen du. Aurre-zamatu hurrengo orriak. Bizkortu " +"bilaketak. (4GB memoria baina gehiago duten sistementzat)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Guztia memorian zamatu eta mantentzen du. Orri guztiak aurre-zamatu. " +"(Gehienez zure memoria osoaren % 50 edo zure memoria askea erabiliko du, " +"bietan handiena dena)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "PUZaren erabilera" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Gaitu garden&tasun-efektuak" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Memoriaren erabilera" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Apala" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "A&rrunta (lehenetsia)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Kementsua" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "Asee&zina" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Errendatzea" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Gaitu testuaren ertzak-leuntzea" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Gaitu grafikoen ertzak-leuntzea" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Gaitu testuen gaineko iradokizunak" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Uneko pantaila" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Pantaila lehenetsia" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "%1 pantaila" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " segundo" +msgstr[1] " segundo" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Nabigatzea" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Aurreratu hainbatero:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Begiztatu azken orriaren ondoren" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Ukimen nabigatzea:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Egin tak ezker/eskuin aldean atzera/aurrera joateko" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Egin tak edonon aurrera joateko" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Ezgaituta" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Atzealdeko kolorea:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Saguaren kurtsorea:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Ezkutatu atzerapenaren ondoren" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Beti ikusgai" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Beti ezkutatuta" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Erakutsi aurrera&penaren adierazlea" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Erakutsi lab&urpen-orria" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Gaitu trantsizioak" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Trantsizio lehenetsia:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Pertsiana bertikalak" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Pertsiana horizontalak" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Estali barrurantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Estali kanporantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Disolbatu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Desagertu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Sartu behetik" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Sartu eskuinetik" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Sartu eskuin-behetik" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Ausazko trantsizioa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Ordeztu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Zatitu horizontalki barnerantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Zatitu horizontalki kanporantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Zatitu bertikalki barnerantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Zatitu bertikalki kanporantz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Ekortu behera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Ekortu eskuinera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Ekortu ezkerrera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Ekortu gora" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Kokapena" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Pantaila:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Marrazteko trena konfiguratzea" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Marrazteko tresna: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Ezabagoma" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Izena:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Mota:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Ohar gainerakorra" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Lerro barruko oharra" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Esku hutsezko lerroa" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Marra zuzena" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Poligonoa" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Testu markatzea" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geometrikoa" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Zigilua" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Idazmakina" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Idatzoharrak sortzeko tresna" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Idatzoharrak editatzeko tresna" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Kolorea:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Bolalumaren zabalerara:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Marrazkia sortzeko tresna" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Marrazkia editatzeko tresna" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Ezezaguna" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Kapsulatuko fitxategiak" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Ikuspegia" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Izena" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Azalpena" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Neurria" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Sortua" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Aldatua" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Gorde honela..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Ikuspegia..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Ezin izan da zamatu inprimatzeko aurreikuspegiaren zatia" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Inprimatze aurreikuspegia" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Itxi" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Bilatu:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Bilatu beharreko testua" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Hurrengoa" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Joan hurrengo bat-etortzera" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Aurrekoa" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Joan aurreko bat-etortzera" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Aldatu bilaketaren jokabidea" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Bereizi maiuskulak" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Uneko orrialdetik" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Aurkitu idatzi ahala" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Fitxategi guztiak" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Sinaduraren propietateak" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Lerro zuzena iruzkinarekin" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Poligonoa iruzkinarekin" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometria iruzkinarekin" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Nabarmentzea iruzkinarekin" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Zirrimarra iruzkinarekin" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Azpimarra iruzkinarekin" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Marratua iruzkinarekin" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Marratua" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Zigilua iruzkinarekin" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Esku hutsezko lerroa iruzkinarekin" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Kurtsorea" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Fitxategi eranskina" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Soinua" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Filma" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Pantaila" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Trepeta" + +# xalba 2018-08-04 lr: Testuinguruan egokia izango den zalantza. +# +# Rich media: Euskarri aberastua +# +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Euskarri aberastua" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Ezezaguna" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Egilea: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Non gorde nahi duzu %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Ezin izan da \"%1\" idazteko ireki. Fitxategia ez da gorde." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Bilaketa aukerak" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Bereizi maiuskulak" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Adierazpen erregularra" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Bilatu:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Geruzak" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr " / " + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom % 100era" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Biratu e&skuinera" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Eskuinera" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Biratu e&zkerrera" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Ezkerrera" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Jatorrizko orientazioa" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Moztu ikuspegia" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Moztu marjinak" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Moztu &hautapenera" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Doitu &zabalera" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Doitu &orrialdea" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "Doitze &automatikoa" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Doitu &leihoa orrialdera" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "%Ikuspegi modua" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Orrialde &bakarra" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "&Aurrez-aurreko orrialdeak" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Aurrez-aurreko orrialdeak (&erdiratu aurreneko orrialdea)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Ikuspegi &orokorra" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Jarraia" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Erabili eskuinetik ezkerrera irakurtzeko noranzkoa" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Arakatu" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "&Txandakatu aldatu koloreak" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Azalera &hautapena" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Testu hautapena" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "T&aula hautapena" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lupa" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Hautapen tresnak" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Hitz egin dokumentu osoa" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Hitz egin uneko orrialdea" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Gelditu hitz egitea" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Eten/Berrekin hizketa" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Labaindu gora" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Labaindu behera" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Labaindu orri gora" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Labandu orri behera" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Erakutsi inprimakiak" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Orri bakarreko dokumentua zamatu da." +msgstr[1] " %1 orriko dokumentua zamatu da." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Testua (karaktere 1)" +msgstr[1] "Testua (%1 karaktere)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopiatu arbelera" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopiatzea DRMak debekatu du" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Hitz egin testua" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Irudia (%1 x %2 pixel)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Gorde fitxategira..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Irudia [%1x%2] arbelera kopiatu da." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Gorde fitxategia" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Irudiak (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Fitxategia ez da gorde." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Irudia [%1x%2] %3 fitxategira gorde da." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopiatu testua" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Joan '%1'(e)ra" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Bilatu '%1' honekin" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Konfiguratu web lasterbideak..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Jarraitu esteka honi" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Jo soinu hau" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Gelditu soinua" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopiatu estekaren helbidea" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Bilatu '%1' dokumentu honetan" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Ongi etorri" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Hautatu zoomaren azalera. Eskuineko-klik zooma urruntzeko." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Klik egin handitutako ikuspegia ikusteko." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Marraztu laukizuzen bat kopiatu beharreko testuen/grafikoen inguruan." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Hautatu testua" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Marraztu laukizuzen bat taularen inguruan, ondoren klik egin ertzen ondoan " +"erdibitzeko; sakatu «Ihes» garbitzeko." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Marraztu laukizuzen bat ikusgai izan nahi duzun orrialde azaleraren inguruan" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Testu-ohar berria" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Ohar berriaren testua:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Gehitu idatzoharraren laster-marka" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Txertatu idatzoharrarentzat norberak finkatutako izen bat:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Marraztu elipse bat (arrastatu eskualde bat hautatzeko)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Nabarmendu testua" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Marraztu esku hutsezko lerro bat" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Lerro barruko testu idatzoharra (arrastatu eskualde bat hautatzeko)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Ipini ohar gainerakor bat" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Marraztu poligono bat (klik egin aurreneko puntuan hura ixteko)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Marraztu laukizuzen bat" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Zirrimarra testua" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Ipini zigilu ikur bat" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Marraztu lerro zuzen bat" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Marratu testua" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Azpimarratu testua" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Idazmakinaren idatzoharra (arrastatu eskualde bat hautatzeko)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Nabarmentzailea" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Gehitu gogoko idatzoharra" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Norberak finkatutako idatzohar-izena:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fitxategia" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "E&zarpenak" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Laguntza" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientazioa" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "Laster-&markak" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Erakuslearen tresna-barra" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Koadro txikiak" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Idatzoharrak" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Dokumentu honek Okularren aurreko bertsio batekin barnean gordetako " +"idatzoharrak edo inprimaki datuak ditu. Barnean gordetzea ez da onartzen " +"dagoeneko.
Gorde fitxategi batera haiek lekuz aldatzeko dokumentua " +"editatzen jarraitu nahi baduzu." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Dokumentu honek kapsulatutako fitxategiak ditu. Klik egin hemen horiek ikusteko edo joan 'Fitxategia -> " +"Kapsulatutako fitxategiak' menura." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Aurrekoa" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Itzuli aurreko orrialdera" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Dokumentuaren aurreko orrialdera joaten da" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Hurrengoa" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Aurreratu hurrengo orrialdera" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Dokumentuaren hurrengo orrialdera joaten da" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Dokumentuaren hasiera" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Dokumentuaren hasierara joaten da" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Dokumentuaren bukaera" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Dokumentuaren bukaerara joaten da" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Berrizendatu uneko laster-marka" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Aurreko laster-marka" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Joan aurreko laster-markara" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Hurrengo laster-marka" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Joan hurrengo laster-markara" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Konfiguratu Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Konfiguratu erakuslea..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Konfiguratu erakuslearen bizkarraldekoak..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Konfiguratu bizkarraldekoak..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Bizkarraldekoari buruz" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Birzama&tu" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Birzamatu uneko dokumentua diskotik." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Itxi &bilatzeko-barra" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Orrialde zenbakia" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Hautatu uneko orrialdeko testu guztia" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Erakutsi a&lboko barra" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Erakutsi &Orrialde barra" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Erakutsi &sinadura panela" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Kapsulatutako fitxategiak" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&sportatu honela" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Partekatu" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "Au&rkezpena" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Ireki hau &barnean duen karpeta" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Inportatu PostScript PDF gisa..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Lortu liburuak Internetetik..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Aldatu pantaila-beltz modura" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Ezabatu marrazkia" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Konfiguratu idatzoharrak..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Jo/eten aurkezpena" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Ezin izan da '%1' (%2) ireki" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "%1 zamatzea galarazi da." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Ezin izan da %1 ireki. Arrazoia: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Konfiguratu erakuslearen bizkarraldekoak" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Konfiguratu bizkarraldekoak" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"\"ps2pdf\" programa ez da aurkitu, beraz, Okularrek ezingo du PS " +"fitxategirik inportatu hura erabiliz." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf ez da aurkitu" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript fitxategiak (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "PS fitxategia PDF gisa inportatzea (denbora pixka bat beharko du)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Sartu dokumentua irakurtzeko pasahitza:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Pasahitz okerra. Saiatu berriz:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Dokumentuaren pasahitza" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "Dokumentu honek XFA inprimakiak ditu, jada ez dira onartzen." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Dokumentu honek inprimakiak ditu. Klik egin botoian haiekin aritzeko, edo " +"erabili «Ikuspegia -> Erakutsi inprimakiak» menutik." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Dokumentu hau editatzeko eta elkarreragiteko eginbide guztiak ezgaituta " +"daude. Gorde kopia bat eta berrireki dokumentua editatzeko." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Dokumentu hau digitalki sinatua dago." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Dokumentu hau digitalki sinatuta dago. Aldaketak egin dira azken sinaduratik." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Dokumentu hau digitalki sinatuta dago. Sinaduretako batzuk ezin izan dira " +"baliozkotu." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Dokumentu honek pantaila-betean erakutsia izan nahi du.\n" +"Modu arrunta utzi eta aurkezpen moduan sartu?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Eskatu ikusteko modua aldatzea" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Sartu aurkezpen moduan" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Ukatu eskaera" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Ezin izan da ireki %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Gorde gabeko aldaketak daude, eta beste programa batek '%1' fitxategia " +"aldatu du. Zure aldaketak galduko dira, fitxategia jada ezin delako gorde. " +"
Fitxategia birzamatuta jarraitu nahi duzu?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Fitxategia aldatu da" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Jarraia birzamatuta" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Galarazi birzamatzea" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Gorde gabeko aldaketak daude, eta beste programa batek '%1' fitxategia " +"aldatu du. Zure aldaketak galduko dira, fitxategia jada ezin delako gorde. " +"
Fitxategia itxita jarraitu nahi duzu?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Jarraitu ixtea" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Galarazi ixtea" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Zure aldaketak \"%1\"(e)ra gorde edo baztertu nahi dituzu?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Itxi dokumentua" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Esteka hau dokumentua ixteko ekintza bati lotuta dago eta eginbide hau ezin " +"da erabili erakusle kapsulatua darabilgunean." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Esteka hau aplikazioa irteteko ekintza bati lotuta dago eta eginbide hau " +"ezin da erabili erakusle kapsulatua darabilgunean." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Dokumentua birzamatzen..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Edukia" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Sinadurak" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Joan orrialdera" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Orria:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Sartu laster-markaren izen berria:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Berrizendatu laster-marka hau" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Kendu laster-marka hau" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Gorde honela" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"'%1' fitxategia beste programa batek aldatu du, horrek esan nahi du ezin " +"dela gorde jada." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Uneko dokumentua pasahitz batekin babestua dago.
Gorde ahal izateko, " +"fitxategia birzamatu egin behar da. Berriz eskatuko zaizu pasahitza eta zure " +"desegite/berregite historia galduko da.
Jarraitu nahi duzu?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Gorde - Abisua" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Ezin izan da aldi baterako fitxategia gordetzeko ireki." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Gorde ondoren, uneko dokumentuaren formatuak fitxategia birzamatzea eskatzen " +"du. Zure desegite/berregite historia galduko da.
Jarraitu nahi duzu?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Fitxategia ezin izan da gorde '%1'(e)n. Saiatu beste kokaleku batean " +"gordetzen." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Betetako inprimakiaren edukia" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Erabiltzailearen idatzoharrak" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Aldaketak gordetzera zoaz, baino uneko fitxategiaren formatuak ez du " +"onartzen ondoko elementuak gordetzea. Erabili Okular dokumentu artxibo formatua haiek ez galtzeko." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Abisua" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Gorde Okular dokumentu artxibo gisa..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Aldaketak gordetzera zoaz, baino uneko fitxategiaren formatuak ez du " +"onartzen ondoko elementuak gordetzea. Erabili Okular dokumentu artxibo formatua haiek ez galtzeko. Klik egin Jarraitu dokumentua gorde " +"eta elementu hauek baztertzeko." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Aldaketak gordetzera zoaz, baino uneko fitxategiaren formatuak ez du " +"onartzen ondoko elementuak gordetzea. Erabili Okular dokumentu artxibo formatua haiek ez galtzeko. Klik egin Jarraitu gordetzeko, baino " +"elementu hauek galduko dituzu baita desegiteko/berregiteko historia ere." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Jarraitu" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Jarraitu aldaketak galduta" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Fitxategia ezin izan da '%1'-(e)n gorde. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okularrek ezin du %1 kopiatu zehaztutako kokalekura.\n" +"\n" +"Dokumentua betirako joan da." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Fitxategia ezin izan da '%1'-(e)n gorde. Errorea: '%2'. Saiatu beste " +"kokaleku batean gordetzen." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Zabaldu atal osoa" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Tolestu atal osoa" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Zabaldu guztiak" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Tolestu guztia" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Gehitu laster-marka" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Tresnak" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Inprimatu" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Dokumentu hau inprimatzea ez da onartzen." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Ezin izan da dokumentua inprimatu. Errore ezezaguna. Mesedez honen berri " +"eman hemen: bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Ezin izan da dokumentua inprimatu. Errore zehatza \"%1\" da. Mesedez honen " +"berri eman hemen: bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Joan lehen zeunden lekura" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Joan ondoren zeunden lekura" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Fitxategi errorea! Ezin izan da aldi baterako " +"%1 fitxategia sortu." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Fitxategi errorea! Ezin izan da %1 fitxategia deskonprimitzeko ireki. Fitxategia ez da zamatuko." +"" + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Errore hau gertatu ohi da fitxategia irakurtzeko behar adinako baimenik " +"ez duzunean. Jabetza eta baimenak egiaztatu ditzakezu Dolphin fitxategi " +"kudeatzailean fitxategiari eskuin-klik egin, 'Propietatek' aukera hautatu, " +"eta irekitzen den leihoan 'Baimenak' fitxara joanda." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Fitxategi errorea! ezin izan da %1 fitxategia deskonprimitu. Fitxategia ez da zamatuko." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Errore hau gertatu ohi da fitxategia hondatuta dagoenean. Ziur egon nahi " +"baduzu, saiatu fitxategia eskuz deskonprimitzen komando-erroko tresnak " +"erabiliz." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Laster-markarik ez" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Arazoa bat egon da dokumentua partekatzean: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Partekatu" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Dokumentu partekatze arrakastatsua" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Partekatutako dokumentua hemen aurkituko duzu: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Editatu" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Ikuspegia" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Joan" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Tresnak" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Tresna-barra nagusia" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Idatzoharren tresna-barra" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Aukera orrokorrak" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Irisgarritasuna" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Irisgarritasuneko irakurtzeko laguntzak" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Performantzia" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Performantzia doitzea" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Konfiguratu erakuslea" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Aurkezpena" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Aurkezpen modurako aukerak" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Idatzoharren aukerak" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Editorearen aukerak" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Bilatu hurrengoa" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Aurkezpena" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Aldatu pantaila" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "%1 pantaila" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Irten aurkezpen modutik" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Izenburua: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Orrialdeak: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klik egin hasteko" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Eten" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Jo" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Bi bide daude aurkezpen modutik irteteko, «Ihes» tekla saka dezakezu edo " +"klik egin sagua goi-eskuin izkinan ipintzean agertzen den «Irten» botoiari. " +"Noski, leihoen artean alda dezakezu (Alt+Tab lehenetsia)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Aurkezpena ematea" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Fitxategi ezezaguna" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1(r)en propietateak" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Letra-tipoak" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Letra-tipoaren informazioa irakurtzen..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "&Orri-neurriak" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Erauzi letra-tipoa" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "1 tipografia" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "1C tipografia" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "1C (OT) tipografia" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "3 tipografia" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID 0 tipografia" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID 0C tipografia" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID 0C (OT) tipografia" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX alegiazkoa" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX letra-tipoaren metrika" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType kudeatua" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Ezezaguna" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Kapsulatua (azpimultzoa)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Erabat kapsulatua" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ez" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Bai (azpimultzoa)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Bai" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (%2-(r)ekin ordezkatzea)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[e/e]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Letra-tipo ezezaguna" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Kapsulatua: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Izena" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipografia" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fitxategia" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Orria" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Neurria" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Berrikuspen aurreikuspegia" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Non gorde nahi duzu berrikuspen hau?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Ezin izan da gorde %1fitxategia." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Ezin izan da ikusi berrikuspena." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Sartu gutxienez 3 letra orriak iragazteko" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Bereizi maiuskulak" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Esaldiarekin bat-etortzea" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Hitz guztiekin bat-etortzea" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Edozein hitzekin bat-etortzea" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Iragazte aukerak" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Idatzoharrik ez

Idatzohar berriak sortzeko sakatu " +"F6 edo hautatu Tresnak -> Idatzoharrak menutik.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Elkartu orrialdeka" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Elkartu egilearen arabera" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Erakutsi soilik uneko orriko idatzoharrak" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Zabaldu elementu guztiak" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Tolestu elementu guztiak" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Sinadura kriptografikoki baliozkoa da." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Sinadura kriptografikoki baliogabea da." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Laburpen parekatze okerra." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Sinaduraren CMS/PKCS7 egitura gaizki osatua dago." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Eskatutako sinadura ez dago dokumentuan." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Sinadura ezin izan da egiaztatu." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Ziurtagiri honek konfiantza du. " + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Ziurtagiri jaulkitzaileak ez du konfiantzarik." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Ziurtagiri jaulkitzailea ezezaguna da." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Ziurtagiria indargabetu egin da." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Ziurtagiria iraungi egin da." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Ziurtagiria ez da oraindik egiaztatu." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Ziurtagiriarekin arazo ezezaguna edo datuak hondatuta." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algoritmoa ezezaguna" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Mota ezezaguna" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Sinadura digitala" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Nahitaezko onarpena" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Zifratzeko gakoak" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Deszifratzeko gakoak" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Gako kudeaketa" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Sinadura ziurtagiria" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Sinadura CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Zifratu soilik" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Ez da erabilera zehatu" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Berik. %1: %2-k sinatua" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Sinatze ordua: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Ez erabilgarria" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Arrazoia: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Eremua: %1 %2 orrian" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propietateak" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Dokumentua ez da aldatu sinatu zenetik." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"sinadura honek estaltzen duen dokumentu honen berrikuspena ez da aldatu;\n" +"hala ere dokumentuak geroztiko aldaketak izan ditu." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Dokumentua aldatu egin da aurreko sinatzaileak uzten ez zuen era batean." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Dokumentuaren osotasun egiaztapena ezin izan da osatu." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Baliozkotasun egoera" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Sinaduraren baliozkotasuna:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Dokumentuaren aldaketak:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Informazio osagarria" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Nor sinatua:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Sinatze ordua:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Zergatia:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Kokalekua:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Dokumentu bertsioa" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Dokumentu berrikuspena %1/%2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Ikusi sinatutako bertsioa..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Ikusi ziurtagiria..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Erakutsi laster-marka ipinitako orriak soilik" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Jo" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Eten" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Gelditu" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Gehitu..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Editatu..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Kendu" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Eraman &gora" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Eraman &behera" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Marrazteko tresna lehenetsia #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" +"Lehendik ere badago izen hori duen tresna bat. Lehenetsitako bat erabiliko da" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Bikoiztutako izena" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Erakutsi beharreko dokumentuko orrialdea" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Abiatu dokumentua aurkezpen moduan" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Abiatu inprimatze elkarrizketa-koadroarekin" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Abiatu inprimatze elkarrizketa-koadroarekin eta itxi inprimatu ondoren" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "\"Instantzia bakarra\" kontrola" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Ez goratu leihoa" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Aurkitu kate bat testuan" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"Ireki beharreko dokumentuak. Zehaztu '-' sarrera estandarretik (stdin) " +"irakurtzeko." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Errorea: Ezin da dokumentu bat baino gehiako ireki --unique etengailuarekin" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Errorea: Ezin da dokumentu bat baino gehiago ireki --presentation " +"etengailuarekin" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Errorea: Ezin da dokumentu bat baino gehiago ireki --print etengailuarekin" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Errorea: Ezin da dokumentu bat baino gehiago ireki --page etengailuarekin" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Errorea: Ezin da dokumentu bat baino gehiago ireki --find etengailuarekin" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Ezin da aurkitu Okularren osagaia: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Dagoeneko Okularren instantzia bakar bat martxan dago. Instantzia hau ez da " +"izango 'bakarra'." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Ezin da Okularren osagaia aurkitu." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Egin klik fitxategi bat irekitzeko\n" +"Egin klik eta eutsi oraintsuko fitxategi bat irekitzeko" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klik egin fitxategi bat irekitzeko edo Klik egin eta eutsi " +"oraintsuko fitxategi bat hautatzeko" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Hurrengo fitxa" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Aurreko fitxa" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Desegin fitxa ixtea" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Fitxategi guztiak (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Onartutako fitxategi guztiak (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Ireki dokumentua" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Berretsi ixtea" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Itxi fitxak" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "%1 fitxa ixtera zoaz. Ziur zaude jarraitu nahi duzula?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Abisatu niri fitxa ugari ixten saiatzen naizenean" + +#~ msgid "Reviews" +#~ msgstr "Berrikuspenak" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Ezkutatu inprimakiak" + +#~ msgid "Expired" +#~ msgstr "Iraungitua" + +#~ msgid "&Review" +#~ msgstr "&Berrikusi" + +#~ msgid "Annotations author" +#~ msgstr "Idatzoharren egilea" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Sartu zure izena edo inizialak:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Erakutsi &nabigatzeko panela" + +#~ msgid "Show Text" +#~ msgstr "Erakutsi testua" + +#~ msgid "Small Icons" +#~ msgstr "Ikono txikiak" + +#~ msgid "Normal Icons" +#~ msgstr "Ikono arruntak" + +#~ msgid "Large Icons" +#~ msgstr "Ikono handiak" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Egin klik uneko hautapen tresna erabiltzeko.\n" +#~ "Egin klik gezian beste tresna bat aukeratzeko" + +#~ msgid "Created: %1" +#~ msgstr "Sortua: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Lerroaren hedapenak" + +#~ msgid "Style" +#~ msgstr "Estiloa" + +#~ msgid "&Size:" +#~ msgstr "&Neurria:" + +#~ msgid "Inner color:" +#~ msgstr "Barneko kolorea:" + +#~ msgid "Name: %1" +#~ msgstr "Izena: %1" + +#~ msgid "Size: %1" +#~ msgstr "Neurria: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Arakatze tresna" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Zoom tresna" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Hautapena" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Testu hautapen tresna" + +#~ msgid "T&able Selection Tool" +#~ msgstr "T&aula hautatzeko tresna" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Lupa" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Dokumentuaren bukaera" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Bat ere ez" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Eskatutako dokumentua aurkezpen moduan irekiko da.\n" +#~ "Nahi duzu baimentzea?" + +#~ msgid "Presentation Mode" +#~ msgstr "Aurkezpen modua" + +#~ msgid "Allow" +#~ msgstr "Baimendu" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Baimendu aurkezpen modua" + +#~ msgid "Do Not Allow" +#~ msgstr "Ez baimendu" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Ez baimendu aurkezpen modua" + +#~ msgid "Save &Copy As..." +#~ msgstr "Gorde &kopia honela..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Dokumentuaren amaierara iritsi da.\n" +#~ "Jarraitu hasieratik?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Dokumentuaren hasierara iritsi da.\n" +#~ "Jarraitu amaieratik?" + +#~ msgid "Current maintainer" +#~ msgstr "Uneko mantentzailea" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid " sec." +#~ msgstr " seg." + +#~ msgid "Pencil color:" +#~ msgstr "Arkatzaren kolorea:" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Txandakatu marrazketa modua" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Jovie testutik-hizketara zerbitzua abiarazteak huts egin du: %1" + +#~ msgid "Search Columns" +#~ msgstr "Bilatu zutabeak" + +#~ msgid "All Visible Columns" +#~ msgstr "Zutabe ikusgai guztiak" + +#~ msgid "No document opened." +#~ msgstr "Ez da dokumenturik ireki." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Ez da bat-egiterik aurkitu \"%1\"-(r)rentzat." + +#~ msgid "Search in progress..." +#~ msgstr "Bilaketaren aurrerapena..." + +#~ msgid "Searching for %1" +#~ msgstr "%1 bilatzen" + +#~ msgid "Identity Settings" +#~ msgstr "Identitatearen ezarpenak" + +#~ msgid "Highlight Properties" +#~ msgstr "Nabarmentzearen propietateak" + +#~ msgid "Ink Properties" +#~ msgstr "Tintaren propietateak" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Testuaren oharra" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Tinta berdea" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Nabrmentzaile horia" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Nabrmentze horia" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Marra horia zuzena" + +#~ msgid "Black Underlining" +#~ msgstr "Azpimarra beltza" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Azpimarratu testua marra beltzarekin" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Elipse cyana" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Elipse cyana" + +#~ msgid "Ink" +#~ msgstr "Tinta" + +#~ msgid "Enable &background generation" +#~ msgstr "Gaitu &atzeko planoaren sorrera" + +#~ msgid "Reset Forms" +#~ msgstr "Berrezarri formularioak" + +#~ msgid "latex failed." +#~ msgstr "latex-ek huts egin du." + +#~ msgid "dvipng failed." +#~ msgstr "dvipng-ek huts egin du." + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Dokumentuaren lehenengo orrialdera joaten da" + +#~ msgid "You must set this name:" +#~ msgstr "Izen hau ezarri behar duzu:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Gainidatzi" + +#~ msgid "Pages:" +#~ msgstr "Orrialdeak:" + +#~ msgid "Green Highlighter" +#~ msgstr "Nabrmentzaile berdea" diff --git a/po/eu/okular_chm.po b/po/eu/okular_chm.po new file mode 100644 index 0000000..c0eb2f9 --- /dev/null +++ b/po/eu/okular_chm.po @@ -0,0 +1,64 @@ +# Translation of okular_chm.po to Euskara/Basque (eu). +# Copyright (C) 2009-2020, This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-02-22 23:04+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.12.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe,Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org,xalba@euskalnet.net" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Onartzen ez den kodeketa" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"eLiburuki honen kodeketa oraindik ez da onartzen. Sortu akats txosten bat " +"adierazitako helbidean euskarria gehitu dakion, https://bugs.kde.org" + +#~ msgid "CHM Backend" +#~ msgstr "CHM motorra" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Microsoft Windows errendatzailearen laguntzako fitxategia" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/eu/okular_comicbook.po b/po/eu/okular_comicbook.po new file mode 100644 index 0000000..631c46f --- /dev/null +++ b/po/eu/okular_comicbook.po @@ -0,0 +1,62 @@ +# Translation of okular_comicbook.po to Euskara/Basque (eu). +# Copyright (C) 2019, This file is copyright: +# This file is distributed under the same license as the okular package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-06-24 10:30+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.04.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Ezin da dokumentua ireki, ez da «unrar» ez eta «unarchiver» ere aurkitu." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "Sisteman dagoen unrar bertsioa ez da egokia komikiak irekitzeko." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Komikiaren formatua ezezaguna." + +#~ msgid "ComicBook Backend" +#~ msgstr "Komikien motorra" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Hainbat komiki-formaturen errendatzaile bat" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eu/okular_djvu.po b/po/eu/okular_djvu.po new file mode 100644 index 0000000..ad265ab --- /dev/null +++ b/po/eu/okular_djvu.po @@ -0,0 +1,141 @@ +# Translation of okular_djvu.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2018-08-03 15:24+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editorea" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Argitaratzailea" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Bolumena" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Dokumentu mota" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Ezezaguna" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Osagai fitxategiak" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Ezezaguna" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Orri bakarra" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Sorta" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Zeharkakoa" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Sorta (zaharra)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexatuta (zaharra)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu motorra" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu motorra, DjVuLibre-n oinarrituta dago." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" diff --git a/po/eu/okular_dvi.po b/po/eu/okular_dvi.po new file mode 100644 index 0000000..15df1c5 --- /dev/null +++ b/po/eu/okular_dvi.po @@ -0,0 +1,755 @@ +# Translation of okular_dvi.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñigo Salvador Azurmendi , 2010, 2011, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2018-08-03 14:49+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Enbata,Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "urazpian@hotmail.com,xalba@euskalnet.net" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okularrek ezin izan du dvipdfm programa zure konputagailuan " +"aurkitu. Programa hau ezinbestekoa da esportatzeko funtzioa ibil dadin. Hala " +"ere, bihurtu DVI-fitxategia PDFra Okularren inprimatzeko funtzioa erabiliz, " +"horrek ondo inprimatzen diren dokumentuak sortuko ditu, baino kalitate " +"txikiagokoak Acrobat Reader-arekin ikusten badira. Zuhurra litzateke zure " +"TeX banaketa dvipdfm programa duen bertsio berriago batera bertsio-" +"berritzea.

Sistemaren administratzaile txundituarentzako argibidea: " +"Okularrek PATH ingurune aldagaia erabiltzen du programak bilatzerakoan.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Kanpoko 'dvipdfm' programak, fitxategia esportatzeko erabili zenak, " +"akats baten berri eman du. Agian Fitxategi-Menuan aurkituko duzun " +"dokumentuen info elkarrizketa begiratu nahiko duzu " +"errorearen txosten zehatzerako." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"DVI fitxategi honek PostScript formatuan ez dauden kanpoko fitxategi " +"grafikoei aipamen egiten die, eta ezin dira maneiatu dvips " +"programarekin, Okularek inprimatzeko edo Postscript-era esportatzeko barnean " +"erabiltzen duen programarekin. Zuk behar duzun funtzionaltasuna ez dago " +"beraz erabilgarri Okularren bertsio honetan." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okularrek ezin izan du zure aurkitu dvips programa zure " +"ordenagailuan. Programa hori ezinbestekoa da esportatzeko funtzioa ibil " +"dadin.

Administratzaile txundituarentzako argibidea: Okularrek PATH " +"ingurune aldagaia erabiltzen du programak bilatzerakoan.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Kanpoko 'dvips' programak, fitxategia esportatzeko erabili zenak, errore " +"baten berri eman du. Agian Fitxategi-Menuan aurkituko duzun " +"dokumentuen info elkarrizketa begiratu nahiko duzu " +"errorearen txosten zehatzerako." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI fitxategia ez da hasten abiaburuarekin." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI fitxategiak programa honetarako DVIren irteera bertsio okerra du. " +"Argibidea: Omega tipografia-sistema erabiltzen baduzu, programa berezi bat " +"erabil behar duzu, oxdvi adibidez." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"DVI fitxategia sakonki hondatua dago. Okularrek ezin izan du azkenburua " +"aurkitu." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Azkenburua ez da hasten «POST» komandoarekin." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Azkenburuak «FNTDEF» ez den beste komando bat dauka." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "%1 orrialdea ez da hasten «BOP» komandoarekin." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Kanpoko pdf2ps programa ezin izan da abiatu. Honen " +"ondorioz, %1 PDF fitxategia ezin izan da PostScript-era bihurtu. Zure " +"dokumentuko zenbait elementu grafiko ez dira bistaratuko, beraz.

Arrazoi posibleak: Izan liteke pdf2ps programa " +"zure sisteman instalatua ez egotea, edo uneko bidean aurkitu ezin izatea.

Egin dezakezuna: pdf2ps programa ghostscript " +"Postscript interpretatzeko sistemaren banaketetan egon ohi da. Ghostscript " +"ez badago zure sisteman instalatua, orain instalatu dezakezu. Ghostscript " +"zure sisteman instalatua dagoela ziur bazaude, saiatu pdf2ps komando lerrotik erabiltzen benetan dabilen egiaztatzeko.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

%1 PDF-fitxategia ezin izan da PostScript-era bihurtu. Ondorioz " +"zenbait elementu grafiko ez dira bistaratuko.

Arrazoi posibleak: %1 fitxategia hondatuta egon liteke, edo agian ez da PDF-fitxategia ere. " +"Hau da Okularrek erabili duen pdf2ps programaren irteera:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Fitxategi hondatua. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "PostScript fitxategi guztiak ezin dira kapsulatu zure dokumentuan. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"Kanpoko Postscript fitxategi guztiak ezin dira kapsulatu zure dokumentuan." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Adierazitako '%1' fitxategia ez dago." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Okularri eskatu diozu DVI fitxategian %2 TeX-fitxategiko %1 lerroari " +"dagokion lekua aurkitzeko. Dirudienez, ordea, DVI fitxategiak ez dauka " +"sorburu fitxategiaren gaineko beharrezko informazioa." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okularrek ezin izan du aurkitu DVI fitxategian %2 TeX-fitxategiko %1 " +"lerroari dagokion lekua." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI kodeak letra-tipo ezezagun bateko karakterea ezarri du." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"DVI kodeak #%1 letra-tipoari aipamen egin dio, lehendik definitua ez dagoena." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Pila ez zegoen hutsik «EOP» komandoa aurkitzu denean." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Pila hutsik zegoen «POP» komandoa aurkitu denean." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"DVI kodeak aurrez definitu gabe zegoen letra-tipo bati aipamen egiten dio." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Legez kontrako komando bat aurkitu da." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "%1 eragiketa-kode ezezaguna aurkitu da." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "%1 kapsulatzea" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"%1 orria: %2 PDF fitxategia ezin izan da PostScript-era " +"bihurtu.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"%1 orria: %2 PostScript fitxategia ezin izan da aurkitu.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "" +"'%1' paper-neurriaren datuen azterketa sintaktikoa ezin izan da gainditu." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okularrek ezin izan ditu aurkitu uneko DVI fitxategia bistaratzeko " +"beharrezkoak diren letra-tipoen fitxategi guztiak. Zure dokumentua " +"irakurtezina izan daiteke.

BIDEA: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Arazoak izan dira kpsewhich ibiltzean. Horren ondorioz, " +"letra-tipo fitxategi batzuk ez dira aurkitu, eta zure dokumentua " +"irakurtezina izan daiteke.
Arrazoi posibleak: kpsewhich " +"programa agian ez dago zure sisteman instalatuta, edo ezin da aurkitu uneko " +"bilaketa bidean.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"kpsewhichen letra-tipoen sorrera galarazi egin da (irteera " +"kodea %1, errorea %2). Horren ondorioz, zenbait letra-tipo fitxategi ezin " +"izan dira aurkitu, eta zure dokumentua irakurtezina izan liteke." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "%1 sortzen hari da une honetan %2 dpi-arekin..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Sortzailea/Data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Letra-tipo fitxategia ez da aurkitu" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "erretratua" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "paisaia" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Ordenagailu honetan instalatuta dagoen Ghostview-ren bertsioak ez dauka " +"Okularri ezagunak zaizkion Ghostviewren gailuetarako gidaririk. Postscript-" +"en euskarria itzali da Okularren horren ondorioz." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Ghostview programa, Okularrek DVI fitxategi honetan erantsitako " +"PostScript grafikoak bistaratzeko barruan erabiltzen duen programa, " +"gehienetan irteera hainbat formatutan idazteko gauza izaten da. Ataza " +"hauetarako Ghostview-k erabiltzen dituen azpi-programei 'gailu gidari' " +"deitzen zaie; gailu gidari bat dago Ghostview-k idatz dezakeen formatu " +"bakoitzerako. Ghostview-ren bertsio ezberdinek maiz gailu gidari multzo " +"ezberdinak izaten dituzte erabilgarri. Dirudienez zure ordenagailuan " +"instalatua dagoen Ghostview-ren bertsioak ez dauka Okularri ezagun zaion " +"gailu gidarietako bat ere.

Sinesgaitza dirudi " +"Ghostview-ren instalazio arrunt batek gidari hauek ez izatea. Errore honek " +"zure ordenagailuko Ghostview-ren konfigurazioaren oker garrantzitsu bat " +"adieraz dezake.

Ghostviewrekin dagoen arazo hau konpondu nahi baduzu, " +"gs --help komandoa erabil dezakezu Ghostview-k dituen gailu " +"gidari zerrenda bistaratzeko. Beste batzuen artean, Okular-rek 'png256', " +"'jpeg' eta 'pnm' gidariak erabil ditzake. Jakizu Okular berrabiatu egin " +"behar dela PostScript-ekiko euskarria berriz gaitzeko.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Horrekin 25 errore dira. Ez da beste errore mezurik inprimatuko." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Errorea '%1' DVI-fitxategian, %2 orria. «Pop kolore» komandoa jaulki da " +"kolore pila hutsik dagoenean." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Gaizki osatutako parametroa «epsf» komando berezian.\n" +"Higikor bat espero zen %1-(e)(r)i %2-an jarraitzeko" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Fitxategi ez da aurkitu: \n" +"%1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Errorea '%1' DVI-fitxategian, %2 orria. Ezin izan da angelua interpretatu " +"testu biraketa berezian." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "'%1' komando berezia ez dago inplementatuta." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"%1 letra-tipo fitxategia ireki eta irakur daiteke, baina Letra-tipo formatua " +"ez da onartzen." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"%1 letra-tipo fitxategia hondatua dago, edo ezin izan da ireki edo irakurri." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeTypek errore baten berri eman du %1 letra-tipo fitxategiaren karaktere " +"neurria ezartzean." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeTypek ezin du %2 letra-tipo fitxategitik #%1 glifoa zamatu." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeTypek ezin du errendatu %2 letra-tipo fitxategiko #%1 glifoa." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "#%1 glifoa hutsik dago." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "%2 letra-tipo fitxategiko #%1 glifoa hutsik dago." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeTypek ezin du %2 letra-tipo fitxategiko #%1 glifoaren metrika zamatu." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "%1 letra-tipo fitxategia ezin da ireki." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: %2 letra-tipoko %1 karakterea ez dago definituta" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Ustekabeko %1 %2 PK fitxategian" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "%2 fitxategiko %1 karakterea handiegia da" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Bit kopuru okerra biltegiratu da: %1 Karakterea, %2 letra-tipoa" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Pk fitxategi hondatua (%1), bit gehiegi" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Letra-tipoak itxura-erlazio ez-laukia dauka" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Ezin da aurkitu %1 letra-tipoa, %2 fitxategia." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Egiaztapen-batura akatsa %1 letra-tipo fitxategiarentzako" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Ezin da antzeman %1 letra-tipo fitxategiaren formatua" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Errore larria.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Honek adierazi dezake Okularren akats bat aurkitu duzula,\n" +"edo DVI fitxategia, edo fitxategi laguntzaileak (letra-tipo \n" +"fitxategiak, edo alegiazko letra-tipo fitxategiak esaterako) \n" +"sakonki hondatuta zeudela.\n" +"Okular mezu honen ondoren itxi egingo da. Akats bat aurkitu\n" +"duzulakoan bazaude, edo Okular egoera honetan hobe jokatu\n" +"behar zuela uste baduzu, eman arazoaren berri." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Komando byte okerra aurkitu da VF makro zerrendan: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI motorea" + +#~ msgid "A DVI file renderer" +#~ msgstr "DVI fitxategiko errendatzailea" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Beharrezkoa bada, okular kpsewhich programan oinarritzen da " +#~ "letra-tipo fitxategiak lokalizatzeko zure diska gogorrean eta sortu PK " +#~ "letra-tipoak.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular une honetan bit-map letra-tipoak sortzen ari da..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Gelditu letra-tipo sortzeaz. Ez du egiten." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular bit-map letra-tipoak sortzen ari da, dokumentua bistaratzeko " +#~ "baharrezkoak direlako. Hainbat kanpoko programak erabiltzen ditu Okular " +#~ "hau egiteko, MetaFont adibidez. Dokumentu elkarrizketa-koadroan programa " +#~ "hoietako irteera bilatu dezakezu geroago." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular letra-tipoak sortzen ari da. Itxaron." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Letra-tipoa sortzeko prozesua progresioaren elkarrizketa-koadroa" + +#~ msgid "Abort" +#~ msgstr "Abortatu" + +#~ msgid "What is happening here?" +#~ msgstr "Zer hari da gertatzen hemen?" + +#~ msgid "%v of %m" +#~ msgstr "%v-a %m-tik" + +#~ msgid "Please be patient" +#~ msgstr "Pazientzia pixka bat mesedez" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Esportatu fitxategia honela" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "%1 fitxategia\n" +#~ "existitzen da. Gainidatzi nahi duzu?" + +#~ msgid "Overwrite File" +#~ msgstr "Gainidatzi fitxategia" + +#~ msgid "Overwrite" +#~ msgstr "Gainidatzi" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Dvipdfm erabiltzen fitxategia PDF-ra esportatzeko" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular une honetan'dvipdfm' kanpoko programa erabiltzen ari da zure DVI-" +#~ "fitxategia PDF-ra bihurtzeko. Batzutzan debora pixka bat hartu dezake " +#~ "dvipdfm-ek bere letra-tipoen bitmapa propioa sortu behar duelako, mesedez " +#~ "izan ezazu pazientzia." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Dvipdfm zain amaitu arte..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Dvips erabiltzen fitxategia PostScript-ra esportatzeko" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular une honetan'dvips' kanpoko programa erabiltzen ari da zure DVI-" +#~ "fitxategia PostScript-era bihurtzeko. Batzutzan debora pixka bat hartu " +#~ "dezake dvips-ek bere letra-tipoen bitmapa propioa sortu behar duelako, " +#~ "mesedez izan ezazu pazientzia." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Dvips zain amaitu arte..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funtzionaltasuna ez da erabilgarria" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Fitxategi hondatzea Okular ezin izan du DVI " +#~ "fitxategia interpretatu. Ohikoena fitxategi oker batekin eragitea da." + +#~ msgid "DVI File Error" +#~ msgstr "Errorea DVI fitxategian" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Ez dira letra-tipo fitxategi guztiak aurkitu" + +#~ msgid "Locating fonts..." +#~ msgstr "Letra-tipoak aurkitzen..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Letra-tipoak kokatzerakoan arazoa" + +#~ msgid "Font generation aborted" +#~ msgstr "Letra-tipoa sortzeko prozesua bertan behera utzi du" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Esportatu: %1 PDF-ra" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Esportatu: %1 PostScript-era" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Letra tipoen zerrenda une honetan hutsik dago." + +#~ msgid "TeX Name" +#~ msgstr "TeX Izena" + +#~ msgid "Family" +#~ msgstr "Senideak" + +#~ msgid "Zoom" +#~ msgstr "Zooma" + +#~ msgid "Type" +#~ msgstr "Mota" + +#~ msgid "Encoding" +#~ msgstr "Kodetzea" + +#~ msgid "Comment" +#~ msgstr "Iruzkin" + +#~ msgid "TeX virtual" +#~ msgstr "TeX birtuala" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX letra-tipoa metrotan" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/eu/okular_epub.po b/po/eu/okular_epub.po new file mode 100644 index 0000000..e0a61d3 --- /dev/null +++ b/po/eu/okular_epub.po @@ -0,0 +1,59 @@ +# Translation of okular_epub.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2018-08-03 17:18+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Enbata" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "urazpian@hotmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Errorea EPub dokumentua irekitzean." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "EPub bizkarraldekoaren konfigurazioa" + +#~ msgid "EPub Backend" +#~ msgstr "EPub Motorea" + +#~ msgid "An EPub backend" +#~ msgstr "EPub-eko motorea" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/eu/okular_fax.po b/po/eu/okular_fax.po new file mode 100644 index 0000000..634eea6 --- /dev/null +++ b/po/eu/okular_fax.po @@ -0,0 +1,47 @@ +# translation of okular_fax.po to Basque +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-05-12 19:03+0200\n" +"Last-Translator: Iñaki Larrañaga Murgoitio \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Ezin da dokumentua kargatu" + +#~ msgid "Fax Backend" +#~ msgstr "Fax motorra" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "G3/G4 fax dokumentuen motorra" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eu/okular_fictionbook.po b/po/eu/okular_fictionbook.po new file mode 100644 index 0000000..4aac250 --- /dev/null +++ b/po/eu/okular_fictionbook.po @@ -0,0 +1,85 @@ +# Translation of okular_fictionbook.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2018-08-03 17:27+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokumentua ez da baliozko «FictionBook» bat" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Ezin da dokumentua ireki: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokumentua ez da baliozko ZIP artxiboa" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Dokumentuaren egitura baliogabea (direktorio nagusia falta da)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Ez da edukirik aurkitu dokumentuan" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "XML dokumentu baliogabea: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "FictionBook bizkarraldekoaren konfigurazioa" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Fikzio-liburuko motorra" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "eBooks fikzio-liburuko errendatzailea" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eu/okular_ghostview.po b/po/eu/okular_ghostview.po new file mode 100644 index 0000000..6ec2b8e --- /dev/null +++ b/po/eu/okular_ghostview.po @@ -0,0 +1,96 @@ +# Translation of okular_ghostview.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2018-08-03 17:34+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Erabili plataformako letra-tipoak" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Ghostscript-i plataformako letra-tipoak erabiltzen utzi edo ez zehazten du, " +"ezezko kasuan soilik dokumentuan kapsulatutako letra-tipoak onartuko dira." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Ezarpen orokorrak" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Erabili plataformako letra-tipoak" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Ghostscripteko bizkarraldekoaren konfigurazioa" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumentu bertsioa" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Hizkuntza maila" + +#~ msgid "PS Backend" +#~ msgstr "PS motorra" + +#~ msgid "A PostScript file renderer." +#~ msgstr "PostScript fitxategiko errendatzailea." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Spectre liburutegian oinarrituta." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/eu/okular_kimgio.po b/po/eu/okular_kimgio.po new file mode 100644 index 0000000..e882fdb --- /dev/null +++ b/po/eu/okular_kimgio.po @@ -0,0 +1,75 @@ +# Translation of okular_kimgio.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# marcos, 2011. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2018-08-03 17:43+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Ezin da zamatu dokumentua: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Dokumentu hau gaizki eratuta dagoela dirudi. Hemen dago dokumentuarentzat " +"nahi zen itxuraren hurbilketa hobe bat." + +#~ msgid "Image Backend" +#~ msgstr "Irudien motorra" + +#~ msgid "A simple image backend" +#~ msgstr "Irudi bakunen motorra" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Tresna-barra nagusia" diff --git a/po/eu/okular_markdown.po b/po/eu/okular_markdown.po new file mode 100644 index 0000000..07ffd84 --- /dev/null +++ b/po/eu/okular_markdown.po @@ -0,0 +1,57 @@ +# Translation of okular_markdown.po to Euskara/Basque (eu). +# Copyright (C) 2018, Free Software Foundation. +# Copyright (C) 2019, This file is copyright: +# This file is distributed under the same license as the okular package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Iñigo Salvador Azurmendi , 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-06-24 10:21+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "xalba@euskalnet.net" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Huts egin du dokumentua irekitzea" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Huts egin du Markdown dokumentua konpilatzea." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Gaitu «SmartyPants» formatua ematea" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Markdown bizkarraldekoaren konfigurazioa" diff --git a/po/eu/okular_mobi.po b/po/eu/okular_mobi.po new file mode 100644 index 0000000..2ade473 --- /dev/null +++ b/po/eu/okular_mobi.po @@ -0,0 +1,67 @@ +# Translation of okular_mobi.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2018-08-03 17:59+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 2.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Enbata" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "urazpian@hotmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Errorea Mobipocket dokumentua irekitzean." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Liburu hau DRM bidez babestua dago eta bistaratu daiteke bakarrik " +"izendatutako gailuan" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Mobipocket bizkarraldekoaren konfigurazioa" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket motorea" + +#~ msgid "A mobipocket backend" +#~ msgstr "Mobipocket-eko motorea" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/eu/okular_plucker.po b/po/eu/okular_plucker.po new file mode 100644 index 0000000..e5dad29 --- /dev/null +++ b/po/eu/okular_plucker.po @@ -0,0 +1,47 @@ +# translation of okular_plucker.po to Basque +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-05-12 19:13+0200\n" +"Last-Translator: Iñaki Larrañaga Murgoitio \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Izena" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Plucker dokumentuen motorra" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Plucker eBooks-eko errendatzailea" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/eu/okular_poppler.po b/po/eu/okular_poppler.po new file mode 100644 index 0000000..28c75e3 --- /dev/null +++ b/po/eu/okular_poppler.po @@ -0,0 +1,231 @@ +# Translation of okular_poppler.po to Euskara/Basque (eu). +# Copyright (C) 2009-2018, Free Software Foundation. +# Copyright (C) 2019, This file is copyright: +# This file is distributed under the same license as the okular package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +# Iñigo Salvador Azurmendi , 2011, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-06-24 10:48+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 19.04.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe,Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org,xalba@euskalnet.net" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Areagotu lerro meheak:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ez" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solidoa" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF aukerak" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Inprimatu idatzoharrak" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Sartu idatzoharrak inprimatutako dokumentuan" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Idatzoharrak sartzen ditu inprimatutako dokumentuan. Hau desgaitu dezakezu " +"jatorrizko idatzoharrik gabeko dokumentua inprimatu nahi baduzu." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Derrigortu bilbatzea" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Bilbatu irudi batean inprimatu aurretik" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Orrialde bakoitza irudi batean bilbatzea behartzen du hura inprimatu " +"aurretik. Honek emaitza okerragoak eman ohi ditu, baina beste eratan oker " +"inprimatzen diren dokumentuak inprimatzeko baliagarria izaten da." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Egokitu azalera inprimagarrira" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Egokitu orri osora" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Bat ere ez; inprimatu jatorrizko neurrian" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Inprimatutako orrientzako eskalatzeko modua" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Eskalatze modua:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF %1.%2 bertsioa" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formatua" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Zifratuta" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Zifratu gabe" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Segurtasuna" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Bai" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimizatuta" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "«Poppler» %1 erabiltzen" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"«Poppler» %1 erabiltzen\n" +"\n" +"«Poppler» %2 erabiliz eraikia" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "PDF bizkarraldekoaren konfigurazioa" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Ez dago eskuragarri" + +#~ msgid "PDF Backend" +#~ msgstr "PDF motorra" + +#~ msgid "A PDF file renderer" +#~ msgstr "PDF fitxategien bilbatzailea" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Fitxategiak /Zifratu-rekin gordetzea ez da onartzen." + +#~ msgid "Unknown" +#~ msgstr "Ezezaguna" + +#~ msgid "Unknown Date" +#~ msgstr "Data ezezaguna" + +#~ msgid "Unknown Encryption" +#~ msgstr "Zifraketa ezezaguna" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optimizazio ezezaguna" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Mesedez sartu pasahitza dokumentua irakurtzeko:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Pasahitz okerra. Saiatu berriro:" + +#~ msgid "Document Password" +#~ msgstr "Dokumentuaren pasahitza" diff --git a/po/eu/okular_tiff.po b/po/eu/okular_tiff.po new file mode 100644 index 0000000..0b0ef88 --- /dev/null +++ b/po/eu/okular_tiff.po @@ -0,0 +1,31 @@ +# Translation for okular_tiff.po to Euskara/Basque (eu). +# Copyright (C) 2020, This file is copyright: +# This file is distributed under the same license as the okular package. +# KDE euskaratzeko proiektuko arduraduna . +# +# Translators: +# Iñigo Salvador Azurmendi , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-27 09:27+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "xalba@euskalnet.net" diff --git a/po/eu/okular_txt.po b/po/eu/okular_txt.po new file mode 100644 index 0000000..9184acf --- /dev/null +++ b/po/eu/okular_txt.po @@ -0,0 +1,41 @@ +# Translation of okular_txt.po to Euskara/Basque (eu). +# Copyright (C) 2018, Free Software Foundation. +# This file is distributed under the same terms as the applications package. +# KDE euskaratzeko arduraduna . +# +# Translators: +# Iñigo Salvador Azurmendi , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_txt\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2018-08-03 09:44+0100\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Iñigo Salvador Azurmendi" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "xalba@euskalnet.net" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Txt bizkarraldekoaren konfigurazioa" diff --git a/po/eu/okular_xps.po b/po/eu/okular_xps.po new file mode 100644 index 0000000..45b95d3 --- /dev/null +++ b/po/eu/okular_xps.po @@ -0,0 +1,59 @@ +# translation of okular_xps.po to Basque +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Enbata , 2009. +# Iñaki Larrañaga Murgoitio , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-05-12 19:22+0200\n" +"Last-Translator: Iñaki Larrañaga Murgoitio \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marcos Goyenetxe" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marcos@euskalgnu.org" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Berrikuspena" + +#~ msgid "XPS Backend" +#~ msgstr "XPS motorra" + +#~ msgid "An XPS backend" +#~ msgstr "XPS motorra" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/eu/org.kde.active.documentviewer.po b/po/eu/org.kde.active.documentviewer.po new file mode 100644 index 0000000..8baec53 --- /dev/null +++ b/po/eu/org.kde.active.documentviewer.po @@ -0,0 +1,61 @@ +# Translation of org.kde.active.appdata.po to Euskara/Basque (eu). +# Copyright (C) 2018, Free Software Foundation. +# This file is distributed under the same license as the kdegraphics package. +# KDE euskaratzeko proiektuaren arduraduna . +# +# Translators: +# Iñigo Salvador Azurmendi , 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: org.kde.active.appdata\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-06 22:14+0200\n" +"Last-Translator: Iñigo Salvador Azurmendi \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.04.3\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Ireki..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Kendu liburu-markak" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Sortu orri honen liburu-marka" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Koadro txikiak" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Edukien aurkibidea" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Laster-markak" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Bilatu..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Ez da emaitzarik aurkitu." + +#~ msgid "Document to open..." +#~ msgstr "Ireki beharreko dokumentua..." diff --git a/po/fa/okular.po b/po/fa/okular.po new file mode 100644 index 0000000..31b8153 --- /dev/null +++ b/po/fa/okular.po @@ -0,0 +1,5647 @@ +# translation of okular.po to Persian +# Nasim Daniarzadeh , 2006. +# Nazanin Kazemi , 2006, 2007. +# MaryamSadat Razavi , 2006. +# Tahereh Dadkhahfar , 2006. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2007-07-31 19:48+0330\n" +"Last-Translator: Nazanin Kazemi \n" +"Language-Team: Persian \n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "نسیم دانیارزاده" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "daniarzadeh@itland.ir" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "نگه‌دارنده قبلی" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "" + +#: aboutdata.h:39 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotations artwork" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: aboutdata.h:40 +#, fuzzy, kde-format +#| msgid "&Text Selection Tool" +msgid "Table selection tool" +msgstr "ابزار گزینش &متن‌" + +#: aboutdata.h:41 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation improvements" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "برو به صفحه %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "باز کردن پرونده خارجی" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "اجرای »%1«..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "صفحه اول" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "صفحه قبلی" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "صفحه بعدی" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "صفحه آخر" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "عقب" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "پیش‌سو" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "خروج" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "آغاز ارائه" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "پایان ارائه" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "یافتن..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "برو به صفحه..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "پخش صدا..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "پخش فیلم..." + +#: core/action.cpp:547 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Play movie" +msgstr "پخش فیلم..." + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "" + +#: core/action.cpp:551 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Pause movie" +msgstr "پخش فیلم..." + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "برو به صفحه %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" + +#: core/document.cpp:3368 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "ارائه" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, fuzzy, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"سند سعی در اجرای یک کاربرد خارجی دارد، و okular برای امنیت به شما اجازه این " +"کار را نمی‌دهد." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "برای باز کردن پرونده نوع مایم %1، کاربردی یافت نشد." + +#: core/document.cpp:4258 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not open a temporary file" +msgstr "نتوانست %1 را باز کند. دلیل: %2" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "" + +#: core/document.cpp:4270 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find file to print" +msgstr "قادر به یافتن جزء okular نیست." + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not open '%1'. File does not exist" +msgstr "نتوانست %1 را باز کند. دلیل: %2" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "عنوان" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "موضوع" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "توصیف" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "نویسنده" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "ایجاد‌کننده" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "تولید‌کننده" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "حق نشر" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "صفحه‌ها" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "ایجاد‌‌شده" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "تغییریافته" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "نوع مایم" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "فهرست" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "واژه‌های کلیدی" + +#: core/document.cpp:5421 +#, fuzzy, kde-format +#| msgid "File" +msgid "File Path" +msgstr "پرونده" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "اندازه پرونده" + +#: core/document.cpp:5427 +#, fuzzy, kde-format +msgid "Page Size" +msgstr "اندازه صفحه‌‌‌ها" + +#: core/documentcommands.cpp:65 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "حاشیه‌نویسی" + +#: core/documentcommands.cpp:110 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "ارائه" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "حاشیه‌نویسی" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "حاشیه‌نویسی" + +#: core/documentcommands.cpp:328 +#, fuzzy, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "&برگزیدن ابزار‌" + +#: core/documentcommands.cpp:390 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: core/documentcommands.cpp:438 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&متن ساده...‌" + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "" + +#: core/generator.cpp:756 +#, fuzzy, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "باز کردن یک سند" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Filter Options" +msgid "Print Options" +msgstr "گزینه‌های پالایش" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +msgid "Scale mode:" +msgstr "حالتهای رنگ" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "بستن این پیام" + +#: core/sourcereference.cpp:103 +#, fuzzy, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "اندازه" + +#: core/textdocumentsettings.cpp:37 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Font:" +msgstr "گذار پیش‌فرض:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "&بارگذاری مجدد‌" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "ایجاد‌‌شده:" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "متناسب کردن عرض" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&رنگ:‌" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&رنگ:‌" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Select Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "&برگزیدن ابزار‌" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "&Annotations" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "خط زیر" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "خط زیر" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "&برگزیدن ابزار‌" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "&برگزیدن ابزار‌" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "جای‌نوشت" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "ویژگیهای خط" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "ویژگیهای خط" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "مستطیل" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "مهر" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "ارائه" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "قلم:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "خط" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&ظرفیت:‌" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "صفحه %1" + +#: part/annotationpopup.cpp:82 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "حاشیه‌نویسی" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&حذف‌" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&ویژگیها‌" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, fuzzy, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "ذخیره به عنوان..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&ظاهر‌" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&عمومی‌" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&نویسنده:‌" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "ایجاد‌‌شده" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "تغییریافته" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Pop-up Note Properties" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +msgid "Typewriter Properties" +msgstr "ویژگیهای FreeText" + +#: part/annotationpropertiesdialog.cpp:116 +#, fuzzy, kde-format +msgid "Inline Note Properties" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line Properties" +msgstr "ویژگیهای خط" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +msgid "Polygon Properties" +msgstr "ویژگیهای جوهر" + +#: part/annotationpropertiesdialog.cpp:126 +#, fuzzy, kde-format +msgid "Geometry Properties" +msgstr "ویژگیهای Geom" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Stamp Properties" +msgid "Text Markup Properties" +msgstr "ویژگیهای مهر" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "ویژگیهای مهر" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line Properties" +msgstr "ویژگیهای خط" + +#: part/annotationpropertiesdialog.cpp:138 +#, fuzzy, kde-format +msgid "Caret Properties" +msgstr "ویژگیهای FreeText" + +#: part/annotationpropertiesdialog.cpp:141 +#, fuzzy, kde-format +msgid "File Attachment Properties" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationpropertiesdialog.cpp:144 +#, fuzzy, kde-format +msgid "Sound Properties" +msgstr "ویژگیهای جوهر" + +#: part/annotationpropertiesdialog.cpp:147 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Movie Properties" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/annotationpropertiesdialog.cpp:175 +#, fuzzy, kde-format +msgid "Modified: %1" +msgstr "تغییریافته:" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&رنگ:‌" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&ظرفیت:‌" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "شمایل" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "توضیحات" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "کمک" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "درج" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "کلید" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "بند جدید" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "بند" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "قلم:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&رنگ:‌" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "" + +#: part/annotationwidgets.cpp:390 +#, fuzzy, kde-format +msgid "Left" +msgstr "پاک کردن چپ" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "" + +#: part/annotationwidgets.cpp:392 +#, fuzzy, kde-format +msgid "Right" +msgstr "پاک کردن راست" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "محرمانه" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "پیش‌نویس" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "نهایی" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "" + +#: part/annotationwidgets.cpp:420 +#, fuzzy, kde-format +msgid "Bookmark" +msgstr "چوب الفها" + +#: part/annotationwidgets.cpp:421 +#, fuzzy, kde-format +msgid "Information" +msgstr "حاشیه‌نویسی" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "متناسب کردن عرض" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "خط" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "خط" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +msgid "None" +msgstr "خیر" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Leader line length:" +msgstr "خط زیر" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "ذخیره در پرونده..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "نوع:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "خط زیر" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "خط زیر" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "مستطیل" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +msgid "File attachment symbol:" +msgstr "ویژگیها‌ی یادداشت" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "" + +#: part/annotationwidgets.cpp:748 +#, fuzzy, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "رنگ کاغذ:" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "" + +#: part/annotationwidgets.cpp:758 +#, fuzzy, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "پرونده" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "" + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "Name" +msgid "Name:" +msgstr "نام" + +#: part/annotationwidgets.cpp:782 +#, fuzzy, kde-format +msgid "Description:" +msgstr "توصیف" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:842 +#, fuzzy, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "خیر" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "" + +#: part/annotwindow.cpp:55 +#, fuzzy, kde-format +msgid "Close this note" +msgstr "بستن این پیام" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "گزینه‌ها" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"%2چوب الف" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "چوب الفها" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "فقط سند جاری" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "برو به این چوب الف" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "تغییر نام چوب الف" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "حذف چوب الف" + +#: part/bookmarklist.cpp:278 +#, fuzzy, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "باز کردن یک سند" + +#: part/bookmarklist.cpp:280 +#, fuzzy, kde-format +#| msgid "Remove Bookmark" +msgid "Remove Bookmarks" +msgstr "حذف چوب الف" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +msgid "Serial Number" +msgstr "اندازه صفحه‌‌‌ها" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "موضوع" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "کاربرد حافظه" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&ویژگیها‌" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Certificate Viewer" +msgstr "پیکربندی مشاهده‌گر..." + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "&صادرات به عنوان‌" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "عمومی" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "&بارگذاری مجدد‌" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +msgid "Green" +msgstr "ایجاد‌‌شده:" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "ترسیم لبه دور &تصاویر‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "ترسیم لبه دور &پیوندها‌" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, fuzzy, kde-format +msgid "Change &colors" +msgstr "تغییر &رنگها‌" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "اخطار: این گزینه‌ها بر ترسیم سرعت اثر بد می‌گذارند." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, fuzzy, kde-format +msgid "Color mode:" +msgstr "حالتهای رنگ" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, fuzzy, kde-format +msgid "Invert Colors" +msgstr "&وارونه کردن رنگها‌" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, fuzzy, kde-format +msgid "Change Paper Color" +msgstr "تغییر رنگ &کاغذ‌" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, fuzzy, kde-format +msgid "Change Dark & Light Colors" +msgstr "&تغییر رنگهای تیره و روشن‌" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, fuzzy, kde-format +msgid "Convert to Black & White" +msgstr "تبدیل به &سیاه و سفید‌" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "رنگ کاغذ:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "رنگ تیره:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "رنگ روشن:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "آستانه:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "سایه روشن:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "هویت" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&نویسنده:‌" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Quick annotation tools" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "" + +#: part/dlgeditor.cpp:30 +#, fuzzy, kde-format +#| msgid "File" +msgctxt "Text editor" +msgid "Kile" +msgstr "پرونده" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "Editor" +msgstr "&ویرایش‌" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "Editor:" +msgstr "&ویرایش‌" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, fuzzy, kde-format +#| msgid "Comment" +msgid "Command:" +msgstr "توضیحات" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "ظاهر" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "نمایش &میله‌های لغزش‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "پیوند &ریزنقشها با صفحه‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "نمایش &نکته‌ها و پیامهای اطلاعات‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "رنگ زمینه:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&پیروی از محدودیتهای DRM‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&بارگذاری مجدد سند هنگام تغییر پرونده‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "گزینه‌های نما" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, fuzzy, kde-format +#| msgid "Overview" +msgid "Overview &columns:" +msgstr "نمای کلی" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Zoom:" +msgstr "گذار پیش‌فرض:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "متناسب کردن عرض" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "متناسب کردن صفحه" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"تا جای ممکن از حافظه کم استفاده می‌کند. مجدداً از چیزی استفاده نکنید. )در مورد " +"سیستمهایی که حافظه کم دارند.(" + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"یک سازش خوب بین کاربرد حافظه و بهره سرعت. پیش بارگذاری صفحه بعدی و افزودن بر " +"توان جستجوها. )در مورد سیستمهایی که نوعاً دارای ۲۵۶ مگابایت حافظه می‌باشند.(" + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"همه چیز را در حافظه نگه می‌دارد. پیش بارگذاری صفحه‌های بعدی. افزودن بر توان " +"جستجوها. )در مورد سیستمهایی که بیش از ۵۱۲ مگابایت حافظه دارند.(" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "کاربرد واحد پردازش مرکزی" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "فعال‌سازی جلوه‌های &شفافیت‌" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "کاربرد حافظه" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&کم‌" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&عادی )پیش‌فرض(‌" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "&زیاد‌" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Rendering" +msgstr "خط زیر" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, fuzzy, kde-format +msgid "Enable Text Antialias" +msgstr "گذار پیش‌فرض:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, fuzzy, kde-format +msgid "Enable Graphics Antialias" +msgstr "گذار پیش‌فرض:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, fuzzy, kde-format +msgid "Enable Text Hinting" +msgstr "گذار پیش‌فرض:" + +#: part/dlgpresentation.cpp:33 +#, fuzzy, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "گذار پیش‌فرض:" + +#: part/dlgpresentation.cpp:34 +#, fuzzy, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "گذار پیش‌فرض:" + +#: part/dlgpresentation.cpp:37 +#, fuzzy, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "ایجاد‌‌شده:" + +#: part/dlgpresentation.cpp:49 +#, fuzzy, kde-format +#| msgid " sec." +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " ثانیه" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "ناوش" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "پیشرفت هر:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "حلقه بعد از آخرین صفحه" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "ناوش" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "رنگ زمینه:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "مکان‌نمای موشی:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "مخفی‌‌شده بعد از تأخیر" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "همیشه مرئی" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "همیشه مخفی" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "نمایش شاخص &پیشرفت‌" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "نمایش صفحه &خلاصه‌" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, fuzzy, kde-format +msgid "Enable transitions" +msgstr "گذار پیش‌فرض:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "گذار پیش‌فرض:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "به طور عمودی مانع عبور نور می‌شود" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "به طور افقی مانع عبور نور می‌شود" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "گیر انداختن" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "حل کردن" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "درخشش پایین" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "درخشش راست" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "درخشش راست پایین" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "گذار تصادفی" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "جایگزینی" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "شکافتن افقی در" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "شکافتن افقی بیرون از" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "شکافتن عمودی در" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "شکافتن عمودی بیرون از" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "پاک کردن پایین" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "پاک کردن راست" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "پاک کردن چپ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "پاک کردن بالا" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, fuzzy, kde-format +#| msgid "Name" +msgid "&Name:" +msgstr "نام" + +#: part/editannottooldialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Type:" +msgid "&Type:" +msgstr "نوع:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +#| msgid "Next Bookmark" +msgid "Text markup" +msgstr "چوب الف بعدی" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "مهر" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgid "Typewriter" +msgstr "جای‌نوشت" + +#: part/editannottooldialog.cpp:104 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create annotation tool" +msgstr "ارائه" + +#: part/editannottooldialog.cpp:106 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Edit annotation tool" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&رنگ:‌" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "متناسب کردن عرض" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr "" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create drawing tool" +msgstr "ارائه" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Edit drawing tool" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "ناشناخته" + +#: part/embeddedfilesdialog.cpp:48 +#, fuzzy, kde-format +#| msgid "Embedded Files" +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "پرونده‌های نهفته" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&نما‌" + +#: part/embeddedfilesdialog.cpp:70 +#, fuzzy, kde-format +#| msgid "Name" +msgctxt "@title:column" +msgid "Name" +msgstr "نام" + +#: part/embeddedfilesdialog.cpp:71 +#, fuzzy, kde-format +#| msgid "Description" +msgctxt "@title:column" +msgid "Description" +msgstr "توصیف" + +#: part/embeddedfilesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Size" +msgctxt "@title:column" +msgid "Size" +msgstr "اندازه" + +#: part/embeddedfilesdialog.cpp:73 +#, fuzzy, kde-format +#| msgid "Created" +msgctxt "@title:column" +msgid "Created" +msgstr "ایجاد‌‌شده" + +#: part/embeddedfilesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Modified" +msgctxt "@title:column" +msgid "Modified" +msgstr "تغییریافته" + +#: part/embeddedfilesdialog.cpp:152 +#, fuzzy, kde-format +#| msgid "Save As..." +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "ذخیره به عنوان..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&نما‌" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "بستن" + +#: part/findbar.cpp:41 +#, fuzzy, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "یافتن..." + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "" + +#: part/findbar.cpp:57 +#, fuzzy, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "صفحه بعدی" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "" + +#: part/findbar.cpp:61 +#, fuzzy, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "صفحه قبلی" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "حساس به حالت" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, fuzzy, kde-format +msgid "*|All Files" +msgstr "همه پرونده‌ها" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +msgid "Signature Properties" +msgstr "ویژگیهای FreeText" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line with Comment" +msgstr "ویژگیهای خط" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +msgid "Geometry with Comment" +msgstr "ویژگیهای Geom" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "خط زیر" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +msgid "Squiggle with Comment" +msgstr "&برگزیدن ابزار‌" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Underline with Comment" +msgstr "خط زیر" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +msgid "Strike Out with Comment" +msgstr "&برگزیدن ابزار‌" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line with Comment" +msgstr "ویژگیهای خط" + +#: part/guiutils.cpp:109 +#, fuzzy, kde-format +msgid "Caret" +msgstr "ایجاد‌کننده" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "" + +#: part/guiutils.cpp:118 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Movie" +msgstr "تغییریافته" + +#: part/guiutils.cpp:121 +#, fuzzy, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "ایجاد‌‌شده:" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, fuzzy, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "ناشناخته" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "نویسنده: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" + +#: part/ktreeviewsearchline.cpp:286 +#, fuzzy, kde-format +#| msgid "Filter Options" +msgid "Search Options" +msgstr "گزینه‌های پالایش" + +#: part/ktreeviewsearchline.cpp:287 +#, fuzzy, kde-format +#| msgid "Case Sensitive" +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "حساس به حالت" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "بزرگ‌نمایی" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, fuzzy, kde-format +#| msgid "Rotate Right" +msgid "Rotate &Right" +msgstr "چرخش راست" + +#: part/pageview.cpp:550 +#, fuzzy, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "پاک کردن راست" + +#: part/pageview.cpp:554 +#, fuzzy, kde-format +#| msgid "Rotate Left" +msgid "Rotate &Left" +msgstr "چرخش چپ" + +#: part/pageview.cpp:555 +#, fuzzy, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "پاک کردن چپ" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&نما‌" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +msgid "Trim To &Selection" +msgstr "ابزار گزینش &متن‌" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "متناسب کردن &عرض‌" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "متناسب کردن &صفحه‌" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "متناسب کردن &صفحه‌" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "حالت &نما‌" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "تک صفحه" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Fit Page" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "متناسب کردن صفحه" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "نمای کلی" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&پیوسته‌" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +msgid "&Browse" +msgstr "ابزار &مرور‌" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "بزرگ‌نمایی" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &Colors" +msgid "&Toggle Change Colors" +msgstr "تغییر &رنگها‌" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +msgid "Area &Selection" +msgstr "ابزار گزینش &متن‌" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +msgid "&Text Selection" +msgstr "ابزار گزینش &متن‌" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +msgid "T&able Selection" +msgstr "ابزار گزینش &متن‌" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "&برگزیدن ابزار‌" + +#: part/pageview.cpp:720 +#, fuzzy, kde-format +msgid "Speak Whole Document" +msgstr "باز کردن یک سند" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "لغزش به بالا" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "لغزش به پایین" + +#: part/pageview.cpp:759 +#, fuzzy, kde-format +#| msgid "Scroll Up" +msgid "Scroll Page Up" +msgstr "لغزش به بالا" + +#: part/pageview.cpp:765 +#, fuzzy, kde-format +#| msgid "Scroll Down" +msgid "Scroll Page Down" +msgstr "لغزش به پایین" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "نمایش &برگه‌ها‌" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " یک سند %1 صفحه‌ای بارگذاری شد." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "متن )%1 نویسه(" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "رونوشت در تخته یادداشت" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "گفتن متن" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "تصویر )%1 با %2 تصویردانه(" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "ذخیره در پرونده..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "تصویر ]%1x%2[ در تخته یادداشت رونوشت شد." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "ذخیره در پرونده..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "پرونده ذخیره‌نشده." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "تصویر ]%1x%2[ در پرونده %3 ذخیره شد." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "رونوشت متن" + +#: part/pageview.cpp:2930 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgid "Go to '%1'" +msgstr "برو به صفحه %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "" + +#: part/pageview.cpp:4149 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Configure Web Shortcuts..." +msgstr "پیکربندی مشاهده‌گر..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "پخش صدا..." + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "خوش آمدید" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "برگزیدن ناحیه بزرگ‌نمایی. برای کوچک‌نمایی فشار راست کنید." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "ترسیم یک مستطیل دور متن/نگاره‌‌سازی برای رونوشت." + +#: part/pageview.cpp:4769 +#, fuzzy, kde-format +msgid "Select text" +msgstr "&برگزیدن ابزار‌" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "ترسیم یک مستطیل دور متن/نگاره‌‌سازی برای رونوشت." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "ترسیم یک مستطیل دور متن/نگاره‌‌سازی برای رونوشت." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Bookmark annotation" +msgstr "حاشیه‌نویسی" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "خط زیر" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "مستطیل" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "&برگزیدن ابزار‌" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "&برگزیدن ابزار‌" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "خط زیر" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "خط زیر" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Add favorite annotation" +msgstr "حاشیه‌نویسی" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Custom annotation name:" +msgstr "حاشیه‌نویسی" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&پرونده‌" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&تنظیمات‌" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&کمک‌" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&جهت‌" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&چوب الفها" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, fuzzy, kde-format +#| msgid "Main Toolbar" +msgid "Viewer Toolbar" +msgstr "میله ابزار اصلی" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "ریزنقشها" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotations" +msgstr "حاشیه‌نویسی" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" + +#: part/part.cpp:643 +#, fuzzy, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "صفحه قبلی" + +#: part/part.cpp:644 +#, fuzzy, kde-format +msgid "Go back to the Previous Page" +msgstr "برو به صفحه چوب الف شده قبلی" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "به صفحه قبلی سند حرکت می‌کند" + +#: part/part.cpp:655 +#, fuzzy, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "صفحه بعدی" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "به صفحه بعدی سند حرکت می‌کند" + +#: part/part.cpp:668 +#, fuzzy, kde-format +#| msgid "Reloading the document..." +msgid "Beginning of the document" +msgstr "در حال بارگذاری مجدد سند..." + +#: part/part.cpp:669 +#, fuzzy, kde-format +#| msgid "Moves to the next page of the document" +msgid "Moves to the beginning of the document" +msgstr "به صفحه بعدی سند حرکت می‌کند" + +#: part/part.cpp:673 +#, fuzzy, kde-format +#| msgid "Open a document" +msgid "End of the document" +msgstr "باز کردن یک سند" + +#: part/part.cpp:674 +#, fuzzy, kde-format +#| msgid "Moves to the next page of the document" +msgid "Moves to the end of the document" +msgstr "به صفحه بعدی سند حرکت می‌کند" + +#: part/part.cpp:687 +#, fuzzy, kde-format +#| msgid "Reload the current document from disk." +msgid "Rename the current bookmark" +msgstr "بارگذاری مجدد سند از دیسک." + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "چوب الف قبلی" + +#: part/part.cpp:693 +#, fuzzy, kde-format +#| msgid "Go to the previous bookmarked page" +msgid "Go to the previous bookmark" +msgstr "برو به صفحه چوب الف شده قبلی" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "چوب الف بعدی" + +#: part/part.cpp:699 +#, fuzzy, kde-format +#| msgid "Go to the next bookmarked page" +msgid "Go to the next bookmark" +msgstr "برو به صفحه چوب الف‌ شده بعدی" + +#: part/part.cpp:726 +#, fuzzy, kde-format +msgid "Configure Okular..." +msgstr "پیکربندی okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "پیکربندی مشاهده‌گر..." + +#: part/part.cpp:735 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Viewer Backends..." +msgstr "پیکربندی پایانه‌ها..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "پیکربندی پایانه‌ها..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&بارگذاری مجدد‌" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "بارگذاری مجدد سند از دیسک." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "بستن نوار &یافتن‌" + +#: part/part.cpp:791 +#, fuzzy, kde-format +msgid "Page Number" +msgstr "اندازه صفحه‌‌‌ها" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show scroll&bars" +msgid "Show S&idebar" +msgstr "نمایش &میله‌های لغزش‌" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "نمایش تابلوی &ناوش‌" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "پرونده‌های &نهفته‌" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&صادرات به عنوان‌" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&ارائه‌" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "" + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Erase Drawing" +msgstr "ارائه" + +#: part/part.cpp:927 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Annotations..." +msgstr "پیکربندی پایانه‌ها..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "ارائه" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "%1 را نتوانست باز کند" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "" + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "نتوانست %1 را باز کند. دلیل: %2" + +#: part/part.cpp:1186 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Viewer Backends" +msgstr "پیکربندی پایانه‌ها..." + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" + +#: part/part.cpp:1409 +#, fuzzy, kde-format +#| msgid "Moves to the last page of the document" +msgid "Please enter the password to read the document:" +msgstr "به آخرین صفحه سند حرکت می‌کند" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +#| msgid "Password" +msgid "Document Password" +msgstr "اسم رمز" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "چاپ این سند مجاز نمی‌‌باشد." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "چاپ این سند مجاز نمی‌‌باشد." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "خروج از حالت ارائه" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "%1 را نتوانست باز کند" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&پیوسته‌" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&پیوسته‌" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +msgid "Close Document" +msgstr "باز کردن یک سند" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"این پیوند به کنش یک سند بسته اشاره دارد، که هنگام استفاده از مشاهده‌گر نهفته " +"کار نمی‌کند." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"این پیوند به کنش یک کاربرد خروج اشاره دارد، که هنگام استفاده از مشاهده‌گر " +"نهفته کار نمی‌کند." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "در حال بارگذاری مجدد سند..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "محتویات" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "رفتن به صفحه" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&صفحه:‌" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Rename this Bookmark" +msgstr "تغییر نام چوب الف" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Remove this Bookmark" +msgstr "تغییر نام چوب الف" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgid "Save As..." +msgid "Save As" +msgstr "ذخیره به عنوان..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "" + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"پرونده را نمی‌توان در »%1« ذخیره کرد. سعی کنید آن را در محل دیگری ذخیره کنید." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Filled form contents" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "User annotations" +msgstr "ارائه" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&پیوسته‌" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "File could not be saved in '%1'. %2" +msgstr "" +"پرونده را نمی‌توان در »%1« ذخیره کرد. سعی کنید آن را در محل دیگری ذخیره کنید." + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"پرونده را نمی‌توان در »%1« ذخیره کرد. سعی کنید آن را در محل دیگری ذخیره کنید." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "پایان ارائه" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "افزودن چوب الف" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "ابزارها" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "چاپ این سند مجاز نمی‌‌باشد." + +#: part/part.cpp:3221 +#, fuzzy, kde-format +#| msgid "Could not print the document. Please report to bugs.kde.org" +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "سند را نتوانست ذخیره کند. لطفاً، به bugs.kde.org گزارش دهید" + +#: part/part.cpp:3223 +#, fuzzy, kde-format +#| msgid "Could not print the document. Please report to bugs.kde.org" +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "سند را نتوانست ذخیره کند. لطفاً، به bugs.kde.org گزارش دهید" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "به جایی که قبلاً بودید، بروید" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "به جایی که بعداً بودید، بروید" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "بدون چوب الف" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&ویرایش‌" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&نما‌" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&رفتن‌" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&ابزارها‌" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "میله ابزار اصلی" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotation Toolbar" +msgstr "حاشیه‌نویسی" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "گزینه‌های عمومی" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "دستیابی‌پذیری" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "کمکهای خواندن دستیابی‌پذیری" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "کارایی" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "میزان‌‌سازی کارایی" + +#: part/preferencesdialog.cpp:44 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Configure Viewer" +msgstr "پیکربندی مشاهده‌گر..." + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "ارائه" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "گزینه‌هایی برای حالت ارائه" + +#: part/preferencesdialog.cpp:50 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation Options" +msgstr "ویژگیهای حاشیه‌نویسی" + +#: part/preferencesdialog.cpp:51 +#, fuzzy, kde-format +#| msgid "Filter Options" +msgid "Editor Options" +msgstr "گزینه‌های پالایش" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "یافتن بعدی" + +#: part/presentationwidget.cpp:169 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "ارائه" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "" + +#: part/presentationwidget.cpp:228 +#, fuzzy, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "ایجاد‌‌شده:" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "خروج از حالت ارائه" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "عنوان: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "صفحه‌‌ها: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "فشار دهید تا شروع شود" + +#: part/presentationwidget.cpp:505 +#, fuzzy, kde-format +#| msgid "Pages" +msgctxt "For Presentation" +msgid "Pause" +msgstr "صفحه‌ها" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"دو راه برای خروج از حالت ارائه وجود دارد؛ می‌توانید یا کلید گریز را فشار " +"دهید، یا دکمه خروج را که هنگام جای دادن موشی در گوشه راست بالا ظاهر می‌‌شود را " +"فشار دهید. البته می‌توانید پنجره‌ها را بچرخانید )پیش‌فرض دگرساز + تب(" + +#: part/presentationwidget.cpp:1609 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "پایان ارائه" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "پرونده ناشناخته" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 ویژگی" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&قلمها‌" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "در حال خواندن مجدد قلم..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "اندازه &صفحه‌" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "نوع ۱" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "نوع ۳" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "قلم حقیقی" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "ناشناخته" + +#: part/propertiesdialog.cpp:332 +#, fuzzy, kde-format +msgid "Embedded (subset)" +msgstr "بله )زیرمجموعه(" + +#: part/propertiesdialog.cpp:335 +#, fuzzy, kde-format +msgid "Fully embedded" +msgstr "نهفته" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "خیر" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "بله )زیرمجموعه(" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "بله" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "" + +#: part/propertiesdialog.cpp:386 +#, fuzzy, kde-format +msgid "Unknown font" +msgstr "ناشناخته" + +#: part/propertiesdialog.cpp:390 +#, fuzzy, kde-format +msgid "Embedded: %1" +msgstr "نهفته" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "نام" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "نوع" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "پرونده" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "صفحه‌ها" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgid "Size" +msgid "Size" +msgstr "اندازه" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "%1 را نتوانست باز کند" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "نتوانست %1 را باز کند. دلیل: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "برای پالایش صفحه‌ها، حداقل ۳ حرف وارد کنید" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "حساس به حالت" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "تطبیق عبارت" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "تطبیق تمام واژه‌ها" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "تطبیق هر واژه" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "گزینه‌های پالایش" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "گروه بر اساس صفحه" + +#: part/side_reviews.cpp:145 +#, fuzzy, kde-format +msgid "Group by Author" +msgstr "گروه بر اساس صفحه" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "نمایش مرورها فقط برای صفحه جاری" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +msgid "Unknown Algorithm" +msgstr "ناشناخته" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "پرونده ناشناخته" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "" + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "صفحه‌‌ها: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&ویژگیها‌" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Modifications:" +msgstr "سند برای باز کردن" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +msgid "Additional Information" +msgstr "حاشیه‌نویسی" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "حاشیه‌نویسی" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Version" +msgstr "سند برای باز کردن" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "فقط نمایش صفحه‌های چوب الف شده" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "" + +#: part/videowidget.cpp:143 +#, fuzzy, kde-format +#| msgid "Pages" +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "صفحه‌ها" + +#: part/videowidget.cpp:245 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "مهر" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "&Edit..." +msgstr "&ویرایش‌" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, fuzzy, kde-format +#| msgid "Wipe Down" +msgid "Move &Down" +msgstr "پاک کردن پایین" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "قادر به یافتن جزء okular نیست." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, fuzzy, kde-format +msgid "Unable to find the Okular component." +msgstr "قادر به یافتن جزء okular نیست." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"فشار دهید تا یک پرونده باز شود\n" +"فشار دهید و نگه دارید تا پرونده جاری باز شود" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"فشار دهید تا یک پرونده باز شود، یا فشار دهید و نگه دارید تا " +"پرونده اخیر گزینش شود" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +#| msgid "Next Page" +msgid "Next Tab" +msgstr "صفحه بعدی" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +#| msgid "Previous Page" +msgid "Previous Tab" +msgstr "صفحه قبلی" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +msgid "All files (*)" +msgstr "همه پرونده‌ها" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, fuzzy, kde-format +msgid "Open Document" +msgstr "باز کردن یک سند" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "بستن" + +#: shell/shell.cpp:606 +#, fuzzy, kde-format +#| msgid "" +#| "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"پرونده‌ای با نام »%1« از قبل موجود است. مطمئن هستید می‌خواهید آن را جای‌نوشت " +"کنید؟" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "پیش‌نمایشها" + +#~ msgid "&Review" +#~ msgstr "&بازبینی‌" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "نمایش تابلوی &ناوش‌" + +#, fuzzy +#~ msgid "Show Text" +#~ msgstr "رونوشت متن" + +#, fuzzy +#~ msgid "Large Icons" +#~ msgstr "شمایل" + +#, fuzzy +#~ msgid "Created: %1" +#~ msgstr "ایجاد‌‌شده:" + +#, fuzzy +#~ msgid "Style" +#~ msgstr "عنوان" + +#, fuzzy +#~ msgid "&Size:" +#~ msgstr "اندازه" + +#~ msgid "Inner color:" +#~ msgstr "رنگ درونی:" + +#, fuzzy +#~ msgid "Name: %1" +#~ msgstr "صفحه‌‌ها: %1" + +#, fuzzy +#~ msgid "Size: %1" +#~ msgstr "اندازه" + +#~ msgid "&Browse Tool" +#~ msgstr "ابزار &مرور‌" + +#~ msgid "&Zoom Tool" +#~ msgstr "ابزار &بزرگ‌نمایی‌" + +#, fuzzy +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "بزرگ‌نمایی" + +#, fuzzy +#~ msgid "&Selection Tool" +#~ msgstr "&برگزیدن ابزار‌" + +#, fuzzy +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "&برگزیدن ابزار‌" + +#~ msgid "&Text Selection Tool" +#~ msgstr "ابزار گزینش &متن‌" + +#, fuzzy +#~ msgid "T&able Selection Tool" +#~ msgstr "&برگزیدن ابزار‌" + +#, fuzzy +#~| msgid "Open a document" +#~ msgid "Only for PDF documents" +#~ msgstr "باز کردن یک سند" + +#, fuzzy +#~ msgid " None" +#~ msgstr "خیر" + +#, fuzzy +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "سند در حالت ارائه راه‌اندازی می‌باشد، زیرا پرونده، آن را درخواست کرد." + +#, fuzzy +#~ msgid "Presentation Mode" +#~ msgstr "خروج از حالت ارائه" + +#, fuzzy +#~ msgid "Allow the presentation mode" +#~ msgstr "خروج از حالت ارائه" + +#, fuzzy +#~ msgid "Do not allow the presentation mode" +#~ msgstr "گزینه‌هایی برای حالت ارائه" + +#, fuzzy +#~ msgid "Save &Copy As..." +#~ msgstr "ذخیره به عنوان..." + +#, fuzzy +#~| msgid "Document to open" +#~ msgctxt "A document format, Okular-specific" +#~ msgid "Document Archive" +#~ msgstr "سند برای باز کردن" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "به پایان سند رسید.\n" +#~ "از ابتدا ادامه می‌دهید؟" + +#, fuzzy +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "به پایان سند رسید.\n" +#~ "از ابتدا ادامه می‌دهید؟" + +#~ msgid "Current maintainer" +#~ msgstr "نگه‌دارنده جاری" + +#~ msgid " sec." +#~ msgstr " ثانیه" + +#~ msgid "Pencil color:" +#~ msgstr "رنگ مداد:" + +#, fuzzy +#~| msgid "Starting KTTSD Failed: %1" +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "خرابی در آغاز KTTSD: %1" + +#, fuzzy +#~ msgid "All Visible Columns" +#~ msgstr "همیشه مرئی" + +#~ msgid "No document opened." +#~ msgstr "سندی باز نشد." + +#~ msgid "No matches found for '%1'." +#~ msgstr "برای »%1«، تطبیقی یافت نشد." + +#~ msgid "Identity Settings" +#~ msgstr "تنظیمات هویت" + +#~ msgid "Highlight Properties" +#~ msgstr "ویژگیهای مشخص" + +#~ msgid "Ink Properties" +#~ msgstr "ویژگیهای جوهر" + +#, fuzzy +#~| msgid "Annotation" +#~| msgid_plural "%1 Annotations" +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "حاشیه‌نویسی" + +#, fuzzy +#~ msgid "Yellow Highlighter" +#~ msgstr "خط زیر" + +#, fuzzy +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "خط زیر" + +#, fuzzy +#~ msgid "Black Underlining" +#~ msgstr "خط زیر" + +#~ msgid "Ink" +#~ msgstr "مرکب" + +#~ msgid "Enable &background generation" +#~ msgstr "فعال‌‌‌سازی ایجاد &زمینه‌" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "به اولین صفحه سند حرکت می‌کند" + +#, fuzzy +#~| msgid "Overwrite" +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "جای‌نوشت" + +#~ msgid "Pages:" +#~ msgstr "صفحه‌ها:" + +#, fuzzy +#~ msgid "Green Highlighter" +#~ msgstr "خط زیر" + +#~ msgid "Pages Size" +#~ msgstr "اندازه صفحه‌‌‌ها" + +#~ msgid "" +#~ "The document is trying to execute an external application and for your " +#~ "safety okular does not allow that." +#~ msgstr "" +#~ "سند سعی در اجرای یک کاربرد خارجی دارد، و okular برای امنیت به شما اجازه " +#~ "این کار را نمی‌دهد." + +#, fuzzy +#~| msgid "Icon" +#~ msgid "Big Icons" +#~ msgstr "شمایل" + +#~ msgid "Embedded" +#~ msgstr "نهفته" + +#~ msgid "Configure okular..." +#~ msgstr "پیکربندی okular..." + +#~ msgid "" +#~ "The document is going to be launched on presentation mode because the " +#~ "file requested it." +#~ msgstr "سند در حالت ارائه راه‌اندازی می‌باشد، زیرا پرونده، آن را درخواست کرد." + +#, fuzzy +#~| msgid "Color Modes" +#~ msgid "Color Mode:" +#~ msgstr "حالتهای رنگ" + +#, fuzzy +#~| msgid "&Invert colors" +#~ msgid "Invert colors" +#~ msgstr "&وارونه کردن رنگها‌" + +#, fuzzy +#~| msgid "Change &paper color" +#~ msgid "Change paper color" +#~ msgstr "تغییر رنگ &کاغذ‌" + +#, fuzzy +#~| msgid "&Change dark and light colors" +#~ msgid "Change dark and light colors" +#~ msgstr "&تغییر رنگهای تیره و روشن‌" + +#, fuzzy +#~| msgid "Convert to &black and white" +#~ msgid "Convert to black and white" +#~ msgstr "تبدیل به &سیاه و سفید‌" + +#~ msgid "&Properties..." +#~ msgstr "&ویژگیها‌..." + +#, fuzzy +#~| msgid "Highlight" +#~ msgid "Pink Highlighter" +#~ msgstr "خط زیر" + +#, fuzzy +#~| msgid "Could not load the necessary plugin to view the document" +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "نتوانست وصله لازم برای مشاهده سند را بار کند" + +#~ msgid "Copy Link Location" +#~ msgstr "رونوشت محل پیوند" + +#~ msgid "Fit &Text" +#~ msgstr "متناسب با &متن‌" + +#~ msgid "*|All the Files" +#~ msgstr "*|همه پرونده‌ها" + +#~ msgid "&Advanced" +#~ msgstr "&پیشرفته‌" + +#~ msgid "Contents:" +#~ msgstr "محتویات:" + +#~ msgid "" +#~ "File Error! Could not create temporary file." +#~ msgstr "" +#~ "خطای پرونده! نتوانست پرونده موقت را ایجاد کند." + +#~ msgid "Hide &Navigation Panel" +#~ msgstr "مخفی کردن تابلوی &ناوش‌" + +#~ msgid "page %1" +#~ msgstr "صفحه %1" + +#~ msgid "Show &search bar in thumbnails list" +#~ msgstr "نمایش میله &جستجو در فهرست ریزنقش‌" + +#~ msgid "Free Text" +#~ msgstr "متن آزاد" + +#~ msgid "Pencil" +#~ msgstr "مداد" + +#~ msgid "Form" +#~ msgstr "برگه" + +#~ msgid "Program Look" +#~ msgstr "ظاهر برنامه" + +#~ msgid "FreeText Properties" +#~ msgstr "ویژگیهای FreeText" diff --git a/po/fi/okular.po b/po/fi/okular.po new file mode 100644 index 0000000..ffdbc85 --- /dev/null +++ b/po/fi/okular.po @@ -0,0 +1,5826 @@ +# Translation of okular.po into Finnish +# +# KDE Finnish translation sprint participants: +# Author: Artnay +# Author: Lliehu +# Author: Niklas Laxström +# Teemu Rytilahti , 2003. +# Kim Enkovaara , 2004, 2005, 2006. +# Ilpo Kantonen , 2005. +# Mikko Ikola , 2006. +# Niklas Laxström , 2007. +# Mikko Piippo , 2007, 2008. +# Mikko Piippo , 2008. +# Sasu Karttunen , 2010. +# Lasse Liehu , 2010, 2011, 2012, 2013, 2014, 2015, 2016. +# Jiri Grönroos , 2012. +# Niklas Laxström , 2012. +# Tommi Nieminen , 2012, 2016, 2018, 2019, 2020, 2021. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-12-18 14:25+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:13+0000\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Teemu Rytilahti, Mikko Ikola, Niklas Laxström, Mikko Piippo, Sasu Karttunen, " +"Lasse Liehu, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"teemu.rytilahti@kde-fi.org, ikola@iki.fi, niklas.laxstrom+kdetrans@gmail.com," +"mikko.piippo@helsinki.fi, sasu.karttunen@tpnet.fi, lasse.liehu@gmail.com, " +"translator@legisign.org" + +# pmap: =/gen=Okularin/ +# pmap: =/elat=Okularista/ +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, yleiskäyttöinen tiedostokatselin" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004–2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004–2017 Albert Astals Cid\n" +"© 2006–2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Aiempi ylläpitäjä" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Paljon kehystyötä, ODT- ja FictionBook-taustaohjelmat" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Kehittäjä" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Loi Okularin KPDF:n pohjalta" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF-kehittäjä" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Merkintöjen grafiikka" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Taulukonvalintatyökalu" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Parannuksia merkintöihin" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Siirry sivulle %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Avaa ulkoinen tiedosto" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Suorita %1…" + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Ensimmäinen sivu" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Edellinen sivu" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Seuraava sivu" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Viimeinen sivu" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Edellinen" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Seuraava" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Lopeta" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Aloita esitys" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Päätä esitys" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Etsi…" + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Siirry sivulle…" + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Toista ääni…" + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript-komentojono" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Toista elokuva…" + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Toista elokuva" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Pysäytä elokuva" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Tauota elokuva" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Jatka elokuvan toistoa" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Taustaosan valinta" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Tiedoston MIME-tyypille
%1 (%2)
on useita taustaosia." +"

Valitse käytettävä taustaosa:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Useimmat sivut ovat kokoa %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Pysty-%1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Vaaka-%1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 × %2 tuumaa (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 × %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Jatketaan hakua alusta" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Jatketaan hakua lopusta" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Annetun tiedoston käsittelyyn vaadittavaa liitännäistä ei löytynyt." + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "merkintöjen poisto" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Tiedosto yrittää suorittaa ulkoista sovellusta, mutta turvallisuussyistä " +"Okular ei salli sitä." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Sovellusta ei löytynyt MIME-tyypin %1 avaamiseksi." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Väliaikaistiedostoa ei voitu avata" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Tulostusmuunnos epäonnistui" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Tulostusprosessi kaatui" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Tulostusprosessi ei käynnistynyt" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Tiedoston tulostaminen epäonnistui" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Tulostin on virheellisessä tilassa" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Tulostettavaa tiedostoa ei löytynyt" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Ei tulostettavaa" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Tulostamiseen sopivaa ohjelmaa ei löytynyt. Varmista, että CUPS:n lpr-" +"ohjelma on saatavilla." + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Sivun tulostuskoko on virheellinen" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Tiedostoa %1 ei voitu avata. Se ei ole olemassa." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Otsikko" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Aihe" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Kuvaus" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Tekijä" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Luoja" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Tuottaja" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Tekijänoikeudet" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Sivuja" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Luotu" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Muutettu" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME-tyyppi" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Luokka" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Avainsanat" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Tiedoston sijainti" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Tiedostokoko" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Sivukoko" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "merkinnän lisäys" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "merkinnän poisto" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. Kyseessä on yksittäisen merkinnän ominaisuudet. +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "merkinnän ominaisuuksien muutos" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "merkinnän siirto" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "merkinnän säätö" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "tekstin muokkaus" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "merkinnän sisällön muokkaus" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "lomakkeen sisällön muokkaus" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "lomakkeen luettelovalintojen muokkaus" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "yhdistelmälomakkeen valinnan muokkaus" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "lomakkeen painiketilan muokkaus" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Pelkkä &teksti…" + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument-tiedosto" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML " + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Tulostusvalinnat" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Sovita tulostusalueeseen" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Sovita koko sivulle" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Skaalaus:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Hälytystyyppi puuttuu" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Älä näytä tätä viestiä uudelleen" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Lähde: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Oletusfontti:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Punainen" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Oranssi" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Keltainen" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Vihreä" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Syaani" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Sininen" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Violetti" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Valkoinen" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Harmaa" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Musta" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Leveys %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1 %" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Merkintäviivan paksuus (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Merkinnän väri (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Merkinnän täyttöväri (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Merkinnän peittävyys (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Merkinnän fontti (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Lisää nykyinen merkintä merkintöjen pikavalikkoon (merkintöjä ei " +"valittu)Lisää nykyinen merkintä merkintöjen pikavalikkoon (merkintöjä ei " +"valittu)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Rajoita kuvasuhde 1:1:een tai kulmaa 15 asteen askelin (merkintää ei valittu)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "Nykyisen merkintätyökalun lisäasetukset (merkintöjä ei valittu)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Merkintäviivan paksuus" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Merkintäviivan paksuus (nykyisellä merkinnällä ei ole viivan " +"paksuutta)Merkintäviivan paksuus (nykyisellä merkinnällä ei ole viivan " +"paksuutta)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Merkinnän tekstiväri" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Merkinnän reunaväri" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Merkinnän väri" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Merkinnän täyttöväri" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "Merkinnän täyttöväri (nykyisellä merkinnällä ei ole täyttöväriä)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Merkinnän fontti" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Merkinnän fontti (nykyisellä merkinnällä ei ole fonttia)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Rajoita kulmaa 15° askelin" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Rajoita kuvasuhde 1:1:een" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Rajoita kuvasuhde 1:1:een tai kulmaa 15° askelin (nykyinen merkintä ei tue)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Merkinnän peittävyys" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Lisää nykyinen merkintä merkintöjen pikavalikkoon" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Nykyisen merkintätyökalun lisäasetukset" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Väri" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Täyttöväri" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Läpinäkyvä" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Mukautettu väri…" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"PDF-tiedostoon lisätyt leimat eivät näy muissa PDF-katselimissa kuin " +"Okularissa" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Kokeellinen ominaisuus" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Valitse väri" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Merkinnät" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Piilota" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Korostuskynä" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Alleviivaus" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Koukeroinen alleviivaus" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Yliviivaus" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Kirjoituskone" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Tekstinsisäinen muistiinpano" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Ponnahdusmuistiinpano" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Vapaamuotoinen viiva" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Suora viiva" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Nuoli" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Suorakulmio" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Soikio" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Monikulmio" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometriset muodot" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Leima" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Pikamerkinnät" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Valitse pikamerkinnöistä merkintätyökalu" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Lisää pikamerkintöihin" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Pidä aktiivisena" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Pidä merkintätyökalu aktiivisena käytön jälkeen" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Merkinnän kuvasuhteen- tai kulmanrajaustyökalut" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Fontti" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Merkintäasetukset" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Viivan paksuus" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Peittävyys" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Sivu %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Merkintä" +msgstr[1] "%1 merkintää" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Avaa ponnahdusmuistiinpano" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Poista" + +# &-merkki o-kirjaimessa meni OK-painikkeen o:n kanssa päällekkäin. +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "O&minaisuudet" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Tallenna ”%1”…" + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Ulkoasu" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Yleistä" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Tekijä:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Luotu:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Muutettu:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Ponnahdusmuistiinpanon ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Kirjoituskoneen ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Rivien välisen muistiinpanon ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Suoran viivan ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Monikulmion ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Sivuasetusten ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Tekstin merkinnän ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Leimaominaisuudet" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Vapaamuotoisen viivan ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Leimasimen asetukset" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Liitetiedoston ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Äänen ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Videon ominaisuudet" + +# Yksittäisen merkinnän ominaisuudet +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Merkinnän ominaisuudet" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Muutettu: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Valitse tiedostosta mukautettu leimasymboli" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Valitse mukautettu leimasymboli" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Kuvaketiedostot (*.ico *.png *.xpm *.svg *." +"svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Tiedoston %1 avaaminen epäonnistui." + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Virheellinen tiedosto" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Väri:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr " %" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Peittävyys:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Kuvake:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Kommentti" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Ohje" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Lisää" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Avain" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Uusi kappale" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Muistiinpano" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Kappale" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Fontti:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "T&ekstiväri:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Tasaus:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Vasemmalle" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Keskelle" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Oikealle" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "&Reunan leveys:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Hyväksytty" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Sellaisenaan" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Luottamuksellinen" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Osastollinen" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Luonnos" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Kokeellinen" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Lopullinen" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Kommentoitavaksi" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Julkistetaan" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Ei hyväksytty" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ei julkisuuteen" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Myyty" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Huippusalainen" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Kirjanmerkki" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Tietoja" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Kokeellinen ominaisuus.PDF-tiedostoon lisätyt leimat eivät näy " +"muissa PDF-katselimissa kuin Okularissa." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "&Leimasymboli:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Paksuus:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Viivan alku:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Viivan pääte:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Neliö" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Ympyrä" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Timantti" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Avonuoli" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Suljettu nuoli" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Ei mitään" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Pääty" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Avonuoli oikealle" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Suljettu nuoli oikealle" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Vinoviiva" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Apuviivan pituus:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Apuviivan jatkeen pituus:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Käytössä" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Kuviotäyttö:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tyyppi:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Korostus" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Koukeroinen alleviivaus" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Alleviivaus" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Yliviivaus" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Suorakulmio" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Soikio" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Liitetiedoston symboli:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graafi" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Neula" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Paperiliitin" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Sisältökuvaus" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Tiedosto" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "ei ilm." + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Ei kuvausta saatavilla." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nimi:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Kuvaus:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Leimasinsymboli:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ei mitään" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Sulje tämä muistiinpano" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Asetukset" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Merkintä saattaa sisältää LaTeX-koodia.\n" +"Näytä napsauttamalla tästä." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "latex-ohjelmatiedostoa ei löydy." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX-piirto epäonnistui" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "dvipng-ohjelmatiedostoa ei löydy." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "latex-komennon suorittamisessa ilmeni ongelma." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "dvipng-komennon suorittamisessa ilmeni ongelma." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Yksi kirjanmerkki" +msgstr[1] "" +"%1\n" +"\n" +"%2 kirjanmerkkiä" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Kirjanmerkit" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Etsi…" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Vain tämä tiedosto" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Siirry kirjanmerkkiin" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Muuta kirjanmerkin nimeä" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Poista kirjanmerkki" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Avaa tiedosto" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Poista kirjanmerkit" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versio" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Sarjanumero" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Myöntäjä" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Myönnetty" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Vanhenee" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Aihe" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Julkinen avain" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Avaimen käyttö" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bittiä)" + +# &-merkki o-kirjaimessa meni OK-painikkeen o:n kanssa päällekkäin. +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Ominaisuus" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Arvo" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Varmennekatselin" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Vie…" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Yleiset" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Myöntäjä" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Yleinen nimi (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Sähköposti" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisaatio (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Kenelle myönnetty:" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Kelpoisuus" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Sormenjäljet" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "SHA-1-sormenjälki" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "SHA-256-sormenjälki" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Yksityiskohdat" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Varmennetieto:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Minne haluat tallentaa varmenteen?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Varmennetiedosto (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Varmennetta ei voitu viedä" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Punainen" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Vihreä" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Sininen" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Keltainen" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Musta" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Valkoinen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Piirrä &kuville kehykset" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Piirrä &linkeille kehykset" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Muuta &värejä" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Varoitus: valinta voi vaikuttaa piirtonopeuteen." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Väritila:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Käänteiset värit" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Muuta paperin väriä" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Vaihda tummat ja vaaleat värit" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Muunna mustavalkoiseksi" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Käännä valoisuus" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Käännä Luma (lineaarinen sRGB)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Käännä Luma (symmetrinen)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Positiivinen sävysiirtymä" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Negatiivinen sävysiirtymä" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Paperin väri:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Tumma väri:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Vaalea väri:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Raja-arvo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrasti:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Puhe" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Moottori" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Tunnistus" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "&Tekijä:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Huomaa: tietoa käytetään vain tarkasteluihin. Tieto tallennetaan " +"merkittyyn tiedostoon ja se kulkee siis tiedoston mukana." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Pikamerkintätyökalut" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Mukautettu tekstimuokkain" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Aseta valinnainen komento tekstimuokkaimen käynnistykseen.
\n" +"Voit myös käyttää seuraavia muuttujia:\n" +"
    \n" +"
  • %f – tiedostonimi
  • \n" +"
  • %l – rivi
  • \n" +"
  • %c – sarake
  • \n" +"
\n" +"Jos %f-muuttujaa ei ole asetettu, tiedostonimi lisätään valitsemasi komennon " +"loppuun." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Muokkain" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Muokkain:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "Valitse muokkain jolla Okular avaa alkuperäiset tiedostot." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Komento:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Ulkoasu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Käytä tasaista vieritystä" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Näytä vierity&spalkit" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Yhdistä &pienoiskuvat sivuihin" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Näytä &vinkit ja infoviestit" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Näytä tiedoston nimi otsikkorivillä, jos käytettävissä" + +# HUOM! Tässä on pakko tehdä erotus tiedosto != asiakirja, koska kyse ei ole tiedostojärjestelmään tallennetusta nimestä vaan tiedoston sisällä olevasta otsikosta +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Ellei asiakirjan otsikkoa näytetä:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Näytä vain tiedostonimi" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Näytä tiedoston koko polkunimi" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Aseta oma taustaväri" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Ohjelman toiminnot" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Avaa uudet tiedostot &välilehtiin" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Jos tiedosto on jo auki, vaihda sen välilehteen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Noudata DRM-rajoituksia" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "Avaa tiedosto &uudestaan sen muututtua" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Näytä taustaosan valintaikkuna" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Lukusuunta oikealta vasemmalle" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Katseluasetukset" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Sarakkeita yleiskatsauksessa:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Määrittää paljonko nykyisestä katselualueesta jää näkyviin, kun näkymää " +"vieritetään Page Up/Down -näppäimillä." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "P&gUp/Down -lomitus:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr " %" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Määrittää lähennyksen oletusarvon aiemmin avaamattomille tiedostoille.\n" +"Jo avattuihin tiedostoihin käytetään edelliskerran asetusta." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Määrittää lähennyksen oletusarvon aiemmin avaamattomille tiedostoille.\n" +"Jo avattuihin tiedostoihin käytetään edelliskerran asetusta." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Oletuslähennys:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100 %" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Sovita leveyteen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Sovita sivu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automaattisovitus" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Vähentää tarvittavan muistin määrää. Järjestelmille, joissa on vähän muistia." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Kompromissi muistin käytön ja nopeuden välillä. Avaa seuraavan sivun " +"etukäteen ja tehostaa hakuja. (Sopii järjestelmille, joilla on noin 2 Gt " +"muistia.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Pitää kaiken muistissa. Avaa seuraavan sivun etukäteen ja tehostaa hakuja. " +"Sopii järjestelmille, joilla on yli 4 Gt muistia." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Avaa kaiken muistiin ja säilyttää siellä. Avaa ennakkoon kaikki sivut. " +"(Käyttää enintään 50 % vapaasta tai kokonaismuistista sen mukaan, kumpi on " +"suurempi.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Suoritinkäyttö" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Salli &läpinäkyvät tehosteet" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Muistinkäyttö" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Alhainen" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Tavallinen (oletus)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "A&ggressiivinen" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Ahne" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Piirtäminen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Pehmennä tekstiä" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Pehmennä grafiikkaa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Käytä tekstin vihjeistystä" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Nykyinen näyttö" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Oletusnäyttö" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Näyttö: %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " s välein" +msgstr[1] " s välein" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Selaus" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Etene:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Palaa viimeiseltä sivulta alkuun" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Kosketusnavigointi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Siirry taakse/eteenpäin napauttamalla vasenta/oikeaa puolta" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Siirry eteenpäin napauttamalla minne tahansa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Ei käytössä" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Taustaväri:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Hiiriosoitin:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Piilota viivästettynä" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Aina näkyvissä" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Aina piilotettu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Näytä &edistyminen" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Näytä &yhteenvetosivu" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Salli siirtymät" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Oletussiirtymä:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Verhot pystysuunnassa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Verhot vaakatasossa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Laatikko sisään" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Laatikko ulos" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Liuota" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Häivytä" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Välkytä alas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Välkytä oikealle" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Välkytä alaoikealle" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Satunnainen siirtymä" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Korvaa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Jaa vaakasuunnassa sisään" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Jaa vaakasuunnassa ulos" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Jaa pystysuunnassa sisään" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Jaa pystysuunnassa ulos" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Pyyhi alas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Pyyhi oikealle" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Pyyhi vasemmalle" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Pyyhi ylös" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Sijoitus" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Näyttö:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Piirrostyökalun asetukset" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Piirrostyökalu: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Kumi" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nimi:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tyyppi:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Ponnahdusmuistiinpano" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Tekstinsisäinen muistiinpano" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Vapaamuotoinen viiva" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Suora viiva" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Monikulmio" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Tekstin merkintä" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrinen muoto" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Leima" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Kirjoituskone" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Luo merkintätyökalu" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Muokkaa merkintätyökalua" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Väri:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Kynän &paksuus:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Luo piirrostyökalu" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Muokkaa piirrostyökalua" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Tuntematon" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Upotetut tiedostot" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Näytä" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nimi" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Kuvaus" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Koko" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Luotu" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Muutettu" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Tallenna nimellä…" + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Näytä…" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Tulostuksen esikatseluun tarvittavan osan lataus epäonnistui" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Esikatselu" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Sulje" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Etsi:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Haettava teksti" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Seuraava" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Siirry seuraavaan osumaan" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Edellinen" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Siirry edelliseen osumaan" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Muuta hakuvalintoja" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Huomioi kirjainkoko" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Nykyisestä sivusta" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Etsi kirjoittamalla" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Kaikki tiedostot" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Allekirjoituksen ominaisuudet" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Suora viiva huomautuksella" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Monikulmio huomautuksella" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Sivuasetukset huomautuksella" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Sivuasetukset" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Korostus huomautuksella" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Koukeroinen alleviivaus huomautuksella" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Alleviivaus huomautuksella" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Yliviivaus huomautuksella" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Yliviivaus" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Leima huomautuksella" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Vapaamuotoinen viiva huomautuksella" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Caret" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Liitetiedosto" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Ääni" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Video" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Näyttö" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Käyttöliittymäelementti" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Multimediasisältö" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Tuntematon" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Tekijä: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Minne haluat tallentaa tiedoston %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" +"Kohdetta %1 ei voitu avata kirjoittamista varten. Tiedostoa ei tallennettu." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Haun valinnat" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Huomioi kirjainkoko" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Toistuva esiinyminen" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Etsi:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Tasot" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "/" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Lähennys" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Sovita 100 %" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Kierrä &oikealle" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Oikea" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Kierrä &vasemmalle" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Vasen" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Alkuperäinen suunta" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Näkymän rajaus" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Ra&jaa reunukset" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Rajaa &valintaan" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Sovita &leveyteen" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Sovita &sivu" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automaattisovitus" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Sovi&ta ikkuna sivuun" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "L&ukutila" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Yks&ittäinen sivu" + +# Tämä on tyhmä asetus: aukeaman kaltainen mutta vasemmalla puolella on pariton sivu +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "&Vastakkaiset sivut" + +# Tämä on parempi asetus kuin ”Facing Pages”: pariton sivu vasemmalle, ensimmäinen (pariton) sivu yksin keskitettynä +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Vastakkais&et sivut (keskitä ensimmäinen sivu)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "&Yleiskuva" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Jatkuva" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Käytä lukusuuntaa oikealta vasemmalle" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Selaa" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Lähennä" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "&Värien muuttaminen käytössä/ei käytössä" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Alueen valinta" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "&Tekstivalinta" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "&Taulukkovalinta" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "Suu&rennuslasi" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Valintatyökalut" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Lue koko tiedosto ääneen" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Lue tämä sivu ääneen" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Lopeta lukeminen" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Tauko/Jatka puhumista" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Vieritä ylös" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Vieritä alas" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Vieritä sivua ylös" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Vieritä sivua alas" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Näytä lomakkeet" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Avattiin yhden sivun tiedosto." +msgstr[1] " Avattiin %1 sivun tiedosto." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Teksti (1 merkki)" +msgstr[1] "Teksti (%1 merkkiä)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopioi leikepöydälle" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "DRM-rajoitukset eivät salli kopiointia" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Puhu teksti" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Kuva (%1×%2 kuvapistettä)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Tallenna tiedostoon…" + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Kuva [%1 × %2] kopioitu leikepöydälle." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Tallenna tiedosto" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Kuvat (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Tiedostoa ei tallennettu." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Kuva [%1×%2] tallennettiin tiedostoon %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopioi teksti" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Siirry osoitteeseen %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Etsi ”%1” hakukoneella" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "WWW-pikavalintojen asetukset…" + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Seuraa tätä linkkiä" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Toista tämä ääni" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Pysäytä ääni" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopioi linkin osoite" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Etsi ”%1” tästä tiedostosta" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Tervetuloa" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Valitse lähennysalue. Loitonna hiiren oikealla painikkeella." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Napsauta nähdäksesi suurennetun alueen." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Kopioi tekstiä tai grafiikkaa valitsemalla ne." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Valitse teksti" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Piirrä suorakulmio taulukon ympärille, ja jaa se sitten sarakkeisiin " +"napsauttamalla lähellä reunoja. Poista valinta painamalla Esc." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Piirrä suorakaide sivualueen ympärille, jonka haluat pitää näkyvissä" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Uusi muistiinpano" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Uuden muistiinpanon teksti:" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Kirjanmerkkimerkintä" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Lisää merkinnälle mukautettu nimi:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Piirrä soikio (valitse alue hiirellä)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Korosta tekstiä" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Piirrä viiva vapaalla kädellä" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Tekstin kommentointi riveille (valitse alue hiirellä)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Sijoita ponnahdusmuistiinpano" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Piirrä monikulmio (lopeta napsauttamalla alkupistettä)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Piirrä suorakulmio" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Tekstin koukeroinen alleviivaus" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Leimaa" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Piirrä suora viiva" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Tekstin yliviivaus" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Tekstin alleviivaus" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Kirjoituskonemerkintä (valitse alue vetämällä)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Korostuskynä" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Lisää suosikkimerkintä" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Merkinnän mukautettu nimi:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Tiedosto" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Asetukset" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "O&hje" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Suunta" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Kirjanmerkit" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Katselintyökalurivi" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Pienoiskuvat" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Merkinnät" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Tiedosto sisältää merkintöjä tai lomakkeita, jotka on tallennettu sisäisesti " +"Okularin aiemmalla versiolla. Sisäistä tallennusta ei enää tueta.
Tallenna tiedosto siirtääksesi nämä osat, jos haluat jatkaa tiedoston " +"muokkausta." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Tiedostoon on upotettu muita tiedostoja. Katso upotetut tiedostot napsauttamalla tästä tai valitsemalla " +"Tiedosto → Upotetut tiedostot." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Edellinen" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Siirry edelliselle sivulle" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Siirtyy tiedoston edelliselle sivulle" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Seuraava" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Siirry seuraavalle sivulle" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Siirtyy tiedoston seuraavalle sivulle" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Tiedoston alkuun" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Siirtyy tiedoston alkuun" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Tiedoston loppuun" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Siirtyy tiedoston loppuun" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Muuta nykyisen kirjanmerkin nimeä" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Edellinen kirjanmerkki" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Siirry edelliseen kirjanmerkkiin" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Seuraava kirjanmerkki" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Siirry seuraavaan kirjanmerkkiin" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Okularin asetukset…" + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Asiakirjakatselimen asetukset…" + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Katselintaustaosien asetukset…" + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Taustaosa-asetukset…" + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Tietoa taustaosasta" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Avaa uu&destaan" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Avaa tiedosto levyltä uudelleen…" + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Sulje &hakurivi" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Sivunumero" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Valitse sivun kaikki teksti" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Näytä si&vupalkki" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Näytä &sivurivi" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Näytä &allekirjoituspaneeli" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Upotetut tiedostot" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&Vie muodossa" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Jaa" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "E&sitys" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Avaa yläkansio" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Tuo Postscript PDF:ksi…" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Etsi verkosta kirjoja…" + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Vaihda mustaan ruutuun" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Poista piirrokset" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Merkintäasetukset…" + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Jatka/keskeytä esitys" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Ei voitu avata: ”%1” (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Tiedoston %1 avaaminen peruttiin." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Tiedostoa %1 ei voitu avata. Syy: %2." + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Katselimen taustaosien asetukset" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Taustaosa-asetukset" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"ps2pdf ei-ohjelma löytynyt, joten Okular ei voi käyttää sitä Postscript-" +"tiedostojen tuontiin." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf-ohjelmaa ei löytynyt" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Postscript-tiedostot (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Tuodaan Postscript-tiedosto PDF:ksi (voi kestää hetken)…" + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Syötä tiedoston lukemiseen vaadittava salasana:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Salasana on väärin. Yritä uudelleen:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Tiedoston salasana" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "Tiedostossa on XFA-lomakkeita, joita ei toistaiseksi tueta." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Tiedostossa on lomakkeita. Käytä niitä napsauttamalla painiketta tai " +"valitsemalla Näytä → Näytä lomakkeet." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Kaikki muokkaus- ja vuorovaikutteiset ominaisuudet on poistettu käytöstä. " +"Muokataksesi tiedostoa tallenna siitä kopio ja avaa se." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Tiedosto on digitaalisesti allekirjoitettu." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Tämä tiedosto on digitaalisesti allekirjoitettu. Viime allekirjoittamisen " +"jälkeen on tullut muutoksia." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Tämä tiedosto on digitaalisesti allekirjoitettu. Joitakin allekirjoituksia " +"ei voitu varmentaa kunnolla." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "Tiedosto haluaa tulla esitetyksi koko näytöllä." + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Pyyntö näyttötilan muuttamiseksi" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Siirry esitystilaan" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Hylkää pyyntö" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Ei voitu avata: ”%1”. (%2)" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Muutoksia on tallentamatta, ja toinen ohjelma on muuttanut tiedostoa ”%1”. " +"Muutokset menetetään, koska tiedostoa ei enää voi tallentaa.
Haluatko " +"jatkaa tiedoston uudelleenavausta?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Tiedosto on muuttunut" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Jatka uudelleenavausta" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Keskeytä uudeelleenavaus" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Muutoksia on tallentamatta, ja toinen ohjelma on muuttanut tiedostoa ”%1”. " +"Muutokset menetetään, koska tiedostoa ei enää voi tallentaa.
Haluatko " +"silti sulkea tiedoston?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Sulje tiedosto" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Peru sulkeminen" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Haluako tallentaa vai hylätä tiedoston ”%1” muutokset?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Sulje tiedosto" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Tämä linkki osoittaa tiedoston sulkemistoimintoon, joka ei toimi upotetussa " +"katselimessa." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Tämä linkki osoittaa sovelluksen lopetustoimintoon, joka ei se toimi " +"upotetussa katselimessa." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Avataan tiedostoa uudelleen…" + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Sisältö" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Allekirjoitukset" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Siirry sivulle" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Sivu:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Anna uudelle kirjanmerkille nimi:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Muuta tämän kirjanmerkin nimeä" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Poista tämä kirjanmerkki" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Tallenna nimellä" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Toinen ohjelma on muuttanut tiedostoa ”%1” eikä sitä voi enää tallentaa." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Tiedosto on suojattu salasanalla.
Tiedosto on sen tallentamiseksi " +"avattava uudelleen. Salasanaa kysytään toistamiseen ja kumoamishistoria " +"menetetään.
Haluatko jatkaa?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Tallennus – Varoitus" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Väliaikaistiedostoa tiedoston tallentamiseksi ei voitu avata." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Tallennuksen jälkeen nykyinen tiedostomuoto vaatii avaamaan tiedoston " +"uudelleen. Kumoamishistoria menetetään.
Haluatko jatkaa?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Tiedostoa ei voi tallentaa kohteeseen ”%1”. Yritä tallentaa se muualle." + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "lomakkeen sisältö" + +# Tekstiä käytetään viestien ”Undo %1” ja ”Redo %1” yhteydessä. +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "käyttäjän merkinnät" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Olet tallentamassa muutoksia, mutta nykyinen tiedostomuoto ei tue seuraavien " +"elementtien tallennusta. Säilyttääksesi ne käytä Okularin " +"tiedostoarkisto -muotoa." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Varoitus" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Tallenna Okularin tiedostoarkistoksi…" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Olet tallentamassa muutoksia, mutta nykyinen tiedostomuoto ei tue seuraavien " +"elementtien tallentamista. Säilyttääksesi ne käytä Okularin " +"tiedostoarkisto -muotoa. Tallenna tiedosto nämä elementit hyläten " +"napsauttamalla Jatka." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Olet tallentamassa muutoksia, mutta nykyinen tiedostomuoto ei tue seuraavien " +"elementtien tallentamista. Säilyttääksesi ne käytä Okularin " +"tiedostoarkisto -muotoa. Tallenna napsauttamalla Jatka, jolloin " +"nämä elementit samoin kuin kumoamishistoriasi hylätään." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Jatka" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Jatka muutokset menettäen" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Tiedostoa ei voi tallentaa kohteeseen ”%1”. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular ei voi kopioida tiedostoa %1 määritettyyn paikkaan.\n" +"\n" +"Tiedostoa ei ole enää olemassa." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Tiedostoa ei voi tallentaa kohteeseen ”%1”. Virhe: %2. Yritä tallentaa se " +"muualle." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Laajenna koko osio" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Supista koko osio" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Laajenna kaikki" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Supista kaikki" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Lisää kirjanmerkki" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Työkalut" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Tulosta" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Tämän tiedoston tulostamista ei ole sallittu." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Tiedoston tulostaminen epäonnistui. Tuntematon virhe. Ilmoita tästä bugs.kde." +"org-palveluun." + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Tiedoston tulostaminen epäonnistui. Yksityiskohtainen virhe on ”%1”. Ilmoita " +"tästä bugs.kde.org-palveluun." + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Mene paikkaan, jossa olit aiemmin" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Mene paikkaan, jossa olit myöhemmin" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Tiedostovirhe! Väliaikaistiedostoa %1 ei voitu luoda." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Tiedostovirhe! Tiedostoa %1 ei voitu avata pakkauksen purkamiseksi. Tiedostoa ei avata." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Tämä virhe esiintyy useimmiten, kun käyttöoikeudet eivät riitä tiedoston " +"lukemiseen. Omistajan ja käyttöoikeudet voi tarkistaa napsauttamalla " +"tiedostoa hiiren oikealla painikkeella Dolphin-tiedostonhallinnassa ja " +"valitsemalla Ominaisuudet → Käyttöoikeudet." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded.
" +msgstr "" +"Tiedostovirhe! Tiedoston %1 pakkausta ei voitu purkaa. Tiedostoa ei avata." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Tämä virhe esiintyy yleensä, kun tiedosto on vioittunut. Jos haluat olla " +"varma asiasta, yritää purkaa tiedosto käsin käyttäen komentorivityökaluja." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Ei kirjanmerkkejä" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Tiedoston jakamisessa ilmeni ongelma: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Jaa" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Tiedoston jakaminen onnistui" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Löydät jaetun tiedoston osoitteesta: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Muokkaa" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Näytä" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Siirry" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Työkalut" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Päätyökalurivi" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Merkintätyökalurivi" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Yleiset" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Esteettömyys" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Lukemisen esteettömyys" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Suorituskyky" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Suorituskykyasetukset" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Asiakirjakatselimen asetukset" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Esitys" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Esitysasetukset" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Merkintäasetukset" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Muokkauksen asetukset" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Etsi seuraava" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Esitys" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Vaihda näyttöä" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Näyttö: %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Poistu esitystilasta" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Otsikko: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Sivuja: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Aloita napsauttamalla" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Keskeytä" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Jatka" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Esitystilasta voi poistua kahdella eri tavalla: joko painamalla Esc-" +"näppäintä tai napsauttamalla Lopeta-painiketta, joka ilmaantuu kun viet " +"hiiren osoittimen ruudun oikeaan yläkulmaan. Ikkunoiden vaihto toimii " +"normaalisti (oletuksena Alt+Sarkain)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Esityksen esittäminen" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Tuntematon tiedosto" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Ominaisuudet" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fontit" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Luetaan fonttitietoja…" + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Sivuk&oot" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Poimi fontti" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tyyppi 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tyyppi 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tyyppi 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tyyppi 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tyyppi 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tyyppi 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tyyppi 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtuaalinen" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeTypen käsittelemä" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Tuntematon" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Upotettu (osin)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Täysin upotettu" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ei" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Kyllä (osin)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Kyllä" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (korvataan: %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[ei ilm.]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Tuntematon fontti" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Upotettu: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nimi" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tyyppi" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Tiedosto" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Sivu" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Koko" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Version esikatselu" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Minne haluat tallentaa tämän version?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Tiedostoa %1 ei voitu tallentaa." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Versiota ei voi katsella" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Suodata sivuja syöttämällä vähintään kolme kirjainta" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Huomioi merkkikoko" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Koko lauseke" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Kaikki sanat" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Mikä tahansa sana" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Hakuasetukset" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Ei merkintöjä

Uusia merkintöjä voi kirjoittaa " +"painamalla F6 tai valitsemalla valikosta Työkalut → Merkinnät.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Ryhmitä sivuittain" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Ryhmitä kirjoittajittain" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Näytä merkinnät vain nykyiseltä sivulta" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Laajenna kaikki alkiot" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Supista kaikki alkiot" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Allekirjoitus on kryptografisesti kelvollinen." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Allekirjoitus on kryptografisesti virheellinen." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Tiivistevirhe havaittu." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Allekirjoituksen CMS/PKCS7-rakenne on virheellinen." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Tiedostossa ei ole pyydettyä allekirjoitusta." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Allekirjoitusta ei voitu todentaa." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Varmenne on luotettava." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Varmenteen myöntäjä ei ole luotettava." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Varmenteen myöntäjä on tuntematon." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Varmenne on peruttu." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Varmenne on vanhentunut." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Varmennetta ei ole vielä todennettu." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Tuntematon varmenneongelma tai vioittunutta tietoa." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Tuntematon algoritmi" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tuntematon tyyppi" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Digitaalinen allekirjoitus" + +# Suoraan Google Translatesta… +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Kiistämättömyys" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Salausavaimet" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Salauksenpurkuavaimet" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Avainsopimus" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Allekirjoita varmenne" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Allekirjoita CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Vain salaa" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Käyttöä ei ole määritetty" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Versio %1, allekirjoittanut %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Allekirjoitettu: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Ei saatavilla" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Syy: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Kenttä %1 sivulla %2" + +# &-merkki o-kirjaimessa meni OK-painikkeen o:n kanssa päällekkäin. +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Ominaisuudet" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Tiedosto on muuttunut allekirjoituksen jälkeen." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Tiedoston allekirjoitettua versiota ei ole muutettu,\n" +"mutta tiedostoon on myöhempiä muutoksia." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "Tiedostoa on muutettu edellisen allekirjoittajan kieltämällä tavalla." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Tiedoston eheyden tarkistusta ei voitu saattaa loppuun." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Kelpoisuuden tila" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Allekirjoituksen kelpoisuus:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Tiedoston muutokset:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Lisätiedot" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Allekirjoittanut:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Allekirjoitettu:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Syy:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Sijainti:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Tiedostoversio" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Tiedoston versio %1/%2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Näytä allekirjoitettu versio…" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Näytä varmenne…" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Näytä vain kirjainmerkein merkityt sivut" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Toista" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Tauko" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Pysäytä" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Lisää…" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Muokkaa…" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Poista" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Siirrä &ylemmäs" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Siirrä &alemmas" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Oletuspiirrostyökalu #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Sen niminen työkalu on jo olemassa. Käytetään oletusnimeä" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Toistuva nimi" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Näytettävä tiedoston sivu" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Aloita tiedosto esitystilassa" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Käynnistä tulostusikkuna auki" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Käynnistä tulostusikkunaan ja lopeta tulostuksen jälkeen" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "\"Vain yksi instanssi\" -ohjaus" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Älä nosta ikkunaa" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Etsi tekstistä merkkijonoa" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Avattavat tiedostot. ”-” lukee vakiosyötettä." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Virhe: --unique-valitsimella voi avata vain yhden tiedoston" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "Virhe: --presentation-valitsimella voi avata vain yhden tiedoston" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Virhe: --print-valitsimella voi avata vain yhden tiedoston" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Virhe: --page-valitsimella voi avata vain yhden tiedoston" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Virhe: --find-valitsimella ei voi avata yhtä useampaa tiedostoa" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Okular-komponenttia ei löytynyt: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Ainutkertainen Okularin instanssi on jo käynnissä. Tämä instanssi ei ole " +"ainutkertainen." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Okular-komponenttia ei löytynyt." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Napsauta avataksesi tiedosto\n" +"Napsauta ja pidä painike alhaalla avataksesi viimeaikaisen tiedoston" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Napsauta avataksesi tiedoston tai Napsauta ja pidä painettuna " +"valitaksesi viimeaikaisen tiedoston" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Seuraava välilehti" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Edellinen välilehti" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Kumoa välilehden sulkeminen" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Kaikki tiedostot (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Kaikki tuetut tiedostot (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Avaa tiedosto" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Vahvista sulkeminen" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Sulje välilehdet" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Olet sulkemassa %1 välilehteä. Haluatko varmasti jatkaa?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Varoita suljettaessa useampia välilehtiä" + +#~ msgid "Reviews" +#~ msgstr "Tarkastelut" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Piilota lomakkeet" + +#~ msgid "Expired" +#~ msgstr "Vanhentunut" + +#~ msgid "&Review" +#~ msgstr "&Tarkastele" + +#~ msgid "Annotations author" +#~ msgstr "Merkintöjen tekijä" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Lisää nimesi tai nimikirjaimesi:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Näytä &navigointipaneeli" + +#~ msgid "Show Text" +#~ msgstr "Näytä teksti" + +#~ msgid "Small Icons" +#~ msgstr "Pienet kuvakkeet" + +#~ msgid "Normal Icons" +#~ msgstr "Normaalinkokoiset kuvakkeet" + +#~ msgid "Large Icons" +#~ msgstr "Suuret kuvakkeet" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Käytä nykyistä valintatyökalua napsauttamalla.\n" +#~ "Vaihda valintatyökalua napsauttamalla nuolta" + +#~ msgid "Created: %1" +#~ msgstr "Luotu: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Viivan jatkeet" + +#~ msgid "Style" +#~ msgstr "Tyyli" + +#~ msgid "&Size:" +#~ msgstr "&Koko" + +#~ msgid "Inner color:" +#~ msgstr "Sisäväri:" + +#~ msgid "Name: %1" +#~ msgstr "Nimi: %1" + +#~ msgid "Size: %1" +#~ msgstr "Koko: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Selaustyökalu" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Suurennustyökalu" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Suurennus" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Valinta" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Tekstinvalintatyökalu" + +#~ msgid "T&able Selection Tool" +#~ msgstr "T&aulukonvalintatyökalu" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Suurennuslasi" + +#~ msgid "Only for PDF documents" +#~ msgstr "Vain PDF-tiedostoille" + +#, fuzzy +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Ei mitään" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Tiedosto on asetettu avattavaksi esitystilassa.\n" +#~ "Sallitaanko tämä?" + +#~ msgid "Presentation Mode" +#~ msgstr "Esitystila" + +#~ msgid "Allow" +#~ msgstr "Salli" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Salli esitystila" + +#~ msgid "Do Not Allow" +#~ msgstr "Älä salli" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Älä salli esitystilaa" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Merkintöjen muutoksia ei tallenneta automaattisesti. Valitse Tiedosto → " +#~ "Tallenna nimellä… tai muutokset menetetään, kun tiedosto suljetaan." + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Voit viedä merkityn tiedoston valitsemalla Tiedosto → Vie muodossa → " +#~ "Tiedostoarkisto" + +#~ msgid "Save &Copy As..." +#~ msgstr "Tallenna &kopio nimellä…" + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Merkintöjä ei viedä.\n" +#~ "Voit viedä merkityn tiedoston valitsemalla Tiedosto → Vie muodossa → " +#~ "Tiedostoarkisto" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Tiedoston loppu saavutettiin.\n" +#~ "Jatketaanko alusta uudelleen?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Tiedoston alku saavutettiin.\n" +#~ "Jatketaanko lopusta uudelleen?" + +#~ msgid "Current maintainer" +#~ msgstr "Nykyinen ylläpitäjä" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum – NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Kynän väri:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "vaakasuuntainen DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "pystysuuntainen DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "vaakasuuntainen DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "pystysuuntainen DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "vaakasuuntainen DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "pystysuuntainen DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "vaakasuuntainen DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "pystysuuntainen DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "vaakasuuntainen DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "pystysuuntainen DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "vaakasuuntainen DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "pystysuuntainen DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "vaakasuuntainen DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "pystysuuntainen DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "vaakasuuntainen DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "pystysuuntainen DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "vaakasuuntainen DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "pystysuuntainen DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "vaakasuuntainen DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "pystysuuntainen DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "vaakasuuntainen DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "pystysuuntainen DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "vaakasuuntainen DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "pystysuuntainen DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "vaakasuuntainen DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "pystysuuntainen DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "vaakasuuntainen DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "pystysuuntainen DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "vaakasuuntainen DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "pystysuuntainen DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "vaakasuuntainen DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "pystysuuntainen DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "vaakasuuntainen DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "pystysuuntainen DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "vaakasuuntainen DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "pystysuuntainen DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "vaakasuuntainen DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "pystysuuntainen DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "vaakasuuntainen DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "pystysuuntainen DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "vaakasuuntainen DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "pystysuuntainen DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "vaakasuuntainen letter-koko" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "pystysuuntainen letter-koko" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "vaakasuuntainen legal-koko" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "pystysuuntainen legal-koko" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "vaakasuuntainen executive-koko" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "pystysuuntainen executive-koko" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "vaakasuuntainen Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "pystysuuntainen Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "vaakasuuntainen DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "pystysuuntainen DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "vaakasuuntainen folio-koko" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "pystysuuntainen folio-koko" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger-koko" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid-koko" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "tuntematon vaakasuuntainen paperikoko" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "tuntematon pystysuuntainen paperikoko" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Piirtotila päälle/pois" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Jovie-puhesyntetisaattoripalvelun käynnistys epäonnistui: %1" + +#~ msgid "Search Columns" +#~ msgstr "Hakusarakkeet" + +#~ msgid "All Visible Columns" +#~ msgstr "Kaikki näkyvät sarakkeet" + +#~ msgid "No document opened." +#~ msgstr "Tiedostoa ei ole avattu." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "Vain yhden tiedoston voi avata ainutkertaiseen Okular-instanssiin." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Ei tuloksia hakusanalle %1." + +#~ msgid "Search in progress..." +#~ msgstr "Etsitään…" + +#~ msgid "Searching for %1" +#~ msgstr "Etsitään esiintymiä haulle %1" + +#~ msgid "Identity Settings" +#~ msgstr "Henkilöasetukset" + +#~ msgid "Highlight Properties" +#~ msgstr "Korostus" + +#~ msgid "Ink Properties" +#~ msgstr "Musteen ominaisuudet" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Tekstin kommentointi" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Vihreä muste" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Keltainen merkintäkynä" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Keltainen korostus" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Keltainen viiva" + +#~ msgid "Black Underlining" +#~ msgstr "Musta alleviivaus" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Alleviivaa mustalla" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Syaani ellipsi" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Syaani ellipsi" + +#~ msgid "Ink" +#~ msgstr "Muste" + +#~ msgid "Enable &background generation" +#~ msgstr "Käytä &taustalla luontia" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Piilota lomakkeet" + +#~ msgid "You must set this name:" +#~ msgstr "Aseta tämä nimi:" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Siirtyy asiakirjan ensimmäiselle sivulle" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Vaihtaa tiedostopolun ja otsikon välill'" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "Korvaa" + +#~ msgid "Pages:" +#~ msgstr "Sivut:" + +#~ msgid "Green Highlighter" +#~ msgstr "Vihreä merkintäkynä" diff --git a/po/fi/okular_chm.po b/po/fi/okular_chm.po new file mode 100644 index 0000000..17170e5 --- /dev/null +++ b/po/fi/okular_chm.po @@ -0,0 +1,70 @@ +# translation of okular_chm.po to Finnish +# translation of okular_chm.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007, 2008. +# Teemu Rytilahti , 2008. +# Lasse Liehu , 2011, 2013. +# Tommi Nieminen , 2020. +# +# KDE Finnish translation sprint participants: +# Author: Lliehu +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-03-20 10:51+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 18.12.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi, translator@legisign.org" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Ei-tuettu koodaus" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Tämän e-kirjan koodausta ei vielä tueta. Tee sen lisäämisestä vikailmoitus " +"sivulla https://bugs.kde.org/" + +# pmap: =/elat=CHM-taustaosasta/ +#~ msgid "CHM Backend" +#~ msgstr "CHM-taustaosa" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Microsoft Windows -ohjetiedostojen näytin" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005–2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/fi/okular_comicbook.po b/po/fi/okular_comicbook.po new file mode 100644 index 0000000..f83b78c --- /dev/null +++ b/po/fi/okular_comicbook.po @@ -0,0 +1,64 @@ +# translation of okular_comicbook.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2008. +# Lasse Liehu , 2011, 2014. +# Tommi Nieminen , 2019. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-05-10 17:25+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Lasse Liehu, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@opensuse.fi,lliehu@kolumbus.fi,translator@legisign.org" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Tiedostoa ei voida avata, koska unrar- ja unarchiver-ohjelmia ei löydy." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Järjestelmään asennettu unrar-ohjelman versio ei sovi sarjakuvien avaamiseen." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Tuntematon sarjakuvamuoto." + +# pmap: =/elat=Taustaosasta sarjakuvia varten/ +#~ msgid "ComicBook Backend" +#~ msgstr "Taustaosa sarjakuvia varten" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Ohjelma eri sarjakuvaformaattien näyttämiseksi" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fi/okular_djvu.po b/po/fi/okular_djvu.po new file mode 100644 index 0000000..e79d8b0 --- /dev/null +++ b/po/fi/okular_djvu.po @@ -0,0 +1,143 @@ +# translation of okular_djvu.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007. +# Lasse Liehu , 2011, 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-03-31 04:50+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Lasse Liehu" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi,lliehu@kolumbus.fi" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Toimittaja" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Julkaisija" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Osa" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tiedoston tyyppi" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Tuntematon" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Osatiedostot" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Tuntematon" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Yksittäinen sivu" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Niputettu" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Epäsuora" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Niputettu (vanha)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indeksoitu (vanha)" + +# pmap: =/elat=DjVu-taustaosasta/ +#~ msgid "DjVu Backend" +#~ msgstr "DjVu-taustaosa" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVuLibreen pohjautuva DjVu-taustaosa." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006–2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgid "A DjVu backend" +#~ msgstr "DjVu-taustaosa" diff --git a/po/fi/okular_dvi.po b/po/fi/okular_dvi.po new file mode 100644 index 0000000..b2ecf3b --- /dev/null +++ b/po/fi/okular_dvi.po @@ -0,0 +1,750 @@ +# translation of okular_dvi.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007, 2008. +# Mikko Piippo , 2008. +# Lasse Liehu , 2010. +# Lasse Liehu , 2011, 2013, 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-05-15 21:14+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lasse Liehu, Mikko Piippo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lasse.liehu@gmail.com,mikko.piippo@helsinki.fi" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular ei löytänyt ohjelmaa dvipdfm tietokoneeltasi. Tämä " +"ohjelma on tarpeen tiedostojen viemiseksi muihin tiedostomuotoihin. Voit " +"muuntaa DVI-tiedoston PDF-tiedostoksi käyttämällä Okularin " +"tulostustoimintoa, mutta se tuottaa usein tiedostoja, jotka tulostuvat " +"hyvin, mutta ovat huonolaatuisia Acrobat Reader -ohjelmalla luettaessa. Voi " +"olla järkevää päivittää TeX uudempaan versioon, joka sisältää ohjelman " +"dvipdfm.

Vihje järjestelmän ylläpitäjälle: Okular käyttää " +"ympäristömuuttujaa PATH ohjelmien löytämiseksi.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Ulkoinen ohjelma dvipdfm, jota käytettiin tiedoston viemiseksi, ilmoitti " +"virheestä. Löydät tarkemman virhekuvauksen Tietoja tiedostosta-ikkunasta, jonka löydät Tiedosto-valikosta." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Tämä DVI-tiedosto viittaa ulkoisiin kuvatiedostoihin, jotka eivät ole " +"PostScript-muodossa. Dvips, jota Okular käyttää tulostukseen ja " +"PostScript-muotoon viemiseksi, ei osaa käsitellä niitä. Siksi toiminto ei " +"ole käytettävissä tässä Okularin versiossa." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular ei löydä tietokoneelta ohjelmaa dvips. Kyseinen " +"ohjelma on tarpeellinen vientitoiminnon kannalta.

Vihje " +"ylityöllistetylle järjestelmän ylläpitäjälle: Okular noudattaa PATH-" +"ympäristömuuttujaa etsiessään ohjelmia.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Ulkoinen ohjelma dvips, jota käytettiin tiedoston viemiseksi, ilmoitti " +"virheestä. Voit katsoa tarkemman virhekuvauksen tiedostovalikosta. " + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "DVI-tiedosto ei ala oikein" + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI-tiedoston DVI-tuloste on väärää versiota. Vihje: Jos käytät Omega-" +"ladontajärjestelmää, tarvitset erityisen ohjelman, esimerkiksi oxdvi-" +"ohjelman." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "DVI on vaikeasti vioittunut. Okular ei löytänyt loppuosaa." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Loppuosa ei ala komennolla POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Loppuosa sisälsi muun kuin FNTDEF-komennon." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Sivu %1 ei ala komennolla BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Ulkoista ohjelmaa pdf2ps ei voitu käynnistää. Tämän " +"vuoksi PDF-tiedostoa %1 ei voitu muuntaa PostScript-muotoon. Siksi joitakin " +"tiedoston graafisia elementtejä ei voida näyttää.

Mahdollinen syy:Ohjelma pdf2ps sisältyy yleensä PostScript-kielen " +"ghostscript-nimiseen tulkkiin. Jos ghostscript-ohjelmaa ei ole asennettu, " +"kokeile käyttää komentorivikomentoa pdf2ps nähdäksesi " +"toimiiko se.

POLKU: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

PDF-tiedostoa %1 ei voitu muuntaa PostScript-muotoon. Joitakin " +"tiedoston kuvaelementtejä ei siten voida näyttää.

Mahdollinen syy: Tiedosto %1 saattaa olla vioittunut, tai kenties se ei olekaan PDF-" +"tiedosto. Tämä on Okularin käyttämän ohjelmanpdf2ps tuloste:" +"

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Tiedosto on vioittunut. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Kaikkia PostScript-tiedostoja ei saatu upotettua tiedostoosi. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Kaikki ulkoiset PostScript-tiedostot upotettiin tiedostoosi." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Annettua tiedostoa ”%1” ei ole olemassa." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Olet pyytänyt Okularia etsimään DVI-tiedoston sijainnin, joka vastaa riviä " +"%1 TeX-tiedostossa %2. DVI-tiedostossa ei kuitenkaan näytä olevan " +"tarvittavia tietoja lähdetiedostosta." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular ei pystynyt löytämään DVI-tiedoston sijaintia, joka vastaa riviä %1 " +"TeX-tiedostossa %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI-koodi latoi merkin, joka kuuluu tuntemattomaan fonttiin." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI-koodi viittaa fonttiin #%1, jota ei ole vielä määritelty." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Pino ei ollut tyhjä, kun kohdattiin EOP-komento." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Pino oli tyhjä, kun kohdattiin POP-komento." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI-koodi viittasi fonttiin, jota ei ole vielä määritelty." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Kohdattiin virheellinen komento." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Kohdattiin tuntematon koodi %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Sulautetaan %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Sivu %1: PDF-tiedostoa %2 ei voitu muuntaa PostScript-" +"muotoon.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Sivu %1: PostScript-tiedostoa %2 ei löytynyt.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Paperin kokotietoa %1 ei kyetty tulkitsemaan." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular ei löytänyt kaikkia tämän DVI-tiedoston näyttämiseksi " +"tarpeellisia fonttitiedostoja. Tiedosto voi olla lukukelvoton.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

kpsewhich-ohjelman suorituksessa oli ongelmia. Tämän " +"tuloksena joitain fonttitiedostoja ei löydetty ja tiedosto voi olla " +"lukukelvoton.
Mahdollinen syy: kpsewhich-ohjelma ei ole ehkä " +"asennettuna järjestelmään tai sitä ei löydy nykyisestä hakupolusta.

PATH: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Fonttien generointi kpsewhich-ohjelmalla keskeytyi " +"(lopetuskoodi %1, virhe %2). Tämän tuloksena joitain fonttitiedostoja ei " +"löydetty ja tiedosto voi olla lukukelvoton." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Generoidaan %1 tarkkuudella %2 dpi…" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generoija/Päivämäärä" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Fonttitiedostoa ei löytynyt" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "vaaka" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "pysty" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Tietokoneeseen asennettu versio Ghostview-ohjelmasta ei sisällä mitään " +"Okularin tuntemia Ghostview-ajureita. Siksi PostScript-tuki on otettu pois " +"käytöstä." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Ohjelma Ghostview, jota Okular käyttää tiedoston sisältämän " +"PostScript-grafiikan näyttämiseksi, osaa yleensä kirjoittaa tulosteensa " +"monia eri muotoja käyttäen. Ghostview-ohjelman käyttämiä aliohjelmia " +"kutsutaan laiteajureiksi. Kutakin tulostemuotoa vastaa yksi laiteajuri. " +"Ghostview-ohjelman eri versioilla on usein erilainen valikoima " +"laiteajureita. Näyttää siltä, että tälle tietokoneelle asennettu versio " +"ohjelmasta ei sisällä mitään Okularin tuntemista ajureista. " +"

On epätodennäköistä, että normaali Ghostview-asennus ei sisältäisi " +"näitä ajureita. Tämä virhe voi siksi viitata pahasti väärin määritettyyn " +"Ghostview-asennukseen.

Jos haluat korjata ongelman, voit käyttää " +"komentoa gs --help näyttääksesi Ghostview-ohjelman " +"sisältämät ajurit. Okular voi käyttää mm. png256-, jpeg- ja pnm-ajureita. " +"Huomaa, että Okular on käynnistettävä uudestaan PostScript-tuen käyttöön " +"ottamiseksi.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Yhteensä 25 virhettä. Enempää virheilmoituksia ei näytetä." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Virhe DVI-tiedostossa %1, sivulla %2. Color pop -komennon kohdalla väripino " +"oli tyhjä." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Väärin muodostettu parametri epsf special -komennossa.\n" +"Odotettiin liukulukua seuraamaan arvoa %1 kohdassa %2." + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Tiedostoa ei löydy:\n" +"%1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Virhe DVI-tiedostossa %1 sivulla %2. Ei voitu tulkita kulmaa tekstin " +"kiertokomennossa." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Komentoa %1 ei ole vielä rakennettu ohjelmaan." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Fonttitiedosto %1 voitiin avata ja lukea, mutta sen tiedostomuotoa ei tueta." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "Fonttitiedosto %1 on rikki, tai sitä ei voitu avata." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "FreeType ilmoitti virheestä muutettaessa tiedoston %1 merkkikokoa." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType ei voi ladata glyyfiä #%1 fonttitiedostosta %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType ei voi muodostaa glyyfiä #%1 tiedostosta %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glyyfi #%1 on tyhjä." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glyyfi #%1 fonttitiedostosta %2 on tyhjä." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "FreeType ei voi ladata glyyfin #%1 mittoja tiedostosta %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Tiedostoa %1 ei voitu avata" + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Merkkiä %1 ei ole määritelty fontissa %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Odottamaton %1 PK-tiedostossa %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Merkki %1 tiedostossa %2 on liian suuri" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Virheellinen määrä bittejä: merkki %1, fontti %2." + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Viallinen PK-tiedosto (%1), liian paljon bittejä." + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Fontin sivusuhde ei ole neliömäinen." + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Fonttia %1, tiedosto %2 ei löydy." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Tarkistussumma tiedostolle %1 ei täsmää" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Fonttitiedoston %1 tiedostomuotoa ei tunnisteta" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Kohtalokas virhe\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Olet todennäköisesti joko kohdannut ohjelmointivirheen Okular-ohjelmassa\n" +"tai DVI-tiedosto tai tarvittavat aputiedostot (kuten fonttitiedosto)\n" +"on pahasti viallinen.\n" +"Okular lopetetaan tämän viestin jälkeen. Jos uskot kohdanneesi " +"ohjelmointivirheen, \n" +"tai jos uskot, että Okularin pitäisi toimia tässä tilanteessa paremmin,\n" +"ole ystävällinen ja tee virheraportti." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Väärä komentotavu löydetty VF-makroluettelossa: %1" + +# pmap: =/elat=DVI-taustaosasta/ +#~ msgid "DVI Backend" +#~ msgstr "DVI-taustaosa" + +#~ msgid "A DVI file renderer" +#~ msgstr "DVI-näytin" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular käyttää kpsewhich-ohjelmaa fonttitiedostojen etsimiseksi " +#~ "kovalevyltä ja tarpeen vaatiessa PK-fonttien luomiseksi.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular luo bittikarttafontteja…" + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Keskeyttää fonttien luomisen. Älä tee tätä." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular luo parhaillaan bittikarttafontteja, joita tarvitaan tiedoston " +#~ "näyttämiseksi. Tätä varten Okular käyttää useita ulkoisia ohjelmia, kuten " +#~ "MetaFont-ohjelmaa. Löydät näiden ohjelmien tulosteen myöhemmin Tiedoston " +#~ "tiedot -ikkunasta." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular luo fontteja. Odota." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Fonttien luomisen eteneminen" + +#~ msgid "Abort" +#~ msgstr "Keskeytä" + +#~ msgid "What is happening here?" +#~ msgstr "Mitä täällä tapahtuu?" + +#~ msgid "%v of %m" +#~ msgstr "%v / %m" + +#~ msgid "Please be patient" +#~ msgstr "Ole kärsivällinen" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Vie muodossa" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Tiedosto %1\n" +#~ "on olemassa. Haluatko korvata sen?" + +#~ msgid "Overwrite File" +#~ msgstr "Korvaa tiedosto" + +#~ msgid "Overwrite" +#~ msgstr "Korvaa" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Käytä dvipdfm-ohjelmaa PDF-muotoon viemiseksi." + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular käyttää ulkoista dvipdfm-ohjelmaa DVI-tiedostojen muuntamiseksi " +#~ "PDF-muotoon. Muunnos voi kestää jonkun aikaa, sillä dvipdfm:n on " +#~ "generoitava tarvittavat fontit." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Odotetaan, kunnes dvipdfm on päättynyt…" + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Käytetään ohjelmaa dvips tiedoston viemiseksi PostScript-muotoon" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular käyttää ulkoista dvips-ohjelmaa DVI-tiedoston muuntamiseksi " +#~ "PostScript-muotoon. Tämä voi kestää jonkun aikaa, sillä joskus ohjelman " +#~ "on luotava omia fontteja. Kärsivällisyyttä…" + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Odotetaan kunnes dvips on suoritettu…" + +#~ msgid "Functionality Unavailable" +#~ msgstr "Toiminto ei käytettävissä" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Tiedosto vioittunut Okular ei osaa tulkita DVI-" +#~ "tiedostoa. Tämä johtuu useimmiten tiedoston vioittumisesta." + +#~ msgid "DVI File Error" +#~ msgstr "DVI-tiedostovirhe" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Kaikkia kirjasintiedostoja ei löytynyt" + +#~ msgid "Locating fonts..." +#~ msgstr "Paikallistetaan kirjasimia…" + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Ongelmia ajettaessa kpsewhich-ohjelmaa. Joitakin " +#~ "kirjasintiedostoja ei voitu löytää, ja asiakirja voi olla lukukelvoton.

Mahdollinen syy: Kenties ohjelmaa kpsewhich ei ole asennettu, " +#~ "tai sitä ei löydy polun varrelta.

Mitä voit tehdä:Kpsewhich " +#~ "kuuluu yleensä TeX-ladontajärjestelmään. Jos TeXei ole asennettu " +#~ "järjestelmääsi, voit käyttää TeX Live -jakelua (www.tug.org/texlive). Jos " +#~ "TeX on varmasti asennettu, yritä ajaa kpsewhich komentoriviltä nähdäksesi " +#~ "toimiiko se.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Ongelma kirjasinten paikallistamisessa" + +#~ msgid "Font generation aborted" +#~ msgstr "Kirjasinten luominen keskeytetty" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Vienti: %1 PDF:ksi" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Vienti: %1 PostScript-muotoon" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Kirjasinluettelo on tyhjä." + +#~ msgid "TeX Name" +#~ msgstr "TeX-nimi" + +#~ msgid "Family" +#~ msgstr "Perhe" + +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "Type" +#~ msgstr "Tyyppi" + +#~ msgid "Encoding" +#~ msgstr "Koodaus" + +#~ msgid "Comment" +#~ msgstr "Kommentti" + +#~ msgid "TeX virtual" +#~ msgstr "TeX virtual" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX Font Metric" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/fi/okular_epub.po b/po/fi/okular_epub.po new file mode 100644 index 0000000..67be6b3 --- /dev/null +++ b/po/fi/okular_epub.po @@ -0,0 +1,60 @@ +# translation of okular_epub.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2008. +# Lasse Liehu , 2011, 2013, 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-31 04:53+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo,Lasse Liehu" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi,lasse.liehu@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "EPub-tiedoston avaaminen epäonnistui" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "EPub-taustaosan asetukset" + +# pmap: =/elat=EPub-taustaosasta/ +#~ msgid "EPub Backend" +#~ msgstr "EPub-taustaosa" + +#~ msgid "An EPub backend" +#~ msgstr "EPub-taustaosa" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/fi/okular_fax.po b/po/fi/okular_fax.po new file mode 100644 index 0000000..39a7267 --- /dev/null +++ b/po/fi/okular_fax.po @@ -0,0 +1,48 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Tommi Nieminen , 2011. +# Lasse Liehu , 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-31 04:54+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Tommi Nieminen,Lasse Liehu" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "translator@legisign.org,lasse.liehu@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Tiedoston lataaminen epäonnistui" + +#~ msgid "Fax Backend" +#~ msgstr "Faksitaustaosa" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "G3/G4-faksitiedoston taustaosa" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fi/okular_fictionbook.po b/po/fi/okular_fictionbook.po new file mode 100644 index 0000000..67a7309 --- /dev/null +++ b/po/fi/okular_fictionbook.po @@ -0,0 +1,87 @@ +# translation of okular_fictionbook.po to Finnish +# translation of okular_fictionbook.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007. +# Teemu Rytilahti , 2008. +# Lasse Liehu , 2011, 2013, 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-03-31 04:54+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Tiedosto ei ole kelvollinen FictionBook-tiedosto" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Ei voitu avata tiedostoa: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Tiedosto ei ole kelvollinen Zip-arkisto" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Viallinen tiedoston rakenne (päähakemisto puuttuu)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Tiedostossa ei ole sisältöä" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Viallinen XML-tiedosto: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Fiction Book -taustaosan asetukset" + +# pmap: =/elat=Fiction Book -taustaosasta/ +#~ msgid "Fiction Book Backend" +#~ msgstr "Fiction Book -taustaosa" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "FictionBook-kirjojen näytin" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias König" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fi/okular_ghostview.po b/po/fi/okular_ghostview.po new file mode 100644 index 0000000..42bb253 --- /dev/null +++ b/po/fi/okular_ghostview.po @@ -0,0 +1,99 @@ +# translation of okular_ghostview.po to Finnish +# translation of okular_ghostview.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007, 2008. +# Teemu Rytilahti , 2008. +# Lasse Liehu , 2011, 2014. +# Tommi Nieminen , 2019. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2019-05-10 16:59+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Lasse Liehu, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi,lliehu@kolumbus.fi,translator@legisign.org" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Käytä järjestelmäfontteja" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Määrittää, sallitaanko Ghostscriptin käyttää järjestelmäfontteja. Jos ei " +"valittu, vain upotettujen fonttien käyttö tiedostossa sallitaan." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Yleisasetukset" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "Käytä &järjestelmäfontteja" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Ghostscript-taustaosan asetukset" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Tiedoston versio" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Kielen taso" + +# pmap: =/elat=PS-taustaosasta/ +#~ msgid "PS Backend" +#~ msgstr "PS-taustaosa" + +#~ msgid "A PostScript file renderer." +#~ msgstr "PostScript-tiedostonäytin." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007–2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Pohjautuu Spectre-kirjastoon." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/fi/okular_kimgio.po b/po/fi/okular_kimgio.po new file mode 100644 index 0000000..a6d3d96 --- /dev/null +++ b/po/fi/okular_kimgio.po @@ -0,0 +1,74 @@ +# translation of okular_kimgio.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007. +# Lasse Liehu , 2011, 2014. +# Tommi Nieminen , 2018. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2018-01-22 16:42+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi, translator@legisign.org" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Ei voitu ladata tiedostoa: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Asiakirja vaikuttaa virheelliseltä. Tämä on paras arvaus aiotusta ulkoasusta." + +# pmap: =/elat=Kuvataustaosasta/ +#~ msgid "Image Backend" +#~ msgstr "Kuvataustaosa" + +#~ msgid "A simple image backend" +#~ msgstr "Yksinkertainen taustaosa kuvia varten" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006–2007 Pino Toscano\n" +#~ "© 2006–2007 Tobias König" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Päätyökalurivi" diff --git a/po/fi/okular_markdown.po b/po/fi/okular_markdown.po new file mode 100644 index 0000000..68a26b7 --- /dev/null +++ b/po/fi/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Tommi Nieminen , 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-05-10 17:28+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "translator@legisign.org" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Tiedoston avaus epäonnistui" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Markdown-tiedoston kääntäminen epäonnistui." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Käytä SmartyPants-muotoilua" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Markdown-taustaosan asetukset" diff --git a/po/fi/okular_mobi.po b/po/fi/okular_mobi.po new file mode 100644 index 0000000..09e5e92 --- /dev/null +++ b/po/fi/okular_mobi.po @@ -0,0 +1,64 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Tommi Nieminen , 2011. +# Lasse Liehu , 2013, 2014. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2014-11-08 02:33+0200\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:14+0000\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "translator@legisign.org" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Avattaessa Mobipocket-tiedostoa sattui virhe." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "Kirja on suojattu DRM:llä, ja sitä voi katsella vain määrälaitteessa" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Mobipocket-taustaosan asetukset" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket-taustaosa" + +#~ msgid "A mobipocket backend" +#~ msgstr "Mobipocket-taustaosa" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008–2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/fi/okular_plucker.po b/po/fi/okular_plucker.po new file mode 100644 index 0000000..14d2447 --- /dev/null +++ b/po/fi/okular_plucker.po @@ -0,0 +1,51 @@ +# translation of okular_plucker.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007. +# Mikko Piippo , 2008. +# Lasse Liehu , 2011. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2011-01-16 20:10+0200\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:15+0000\n" +"X-Generator: MediaWiki 1.21alpha (963ddae); Translate 2012-11-08\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nimi" + +# pmap: =/elat=Plucker-taustaosasta/ +#~ msgid "Plucker Document Backend" +#~ msgstr "Plucker-taustaosa" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Taustaosa Plucker-ekirjoja varten" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias König" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fi/okular_poppler.po b/po/fi/okular_poppler.po new file mode 100644 index 0000000..a03f2ce --- /dev/null +++ b/po/fi/okular_poppler.po @@ -0,0 +1,236 @@ +# translation of okular_poppler.po to Finnish +# translation of okular_poppler.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007, 2008. +# Teemu Rytilahti , 2008. +# Lasse Liehu , 2011. +# Lasse Liehu , 2011, 2012, 2013, 2014. +# Tommi Nieminen , 2019, 2020. +# +# KDE Finnish translation sprint participants: +# Author: Lliehu +# Author: Suhviksi +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-05-10 17:28+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:15+0000\n" +"X-Generator: Lokalize 20.08.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo, Lasse Liehu, Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi,lliehu@kolumbus.fi,translator@legisign.org" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Paranna kapeita viivoja:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ei" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Yhtenäiset viivat" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Muoto" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF-asetukset" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Tulosta merkinnät" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Sisällytä merkinnät tulostettavaan tiedostoon" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Sisällytä merkinnät tulostettavaan tiedostoon. Voit poistaa tämän käytöstä, " +"jos haluat tulostaa alkuperäisen tiedoston merkinnöittä." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Pakota hahmonnus" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Hahmonna kuvaksi ennen tulostusta" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Pakottaa joka sivun hahmonnuksen ennen tulostusta. Yleensä tämä heikentää " +"laatua hiukan, mutta auttaa muutoin virheellisesti tulostuvien tiedostojen " +"tulostamisessa." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Sovita tulostusalueeseen" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Sovita koko sivulle" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Ei mitään: tulosta alkuperäinen sivu" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Tulostettujen sivujen skaalaustapa" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Skaalaustapa:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Muoto" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Salattu" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Salaamaton" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Turvallisuus" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Kyllä" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimoitu" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Käytössä Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Käytössä Poppler %1\n" +"\n" +"Koostettu Poppler-versiolle %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "PDF-taustaosan asetukset" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Ei käytettävissä" + +# pmap: =/elat=PDF-taustaosasta/ +#~ msgid "PDF Backend" +#~ msgstr "PDF-taustaosa" + +#~ msgid "A PDF file renderer" +#~ msgstr "PDF-renderoija" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005–2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Tiedostojen tallentamista valitsimella /Encrypt ei tueta." + +#~ msgid "Unknown" +#~ msgstr "Tuntematon" + +#~ msgid "Unknown Date" +#~ msgstr "Tuntematon päiväys" + +#~ msgid "Unknown Encryption" +#~ msgstr "Tuntematon salaus" + +#~ msgid "Unknown Optimization" +#~ msgstr "Tuntematon optimointi" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Syötä salasana tiedoston lukemiseksi:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Virheellinen salasana. Yritä uudestaan:" + +#~ msgid "Document Password" +#~ msgstr "Tiedoston salasana" diff --git a/po/fi/okular_tiff.po b/po/fi/okular_tiff.po new file mode 100644 index 0000000..906c83b --- /dev/null +++ b/po/fi/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# Tommi Nieminen , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-31 15:00+0300\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Tommi Nieminen" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "translator@legisign.org" diff --git a/po/fi/okular_txt.po b/po/fi/okular_txt.po new file mode 100644 index 0000000..735f833 --- /dev/null +++ b/po/fi/okular_txt.po @@ -0,0 +1,51 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Lasse Liehu , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-22 12:02+0300\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Lasse Liehu" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "lasse.liehu@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "TXT" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "TXT-taustaosan asetukset" + +# pmap: =:elat=TXT-taustaosasta: +#~ msgid "Txt Backend" +#~ msgstr "TXT-taustaosa" + +#~ msgid "Txt backend." +#~ msgstr "TXT-taustaosa." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/fi/okular_xps.po b/po/fi/okular_xps.po new file mode 100644 index 0000000..7e8f207 --- /dev/null +++ b/po/fi/okular_xps.po @@ -0,0 +1,64 @@ +# translation of okular_xps.po to Finnish +# translation of okular_xps.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mikko Piippo , 2007. +# Teemu Rytilahti , 2008. +# Lasse Liehu , 2011. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2011-01-16 19:45+0200\n" +"Last-Translator: Lasse Liehu \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-POT-Import-Date: 2012-12-01 22:24:15+0000\n" +"X-Generator: MediaWiki 1.21alpha (963ddae); Translate 2012-11-08\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mikko Piippo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mikko.piippo@helsinki.fi" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Versio" + +# pmap: =/elat=XPS-taustaosasta/ +#~ msgid "XPS Backend" +#~ msgstr "XPS-taustaosa" + +#~ msgid "An XPS backend" +#~ msgstr "XPS-taustaosa" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006–2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/fi/org.kde.active.documentviewer.po b/po/fi/org.kde.active.documentviewer.po new file mode 100644 index 0000000..2697738 --- /dev/null +++ b/po/fi/org.kde.active.documentviewer.po @@ -0,0 +1,83 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Lasse Liehu , 2012. +# Tommi Nieminen , 2016, 2018, 2020. +# +# KDE Finnish translation sprint participants: +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2020-01-06 09:57+0200\n" +"Last-Translator: Tommi Nieminen \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.08.3\n" +"X-POT-Import-Date: 2012-12-01 22:24:15+0000\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Avaa..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Poista kirjanmerkki" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Tee sivusta kirjanmerkki" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Pienoiskuvat" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Sisällysluettelo" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Kirjanmerkit" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Etsi…" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Ei löytynyt." + +#~ msgid "Document to open..." +#~ msgstr "Avattava tiedosto…" + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Tiedostoja ei löytynyt. Sijoita tiedostoja laitteesi tiedostokansioon " +#~ "alkaaksesi lukea." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Okularia käyttävä Plasma Activen asiakirjakatselin" + +#~ msgid "Reader" +#~ msgstr "Reader" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Avattavan tiedoston osoite" diff --git a/po/fr/docs/okular/annotation-properties.png b/po/fr/docs/okular/annotation-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..c15ec33ce03a7ee54e933939066c336e01892df7 GIT binary patch literal 21873 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�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%0AWDs#exjP*9gjW8aPY}ZMD;N&TX z-^l;deSpcP?%tjC@sfiJSGR>FX({QS+x&{19c#S3@*gqYsZzHW8C|v;zFhUqcF*3J zOSJ2{f>UdLUOVc&^G(VH&qKcFpWK(@fAyMqk!q4t@5V}(W#j$UNx_F|Ha#$u{aYW_ z^|sGXo#4r*TGm$JKKvhLtNHWQ@95)O5cdL`Wz>B<2@DIpXaoNtn~S) zgwN?#wrdaD!y5AABojZ=&4Sq#56kj>&bw6TCT6?dS;bAUQ(({CoRRDZ$&9i2;nnR< zE?fJUm_S=uwHZw8yU$fED0dBUE!1RIsv`4}z$3yuyC^YiuN%5yuxV&P1 zUp-W1pet7OHFS5@?>F(xhbh^a|GCb_^v$x@15#$KTm=rK@UoO0sDzB-hrltb0BxZo zoZMCS9-Mw*XDTrfHY_VyvWGr~5E3}+b>GKN zPh{N~Doop8;S(44%l{XU4&FDE+2IDpl-bb{X2J}qYfc=SZI|BOG6IvXU-_Zmr>L_c#-3go~uk`lw zZ!+*Q)K%tF5v=N-Jrib}rg7Jp`fq3o|H1TKHDu2oj-=MEVqM79~yp%@Hx^e z$oj(OaJ4)AHpn_aJlmEo{vMWiD~{X2yq(+20ihrlVf7~V1pBGD*|dR1?@{jrOB3#jXV-UdP@VK$QE+=5^{Ofhsq;$jpBEef zqguE@tn2_5`%VrwaMu2q+1m2TZR928$-)g*Q2ojdhuIvaz4)S3A>w4pO+;m2fwEFCXEd?D5cyg)(W;(OgesFB|>uB#j=VU9TB~wdJopK zbtl|tkGi&sGm%zTN8Z7K5`rZPnPYaz!Z-ShzD;fCI((Q@g!BHDO8=&`K)<&Zh1+tc zm#E}}#(6?SY~utM8}}ypg(@>?0U2bwHMvR5(dJq$W9~kNEom!1-ah-`bl0porPe8~ zcdgF4$E3LH+5qEOnH~d^i*;bN;X^MIm z26%Ry$>FcQ^phpSF}jU!*pOgPHR8HwFl^wG)qmPU_v_JJqEU3B&oP%N+-3 zlPTAX#fUp;WE%4_1q2Y0UQE-mR@?cj>)tKK$#W#URZFI`JZHb&Y@^jcxs{U1$~4xSEJx%cHWlin$LN-vu6?OYYn)|tsWYuP=7&nfSu5~3@(Qjm7wLD%Mn z;@r8IZ4eVxJ^5P`8S`CrHMlu6xUEm4{*HH)PBMe0GL0Ht*DpUw^tBavPMN{gln>La zj)f>bnI6K17p~e@9>QmzR$S%@-|4DuqO5%_+qJYNn4^a3f#I1yG9D>`eSW4t16X~m zQh0r1!{14(O6yyWmtO+2f#)>-Wko9NUG&Tze0Ag1IXhHRp`=K9;z zePxwqAE>wcG<5Cy%6zw3pWr0x%^j#OX!4|rDD2)9Yx}ZrQ+T^*`Ahv%6LvbYEkw1_dWc}s?6A_+YU*k`fESxKi1-w>AXCG_tDZ>Be{jX*<{tDN6QJ$7(gpAu z>YI24+O=!{zdd}=C=w*}olU_=(ZzehrhNU(mF$1^9S23IlZgmuBErT$Cp=_IU|bZR z*Wv!_mxFffU&+t4DQV?Gc7vP!P92j&XTz*|aJjMPXwuQ7jci)e#GJn^hBSO1g{bo{ h0h`AGY-7Lp&zSpDq;1zHe`f|D@O1TaS?83{1OU;4d)5E| literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/bookmark-management.png b/po/fr/docs/okular/bookmark-management.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1e75efc167b3da48d941eb97418184e6764836 GIT binary patch literal 138393 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

^c82p4?AxKC8tb-QRMp|WDcy#Td-v|P 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 literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/configure-annotations.png b/po/fr/docs/okular/configure-annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..f5cbac63fdb2c720cbce3d2d91c22005601e0f6d GIT binary patch literal 110207 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

*ptYGuHxDU1SgcDmO7EpSbYfWrd< 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 literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/configure-backends.png b/po/fr/docs/okular/configure-backends.png new file mode 100644 index 0000000000000000000000000000000000000000..89c8106a2213f1f5055fb5c0722e98194395a2b0 GIT binary patch literal 52664 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 RJ_`7edME!D_Qvq@{{c=%0HFW? literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/configure-editor.png b/po/fr/docs/okular/configure-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..07284179fe65158a584c95ca74be5ba50956c9a0 GIT binary patch literal 41332 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℞ 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 literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/configure.png b/po/fr/docs/okular/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..1f59d8a14578525549a0725d795e4a3028461227 GIT binary patch literal 133957 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%0D34jktP(iP+82*39# zrJ%Z?3rm<5ZiBPKmC_ZU`FYEIjsa4Gp0n{cd{*Enm=!Sl6>KO zZRTXKngV82-%+E>mM$0Q!;AJh9!v)AfY(~#o6q27<@JZRqExB$kVMTiv43{4GZ4|_ z=@2zSQpa>bq@E>*0~s|^kc1MdDXRKRv&R==sY)MNE7_si#UrY=KUT$i&r?6__Xdk6MzteK zHI#rZY9q2d+B|3s-Q7({76!60+?Cu;NaNbDa(d!{d!^NY*>56fC`QV)^K~A#KP!K9 zLGz!mY3pd$Ef;n%-S-AvPy2nKm#M;!nbg;ao;$fBIjrVD$s;^ zy$_ZI*-4mv1z#9QY0>IMES_S!Q)>Ywk|=Kb^3-nyA2vd@i*waxwH#o`E^AC4 z5B-3en3l-&_!?%sYl?^@ysH2YFK?aYy`{6WwM1t%QqCY{9vKHlOJ?IYa%~<3*-R!d zqUldqbV}Ld0duRM4-$rn5AeMt_Nx)iUxna=4*hY7Txe)BD+CZ=*J@^*sRT8AuWIwx z^~iyb+kQj}0^BeYDU6}zkVzL^;+Rk)X*uD&YEVULmio4Hs~| zYL>HGKfxfOql5p|?`_(2=;%9peFkIq6WZZ)MlA1TD`61y7Z!bNyqPHw_Z0Sgd$0}wtNw2@bYkQMU&p$??I#Q9va)sIcUlL z%LI5J&xM12C!_9t0|g?mL3AmT=bbIrUG2#~gn~{*`_13&rCm;aI}SJ*fVqXu&{Ea9 ztNg5C9#PoDxEmV&&g&{I`F>&^Ymwpo0~^jhm+5rz+dgvP1}ibb@(OAMj#9i4K_Zfg zgVxt+!B0MrP(~imTdGtrv$7IKA(On*2Se1~|10u3V|zn0-n;@dEdJqj5uTiUDo9BY zaejC+;)gy$^eI;`KewJRpWr7!G_wD+AKUWX%&VfD7K7p^EJvV}Ik1d%T}MLYF&RkT z`9j+;9hl^mJXazps@B#<CG*36NpG1J2oXh@FVh2`b_$_60A3;+8aD*(W`{l+_J#7y_&jT^*oMcgA`GYpC%zoY7V z*MZkp8q5_+wI1gaVKg|75I%lk8n(X~5*$Qee1pv$CB)H zkXWtLo%yThF$qWpLr|9*2!YH8i>?1A%ErL~4v67@-~!!vi~@WA`AENasY=ITMi^%A zNbr*zEgVuv5;zisY`9u)8a8Cab=?c$0Qw`g4}sHUok7&@oDAbXL*HnS6zgV26nU>5 zq=8s#vI3C@(aFhJ-WOIXHv>dJbSFQsmMK0{#!RkPjAM7Bm$!Qlr!tr=7pQgZ``rEs zD4-Wx-#dW!suMvbh2dARg}Ig00B85j7Z7E1q|+>KnkK1#bE5f&Q7GunrqMA`vKr~_ z=;3=x6CG>Fk3g6#9UWGx6qI?{f{XmhE!voG;JcdYksks!SSTXO#MgO6MNkz>)vTb+ z@no$6Khfg6pI>GZV@4|iJA7FOv&PFavxXoQq#g2-ap%W%^!}l+>{7b99#Ab8cA*)& zbWV95FKJk~5Y0gojrEI!#DTBH8b)9{0qh7dG)C5-XIDxx;m^ymGLZyj(&_De#gcxT z_rt14p)w7icQWk=bE4;=sm8EB_y*vQEbuh5a9HE#gQ`;U)xS&yxfetfI!v)IlVU~g zCaTCYtYtc%d>rBbUoF6#6xT(g3bXUEqE3#!&pjq6ze=9|{8p&F>V7p`C{=QQ+;npo z0#V~5F@%)sR3JutzL+osMB}w=`{FZpUSk7#GeKPC%bA@)e=r=^=i9BrabBp=#adJK z8MoCE-9K}C5H}85lsfn8zR(DlOs7iiCU^~92MR2@CyWt7H-dkpDk(oa;g)}RWlb&b z#|j2m%omfyOYT&)Yz-qYb^-vJ_lvZ;Ac9`A)P=5u?M&+ggx0h9E^Ql1@m*XY2j6(cb3T4Wr^W zogRkw4uVtRJ?i%xZ%W|7G&@#os_x!hWM0kZt^V?c{>9sogCwK?z z8R}YFoxt}UM(4K>v-<;PKJxMh{E^T)kLvftBdvg3ERx{db(TYLf0ryRkjV9G(8a2h z2<(z`;q@>yRE2ugX*82ndKQ@zH=z496*yDsmKS3=#3E;!n;57JFO?8y2E!JtjX++;hPjm51?flxtwkBpbr*JMWitxORilBbrlwyx4KQT@U0@!+-Swor2KM_DVLRO@ao1_*TPM z{^7mjg4p5f-2sAS2T(e>Uv>R|tbK)7m0!>uQRx8ks zJ1xaMPD~Fk)no*lW#-+-$iCg$-5r^-r;@?#L-7lTTDI;XV){F7FUm}G6Z)ShT-IuD zLZV6E!)~T%<&^Oid)tPe`07rZ8IO@uBOW30LuE=svkt*uOS!knz47{6lHJ(2K+0HS zK7#~hY|1P%h{sNw5Eg5IU0hr|U9Km#=%Aa)&tWkS1%<`u!s<2uhzujypB zui{iRTWLxgbPK*Ux+pP)q?pyGQ03ZjZ|vy}CQp!C*MSi79$o?;v|AkfnR)iDDCxWq zc6@yN<+A?g_kAHK7n`D|f$X)`hS(hV%_7Mkp3v!ypapJ*+bNQ|%Z`lXW$V%7uE@rV z@#-W*=yY@JG3U&!Qa?vr9HR)Oo2~+HG*M)~WwcLWKjx`}Y6Ue5#!Ckk;zZKlM7{7% zlFJrd33*S$2&g}(y7D%;dX5#0AIqJc->f>OF+Sf|U*zrmS-bMQ!&~BVVwIkDCDrt} zp<(PYhnPB&gESWS8s}?bSz?$Tbdju!BTE`r*;?|mX+E5g4GXpY7Z(UZchZkSWfef} z^W0gMCcOsoGZqcoI=dZas1_l3d}Gr}n~g6}f-*9w?B8c!5+!V~TBwxjSx=X(K-pv! z3+lLZ0#}gw6Z_@HadYJY{M&lT{Yn>9zp8aMWQR?61himq2T%tRqX^tv#T1`>9abt- z))`1-Qms3c=uXU)$q2`0X;Pw{vR@$oL=`8wmyqJ$$z-ldZ|ics0%6kYLXsgYPn36i z>K5P+ea=_m37m+A_XdEjI2dSkmm@UMIxB@m-*HR$jQzSs+|(zja0A@OdSR8ew244C8cpg;h}b zhMCdNmp+v4YFHemE`oud1}XRB9~+yM=lLP!1@P{dqiQDsi^P zek_2o{g&yuA4GJ%jc%h(|M)@oey`_vzB>Mfsyr~lgj)K?#k+XFH>_O-=7-8Zkw#K( zV{MTpfb9J4>DGPTeQLq!a>fYcI)v|!Fc6`hR|X}8eQ^B>G@^VoGQxcJ3`ug|DA4Qh zt2ZWC!EA1B4#dH4cHd;W&jFQ28eEns`{;#hJ+3|$B+DM>9A@`YPDZjUG{_Jy31 zMDPZaNhE0RPnXN;=QtG`+S-N;HZ}c(4kU1(Tuiwm@NmDF0O1K?vx#R41ETeKis^RT z3Xe6Z=m)ipXZ;XkG6 zIarwy5C8`fCMKtg36&ENWmn4DQG~&Mh{2#4%GVXv?g5YIRan{tWNK2=2J4^C&(8&? z>_O5<8ZDloN9u+#ChnyiZxW(ST_gb|#7`L2P2g>Eb3REM25oaH;$msyoBV6K2fwnbp^ z37&H+k;^u>xEYxL^5!>-u69p1th24*KvHo~%m|kH=GUeT(7Um zWSZavAYuCus-MG1&KLz}KY+mYV~NDEX8L`<3P>fM#e)kfp{~I767BbB@2}dQ!Zzb@yZ(*rUu5d8iwEN!pl>)NOoNY$IKwRT#&;5gn~dP4a^)fI*tc%*r((G#qT z^D3T#?;iGdyYHtqbrdx>t@xrWIKtEnj-foUHjjA~!o@a!w& zE>8l1$;;`tc>`pTJmQVz`iQGizAo-*1%vlW2UztdQv20c{7QRkMmJ(n&l^7H9?u$hBYzlgG4zlC9kB z#)h#ABv>GgLIO3T|L2? zE=?XYZ9k>)T&__mIuVuQ2Rcqb{}=TsdoMMb%lqq&=p#q?xuCc0qZ1SU z-GrWa!CBh#wR~0}wy%L=@xXCU_m@nEQHh?boR*CL1tq(RQm)|LFo)O^UrC|(hWK!r zYjBaC%)>R0BGDVDR3;=`b|fGlf6i5&YeyskUMxO7KGhlv{6+UG4ap3C{QCV0L>Ctq zpcUl}CE$CO{Z22|;XjwsMu?cYN8+xcoVf)LM{%>532zxAo0eQzU#Jafpc?%}qlFr> zol>8q8Yic1Byek}qw#&Zv%^P8QsmIK+*OdWXu5H9$NxC94+<-%W$(K??odsNo=gUA zXq@|5v8jE%Qb~X0UxF~nid%=Odoez4o0%nV?Tp>M8(gti&r>85{+D@6Nl!2>4v$KpcjjtN^p%*mAQTjd zSa?Skzckx* z!1xeeF=b9Yb?)U0AyrcGw#x&2(2!(uf^ws|bqeCZg2Nm#c2H_QQTJ%*vQ!R2Xwy_ku>tKu}2fQ;uB-Q0trE8 zkNnArxy9B75Lh4IL=T^A^uziBlj1!7k+-?7KO#wsrI}7CPPX_R=#G(t#!mJr6Is~kZm?fL++J*LeV1|eR6)$ zy^OEAKalV-$Sk{oFun9BL0Cm?6W8Xm`A_PLg#3BZ&*&c&^>wP-IIUMXM@KIf`iqol ztgQpNT-IMXE7J&hdyf|=g?v4j)$EQ|#^VsRQtNzlGMKIYAgqfB+2;B1d0;?qWAP=q zM}30$Le|b`8F#@8lt5odo=l9cy)~!AFhd@`pMStejWs2mDSTv9l#t+`I6oM8rf-Gb zGl-2sCC%tr6*oK{OG;s*h)R1`9wLepkADz|J8}w?5Owc{G`26`Q1E#_D;vTQ5MZ>m zx0_7A|s*JP!5L3z)-jN!^678B%_}c>_&%`{_UoJN$pve@j7=Wo zN2|7=-11Q3uHEmw?%v9+Yx}3SiYoMB$*k>3No~CXsAZ0O1VeKN9UUFZTU&wBdF?xP zy5oC2gP+@z%{trXRC8vF5tKxNzDW7tg8?>i;?<@T^TQhqsyoyoRyQh2)x*rm?Luug zq>|z0taP3)2vAW`(M5=9XhMKub7f;gr1)#Kv2q?8aYQoP4Gj&)mzU(++&BUP0=&Gus?{Edu4~~Z3l zM}(5T7&V$l1&Gfd{S`5_H|~epB802DDkE|<4D2w&K`1eLwXIdPt1}rV7uD%zPk|pl ze)#$Mjnq3@;;?)Nl|G5Nuz# zSWHQNazJWRWE}WIU6uCyUVd*@GaQ9qCd4_b7V&W)mX33tR@hkOs*b2N^w?pK!cLMG ztPFOPX#VKb)miU}`t<1&_-ws>eQo;8b(XUQCOG6VKYDsT*cFCU0<&sefu#d{qKRkvObu{YBeAWkFXO(d`+(DArLerrI3Mv-;f(`04+#)TD9Iucy7@Dll& zr2qL4voXsRSqgSe%7y-HEOBer@I4BWMNj7RKTeFc?VsKxvzmN#bK|8?2+7PO`taey zG1b03?a$TVtXiX_!SY$o_{g^Wb=r5#MTw0MuYSu_+Wg-OC)YFi^zUhSHGei@TwT#h ztBNI^97^%Y;uteK{v0YwQdd{!=kLD)yeA<66V4Y}3Sw2Ko&cK=oD~^kL_tLpQKe4t zTFqhXjCFtjdfN;R4I|5TiKDXO|GvTOU+@OhBghF+Zs`UPO`>5#z2!ue*ZFAvkQJhe zbPDK2g2Qjo=M6cwJ9WP{xj*;YMj6_#$Rc5dirR7W1?L4v7>%we`u}g? zcLhPwxe@W04*6_{ zM#P#|au;}?t1D?%@K8Fv7L7mUReEJ*o+*yJ-~XoSz7tEEv|u4Ny7M~!efW(2ix$}5 zr<4)@@0aJw+ZKyT>&t!YR0ke7U+;q5fLHW|ZL-57F39u43?&i5mO^3{Z!NI(JYabNC6S``ZIi)hlSkyN41@h>UNvacH zJH{0opDt?m5b!IHv_DeypQD}BRL&jz%FB6&^EISB@DdH{jcT|$wTGg@if@0juifg8 zXyCZ=3JNF3$3#>#XD*mx|1E`_LkcpXfWY%l&Mt)W>h1P*HYi$iYJb+L(-+k#t0xz} zbHgP4&z0Gv`k(f9Y?OMJ7msWjb}l_%Yq>*t;KpA7J0?rN4t{vb~^ z@=vX1{I5YrruXkrlHB0o@_R+oO>oMU)RkBlLcp8S9;`*^Du z5o9Jl*x5-36KDy?dG9*~pRq!Qt~m*)p3Av;0Y^T8NmY zTBv8(S3wVLNBym*d4oT5Mdpt-#I77AAHWCn{`uC<=@?u0tK$ppwXL%s4^9{t-|Sn~ zcLrOF%}$PAXLiR7D>U1S5j6+e9l*12J$7487jgNCE=bl;kjwM&zVkw*;2RoUXtuiZ zqTnpIT1P8RnA8m!dO8a%rB7K>0bdbZ+^WZx`M#2lYqv;YdNv()9cYg*RtPwe%B z4=x+2ROYJegfW4b2Z!#VMdSMMjm$pT^`2DIW}vC={kCbK8x6HppssoqKLtSAI)?HKH;n`ZZ=^q5@*RtICOi!2Y*}|EnVHg z44Q$Yu!SsY@6`~#v6e8qx|}c*vtB|xTCSRND)vOQVS#*>2;I8>!5J-0NJ8|By)pff z18V1o(F`aR9g6S5|6CzCY>j4q$AshMfIR%YI_}*@5@j9qCt-*fx6R}FYeqwH`JJLn zIqidef$?{B0;QiQAA@j*3zQ1C7qj6(@YlQ8o#4H^UOTjRygHCrsy{NEvuut6TeaQ8 zZ74PiT;Lir(D$u45oSg8X1;|jm%%I(x_7J&SBqyXE24ssBb*~xt}UNg8w!M;7e%l-*--1 zuf0M=ZSJC@14I5;pA*v7EV#-V!r-hd6MFgKG~yy1+Xfi3k%BAXea$O6XD+o&q1`$k z%S^T~=k_D|XtC3zHRD--uisytNR#0T7K0XzJJOBF7&ro}e0b%D(zR!WYcP9BcFxN` zd{?NK>;F*d_;`-|t=T=J>da`ql~HzN%~_5ySE+#=1FWc!yzYnQr$-*pHAp*AsA4pl zC4%I?l|3o+4V-p(+WY;M5Y0hU`F-b|i3he=JKK zN+Aqkg+s+|8{}A$G&CfCx}9oP1=TeY0dq&AW%@+lDwzb-XBioz{Y0ivJhotvTiG5j z3xTG$7FR^fcX)V6Eezjkm@OaOUc7jrT4nqeanUsbJicrb957zuLzXl?|IN7q*g(O9 zhtURq3?#FKa4b6c{@ylLrqvp1)^zd)BOcx;H4?*Vzb5{aW9|Dg;XTbMQzGrB`T1x) z&-=d3CwkJ=&B^O2q_v@Ligz{NVZh27ds$XT-s7YDL!%k#Ryk?*e3CoeQ(EqwHH*Y)4hjo7Ac?ge$)dG|p zJrEgzgU2)u?G~sJ)`rH0?U_o7y~&asjk!PLD5!Z3LPy$O%>pn-^%0g$Hvz4_@by>t zoK~54&ijAu$4j*`N;LjLjg$$&STtTJvs=!_dLm^40{i9lop0{wA1U0)VhzOPt`og( zPMh^tEJi~e#;h+!ep%~{u*Q2{;XmA6il3XK}O&qHd`$G4L0@-YE9Xjk3ofU zTt59ap4(IOx6Qgcx1Pf%D~J)%Zns#r8HXZa+)Ti4$I#Zi@0n8?+>FN`=`Sr*d*e$n z-cD3JuW%~YJv`f92Z#}SAMER^(s5*KX1>4l8zkC9r?Pj=`35zk`sgWk%qtu4Z&OxVuEPWTe`~8nfsns065alhwtprQzX+J32-puh`hw`%%i|0L{|wx&Hn}{+6W-t(a&*$Y&`jgTwi{ z{e>FTz;^Eii|$fJ2B~&)_O+drmBlOdk1v3Atu@^p+7iwgR=!0?UtjD3p#H?+Umo z`$QDPk<{LYsJ}lBdxaFTUcRGMvC$8Uw@~L_Y3<77dh_PpM9}T``ge=J-_s-i6}WiU z#P*S^%!Dna*$p+OGX}?A_cvtUK|P^EBw-Sg<88`#(y}gMe!Z?Cy?+zdKIhQ|;qV$s zBv&ldXzt<1+*(m+#7GMaHQJjBQF|KY88?}a4@&uFt>3+Q|1BccX20*VVaWTBisW~f zM_T~obUPmva|3Obf*y?UjGHq?<*KxT9##%#gB&n#2nl5b1)&NGvM7DO>VNoOEdT;2 zkAJP}gH@=Tf`^3#EbbX5ZHsyN@#9!d;-DeB#e5HNcUkn#hr83&r4$fV^3*B~8!mSX z$>P=OoH9aAfuaZQhqyQ=9tskiaFlz2N~!b|y~ccF2H1K@?!C*2Rz*=2fQ)|+NUF!-HhN-Bm%vUKT zAg@f~O$pneQHCOWTHK$`M?3O7hBouKXL`a)?pkRNJUKffsnQ-xmk?`2rw{q95Xf!6 zdwf`=hJ?>O?mlP$V%s((54E)UksI0a?+-X+9PR3_H$dKFvhcUs^;Iz_ZOJ>sUeNA& zyw}KiMgK%yEZ^{c)g`9#()d6J-wvsdE1wO@YB~g;&)fAc41pU^yvpS3AVG( zWAX|nkUw-0e2=wv!eOJvq}<%e0LUklg4EV%3Cu3I(BLqxmv=ioTulAYXeNjm?U4$@ zvF2wg?^qriUdq^EF=TW+R5u(JB-piqP0Q*nBC z6ryo;4O(xZYjdpi;MDE#*K-c*t~9~-Vt@Qp@wWs(nU?lc04>Q2uj6AY(57iS!ygqD z1?ZLR>9za2oCNy0%M{CI`(_j*r1g#7&WO#Ok)JU5+;)`ZD9?rzKuxG#VETCBWy7@) zCLVXC@h>3{GRx|NPgvoHlQuNDiFu`d)D~pc2RnYrBIt(g7)ftI{7Ff1EY#1xf87ye z*FnwVaj5k5lNUsnztYflE~%Na^C@v*fA3jl>eWWs!Rbn3F4AC>g$83 z|Ne6-7?fLn?K`W>JFL=V2GLP_Eh|<&1)En5JgM7?u$HJKD-#XISOi`|6ls(HT{);( z#vhfQtnyReStm85sXDl)2AVWsk;z{3@_!dyCCojU(oGF6YJ*S6(#O3_-RvLqlqad> z?(#}b?fDavmb#;kfb#K`wEk>)jv*8#Y-}G{D_Le{WL!djU6r~d96m@u%dEcRH4{o}yFFoS zkK?-jHdng8{QN&pUBsvVOV`dAR`an@cn;U=g7;lNE7e4@KIbfZii`#wmt|2~@y_`b zYU?hyMPKLPQR|;sB?224#Op*JTsIh1oWyGN|r`Ty*&6N6Fyc>e2T{ib4hA zUj6@`>Bm^DjaT&jJnH2LVK#1Cg<7rcn0XRHwp?eJnyeics|9~$omTb)oD1|gUDDcI zaiyaYj2ug+=;t_|)Lg@zpB=oY?_u&pd43?`YGHGqmOOM%03U;XopJ2$!Km;n=F)QV~wE`nT=5K1S1yWOMV!$jK z@_lWs!3A)QiG8F&^%i^``nPR-l`Uz$rJL7+l=4i#+7TrEPhgSh66Bpi(EFzEwiqQEMa zSsHWCj$2$@YRwQ8m3d6Qze>jR3j$5^Q~IL&?HdBkl-P0B`-g|oo%O%UCs$vjr48q= zPa2Nz&pwHWXdJCR-^D7NJe48FXkSu6aMd|pDm`*wyR*2>ik0a!8*F{7`SrP@pKMQUul+tnfy_?||KR8E-p#QS^x0@U|g95`NN&w0bHuBUo)*@kPBwRk)> zC8gi*WKE6Hliy6abV$o^uvLxmEhKL2`Ze12WFyZE7nevpMc%LDbC%(edKtoW*GK0H zTN^Ak7gj#ki`Ar+_8a#*2T(l8n?5elX${#93uql?l#h)?2t0Homg_xD@;>b_KgF1A zm1ywZ_mDiPYC5yymOg9=NG39R_xz^3I*lDyOvmO=t#`TFtlP>k(lDpZ7L9Ny^|Trx zdYrD@`dc&HNySg>UE;XtywFc99!(0q9@6qhv}S5P6dv;>#A$aen6+6rX334%=0p9a zEI?7r(H0UqBBPd;5`wT^u_XY!)<{V3N3M^A@F=eXn=zxRbaI5a3Y=NNH(9`Q7j0x%PhjB6T>J6|u5n6nIXwTrcfP=PC>kT^iFj z`V;E4jEsybbvqFhl{SE8m=}zN+$dDw;=&96;)rizZBP<=L8;G*lLWL;2K^j>ob1)t zy*b^W3~t+jpV*=o=W{#!Rw(go<6jyoSg zxVws!NRtjke6I+@PvAle$M%#gS)ayR7?vi61~6*a!HprvaJSoc8a3$H3)j%BC2kGp z(wnoba_cqG26wkaK1+U#%KXp#DzkThLjGmF)>UOb5ju0B9^kR#Z{&Y$=4d9p?spg%a4qmh&BMX(X?g|+$%u%&z&wtz zUnY?LzNDC#_Nto2XU&>op>o(EAam;Y9!nbN`Lzg~mZ7h1-o1U>ihnSN>0DaH+_W{! zdxivR*Ul9yFlLW&cf7bi#j-)@<=Zl0J!w zGN06KF(ygg1C2tPMNR$i36(-#AEOrV{VX4V_rLp%iPJO5qPC4peh$P8i(W&&Ga-8; z*y!in_yt2=1rXl?;ZfY+^9I0t*ujw~OLfm&o7>o&wroJW_C1*DT#yn5le)blkpU70VT*QE7;Lg^c$Z z(9?+mmINm!CokdQA$gWs03mX{+_#3eedfDVn^Kc3n~__9d_IZA^-q21lgEk3hu!g& zH5vX^kS<#;@n2axm@i2OULM@srdVF@bQ3y*8tvw^pFvJB4p>Cwg6DnfKG0a7p6Ygm zVh^P7B$TgpLEi`kvoS>YhhW5g%{V`|>k7l~4~in$8P7)xM8RLJ`+=6!tPKrDwXa`H zX>CnRX=Vev);Bbaj*OJm)qDnqvPHvm&nt&3z%Wluj~%jS9OnN1zD$)?(&a?NG%)aN zD~co(mnR+|F*qC+NG$-`aW3%od}w#tUrL{ z4bYdK6+rul(QrlJ?d{#s-JPI11R7eRVp96IwA_STT)2k?uGEueNjN#LE&KPrY)M#u zaUDK8J>_)S$0BsUX9DZDvc%BzytdcFd!^Zw2qXchTVV2P4w(I-V&2_$*Lb+poB@W8 zVJazM^B5ulKg+dTYHB#$E#$rJA#wX-uJ+@A24w3&!8!8kw$9mRZxs*|+QSDAKXh+? zU>O$q8XmK54!^~6kSbMa&CM1OL*<+*SstCf*QU(~O41QrDNroR+oq;US4Zio2pZK! zDn5vatGvw-)CMtBPLrNCu{l!hN}k~B8vL@KW_a0 zV-JC+)GRsRUhGX7fw7gDCaji=sX>5EMEC#Q^BGjO9VKZz3wNTTqGLrSkPkN+f6Y5j zH_rE_B5p@Ve+Pfe;CC;ZF~{SxdD$o(IB2+bU9LC%o!!T5lC;)vP`4ik7q>sM)farU zS0!p^ZL;IcRozR;DkfX~BEu4{!)#J(C*1_?y6lhw1Br&l#+}(}nu$WC?60zKK=@i8 zuC0}yD?hGvTyl4O#MBS|*dI^#gU79Q-S+Fh?M}R4KR>weC0_zZ7p^s#D?+(3F1r&{7qwv)DPJE-ISA|R)zR>*{T?Tf9)Jyab7pk-bgWscZO4vz zANrwYB0c3G?iBns{X(W`C zud-WZ_itNT1g~shL1itUY&Q@qI1V70Ne5rlvrIjPd-)THHFAI@`K z9xWXaB!l@Kj=nEos0~=f0-rinfQqJi#$Im(u`cwzjCa#Yg4Sh~cu^W6GDT5-5 zwlTemza9o)w@{NEIvr@|n~w3|8L`6--Aiw`p3~vqw0*ed%02==;)rU|HNJ@`EC{bP zNN0G;zkf|{kLf}HzKQI)@q-s%)sF04P;&EaBQGm5{5|+AB%6=1nA`!2@batrx$)fc zt5VQYpz9-_4 z2-RgGdrH`az*Fdg#nz$EB2^wl9IS{ZK*ObyS*<;VWNSTj=sO!rG#f!i`X7eXo)bs) z=Mad>*i%j}FE=Mtw8)s5E2bSN^HD_hTz=w#XtWWRuMo0unVVv<8aAcXZBcUuUUjl- zR(i5Sk%1nQ-*(f{@u8c~@sXE<&D1Z8QZk*{pV${3Qf;Q9sAMo%q*lvH=XtlPDZ-)W$if7jG7HG_vbbWp!{Tu`*@(m?xac0=61 zd9xv(=iV=NhxkgQ5!m@hxUh164NoQGwtAW+zRu>m`wzcacsM6Jq-I0S=U ze*_68d+r9C8VF128r!-t#TmU6>I9k-mb-z15989gV<#Ig4ixglQ0kCiB zUnD4e9y{%$#m0NkK?z<7qy^8oCP=i_*VoHH=5~5|%7}$@eS4#ELXZj64muON6Sb^i zVBWvYatpKtUE(VW3W`9`nVnTY4GhTt2GM?^Rmp2SNWkcEkXc0RLY$p&H zT5NQ+=1x#Av*oN!O-{tl$%prQwrRF z=0(>&GUW8b7NDtfk5DaFp#AFCb$Xf`L2z}kATq!=iCl6nijGbVZPo73v|^A`nmB0< zBxKRMwd;~f^kSpfs!$y>W{pmCB2dbU=lr(6%VxH{*vQjLOe_+Ab+nWL&`&0t^`8Dd zw@xt;ozwN+fpoqUcrXBR!)CNdjm3g0aXGj4FJ}C~XshoHSXpO>0j#mHF>r$HGUzt_ zB{laa0l)CqA8NPrv#Tx8f2I3)e>0HG$Mcj7>X86c!f-gZy9Gzd6n=cKkrCN+hS~%J z>tqhgp>#gi=Um|N@v-6lv>&8R+0fZy5u0%;TAg!qxIlpe2onc2u8{t#RfEBARod6b zE0P&ZzSq}Iv>1qB4rs2@-sJlF<|%+sK|2``83=;(1nZj>!>|Ns6bS_lVJDt4yxyI< zKLN{PK3`idd2k}Lt~BN>f8Ee<>f1LdX1y2G&>}9l3AQmzN0+^=WK0O=JZgl0WuP z3Hc=>>Tj+1f3B+uFl^d!bJ=bpVJ9WckNzZap2XXS|LqwSYcSu+;aHN#37dEOeOG;KSvg2mWYfmz>t2LJ{ zghcC1wGGOZ2pf$S9EshXBB~$4Q1>ZmZBRYO9}zj(_x_p(x>(cHSnp7`P<7~1Q^n-y zcY75_Wlvq{mH3hihCPQw=FrIz$l)ulTXyiz&CsNmcq~5BZE*j^O#|{Y0U{_+kL@0* zM5m_u^qRNo|H*{l_Vx~m=5b)qo>>WylT(~M1jljWIo!j%AT4_ietvJ1f{{XsN$m=P z17|w?;4RlAR}t7V77(kGz5A1zy?HPijBVbD3`P*Q@+FB!CFvr%@-fEGCa?)vr?P@R&hs+{QtNjggCg$i3kWF;XQ zHHSFy|G~oQMe;8bPT%4wDz)me%dzxiWTe5X}LgjHz zCJ^x+!B(~@{)0G2Nu9_`e8!8n@G$}IvEld_|D_6Ii!S@m0;STaieI+BdoDCpCnxQ4Rjat4nDPO*|FmpD1(E;d(V^-dVS+$Jx8}f8?rFGdqC66dM&Jte_R4>m~l^B3Kh=VBNZ6x^qD(2 zfyCE>t_^#-9R7mjZ(6py}#@3O6IJ@Ldl}$-`UtL!5AKa8 z$BYWuU!jn9{ZG#MOw4C&eU?zt$qvtnhjI;K()M1m@(yzQJkWjeha0PKN2*~fks2iO zd~xq~e0kcT&zK46Wt4h$j%UUycu7j`#8)D$nejxt(-WpoB2VFDB#99h8GHZ*np*C# zti9v1i7%Sz_$dqFkT`*uGHE3y9Hc}^I9fwA!pVvOCl<3Xbaj%v*pg?He9MbaY)U8_-p~eJqLC8*rMNPurVxSq#gDeoSoc{x! zgK)##`W`~K|1|psm3{r>H=zsoCat5@SW`e3y?Lt~0unFuyT6>i1hpC91+;hjmCPGa z2?<*kF@UetJ#+I|eQ7#XGT7EBLH%9Zq-M_A{4 zb$Wj=ucGzTP#PYO%lHG>iJP+kdpA}7DF+b+B^T@fpFWLKo$<@b$>|#zp<$t4*KBaP zZ_XJkUVg1h?$yOdfd`F-zklEA8|B7C#edu72apu^#fKj}PEbnLKooXODDdAC?kfTU z8Pg5Pr>fHCTLiBZ9JUwQ8>bry7hl|)ZOGh@b~~kzb!#_r145lPv9JC%x?VC~M+KTJ zR=q~f%HD<)=GEs}g4;xLS@uYtpAS+7E$1Hls$&qy!d(-e9^Aof6?uULe)6IX3(R3- z0_ahGaom2j1Sys<+7+8z%Y|b)-*%ud^SpiS1$IIpA?Q6>>kf{EfF!cb7Ojpdmmhy_ zsTC0S+nSh|nBAZX6PNx%{|BFbh=qwM>Ne_PelMA=$sa7Z`C?V?f+1hMW46wNG55R& zuC3u9C{Hv+3KL|Uhkr)Pe|6yo>#T3^ORr|`8Qj!=)^83hG0^cnSTe*sm3dXO)-IRKnxyr#rG=V#dGtV4to+%kZv?< zd9>Ct>HStN#*yLWip}uU9R6n6B&4ZHpw|^vKU=fB8*7JRGV5<|z&i-AVk)Y9Cnwd< zGISo(M>+Be^4E`ngtdi^mcWLEzkH$gX!6*$vyqYiw~69@S=kyc46~-zmbA<7d#kQ2 zxHr`u9Ubix5rJB>=zzQM_iDKvb#ZI2w8;iOAp{&1tUX>i%xrpIDd-`KaO0gfX!xu? zI^C%lh8|%>2KjTLLSAG-f><*&3}_W2HO86qxC>kIc!(2ty!PGSH;3ZorTqj_X@DC$ z>x_{qDv{C9pw%yg=jBmUx0$}h#_kM?$_CA;EUZV;3R&TD_)yYb{q6cu) zm!&56ota9bs12Z4M#5nYBJ{j3pMEHrJl}!jt5uSN$tSnpPH6_gTn8X1K(=hWm=thH z1>jYg$AgQe=Y#!K1!%I20c7zZK(0K`r>EMhJqVxoGvZ(cs(?=APfO@XKMuz0Sb(Dw zzzVh8PTK?V@C&QU0c@ybHp|1s(qry=7TCRHcC$^*JW2#Wwkc4^Kp#&eXpI$}(6O40 zB?75BwAFdf+gZnL!7Bp3=}IGTv!xS;{1kc)wv_u1fhh`uh5{ zr8@V37rzGI^Lqefq*0;WS`i~4BPI0%O+DpiThbQI4=6-WFio1J6hN8ewNUR+cSW~f zSM**P(d&@U<#?n$qIQZWO&Yl7=-$PErzNqPS`r?wRb*!fM#XL*;q`uuOd_v6wG1lZ zPz+Fj0dQF0;hcmePsZqRo@?IrsF7@Prw91XWrLxWRo(2?>d*A#{tXXJnj#E%RJ`Sx zay^s9`?d~nuotp`K(h`0o(oO!mQCyZ4M^EvTM`l)f>Ad!`u7su{h+M9+@Ar@AKt5~ zigj}!=~E0>A?RzkKgT?002rZ zDKL$}>pmmrS@s7G+|jN6YBEvqoXl1ATdDZfz4|C2FRB|EATVH06GuADG1B) z-z;=iJASB`H=|KVGlJG^0GkQPz^WvIZ8JEK z&^eYkLSU$wLP~e@d}n{565i61FdXkD#8L|#KbCXyHPOc zH2PqC307kw1PtBHY1vH2Nf{|4V<@EG;ns&&m+##y#nVZ;?n!;EHVrE+WiUc0$wPXD z1Vj%bC*eHXz|n#DXzTc=FzjA%#!mGJP~ULzEU z%FBO1qX?zom_$ww-VFEC*A6N8B66H|+izZ<810PL+17<$)KKqnUVfM| zG5z)HSJ`f$()sQLnt-S0l_5=h>GIidvta4e8K_ZTUf(R!?(@-pFM1HU(K5LKP}#F; zD8ucZNe#5;KD8l^7s>e!!5-9^P0=s9tsw(Jq^u1-Vjr-uA-~sXSdRlNcKg#&!hxt~ zZHNqvmWS%h%q%y6s7V4;0tm;Xq@?TclL_lnMC5QXGBO@Zf5HGP0`sQc0v`Y<)ZDnG zxuD6V#q;ruFjqRMjjm?C&9Oh>Y{7A9^sc0S{^oG8F$EjQd@S}=9rmYN_beM)xBBCO zqKnY|{OvR3b<}i*q6zkZhs(Kv42}rUF3o7SJ#w#8{&W*@7s=yzNXkpQ-&Uq7Rj+$T zr(PQwPxtlsav*8?zyYPZ^ZlGha=!>*eUdnJUVvB%toV7vPOeOfXdZx0mVHrs1_nCj z`e~Z^boH?LOwo;J-|t1n$9Fw{^xO3qyMx*Hz@L7^P)Ia-sM^*!0pG2wlOthfW_H@y zNVowl*UsxJfguasrq#e5k}eMG^$iW4d+$G(PJ#2_*i{DlH*COhK@87$nc+}kD*$w^ zr+$gs?T+VF|g~QTta93%(;60pRc8cX@^O9RXV6JTUr-<@gca$!41oBuO5U?#d6x zd@M$iMrXNFRYxPZ6aH6l}j!^q{pyo9ag6>XqXG62yYhbi>cj?itilt;Cb$?%G{wz10FvXz%+VOjI z_&NIs=qjB9T!iByv^F3k-r&Fg(XJy#Q(I9v-Vk^HEj!juUBnxWA{-4QmO$;R%bxNI z0YP8z$peIHCeLp~fc*o@s9BDJ&btH-mb%yz18WV+{I~#QUE`?|x~IFPC&q1iK&^)p z3Iw$4P;l0g6BD;~ZqC%%QcQN12+Ort)Ra5-WBj$-*{4^~Y5Ze8BN?(eXaXQYINx-@ z@(BwHw)i*n5Q@6mW~a!a1GO2zFp@|qD1K6w0rn`}ZS@JCjCF9K zncD1d=9De}39q>Lk3>mPM=p9PaJj>U!;bcLpI&|a~(9RB!^p`E#BWpW5LhW!&IZYAOW`U3*6Eq|^K5uVmr0t~) zfQ=_Or9+<|O`(cF6IwF3*c}alAS*Grw>?VoD<|h<8Rkllal7vS@buMTQElJfpdyM2 zN~4sNG|~+h5Ri}tX%Oiy=~4uwk?u~BmXeZ|7Le}l?ta&N@BO{c!(Yk_XU^=i_gbG? zOVJ5ab>Ue_vTrZSsQ#^_m7|n~B;eR~lYgwKO-n`PyO0ym+c{n%JA+wNW(Ied#N$$; z1gdwd-u4s^mCc_}JJg?A?HM4c{?Iq^-w+ETL=x8STK1JW;fz%h!h{i*Q8K z)aB&9TDaBL1=eyr4PI0)SOjSdg5Ag~O8tgcPd>;NJUKbA!yT_PLsvPoJJ(n2)S=+Z zf5avrAn=gTiG=^BV*@=26v7uIZolAp@960fRaS%AX(?l*N)qTUq29by4bc4#3G+~>s!39LY%DKMQ$U2vDQ`lW_epq#^L?9}zZ`sh5t6UN|isHx*D;E5|@@0FO5Cjav=XMg; zAdpbM^til}h>i*(553=E&-INAHMv6-LKHO#*i+SyOjYR(1+GuY8Iw#-n(8Iv)|F#* zKn@B)AGReMJDUzK935&9PDI0Aw**S586&_lV=SJj=i`D7zVL(WW-Cw=mPC0^Re)%Bp0P7zLSlKKmbv&%4f z3T@D`51w`^oayl8Wc;oWy#5hwG2vm<7PNMHcJ>wI{a~{Wlgwv|IiI242~P|U7u>KB@^Thnh6(Em*#{DcJ@{=7%jH$%yAt6`l=$p9dmbUX z5~n@PTeogo^ALXiJghemctb@;epO1K-_;4m)3UM2wSh5hax$`e7)3p`&Ii9cIzX!e zonOy%-9@Kz4AgLCK${O2YWX$KK}k^TdE)`T&MxSk$7&o&WOA?qTR-LGtl;eQ!(L>h zQh1pR1>%y9_uC+Fl0cALWtr=VCEJ^Ynw{u~#6->I{b?vVA*ig6f6&_0l(yk={{fPR zhesl>W8v$Bv$Hds<_ZJOaHdK|5}}~ zqj`mrsrVt2;zb7M)8Ywpt|WA&q!4gTd?6S#dTH6@WNXJVHKK~k^7IV_RkC;Uhj zQ7<7_d*N`HYfgF2InoJeJr|(QQ1B*L{`6;lFIkUj3iJsiwIK&Toq7dM;eaUwEQydb z!GZ*DiA0V}(iea5BvVfW{e(LDUW$7~5Qq~ZqNBy&;RJ>fLGpufH!>{jF$i0{w5?{l zm>N>S(IXwl;se8B{a{PjACS7K*Spw)ItS2i=$8FbQkcL=Oz-d-VFZTAD^x@_OLOxe zKh}0DkK=YXaG=gmX9UnUC=h|B%y}VrB#zTc0Q$aGeU|neMa5PR-jzwD>K-gOV=8)7K4^IEIf-|dkSJyPijDC*65&tRU=&a^&} z_3>ecEzZH~$+R1zo%)3g>T#ryn`2YPFo);&!#+==WZpjw@WQ6~L@mlgR(J2yDxKul z>CAw`>;WOSHPSloN5ZHQUUIkA_+vCDPC`GEKj*&_@yqS%yF^8IZ*RA+D@$3~595op zt>%#3b!HIXRBU)gGUzZ*ZQWej1rG02lJCx4(Px=}MGF7%KlaiOgQvk-t4S~R{uUB# z)YBJ6cx2>F3P)_FKh!tveYjjsU&@4_JK-`VzuTF~7mGIdX}{H$>5rAG%Di=sX*&Ww z6#_ne>Kezb?x;ifc4ewh5%MlyX`+T7+; z`Gc~KFVn4}ccOpocwQnTPPli)K1Ro~ZURR5r$?n8XwHlaNZsEpw} zK0dw?W;|%HTS08_aim?5^vVJLST7bO|4e;9tD*4_u;2YP>u5zws+* zVwUhSb`KA`H_Y#Uf;${0zVB{LbMNe{aN4i2F#=v*UOv76Ogy}pHD-8!E*>sjBcqu4 zqen%heZCkAWpmB8{8~?>4TCEyPwXD~Ta2ZnFlhYv-AeesH+pn*y5Ckly*x7uHbo#7M0&zu4ICn+H(nGSEUfB!+qN!h=|8F4ZH`)RVHBju0L zdpy@58g0;PIU}=J=eo+rXFQoDrENqLlR4t6KSAd2K=tph*UIg)N;#nS+@vTUcv{DK z+v3?SugVHOu|8ul;N#m>EAvIWx>)%TZ7XY7Vjy<$-`^0n?09Fc_IUATHaw zmwOI_vVrnI?{LQyEZoecMIVb$a#I4-Nz|+o8&%gf4=qVPE1kijxR<|WF@CTSIo+KTW|~Vo@l^hBqva> za^|ZneZW04#qTxl#76#p~#Zp4EuDV?CBQx!k`_F^t|~ z1s(P`pFiKZMLgNA&ju^L>;vO}Z%+9<;*fx?rije>d3A>}3Q!cb-t=AF*XwjVhwDD- zX|tUnM6Y6{jRSC+cjiP2&(4?^+DU9a*mZ4u$GvA*MiBULsWavU6)l>Gxpa1Wu99hI zBvW6H*+^Kop%Sgl#ecU>E$Swt%k5_En9?1kyP?yZgVpuW_~#?SFT&Bzs|(Hj3>ses zjj1WRG#ea4LoW`~)UVE+lZNo9Ds@CLpWui_nHFIY5%`apcMdR9MSNY&eO)UVz1TKH zSG9gL#+C8!0^MbC^4GD8yYZHKZnQo1v-LcRZqM^HtZSrb@Vh*DWO&O}Al?|?`@48< zZeNhlP*4vfZm#X|*{F-k5?4xHyfx@?o0^(S22JmW2KNpy&%JvGwzW`@!pfD}tHJ-+ z*xCx`DJ}Cg|MxtEh1Qy5jMNPXlkn>;d_sA+HXen1`);vwJ32@QLw1(BYE>%eIb{-c zuMXEPo#$?){gX@4KbH}@dU7=4oOE=n)wCRw#OfEV##aOG!B*Xu5bkUo&7{!_ZF86b z_nuQe`=DJg0juxHjFn%b?&}f(081cm?@yYDIK+^JHtHfy;KgQ)30A$9*NmD~zr2ud zv%c}{OXi0RF@bi2uW`+Oq41`wc+nmXAUW^@KyBp%M=3qs+1AtrR-tC~In&bW&``Rl z6a=LpBaEN`G2AH~sW(tF1Pu&eA^yi(ytT!(hC^^ofLurid^lL{c@Gtrb0j$|pE(0k z7e<|1F@1@1=VN83mq&Ph*XMx=9v;*N1eB=?FmL?bEgKAC>#Jb~OVm4$(O*emUim(p zJ0M`)=ea=9Y`aQ=9XL-h$9AFZ4T#K~8?C|6Fu**4K9ljCSJ~|*PtYC);Et;K)JX4HO zz@3QuZ0>5|pV&dK(-p(8u;?Gb#l^GV9G+#&zMjdJoEdSw=Z8U(4(Y6a^RyD6Uqje0OC(l@-CHVdbK922BKg6{a@#r1(t$2*OB~@7eHXc?RI)^@BUt`{K_MNEBkwJ zU`#f6rlh5y=V(+G0?b0#H{TjDAg!j-(Qtl#Uh34r0_c>tc2SPbOg%VUF}wzI`idc= zU09^~&)8Uho}xI9y>ZGnO;C9DU82lDfu^NIi(^%{Vu)fxvPP>8mI87(mI z0lE0Y7t~yzVM=7W0?k;ND+WM=3$R>g>o|7GT!zp9C^c^v6BFHA`|})$klQ8lO+v+E zeEcu)(q;i7Nw7Gx(BlDclURMg<#~NeB|i#=Pq4a=Dy=)jNJ&ZreB8~c^S(qimgU1!=w%_MMZQE&RN$FFkX~!R zt;ZmntUY^hda-j*Rb9QeUDGpK<0uHzihmdLQA%{$UW6OOeb^W-Gdm$xqNS_@Zm1(# z|HN$mueLR43ptB_^o+B_^Tw*Gs%m%0vmq0}8~-imDHrrh2QN?$2jDPtdVRdgQ!b;z zAm-DDAael624MmIeaa3W2l8adv5$6B^?de`%qNcNcpbOMsHmb%mGfELPIFcxl5uw6 z4wHEN31Kzr!z3aSsV+4*n-7#XE|0f|2!%UBPV-Cd>nt~@F-%6)f-$+pFC7ZinhPG_ zaaFtX`i`nzBKfEUCa46e=?XNL#Voy)ch~u)s)Tp== z?jxS6{;+}Tda`A-mreqDOg@iGd^O*Z{Du(VHK(6 z@!Nuk#N{0^;yEqiJv;`(1D$U{;ui&wPVMF;FE7iUXf}9wr-|HUEwneumPzOxE@=4E zpwmD&vep@u@0=lHvD_0E+@U`|%rMhZVH)LJ=HY&Q(TWFkO*ErM?_~ACspYUV65Okg z{l@yuKg$8cWwpGlr0Jxp+jm<@YE!e+frfSE*GKQ}1lDJD+I^t4SNsu3wNopSChVh7 znUZ;JJa+ExKN4LG|KFg;R>9&4}?1bR%b<#*rx2aiOe4X#fQ zFmNf{en)s?s*n{>tJWZ3)SG-8)6e?iVuqZG3Kta>wKIw?#*l|n z(n&F+Z6jBS_K=Yg0GDL&ry!>)<$+Xuvd$GRqT>|+Iu>=>W93#e9s-xMx4+dNKMkjt zTVD2!iFup7l&+BH9}qGR{L}03S3YPvlB(I1FEF9WM*u^<}++~w^-jtgvBc2;L zm7tIN)zcF^lPtLM_5ZX0H>b@NvI}Ct<{y`^-b_2Ut9S-K<#<)l{|5y7Kb}6?sh>!k zsN5O#=&K#9LMRUjMvF_fLPmPE9U6!Y6-0$yt67japw1+(JU_tv;Z~acm zg};!I5!=Q#-SlYv$J%t#7x7S4HfI(*cQ}Cq1jmQMR z3q5bRJ{N?#_9KNv-u~C=4JCcjmt6QTp6>6{H}NZjH9rNkm?VtL)#o4HoyWrb5)_~Z zmsDX#rNv@%_clxFkZJ$egwZIod6&5EwG9Py%1i-|W>ScRgRLgBG&Hn%o7&2^W) zDMvCW`a)2L0^lA>Ccb`tpvjkn;~-?rybTg878gH1jAYb`N4|Ytww#kv?YKj11$0rW z&~2L!AKpaeEDGi*hkO(gVl)0jI&^(ME>a58@4kHbqB{_o2i!R*e-+Om4&mF%5-}>u zJC204shlEF4D+h{H?JuKAijINg0qQzBb%imK392z|rcS-EYiHF-6x`Q4&@xH#xjW;kuWml&kZ08?uT;+z%FO{z@)>HgmiMd24BM)R4II0%*hL zw=em}aL=W$(Qp_MyGP^mv??l;T3HXlu|oDdt<1L#u&kQ8ivGD1!}KoHrs59DotFlu z*1aiQLa(e}qG6_#mojPM8#y}ukdaaSYbqua|Jk)fZ}O-0$0fyV>!VJbhrc=+uA5R7 z(iEtR-_ow_?zP7y?kz=(<&Fj&ckJS;iDmQ`1OIk@ywz+WD0qD_^j5XoP`%-V7#Mvj zDq5B)wgH};e&fYc{{{SDDjxSpE*eNuc+SBQEfvG02r?Zu@3g~D6r7x#!XhHf@zS|N z>q=*@H^vSA$rzfSo&5#ODYZt0bo>aZM4VvWIfahsD&RJK zmJ;xs8urGwg5X+Vs|L#I9}W)mT0id;s35+ov$K`*3O9tm2ej{4L_|H13*RRzc+(9< z*jEbCZ!9Bg_V{n8CVuAT8czsVT3X)WbBSC(XQ9LM(k3}cA8D_1I^BIfOKju!p}hGHM5vS}Yl#zh&aOvL2p zCl~MDoA}^M*@Ky&t(EDxV^E=0FXm9cN%fiL6e6@pxSWj{f6CRUoqxmw>hrE}U_$(%vTdpT0uDgJTF)C3vfI_7c8W7c5rzg;kW&sUH$QOH+RsvI!GW9#c;j0V+ z0Sr70F-$tW10~>hFoelDcTiA}{p)-|9pzea0C_=k6Nu6icDzv+!Xljp8Ay8ph#mxp zpc?Q}FKFxNxbH)@rCmNcstQPdziBz>M~=6rj3$c-uCx>;vqL6{FMStiRSsqwy`{Ta+uQx1^(5F?iHyIk??{X?&dgqAPi z>=`BFn9p3_rjm|rf#xhCBto&f?OcCZF8PdBVt4Db1W|s=x_EwSHO*4#iHGWbh+|`` z?93^=Qk%b~47$$x^L09iytJ{gNmDD!{#*2xbEtaYm`%q8&&W_Zr47(zwNibWa0+>_ zPC^NGr!)%aZ&qlCk)V<|+lkT1jB_Z`=7&Yf_(CS}pNxKmEL%#Th{D4BIq_9X_3wjf zC0CjDTdj)Elaxo|!r2CaxYBVv!BD9xWQaWie=6d<0_zWB!<7RPXC+z1MtE4>g_s4{ zow_d19^6Am7b}uYWEh_4Vr{l{zC2}qfa@j;-8bk<9G`Ng+hq9Wb*X;ZTWBlQTcQOT zUKUVwI8!oQD+||_Ij>lHs|riwa~9Y53ubaQk}Wj23kId|m=IJW#EZdNglz9fvO*X2 z3a1#Dko8jkx7_B|7NSX3Tr~OT=DIsUFol@kC3U1`U@@tUP|#*zxOb4QZ}UeH)ehTy z;$U~-D_I!eWatdG2gP!hfp&Y~3?>q1EcSqC@c zr^C|RRLw(T&XC&)obOo@_GopIuWB3*+Gjl9BW>cKL8~7imLX)qV$<1&@nL}OnKlX} z!(Q=vWGTg!u30uLZAeXEjAL2vSVj;0Q2l;~4~>+HF~l*RjhvAK?Y#n%pJY~}M9~Wt zdJ5%GFEKN}Lb>N5gnU66BF_Wx=t2}|?qb{%me~TR6uh)>ms@Ik0}yzuzQ2*b!sg^P z9dsF84ngy3=@jHv*weIX-=E{Ep_Snmyc>4n9tdC`*9+HEqJC(jVpcnB9*i0#PpS4s zC1OZFnx3jm!7Mz(AW-2wa~Ez|YbvuwaI{k(V<$ySF`ZQ%f!C(TBj*j=?-f{*3Kbb@ zdmR->31v3q7OuxFkFlDQCMuaFFd@UBWoi&BN=(G2F4=UcQ@(!?Yem?{_zKdFlyuM1 zsiV*|6O$xf;*Zvty?8e#zlz44O1J2xZYHj2PH$S^KENYBF#<>2@#d&c2YzT^S=l{$ zl;;T`W~@qLn^;?D4;?$+xH0}STfo;F^*G#HF0~_?Gupf`EZSGp1koM~SKE!uTLPr%B-~6GDjn;1#NAd-! zRF_7hf<9lR5IC#<@i$>1ZX}w^i}E9j?e*r@Tpo#nmaX%fi~e@+cs~UyWp3r7Jlv4S zi=wsR5D+n^mqABgB_fjN=C!*>@l@UI{vKEq9yBheKDcWXl_{4xxK>G3^)wr*AE$y`3UuY3GZQ2<|@>HXoqU3-tp?v8cqunKlH!me`a-h zO&X6dr)U1VjNPIqjRwewY9haem(kL)3Z8tauVg0Mc-W7=#Fypu(-?#1Bm4x94L~d zFm_A4Ts>GatJK}Sl;P}cl%x-RSB2N1GTE~0|AZ7l3wd+!7$_C6&7X?U+qe0N3556EwLEl%>lyf z05TCM)0I$h#Qn%j)$|E?CFYBThZV8LOj{mri$iO>wT>fg$VwYkb@ksR#rWZ;ytv2x z7zanRLm|sQ=pH;^<5Vi0#>@o4uf#qpmMWP*9Qpn^;sHhcJb&vy%YraWyr!{Ynoy{h zHhJ1G<%M#v@~*e3%z>apy&#B$HyUCIL~icx?Ly8N%RJRBdBa^0UCF1NtK@h@}ODuKBXs z&Mq+-I-nHK>$#N_4+@Y=^v}388PA zZM}pI|DhWsVtiLE2?wkd3d_B{yZZT*z*s%wOvadSB%OX7qv!t02_Mneizn5*eAo19 z{*jFv&!0LeQXr*)sMdhqc8Xr^rDOSYq~%tcWT%jOGpG%6dw%0iPzHt zlSQ?|k?GF~JJ)KrGtAp}(YwnJ)f+~9Ax8`^e#O)5KH9^~DO8f>3l@aJC4s}Dv%h4j z=H%DOu%NT{@ESwkpa5%41IR#Hs%#bx7JtG)ZZdd$MZa@1wA!D@Wkcw{a*-6FA+>Lt z$ZSUi;DTB7F;1Xr%f2anhoI~72lE3mY_D0ChR@Nn^YcyXB%XR;e%iO$nMNYyar#wp zHDWPgJXMOKOskT*H}OdIhjm(k<2p=KO^vL?JDSOD9-s`&Q(pM+(_vd0k{rBRI^G#d zC$xcy0m%vb@vmK3!7S~hais#yxMPwZpfkd%u=}tx?xQfR-5t;EEweSDSfZ(RUF{sv zo5Z64t6;3mu>acIL5Wr;r13WDF329wPu4`1(3VU_Djqp*Pa=~-EDgL>#_+}v&D)>Y zh)cjr@sv?jjos2Tkc!HL%R<-`l6JE*{o5A<;fl3i!02h ze}BHeuvhKmKRU`)VL8^4$UQT+wkDbb(4hxWb#ZL>vL?+$P{_t~9i3<(PLIORwWSxF z`(H^0Ix(bV3Rh+ry)WgKP0CwqEmKU0VlJ;c=`Hf<-&d$=zjnr<)r=8TvLDxN(|M-M@d|?Yb4O;{EO0x7F&+34))pH#IhX1%9E#bwmb&&a`Si zWN23JBlr~XltKEbNRN6s1jQKkZELwrW}r4)o(q}|6M4ObYkBI z-8=5VvgfpLo3_z9w;ERBH-wxQ}vxO5oXa{Gv zw8$K3=`(8NWmYcevt!0Cd{w@yHUfo{ zHU&3?=t?Nha|wlS2W_pb2p+08rQx3^Z{Gsib9~6-zlbT*LXNhL3Zg~H{ECtO&jpf!zqZ{znUSZ(W-}iRgYMBhVHI%F1@q~j zQK`S+N!7$>(SKQPI;=l=YGndixSj-dl-Yr$E@(C*DFgA4{}hPJ{&ZOD-sX3`50YUR z5N^LS9tC8F%~B`e%S?SE8R83@n~^3--Lc#c#Klo>-6DSS^l3nnOuJ_TzG#VFYb=+E zZ2$+CWjB6jG($uIi)zC=a#Rc=G9KE1bkV?pA{`ym;aucj)9x2sAJ*9bj{>W;9$Os# zXhTDRMKZT*G`rySD^-Ph9tYz-KN7dFZ^Yp#eR?G?-P@!AKK1R;&ldLCfB1|i65cJ_ zozQxzlikpr)9=fdd+Q_l?KvWT0MW9(p)063O`kAQ8SLD=W@#Z%Ew{zlyMO=iI+F=F zU!1OJmiNo_z~gi`d->f#_1iuB@CZcY>N%hM?$4s(J)kIED$Z)D(fd@(K}A@GA0@zyxBEl}S32SNN` z9Y49an_+$f5U~f%>8+EOD9_^IhNk=7U5*9gw;kA25M_J}$ zrEUVYuhuzYl>FL5QglH$@fk+OWZRqgx}Vc%YbVD=XOZ4Rk&{Vpz4cfNH)xh6#R>ZB ztlBz-?;BSVBuFX+n)iP}GLuALG=s^&cY>|)+V*czbokt+krtjn>=c`@M$szYnr%8e z*qknpfG(KTqv;ir$3#O4oSn1V+r7gU4M2rhTT^%Y9&MbhwX?%48rW+}^vCv!ujmMnpH;d=> z9;)Z%HE#@~78wTzE|RM&QI=#(w#mV=8>@qPa_s{a)Dp^4dMsk%wrlr>{%;@X0N%2= z*cz+zE70&1`j^}#d@%8zBTganYd<#zk$^N1IC*OMRCI3(mirgl5gZ$Mao)4VRXJ=u zouNRngJ&O-O57p8mI#T2ge00t=c^OCn&JLmlSq2`PdHsM8U4mp9t*x(mjVKKCVx_q zp@3TW-Jj8|QS4PNc=MS;!hH0Hf7jbW7NcWFY(~vkAHmCC0m}LK0_ON(_0zvp<3)#J~u}zTh+&xRVkXvwJML`SDG1MPkP> zXbfLo)TjaXs;|3#xCSmV-=Tb!C!j1i-J6-;p6lfeewNd@(m7-XSt^%RhU_2{2)c0) z{8F zuA+(6i5%JJ^~Ju1YrWphF@%iZV7&bM*_u&3@fFTOd+__&RH5%`b+kQv`dJSFj*4Tw z;Dz0Z%jFP%(5PGg=vx#vtHMJH2z)yxgmJ5guO?RDQMr20-@HN98cTi{ zDb%5$-dEB3V|dB%qT5tGZc3+>pMPzlk_kb+?q~YbRHR&7IWG4kiF_p!MS|C8`8JRb zkayYs{1DskjzdV;{e8#qpl3t}!8Ts*cutI!IWp~(TSl!59334Q%v{f$dNjI$SrGEl z{4*rOkGWm92_H1*cxe|I^(EIKo*oELgW4DCg>0Jk)XyLi!4P=#UOG%V1>n+&m48$I zc(@a|xZ-J>?CponYSVNF_S5D*!J_h{l`(gBMs5AG037L42R?(YX!vVa((x=lu!H-b zkU#hoMsXt^GheC9!RNeO3R%yGYZEa78*#~Gc_2$Ms%)X)QjHcXeFE=eF+YR zD8fI{zJY;(48_uY-WUERus4hk2g(<^`LtMI5ND27UME;($B7Mn8$trz08*{W5j!x8 z=pp|61vU~wTCZQR`g^i>2zu)$L7VueKob~70yjQO3kvhLi zyR9xTid}l1iUps4+AV&mueJ;eOMebS5b34OK6Ym`qd|f)2c6|)RR?UkkhOPSg+n8p zB^kwKe`+1F@3b?`kLW|eNm*Q3DGptv04Z`Lz1pYcp7^wWV`C8FfP!FR-4mYp!?R3I z;5&oGMEZ#NxjxV?kr0np-n^7LLkJiEi&{u(3znzGR{E~`6&9QA@nkij)?1hH3JWvW z(A=9kS8!wW1C9MdodJBy5cTH;wMAA$JJ#XqG?A;TD=3$o1lO*6{oy(Xp)3f%V+!f* z4I!R#%^dXrnpa?Z2n(2OST!J;pMzD4w0X0|IbL@oP^6p(dRzEh;RVxy=vxyRBO5l3 zjw?qa`HFc8qO{82J|`s+K{dHpF|(Dq(Nin)l->L@2%?Za%sAZ!=dLE5H`rd&M>f7v z_*1=^7AkU_a~KG7e@!^Ank8v~WcoK(NLo6mz=AeP5<(xvK`?-hjvmRN!7+FVR5}zR z0lmHGa9ct_L;{dV z@7%d#eQ`_#(D~YQ-7`42;aL6i-9#~jkURW4VX21>u%lj*QM3TGf)^bXNC0?6=D5|& zwEGXU69HIF;%Rcb+8e{*Dnr;OO{xL4S;R|UVR@F!XBUUdWW{8u+0gr2J|kDFCd8ty z-?#-#9LEpSRPuWc`Lw5}kxnmWS`!ZiUg^xVyvx?srg4=iSFcfO7nv9Q=4HVZDH(P8 zZh36fu-9?M=Je0=r|g#9zl6Mdblz_$!CL&x1}>yMQ)miKhK zD&H!|T6L)utoE11Y~e#c?t_LSm#0LpRsShA))=m-5zgw-N=K$=BSl8@iyd*1O4AVr zap*+6HixG+@WAY~#@rZ;7R$!5IMYH6E+pdnCwFe5rR|jw-4r-b<;%n#5r+F}aUxVl zJEJlumQw?Sj4@wRXLU6LtJ3?86HaR>{!a@qFj+WKGhQD5SV%w^BNEcVTn!pJHqS zQi*Vj*z+>U7+TSWdiOKuEp<>c%7WIAfGf3uAyryn;8mL3?CRocV^#dUySH8H1X^pp zOz}^0dtQIqTG^b$+wK?-gAdc%8uzF8B`k?#y#|kaKb~@!zUm04+&ej0$p|4r^oS>g zNl*Ebol#8@Rzx~buZL5YP-#W z74yB#JiKMl-GHE6y`xh(e{G}^qw?w!|LTbIKdPMMWL;G0)jGyq*@4#^iDDUF!7GpG z;l|6KA>rmn0asb5StopCIusV36><7zK76=u+fo!UAI_X3YhCnfGJW5&$Sq!82H1?; zF1ENjBWaq;gtJ;O90;N{O5LieapqtLWc8RFeTeQPnHHv?t+-E-by!IkUSQ`)_X)N{ z$a(H&qplnoOB-DK5)|}{InPl5NVB~}3BUEt&6f#pDpE2sG8D~adxw;PoBC{_p}#oz z!=8s1sHFR7=%py1Ag!S4=TEArsAr+Xf-V(ANp5%wpB<3M5u)>Mvx4=WKmn zRXi*VUVwt5*dn1rzclH^8UNX0z13vZ6B4&w`*}{lfmKjU0+KhMH0#+(tT1ZDv04cf ziUt%L9?^Pemc_S+-a4IaJ|2^if;jYdgNEZj+*43bcI<#O)-ICwW*5AYPU4*YJ>=#o zu>N3uIKMpw!f^pwblNDmJ0_C>`UJHq<0ru2A|fv@D?CZGwf*agaA=iu2crvWy9mXlLGY$-Lw6uJ1BQQ z(PKR!?j>os`I`Qag)t}R%y={v8N@>?zrSY0zA=Q?jTGs~5)wzZmGsKU@VPi>lwM}n z@f&a>x(!UqTD5wWy5C_j+HZ>^WJ^^JiX0H)AC&?k5=dMbrfyq^y>8Ty|e2vLtnTh=Zpw5~`#e9>zf)=^X9rgXIK(T$(ey#7Vmnc~5vl zZ{Lns+A<-y01@KWIy=1~D-SP`&*m0%2NhS~J#7X@19L+6cR2bnr>C)*RDuSwB*zRY%*uD*+|hK&Z zg8j7|8js_ejgB0+U9C- zUU)8AJ2)7QM@oFxEQi;RXEx~kA{sw(14Z zj7fs?gLCAtHA*M2`0Our8B{;)jAVRMmi-2w!|e`;5hAJQ-c;Mh3EH8OcCpl)Y#TH- zwXDSR2jZ;+_K6$1OoHCirm@{m*3aD+a7GAb?mCS1ee`U1rauD`A~Lt1eOMjKa19xB zQTexm9=kd?2MAu}JN1;y;VVEf-c9wHWJmPx+*6Cb|L8%6?b2TnEjx8TV&ZK#4mbRW z92wF4A%&)i1Sp8JtF3CECuem`_G-&FvbeD{U(4{UOJ8DvwRIfk|;*ORbP64&gDXmk_3m{}~lcE}IC;ELExd>k~9#G$7}>>3L~21*hL zZ3257WnjnmzwwL4W9ffYyGvWmnT@+uGAO6h16evKH#;?~?vmE%h)nxw+EOrKjUTC$FTsuz^HSb91+0)T&D2$lg2F4MK4JA2E!?&k1qbYu7k*T1DBwT z400Hvg_zIlnzUWrJCnV2p*HOZm1W=mnf`=+qdn0?6As_3ofpYdnxEecg17PWL$$Gq zYe;UK*7nQrzO7zxT&?q^&gi6Yg-08_UdkNj`9D%zv4OQrmPNkLXvbqM`q1eK=|ZDy z$8gtL!)ty9wEOlB>YG2}m9S1SDfh~W6he9_|7F>0rEOWb1aI0oP$;UfKVQ;`{-OSl zelN=X^h9&{hE(hK4vVRXo+0YLyy)Bvncx9?P5aV&6tXI8Z#|!tudPBQUp{{Om&R>s zm|G&melSnz`u}NY2phfM*qF^0p$UU?5R9h zDxcHot5JafE`KOKYeWwTx@0IBk->xn6Y78v0I7E074iRBVIONVkX5JU z+GOrkhBg5j+AwVYy6EsoCF?N!H=VD;KL;h^>xScpNur?`2BP@4qz;&tr-OvIlLdZ# z_2|6zXXa!~N3QCkzUY4r+j~r%UA(j^(yIq7(0_XYW(gnRuPF{~6z$LnZ4}R#3p<#j zeS|*>=e^2P0xTHQmCb;g<_+B9IZ+sP;l}%p%nzNUcjG(awh0%~JZ@Yn3#~K!;B4@l zC0tlIEes6yRBUXK#l><^RfgANlodR9^oWw44G{w%98vH4`3@E)rm&LIUnyQ}4mu0U z{4LYdFHbHVc6CE03_LW>F$i0R%tp%GHFf14Z}B=vmTa$PJZ%^T|^Ic;#5_n5|UEr`=+qFdZmH>_zt(p_v zjS7p?DZqmoMOG)vpTP_`|8j6$*^li@55^r$nR{H#97~^QRGYFNtq)~D#DTNN7UDo} zA&d63n&S@b+1bA;9({$9#dYBO5KJjRMseHB8|&@7|0$Fnxq0K?E{XYDg@7QAW2aoS zKn27M*FK3i2?J&#vQ{ITEkg<%C!Wz`=3-f$B$YD}W*yr{eD2vNYd-Cq zwye&*NP4rD6=7zwbQ`m8L?wmrm~ZK8ltUQFCQL~Xdo+^`ffq=Sjurq3d(2=TK?3y4 zzeB(Ck|*=~l#Ygi=4HvZz`R8#*bR1gy%|8q>v3wVA0s298;|`jhuzc@nG?Hu8mAL^JP=KH~^beIh3ppMFcvxxgNItv*HJ z5z#GV1&LCLikXY6l6MkTcO~ZeE`6t5bCS4O9YLNJnauxlu(A&k*AX0*-#`WvWX~V1 zL-Uydok`AXdB?5sp82e<-`&3<*<#ySAVs-e{eXR?H|agNv!)MErbqm6QW(ieNmJ$2 zAWe98`(np#S(*>Z&xxDOBci0&ddF8~Fz;Pq_+WMtpwlvkXG+&pX#z#mNIW10`{IEiV zM0wm%ZFe71>Z8)UQA<8dSgDqlR$WzS0B|9gz+q(w_9d{Yd0a2ysh69#E=pjbt<8RX zlCkP;#RO^Y-jrR!AhnL=v$+Mp=+25&p#Z4!RjXFtA8!eI$>b~)^6uzD$kglb7ASw? zE*jlrQnQ#g?^?Vd$p_qRG;;p9vNgpot~b*+}mr1=mVtLK&H2) z?-s;ZSQ!wbVGIvnk5`!7mNTytJvsunWbK+|?c7~r4`W0k35*9x(W-HL|7TR@=8TEKW-9Ciyz)wGcY8X_rWTtGJ^nODF22<^OB&B%i&LZ4 z;#%W80Enz4x0BOK+6o?*&DRrpdaxadQ3?r3`}^|+EE-J!8G%v!AsPSX#lzbduChMo ze2CAMloX&{CK7!tZ;WAA)um0cnAgyWizX`@lp!r=9YnKT{mRep%$$Yxk__DFt9i7^ zWHQ9k8*E1k3P_xSa=F3`(3@iIkH zt9no9X>XJJx3;&>F0AB7Dt-eqAvK3>QUbRlqDo|cjCM;9qw7g__3i;4Ko=sNrwdV3 zs8Zd$JJvTTiIA{U{TI1^)Xve7rB{FL)>#o3gP98t@n5mC(Z_Q^c-+kw=eHbePdd2h z4PT;xd5wM_xxeGK*Al7;t;H;g43}|vxFowQZ}wyW21r@;I>BYi0Nag?5FGnd zkRc2sHJd%IV$oY{+JZrPFcs4o&m4EKKDIq`_J9oxgz4ZmfiMNUuGNi_z<3PlSI=qQ zLqtp*Ce*^++{HTa9{APKx=S=L1_slvvUiSv{kC^L&nNC+=&9LyiOXU#zfrXbQewfQ z;}ge$u4wkSoA>|jwxtBMc6TqPt>ix@AP_IhQ~g+I!Va2p?cq*V3l3F~?OdgB!ozIJ zn{am6Oeh1TG7RCk=^eybJDldSUdfcHVgUzyFLsKr>h2TuIiuD`4t+vLCr6md=6tfU zAf|rjkKI-9vCzS_`CjeCqB8tTBW#@3?zVK8#@nl0GDBPJx_nr~{uRa?uWha9Q^D7{ z$#rvfm#(@oT8emurv?`+8G&1NTpfdz+{1IubRTC>|H9*eV(pnsqLY=nJHy>a#P8%fj56JuH`Z7u8jLUMB8777OPV*XyRR;&uGe~zz%IT+IHsae_hDWV)p zR*p{!Q^oA5U6p4%9+iA{iJlW}2Z!Lr;>U3So?s+wx_Q<74Y6_g`mi$k{rkF`lb4RG z6^Dt=y@s~Q9`eJ}Hf&#c@q-3tNT4AH7Y#|x)zYbFJT??OWQ2emthk!zpD|#Evr6EW znvRQuv;XpN+TB8ufnv)iX5}+C?bat{j85GzbZLl%xZeL{e^w*jv-SP$XsxzT(^Cx0 zM^njsu49eOPWh-Gsd3&Rept4b9-g zhtuj-2~DjIJB^h6w5nRYpRO1%E5WDq&r}{v?vd{6yPPSCC-8JNXcN}A%zMhGrpW;{ zMnDCcYY;JD)riAec|ur3Wbw0R15EN3n~nNGAp$`M3h6w+icHpQ+`zhe?JCMUuq7yo zTKRH5y<%yjs@JHvHB{`hbe+wuK8%-(8ab}8tv?I%ev)NBv{yD23)mi>o$uefblJdpnWF#sh zhf#TuF)`N8cWdjX%V7g?z3>Oo{mHv`7@Vg@{87fHQZAKRH}rcFQejkyi%IVud@zK1 zJjAg}%lV01$#?9a6}gG^UPS!mM(d+yuDzd!wGAs^h*{psqDI@ISBA z##8jLdr3?TNpXT{^B0hNK@8rx32F*DsyD_}C2L<;2eYb~zlJvb z;>wjtXF<;^*+cS1NtvI1YqXO4OeP;TN9=EgBqgcWo|Pic9EHWin^$ahl7tBMC#|XO zl)U6V-|qcWfV$$abg?FI(t^clv6{;*ibw8vI&=n&q!V|>>_4IuAu}QeO6PiRLAKTC0hQPk44gn2<1od?4kv7UUI0doC)2FAY zw2>N2PN%6%_;;?O_W#7AW?g1@N>+tMmQ*6Or-jt0`vz1ZcVY(;Umf4>*3Hz<;o+EY z(D3lowuXMWQ?4S8%33sFD#v1#&&Kj6eIgthGLN%daprRygJpLqY5RDCl$5M*W%1kO zst00yG!-oH_I`y%G{N}B(b{fL%xgC;ko(VvW5VZLc`q*B7S&_Gw8%+IHlVd#`v9tW zmQv;(?p?8pc~*#S0b=URx~D(c?Ob{wibdQnkj{b=8UP49?>(J#7R_Y@!wpo3NL5r~ z;*6{LtK_Gm1T~niI`G6GiK^ClW##$geQ%M!JwJOT!SWCCTb6AqT?_-rh{Y8yQe8ws zQ%Ty#$!~N4wHLbq-AiuS7*v8<;_X&Z(gIUj&{8|x{xIYZ;iEzL=PI2O4 z^bgQIGQl7NgLPE8(sT1_@$=|sXaq@Yl=dR-+xy-=UJF$2D?1CY7Zz&|X`#*lwypr| zg#Mz~}CB?Y|y7PV+3s)n{D{a<-2?Hy8H_K9bw-;e*!shFg`z4`Y%1_GyvQQc6 z@{1D;h1&OvluO_#2z(p3*ulPo$|`xtAeh8gnZte&N-J<%6&4kp^C5I^CD-=6xqm#@ z!wYY_!D6OT^C{@q#LdC{vF^fe4i>5f)g804IH)(R01inRpKtRe5k@*LCAjRgX@!Q# zz=s9|+;h7;cNbW^d+%Q3f>lUtWTXUZ;sk^Lw?mRP^=?&rWZMY%toCWQpuv%}Hd#Y% zuit%U$Z1<0!+W?sr=|5Wl%zm^Qw`+aHMT53-@;#RFe@V#etda;;iGk0s@ZT8s>Ge~ zgLN3cwz9ed-Vr+_?qrjNPuNHbP2Ar}lKF%l4*{mIE@d%^^t3l@U2 zJ&80@w{GZmX19c%{@D7nA8@UwCOP>HtqK@QInchQt>F}T`W~j$xWO^|SZDij52n-f znb%#oeL$~`+poP~WPAbu8wLw}C8fahXiLeD-XJHoT063Y;>3@x_60{JE#$a08@2Rxr4RV*uP%^uIMWLF)bX z{w^5zr-U$PB0Q+un5{aWvU(39-613%Gba73Sf~0H(e6{1?$K-MiJqr`6KfJA}K zD8r=7Dh*sgmwykhe|~;XM4{Z!>7-HDOsar?c`#>01&9Iz2oEU`h}TYow-?=B2Zf}z zJbe6E3{F?YI?Ytp%|Csq4u|IzIqG$vVf&bs*Lr3!BltBm(DKFHAx$u{z@V??g=0XU z4dLu68n=tfo{oTj_*c`R&8qROq88YiSVcP=b+I^G5f;@_qZMj+b@P!BZhfQJaBP7h)L%>AG2R zRH4usCnF%06;ER(Mc~gm2Kae6?uGckioAx2a|;w6)D&pk&Nlknp``I#j(*V0aIx>B z%gPavrPG4TDoQSJ{pNLWRS|#`!D>_Lyh)Fp2e=H;hm)6|OzTWrl1B!L6=kHQWp>J{ z-f^o`V3bVflKxK%aPOYR$zIeE>9GdY7WGiJ(s0ScNgu~t|?~WJL$LF5BaZ5Hj?f{BkwNH}Aa@H~KtS%pzUA9&K{JSJ){~O54gnS2%U3 z93Lllp3bn?tV%rF$fi(yxI$L(7Hy3x6|Sq!=rTXOp$#G_V2utp?M#_)TipNNpR zQzqd&FD_*JsxBi0>qm=_6B+K`4ULBa!8Sc!{AnRIu`$#8LKj`rA0&<(Qad?GBqLN- z75ci0g8cka5lDP3tQ>ZBYW3QH;9kkj#TP(cC@NyZ>w}m84`xSnbafxaRN1=OqE7e$ zR&^=^Rh{JBADyzrhiDF5RWZi4=S$-zjt#)vgYk|0_Iqg z&usT!<(-XD3NMuEWmhjrPxFOxd+Uho2*hJl9e%w@8Dtr=Pu z-RFUVo^3jf(1r?!T2xIyp6sR|FBB7~qYPD35FmUk75BM+DLltgOl{Kbda*ifg*0Nn z|E8_TOop85x^2SO9Qu?YIG_R`J##aiL_{&eOJ2wi_pM`Te@_3c0r^|cZ+P4Z<-Geb zz#R3lgDw}{+b@TvH+A-*ZTa*?ims1HkS}{A1)-ZXkTbij{fd@+l*5;re7Tq-;3hFy zDtg&?;J^$RSbZNdw5&oZ6cKsc=|#vG5qr1w|$X$9oq6^d-40Z zHy2%>hx|b9hjrUnINQ-stFK~8a_a)T3fwz90aWBK+GHRfh$=?&)^J#uOMlSYEVu<4 z75?|ilke=>o5UkTnc+)L)4PxeU(L8d^7QyTvgv;3nW3!Q5_2+Una6|~r2j2NZu(kq zB!EpU7+gq?e)!LwL)}2;Xd_LPJ9WAn6^5C?)&wN12KOqe>LX{(I=Bze%J60Hhu#6| zi0nfga-5zO{x&^Gw-2Xic3+AlvqO{qcEfw*LkAi}Y z-|3y*$g}A^@yOY|ECXsdrG5!QIgS@;jq*yQbO{5OW+~2{WvBW6gf1mLpQ&ZM; z?(vt;S&L4zHP%XU7J90aS-0l7^3nXrgAVt1Vn{wwJGvzMRo&dYr;It|TK4h3i-E5z zIi;#e{u(R@O0<=owuq>F(q2Sz!;?E~w3gSpk<*dYkzwJ+Dv^%aivPEMUQk@CFVA6_ z-&PU%q;}(4@{*rr%!sukl;~)7SZfuEbhuIf-(vHXeKJ>g^CY0df5e*7F+e!=`b{k6 z{Lhq28=GMxKf||?va-QkHxWNXF8L!OdFT#|;*fqR({@#s6)F@6KWdaK2NTZyLh2~B zPyc(2HzoTV3*;{Ex?Uo>|E{u3H0BX=Mf`vcoXRk1N7&Dbk-g8ZS?>J_xJmw=L3)F>AT)e6Fx*-} z20<{QGkKW#3h_fI^}!n}UE=d`E*;%bn$pm0n+g@3g?Wp)t^`0KUNW<1Nyg%3_{XoA zxSXH)nofP5vfr%l84-FG{oiNB9D!4DA-M*U5;9Js|{^2`BKdmXy&GhJW{*i0!KI!`f_y=8ch=kI3eRsOmVZ zF6wXCZHzS)ris4Bxd*NC79>$@trY5leiYIz0a$<+;)OOtg$nIV6RiizUkv0Kku<6v zYWeU=Vssj8ty47&W-X3<%3elWzNnY4i1eK zIX|ICWkiE9VpStc0TYGlpju@E#q^9-#Yf#Tv`W6KPbfi; zdWFsHj1BmZH_}!NBPHfNUs_r~kSl6J>`{q7pSXh z=}rKL8>`tyVLWkiZNb14087vS^u(r9ZJ(^E14uK0({}drOhd0x3D)0^>iPMPDA#-U zvt#n_L_{{AVpcx`&gy9T{17~HZcTSYWWyHP+4@s(+^@PpRn_qO2>nToYeZ~pdrghg zm0+;vpCuI?b)QC~jq(R5&CzNs!VL*@I2F$&9v}{z&dyk;Do{j*N?_B?h`Dg-6~){l zeAc~>&w;izJia--y3_#%;qQfoHS3RB48YXW*Om0&d&wuZ>aVnzKh|y9R7AvM%rab2 z?;F+{4>77HIQNGZtQ_x)ehQ!00nZw*@%4jr%ReSxzIbW1{Y);OXd03EQGGnFSu`$% zG+XS9ZCZTD>s3H~8U&pZ_&K+Qas|%EUvM)|iD* zrB0V~TWr@OqU1uGmHv(@VQBl@Vwp|rcS!wL9Ckl+x>;igeZzyauu0vqa7t>mN=#8b zvdmZD27;=Yxp*$MdjuY|{dZ-!9m+(LM2sj902h?(#&(LoH;@AI^ujBRMpZh37#$t5drMNW5gXMu#2jQ()KKAO>(41_^iU9tI8gHbmc z3Ku$njHNzVew*mJXvkuMjCNO9K(OTJ9OqfT6?XMPq`bOQq*vz)R(Th#r-zGmIBt4+WYjex!1ENCnQEqUtc~(>mPk6q&bgq#x$_Fb;OOY(2y;m8 z6~nuHw!2g-0jd|Ob;ftsQO)WX96Teo`f|+Mub#tc%DL7GXK0y!hqtzqp!dkn>dq#A zU*Man4ORSba|Qh;H0f+7bPa(ls;Swy^5O;Pd+*~~L8>kPirofMAnwm_vGF)ISVFnh zY?4w?{OsIE>9b%}id+1A4o-f(zdc6_jH6h2($%~>tSKj~|0T(W4@h2+new(mZ!z2yE zQcuUpecb2FvwSeJ2vEn({naI9a2<9%e1wf7qM`93fx~WoJ}XSui1-(`{e+iz22~hd z8tm;rT;?68KLA9BCM0}NQo=!lDIV=Vy+p7`KpFk~PaR>M*~Dy@a$+rYt9hNNe(N;f zQMA~*FFw{is`e3Ct_ur*-^BA+d;2s8G`HyRXAkuk3fwiXMj*IeyRZTL2H#|$SUBuu zOE2`bhJ!zeRLv@GC`KCgm(#PVOnnANMyCOrjX~ew;Na|jjDPhCf_O+rDd&x3U@(cS zK$B+KQtjb0-^Jt?0E<>QY^Sgq%Gxkpxwy!zr~~=pmoB}xaE!GqS~>6}yCW#bX% zT~U1bJ^IPZ`%We-%HIp2SOH`;R>;M-xA!Ll^N?9tm|?-|rS-CqA5?X6S%|;6RIPY6 z0%V>90G_lmHjQgAX%#v3laXdvK+ijzr@k3jHfr)iT?9g#aysD&H65LI-)$oJtVHgBQn3kV z3EZoUb#1Ts_b(2 zcoa(ZQ(uqBF2pSs%w7O%)uR)f0?vd_Ee3JB!{c20^Gq=2_SNs3-tZc$6jqb5ijgi2 zI=X(}yxFXDyx8~e-&Mp!NLYGm?mm5je)lfb_FA`xsoa$!_UHzm2TL*M2mljjKj^>4 z0nBsK!M|y?E1UJ%*6!|HOh!_=o0u38``vb_SQXSU0BD_B#bjGG$-GmeUk6p2wC{Oz zbaDp2G7#XB@M(z{`WT1O*tsp9s1^fcRSdB__K6By3F`hK?OUq8|w6nm;(VH$6= zB_t%~U*lbU(r!~}^S2cYhw@4&JVf3_>IRTq17|6ybsRH*O$8~4soUA{)6$F51VZ+vcu}7wC&vy@BxKs8EuM0kQv0-cls+RBvWRlicO~|@@>ek zV__Cj(H3Ykz5D&NraH(29gB?dZ*&A@s9OdOJ^*_QCi;KqwNX`JCT6X>?l z_3378*s71k$Os{0^S!8WnsAsPDNa<)=DJtMg3dua%FgStrl#gS0;aFx_?(f-lUrM_ z$;2Gu9q;mxa8mixs+zTxt?KUTbuA;ap2(z&H}v!bfo0la2d_i#i(!}Z`*gKj2>?R_ zLxvhr#28UkFjEA@K*O?B>d{uJ7aWsXOwVCx{Koot2^F(B$~Q3}Kx1&3-oRD~+x-k8 zO2MJF(tfo$+)&~%L|wpG_I(@}5eSHS&SmgWJx`^{ny&hdogD_CyfZ80cbzL<6$Li6 zNhzKXLOc|;Vr4k`6Y`hB43OIP!#s%xD>VBBkesd6H|{!U{bd3L7fdf{DI}JB2Ub*P zjpjKuCTDMOjULif~{GrC|yl!p>78Xl_n8R z0q@8FeC|qqtAB5!;3S0poa{}kQ}JBHq|3FNFUd>Z7%AaWPTGl;-drZBY0ji)FE0Gi zXN1HEl;4SBQYur;kYnahBwtlQ%*DKxS99?irtBq4YZ6)2r7NO#Mag!$u8 z>-Qp@9~f-bvkqR3)fN|AhkN*vi-Gj*?YeV?io1)zM(vEuGys?K7!$LxxvTDRsQ&qw zE*^%@;WH0oVO^XkOZW4p0SRtlh#4fLQ?n|0ccBagwcD8!bBR@r+zsg76FILzko^wOK}Z znn39yg6{jkWr%XwvS>WWl^aO30+@>_1S=@N|itH*5E|pMs zsyCsaYKA0L8)L+u;OgSOfu3RR=Dy+6@mSbdRtGuy zPlX{gZ`^vZx2A)J$-FT{L^*USW8VYy2r^>CFXH(f+*Q&7p`^v&3wv=zM@Mga2oVu|?JCUg z017?!g$I0nY`48fsGuN6 z09V2Ji4S~H!8+vRV6*2wOozafjH5w-e(VsG?GA?tW!v<}uMKye?5*;mRZT3aULGKe zdbTc{H$h0!<4)ih4&4U<4x=~zc-c~zVZ+J3j{cGbIMhP^QzUtY*zXmaexPhNF_8q^ z&J3U<%vZ^^-@hJ2#vYAc7Ukcd@+kf|>uK0B+JcOqNmFLl>{giZ-I6jKp zLrtlCooP6(yK4L^l2%cy2y*a{KhQy5Gq*pYmiuKgQwj7UkAZY>cz+v29M^cykDe@b zlfN|Hk9Ii^VRm}_n0Binh5ha_?$sz;xzkV6hc>Ke-JYHtr zG^Wj_mEdI$%t(q~tTBVALRKW4atDqqX_9ggJ#{K8s&xmDTLc6GfE{Ragh^0a2ApSkOf2RPw1hF+$|kh7qSoiE^h>(n&@;2m(tM=niw0LI`yJId_GuY3;*qe4V9v=pS2g?$`40T)!1#I9!bW zo#;CVz)2Kq7cov1tlU4A4_n>7E>Hl2NAxTx#mtLL57`HEg??`S2E*0t@H!`gp(gM! zV035=c3FMZrDt6mDAnEUY?rQ5&j;eLZZ{@yM$wr94|Qeh!ELlHoMDB)+2-I_@{LykjEbS#``b+* zDAB_BZB(RHGzNe@2=jpc29!Lt&p~(66$^j!zZji|$Qv)5$|MOu*|QOoLf>$@ritGA z1p*6yoR^xCidMdxSM}`Tm*?auFuD*D1g;pz7Bepk3#l8=v0BIp>1M&PY1SW$3JxvV zUqw%5eeOP;S#{R^`$PZ!6c!Us#TT~wXnt0@xf>9w-PU{`cX=!q_tJ4*sz-J#OQuG~ z)xSd_7@`2sAY3D`V*#2LD=?stP?43bEw(aqys=QF6t1U?AkfTHI#)`-;7!0#=dE*b ziXd4b9QaS6a`p4{n2gkTA!6*EV-|L^Zj+p1Nu@^X&zYQ~HAWWmF>s6_A^J|#nB=QJ zkRAwr3Nf&q8JD_7kroYskjoGnyt;lD1Dy=~ig;X4cVH5q@zS#b>2$jOk%1fcZ?VCs zhj>DVU9D!WQlhHN)6S%p%kxe9oA>a(q&Rd#&UplE_uA8gafSt|_fdJOsI*u8?s!d& zOE)-zb{h^aA*P7H!Q!2ljXZn!-jSN_i0&1VEDFy`qd=MeUcv97A0CUk%zqwc#y*Q; z_JrHKwSX9^J|D)rIGrd1Xa}5nKIE$%0^pBIodDm<2z56;d3kK8$@n~dwzk~4WOSyY z+5MN7D_t(9Hlsl$addn-P$(c;X}c*U(xu>FgJk=L&s`r<&IbGAz0a!ov@fL$JEWL6 zAFj>Jdfi1%WzdbgpXLs_XwDq>EHTB1xm+xW=v8mubhg`^1rOk2!|_Pru%zUM{gF%8 z8)~MA-`A-A2QGIHu5HH2UB-8uWL*h_?Ugt|jqf~g(;g@86ytg80*`4-(6vV^ZMl3_xN+w+g1a~jc+kd78 zMPvQ%PnQ23oSx7^u~%4ANB{QdzweUVE++{aXS{lRHkylLQ7 zdpSky2geMe;xj5XogudZdEn3N@Pg3=#UqI1D$z8)= zcn(_QX09_r0zBqe_~Gc+$LJUYJSs-D^ban5z>f?2c~od@^Dm;e`4y7_CPo_>BZgqkwy|hDG^B;7X0%cOdba?xvbU+ zq=#dGM~lP9XW)mCB6PShSzhDp4%YjHdtnk>BXyTBZH3W+O$YK1!1pUIYfnYYt#w^- zX1C|DV|TI_9p&yKPcyQ9*vX^6DwxXS(2XccF-0U347=>!mm!l#cP!FFgVM+CCGpD+ za^ovtW%ZofO2=!Sa_9IF)R}zyX({dl2)3bVIyu{8Z<5Tha2-{rS&}TP<`@LxW9}%E z!C3qnwP?k+fwuNSNzPZX11&)s49|mq%$EI}s5GUbiDk_&jr-^}QRoGV@hd;=CY*RK ztw^C$vkVHl^-He^1x=gO&!Ms5qvTmDV`+?NurjGtOXIKIdN2#Z?+FB!Oj2|JiQ`z2 z&ZsoYW#tWbUS7b*W9>}GuL2>axIctbYBuiOrI+DaRSIpw9f&pHuXjvzSyVhZTyKC# z7f|YG{CyI(TQXy{OCsDgRQGq?r!bt`sL|5}0Bu0%ZuvY&g}$mY?vhBjtImsydR{2z%}v2S~r9w;>(v^m*QpZ?#7nX zA){rB3EKby_N$)1B~$XiNT}A6S>64ukrEC){l3He_kzJZRoqVn4|w@udLHG#(nd)M z;>U>3=cn}clP(ySSVEvzhz9#@i0Va)=d$%96^(l0&O%@v95d74jna6cRqsxo0;pyQ z5^_UBm|YMg6MrV518F`yiem7G%xm|tIT9jIoevkkjhj<3xs{%mCYaZrfBONsupS-` z2AvcD(m@*O$I3Gql!^)HVsMFj4#h9fw6?3PKMxNtAAyZfWbXKF7GR<@xwg0Uk7qj~ z*i>o3AFOq~Y~qe2ZB5jVy24^%IXQXv67Q1L5wHS!&S0QXTdIouK_dKk2KZUrlllOrp5q}>F>wpkCv{pQY$JB=E?bI zB*u&U91XY*66JWu-KDVjQ2tXp)91V!QeX-)I;seGb~xweR%>ENNE-|rusJNh;K=

ZjhBz(Vp)7o&}Oc_`K zYoGSLhVxq(7U2B20|MkdJaInoc~La;oGpONQlBqR z=OiW_*0ErD9)Sn8yvqftgjizhANtf|An-I`ZiLAYS^mD}vcjBDG?GStES%h6tQZ|u zKg70!1+iZbO3$27wlr;18O?6YqV9g0ka1oyr-@7rdOiF5*3sWp^XT0JPO$a&wx4qJ zhbhtR<^V;c&A^AF)6)piP12QoYSRyryfTH1B76^7cepVg z@Qm4eDbd-xvab(KES{@Lc{nP&ZnpRL+v>CayP#&UI_Z3F!;!%12AVyt(@vRX8z(i# zb!L|HN-s{cx?ITw>q$4C=x8UP;dt2D*{d&_#UKx_Jk44^e?!gTLa~{bCGVr+KZW~w zW<|QL?MG|HCndC*v6)6`*MU+PUpHXJ!7Qs%ag-~=Rm=vqFqJ~2VC5SDcQbGcNDJ3n z{2rbtEWFNaG?Z7hmIcdXE@Bntb*#vE68ngSAaevFWr__ZJL5{tY?vmh>;y7~`k^<1 zs1Uf3$%q`~y3gP;W;7_8_gs>*`% z{to7S$d06ev=s0I=wD5&f&mVTtV*RavulS)Tk`v>BSMiRW_9cGco^g$FR!uPt1WxF znEV1v;ovwR{eZ)qE)1C_drlnoYppPD#3zT^b@y?ZrX$4@f=PX$LPxzL*CtM@$}TzV z|Gt;hc#-*Pq{OtNjmxxVM zxbs7OipONMa@~($btp}ANgQ?M6a6vs^O)WkIA7Zge(3HlUcVJ5%x0g5bfS}UPb)Tr zju+|JvOee+@XO%!YlB~(&a`VYm#Tj()k=<4pNzM9KDb9t&4h`b33hpIwY8HjhZE!e z!0cVUcDCX$@B!#YhABo%N9qK4+k+titvUC;wiei<>ZZA}_=1-G zhp_8zem-%+R^S)iDk z>Ble3eYP4&Q|xOR2;(wn_?(lC4|p#+e_fo5#EU3nQc`BYH33m9&>YvbNHr_`_@?KT zxGrx{|7aC#9XM|iFJ;Nd{njhG0!hFks+>xgx^&~qfdjbr;88l}({(t;{QC9F#TJ}! ztXBHd_-*xdbbg){VS%N`J{%W<11gqDeM5R3VO>!Nf zxbkQacAsHMyu^D*JHh5utzWSz)Ls$?#a=3*(=)U(Wg^JUe(QcN(1A^J=R+CAQLMr+ zsJQ$4X=f}r{Fz_-w`cr^0Le0x@%5!VTc|7N=#X|3=%CFksvZ$;6F!~=wI?_-3V-MJ z;yFLN3nja?UQeUO>z~d&YVx^Cs)#&(evg&GEaF3?tAg(iHo5wwGZ7IHisUtv$-q>W z|82EfD^kJBgOza_9IQbL8B$sHP)12x-MLaBs0qYAJOJH9B_)fs2)Rv|Br0Z!>Cyvj zYV|f0Ysc-Z&jQ)v#m%dmLglm^9apeL0a2YR0^KU$qC(SVsMM9HlnH;OSx9 zhmaEmgU}{m{ivkIUI{9;v`szNcLXu-v%s6*8u10pnIeo4Uw#{)`aJk29bwwSGj3-$ zAt~8Oa2^}9l83MC2_KU%V@;_;j*v|+#9 zI30I70CPtPSQJ;V82TBHrY~&@f96z=ypfh>fPpK1IoX4a^8~OM>6@us zy_43}*8N>xhvuHsHF2M?`%&D6Y0H0y6Cq&Ykk?}Ek0sELdL;$+o11L--Bumr+v#y% zIjzFst<$h>HD^`HCG(w*Br+@K*QYnMYSkZeCY^0IyTSgr9x{QXup$P-WxL5$(6CT% zJ@9I2>ux7Im*z08z3`?5B*l;mQ&;$ZPsg@;MGx{;119utVY!{HM7b0;4raGpoS#Zz zVP!P5Ro=(F)1lUEx4$--Ai=B52ikH(iq*;9^FnGx-OVLr0VXKMbUV1Uh2>;vnw`sT=C3dA?4?`xM44Rg|OotHGs zfyIM5u}nr^NrVO3_ux%svpVLrwRPs|1_UwvX>QpwZmTbc4ND?!%u^+Pe~$y&YZ4h8 z8APLK^v@cFL1VQlpKCCg6Ju}qhL2r#sA$m=<}qD%C+w?t{u%=;`xx`t`zYG7-dfdh zD%*%;1-bqA(z3CB;jW6b=3zq}hsi+R;qkh~_wZcCgLo-1nl0qhr%x`rkcR&2%DLj! zjL_PjlDjo(LSfB;F!@6zrvM=}j61(?eLUK30Ra)DtQbz_JU7+S-ffjFc2TgIalC)~ z_VlrS(#!xB6>9YE@xv!i8ZsX}SWH*2b`PTH&9BHmoEnL15{)WwXp@G#kd_Jii5Lk9 z)A3?W7+ZBIws=IDl@;yj@r=<46D)EWO#Vnl(p`oN%cKJcz&hpf|Rs;c1%4$ zC`2vvIUAl(<$g%um=vo&zMkl~;RqfyrF_b6UiLhSd31-J`~*YUXe z4VIwFX``F8J_FXpviHxsRSV>^5Uf+5KDP?f1jh~w`jz2_=$|}!vNB|@Q6O_}bZ6=^L`?Q)h~55~s6>26vpUa0<7eCIgWu+2ILSml z28l^U$FD>jO+l`D_EQfFtiJ@BtB_{hq$Czg6E$p(OnEzhZ7bfhMg8*np|ep@#+pfM zG90fpfEz#-TynNGVL#{_kSs2XZ!-&iR@&#yAI_!--M3^P4T#-Pc<|l+ALOw!kZfq} zcD(JJ@^_F=xjqX`Kq_BTJ2CKqI!#3cX4$K>3Ve}REg42kO#g98UBi%Ec0Vn~a!gzU zd?jJaSK>`8p-Azl=4n|PgmS8Vm26pu=};A>&-fyXF2_)1b8~yhZsv@SltTV&yB-l1 zTZV*-bM6%z6U}STljt}6ER=`! z+ETtM2iMUPE{bl~+(n@~!GvWUUV@=i%QM+0vUlgCU1%s{9=db;KKHUGrp8!U<5W4@ zb+2YHrqmWfO1ydRZf5dl_mzmlI;GjYEVR%s5GVutrOJUi95pN9U}Njk+V=NDAbT|wM#3Lrv94ljBXN^yJB;muK@8YK>;p^8s=6aJTlE(5tsPHkp-+8Y9vEJN+-p2A{;z13nXLpiFQmuIhU)--CLzi1o%Ea)ac z*tc!Yzmr#iiF(SY7fc?3-z@fk)(yD_a$a7z64sadCAVKkOa_knR&DLlZyi5a>icVh zbauV-O_1>XTBy7$Nn6q4V@s9)uttEbze=gZA`yl)@~Sywy!-KdYMSwGFGHF=Y5vS= zm*pS)e(*?`nvs$I`$ubP z*8v6SM^E_jxc{^?rox>h2OXUx{QcFb4#plmd%bR#rOvg&sqPp?E~lt^-#wARKoj+L zsmKQ~&$(O~UxCSgo9N5KwDwfvr#wm~>_>%4w4ohVz27bo(NAJ>f`n)1gm5Aa92Mjr zUuk!%Jvkr|58~g<8~ylKoO*$xBeF=%GK(V9&!c571h?icd=mdx=`>>;M2g1z#OjVq zxQ{tv;bjH&Q<`JC*pi*ws&Vo!dRwGZ7VrzyEsm1AyRRuC`=m+7SKii)l|@*E>voQ| z?6%b`7KRJ?WBvPP{JZn2){b6oo7A`3(vbcnb-6y$z7qC3Nw|n`2Yl->X|itn&nf+@ zd6GF&3T^8`ci0XM3Mvma1F)&!%iJc)Q>#pLFaAR%!Tz3Bz^!hROTb@=h*XVdZdwPA zeXGOiK}k0M{-<+U(?3O+#MJJx0(?=%v|gy+d`CI3k2EV#cqL5R5kqq;)Nz4#B;3Jq zuJIk2>ylt!0+&;q|JroR&p%g1=<9a`i0t1Ge%Ng_DERlaQ)Cw=m!uc!`#TCRRrlNR zZynwVkDh5<8P0sBL)Eu4O0J+m{CTu4^XN}ku_5-GA>&H8`UMFyt1Q)x*Z;nFBi4qE zm1A0^m9gE8e%othEuKxXg%gXu=K&QRxoioeT>b2xGVIK^5jJlrg%oQk{5(=9o>jV4 zynXcV3n;L?9jTe(&3~s`tGw29Z%O7r0xv1)4xb&GU2}ThcTF#A+SN{uZ*}_IVYLtH z*FTRdM}N(nI-j~-)Jb{pOj?dB)~*Sk?myRJvTcBq`4{W7rl^xV>Y2C7-6#qFG0o1S zIgNt0w9~EE7swQ=m*^WNA#VjseT;DrE}~MXJ-aRMWxde<@2$*YyhmKNy6iR2y6}QD z)U05kb57N$=<*$hwLCt@l9lu0JpH%GK%E5xwetDT z$K<^Llb<0S{u+KEU+xdElX9F_4K^xkIg(te0@PxU)3e*tRu$})To^$ezN0P+=^6@VU3rh~ zvVF@4O`69auxOu#V3y*GFScggLwKLO*HYxKc*`I66(JQi_~Tu_j7k(I$-nz)d86QC z?z^F!w$IVexMICWbt;iW5qE@X^Irs}@*Ch`SyePp*fTIPWGdHP$rAQ0R|)<2??HSO z?SP@u(D3&WMnk@%C7#pM)4NK%K4KM|QVrz}3_J6-2J!ex2%zP*F=c#(UR%I<5%LJhK0{*S?g8+g!t=z2&VLKjM_YVNdk> zb!K=+0h zVX8!GVrH+ANA0+(pNY;(KH*nc2c*0SFk6S+5(U)!19Apld97jNG%OFrRW{ytf5@w- zz7A3Wew%%xcMAD}`2^gwqW2nn?vqwJF;BX!=86`oq}sLek;*A_Uo6D?SZ(nAa1)5{CxnC&5WGjH z{qAW#NPZl+2uxVU7cdsotxw3x_`mLme7DVxya%bwn^by56@!!G8692fZV3=fvb|0D zB#B&PvhIu?3v1Uff=Yh2rp!mB|8{q2u4vobwn{&4D6aSCyw&KuUgutPqV^1U*WIVH zf7TQ_zw?q5eDIxyUSSG+2X)ZeSVb7=6z!t#XNjvn4F?1(r|b#AK>UY75|0bB?JMuR zfhr00ME7k0v}RY9NGW2$-U`vDkfnCCAEge8levV$sZ`M@Wi&R+GqwhA4BdtkTNv+? zDN|EL{Sw$D_2A~$HOG$@U5RGb=3vwpTROot)0mkxf6lap4ly!fR#psxcz6Sjc3RX5GOeSovZq@F&h?ad#@AV7Yx)-yde0h@IGV!q(+dD9hv`m~ z$3%J7+glK5uHFp_Wb_9Q=BB?llp{g?@>c+))}N8{x-(@{g+^UUs4XL%#*kmVbrqbC z>euad2N`>=ZuRf>JbG#$z$>3O@4eV{rMqH+ey;h+!|9&3ux*lz9~x!j4tl*WHiN=~ z9ys}po3FPo(kQofcE04`@XJVaxSBoWmu?tvVS?wZt!3fN1-M{X%jsbTct73v8>soy z{ql;rm_U;XF$aL;BLxmC(jc7m{pP3jEA>1}x`F}iE;fzcsNVt`p16mnhr?`vkl~+X zzVE|5ZEZ9Dlrl%o<92{zuKcN;;I%{x+FNglev|~=)C>&>OFe~74=81aLBy_D<#z2m z5fQjP;e8lbKHhrEWZK_2&Qdnn@AV>q&^+vt1pWInKCM z1efl1IVXW4lbm|PVB7?^wdTXHN0YxIY)6a?6tcQwFa;y{N0_?=5BXKHs#BXp%KlJ| z+lxjf8{&+x7z={+KiZL9UkX1eR&}?dhu3;U)jkYHH30J;t#wuY48~`r0XaD)V0=Bv^~Go?#jvD*G^yu3K^=izoPwC%t~ISGVSUs|lP8oap_ zB3$^!xp`GXy_1Jy!iBMi>k#ilEQ{_?JMZ(YKiUpliPm}c>8xtb5j`zIEpvV4s~eXO z3Ee~OrwHnQ(A7~$;lpC@;o*)3l_}#^8{gjgNDvs4J$(Aq-jZ|rF@sL1aJm(@W#ou$ z!*rNb5-JF^_RQs~=PmBGfKl}#>qE0m22T6U#q@9Z$2xx`3D(D>e8b4T!t;&K&>N>*p~M_W^=fE2y? zR7KcI(f?!Wt;3?~zOZ2w5fuym*p=j^lhTKBrcjAt=`DduR73_!oPHgmsJLzK4qw3|dhu(7{K^T7yJ>3sj) z71!V?EdEZBd+ zK>8Ag=rKNzsjq^EX$Im%Eql0U=Bt0qR?}l*si{uai8PPmKk{)0LNvb-W`BYy(1m2I zXJ5eF4i2&PjYBiz3o)C!!_lW=jFIx(dM8f6;O}qgVm%%=VkoPW1yfSS2n5=N3NiMZ zL`@BRy9g^>S6O~0fTKophgRi&9WHPCv6SaRXd=!R3^4|bP7KH1cPpz!fxk#7q_<<} zZ;*lW{n^)xn74oI{Z-MOjfTbYuHdEq(wQ!iSN$bySOQ~q^tLs}w5Lb=xRXc&AH$Ii zB{zp2mEiadp=v;4nwoA>QF(UlZaoEq3RF|jg#(Lbd~ph)2txnsI4^z={9wp>hgyYQ z4yzSJ<;?-tC7-hWD@yeq9Pz1An5`~*lqI62G*0saF!Hu zZ&kC{BgD1pcd>HITxxa^907$sP!j!(})BbNcT3t}T zETru0*1X%}^gP-8yGpyNmf7^cj^KNiTt8z-)ixx(0}Tl@cpxOh{H>LcfCt0f=SfxV zJ~~~i2$yfBos_^lXG;{Bai|cYqzW1}fiG~2ipn3gn(^@Q!yGL{DDHX#jge&ln^6!JlQUC=VHWs^YUeG?1f(T`{f*vnfc3b}Iit4}STfG`}5Z?a}vS{|^_S zMS0zO9dka>6G}XWv=8_h-13QTKLRR_EU^zn(-Z%V8*x08m&X@zojp4m-5o+*Aq<1n|A^Db1;l(X>Gj?^lxy{#!5}I zbj!d0Lyu|yX-`?#iMuGRIH+)Z4yHUKA|tMKJe8AAhbRk%tc9gj?13ybyw}3+sIV~D z%r=R2aL*Ub^?l~lFeO6tb~*Mjc!~7>3@h8Ou0L-zAazK4db>^NgXu8;H=u5#HDGdh zI8k8y-tYa3Hdj6U$B%K&&?Ri^-ubhPL5JelaObaQ-pXuO0M8y9jX@p>dPRxu^Ku7| z=dy|lV*4&6*Q|yuil*!YuYJ~dQ9bC_5G!IZ>`cn4+vukdZ#O#&`rf#V@TkZ~wM&f} z%9SV~8Wm+Orn?M6?g!>exHu#+WRRaACzrKfJUL0UKG9U{3>-ut*Q4he z>g%_fKB1%^)YajXAfV8g=g_PTm|^1N1PSn0Z&V4|m{D+IOTB_XP3`Ix{GB}8B9xtA zB6@3^!?tMD!B>XDo7FH%`cLG%=9JZ~t-{-J2%8*|c!0P0``rd*=Ndb)7dwN?1@yK;e_}DsI0> z@b>LDJv=wlQ%9`Sfo>BZ;mjf+)FPwYHGa5YRHBm*m94Q|V~uh%YteyuUIbVwrC}$f zlv*N#0)<$4gG+KzcE{ET(lSNZPoRhq1C5+~l5o@^9x10??dyx}Fp2kCap~*pt2A@& z@9Vq9Zd^3gwQp=<+FVxQ3L=55+U*0C%R~hnI}kqN4Th3bSMlAei10MMpRVRY{iT70se- zFPQhGUj-wRKZ&4wg9-=Yl#U{-vc3JU1Ap-b9bGr}zUxeE-Md&Ywa&`w%XVGkfWQ@v z3zNeJKJ$sU9~~TKCigfKw44$OiiiZ!RUaooEZN1Em^%*&*Ro@YeXO1uB?Eo$!Km0IuTJD0U)2xc1PWZh)IR&-7ePUWCx7+WhH+BmiX(h%hcjtF&)A9APU}e6NP!g zoX)S^`&Qd*gBV*&y3RjLe^RzKnauhl`e9X}&P*awDqKHZ4J7+cM;BqvrAY(rd_V#Q(0{H^wNCmUA z*M^_I#I-@r7{|G%JY%d$`N7gPjrnffFN1nNea3|q69nH3TD&~!(87sGe}hfC5S{F6 z+FOsa10(%Z#N5nG1N4>@{7%eN0y$=&#pJEp(+0O3oV=Q;%UEmG3$#9GhfF}5ZG;n; z6aU@q^-5@fmJjBl4ang`;}sH;Zf=(X0w zsbzN+fxT$*O?{ppSuDGGKakxLr?Su%`S|!aEslh{PI#WDq86Ut%SOf#rJ4lu&?>2@ zMnxz2hW_Z!;F)a2z=b_&$cBM@gPM^yr1&Yvr{kJG&AHYq&o7K>X{r8r{vlf5jaI_f zcdcqcqVlLY-aM{ZC%;DjKfeeo#P`w=o)X)HO~eJKm612#_q)*sY*+Z+yTb;qU2{qj z2<_YtMqqQxT2BC5uXNlp&T=$QB#bfHgElyiBDqmIZ4ApL$REZkI zI2|}_5$n635`bkQ#$yqzWzjD^_y4pua#YXmOPt+hWer}A6A&@05U?5e2n40A-7$BV zjtA6+SoC0daR}BR-NcYp++cBM{n9I-6t)eVy(w(iwa?A0R5QmcH?9AuV z0WRoG8;o!l1asKF%$0K(D_W5+)kz{p)63*d86>%4`7)cVVpy}Jirw%BFVbfB z=lu3o8(e#^&!vU$OTs5veE$JsHl@Y$;Aai#e!iNkCi@M?#_Y@;?;9_z{n<;|f9q?% zixJ(|n2SRyh*a0Un<%xY*T*isatMex=a7NzC6yUd#SGP)O@o4&C2C74L9i~{wz9S3 zl|hu;;lnHT{8J?Ni@Zj=2Ra14$UTu7&T7y>vT!`(6;tNg7Ne_pe9jLF*cf>0NQQ4M`8D72JNRrv%`VYS? z)x=bxC-1wtVml#6?==wC^wvH>i5N)V`i;mvID7JrCBP|!!V_ZwT>`GPz{}$_S}DEp9y_7*FT|j|3QNGQ?qeT|AB+=iO3Wp{@=fIshxsIrVZ{4qcNB^ z+?Be!WyJMQ*~|Zd+|v)EPHhStxS#y*f1`NX9vG?aMgHGk@G=QDaXCTi>)bp%y}Thg zIjo>#RfB+&an}h3Sd2(oPkcJM}LKYqL-Ybage)Y(gW66_}dBd<|^G zA&&wyfD&g1^w6$hG#v2HcVOSHH{ZgMUpUb#`S%(=7CtR+`r@dV896&^f^n+`^8&~i z2T2!@O`j3t{NuVnNn13E1-TteU}_GuHI!|Qg0!?BLiCZe{Qp35T`VC-txynm6&4o4 zj02}j?jqFM9i~P5_}@~AX%AJ^)QF|(zz7yZ?jVrT*Y{lI1IN235Z!pznf32}+|J{S z(EVZ$2Nu{~V5KYz$7L9D$5yJGJ?`VgS5=czQs4Oor~9BvOI;SuVqq%!2ka3oC`Gh$vokQ@G;l)L_%36ZpCSBixKCLurbR*m zKU9eU{IpR3(!tc8TT4gVWhn+$(TmxgUE#(|v3!>N<$2+ek&h}|R?Ua=5)oGad+?=1 zm}`x?ufYh(lX}Cw&Q+6IPbG(W9mZ^^6`885&tST4gvB`czR7}~SrDF@2x-w(2?Hue zQ+BY1|1vPZtIJLXI>7QVHP%P79xDHSE&J!Y(Jyr+C9&c%+`FG=WxZ`!dfe|M8W)=S zJ>@$D7pN9R0T;$=g@46`YQ8eBpga%mkXD%kgXK^T1Ne174|W-!TynhJ`J2d!RF5-_ z!tf?oE3jLZXmZXu>yZ9kHPdqRtuKXOnOu93GP(2J+%Is@l&RJf$QUn*;~?bUkolr)GUKGmpT=_XS1qB=ADA`2I()3N~DLhv4VIk0py`v0U20 zg3>gIBpLpXQWFsoy*4D5LRZgPq$VI4qGOjR240PQ`t{jF)J7v<$i5;W{Trh)Um*(@$`w4J z9NvWg+cK2*J|E8ZeR`k{_8bck@C4!{Y8wKC4sIkt_IPv(5tU0eNqlGEXnHEM54j&$ zbk|P}aJ~k`Tao8J?cRFW)De~TMh6~8Wb91yaCcaG`rX&r;sx&`2p7^`QT}+fbTH!G zs;DHAZ(W*j{o=cavI4r)L_D|HJ#uIx z2EnrS^qfYnR)c?oID4^Mo-`)Dxs1$Uy7z+8&zX3RQc1OQN4w_ zy-;F$rii`pIQcB&ebQ_i2?>LXZy$mpeQNTJ_sPx-Ay~%%yxslj_9OGrLYyZ7S7CK| ztcTxY*L}sX(5`XP1)jW169_`cMxmz{OLWI0#ZdluPSOZ5AifDo*n482Bv%K9Cu9&wxf$(tXnIfzJ*mj^> zrbawa|8fg^0}sDBNx&$l(?V)@&xY^7YK7d$I4mM2rbR(uyfGIs-i3}iP5HjaDB>f| z!XK}2dAC)iFRv~zRT2Q61YH)nHRf6=tNv9Np8a^+#m$~~zid&YSRf8aq7jWD)A#w1 z?0d>FUNMf0Sg&3<*qp(qJb3R4>Gn&lfG=S{t&aht$aaqE$wYzmcw1TE4*y`n<%Y=7 z{|B3j9yVeP<><*gek_Q|i3a15oQa=Y`!azI{!2Z1G{7R3sbfhw>8Gvz+Tb56?nqit zP;klr(ss)uLVLaKc`U23%2=W8`S6H{z;PQehhLlR0y4hpem{!ff57%Q2H0*YR*1hy zXaMg)?r0qniL200zC9|q*W5U{=k{GMn=x#6T?vp9EOOzKTiOVVC(yfH z7%BD?P|56mF|ZM)h48^Hsy>UmK}U$um&5dgd#k_KOLT`G%&o5tc-NB|{B&FGiT?F*Zoy;e+k~ zx3j3{$f~>WLugT|Wi-2_4PvcmaCc;Lrt)lvXsu#_b|_Cr=9?S|#ZKcb`2^lrD0tz( ziegcp?Htx;+u||qpJ#)_TmPM4{ND)6Aj8>eI9sRS^YTeYBr?XvT=DX{u6m9~dut(V z9PYH7i}!45itoplSlzzQ19~#%%VL|CVBwV-BM;z}Gzx1@jgtr8=oqtPT3z$wrY5YP zrmMnWJtPM&UazvU=$W~1mTF#b!xXcEw4Mn6!3C3usc}2((HU!brvF#W()8=4mt?B((ctw@9@0PL7C=&jHk^;y`0Enj= z6Wt&U4jaEbo8-)mkB#8L_3!@xY+Rrbn!@M_wnMNx5jxOfQTq{^QMOrtQs&}}hw?r$ zCWiUl(X*|`y`1bGTO2&gbeJE>>YQuQ-$Y66bdj7G-*_uHeNLpI`My zVd$DQ)5IPRH}`?v2y$n2FlZ=O8{^3%PRkYXm9A0=vKEqkHyJo;HZBtUF?eKZ$_VQ~ zYG|C(Arc}dJR;wONpykwCYICw&MjmZ_KU{vN@aQOJo-LUIHA;H^*vL`&u*t;KI+)D z_gyWUvASCPq{^DAGp~yDHDsOiWH?)5!Oqx$F{VFHL^w`J7)6)#Ns&^73Nn3CN@egHA|p6y*tJcY&v5tP%9g4Y4p2Q`bso=i-%*J(@80{ znY$h+i9T>~;m5euFusMiZk}y<-5M1O$}vEisdxVj-39}T%=WqQWQ@_$hlM11VU`F? zV`p~emE?J}^bq-{>`$QKq?0h1l;G1H-N2GK*}0{d`K}x3?bl>AzY$I!(>ecelZlam z%clMk#!(CaS72J7HWp5N>7SdAuR^m!1RI&JcfyjVjYbL_nRraQ=Li47B7t-Feasp& z(}y2Kv+O6$mz;qL=B-P|Lm}q0v>G@3FU7 z_j`BQ?KDc`^_b_{mmP0L*tI{CmdzIiizKdm@b`xV4$gSh6;hm_C%55XP|3XcF+`** ze8iYq%qMV%6?a*{+OYopRcHqR`ym%~Fs5!zW3J98;1==#F@y<5bKnsx5i^ zL~n#Ix~a9LrPhdxY;>3J?%kN3;0~kqD};E!2m1{>?2VSwzBQ*Z^Re$=U1NvXbUbdg zr#_aE>V%z*mC6*|qUCGh2E5^1NvC ziqoSV)AKi{mD^{y1NjsV|P;?d38|gYZ1(kM9Ji5!|4j0FZ4OLOHVfVSTwAqCqHm&1>Pjz*y28 zcZpnu9;GW^``a~8Kh#?B-=ZdNq(O`~=Z#n3eeNxOY6hW%fOnH7 z6QK2#NaSJjPpiXgn9GXevw+S(Pk162wb~{YuU+r)WmZshnagX38Q9$?3wagrj_Io8 z(+>05s+;I3B6Y^9+t$6%W>8x{e)WkbdhYRy7ylu{=zyd=X7eF|nlRwWD@|7QlaqJP z)IhCg;I*ob_BbVhMyba+alSKtd&D>l+~j(Gy*2RTQvf%)lvlrBW(|_05O-aJie%Eo z6XHKuKEKFFPrpe%>HCEb&jMA>XE~HRH?JsAV7jUe*(`6e&bB?D+u8L94RhG|_`uGy zfeati=ft?JBamZV$t|er>JZUG0 z@fp+n6$37M;WKvs!?qLk{<9aNf=R~jUlyHEb<8Y1cqd0}sf=Og+s}lUCDKuzbmv+_ zCv)AusE500kfheMn6z|nZ$4f)9LAoD1Dhqy@gu2w@ z$8O1)-@b8qcIg`JtvAf{Zn%kFO6r{(kTCGn&Ly>_fy1x!#Flj9NaxX&jr|2kqSe#>U}(j=*779let+k8XC-7X*ryq`E;QRJ?yM!cG?{B z%X*xW7^h+!7lE8%qo?O7k{o5zDS2^}10W$|p-sbOefOoNizt{mc8(JGsxP)L zSaSd{0OOXeKD=(SG81V1+*YHa0nRx&SK6+l*zj zG5>8YuKg9utG^*Guno*rJ}BsvfP1_tCSk{2uj};m)E&&|tbRG?nwV%BEdD;zXH>i)xxXgbQzgQrlr$R|p7t>?I9(6DTbl_N2~xqc zi_00`zPZoDL1rv}MTnC48F~C*TeCv^f$3E0ozS{^XJB^BwZ2h$L4Fx}^ZA(@^sqzT zfJn0il1G}FU{ zYLk0qH*E1ApWhibYQGWL`o4X&*`|2XnD6VXp6!oUlv!Cfp-=Fq^O1!v6og@-2b1rd zR)0sWtbo5a59rCcV|#cB!jK_Z%zt}ldiog$jeK2}5Ss$n5&h}BUPIYiWU)(GSXd6RRW~xM|;vx|VNh>;rd|fLTme4mzA;43C-SGa2O6K(P%p-6bWcS9NeKlB! z0|X2hSt_76=Wd%$hy#@;a>ni_gl)mA2!8`K67m__=Zm22#ekMlK{cIKYipCY)$??v zDoU(hPouC?K%IM1;)Qd5d~6GERQqmm+A|x+~VO5^espbl058 z$#;n3|HaKg?~vdsw2)<~4D6@YfLlyZq`ZEO)j^7vrG0?=1CY8TYm_Sy9UWoqms}m8 zs85rL$%&B)b8=Cj%qktX`I3K7)yS1U@$(J1F~B62S@4RK^0S}=<(yJ-3|P1Bdk}tl zObCx3HZI_SfcW{TZufL(gCh`7>LqHE>3mLZ=nV&qBEleuG|BnUaWy-oR`TY}TUBC8 z?1RVh06LYD1Lcld(7UA9qIlX#7}~l=0xbgER(a6|K2edIn=tjkxLn=OuY3sgk>A%D z`wDx{F~H|w54(E(YQx%$fB1~F06rjR`9}}DyUZl%q|_h_qs|D#)ud~wF8nSPgaH8o z%vlayCPn=U0)~j=jd4PWjk(!Y7!KuG|9-!ZcBcZY4!kp1DEUn;ik#Q(Meobxmlc^|?POpynV+F#RvY>53jUQ8WCNixK;&{` zwBU_svN!Db9cqKGhnEM-YEa&+him_TWI9hz2Q&7j5&mTcpq{wM(+FH87&Me^FWe#~mmJn92doK01Bth-c@!xf@?AMiI^5b~ zL#eW?;?BN%Kcj+MILC?(*bzhC8Qev9`U&SuvtK;x)$IALt$)3a z96M_eC;qy}IGv=}Al5g1lFwic znoAYWEl07)VqZC7m9~d&;Wwg^k z;1+1IlKt}00=AGMG;M>~8Ze**uyl>%AWP2SIW!#A?e*VkV3=7E!@Km9)~6I#CX}|x zssLu1IDz*N6>4ZcHNYqF6N7hDsjuS#@o0Q5Z<=AjrQ*=1*XvF_ePF`+rkkMK0a0Rw z6GQcTvo}t93$v|}CL+b1$N!fLkoXIn2ReQcCrIgHJ2S?Q`@c>hQqR}^kUXvkEAg7H zC&T;FBMil(w^w=08A;Q`!3sy~SoX6rmiFjV`OZbk1#ga}?{UQx4wY>erTTC2J$f>v z>ruGI+2^!_-p>juno9WR9-#jquS=Vr>z4lnVb{8;$7)4F!7 zg}95l!8xbv$-;%uCMLt(tBqFAuW-i}#3*R8ngT0ZjRap0xjIy!*^wX|M6F1sUIb@SeHuw%(e~!%SM4Yk zY7zUlQ8oGhrCmbcUcIuxbSL$q+IHpOx zQx3`AsecFp*J_=durM0fK)_WL{jth{Z6J2OE6IJxy-$Byt_S)H;a|2IlYBxY0PE}C zYx8lqcfN4(9RIQ*Fhsh#7{`XAu?A~R-U130Ega6`DmE4-R#6iEDdw@Axu8v$-}qXP z?K8o;DH7-r8q!%736xxSoma-w=?oba1#3dfjt&Q5jU~axc)#MH!q#}#9oL`9 zV>*rZ0{xykhDRkSg75ite{9HI0Kal@#5&qtzC}dzUu*im>zYo5m2f?gb^tj%jHq1( z`zVN*D=aE%h3V6rgCY54;9X8mzJR~m?IDqvU3}llhx@zVzt55>0vCPO=^~hYK>_)= zpBHLnJ3(rg7&+;|_1+>TejGx%P|dX*+d4a#r1|#OoBw_8(cjN)-MV?R9%yAiE4~d; zQ7tVkj*Joi_rg-0Fc{rmcGTNfD3*xNsqInHBk z*oDzX3q@r2e;A8VA9m)|L(aI6Rpg8s)um^B&pOGV|NHSgQ5f;u2qI;j%)X}*!(}-% zcU|i9C)7-xQGqf;);0cYv3;ozWAVYHn~M%*f;TWcuEysbe1(6X;ls}YTLg&U#i1&Z z@p9LiF~g5Hx7zF7xMH4!S^nBp5|h0w6_8<2C>MM$bVmXE?}p-qC*>P zC)PWdO%ew?sM_q7ul2Yb(8F~na$@(3wR@F;C*C~O;D3Q!+=>}~Y!hnTQ!2GmmX{_b z&-k(^!Dy&dPZ7U?*~Q`COoAt5Jp0-rdB3Gem9IDYGE zl5kXoNgOc~Z!hd#+a4M zu2-WMfE+o8VtC5&J?CVZ@$TKe3WM`)?enDt{TCBwr)D9!Iimp75bm#ZHi&ul7b!_3 zdCUtnhsJ}IyMJZ7iJ6&a^ipp&p_14sYf()S0Nm)8rd>yI{+@fLhk+A#pU=1RYqspV z(H)8Boi*xAnBl^#%JsfGFp8D-68E9rp6}WeHvpOiY;qa~9sw`g&z{b;MS&Oobvi;S zmo5jO2e*e>qee=ssdlM&Q()4p8Ws$K{H>M-Li-ozJ~kDnE*S2|ul$THNyM?{=0e-W z{Z7`kq!R)6$F-FzK;P6x3FBc zz4&*KqKC;f+a_b3P23lsoCy<$6x94iuDzwfq8>}|(!&tQ%DlA7X@4m!4*^x0#_Uy| z4zYxU1hn(ct!?)SfV}0!Kd%D2Smw=}n$^<)z3+SLd(JUX@>wnF0ZC&@_2b7$b1T*c znc!5Tra&hkdAs^RPl563hv|On@o&(I|Iq!>SEEgbxnG|-Ud~XZPcHVRQHyyD9P17{ z_x1N{m8{fY$tUtB0@I({_=p!x!9ANZH)g+(xH6IyuZsqkxysWuPplKnI{oP@!Dlfr znPy0bZMULH4Q7t?cw}A;uQ46+vq49uXg@8!)vN}1JI=~ajo z@e4V)6tpyEjRz=C%zmeU=*cAZFYA6vENBUmd@P7Ks<$X5&W{Y%N6qzyV|ib)EDziM zclYjlU@`RldSZ+P7Yi^gzlh6Py%CoqG;|mTcjmx)7@HhA&avdx!}7OeFFSu1gK4=+ku(7`iEp9Zx_RS9UDlxG zm8;iHH&m2>%Zoh0!2=4HsGY9>G;cq8%IU>v;EeF z17R-pS1>_6pP$kFpO8?jl1vy>t9JW|u6BChnV2lp9{(N)bb$augWd823=;qZ@qGo4 z)<&l$zU04XXjXXd|G|D^YckdoZ4lq_UT$thObermYMUy_8_?gKif8&|T$WGH4 zD4o%VyIVKQj&`YZpB)y+7+(-{S|sX>=l=@*5DX{7u&71tQd*ovX_dnB{olWrHHt-Y z;y-`>T=Qi0=5v+)Yxt8zR-+EpV9N}kCd}iTx^0?fdIQs)!HxSXJ^T^ zLvl96OQ45K)<+(6Qu4)|%sr;{N)a&@r;_nNJEx=}Lm_wib$7E@8}52_19WbhMK0r7 zhzc;vKzkmqJ`9+91xRPth?2}!(|dc>9L+ZzOiFA|ZuNo_Jtd!c?ZB&kIR8!S8#$JS zGhGV;UMj<1dNMBT9K&mW5i@mIESMQV_)4Tn<1dt%UFKO{7J};|)n1hM$@`4=Smu34FAiU z`89jjZcLfk291np`h`*B)V}=?bl^DnXWOC(C=PZ98#fXZ&Az(BQ*3NpN%PpX_%L5= z-R~EbJ&d)nkTv+ra(FKR1<7ATGZM)k0mjK*;yIj{Ky}?${JWv}LeXFtwdMRk#C}>3 z3&=E0d71MBHzUu5vn&R)u>tUDg3%bByqM?im|<3;|dx}k60osl%V%V%nE z;h!BiGHlPYL7s=iT|PdN22QZtDA^qRMS)d$^gCNMUwu?0%gP?rF5BH`#6PpJtYNNi zXZLJPw#dCnHRsuzu0&zO=L%zPr@NTZKxaJSCTM^j`4jeM%Me=k$x91i0=2$f<763QXl z*P|wkf}9^Alr{@SJ zGy;)$;cHzTxgWS{mbk_uCcKlGE)&dyCN536!EemLap57-1;AykDi4A<8RPNt-CvgD zM+xfz%kcu4a&v9Liye7DKb(7u<2^ z!4IsGJD?YXW_`1-J-_F>y)lG#H8vAa9eCAW+FM6;=VR{f@(S4pCTMKzOw^ z+Kl+-q_ir%NP)`N{c*FduCBx2=W8fhzI=~gPIMisi+_ZkhvR+BcfCqJQT!c$u1=yx z<=^I@X13!cg*`+RW9m)xy?b0&U*CZ0^;q>W zdrln1@}H)!(FIkDhiXgARgq5#pX9BcoyiK`?87F%(tW(E&F)$ua@=7xHE-(j1)$q> zneL>Ok?O>IkxZM*`8Ch-^}YWLbyf~917#bdo-tEQHl6X?72TYT)ZpuW`6lBPxzn{s zMul{_C>D&L`hK&IB$QdOETz|RJtE>F64ENH46{^!yiHE#ph`<~^vcU(>5UgyAdg{S z7Z*oz@0AL^wR-UW5-!ZbVubB40wQPfJ3YXQ*ZEqSz9-+rDk<-${&HBD%j=239;<5N zae#~1)~t3)ylyh8TP+_6IqCySuu{Tgv|6?~DuXZCn=4;-&W>R&3L*9M%L|A)5!e&U zP)h1}?c?p(`0aj*C!R_jE~qoj92fhq^)%{GW7ii)YoV7VVz%6F&yk z$m%q}%JWN1$tEkMgbq&89Dy-0ovOLd8Dzq+0WAP4r?MhTjX#4w8Z_E9X3J~I@ftIRN(JME!O9t)s~8|VzcwHlfB|N-_^M} z>PRm=>*l-B(o4M#6A-PR=Jt8N+GM1;?YBOAAxJ1Go9mkl=EsIMf>7miU*@TW^xY6+ zQ~?>U+<^7>+Z|kfTV7wl2Iq(rFB738D)G;a?@Ns`U-6Q={dBb@Wk0)_-4tj1OA~?W zOw_a8XZM_6(eg2<_;P*qcfm||&B6ZU13%GiUXYrq<`A`>d~NUg z2GOWMj0}H#$m^Vi{Ii{Q4xxFCfUJ%Q5!b#l6&WCWW~=9Kb~%=f%O`Jg5$=>Gqbi)H zI=O7O0d%%AK-e^erlo_@!QN9;=yDu{|7I$#w#6tg>auI($=JfM(Qa==$YSVw`2DK3 zD3%*HsXMmvYre|t9}Bvi2>RyeAX^svNGRI_BAJAI#X~3uv!O-YC^$;#pF0&v4htj1 zkRRx};}j4T>-EFK{+&7qhjp?2+4ySYOdX6NEfGcY`x9CSLu?K)3GRtG&#{Tb;R$Mm zu;Ypai>tO1C2Y{0q$$EMY93ZvMQLt(E{w$Dl;(XP3#l?V_w|t7zbE&+jQGw|!>|{v z)d~9fOyc4f(prQ2!^5@e@xlR{F|# z#MMF4FokRCy>%6CE(oN!<~x-~%XL_It)3-g3X_a9054o0Vs6?K?gxOt2bm3o~8@L$cgBzK=>D_cMl1(KcTEw&Ka%@iN`C z`~8LP+tkPBhg02~OAE<7i=%ZQamBE(p4Xs1TtI9E5l~ZHua1#OhTmkwNsb{!DP5wC^1C zof()ME&CEDbl69`oq^)nW2~f56@Id&idE4^*$x(d*xyFt?r>}!-i2=KV_}-f`LSi3 zYn6UgZ(_FpbCH{Kn#~gBJ6LH(eL6epnGZ4{L?ukc_Sp$ZRox6HC2y6o*#O0OT-Ozw z$cB`ngGDD&fh;xKffJ|26K7I}XSRJf%Oq@?{mT!LkCRrMSDvBMVo4c?XrCgI&Kt~m zznFX5pE{Q5dewMcHT-Jm-sM^`PA%*Z!;WyCTlt|PC8wgM1}^1K;~E|;yW~DmkZTNg zPEPJMxg*G%aOqepK~W=g7nr4IZyw|rR9rU*`rt5kXUn?a=3iLjrIMS8l=^vjgoRob z>2cX~RJOX=z|ysL;xLPSbGb_7kLGL&?TEm*Y5RLWE;}u~%8D~|$)ro(8Bck{Df_58eX`*v)%r|Roqd?s<92bx7_ORfApHxa5d-})4o240B{ z{PqtCQ%QHY_xP%2t~!hQ$Jv3U{*z6V#q;M55;~jDL7f22(k-oOQT1%Ti8+w9EJO!kTTGEiff76tt5A?oYL^F8@6Xi*0NvPGl1FS6&Rah}`% zj#GTx*zZdfGa{}Cg|NU>NRUdpGQVJ89zwqA2h{!Mh zmqj0~pw0fFC6##LLG-^5exy#H`yUE=yYVIFCksE%hC+IfvKmQryV_!*blQzXMSn%6 znx%igtx$#~`l0T#jtkzfrCyGVy{5+Uf?tbULbWC5+x+GqCt)Gy6+xR!>~{|o#r|H9 za*6KtgkAB?Vy3IgUQO;@-%zWUtKMYsS$;~0k<^xR__|CU%$S97z3@JUSNVC}zZ)gx zN~0Q-?wdr!0Au-wAHE0PWoVpn5boj4?P;BJ`t+Gxrm2ktQugkxvi?Ic?WLZ~J^yF~ zNFs*0QhY#MW)vIqsU?tP0+jp(+TJka0v*6-7xni<0$0@3D30s=PpVz4Ut!EaQt=~w z+#j0s2D){B%gRbO6O>fxp!Z zFH9~h$c+CkUYgkF0&u>U$03Rm4Ffo#mS52oY4-QpPvjLC9xTOa(|yY>s3W< zgE$UE^TcU*kkwb-+|-xd2>hn@o88!;#CrT%_F%+9d9=zrs>Bu$?akH>3P56(c+3_( zbfO>jv;6%wZ*_Z(cdjLgM3YDlah*tp9p59n5t>>HKlO36@WUuihB34_K%3laX(%&V zJvLA7yQ&Q@41pA8LHgCRMB|aNnnGuIaCpqK*FebmC+KWdHIo^_*dT=EReu)AIbw_H zzapJAIJgbR{X$??4fcVL&#S|XinT8YdL3NZCS#jl1O|Gr^jdk*{qePG6xBM}HrWR9 zw=*18TqyNJg@e0Pog`chB`LGhxgs9NJh7QitRPca`ey# z(oS2$!8krEa2*Fd^pN$4?5ED=NwdrLCyiIXupVDSpdLYy-180E!Tp&JTka{yQ>)<6 zd9Oe2!Y=0BKuT6>e+3Wk8=U7jbgwb^wn2wMOP-h~Cndqy?;p3u*H^z-Ze$y1(t+Kdr*4o~>Vcs&$Vj!JX$l9ag99*z5=XY#94RW6=Ri8Va~ z10S-wJSAnuynVx~;Ajb#UOeR+(m5u=f=5AVzO!<-7suazv@8hNd>Z_Ro^oypgP0zoJ51U0nZ-- z7{wi!tSxjH{EA`1y^aC@T+wtg$^LY+gZv!eK_uw@=d(a=Vuee8s=K3U=K&qYUwkM* zDTd4XT43t4YF#0;&o%)df?BXCsbqLJ4g}oV*lf-DwT3Q=1{6Hp?6TO^TEMwRf4;h9 zTO$+*S12BPtQA^{7kG>NJ{?@t{)Bf$4>#<)Q&skKJ^Q^fz$V7QL~@QDT&)zDX9Fg< z!)hdKTad=+C|$M3a=b_P;v~KGFLLXtOMQz`>17L#Qh&NVJ>(m9mu}vQ5j}eZU+mDL zX?O)L157qx>PQqyE8^E{&e~V~yUbGHU6NaZ44r#Se$8np(0}?%4Y3)$I71u!!#HhD zE@|`Ih9)N)gtvi~eFGhXkX3wQI2*)a|FkInhvwId-n2fSLgJ0w=9(%iUV$k7Js&t( zjJP&K(uE)yl}_r7c}9gqMOD?88H#a|zYlrQ=XRo?28ZgJ1?d1Obrgv9rfO{5N{O4W z_)Q1@OklAumv-0;uZeZ&lzt?Wxt=MfN}LTA;#VUxH>O7REA=|S|GQf!4P6@}ll}4m zQdtuszWU1yXa0{bKzC9D9(_`pO`>pmMiLWLWQPuO*Vxwa;0o_r|#Oz$+$pXo)$YAMy-e#pZ`TqF0jgya4)FK|i`{D<$KYp~s_+ex$lAmcJ zk`QP&ns~NPVP@T}j-G0%scwgd;lMN%w3QO(x)+d%OUSk-jyYxXE>ZNzd}P(WkxAWd zL0NNN@P(sBw>gGu9kNS5X1qE%T$t!MW!+B7jMn!FkRxgL#67>A@3b}2d?FP@!RyA1 zfzLrGd3kT$|8kD@HWi`R2$jw!g0$Ah`M4fLMecZ%Kku3H3}&f+Gxoo}NN|}|{XRfC z`x!dGiieT4f1P={G4gtPddAJckvKWkzj3*%eP-6WX^KcwizPpaIC@X_7w)@ye zrNguwyf+M|3}ZS>J@!f^WRk80Za<`5uU_uD6SdnML!PCUD;GbM`^-r=OCw(qZcw2! zYEKt*(jJ&S08lgzk9TiiY}=b|Z)~g0rBm`8p=ce)Uv)K6UkRK_0FXC4PWJtJ0rM=y z!Lb2+7nrXpD=Qxy9nQNa=pI!&%*lZzJmtGySyYKNIIQoi?P5WfRPMY?1R-w$Dw%<* z;(@7l3p9GYSkQjM^|Zmr&vD?!_I-iG2VoFJI1+G6aNGuXy?B-1_M0NQzo}q`sS>r~ z;Yo&n`BBm)i3|18u7@I+%pd;Z^*Z(X@%)=yc-wJ3x3xAR6)cy)T1mUa{0-NA3F*iH za7Bh3bS_nenU(_Mk(p_?6f;8T{s*%((!48Na`b9$5RCl17l*Q4e)zcT3NX^DJoZ}D zN^ofWql*Y%Mm)htu*+4nnAk8y-~f;K@!*60(o7uz@DT0*^I^B+)qV1w8ji?J`G%Rz zo_t>kcsrX92R>K!Grx!zTVGcMqh2A06>=W&q}IB3{@-;F?0_aiRQ3(I(7M;W;Gp~y zHS_TbVYi4L!P~c1X!mQ^pr{VU$2E@~C-gmM%#p{P~UgKZ8E33V~rJ9q9})7$SGZWm%NLRunFAi$@~9zL1ZgY?jM zjg5CxSl@qf-y89YFSzpclk_uJkTm?&IqXLziZ*U> zP8L%|T~_GlTy&O?;|-r`kimGvps9{80B{QVl4<+cVo&6PIh22^2Z0_>`c`~MlGvIV z-~qvO`{G~`EGl6ns2p{FL7NG9`aoYK_S6B9Q^)Bv9vlN%0^`y8o&;|z z&7)Rbw0UcqsP;iB%Y8p^6y!5w>>8on!0iZ1@TY!7^3Cg73iAh7;a3xRG+^INzkA{? zo_I{r{)J06u7LN;bXT6*m8X@cmYvh1e(-=FNRlwDgQ619ITwKHiso^{KYw1)69+^5$EdQ1 z<7ZHl7Ek^@fBCGu>6$$SuR_C&%S?-4H?U5wUb|Mmy7^4Jkh+_IPR7_Ah-Jv;Q@r4leLIV&AM*(gOsijzU7R>lp1mve&x(l>~RBtNvs zW~u*pJ}GRigO~@M}0M>DS_0AnUG7eMp z2~G;LYCvGy_9oPHoJNa8roO__=g0O87=EhpxB% z9GRju4kf#3y^4)+Y^%1}7yA3Y6KN&gXh>@49*%x8P(&~gq(wox8wo)|TDn2$?oK5{x;q5{0cnw3U=Y$JB_-Xt=)803 z{@-&xob&D8G2CMh2eQ^L-*?VuJ~2oIjR}OVL59Pj>+fGANR-G+|NL@yszAuMmzgkz z;%CkDDVtHk3%Ctmxz)i;c+}s)lZFGlNU7cWwrH}11oK~+mm&mqu4Q=d^DgQGj@}6v zT40NY5H=oF_-Xhf*?~i+J@bXmv>Q)r-d#)grgPXT_}*Su4QuVAw>J$o2=rJ?w{8J6 z>vs6<0xYRW(LkHnmOqf^de+r0EsJ|eKn@|it+tC1@x!!tS3FI@#LjN#NVgT2;DW&VwYmqxg!_5P&qo5m<*kqfakfL{ zAMkdbcWT|)Vd>|q+VP>d0Wr$}MU^;qlkVsZ$KG5WV#Sy{c7}$N)FvEB*Klr9fAhxA zV>ht~9@TFaVtMCeF+5}NLda5=~yw|*06Cq6N8{)D{eKOqeVn{WCskHAu5-eeFzh|7uON=Mmw=Cu3uI(@-DJ?Jezs~( z#9;|4Cv{aKEJ8vY&r{#htoNCjMu^|D>z1MC*Zr~{vGJ3fIq8<|y7HeQ9H>E1h03uo zTxLt=wov`9_vtUrB`RDTXx>+;2PhViVWnpNEkd}XCWi)H=8C~Ar6G+O$i^ekt z4w`ql)C7{Rrfk-WAsc8E>eV_>{daa!1`r8*GUfu}$)Lb|V6_;dj1JdNYcE)zA1o3_bkM829IxQ!k@x!`6*| zUuSJQEL^$7_wj!Ldqa{{>J;_CJ}8jtV*zAa(>ZED!nj=Cv%Huo$A8y#6a`6^<5lIo z8C!2LWm9^uh~D{FdLd9sRm82HFHKI4^htQf^4FJ&YdGX?CQqvV;^?}ss8=NcNW3BJ$JLNLSpsD`zk>n{9U!>Fq3od@ztc_ zMBkbHh^G?uD>k;j+xI^V^B3ooJ#CYZ810M$lK>g6Br5JtP|UonvwPY0)~)-Zic)Ns z-dtMR>vwm{0rQfjswoPn2;TPyYW<#mS4hLk8dXN_`4bhH9QW~KKMo4qte%$afZO)@ zpw}Yp%e1(ys26FNXYz}Mf!iB6b~c(aaUgGM<9sq)1$tP zZH5{BQSx(j=p0)cN2CzwxmEV={#D=KrN-yoY)%`p8vj{0+Y)Cwkr#+P|7ZF~^VGuI zo4<;bFva@HTrRw!(F#8hBJmMJ?g0QN`CO`Y#;ohykqOeIbfSic&rffxJ+b{$uwG|T z_NiPRd?E-djFC;VSAv3rcf55|**b0bOsY_!wW+OxMkF20X_MYI3^0O}_L}nI_rRGt z-+GqcVp|j|raPdf=hKy!;ibD`_Y>yq!^6r$sPiVk+e??0MKTrMn-%Qhhx+;qO4|L6 z32Bh{^!2eiuJuknfs|OQ`@0y%J%=>Nv;B3@bg?eZ0`?}N?a4o}QB$|Y?^fcR;8WvJ zH&KI0*Z;ZWdE*vaJ99YMfeST6HVb&{Yu88Xz2RTLE;%f_7q6P4$_RXVDn9%YGc^ji z>~CM`nHy|b&q9cQc&x?#3UI2(Q9zihd@@G*s7P)-Q?N4K+QG8A--~e=G$Xb1~NV^zXo*X?!SXWss=bocMv=ia- zGXKFT60KUB>GbT>3?zPNU{wmLx_3Gr`>^Mmy(l4r_-G6^E&WAC^`8KHOm8kq0I=5w zx`hW7H?{x|dj%pg@LGkD%=1PGa^O_iuk4!X`Z#b*Y$6h5S^HvdL~P|I5rCKJuLxt? zKN&u@b=t}$x?z{jj&GCU$8YkT;F7#Vc~VhPJ0NAbQD7iAh@k-lXWSRf928cG8WKe8 zx%tEBZvc#GVLy|G#vfu0O?JmNK?iuB%brr)FKT;sl9@#>p`Rn{-jrttylB0vd%GK> z>}n0g%9_MnRu36CV$D?w@$2d#j)mG=r!pDH)aJv*U9TG=fKh;k3V?%IEd@B5?63c} z1GY4zY{`HTArvGRvrtH2yU*C!XrdfrJC_GQ^vPUV&gZs+m*L5k0KO5K!>iykd+Axa z8_{dXqGz+|6A3355(ePU58*MeoBP-;zN2NywBc;S0~prutm?mP^p0iL!})nppU7gy z##A-t;eC^wFZM3Ad^uz^T3i3d`+0GAC6Q~^0PYQs!#)FaV^CtJ6Yk=H>Z`JG4aMs8AvOT~MKe=o2>?B{ei0D~{ z*IS5Fxr{6WZ6Cy}`RbOK?Acg+)T+Zl0o-881NGI<4FL}*1yNYqN$rGR7ELIz&>K}o zO~`D~LfhXMYh6Sxux}t-5M>jSIXASbtf;9t18DC)#w%pN8p{}+ck!ZI8lkmpOyl!P z)^HG?0PdW_vhpvhBCW=BRmNlpqIJL_ISd326&|{ET_w9f?G!2m21OrGf>`pYY%h@c zygfLp@JrvZ#^iV`pAy`xZ`>a^o5<@$r(?4j%`5*#r_M!*s(`IRFuBF+z}aA*I^!}? z@MTzA7*F;$7mK(jU;h4Zo#yLz=EmKYC0ia_KGOP&?lFFDN89&q=0m%WA4gogj>waz zddQ#3o8g_jS&l}`Wj(j2rfa<8k6YH-yge9vj|L06Fjlh_W%s?MZ)=1DHI+&df~hP~ zpFblfoh|{enhk9%fFz{3a;abaaVMD-8_MPTSXluj2=4<|Xn#9{(e2?3-u>w~nbm%S zvdo?K2JOy;u1}{&1iJTGQ5`3{kg5Bgj&C9CRo$XH=F!)H&V9&jakKZnIah}4? zWuI_1_*2iWU$fqk7Al3A0S$6?gB8P#pM1tjN=o-nzF|5p{|W-|ANlLyLmFg1HUf!ge*$%2ll<(N|#qD6rF!pR5~kv>HKt+ zIo*5Zy5Rj2rkg9n25sd=ZVT*8g5iYhCjEe6CUP3^2@4B1{}ysf<7Q2%+FFrjW;;JC zvz#msz-^HS-1~raH5-)5#^*Nk?IOs&1}kFCar+wwlMdW)NB=D6r9V}8*}l7c^$@D) z8P}G2-r&Tplu8l=+;JPO&i~|%;gV& zK9i!tL?&-+!ezU))`C=Du!YHX@PZT$1XfyN86IdEX% zuyAGvgFkp?(;!k46v^;X+OHj6KNkFr3HH=bpaaG@c?9+tA3!S%v08jirt(tebnu3v z{l)9fO1Pn=g>?*29!g_mJjwEu!*H5d@UxQP0eFWP@NbA`M`60}zr1+k^FoDl%4wqk zDF?6&*)E~^)r^+1gG96E>~#==w^^ZrCw1s7t5@K**4r9prPtFdF< z32K`O#*^@_ok(+=gtW#Njk*GW3djLT6kKglQp86R5%|31qiH;D(cmfGzc?Mpk|J{z zeYASDyI6Fw0vFl8_hpP_VL+g=w4BD&XMy@;FQ2AW&iiEjXP*H`mivL108=5NUnQue zAvo0rsu=}sa2gIcjKHhR77kx|b-k_`-`U^*cC&#}VK0El`(DR0YL@QgWh~qIxRghj z7v7s5BqNZ25qZ&0i0ZYRpPpR} z88oM0qIh%YFA7W~hqc*1e=M_RK+-=y1wvl^Ab6c-Ob&k6jEp)^bu$Z_v ztCYg_KxuK%odz5iX`mrR0`wv;zR=^k!f9kZGW>Vl3~yy0Due;&Z%6VvMRyjX(UsCmU+CzO+l zlWNm*@vh4&BZc1cP7C4$-3%-t=bb4V;Wu2-F)_?RjI<7snKw?_=DS&is5o=}oB^-K zC=zT3ABJSnG$+5P4)tI{%0t!#DL80WA52c4xwL>6xxwMfwYu?NA6PAht$zM?Uf6eN zdbaP#w2-gZ91NW9DD)cyQBhHET4!H@GUW*7a%V+pPs(2Q>Ceo}DBuM^%qQ$GC6;3h zpT?QS4KgFs)5E)rAF;4N2K(Xsu!_d&Vj9NR_6#3X$p$GLs-7o|AS!;UfCv3>OM}?)JosfhcrL5pp>*qO`#j1jjP|hW7HNJ4-<_cuM{pht$nZYmlxQe1 z)Eu2<`cz+jF_Ehx?X81&3#b7M0oCgr37yP`K~s~sP{m;|Ts*NhQAPe5%%5PYGdE!z z_pzOXXA2i6a5g%TX0ZHsy%9Yi@Jo(-zLs2gX*dXB`9gd~6k={U^7*=o3V@xb9$OC< zyVE*U-l70XTzWN>x6cD4Sv{b@P-@UfUcS{8&c;Q)24qMb&EMPK$Y4*Fflm4aeZ7iK1qEbMxFd~0Hp#@4 z4sq=s9c=s$N%A_{z64Awh1xSGJxzseBXPJeNQ@J(Q&H`_Llcs3>Pz^(g5a%C&A{s|MRk}#;S!|-h1JY zg{rNgC!0|aZw;Hq66^x}1yV0;Z$a;4yxngklfoLaGvC2#f5-xpHZqm2s1iOW^ShAE zo%!t<>(ZV~24BrrPn`m>kcCtpr{H0Uu$C2r`S=u@?slzdBjxeW<*hpEZe|+us|qUC zH93U98E6U1cnT^u*lp*a$oZOGa5d0>YYr;0v$nhs=|b|Ws*L%nMRa@!vWNmyssRdx zrnd?G4u~R5@#aS4%;E+&5FSUK=a;qRsLwB*?|Q5$Y$CFl5iHTodQ3)>rvaIUs^(-K zb5Ytx>afcm^Pk?z=sZhRuOkf^m0AB?X*N=NsUUaWLl<_-ja6sdl6qFGh_N4F#}+xO z&a`{@Xwhw6L1oj;DIesOWaPaOK{0vyY$@*;^wOad%QiQU+LzZ|3`@3}%vp5Zw-9@E zWI9#MIFQ@(XIr=j_H~`NINtHVV=)4*d5fo90C_*N#P;nDTfuJIqW0dy$ z_Vl8`D~WCW5iDph#p?=1ygtREu$Cc{AIgquHx;Wetm)_2bVs;nKT*TYai(l93-xha zz9ioKp=zl}&QGq7c$X}1GV_q$-LLf(hpBsZ_eb_x&a~U(j{}8Gw)>VDtd$EVKOQaj z9<4G+Wlny$F+{IfnmZg29?mnl+SK=h3XA>!Li%$PYWTLk4R3~|<`?T9H3NAevAG2W zFdc};P6&bY)9B>bcaO5SuyX%ll$8LaN3@BGieBYQb0oWU!3atzE`7?Lo1`L@kh%JV z1YoO~w|8^}qnE-~^C9B^1JR(qsv27GeW@ZYftGA=qc7GqLMcp*{WIk~&gNM~#hXk0 z1InB~)>PTQ{^6i0kao&vs+zH@*)vXv&vM&+9HE7*7Fd2_D>L;7g3-khIPk_de(&{ORzRWR`N`%%8| zreOZeJffoF)qvD)vdB^7Ek`Me19~jGfYZH$DHNoG`1TdX1EJqu{;c0r2p2+~i4Z(i zcxj5?@f$2Ml$n}u$}7ZnGTAiqbaXWc#zru-0{7*}YOv&k_I<-_v~zE7|F;1O4W3tx z^)mFWm1Vi#K0iO)&ot7r@P1aI-@GV)i+p zckk$zzP~mwiv9a-c>~$*{LRPck|i|2E`7lAYYnD(4JuwkE&{WO zwQT>m!`qMl!jv<$Iqv*R9b1XS07r6j*aU2{(RpyU_xAt$>5icfho%PQ-w#^eb(QJ` z!*~>;Cu;Y+YDAG*@346=XMomJqo?>kBVTi14yF}j_u4ra@6$bX?)n1H$z{AqF# z1qDfuTK*9$?czR?MW7DslOi6vn8MQmHobo?y46w~vWUa8ibD&%ZP#KBpj3=+!A7cr zu?y)@@Fb}v<(kpdmTRHY*YV!XdgmDYP)GmYbx_GOGxB(fVub!feEq8};fw$N5+MGg z#YgQqyQ=^F{hdWdC_cR?zRJK00WuhR{x=t(XustL2yhAWz=4)8w1{ZnJ7d6-6!b}* zFlO}XYhT~Dk4tvw{98{ng*2MFq z?Rs}V&Od2?ECrATKAI2mK*GCq1g4*^-fs$>d#Jl=U5lrtW-f(Qxia*KwL5%(_TE31 zshtsTn%te4HBr@1O>YG1Aa)~%v|q)p3wP;J)8O2;>t7F;y{P}lx7Fs_IMk{ks45Ed zd}e_TD%zMRZh-(OtEW5BWW}OX?f+gJyL7AmLk_R4jZbHOtu&xR2Q9>Qnp!tfxeD}$w{a8^NibR;*3OG4ejVis*w`Lj&BP7s=Bf3hTaJGYf-VBU-sce;6PF-yiV{Up-8N|LUEbrc{snZ> zw{uAupph+qIsGtNNfCBxorPmuCINccPxA$!6e6iuOz?}8Bq^?`F8<_lls~=+23A51bYp;CXFA?`KrKW`|C~ zYwr)&;P+?Cq}kdmB|KEYRIF3C47WD3%%g`4=)Ecc3bghawBA44e zhZQa%h{*WdH@RiBd~eBpwA%`q8%15!?>h)x_?is}>Ho4Q@y&(g6ChECdM#Q(ON44} zIc$bPfkasfnG(QuZAw(I`8OoDO&@*=e7u2NpQd+aKGBgH_ zFQLfAfu{q{rQ{aUAaSYZ5ias~2Q#?%@wn|MtA-LiaoNaHLE?8N9YMoYvN$_h0k9`{ zj{l=4T5tf38HjLSKhP>A3A)_@mE9-3#y21cbYJW_ceGYbGLBybHB+g{rtT!!8CZcf zbRIb}A;F0vzm>dEN+JY=>x`%cU4!Fqu}{xJ1zBz!MBCeYU7S6}Hy-j*HJ<>LtNkyn z%%v-tbEMpgn25kgPw3Cea`ATTh|b z0g}NrBAAJnwvLvywi>Vy<%2&!x?4~`c=7r3XYB*k z$B!T1`LhX$#WXa);dRjV@V#tB`Iyq!JAQC}x8EWLeh@4oqW=)2Ba=tKJOK5?ojZ3* zj}JkI3a{ei9>6VNmm;PB<_63l?)gq%f(VDH?t$~FcwRWE{X7)~>zj95*EYHE#I~)G z{nfxZA60|=%<_QHT}OC>fq(+Q3E*($zCG#WRIMK9RE1SVBH*$P0o`u83HR_IHqXAv zkSnF_XZsj%Ru8xHGM>vk7tI@pN{kgXH#av){-!OT&W8^lSd4x< zI*xuRyaWdq(i}~X51R`w(BDzJzi)x4*!1FJE5s00Bcus77s1?)^zO41t|CMRq-Zg< z)|&LBWvdoxqR~iwOAGP!vjn5E%@fekq0FUT*s_3&2zm)INfWyt#(T3Q9fzrlKhKCb zKFX_`nugB#i37pHuX3&bUN@85cAZccY4!?QqCs4~$1s)Os; zzJ7@d6IVQ{ozTh_zkN@I@HK(1`zWz5KnqMvlXa&7s=8y~^F8lMlPhl;d%j*yGIUdJ3txw5UmR8Si(PU^_AgRfBm zN059vtuL1IU@ppG;eOYY=*^`|sR9mMCdZ@2Dps16GmCoO(;&^~A;rOG&=ds?`?c#> z?UkPn1d@CtBqRWA^uIhgq=b-5pl4=G=9~q#8L!6zwkZ*;#IxF#mgz@wPcp(VXMl53q1viq6i{On*Vq~ra3cS>$ldi-0E2z%CC z>*av`su?WP>pQ9-nJ&ZU2<#xk2c};h?cC#?Spo5y9>iQ&s*=UrxjWk6<&jUW1d3!O z!sK=yc*tiiFW;m0uNFZuD9Op`r@RlYurGFg(=Y12tlcb&;rNBOk?Y?6N^xe=l%Pf6Ebd;RXfmj3e z`2gIxZV#$~PHx;D*~L54wdZna^NQ7*`u%q4&XmST<^|@jhHUmgKmw>>FSSEAy5!@> zcEC)-6ZAYtFVKAGR6jn2^`jm+R%!JkUn$RZevg}l2zz|$Oc03H5q*Ye=A^uYIjcN7h|MS|Cc9l7t9+$)mqVqCrEUGF(XqlhCArye$fN3?VsJw}B zFK47u1NAWZ5@#0r-kKqz98SLgs^xS^<3+CIYzt4S9KP2P6{EG;;}ZxGDZT}j{WR4X zEUr1i#R3x<#>b&au)q`jDr_}~5DZ?s0t*it6bR5%#rlp}BjVt{%FjQl-@}I6 z(r^a+A6TJ`hB$>ZKkX|2YbZpZ7eH0HV&1KP+m>5dbHzvhOXD>x_gS68 zQ-euKffnrF2LL(cfBzjQRo*cK?*{)1Fv)5v_G{1aoF%xp$=m<8_w%QzSf4=m;e z1eb)@8P9JtbW~p~ucMw=dVm8@EK1Fdk-Y>BM)%dJgvv!EVlSUQHA{ETkwTTd3Q|wd z;Iy(rfvZ3LXZqRruX=Q-H*-kCZ(X2>xz3hB?^X9!4o{8}oOyCY{#MF=Yy74-yS1k4 z*4C50znxZQW>jTcM-*Gg`p7&@25 z`2MzlYQD|p%{><_Yxp$nxjhTs?O6dg&_)mz1bUwPgkC2HJ(Z~$jY6vA8HGCt#X6kY z(Z8yy-+Q+3+fAHn5G=rOX3pzzunx@V7ZhyK;6#Di)MG^&Oa-{@DdmNZ@W49pI3f#C z-coV#pCbp8Ii7};RW9qv7H+Zw)+3v7wf#7MQ*MSE zXImrKSBh8x+GH`_O#!h1-`R;^OE`GE3kV=S|DZ>r2&^ERyN_Ob(6Hfow(fFzbRZ{q zw&nnb&_8yEvZ>M>q-pgm_LM3Gs`IlN6_AWK2UT4@lrB9H_q)SMpGZAvvIss^rWD0T zEyA~`svr^;niWxKR`$GAv&Eg#$yxa=etM78I1oS|w4iOt04>(?!ASP6j|yk{58In9 zwlB`AqcePT#6aT>UD?d`rL(e8OK4Dn)pW_lO40>Js%ew|HWzDO&n7mn{23m!fY=5Z zQ`2jpP5}$HzJoqNROY}>lE_(p3Ua@jTU~f&p@Dd+25Zs^5r+3D|j?w zAxfq<0tkTT`hrHYc_M8_m4?&&`5Sx}7hkHU`tP;~SlV?DSO* zPoA`Pjylvh9iz_yF5^sXXFh<&{UCT z7nn*Y6b^ED777+kS_M%`b|$mqVtPCg*_?R9#ugmmaqz)3>Y?S)E8>gO6XxsN*YS4g z;H3QQoSf!=MAWi+wd3u~BhmhxFlxazmUkkdBPl8Q3Z*CG^}xyQd;aG1h>&-NoutUo z>dffG`SO*^G`b9nb)7?#ijb*jc!Ve|VGhT^;o;?7ObmQbkDUuV20yDMovo4t95Cori`!$xqbJ8#rTVJzt_t6}I-T^hyc2lbAe}TQL{dpUe8?7^ z&u+|C>Z8}5K;H^>DlB&G%Eq!8!CvuwqPQgdO(6g2{&_oNI*FN_zCjC8!*ASYUvWSK z@;B>!?9ht^dKkzMvaPX$okOV0dl9tMM%y=b2I75rYVyEWZLLSYq0Zuh6HQrWw2G@; zZ5vh6cs~Sz5Ri^%G}-&@w7aq`G*mS8{HWaM2m}f+d>*zLFV#$c_w)HecS_G6;VZOC zwH%G7wP}scYabMTV4&e`Ge_skfF0|HsaAvnT^x$c5)hKW=Dhp7;}lrZ?Av1{sEggx z=*;5Kt=-~tb`K3^G%YlZiW zB>^uF;&}JH%Ic7OD%_UmAjJ?;23&6JN> zgCu3-xpH!IqvPY>hJ-kTcaZQoCPq^QD}f^?9v1rE3dZclLJQPhQAWIHqM-~OKqL2_ zbgR1^P+$L|aIk*rNT6G<8tl#}%Pq}6ak=HOmNU#QEj_*MBV;{(jdlJ}2OguQzy6yy zKg(s7GZi62>(0G<0q`-E4g_gatM5WWZkSglgVzI0mR=cZi03HYA-gRpYDh^3V2Q-g z@}KuVV(CoT=4u=rd<+d9mhbAXmX;QbI4P8;GwMac@cX81 zodhF*>6sZ{h7JzbLc#a%UqQN}-N`dQFLP~eZPTF-*D-NP%RdxpOza9o zFRxC59*7%BrfWe%a-g8@gU7(W*4HQs2VI$9Ub?NY2H@rP?86G;?** z`WMT=*~38Q!PG8}Fb#)=a_2qsbMW73bk`#AU(AZEa{2OhK6_!_*|L74DNS0K zCFYa!%x!oR$eP6s{6Jg$n2)Q~!OT$x`-q>Pt*a-Y$8YK55_Sn#W{65im}m}to4ll@ zrInR!P+Czbmfe@BV8L)?%0UE8VONJV&&U%)%?QmR3QnrH&m5#cr07h3!aRodET1;t z^HB1-2L&rE zcrR%10OnV zlm_}iAe{O1{FK)^FqGB!(;mj&6w0wGsbV1#fHB*&-;OK2-&S0X1j18?Y&QSAM)+On zs;}p9o4L9=T$H1Gb}V0sBkX$H`mKNF3pzNFHo?sWSxU()+v)E~x>e3hu1fD(avogs zeQ>QuG@4Qh6W#95A7S9qTRIVP6R62$2&61mZf#uy>PNDbhMJn%_eT#IeW)Kl2A`17 zltR?7Q=T+0OdRq=ufX7}rDvFX%(F`0U9wA?PTC7^Q)LTqS`nz%#g0*DQxk&Xg zz5_SDW5qp#!09dS^{dlH96QL{+6emq*(sZE!#zDa$6>3(%OmdvpjsMDuknltvM%#| z89zMH-h_IMmsQdyS9{a%=E;@0uWN2hHOeQ;wSx2`5fX<$c&ePQ9dv_$$rdO=u)NhB ztWm(4i#6X4=bft?n_Cb4NH=65HBZ#N2kCIR@fn5`9<%kvdD2;G8f(!}L?@E9a^6rQ zSNQDslV(LcU=4;E02I6hUg3idHcTASa*jJ`si~2a=+PokMV}xybzyh3V!Y0WTqB;> zeeFK(_a9Mhy39e6LDkjOf0mZs!3wb7nvpbfCFz+&xGf-Sa9Ak~Q@*fz&-G-GZ;AwL zG0imtNfMG@zngO0A;NEImQG+at0=Aj+5sd&r^7J-8;F8}J19c_X}l4zWKeggoZ&8b zlYjdW_)VMHq&uC8g8>_O(s0A+;;;fl%4>^!j-2YK-j3&n-nk22iI#*_))NomL>kYJ zWA;{u`aYNqTpX|K+)8ij?RguMnkv(C;Y3YGhXp#zYwnJlasYe#1$rhkhE+Peshpj0 zqTJBN@*T}?@RPlDRrqI;&GdIqPHTpghKuwlgO;q})$N^~tZ!O-Wfc`aCMVM={4mO# zf4DDnXUKo^MJE*8RU#oFks*AZdjU_m@!kp~n6LvY?@m{CGtSa5fn+qpBNk&m6O-pD zlcVgbyb~Pm+2BQHHM&0_?_NKqT|DRQ@M0t$es?H0?-UmaUw0a`pip0l@d&|rJ{%ma|nc|cN53m7ph%xl! zm^dpdi$?RqwP%>PBGHt!o?C*ba&A+=!_LJePcZ;%;kG*!ypHO%`sj9Lb|a>hzX}xm zK*6T&WpnB=rTdGBlgj=`uHSO6Evb1g1<%-j+Tzbz>ddI5L={mRG*=l}XKUB~DaJ_^&O|G>^ ziz~Y4QO4jAlya*S+@>QRS#dl4?xWVL?;&g!8~nk?Cj<4P$VR_|^(IMdQvPei#3_sE z2ifD*gx~Ad`4-x0(We_r?VGV$d``mVH_P-qznzeKCR)|}ipBH(T|R0)?D5(Y{YDwG zWQt~HF+yt3@Zbo`{bb9@|H8QKWhl!}#aN22`$jTR24VMSZ}QO!2R!6$GnFapBUXAE zmm3|*2NUE0X^b>ov+S5zBR@rh-VO`|g+?}aE}k~mCn1M;Dzxv1H66a;Fu74tZgIYcY3*eWyO5^{o7?>7+1~-&WxF{v z>M!QlXk&d3*?EkO%ZR$M%)y#Px2Ftf>!T*;EdCa_?At1o|1OyC)~@KH3+glf{+Uh+ z`fv9_{dlWW_lRbN);b;G^e*XJ$ z>7(>po&PpN->rh6u&_sS`;5Q1xJFE^6li1)IG~n_rrcIK^|bQ7{DG4Cy|ip|qwOn* ztUgciTe)|iT$FOe^jp|DlRT|BMpC0f2*&rFO|ph-RmqdTSwc@ zRofkZQ*A5}KH8EisH5{A{;^)?@=?2zs98F;se4kezrSTyJrSp_h6V-eCppTZgLWL8sk9 zvmFGSer-L&TyPKfN;TU{c8WjC_UM`PJnE{_21AFQs znJ4q*s}ux{7hlpO?>>G}rbrb|@Tb+jV14Uz1 zgeUXEuCCR{K>`B}78@LLr}gjKG1OqW^TpHKka4|(4?(xxz+gvYM2PsdB{DNB)P7)8 zJQcdVyEGX#NUyfFKCA~FK^I&{B!6-1C^fWjB2y73uPFr-1Oc=*>0DCa;o)m2J)04; zIe_v;>5I%VbuqDp64-aBBka+^?c!@|YanDnFLC~!9&-)!PmfT~U>B;jG6plC2pSzE?zc$*@(lwP0I*emE15LzOfBEV870l87 zS$R=0iD|8o1hNUCte4+>A@n1T&8WS1H?1Y!sPS-xcxCWruI|LkFQ=tp5WN@$A@C** zo}OFY)KCIn+8XF-yhVgBo}nwiX!gWsBu)&uIJ30$9L#qMhl^*|z-4;RT?#W!zxV5< zcs4=VdNlF_^5?5AT06txX~5}u!OfG%Wu;jLgI6ZqdeNwdVuyxLg*tAHbBl;T)EQ}& z^;FAXbAa5YQ>K0Z7FuT#H#sIICaS_zR_4$wiud+9iJTgU0aa%9z%n6^={2-x7&n`s zwjTI0T4q52{T1rhdrMic-LF8p`v=P;HZ&-kyLTY`YNc`&K!pBsHwQRH?@z}mkZZK> zyzf6zCt;{e>E*uvLA~rN!%4`IkVeZ(meTn^D^&XloiMH57Y1^tvs=&>q3nM@8xq2R z2E5G_ANY8Sdvf8mGE6kb`&31L{794AlNcaXlxu`E=CItthnmo6;y8@|8g6Sx;R79^ z)7P-XU0V9R?jw`N7UW4rhGsc>d}Vw4y63OGXG&*N*Isqi?v2+w-3Zf^jd>hq*7u3< z!J`gw7zK4rc^phH{drmyQLEUHx~$I#oetRH+Hah?{W8A?VuQtrc*aP|pgNb$a>G$9 z*f_%!^Wp6KVM3fRE-EHAy|5rIBZDm`Cl_Dx=%-XPWh@ptG=LwK>hQ;WF8qLHI zepkvR^$F@=e8%Wm=N`nlLj*ksM`(a_yzOGQPB1zKG;o)Yg49B6 z>#)A;$jw&qI$irdY1eut$)+?e?yoJ3 z8M+j4IByiZ6Sb*YtiRK=o$ILeCA#NF8kFa`GAZ9qc`F#Mya5<1o=Q4_-J*r#`}d79 z$7ZZTBgrWt2&M0OT#f6VJ(oKpN~z#akWya`7>>dy#TY(JyKG? zkP!B0N`av-XHF+Jz{4^WVm6*K#D~%j=HqZf?X`7u0OHAc)_QR0jeHE!*hI#oq7-gg z-7LT^u=Iq4L^dbIic~8cxAnPf&M1ZtuTHxq3tG|P;NXCh=Vbx{0<`h*arIhHbf}_@ z_B#nbsn^g+)A0@?Cs$?0Yw)hJ({>0M^0=H|=Cn}m;gS~-p`eY7gwgvf*kj9Nuq7#g zCB&?}ki&sB&7C{I(nUd8p5t`{()bLS;(O*YDZDpEX_V@W8TU7ZUbZnmd>BnkL7`lz zh<^Qg$z}9I_i^=jW?fOFu`Gyd$l4^^az{GP!q}QE&WQ;jImu78&}iWoEkiPQ0{F>~ zm5&d!q%?$sT{63QlPwtL{CxjNA`!gT;c6K7ow`BIeHltVK93qydL!GnGC^m2V)tN?$G7KlVgnujKvN(^eu5W2D0mE)5Up#gV|fLYhw@GR%T8|DIFh2I=X zt3;#wNqzt9(T^Q1$iWIBVBQ`aVeL%gz4DrKmFodTnZ@uFbhm6a`wa0++Mr^Y=>5n! zx^prmK@RU?OQdiHi%E+k7&QW%g$Hn5uGbhBg9b|m#@;Hs+X_eYotX0G$V%;PyKT=W zc6R`a*6*vYLEQ;ODk;r)0f&7O;3P1l3q`0hYL&aTDMreg!EzH46Y~fJK8ve%voPyq z0WqPdh(6-zO2T{yLD|c0OCoOfCt4b8WY55*bbe&}?s((HYrxyIhF&2AWs#0%d|><) zr1s5s#Jm!FZ8!pci*+vMjpfO^wQ08GJTJJA&@!*^g7(k8RWp`dHf~g-?yf(ksPN-B=jN(qP|Tn=lzI zj&KMC)=ZdPwgjtHKc&9G>`2`~21!IAb$&L0OAucMVAWg1$vFV2WA@|wckYP$ML~t5 z)L=PEl7RC6Ugfra$jBK6l5YD8Z`WeC+)Xvu0=`X7l1X@A{;ss{`d;IZ$Z@W3d|krR(~}LcvAWngWF@q-?jJPT&)-(IUF&v4oM2;|t>=0jnji=g zd0Tj-RFDc7DKI2T2hBkbLIu_m0QA0I-q4I`u~BN8A`cJ|&c?Xeo3jiDgag>~9ITny z8x)dv#7@s3gf1d(6Wo+&G_rUA<`9KWuF+a&d}5r}Zs*sd0Wu!PcUkA>ze=CxUbhgs@-O?)U{8^Qb)pDoBHengc5ioC=rx&_;A2|aD5g!9T$$y5 zR{}bJN=X=3qIO|G!qL7)Ww+A6xWLHQ_XS;C{lMY6j0=Ly#HYJp`N<~QOB)+`MD4dV zA=j^L%&US?W6nKA=MEwCa|^Or2KuIF*3!y!_j3GvKfWj)zZGi`I-3kqMUIFTI1>6tZ|fybM+;OT>AJy|QJ z?Mbrv#WWo1718Y(WwwJ<*Zy*P6)DGB4(q8JKe>`t0F_`$4SJF{uS>!KAicAlg%FLiHwhwf+W@&M{pkbQUK1lssbRa)M@&(3}nbp5(&0y&o_Pvhw+`$VnttC6i~?K=0k zI+thpS|x&KC*GZPjLAqHoGS&_z9W@?juA66mr$o4i=!DZSb}Mqn&_B+px8GBAx@#VbRv67uBV>adawkQ)eeAwfV({ z&{G&IFdUuMU7$5y9AWmcmci}NH_(U41$R$EmjDx6Yg~gIfX&KuD*H!0_nBW;RK!pf ziD!Qs9X)!bOLP-H7rx2W^=d+iw$ax=6!G=Iae_WOciw0K-P2vOQWI6^lrw1Qc392H zYQ(b_jp3!REA;hMi`M*Enei2QU)p)FWxKeW#2)dfad)JAAx#Mz2#QUut?U-v+8<;l z1dM?3m#^1IR%Tb$nJ5qlz?m;3@fn=#^KzH7H9;{G7FZ{d%frvl|1LPVU0DKmQOJ|= z;ln%f^74g7kw%1SY6&t(OG^$)NP8tC3rC^*y|3ck#Qk6phlRba^+g4_9z<( zk85P3^Tr3D(}mvWOcuXM{KqJVei`h!Y4wUz2l+rS3hLfCc}%bGqsT?pc5xtGW~|nH z5jnC)jY~9)(;_&^1y@j%Xb<3|&PAKEl!1pY7c2vcX4TN)?|Txk^ThE@wV~1z%hwIx z&7D|^qNX1Tw3udqE1Nq^Xsqt!=5vNF>GKG5(iYZCD*qvz3F534``sLOdqzL=Z6d9J|M^Lk zK~Egvz6a?Wi#s{eyBkPWqOiAYMjduXJ4W#Qo-0X&lTZMe5t6Bl%|%;UTPrLU- z4Va#cOO2u;4@|E3(r{jv8?^(*_;bZ+HD9%|Acr*(=859j?=#&Vpav**i`_qpH9?u9 zU2C5N(rdIY7w5J#mNqsvp7jWgO81+<>IVphN!xRzaz$gt>kjyA&G*OAqo52hV1$m6 zUaiC)289y2PL7VEHY|{a6Sry)uhl42t>p|3;M!O`b?v=kGZx}tDG}`TsI|;u!_Ia{AOQ>2IEU@nao}8{c z825q|pO2wNJp!=}!#MzNp38Af+`C@q5&_f?G~2DMSHQ!Fq`VF*IAy?PF&vjy7OEw3 zc?W#<3*#DsCyv(+$oXAoyl8oOfr)7Y^a4PcNd)bGv6V>0wWFGLBmonQ6MZ&Dgk@wx zjm~2>dVsTGhCBd`>c-o*@#Zdck6(-DIgeMFFl2?43}x#TxJfDjRxed0!%&H2YcI7i9*$ z$?^<=;twATvG8f$!I)Ss&%oquT_g|zU=02zVSNl9JM9|xI0Hg)C(r2e|A)4>j*7Ak zzlC1|Q4vs4It8R#x)hWa6r@X}yBlUyx{;I|Lb|&_KynD_X6S|ih8kixH}89X-?z>m z=g+g2x?G44Gtb=5eP7q!``R1y6!GAF--yAh#=e+Z1}Ga$Bd@%0v_0N|*9-EUV=eot zEXR%3i|3L>yb}}0EJf5bDLbZmf&#nmKf2f6ez;l=HE}-g(*&BM*I=yk=99=2qxxZ4 zgV3+JKKU~vm!&+E?`&z(pZvzj>DBsR%JM~jlG#MFWbr0&5Cu`s~{QqDJm#zz3!4 zS4|#c`9Q?MkSR`O(31md|JEu?6ncXT;CUar;W$unaU%sZATkl|(I)GR}v=bxH91OpC6T_%Sp0G2wluD=9Jv-JO6Q_V0h6)J^f@xM$U^tQr zAX^{0#r19Z34HNVC!W3-K1nOmszlIabALGkG6hlE0Q{W57HIXZst{u!z&tB}aZGYb zGTP`h6fRRGDTel4WlqhW2Q?3l^`v zi_6Pe7dB8bclls10-WaiWUWA@78`GYdJgdNQ$s;&-Z_GbJMnpe+EBGK3(&IlEhyas zk+xE6eXt17ravO%o*Z^YwGX6d)*3wkU3W-Q64`T>n88oiFeqOr*jmag`bl3|;J#0K zl`iuHDnGH%$JHHY&FQxAdfaC6_kSd-9Axma5>k`3X|syP`IptzB@GW(bV5#JsT0MM zZ|4`H6J%tgHbA&o^%aMsw+U?GDzmsRrR5)h&5~14Fj_-8)#8jnyZje`c!X@aauO0R zs(>FK(1pbn`$SZTo3b{68Wk}Z@l8?;OEVix`GAZpnlA4bHM^*(UqdO4mj^`@(;x4>*s+w!V-C)w+*lC)6jII0H{x=9Rzne6;wkuJxcA zDrZHxWcmxb&_|D48z)ROzb7MP*K7kemVeDg0ivc+A0{95C+*uEFt^SGydMc}y$ey! z)Z!ggDuaTs$O?yJi@mv)2)V2bjnCAg4X!*LbEQvEgzQF>frCJqlLMesauKIViyDou zz`~=<5 z8vwY8+cebcVV3mhTrNWr!7l<;`ReWC1L0!c7g`ide3=|wVXLSgv}~@G7r<4C;m&!5 zeY=OnXko1RSL!!s9JLJ%Dpgv%csq!}mg`H&T_NYQQy5f6PA0Cn&PO`oJo+%@g39+QOmtat<}xbzbkeeU+`sZw%aw~hu#9?W zrr&FNshah7n(3LAsFZe=mdl4UyH95Hrdd*p*)c}^ntA)gyO5@fEeXvhLB1OUh@_clEb{LqKRzb7!(D1nh~2Q#q29O{M!% zk;VxS*rTP9H$IG7f3AlfaNozpHC&mr_o{I^$Rr}9G#?(_1T$LHUBXH3#simFH^^{? z=13#nYL)Bq+Iy`k=%59^=^MA_x^-R&(F|1cS0x|HUfjAhCH`6Vz3gHa8`%NNjwLUZ z5(kwF=9ui=2WJ%=)uD($q|aSdX4T&1+<9_)lKMQHwgUE24X)dF-qUIk zvFOcOv_GZhJL#WCzN^sy>?zHl^Lc5(*u+GMUV>#kxT)N>i!Y2w8gZU~=}!Ar2bl}n z|59l-&RQb*4>f4jO$JgW6BPprLT~`Jk@ouAr8~tqS*x05d%vZ+9m-BR?^%3O+jhDR z`q1s-YytE-&dqO1*4M^ZCMQMa)x(>@{|vF;H?cLFI8#^iIkz23!)SkLXnHwbR6ZZ* zHF~l;Ud1w3Z({RPtY7S7>E}0UteUJRITH$CWFuEQM=^Wi4`I;J)c{k(wEBY+5T`CdPAxH%T*7i09~6DEnsYY`Gao0Iz=|^`5y`X z=5Z>{zb!}3g&yVqeCf5<^PvAtasy(VJWx3P`{$RyL-)U{aTKX9d{G5-b*qBM^YEM7 ze)G#s_C^5pKmV(Zhrsp!Z-ULqBAcg$h9evMb9WkYMu0^j!~Hin05JumpqD?fe8=dVaOHi^@ET==7d=ighf zUwGtkhcV{agZp%XOh114o;Bjhf*+8j{O-r^*X*#CuX;JsS;}k9G91bO|Gjwct{8{*4DS;eh26*f~}73q~g(|vjyH;$WvR@4`Sr#dL9 z@0&ysv#H%Y;-B(0z5&$T*kgBT72cO98sKl+bUdA$30t|X6UE)a|D5r|*Ro706YV`P zDYY7nxnla*c*fJkps9%@$cm?v*UC(8;;J-UXP1k|%TUgGxHDM>?50RH*68W!xl9K{ zfD7Msi@>-4(E@yHXu!rLYc}oyj2Nf=5@=v+fvst#M%kC6?NctShb!2hhkxZw&dk^& z=e1)bGUv95L^pLYQ86e)8%;FgfESz23@tFh6| z)2a%l7YAoLuseSM2!y|Bw}8Z!TSarcXy!N2><5K}n9f9q4`oX8_r`OWR_Pfjgvn=G ztqi0H_oXy^1)y~9CpnNMC|9BJIEV2)2N&^=wXT?gVYflRd0YU(?nNN)p< zkpftH$$=2-8-H^>JuLJkYH#J_>6;)s}=l|=2GIfh-wfkw?4U~-Tzc7&6>}uO~*z?f2dDcugu1(*74Wxua zHvPBM#XbuQkgx$JnTZOr4=NGDclU0XWxz9m2*20qk+~m>geZh7YhH~5ML8T8H9x?| z?<)BGrrzu97WnqtH*v-Q;i%2(^<_QZ{EA_`x?;bPxh5 zBS?QW1NPhuim7xU>SqC%vl%ou5P^RHsWG+Q>v(cmQF6~&{;vAq1I^w)M--fqHDr81 z#B2D6fsWJiywYm>rZwH>v!W9d3kUE<(w@V?ev|q2H=oP1k^fN>TsvO`e#gS$KB`y* zdjyv$#%pJ1CqcwOL>oHUnd*H3#Jax$jysQ>4FXm8KbIgl56ptxXy)Pd2;^|AA8HLG z5Simq2!2=2yTM3fSU)Cu+u_irl{cc)d6_Rc^`gW24wQEi^4L!T*zv&=crEb|kc(L3 zer$Y7leNCQ+Pb!x_Xew8|HN`RYCJ`r-c zkC)r}d8O%8=tKS|*`;LyVsXd|1hgd<&_5>f@u_@Gcve%nLhHjtZ$F zx4`4J*0240I19dsXen8>PcK~M^M>X<$^5tm#@f7&#{|H0@^hIFI@YgW8aPw4x4(PF z!K9IvwtD<8txqZs7Co`(Im&9&h?@%EHkiMFpp<&0(`k(;`sa-Tc=h1d$mUNlzX3uB zZs=|J_I5vRR}Voas-H;T4zq*>IY*mD8o!`@@e^cY@6J@30P?a?wS-b7TalKFrZtB0 z%=8*EZ;43tb6lsEeX8$;em?K_@P?rTV6w^T)|g;t%)ip_Wq6t4*_S>uKo|l>k>NF; zv!)fWM?itxyf%J)Ma?l= zW7n&d(U=s?S1$-|NFwV9Au&y_#(^X-M6uS;s zTIPmE17Yur3$2oIms_KGeho>M)egUu0B79RF-2mO;NiTzu(j0&u2#gJq{mS{6bQJR z-WWWIyblXYJAWEL`A<6-m)jy*p zM13$}%+kuH%4o4B!Gm1YOrdunXLmkiYNO^1bTdSt(t;wiOw>#r7rX#MT zw6eg}NvUZ;=myUZe%`yR+l_;i(EF#hUSOoKM;Jg4rrDEZ{1(1a)>q}*`$M!~AVe1J zV0;T~tW3~LbWWWo^UiEl(v5iGsV9)h9KcIv011fK?1z(dQ7#r*p%%6k*SI}e+@sWj zX)Ds^XVT2@Wl}0{Sy^ya$$ z#$-ALkd6R%z2(h>!KeWz?1M$!hGQ~5`~3x)sA!e{rYL}wp1qUPUCqv^DZvq;lw|Ut z(9mC?_Fr?Uw@QFsx87mbt5=9frP7X@*c`TVcI0KFh1VMOa1=Coo*tk$W`e@Q-=u$d zOh6!MrBFEbD$b@%ik6G3%&W%Xc|5zW6o~Mg*anzhud!~nf7+1QN^fjIp?1p;z>&R) zlU0z*&};e(wxV*Y`ii`5)&|Y+x{{UPOs38)#jY*@9_94-%aPV$^ zKu$#rwMaM<;WXk>6is*{qO(6a?VrMc;%$X#goMxPKCoP+6%qNKP+H9EsT@I|T{C70ht99f!A22;r~x2Q zou40WX|rboByhk@At*S!vwx0lq;7Vu-KV>o@sSi5XuDBJp_!{l0jvl|SX7aM+So#i z)S^mAMd4niIVTYyeU06LSTrNUkdrtJoONZ8cBx{WCjZu14Lc_XFX9k|wU!D%eZ7Q9 zH!Gk-MMM+^NlC+erQd>m@f}baStr1v66HQQy_%n&r%tM8&dxzV7pTD^BH}9JVx+_3 zDk}q51uu`Qmz&$6TI12$QMTzt`5;s$+gYS>IaU!g+=DF_Lz_-co9E&q<@fG@1LCH% z9)6QmT2)0a#7yexSTp={!%SWb$iWu>1VwvYtqOpu;AUV3E-k7MM(#L!ikzz{oJ z8ym#%6a_yzjFP{eOT56REHxWaZbqNu0RPNe#3Cyd$=LHh zsPHx_EXGK!Uh#pLZ4xpvGCWG5zH{6p2Z~Z@J_K7bx3dt^*-B|{K?v}daqQRZ?G!vD zO!9rj>;phf#Wh0lx4T;gh=w!OfLrJ9by|O5;2Uq90=7V*6m}H|n8x|syv+ocigYN> zoOt)eiyTzrs})aZf4(xfE!s~d6H3Yx_W~mJr>oOQJ{l8R*lPB+*Q1c6Z&0@-yJ#T3 z1yo$uTv-wcbp?^2!--@7e03WLh9eep%B^cyY-P9UZ|e{Z^x)wUMeI3c0xW#H+@F z7eJYB45+C7kqRdXv4X%xrYAw;!L|v+ZQNNkf6$f4Ad+Dd^1tg~CJi|1W-GybwT?>< znn7{xvWrOq8nq7JeKSwu-?~L%|O?;e50z-ml!f38qESq-CaETJtkp~4(HdN%{57~ZN<++FP{!8YWAZU7#Pw&7BDSrntSM>F0uAzn=BKM+so}G zGf)sqh*cDZ3$z2K*++_s;j=AJ@rlzvyU@!wuYY7b!+F###?u~9MbaR@H{BHAas2(D zFP>v$>3vdD`%2Hq=6n$j736P_Ur5~H=HDkkW%vENoWsW7Ctynlvzd~!W09ZV6?o|8`5ENS4)eU@sfpkl4n{&IscmFoC zp@>*bu3NBghKX1RWsKf_3g4DPCR)5A-JHrKt1uaCZv|2>25GtY2jweCsbYp=U|92L zcP0dwFhxg3z6NLKgZqrZ%6R~T7;g3^gPbigG@l)k0jZgty*;28DL@YqpjDKuKDeil zB!*L@Cja`Yc~VaN(C}wSKT;>V0g7aw6Wfwo?nExA{*5kesBzGn94_sH%#wvl(fR$^ zc1I`!u;`X-6ep?i%EU1v5de#@$bn1<*s_lo>JKIYIbT1{qeq|nx(D4$46#AU@_YYd zX5_P{H+gmMP$u0^Ydvehj1dI*peCS02vtg7-|~NSepeW~Az;G&DgNN`8mv4PHZ_k= z2krt09py4Qvoj*OVR8H(uKxH2oVm(?K=h_@lFEDuR8tulncS;}y!t$+UX+(5+WaO1 zDFFa{2Lfc!Icf~Yuv7fG0LHRjtIS|T>hJXAhekK9-Z++MHXB%**l4kC$dEq7FFKPJ z^v^&U#_OyfLtUyt4Lm=Lk7_weT}yLZ`V$j|v9Tu%_8PH{_Qb!YDbthuEwQb3JH?>z znX3|if0-hSCxIuFHGpI<$%>|XAL>8Js(GL87qH)h4vUXmo(fe;@{tZro1IxrE-0W9 z`MuW-Qp-aNLU{B;`!7}5Hn$6O%5KN@4=!i7>}gL13}yP8a`+5&14vvej6ZWAMd)vx z3UQ!?MA?e@Jk>zPLR89t;Io21RQ=+b>gsMUaK}A%7NKLyw$ams!pB zF4Aw_J)g6kw#|H~+OXP`!IwWkF=u(5jjU(=#~_$XYW>}WjnAlFe0%7}B7oL!%41a^ z#qXTtXffGrL%UP-$}0h$c30~D`$Ycr@h}z+tEP%|R?tU^0|(&4wsCYmu*P~tFCY6l z>r?qvjre4lA^%9u`?q;s-VG*eRc)A#v)y&;GpZIx5K-m*)qN}iT8YGW{umEIeqq0w?+BN@$qY>+?S>pV3W(` z;Vw4HazB!y-*=qjHlo&MLMdDY{N_A(S>^TNvFh%-g(a)2Gj3O5*J*4=jLdzZdVAek zA#n{I4~N{%Qy?d*rrz_Bz^cWb)33aILsz*in@#)Y$$<9g`0n{vcN(G0$xG$KqG#zczMlnV7nMEzCiVLhbA^12Yht8_6M{V#;PQqVGVmaRHdSqs%MJ@$xF=< z63wa^(?`29EPij+{&UL=tTqmPhqQ%N-09Qb8*MeFduq_WZaJjIvtODXP%pGZt=(|Q z!v{GK{83ma3Xv*n&y*4ReO>zBOIVf@UsraXuIo+_s(ln7Nf&J|c4b5ZW7ql#nf2Xx zN-E9b)A~65gB=yjnX|KdZs$M8(+NfXmsJ&N@vlc^AfIW`yWM37HHGH-91l&REDJqT*?%vkU$fzw z|7i1mlPb9FHy63NkDULPzn3aPfr%sdj==GijQzrlUerfJ@}+8&OO8Y@y}IX$FgqS0 zZ0mkSGg#wt7uUQZzsZV-ExA$ylH{tC{e;+IhzOTt6Qvh%)dah5xbf>(r#Hj4Wa?5+&bKqPxj_m2g6( zL;25y^8|6*Pz?LKi>a~2+eBYk|>jGl_kEmL6 zT9DByfyHto>MI^OWL?ZkG6n zxevU4TB}nbS>}~i$a;Oh*7|->*XN?HABZNu?%%S1?Xuo5y&E~w@q2f$Q0HExf55kr zNcYilL)`425V7;0px~N=*g&W8(z3JT#tPK$yxOk&A;)wNpHjibMzNxXrapCzvgYQg zA0-axIJh4X+CxiN)P+ifrtSplOgxSlLtPDFU9N~{9i4VWi8Y7w>ecM%OElgFD}=9(t`HcIqUIp zL->NTRF6^A(#~UTYv0_wd1LfRvt(dmqHcVMWEUM6`pzDN)q&Rwx5~^<3_Hc7CMv}* z(?#d*SQTdWkiH6>SHHfSf+)LZIIXO{G3eC0FsvmnlJJjV+4w8Zrsphi752*>%6Gyu zUwGcXlVbg6yMUzGnH^1_^iKNF&b0Y={A;8Aih}46%7;L<;eA ztr;BGdfFpU9X3rz7;*qM`A4Jz|Fj?wTdS@f<3`OeT|$c2E%<3$$2A(L24SW|fp21_ zsj@B+l#E%qEG&jImuN4i0d>KhY_jg_VUnUUh7<`?Y-{9qX`USixpV( z$>((R+DlRs1_T)>TAlG*I_It(`KA_M7uaMLRkn2;2a1#oj98>pYUJ0;W?J?ILH}@2Lp5JX-vArHO$jk(kgR3rA*h z*D^$h0_tyD_mht7h?DL?2zkW@yst>Z#m?QnXX9tJG(}I1AXa_cQD>K?{2A)fg2x5% zAND7Y-HK;+4xtAjNrK2m+s8#Ewub=S6z|3vY^m)!wyDLuG*N&JWq40*L-h(nk=nQf->UXE|4c@CXTMapdY!5=!M!5|7q~xZ`Aj zv8%We?S{B$B@y)3t%*y%vZ52Bq6lu!fdB=NO&S|y539`s0c8>XNCjabAQ7Nmc z&gCC#l`arihXJrWBEUhB=>YY9rq^QTs?ceCOXxL3&uSvBllcUjA0dgb6}hw+2f zs9mQMj6y@pkz?8}B8tUq{I(pI!=52IdJdkeyZ-r)X!jTn&qQQ0$!h_sRh5(&e6Oi}lBpuqxc$X|%F~ z?u7M;>Rd`hfnkKOKlptw#5$_@;1CX7?<9kE=6<9l8yAjr*>1Gv@ZA8p3B#yf&yb(Z zpYLQ|5ZX<-cbUv{l;kg`uFo&S8QxQiizjU*YQ4Di{%_7{T^JODf{7gN)9QH6Re=QN zpx$0NO6ZO~XTQ=|LS6ydi_XFDx_EnnPMZ?8qe${?e z1&^5l|FvyJFVuAF)A=c~OBktOyfevl(IC$@Tzh>nB5p2=D5%(8Df)Xjd+l51Rp9xx z2#fyi^${aJK84awXcA)|%RgyL-6e;^*)&BjkX5thBiTG2 zM>3reRD+|g+4j?UIYx2sVPZaj*uWzbx&KwrQEX+?G&QTf-d{ygkZG=`23I{;B!WoK zEohU+OxRSKonCfPiPtU4wVhbE>@OjH3OSSV z@>U(~O!*-7JsvD~hG9{Yh8_NGk0}4#DpBu>?99ta?n|<5>d%C_-TxZuN3i)nT7a!B z3rgq`6Cs;cC<3`&STV40Y3qfX_3VaNOb@vJy$*wZTNVfv_aYa+nBr~NS>Cp7?72V= zX5^Me0^{T*5B7K+2QGq6s?_;-K}UBCI-Ze@jUKcCjst>8jx7#&AREqVCD9VviA9t= z=!tAn0-S!GeZT_QFhe?#{w3M9`_+3du>hpkMaI#E38HH(0&--SpPyg1UF_M@8@%7$ zj=xjYWYcuaPY%5_QWQNl`iGE1v)3>}w6z_7ZZH$-m25rJTen+{SUkNzpHB=d%j*kO zxOXKymZ;=m+ca!EpMODERIuL26TUDKo8-0>tEqDmYnWSDv|hY!!inx4GBU=>%P-C< zFOR$Syr8wI-I#2$p^cS0=#swfey*<5N|KYKf>-h433v^J?DZQnmtae(JsOth$)pc6 zZn`>|5y6}-&w8KEJtF2@_&WXBl+8Sv7l<&8Et#aLoWY$eF&)b20B~5a+l$tlr^w{U ztdQ$Z#>c{{KA1SnFhVe2b0)W-gdtXr>!`F94Cy}PkL{fm$*Qy>i;ayvyMino9L?5< zdCPUf`?0{I=`0W~`6A)Bvo3j;!RKp8!n*kFzjhc_4i1LL_a8q9_$Rk8-{i_athQLb zCPN})h!}V-ebmtSZOWpqqM`8`eC;0#%k49-D-Wp%@>{QaozY*e?pat`eAF6g(tbkU zftQ&AWF;J0E9vs^@FsjuQ&hi(cg9Mjpew{-lL8`-zK3d~z4mE&;BB z_OvoqtPF9Jox_4C#yv#*<=$MbUKMy-8f8m7%*@QS$8q|H@FZx*^Y{s1-Tci7YCc{# z<%AqhQ7ur9mdmc)DMxbIFWvoTulYjE!NGB|(VYiunZ6P<#SJGpM>`2NT_w zpJzllGkbnSdKsXug>$s9@~l^ug?nxzc*iqKOCtf`XxGccfT}_bSVJ6LzodwrR_5(5=Sthw42-&erT*GJyYnBD( z_Lf>9z3Pv)0>{mdQSDen;R`+5&GUuUzm~U-n!A?m*ZMC4Ay*d$p$3a>N@pX{O7>$B zB`YOR_r#v)@a5{6J+Kn^Z0Fm&TcD9tx(9bKhwC|vd-F}Q!lX&;4fev|6Lnaps5xju zLDve_A%4Qh`hfa+p-`^N&7K_Dm(e2V9Pz^t7~;>UIg&5$0=ZY4G&@TU&W9&^^(dEl z==B|7a1g}hp94elfCqg5H7E*KQ4$@9sTiDYhiDOU=(REBr1puP&bBH+55;GlCz?K~ zseK8hA%5hr%PYQ!UQb>1Co5jgipLBrb;xsHfE_fjYxxq>+)#%xo!C>x^d%q<21Z@c zb4W-#Eg0VqK&|DRrZ4tx&xaRCQ@Ve(6X+|dxl9hAyu1>dflI8p@r5x_P)BOwpdDQL%!NC}-;YkJup-C|IH4mA8L9d8wf=3eI0oT4d$L0o zN;O9X{hgkX?_XXnhvD_66u(;g_=uHh+A;yIUI#d>glonDCC5+zz%zR`?y20va7>0G9>)*soK8Y^40{7 z7(Ji3D;o3bgKu43aDO@b@bD0&QDriRXI&i+c@)5{gh%V*GTLrSg%eBJ+t-X=?`i#w zFVs90WNMKt^djrf7m7A=$I>pYPu#mB_j!ucN*7Chjbq{GcClaYL%tGy>Hhk`B-ImP zl^pw(AJW`T8;>92;J6{L@Ljez*j7hJ6xT2aL_0q8%$w3{|B1+;<%W;O+Te9yLGd{i zrPqR3XBb6$#UQ3iR=DIk$$ndNb+;!)C%L+XFsZAcgv#p zxhI=z$KmsvWX;S7q3__``r}dn)4P$RH9h{&1z?pQ0wiZ#n0j1PW};%Z7w z9M35NS%EH!&(&|Btl^V&nH-!npsdh`a`QOUt=DU%Le4eW(euVSN4wWR_4S8 zHt!a~0TcCW^|_bvm1j^O%!s+CzH0j?k0~BFvki8B4uKcu*{iv^{(!gAP{?Agc^5q5 zwBj82g{yxEUaCau{{}N2rJeh&*cIq;{y~OkkA{nKBP(*em>jV{!iKnM{}!(ovZY!6 zH!_D>JfbAok&nuY6UXwA7)(-Alf>BA_>3Z8Q8Hi;A|7V^`Wg~S!u!#w%D zZjf_%8;$0YWoB=YS0zoQo6)8w7s6G}9u1z?^Y|;Z&m{tV+Nuj9xY7gy{9wgdjg5(J zA{}YpuJVdYjQRp0D<PC$*1}umIk;@0TLIa29SjSDc-|=wF+-51en+)O>q; zk7gBE!8%xW^wKb7VrHeIj39{UFi&p(xz{pzbX4Szvlttz3M36VDt2toT#>1Yu~xIi z^o~Qbq%)6yW?u^vhCK=E+|V7y@oQT@1G{iaaBsds3g}R?2Le0>vT(f0KHthN#;eJQ zdathgKFx$>-V-Hbqt(Bo6vw^TN!BfV;MUgJUQqbkx|1&|=q|EFJfx>9OL~`q!j%=N zIFmkT#VYAf9=E9!M!}O1qng!L%QB!piEqJ!U?h*AnYzq(=C5Y8Sqfx0Yn(Lm(rj#> zc5&AmGYJj^Zkt)+7n)B(dCB=VHS|1p#dYl7c$hWWLz2q;4}%|i0F$L(jY~^=#E;6{ zLILWtSBJ#BbUzu_$|z$@|6tZKZKjks<1((H+;g`#Cs4H{qu7F}1p2chm!M?r=TNl9 zs|)=`OwV@m<0M&R5W|wMBQZ~gZvf>ro8-XRs#uL=`z0M32uT40bNtGc&U=mE@-7=H|*yy?f_JOe)PbBEAs@H*G!@yT+W7f%7P% z3gnL^ZY7d}7gnYb+LqDQXBraxkb65WF7AheF2re7HDT8+H5~+v5L=#MvaUNE2V4F) zPt3`lOCmDYl^1zQ!{=-l_-r7QLFKJ1WIzTe6`W`m=@QjwlD2 zEaguVpK>_fB0p=R`3?^qcv@=mJ_X0?V}#Z9(1;bHm6{$~yAi~>H<_RVF^;%q-}&+O z=2!udc8yI|TH04o1&9pN3JWIz&A0vN6M~+8xVg(z?AWHMwTY>zK_Lx?cs!f7JosGh z-oEvS5H>jRO9cF3v@(1k*ubhp7kzdI<4;|-C}LUzLq+vGgS52tc-(4%*3ibkZVz-= z&NUShb=}N?gHam4&zzAMyt1>)WR&sbuQ9nCap|#=Q^))n+wl9gA(G({_!b72 zgHXj*%^VfX={4<+#tSjOiIQuv8ZOU0o!{Ipvl~t@bgki8*L73d8k_dUP$scYzgJ1v zB}9BkBlNpJ-@vp%9mfI#WduJO+|0)_j}Q1ya!BKm1yIw{738Qbfq9B}t<});+wgOI z{mjeoB*85-G>RG4%J!q|ZY<6(7(DPck+{kiDtk3Ia^urEY4;y5uYanzXn$djUGmYa zkj>Hon>zm2qgIkIDa~>tl1!;EGj2NlNZ23{MJ0_k0uFx>3lf=n`nh32XM=W+D*?zC|1UWuZGWXiT?j8{a!5gN^L|F?lGj ztj8&%1XI=Nu7*70vlkp3@$Fzt=sT*VQ$^`I!G5{(!>3Q(E3#eoCsU@o<h>>B@IsuAANfbimA8YDA3g0bT2YC zp5fjmBqV(N(9dmU@xnDh!#0#gTpY%7eQ|j7z;Kh>=6Y@}l$19L_<-zICdGlmH>t8? zoK2eqs8&0P_nJ;2?6nJI$#$1?mE$7EN3gPN^Wcv8=`ygk@_Y09Oqp2cZlS`5{_9l61y%FZ&*ZnzQ|batr;dYnoV z94dCL->dqfDNpVMC+Y4jwE6&e*kEha+$+m~5@Of{6f&)OIjO_@Gs%0Bv+ffVm&o_m z@`{RlUF4n$AzSma+N{-;?>oauI@**7D-7E2$pJm5BeA2SBl>JPLcn3k*NNE*r?)6q zMu|zY+{r!q6b@(E1aa}_b;&_S(cA<zk9+T%Um=rc5?h>!Ic}Bi; zJoIw)rAm(iLees|(a;Xe!@}hf8@^pOscKiS9W& zgR3@q?6#@JFgGSUiBVwrRn+RL+qD}>33G6`z!^6F^g7>s3ZIXgNUO2<*~c|eOE#n; ztQBh=+LYepTC}~_jBiGqHM@vP|4=GR1?+eDMv8?`a!$rtp0I^9s zF}%t3I=o@8G3DmBC$i4x!7~2(+$N8UOtcIXlS>=15dAJ>s@xrCT;rxI86Gb0I~-9G z_A^aI%b$xH=H(ZD!CXenFp6fluXa3rqjv`HYCId&!65V}_F?hqm2F*~CG+nJiyvk^ z)2#D*hASMx?O(y{{xr)^{mVJjCq00o`t;B|QNm%1i2?tQ zH;Qpp)v?bs9Q-AVbuf2hTzW(%JqCB(cFLrAoTr_Z%I=Qe9Gl1f&SvBGSVqGhCu4e77pKe7N`!_YlH5O5 zifXb=rl-NNV#BV@XKg-pox~>aZwq5?E|kpcZ^LnL-{LR5%&X^x?!bj>Cmtu#G z6=-!erC`dYh!W?9lo>^;wieTtUKl}U;G(JA=jVuxnSk3IA$9zS-}y9i0`@ykJZA@h z=3WpK1Do@a{*z|CF+6n_sTb&ZdW5wbr=*8WbFTIifFNGXdJkUR{eH{il--~^vYnfW z2yxcw4#51Dv#}D}9MFeeUWzCRK)6AYhH#q8bjn)w+@|;$?Kmmux_hw@=Xl}EkMH|` zl;f?NCKzC+CKU;iHPvs;#GfCSY>#*=>;ao8vr^Kx^TN}|96rM!W1$WcDK!WBM9`!z zm|N8FFt+EF>vC%nM7_8JAL8q zUZ-<4LKQt?xBMO641Itva&&)cYHDR=h127xyN|14IgIpVrFJ>oV7c@C>=8=;>4N~l ztz6pwj+@J!=IQM|9;M|)X-qfo#N2Ba7ed3XQ1fBE_0)giRMS+CbIoQ<80zN>*O2ED zP9MU|o!FdrT@_bPOc6!{(khw_1_TJf<-48uY*QtN&97GFecKK6JT{H@>ej^o+0&**a5kb_<>Qz#YHXp6z3s|37`Vjy65+VH8nNgW^z?qF?AfEH)e9~?h0(~ zYRW?(>_A^gPpS0yAr_ceQID>l>~!g${mYPIG1KsifsD_(6ZHt(GT-(^e~f=t8YgU{ zv)`-Q0ylg)G9~t%^Ly*;*=BE#3TI0u7Paj4`{#FV1ve07wX`doo6KM_ux;`b?A#B~ zcjcu*IN;FANlXSmV=xjNZ9aQd)^Z)Y7yd^5?NrRVsiu4IgO+;ISc<7_K9fGLh-U8# zPDtD0`+4!@P!;!8*!7pqa^v^sw!#)WK9ecgYs85sKbk!c-ie%V5GZ)M-UFpMV2&UG zm>BcJsitG($tV1w$jzxQ<0j+6*SDQEWkyS%juIWj3V|5DTMR3{(PBm9uw{A*SntR1 zLHRT9@dL}2lLobmR$MwSp=U!vD_`2e5hj*S;dpr>3~4wN#yCZp4Oh0U`6zjQTZ@m! zIupkI_0Gvxu_gN*(>GMKaJ-J99)w*|=}c%jPE-=(X?Zp-Yx=`+(a($9i_xAnbKLvQ z?u;$Zwk=0lqir%oUA((Ay&;>k()8*c-YTM`xh?J19T)ePgE#E-5_Muc19*8RUjp_gR0_KpkBNadMJW>_@r*Hjo+v6rJ$+2 z`*0iFe|2L#Ot%`mfZk|A-_^Mwc4}&8_urn`*x*%L$k2S_Rji(sR*Ojsylnh%ZT9)m z_Q&q-Z$)UCpz5K9YidPLV;&+YJ_k3tX(P>gWNDm=qOcFgc#&AzZcMB-ZPas`f-$PH zYF%Sh-YVzgqivP)nN_e_XviNbf6}n~J)?Enaql4tg=YaXHNC>dGuZ+>oZ0W+YP+Ym zK&;v=)Ls*;wLU!RYX({HSLILtY)4bVo26SK{kJTa>mbc?X+i!xMm8ZvwysycPLb2tvS|IT$b?5R5l-#P z&5kC!_q``LxLhoJ1|jhV`WUhqT9Yg-FW$_NlfRWNxw(Zeh#y7=b|qGYb8W6)vFWI{ z7mD%o*zer2(mS#($6S#zD8dwf{qkLhyz)Cwf5%E0*)zxR2sj)dUC}~TIUy~M8{bWz|{I!nev?;TT)b$wpZ%x z59Q#BaFY4nDoZjT8RN)Ed{Gh?dFXOMQbdt&!Ti8qf^O;HYJPm+lMi?E`$DjYJuo%^fe*OS8 z)ab4tw&-S2&>Pfsf)SU0@nd0Fz8ROX@^+T`@`+&dF`1O3)0^*uCEF|6`RwXT~b^MAzz~F zbJj2tGM9i+zzc;hbJ}12Q6qDn)^2FtpXIq(x&Mb!jvN1jO^_Swz#aUnZ;6SdV5?*x z7f&Dvk7u#NmUsM5@Nh`p{z11jT0XzlK;nVLOtuM(0Y8>!FuA|0D9#V-38S#JSq#7Gt=>qgk%MOAj$~-d=O~0=1&&K= z))g zYB@jkmosO6FY0izM$D)CHyAi>K>4*VoF#QoOTiY*;KRq;l<=bMC^ zJdWsCuYdzg!I7zuwOwB93kLpx&%c#w+9Z~+Bd-yffR!n)cyU*PrgFM{>Xy0iP&4T8 zZeYIF999EqE>-UT$2ULN2s>S1=YQ39?f*>ge>`_{Bt_*iw=Z@!5);cM z4syvDLRw=QYq^YaKavVj(yXviWLDcqwjE>BqC_#iOJQYLx}5fvqfx1&-0FOH!ukFM z-_LKK>+AJ?e_og8`De++O5hKo(gMlH8him<@=zi0=hIoW;@4qR z@{6g5!@N*=Yxa_lU_1TQXlDlbdtigsPQy&HZL7_`=KwjQtwTgt+F92!v+LcvSo(*d z)PMi_vsQS=U(OCM-yc6=^MhSisEsaycDxL1x|i^^o1yu5RsGqly`8ANowxj2q^G~G zot=?vWJYWKrdAcbZ1R0o#Lla@O)hgklfTOdvvBYS$xdBP3FU2xGPaZR7*}a`8JTH& z>mp1OR+)KT#cZ~DkI(Ecd{Wt(VxIT*(ampeWSK-|6-K^a)9m(+Y^nd&=QHchpHaU( z@sBYJ^C}kAd?M{1TcLi%7bT}s^lt~f2^sZV^FWJ%RFiMs!~e60$uQ219!osaU$42% zR3-0X99pJ_cOZ_qI(|&%vTpcf+e^pfNxBOB|cT-%9f8u?6oTTN%2RfGrTBhf0_}&Zss5$D3-9ai3bI+y(`V~bUwlujDSLE|BUn0;(~#@Q zl*Ss}=Mm$Qg#jO$dvl1N^jUVo-UIARBU*XH^cBzE9k+}J#rL+ktlT39&9(DC-Cn+q z`J3`6pR)LksguFXKj)FlABM)heoU(M88HkWurf*~z^z8xg}oyhQg9sy8N4i-tCWss ztW3t9>dtsQrdK!Yd*^zm7);OB&FT#W@APo&+&nFpTil~Jl)jqci?8VV*EpB~XHj(r;y0-Xa|~*{@b~TOGi7qQy&s;= zB6ElgfBoVU>=M+dIB`@^3i1?zSUgCu>oFnES4N+DdYa}Ye~}=r&O`8#ht=`jIfAiU ze9oc@C9_ox`F5v@FAs(OYKsgL#wH&nl~?7Lg@o7(#q6j?c=|Wk>ji)X^8k?tkCfdJ z=Xl~s0E19}=^|_Hj+oxeZi%nU0*>ZDYoDR;v}CyS5TSt116|J*o{tE!p1r+Bd*z;? z%ro&(O&J4-@he%$Kx{0#Nk>)ZGrn)0nM&rc2a!?;K0{~_yqgduU}bW7VtNBupcsPs zF#ho^S(ij;Vbt{Zr0c_HM^_#x83R^ESYw}U$0%AgPw~a2Bfo`pU*U8sVy&&8CU8)Z zI$xMya)nO$)a`$kOL~7Jr@qh?&IMXc{<@+ucv0WMz0Tg97G>)xdTR9+DLr`W+b=FY zYgvoB$kQ7PgY;e2q?Y?uq@ZiNc0p&Ij)?*ogtR?4=EW~3JqdAMo`av6sZn^Wq}qEg zD#gN+ zC*e?d5obrfll(zE8W2a$0uts37w}lcY&}~>uGRG}D7*aiDs5VQ7#CmXD13crw4I$L z3Iq77RSL#PalqY}Kv8dw7_|xKW}8qdtM{`zrHXfBR<(w~lU{sTtTcE2*tG?f{sf0j zOtNgtN_TODHS}}ZpGj_F31TpdClcp~Zv+Yxfig&61DEzu|DdH?DHd%wbh^fYasWd9 z6gjJw>ua6-@mc4swH(#1JtspF9Qi^7q@qP!zvAK+JFVY0A5$)wN+-vm3G;zMgC)L-AenX*7y0?Rka3;<(p>X^llu{+KN{HgVy5VMHUbUK@#XEblK@2-o z3=ms7YS$+M_x*Gw1JmdxOT?o4Oj0T&?QJisF2NmW(Mh$SxCPF5f*;?=4%okg!`#{OdNEfNNMBFuPLL*_~LV|W>L3aMyN#T_!p#+N_;k= z@ROSiZ$vZ|8|F2)(95a05fGdyE{YX3s0tjVb04He%~~;?sqfZ1Mqg}*APyb41T}Y= zUL-iipOM!D4n?|&-^1L_6F=3n-P$V9!#cpE}_~)=-6FN zCjG(wA>u?P z87v+pS$)S|xku3G2Xd!)acL{;#*G#T`SdIoox3t{b22mu&*<^O(|g}LJ zOi)NnhdO&Wsq;LBiY^E1T+06?i5e|cRf;$vOjQ&vNCC8Oa9JKLlp@OCAmqbCChZ={u(v)E`L5_C|gT_Kw??*1w=vOZ=T3nqv*V>y#iHGl2$Fq=m?o4N=8g6{~a zHD(b&tmFvHxaxHC)mRiwo9dqeSXQ?)e2aNo#4X7oYUQ9BR&M4EOXjby_$CZCgb$tn zv;}^`JzP1Z_R9YZJe(>@)=i0G>TqGd#~O`FNNs|t*b0f>8I770!UZQvBhj$tDt7#u zyd2r^lX!k*Gig)E>L>Ss;)SD^6rLSJ$ED>VJ(~7yDc_7mgj>sEN`0LbaLnLFByg)1 z7^id7$-{Ikabz8TeR)!9=Fps@00*tQe|F>dCi;v+O{ z2%c}recO+ty%@OvpWJx+f;%S|CGv1it)#`8`Hh?|GwuykC8yC)I2BTwlKd}pH}_$d zOLHgq6VLos+re<=f)`9@#iv5NWR5&6k}Szh7IX3oc_XRV^rbtXziZg3CAk3Jy>kwL z9Vhf9v6M-o1cZDJ=~9j_|5rys<1HIa@HtJhwoEjrKQKIjY$CGS-|9A`+^?}OWDR=# z(f+Pt+O!o)mBWU}t-E1YjwgX`&Op0b(k$h{7#U)pShe|4o92$|tb%|sd>)|rGZ^IY z_ZY}Tc;Qn|9F{tMG*fr2C~Dn+QkB&OgpJ$jXW@CZe%1<^>D`#mr#GGtiho$Io zVz))oCUA_crzMcowMFY_%6R;4Ptc6}P$Bv(Vy!X#QBvaPs7!ne0RK)^AzyuLG*Ifu zId7`drdI7LRIXi}8};EL2h}oH3DyIk=5})+=}Slw_rg8pt807Bs;9O8KG#H8y4%dN zejT?=m}yxV@?PZy6|5T@JKzcct$)t51{>Cp*!rdZFRR{$i+`0rQ*J0LewDOAzWDnD Kd9%GR1^)#+UbrLx literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/forms-bar.png b/po/fr/docs/okular/forms-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..68a36758a64b45b5920c54ce8a7f0630bd09bbf7 GIT binary patch literal 5463 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 QTx%5220vD>Q?rZxA8s~?0{{R3 literal 0 HcmV?d00001 diff --git a/po/fr/docs/okular/index.docbook b/po/fr/docs/okular/index.docbook new file mode 100644 index 0000000..6ee9d2b --- /dev/null +++ b/po/fr/docs/okular/index.docbook @@ -0,0 +1,3505 @@ + + + ATEX"> + + KPDF"> + PDF"> + + +]> + + + + Manuel d'&okular; + + Albert Astals Cid

&Albert.Astals.Cid.mail;
+ + + Pino Toscano
pino@kde.org
+
+
+ &traducteurCedricPasteur;&traducteurYohannHamon;&traducteurJoelGuelluy;&traducteurLudovicGrossard;&traducteurPeterPotrowl;&relecteurLudovicGrossard; + + &FDLNotice; + 25/02/2014 + 0.19 (&kde; 4.13) + + + &okular; est un afficheur de documents universel pour &kde; fondé sur le code de &kpdf;. + + + KDE + okular + pdf + ps + PostScript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + mobipocket + plucker + annotation + + + + Introduction + &okular; est un afficheur de documents universel pour &kde; fondé sur le code de &kpdf;. Bien que fondé sur le code de &kpdf;, &okular; dispose de quelques fonctions particulières telles que le mode continu, une gestion des présentations améliorée et une gestion des annotations. + &okular; gère un grand nombre de formats différents, comme &PDF;, &PostScript;, Tiff, CHM, DjVU, les images (png, jpg, &etc;) XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub et Fax. Pour en savoir plus sur tous les formats gérés et leurs fonctionnalités, consultez les gestionnaires de formats de documents d'&okular;. + + Fenêtre principale d'&okular; + + + + + + Fenêtre principale d'&okular; + + + + + + Utilisation de base + + Ouverture de fichiers + Pour afficher tout fichier reconnu par &okular;, sélectionnez FichierOuvrir..., choisissez un fichier dont le format est pris en charge dans la boîte de dialogue et cliquez sur Ouvrir. Votre fichier devrait à présent être affiché dans la fenêtre principale. + + Le nouveau document s'ouvrira dans un nouvel onglet si l'option Ouvrir les nouveaux fichiers dans des onglets dans la Page de configuration générale est cochée. + + Si vous avez déjà ouvert des fichiers avec &okular;, vous pouvez rapidement accéder à ces mêmes fichiers en les sélectionnant dans le menu FichierRécemment ouvert(s) + &okular; est le logiciel par défaut de &kde; pour la lecture des fichiers &PDF; et &PostScript; lorsque vous cliquez avec le &BGS; sur un tel fichier dans le gestionnaire de fichiers. Si vous voulez ouvrir un format de fichier quelconque qui soit géré par &okular;, choisissez Ouvrir avec...&okular; dans le menu contextuel du gestionnaire de fichiers. + Une fois qu'un fichier est ouvert, vous voudrez probablement le lire et le parcourir. Allez dans la section suivante pour apprendre comment faire. + + + Navigation + Cette section décrit les manières de parcourir un document avec &okular;. + Il existe de nombreuses manières de déplacer l'aire d'affichage. Une méthode consiste à utiliser les touches Flèche vers le haut et Flèche vers le bas. Vous pouvez aussi utiliser la barre de défilement, la molette de la souris ou les touches Page précédente et Page suivante. + Vous pouvez également utiliser les clés de navigation comme dans vim, c'est-à-dire H pour atteindre le haut de la page précédente, L pour atteindre le haut de la page suivante, J pour atteindre la ligne suivante et K pour atteindre la ligne précédente. + Une autre méthode consiste à appuyer sur le &BGS;, n'importe où sur le document, et en déplaçant la souris dans la direction opposée au déplacement voulu pour le document. Cette procédure fonctionne uniquement si l'outil de navigation est activé, ce qui peut être fait en choisissant OutilsOutil de navigation. + + Lorsque vous affichez un document en mode présentation, utilisez les touches Flèche haut et Flèche bas pour passer d'une page ou diapositive à l'autre. Le numéro et la position de la page ou diapositive courante s'affichera en surimpression en haut à droite de l'écran. + + Si vous voulez lire un document comportant de nombreuses pages, utilisez la fonctionnalité de défilement automatique d'&okular;. Démarrez le défilement automatique avec &Maj;Flèche bas ou &Maj;Flèche haut. Utilisez ensuite ces touches pour augmenter ou diminuer la vitesse de défilement. Vous pouvez démarrer ou arrêter le défilement automatique temporairement en appuyant sur la touche &Maj; ; appuyer sur toute autre touche désactivera la fonctionnalité. + Une autre manière de naviguer parmi de nombreuses pages est d'utiliser le pointeur de la souris. Cliquez-déplacez la page vers le haut ou vers le bas. Continuez ainsi même si vous atteignez le haut ou le bas de l'écran. Une fois que vous atteindrez le bord d'une page, le curseur de la souris apparaîtra en bas ou en haut de l'écran et vous pourrez ainsi continuer à naviguer. + La barre de navigation du côté gauche de la fenêtre vous donne accès à deux méthodes supplémentaires pour naviguer dans un document : + + + si vous cliquez sur la vignette d'une page, l'aire d'affichage affichera cette page ; + + + si le document dispose d'un sommaire, cliquer sur un élément du sommaire fera défiler le document jusqu'à la page liée à cet élément ; + + + si le document comporte des signets, activez la vue Signets et cliquez sur ces signets pour vous rendre à la page associée. Si les signets ne sont pas affichés uniquement pour le fichier actuel, vous pouvez naviguer facilement dans les signets de tous les documents récemment ouverts ; + + + Si le document comporte des annotations, activez la vue Révisions et cliquez sur ces annotations ou sélectionnez-les avec les touches Flèche haut et Flèche bas et appuyez sur Entrée pour vous rendre à la page associée. + + + Certains documents possèdent des liens. Dans ce cas, cliquer sur l'un d'eux affichera la page ciblée par ce lien dans l'aire d'affichage. Si le lien est une page web ou tout autre document, le programme par défaut de &kde; gérant ce format de fichier sera appelé. Par exemple, cliquer sur un lien pointant vers http://fr.kde.org ouvrira cette page web dans le navigateur par défaut de &kde;. + + Les liens internes du document ne fonctionneront que si l'Outil de navigation est utilisé. + + De plus, vous pouvez utiliser les fonctionnalités suivantes pour vous déplacer rapidement à certains endroits spécifiques du document : + + + vous pouvez vous rendre au début d'un document en utilisant &Ctrl;Début ou en utilisant AllerDébut du document ; + + + vous pouvez vous rendre à la fin d'un document en utilisant &Ctrl;Fin ou en utilisant AllerFin du document ; + + + vous pouvez avancer dans un document en utilisant Espace ou Page suivante. Pour aller à la page suivante d'un document, utilisez le bouton Page suivante de la barre d'outils ou AllerPage suivante dans la barre de menu ; + + + vous pouvez reculer dans un document en utilisant la touche Correction ou la touche Page précédente. Pour aller à la page précédente, utilisez le bouton Page précédente de la barre d'outils ou AllerPage précédente dans la barre de menu. + + + Vous pouvez revenir aux positions du document affichées précédemment dans l'ordre chronologique. Par exemple, dans le cas où vous venez de lire la phrase Comme expliqué dans [15], …, et que vous voulez maintenant lire la référence [15]. Vous cliquerez donc dessus et &okular; affichera la liste des références. En utilisant &Alt;&Maj;Gauche ou Aller Précédent dans la barre de menu vous ramènera exactement à la position où vous étiez précédemment. + + + Vous pouvez naviguer en avant dans le document après être revenu en arrière comme décrit ci-dessus en utilisant &Alt;&Maj;Droite ou Aller Suivant dans la barre de menu. + + + Vous pouvez aller à l'occurrence suivant lors de la recherche en utilisant la touche F3 ou &Entree; (lorsque le champ de texte Rechercher a le focus) ou le menu Édition Poursuivre la recherche ou revenir à l'occurrence précédente en utilisant les touches &Maj;F3 ou &Maj;&Enter; (lorsque le champ de texte Rechercher a le focus) ou le menu Édition Chercher en arrière . + + + + + Le mode présentation + Le mode présentation est une autre façon d'afficher des documents dans &okular;. Il peut être activé dans AffichagePrésentation. Il montre le document page par page. Les pages sont affichées avec le zoom adapté à la page, ce qui signifie que toute la page sera visible. + + Les documents &PDF; peuvent même spécifier qu'ils doivent toujours être ouverts en mode présentation. + + Lorsque vous êtes en mode présentation, une barre d'aide se situe en haut de l'écran. Déplacez simplement le pointeur de la souris en haut de l'écran pour la faire apparaître. + + &okular; en mode présentation + + + + + + &okular; en mode présentation + + + + Pour naviguer entre les pages, vous pouvez utiliser le &BGS; (page suivante) et le &BDS; (page précédente), la molette de la souris, les icônes fléchées, le champ de texte dans la barre près du haut de l'écran, ou les touches spécifiées dans la section Navigation. + Utilisez le bouton Lecture / Pause dans la barre du haut pour lire ou mettre en pause la présentation, respectivement. + Vous pouvez sortir du mode présentation à tout instant en utilisant la touche &Echap; ou en cliquant sur l'icône Quitter dans la barre en haut de l'écran. + Vous pouvez également dessiner sur la page actuelle avec un crayon. Cliquez sur l'icône Activer / désactiver le mode dessin dans la barre en haut de l'écran pour permettre ou non de dessiner en mode présentation. Les dessins sont automatiquement effacés lorsque vous quittez le mode présentation. Vous pouvez aussi cliquer sur l'icône Effacer les dessins pour effacer les dessins de la page courante. + Le mode de présentation gère maintenant plus d'un écran dans une configuration multi-écrans. Avec plusieurs écrans, un nouveau bouton apparaîtra dans la barre du haut, avec l'icône d'un écran : il s'agit d'une boîte déroulante qui vous permet de déplacer la présentation vers n'importe lequel des autres écrans disponibles. + Le mode présentation dispose de plusieurs options de configuration. Vous pouvez trouver leur description dans le chapitre Configurer &okular;. + + + + Recherche inversée entre &latex; et &okular; + + La recherche inversée est un outil pratique lorsque vous écrivez un document &latex;. Si tout est correctement configuré, vous pouvez cliquer sur une partie du texte dans la fenêtre d'&okular; en utilisant le &BGS; tout en appuyant sur &Maj;. L'éditeur charge alors le code source &latex; et affiche directement le paragraphe correspondant. + + La recherche inversée ne peut fonctionner que si : + + + la compilation du fichier source a réussi, + &okular; sait quel éditeur vous voulez utiliser, + l'outil de navigation est activé. Pour ce faire, choisissez OutilsOutil de navigation. + + + Avec cette fonctionnalité d'&okular;, un clic du &BGS; en appuyant sur &Maj; dans le document &DVI; ou &PDF; ouvrira le document &latex; correspondant dans l'éditeur et essaiera d'afficher la ligne concernée. N'oubliez pas d'indiquer à &okular; quel éditeur vous souhaitez utiliser, dans le menu ConfigurationConfigurer Okular... (dans la page Éditeur). + + Pour plus de détails sur la configuration de l'éditeur, référez-vous à la section correspondante de ce manuel. + + + Configuration d'&okular; + + + + + + Configuration de l'éditeur dans &okular; + + Configuration de l'éditeur dans &okular; + + + + + + + Fonctionnalités avancées d'&okular; + + Fichiers intégrés + Si le document actuel contient des fichiers intégrés, lorsque vous l'ouvrez, une barre jaune apparaîtra au-dessus de la page pour notifier la présence de ces fichiers. + + La barre des fichiers intégrés + + + + + + La barre des fichiers intégrés + + + + Dans ce cas, vous pouvez soit cliquer sur le lien dans le texte de la barre, soit choisir FichierFichiers intégrés pour ouvrir la boîte de dialogue des fichiers intégrés. Cette boîte de dialogue vous permet de voir les fichiers intégrés et de les extraire. + + + Formulaires + Si le document actuel contient des formulaires, lorsque vous l'ouvrez, une barre apparaîtra au-dessus de la page pour vous permettre d'activer ces formulaires. + + La barre des formulaires + + + + + + La barre des formulaires + + + + Dans ce cas, vous pouvez soit cliquer sur Cliquer ici pour les voir, dans la barre, soit choisir AffichageAfficher les formulaires pour saisir des données dans les champs des formulaires. + + + Annotations + &okular; vous permet de relire et d'annoter vos documents. Les annotations créées dans &okular; sont enregistrées automatiquement dans le dossier de configuration local pour chaque utilisateur. Par conséquent, &okular; ne modifie aucun des documents qu'il ouvre. + + Les annotations d'&okular; + + + + + + Les annotations d'&okular; + + + + &okular; dispose de deux types d'annotations différents. + Les annotations textuelles, comme Surbrillance jaune et Souligné noir pour les fichiers contenant du texte, comme par exemple les &PDF;. + Les annotations graphiques, comme Note contextuelle, Note intégrée, Ligne à main levée, Surligneur, Ligne droite, Polygone, Tampon, Souligné et Ellipse pour tous les formats gérés par &okular;. + En utilisant le menu contextuel, soit dans la vue Révisions du panneau de navigation, soit dans la fenêtre principale, vous pouvez ouvrir une Note épinglée pour tout type d'annotation et ajouter ou modifier les commentaires. + Les annotations ne se limitent pas aux fichiers &PDF; ; elles peuvent être utilisées pour tout format que gère &okular;. + Depuis &kde; 4.2, &okular; dispose d'une fonction d'« archivage de documents ». Il s'agit d'un format spécifique à &okular; permettant de déplacer avec le document de nombreuses métadonnées qui lui sont attachées (actuellement, cela ne concerne que les annotations). Vous pouvez enregistrer une « archive » de document à partir du document actif en sélectionnant FichierExporter comme. Pour ouvrir une archive de document &okular;, ouvrez-la simplement avec &okular;, comme s'il s'agissait d'un document &PDF;. + Depuis &okular; 0.15 vous pouvez également enregistrer les annotations directement dans les fichiers &PDF;. Cette fonctionnalité n'est disponible que si &okular; a été compilé avec la version 0.20 ou ultérieure de la librairie de rendu Poppler. Vous pouvez utiliser le menu Fichier Enregistrer sous... pour enregistrer une copie du fichier &PDF; avec les annotations. + + Il n'est pas possible d'enregistrer les annotations dans les fichiers &PDF; dont l'original est chiffré si &okular; utilise les bibliothèques Poppler d'une version antérieure à la 0.22. + + + Lorsque vous ouvrez un &PDF; comportant déjà des annotations, vos modifications apportées aux annotations ne sont pas automatiquement enregistrées dans le dossier local interne mais vous devez enregistrer manuellement le document modifié (en utilisant le menu FichierEnregistrer sous...) avant la fermeture. Si vous oubliez de le faire, &okular; vous présentera une fenêtre de confirmation vous invitant à enregistrer le document. + + + + En raison des limitations dues au DRM (typiquement pour les documents &PDF;), l'ajout, la modification de certaines propriétés, ou la suppression d'annotations peuvent ne pas être possibles. + + + Toute action sur les annotations (création et retrait d'annotations, modification des propriétés d'une annotation, déplacement d'annotations avec &Ctrl;+déplacement et modification du contenu textuel d'une annotation) peut être annulée ou refaite en utilisant l'option correspondante dans le menu Édition. Il est également possible d'annuler une action en appuyant sur &Ctrl;Z et de refaire une action annulée en appuyant sur &Ctrl;&Maj;Z. + + Depuis &okular; 0.17, vous pouvez configurer les propriétés par défaut et l'apparence de chaque outil d'annotation. Veuillez vous référer à la section correspondante de ce manuel. + + Ajouter des annotations + Pour ajouter des annotations dans le document, vous devez activer la barre d'annotations, soit en choisissant OutilsRévision, soit en appuyant sur F6. Une fois que la barre d'annotations est visible, appuyez simplement sur un de ses boutons ou utilisez les raccourcis claviers (touches 1 à 9) pour commencer à annoter. + La barre d'outils d'annotation vous permet de créer des annotations avec des dessins, des formes et du texte. Vous pouvez utiliser les annotations pour marquer un document (par exemple ajouter des lignes, des ellipses, des polygones, des tampons, des surlignements et soulignements, etc.). La table ci-dessous décrit précisément à quoi sert chaque bouton de la barre d'outils d'annotation. + + + + + Bouton + Nom de l'outil + Description + + + + + + + + + + + + + + + Note épinglée + + + Pour ajouter une note multiligne. Cette note pourra être lue en double-cliquant sur une icône dans le document. + Cliquez sur le bouton de l'outil puis cliquez sur le document à l'endroit où vous voulez que la note épinglée apparaisse. Saisissez le texte dans la fenêtre de la note puis cliquez sur le bouton Fermer cette note en haut à droite de la fenêtre. + + + + + + + + + + + + + + Note intégrée + + + Pour ajouter une note intégrée. Cette note sera affichée telle quelle dans le document. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; et maintenez-le pour définir le coin en haut à gauche de la note puis déplacez la souris et relâchez le bouton pour définir le coin en bas à droite. Saisissez le texte de la note puis cliquez sur le bouton Ok pour enregistrer la note, ou Annuler pour annuler la saisie ou Effacer pour effacer la note. + + + + + + + + + + + + + + Ligne à main levée + + + Pour dessiner des lignes aux formes libres. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; et maintenez-le pour placer le début de la ligne, puis déplacez la souris pour dessiner la ligne. + + + + + + + + + + + + + + Surligneur + + + Pour surligner du texte dans le document avec une couleur de fond définie. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; et maintenez-le pour définir le début de la zone de texte à surligner puis déplacez la souris et relâchez le bouton pour surligner. + + + + + + + + + + + + + + Ligne droite + + + Pour marquer avec une ligne. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; pour placer le point de départ de la ligne puis déplacez la souris vers la position du point de fin de la ligne et cliquez à nouveau. + + + + + + + + + + + + + + Polygone + + + Pour dessiner une figure plane fermée à trois segments ou plus. La note correspondante peut être lue en double-cliquant dans le polygone. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; pour placer le premier sommet du polygone puis déplacez la souris et cliquez pour définir le second sommet et ainsi de suite jusqu'à revenir au premier sommet. Double-cliquez si vous voulez ajouter une note au polygone. Saisissez le texte de la note puis cliquez sur le bouton Ok pour enregistrer la note, Annuler pour annuler la saisie ou Effacer pour effacer la note. + + + + + + + + + + + + + + Tampon + + + Pour marquer le texte ou l'image avec une forme prédéfinie. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; pour placer le tampon. + Un simple clic place un tampon rectangulaire (utile pour les icônes). Pour ajouter un tampon rectangulaire, vous pouvez cliquer avec le &BGS; et le maintenir enfoncé pour placer le point en haut à gauche puis celui en bas à droite. + + + + + + + + + + + + + + Souligner + + + Pour souligner du texte. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; puis maintenez-le pour placer le début de la portion de texte à souligner puis déplacez la souris pour le souligner. + + + + + + + + + + + + + + Ellipse + + + Pour dessiner une ellipse autour d'une zone. + Cliquez sur le bouton de l'outil puis cliquez avec le &BGS; et maintenez-le pour placer le coin en haut à gauche du rectangle circonscrit à l'ellipse puis déplacez la souris pour placer le coin en bas à droite. + + + + + + Le contenu de la barre des outils d'annotation peut être configurée grâce à l'écran Annotations de la fenêtre de configuration d'&okular;. Cet écran peut être affiché en cliquant avec le &BDS; sur la barre d'outils d'annotation et en choisissant Configurer les annotations... dans le menu contextuel. + Un clic simple du &BGS; sur un bouton d'outil d'annotation vous permet d'utiliser cet outil une fois. Si vous voulez, par exemple, mettre en valeur toutes les parties importantes d'un texte, activez cet outil de façon permanente en double-cliquant sur son bouton. Appuyez sur la touche Échap ou cliquez de nouveau sur le bouton de l'outil pour quitter ce mode permanent. + + La barre d'annotation peut être incrustée de n'importe quel côté de la zone d'affichage, glissez-la simplement pour la déplacer vers un autre endroit. + + + Activer la barre d'annotation vous fait basculer automatiquement en mode outil de navigation. + + Vous pouvez arrêter la construction à n'importe quel moment en appuyant de nouveau sur le bouton d'annotation que vous construisez, ou en appuyant sur la touche &Echap;. + L'annotation nouvellement construite aura comme auteur celui que vous avez réglé dans l'écran Annotations dans la boîte de dialogue de configuration d'&okular;. L'écran Annotations peut aussi être utilisé pour configurer le contenu de la barre des outils d'annotation. + + + Enlever des annotations + Pour enlever une annotation, cliquez simplement avec le &BDS;, et choisissez Supprimer. + Lorsqu'une annotation est enlevée, sa fenêtre est fermée si elle était ouverte. + + Cette option peut ne pas être disponible si le document ne permet pas de supprimer d'annotation. + + + + Modifier les annotations + Pour modifier une annotation, cliquez dessus avec le &BDS; et choisissez Propriétés. Une boîte de dialogue apparaîtra avec les paramètres d'annotation généraux (comme la couleur, l'opacité, l'auteur, &etc;) et les réglages spécifiques à ce type d'annotation. + + La boîte de dialogue propriété d'annotation + + + + + + La boîte de dialogue propriété d'annotation + + + + Pour déplacer une annotation, maintenez la touche &Ctrl; enfoncée, déplacez le pointeur de la souris dessus et commencez à faire glisser l'annotation avec le &BGS;. + + En fonction des droits sur le document (typiquement avec les documents &PDF;), certaines options peuvent être désactivées. + + + + + Gestion des signets + &okular; dispose d'un système de signets très flexible. &okular; enregistre la position de la page dans les signets et vous permet de définir plus d'un signet par page. + Pour gérer les signets dans &okular;, vous pouvez utiliser la vue Signets du Panneau de navigation, le menu Signets ou le menu contextuel de la vue du document (utilisez le &BDS; pour l'ouvrir). + + Vue Signets + Pour ouvrir la vue Signets, cliquez sur Signets dans la Barre de navigation. Si la Barre de navigation n'est pas affichée, appuyez sur F7 ConfigurationAfficher la barre de navigation dans le menu principal, pour la faire apparaître. + + Le menu contextuel de la vue Signets + + + + + + Le menu contextuel de la vue Signets + + + + La barre de filtrage en haut de la vue Signets vous permet de filtrer le contenu du panneau des signets en fonction du texte que vous saisissez dans le champ. + Le panneau de liste vous permet de voir la liste des signets sous forme d'arbre : chaque document de la liste peut être développé ou replié en cliquant sur l'icône > ou v à côté de lui. + Cliquez sur l'icône sous la liste pour n'afficher que les signets du document courant. + Le menu contextuel de chaque document de la liste vous permet d'ouvrir le document, renommer ses signets ou le retirer de la liste. N'oubliez pas que retirer un document de la liste retirera tous les signets correspondants. + Le menu contextuel de chaque signet vous permet d'aller au signet, le renommer ou le supprimer. + + + + + Options de la ligne de commande + Bien qu'&okular; soit le plus souvent lancé depuis le menu des programmes de &kde; ou une icône du bureau, il peut également être lancé depuis la ligne de commande d'une fenêtre de terminal. Voici quelques options pratiques qui sont utilisables dans ce cas. + + Spécifier un fichier + En spécifiant l'adresse et le nom d'un fichier particulier, l'utilisateur demande à &okular; d'ouvrir ce fichier immédiatement au lancement du logiciel. Cette option peut ressembler à la ligne suivante : + % okular + + + Pour les documents &PDF;, le nom peut être saisi en utilisant nom_du_document#nom_de_la_destination où nom_de_la_destination est une partie nommée à l'intérieur du document. + + + + Autres options de la ligne de commande + Les options d'aide suivantes de la ligne de commande sont disponibles + + + okular + Liste les options les plus simples disponibles pour la ligne de commande. + + + okular + Liste les options disponibles pour changer la manière dont &okular; interagit avec &Qt;. + + + okular + Liste les options disponibles pour changer la manière dont &okular; interagit avec &kde;. + + + okular + Liste toutes les options de la ligne de commande. + + + okular + Liste les auteurs d'&okular; dans la fenêtre de terminal + + + okular + Liste les informations de version pour &Qt;, &kde; et &okular;. Disponible également par okular + + + okular + Affiche les informations sur la licence. + + + okular + Ouvre la page du document dont le numéro est spécifié. Disponible également par okular + + + okular + Ouvre le document en mode présentation. + + + okular + Démarre avec la fenêtre d'impression. + + + okular + N'ouvre qu'une instance d'&okular;. + + + okular + Empêche la fenêtre d'&okular; de s'afficher lors du lancement. + + + okular + Fin des options. + + + + + + + + La barre de menu + + + Le menu Fichier + + + + &Ctrl;O Fichier Ouvrir... + + + Ouvre un fichier pris en charge ou une archive &okular;. Si un autre document est déjà ouvert, il sera fermé. Pour plus d'informations, consultez la section concernant l'ouverture de fichiers. + + + + + + FichierRécemment ouvert(s) + + + Ouvre un fichier ouvert précédemment via un sous-menu. Si un fichier est actuellement ouvert, il sera fermé. Pour plus d'informations, consultez la section concernant l'ouverture de fichiers. + + + + + + Fichier Importer du format « PostScript » comme du « &PDF; »... + + + Ouvre un fichier &PostScript; et le convertit en &PDF;. + + + + + + FichierEnregistrer sous... + + + Enregistre le fichier actuellement ouvert sous un nom différent en utilisant le moteur d'interface du document. Avec le moteur &PDF; (Poppler +>= 0.8 est nécessaire), il est possible d'enregistrer le document ainsi que les valeurs des champs de saisie. Il est aussi possible (si le document n'est pas protégé par DRM) d'enregistrer les annotations dans le fichier &PDF; (Poppler +>= 0.22 est nécessaire). + + + + + + FichierEnregistrer une copie sous... + + + Enregistre une copie du fichier actuellement ouvert avec un nom différent sans utiliser le moteur d'interface du document actuel. + + + + + + + F5Fichier Recharger + + + Recharge le fichier actuellement ouvert. + + + + + + &Ctrl;P FichierImprimer... + + + Imprime le fichier actuellement affiché. + + + + + + FichierAperçu avant impression + + + Montre un aperçu de la manière dont le document actuellement affiché sera imprimé avec les options par défaut. + + + + + + FichierPropriétés + + + Affiche quelques informations de base concernant le document, comme le titre, l'auteur, la date de création et les détails concernant les polices utilisées. Les informations disponibles dépendent du type de document. + + + + + FichierFichiers intégrés + + + Montre les fichiers intégrés dans le document s'il en contient. Pour davantage d'informations, voyez la section sur les fichiers intégrés. + + + + + + FichierExporter comme + + + Cet élément contient les formats d'exportation utilisables pour le document actuel. Le premier élément pour tous les types de documents est toujours Texte brut... + La deuxième entrée est Archive de document, qui vous permet d'enregistrer le document en incluant vos annotations dans une format d'archive spécifique à &okular;. Ainsi, il est possible de partager facilement le document d'origine et vos annotations avec d'autres utilisateurs d'&okular; et de travailler avec eux de manière collaborative. + + + + + + &Ctrl;Q FichierQuitter + + + Ferme &okular;. + + + + + + + Le menu Édition + + + + + &Ctrl;Z Édition Annuler + + + Annule la dernière action d'annotation (création ou retrait d'annotation, édition d'une propriété d'annotation, déplacement d'annotation avec &Ctrl;+déplacement ou édition du texte contenu dans une annotation). + + + + + + &Ctrl;&Maj;Z Édition Refaire + + + Refait la dernière action annulée lors de l'édition des annotations. + + + + + + + + &Ctrl;C ÉditionCopier + + + Copie le texte actuellement sélectionné en mode Sélection de texte dans le presse-papier. + + + + + + + + &Ctrl;A Édition Tout sélectionner + + + Sélectionne tout le texte (si le document en contient). Ceci ne fonctionne qu'en mode Sélection de texte. + + + + + + + + &Ctrl;F ÉditionChercher... + + + Ouvre une boîte de dialogue qui vous permet de chercher une chaîne de caractères dans le document. + + + + + + F3Édition Poursuivre la recherche + + + Cherche de nouveau la chaîne de caractères précédemment recherchée. + + + + + + &Maj;F3 Édition Chercher en arrière + + + Se rend à l'occurrence précédente de la chaîne de caractères actuellement recherchée. + + + + + + + Le menu Affichage + + + + &Ctrl;&Maj;P AffichagePrésentation + + + Active le mode présentation. Pour davantage d'informations, voyez la section sur le mode présentation. + + + + + &Ctrl;+ Affichage Zoom avant + + + Accroît l'agrandissement de la vue du document. + + + + + + &Ctrl;- Affichage Zoom arrière + + + Réduit l'agrandissement de la vue du document. + + + + + AffichageAdapter à la largeur + + + Modifie l'agrandissement de la vue du document de sorte que la largeur de la page devienne celle de l'aire d'affichage. + + + + + AffichageAdapter à la page + + + Modifie l'agrandissement de la vue du document de sorte qu'au moins une page entière soit visible. + + + + + AffichageAdapter automatiquement + + + Change le niveau de zoom du document à une valeur qui, en fonction du rapport entre la taille de la page et la taille de la zone d'affichage, adapte automatiquement la largeur de la page pour la rendre égale à la largeur de la zone d'affichage (adaptation en largeur), la hauteur de la page pour la rendre égale à la hauteur de la zone d'affichage (adaptation en hauteur) ou rend toute la page visible (adaptation à la page). + + + + + AffichageContinu + + + Active le mode d'affichage continu. Dans ce mode, toutes les pages sont affichées à la suite les unes des autres. Vous pouvez donc les faire défiler sans devoir utiliser les options Aller Page précédente et AllerPage suivante . + + + + + AffichageMode d'affichage + + + Ce sous-menu vous permet de choisir le mode d'affichage des pages. Les options possibles sont Page unique (une seule page par ligne), pages face à face (deux pages par ligne, comme pour un livre), Pages face-à-face (centrer la première page) et Aperçu (le nombre de colonnes est celui spécifié dans la configuration d'&okular;. + + + + + AffichageOrientation + + + Ce sous-menu vous permet de changer l'orientation des pages du document. + + La rotation est appliquée à l'orientation de chaque page. + + Vous pouvez choisir Orientation originale pour restaurer l'orientation du document, annulant toutes les rotations appliquées manuellement. + + + + + AffichageTaille de page + + + Change la taille des pages du document. + + Ce sous-menu n'est actif que si le type de document actuel gère les pages de différentes tailles. + + + + + + Affichage Réduire les marges + + + Enlève la bordure blanche lors de l'affichage des pages. + + + + + AffichageAfficher / cacher les formulaires + + + Affiche ou cache l'affichage des champs de formulaires dans le document. + + Cet élément de menu n'est actif que si le document actuel contient des champs de formulaires. + + + + + + + + + Le menu Aller + + + + AllerPage précédente + + + Affiche la page précédente du document. + + + + + AllerPage suivante + + + Affiche la page suivante du document. + + + + + &Ctrl;Début AllerDébut du document + + + Aller au début du document. + + + + + &Ctrl;Fin Aller Fin du document + + + Aller à la fin du document. + + + + + &Alt;&Maj;Gauche Aller En arrière + + + Se déplace vers la vue précédente du document. + + + + + &Alt;&Maj;Droite Aller En avant + + + Se déplace vers la vue suivante du document. Ceci n'est possible que si vous vous êtes déjà déplacé en arrière. + + + + + &Ctrl;G Aller Aller à la page... + + + Ouvre une boîte de dialogue vous permettant d'aller vers n'importe quelle page du document. + + + + + + + Le menu Signets + + + + &Ctrl;B Signets Ajouter / supprimer un signet + + + Ajoute ou supprime un signet pour la position actuelle. + + + + + SignetsRenommer le signet + + + Renomme le signet pour la position actuelle. + + + + + SignetsSignet précédent + + + Va au signet précédent, ou ne fait rien, s'il n'y a pas de signet avant le signet actuel. + + + + + SignetsSignet suivant + + + Va au signet suivant, ou ne fait rien, s'il n'y a pas de signet après le signet actuel. + + + + + SignetsAucun signet + + + C'est une action toujours désactivée qui apparaît dans ce menu uniquement si le document ne contient pas de signets. Sinon, une liste de tous les signets est affichée ici. En cliquant sur ces signets, vous pourrez aller directement aux positions associées. + + + + + + + Le menu Outils + + + + &Ctrl;1 Outils Outil de navigation + + + La souris aura un comportement normal, le &BGS; pour déplacer le document et suivre les liens et le &BDS; pour ajouter des signets et pour ajuster la page à la largeur de l'écran. + + + + + &Ctrl;2 Outils Outils de redimensionnement + + + La souris fonctionnera comme un outil de zoom. Cliquer avec le &BGS; et se déplacer agrandira la partie sélectionné, cliquer avec le &BDS; ramènera le document au zoom précédent. + + + + + &Ctrl;3 Outils Outils de sélection + + + La souris fonctionnera comme un outil de sélection. Dans ce mode, cliquer avec le &BGS; et se déplacer permettra de copier les textes / images contenus dans la partie sélectionnée vers le presse-papier, prononcer du texte ou enregistrer une image vers un fichier. + + + + + &Ctrl;4 Outils Outils de sélection de texte + + + La souris fonctionnera comme un outil de sélection. Dans ce mode, cliquer avec le &BGS; et se déplacer permettra de copier le texte contenu dans la partie sélectionnée vers le presse-papier ou de le prononcer. + + + + + &Ctrl;5 Outils Outils de sélection de tableau + + + Dessinez un rectangle autour du texte du tableau, puis cliquez avec le &BGS; pour diviser le bloc de texte en lignes et en colonnes. Un clic du &BDS; sur un trait existant le supprime et fusionne les lignes ou colonnes adjacentes. + + + + + &Ctrl;6 Outils Magnifier + + + Active le mode d'agrandissement du pointeur de la souris. Cliquez et maintenez le &BGS; pour activer le composant graphique d'agrandissement et déplacez le pointeur de la souris au-dessus du document. Chaque pixel du document apparaîtra comme un carré de 10 pixels de côté. + + + + + F6 Outils Révision + + + Ouvre le barre des annotations. Cette barre d'outils vous permet d'ajouter des annotations au document que vous lisez. Pour plus d'informations, veuillez lire la section sur les annotations. + + + + + OutilsÉnoncer vocalement le document entier + + + OutilÉnoncer vocalement la page actuelle + + + OutilsArrêter l'énonciation vocale + + + es éléments vous permettent de prononcer le document entier ou juste la page actuelle, ou d'arrêter la prononciation, en utilisant le système Text-to-Speech &jovie; de &kde; + Les actions d'énonciation vocale... ne sont activées que si &jovie; est disponible sur le système. + + + + + + + Le menu Configuration + + + + &Ctrl;M Configuration Afficher la barre de menus + + + Affiche / cache la barre de menu. Une fois cachée elle peut être rendue visible en utilisant à nouveau le raccourci clavier &Ctrl;M. Si la barre de menu est cachée, le menu contextuel ouvert avec le &BDS; n'importe où dans la zone d'affichage aura une entrée supplémentaire Afficher la barre de menu. + + + + + ConfigurationAfficher la barre d'outils + + + Affiche / cache la barre d'outils. + + + + + F7 Configuration Afficher la barre de navigation + + + Affiche / cache la barre de navigation. + + + + + ConfigurationAfficher la barre des pages + + + Active / désactive la barre des pages sous la zone qui affiche le document, pour gagner de l'espace d'affichage dans la fenêtre d'&okular;. + + + + + &Ctrl;&Maj;FConfigurationMode plein écran + + + Active le mode plein écran. Notez que le mode plein écran est différent du mode mode présentation puisque la seule particularité du mode plein écran est qu'il cache les décorations de la fenêtre, la barre de menu et la barre d'outils. + + + + + ConfigurationConfigurer les raccourcis clavier... + + + Ouvre une fenêtre qui vous permet de configurer les raccourcis clavier pour beaucoup de commandes des menus. + + + + + ConfigurationConfigurer les barres d'outils... + + + Ouvre une fenêtre vous permettant de choisir quelles icônes sont visibles dans la barre d'outils. + + + + + ConfigurationConfigurer les moteurs de rendu... + + + Ouvre la fenêtre Configurer les moteurs de rendu. + + + + + ConfigurationConfigurer &okular;... + + + Ouvre la fenêtre de Configuration. + + + + + + + Le menu Aide +&help.menu.documentation; + + + + Configuration des moteurs de rendu d'&okular; + Vous pouvez configurer les moteurs de rendu d'&okular; en choisissant Configuration Configurer les moteurs de rendu... . Pour le moment, les options de configuration n'existent que pour les moteurs de rendu EPub, &PostScript;, FictionBook, Txt, texte OpenDocument et &PDF;. + + La boîte de dialogue de configuration des moteurs de rendu + + + + + + La boîte de dialogue de configuration des moteurs de rendu + + + + En utilisant les écrans de configuration des moteurs de rendu EPub, FictionBook, Txt et texte OpenDocument, vous pouvez décider de la police de caractères à utiliser pour afficher les documents dans ces formats. Le bouton Choisir... de ces écrans ouvre la fenêtre classique de configuration des polices de &kde;. Veuillez vous référer à la Documentation de base de &kde; pour les détails. + La description des écrans de configuration des moteurs de rendu &PostScript; et &PDF; se trouve ci-dessous. + + Configuration du moteur de rendu &PostScript; + Vous pouvez configurer le moteur de rendu &PostScript; d'&okular; fondé sur Ghostscript en choisissant Ghostscript dans la liste de la partie gauche de la fenêtre de configuration. La seule option configurable est la suivante. + + + + + Utiliser les polices de la plate-forme + + + Cette option détermine si Ghostscript doit être autorisé à utiliser les polices de caractères de l'ordinateur. Lorsque cette option est désactivée, seules les polices embarquées dans le document seront utilisées. Cette option est activée par défaut. + + + + + + + Configuration du moteur de rendu &PDF; + Vous pouvez configurer le moteur de rendu &PDF; d'&okular; fondé sur Poppler en choisissant &PDF; dans la liste de la partie gauche de la fenêtre de configuration. La seule option configurable est la suivante. + + + + + Renforcer les lignes fines + + + Le dessin des lignes dans &okular; est implémenté en deux étapes : génération du chemin et remplissage du chemin. Lorsque la ligne dans le document original fait moins d'un pixel de large, cette implémentation en deux étapes peut poser problème. Pour ces lignes, le chemin est rempli avec une couleur qui dépend de l'épaisseur de la partie de la ligne à l'intérieur de la zone à dessiner. Si la partie de la ligne à l'intérieur de la zone à dessiner devient très petite, le contraste entre la forme et la couleur de fond peut devenir trop faible pour que la ligne soit reconnaissable. Les grilles composées de telles lignes peuvent apparaître peu esthétiques. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + La ligne fine (en rouge), son chemin (en pointillés) et les frontières des pixels (lignes pleines noires) + Ligne fine affichée en faible contraste + + + + + Pour renforcer l'apparence des lignes fines, &okular; implémente deux options. + La première option est Solide. Avec cette option, &okular; ajuste le chemin et la position de la ligne pour que le chemin et la ligne aient les mêmes frontière de pixels, c'est-à-dire qu'&okular; augmente la largeur des lignes fines à un pixel du périphérique de sortie. Ce mode est similaire à l'option Élargir les lignes fines dans Adobe Reader. Si cette option est activée, les lignes fines sont toujours élargies. + + + + + + + + Ligne fine avec le renforcement Solide + + + Ligne fine avec le renforcement Solide + + + + + La seconde option est Forme. Avec cette option, le chemin et la ligne sont ajustés aux frontières des pixels comme précédemment, mais l'intensité de la couleur de la ligne est ajustée proportionnellement à sa largeur. + + + + + + + + Ligne fine avec le renforcement Forme + + + Ligne fine avec une Forme renforcée + + + + + Par défaut, les lignes fines ne sont pas renforcées (option Non). + + + + + + + + Configurer &okular; + + Configuration générale + Vous pouvez configurer &okular; en utilisant l'option Configuration Configurer &okular;.... La boîte de dialogue de configuration est divisée en six sections. Ce chapitre décrit les options disponibles en détail. + + + Général + + + Accessibilité + + + Performances + + + Présentation + + + Annotations + + + Éditeur + + + + La boîte de dialogue de configuration + + + + + + La boîte de dialogue de configuration + + + + En fonction des moteurs de rendu actuellement installés, les éléments du menu Configuration Configurer les moteurs de rendu peuvent être activés. Cette boîte de dialogue de configuration particulière contient la configuration des différents moteurs qui peuvent être effectivement configurés. + + + Général + + + Afficher les barres de défilement + + Permet de choisir s'il faut afficher ou non les barres de défilement. + + + + Lier chaque vignette avec sa page + + Permet de choisir si les vignettes doivent suivre ou non la page en cours. + + + + Afficher les astuces et les messages d'informations + + Permet de choisir s'il faut afficher ou non les quelques messages d'informations au démarrage, lors du chargement de fichiers, &etc; + + + + Afficher le titre du document dans la barre de titre, si disponible + + Affiche ou non le titre du document courant dans la barre de titre de la fenêtre d'&okular;. Si aucune métadonnée de titre n'est trouvée dans le document, ou que cette option est désactivée, &okular; affichera le nom du fichier. + + + + Lorsque le titre du document n'est pas affiché + + Vous pouvez choisir l'une des deux options, Afficher uniquement le nom du fichier ou Afficher l'emplacement complet du fichier. + + + + Obéir aux limitations « DRM » + + Permet de choisir si &okular; doit obéir aux limitations DRM (Digital Rights Management). Ces limitations sont utilisées pour rendre impossibles certaines actions sur les documents &PDF;, comme en copier du contenu vers le presse-papier. Notez que, dans certaines configurations d'&okular;, cette option n'est pas disponible. + + + + Ouvrir les nouveaux fichiers dans des onglets + + Ouvre ou non les nouveaux documents dans des onglets. Les onglets sont désactivés par défaut. + Les raccourcis par défaut pour se déplacer entre les onglets sont &Ctrl;. (Onglet suivant) et &Ctrl;, (Onglet précédent). + + + + Recharger le document si le fichier est modifié + + Permet de choisir si les modifications des fichiers ouverts doivent être automatiquement vérifiées et les fichiers mis à jour si nécessaire. + + + + Afficher la boîte de dialogue de sélection du moteur de rendu + + Indique si &okular; doit demander à l'utilisateur quel moteur utiliser si plusieurs moteurs sont disponibles pour le fichier actuel. Si non coché, &okular; utilisera le moteur avec la priorité la plus haute. + + + + Colonnes d'aperçus + + Cette option représente le nombre de colonnes à utiliser en mode aperçu. + + + + Chevauchement pour les touches « Page précédente » / « Page suivante » + + Définit quelle proportion de la zone actuellement affichée sera encore visible lorsque les touches Page précédente / Page suivante seront pressées. + + + + Zoom par défaut + + Cette option spécifie le mode de zoom par défaut pour les fichiers qui n'ont encore jamais été ouverts. Pour les fichiers ayant déjà été ouverts, le dernier mode de zoom appliqué est utilisé. + + + + + + Accessibilité + + + Dessiner des bordures autour des liens + + Permet de choisir s'il faut dessiner une bordure autour des liens. + + + + Modifier les couleurs + + Active les options de changement des couleurs. + + + + Inverser les couleurs + + Inverse les couleurs de l'affichage, &cad; que les objets en noir seront affichés en blanc. + + + + Modifier la couleur du papier + + Change la couleur du papier, &cad; l'arrière plan du document. + + + + Modifier les couleurs sombres et claires + + Change pour des couleurs sombres et claires de votre choix, cela signifie que le noir ne sera plus affiché comme du noir mais comme votre couleur sombre choisie et de même pour le blanc avec la couleur claire. + + + + Convertir en noir et blanc + + Convertit le document en noir et blanc. Vous pouvez régler le seuil et le contraste. Augmenter le seuil en le déplaçant vers la droite donnera des gris plus clairs. + + + + + + Performances + + + Activer les effets de transparence + + Dessine les espaces de sélection et autre aspects graphiques spéciaux en utilisant des effets de transparence. Désactiver l'option, pour les dessiner en utilisant seulement des contours et des remplissages opaques, augmentera la vitesse de sélection. + + + + Utilisation de la mémoire + + &okular; peut atteindre de meilleures performances en personnalisant l'utilisation de la mémoire en fonction de votre système et de vos préférences. Plus vous lui permettrez d'utiliser de la mémoire, plus le programme sera rapide. Le profil « Normale » convient pour tous les systèmes, mais vous pouvez éviter qu'&okular; utilise plus de mémoire que nécessaire en sélectionnant le profil « Faible », ou le laisser utiliser la majeure partie de votre système en utilisant « Agressive ». Utilisez le profil « Gourmand » pour précharger toutes les pages sans risque de saturer la mémoire de votre système (seuls 50 % de la mémoire totale ou de la mémoire libre seront utilisés). + + + + Rendu + + En utilisant ce groupe d'options, vous pouvez améliorer le rendu du texte et des images dans &okular;. Le résultat dépendra du périphérique qui affichera le document. Les options Activer l'anticrénelage du texte et Activer l'anticrénelage pour les images permettent d'activer et de désactiver l'anticrénelage du texte et des images du document, respectivement. L'option Activer le lissage du texte sert à activer ou désactiver le lissage des polices. L'anticrénelage et le lissage modifient l'affichage du document. Vous pouvez les régler comme vous le désirez. + + + + + + Présentation + + + Avancer toutes les : + + Active le changement automatique des pages à intervalle de temps donné. + + + + Boucler après la dernière page + + Lorsque vous parcourez un document en mode présentation et allez dépasser la dernière page, la première page apparaîtra. + + + + Couleur de l'arrière plan + + La couleur qui remplira l'espace de l'écran non couvert par les pages lorsque vous serez en mode présentation. + + + + Couleur du crayon + + La couleur du crayon utilisé pour dessiner sur les pages en mode présentation. + + + + Pointeur de la souris + + Permet de choisir si la souris doit être toujours cachée, toujours visible ou cachée après un court temps d'inactivité. + + + + Afficher l'indicateur de progression + + Permet de choisir d'afficher un cercle de progression qui montre la page actuelle et le nombre de pages total dans le coin supérieur droit de l'écran à chaque changement de page. + + + + Afficher la page du sommaire + + Permet de choisir d'afficher une page de résumé au début de la présentation avec le titre, le nom de l'auteur et le nombre de pages du document. + + + + Activer les transitions + + Cochez ou décochez cette case pour activer ou désactiver les effets de transition entre les pages. + + + + Transition par défaut + + La transition entre les pages si le document n'en spécifie pas. Choisissez Transition aléatoire pour qu'&okular; choisisse au hasard l'une des transitions disponibles. + + + + Placement + + Dans cette section, vous pouvez choisir l'écran utilisé pour afficher la présentation. + Écran actuel correspond au même écran que la fenêtre d'&okular; qui démarre le mode présentation. + Écran par défaut est l'écran marqué par défaut dans la configuration de xinerama. + Écran 0, Écran 1, &etc; sont les écrans disponibles. + + + + + + Annotations + + La boîte de dialogue de configuration des annotations + + + + + + La boîte de dialogue de configuration des annotations + + + + + + Auteur + + L'auteur du contenu ajouté dans un document. Par défaut, il s'agit du nom figurant dans la page du Compte utilisateur et mot de passe du module Détails du compte de la &configurationDuSysteme;. + + + + Outils d'annotation + + Ce panneau permet de configurer votre barre d'outils d'annotation. + Il y a cinq boutons (Ajouter, Modifier, Supprimer, Déplacer vers le haut, Déplacer vers le bas) et une boîte de liste (qui contient la liste des contenus de la barre d'outils d'annotation actuelle) qui servent à configurer la barre d'outils. + Si vous avez besoin d'ajouter un bouton d'outil à la barre d'outils, cliquez sur le bouton Ajouter. Vous pouvez choisir le Nom, le Type et l'Apparence de l'outil créé. + + Rappelez-vous que les outils d'annotation d'&okular; sont hautement configurables. Par exemple, vous pouvez définir deux boutons pour le même outil, qui utiliseront des couleurs différentes. N'hésitez pas à expérimenter et à définir l'ensemble des boutons qui répondra parfaitement à vos besoins. + + Cliquez sur un élément de la liste puis sur le bouton correspondant sur la droite de la fenêtre pour modifier l'élément, l'enlever, le déplacer vers le haut ou vers le bas. Le raccourci clavier de l'outil (touches de 1 à 9) dépend de sa position dans la barre d'outils d'annotation. + + + + + + Éditeur + + + Éditeur + + Choisissez l'éditeur que vous voulez lancer lorsqu'&okular; veut ouvrir un fichier source. C'est le cas lorsque le document contient des références vers les différents points (souvent les numéros de ligne et de colonne) des sources depuis lesquelles il a été généré. Le format &DVI; accepte nativement les ajouts d'informations à propos des sources depuis lesquelles le document LaTeX a été généré. Un dispositif similaire, nommé pdfsync, existe pour les documents &PDF; et enregistre ces informations supplémentaires dans un fichier externe nommé en fonction du fichier &PDF; lui-même (par exemple : monDocument.pdfsync pour monDocument.pdf). + &okular; est fourni avec les paramètres préconfigurés pour les éditeurs suivants : &kate;, Kile, SciTE, Client &Emacs; et Client LyX. + + Pour utiliser la recherche inversée dans Kile, vous devez compiler &latex; avec la configuration Moderne. + + + + + Commande + + Il s'agit de la commande et de ses paramètres pour lancer l'éditeur sélectionné avec le fichier source du document réel. + Les champs seront remplis automatiquement si vous utilisez un des éditeurs préconfigurés. Sinon, choisissez Éditeur de texte personnalisé dans la liste déroulante Éditeur et utilisez la documentation de votre éditeur préféré pour trouver la commande correspondante. + Vous pouvez utiliser les mots réservés suivants : + + + %f - le nom du fichier + + + %l - la ligne à atteindre dans le fichier + + + %c - la colonne à atteindre dans le fichier + + + Si %f n'est pas spécifié, le nom du document sera ajouté à la commande. + + + + + + + Remerciements et licence + + + Copyright du programme : + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; mainteneur actuel + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it développeur de &kpdf; + + + + Copyright de la documentation : + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; auteur + Titus Laska titus.laska@gmx.de quelques mises à jour et ajouts + Pino Toscano pino@kde.org + + Traduction française par &CedricPasteur;, &YohannHamon;, &JoelGuelluy;, &LudovicGrossard; et &PeterPotrowl;. Relecture par &LudovicGrossard; +&underFDL; &underGPL; + + + Installation + + Comment obtenir &okular; +&install.intro.documentation; + + Compilation et installation + + Si vous lisez ceci depuis le ¢reAide;, &okular; est déjà installé et vous ne devez donc plus le faire. + &install.compile.documentation; + + &documentation.index; + + + + diff --git a/po/fr/docs/okular/mainwindow.png b/po/fr/docs/okular/mainwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..6d2e3720bf2c0c65869adf33f79d8ba304b4b23a GIT binary patch literal 102095 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 + +]> + + + + +Manuel utilisateur de KDE +YuriChornoivan Page « man » pour Okular. yurchor@ukr.net +09-03-2013 +Environnement de bureau K + + + +okular +1 + + + +okular +Un afficheur universel de document + + + +okular Qt-options KDE-options Options Okular URL + + + +Description +okular a pour objectif d'afficher des documents de différents formats. + + + +Options génériques + + + + +Affiche l'aide pour les options. + + + + + +Affiche les options spécifiques de Qt. + + + + + +Affiche les options spécifiques de KDE. + + + + + +Affiche toutes les options. + + + + + +Affiche les informations sur l'auteur. + + + + + +Affiche les informations de version. + + + + + +Affiche les informations de licence. + + + + + +Fin des options. + + + + + +Options pour Okular + + + + +Ouvre une page donnée dans le document. + + + + + +Démarre le document dans le mode de présentation. + + + + + +Démarrer avec la boîte de dialogue d'impression. + + + + + +Contrôle d'instance unique. + + + + + +Permet d'empêcher l'apparition de la fenêtre d'Okular après le démarrage. + + + + + +Arguments + + + + + Une adresse pour le document à ouvrir. Pour PDF, peut être donné comme nom-document#destination-nommée où destination-nommée est une destination particulière nommée et intégrée dans le document. + + + + + +Retour d'informations +Sur IRC, irc.freenode.net #okular ou par courriel, okular-devel@kde.org ou sur Internet <http://okular.kde.org/> + + + +Voir aussi +Des documentations utilisateur plus détaillées sont disponibles sur help:/okular (ou aussi ne saisissant cet URL dans &konqueror; ou lancer khelpcenter help:/okular). + + +Copyright +Copyright © 2002 par Wilco Greven et Christophe Devriese +Copyright © 2004-2005 par Enrico Ros +Copyright © 2005 par Piotr Szymanski +Copyright © 2004-2012 par Albert Astals Cid +Copyright © 2006-2009 par Pino Toscano +Licence : GNU General Public Version 2 <http://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/fr/docs/okular/presentation.png b/po/fr/docs/okular/presentation.png new file mode 100644 index 0000000000000000000000000000000000000000..b16cd789cf267ff3c542fb05a4832aaaa2746508 GIT binary patch literal 55325 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Èzu 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 ZtzZ+KAsgyGppXtoRY?n4eBb)@{{gieSv>#% literal 0 HcmV?d00001 diff --git a/po/fr/okular.po b/po/fr/okular.po new file mode 100644 index 0000000..716182f --- /dev/null +++ b/po/fr/okular.po @@ -0,0 +1,5852 @@ +# translation of okular.po to +# translation of kpdf.po to +# traduction de kpdf.po en Français +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# Cedric Pasteur , 2003. +# Matthieu Robin , 2004. +# Matthieu Robin , 2004, 2005, 2006. +# Nicolas Ternisien , 2004, 2005. +# Nicolas Ternisien , 2005, 2007. +# Mickael Sibelle , 2008. +# Sébastien Renard , 2008, 2009. +# Alain Rpnpif , 2008, 2009, 2010. +# Peter Potrowl , 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019. +# xavier , 2012, 2013, 2020, 2021. +# Sebastien Renard , 2014, 2015. +# Ludovic Grossard , 2014. +# Simon Depiets , 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2021-01-13 17:24+0100\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.12.2\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Cédric Pasteur, Nicolas Ternisien, Alain Rpnpif, Mickaël Sibelle, Peter " +"Potrowl, Simon Depiets, Xavier Besnard" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"cedric.pasteur@free.fr, nicolas.ternisien@gmail.com, rpnpif@free.fr, " +"kimael@gmail.com, peter.potrowl@gmail.com, sdepiets@gmail.com, xavier." +"besnard@neuf.fr" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un afficheur universel de documents" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Ancien mainteneur" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" +"Beaucoup de travail sur l'environnement de développement, les moteurs de " +"rendu pour les formats « ODT » et « FictionBook »" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Développeur" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "A créé Okular à partir du code provenant de KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Développeur pour KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Graphismes pour les annotations" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Outil de sélection de &tableau" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Amélioration des annotations" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Se déplacer à la page %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Ouvre un fichier externe" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Exécuter « %1 »..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Première page" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Page précédente" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Page suivante" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Dernière page" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Précédent" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Suivant" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Quitter" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Démarrer une présentation" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Terminer une présentation" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Trouver..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Se déplacer à la page..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Jouer un son..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Jouer un film..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Lire un film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Arrêter un film" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Mettre en pause un film" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Reprendre un film" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Sélection du moteur de rendu" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Plusieurs moteurs de rendu ont été trouvés pour le type « MIME » :
%1 (%2).

Veuillez choisir celui devant être utilisé :
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "La plupart des pages sont %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Portrait %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Paysage %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 pouces (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Suite de la recherche à partir du début du fichier" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Continuer la recherche à partir du bas du fichier ?" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Impossible de trouver un module externe capable de traiter le document " +"indiqué." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Supprimer des annotations" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Le document tente de lancer une application externe. Pour votre sécurité, " +"Okular interdit cela." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Aucune application trouvée pour ouvrir le fichier de type MIME « %1 »." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Impossible d'ouvrir un fichier temporaire" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "La conversion d'impression a échoué" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Le processus d'impression s'est arrêté brutalement" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Le processus d'impression n'a pas pu démarrer" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "L'impression dans un fichier a échoué" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "L'imprimante était dans un état non valable" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Impossible de trouver le fichier à imprimer" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Il n'y avait aucun fichier à imprimer" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Impossible de trouver un exécutable adapté à l'impression. Veuillez vérifier " +"que le binaire CUPS « lpr » est disponible" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "La taille de page pour l'impression est incorrecte" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Impossible d'ouvrir « %1 ». Le fichier n'existe pas." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titre" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Objet" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Description" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Auteur" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Créateur" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Producteur" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Droit d'auteur" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Pages" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Créé" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modifié" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Type MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Catégorie" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Mots-clés" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Emplacement du fichier" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Taille du fichier" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Taille de page" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Ajouter une annotation" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Supprimer une annotation" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Modifier les propriétés d'annotation" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Traduire une annotation" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "ajuster l'annotation" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Modifier du texte" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Modifier un contenu d'annotation" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Modifier un contenu de formulaire" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Modifier des choix de liste de formulaire" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Modifier la sélection de liste déroulante" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Modifier les états de boutons de formulaire" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Texte brut..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Texte « OpenDocument »" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Options d'impression" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajuster à la zone imprimable" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Ajuster à la page entière" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Mode de mise à l'échelle :" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Type d'alerte manquant" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Ne plus afficher ce message" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Source : %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Police par &défaut :" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rouge" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Orange" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Jaune" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Vert" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cyan" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Bleu" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Blanc" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Gris" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Noir" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Largeur %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Largeur de la ligne d'annotations (Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Couleur des annotations (Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" +"Couleur du remplissage des annotations (Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacité des annotations (Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Police des annotations (Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Ajouter l'annotation courante au menu rapide des annotations (Aucune " +"annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Contraindre le ration de profil à 1:1 ou l'angle de ligne à des pas de 15° " +"(Aucune annotation sélectionnée)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Paramètres avancés pour l'outil courant d'annotation (Aucune annotation " +"sélectionnée)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Largeur de la ligne d'annotations" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" +"Largeur de la ligne d'annotations (L'annotation courante ne possède aucune " +"largeur de ligne)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Couleur du texte des annotations" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Couleur de bordure des annotations" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Couleur des annotations" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Couleur du remplissage des annotations" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Couleur de remplissage des annotations (L'annotation courante ne possède " +"aucune couleur de remplissage)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Police des annotations" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" +"Police des annotations (L'annotation courante ne possède aucune police)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Contraindre à un angle de ligne à des pas de 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Contraindre le ration de profil à 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Contraindre le ration de profil à 1:1 ou l'angle de ligne à des pas de 15° " +"(Non pris en charge par l'annotation courante)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacité des annotations" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Ajouter l'annotation courante au menu rapide des annotations " + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Paramètres avancés pour l'outil courant d'annotation" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Couleur" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Couleur de remplissage" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparent" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Couleur personnalisée..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Les tampons insérés dans les documents « PDF » ne seront pas visibles dans " +"les lecteurs « PDF » autres que Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Fonctionnalité expérimentale" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Sélectionner une couleur" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotations" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Cacher" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Surligneur" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Souligné" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Gribouillis" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Barré" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Machine à écrire" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Note intégrée" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Note contextuelle" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Ligne à main levée" + +# unreviewed-context +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Ligne droite" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Flèche" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polygone" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Formes géométriques" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Tampon" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Annotations rapides" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Sélectionner un outil d'annotation à partir des annotations rapides" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Ajouter une annotation rapide" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Conserver actif" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Conserver l'outil d'annotation actif après utilisation" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Contraindre le ratio et l'angle des outils d'annotation" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Police" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Paramètres d'annotations" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Largeur de ligne" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacité" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Page %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotation" +msgstr[1] "%1 annotations" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Ouvrir une note épinglée" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Supprimer" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propriétés" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Enregi&strer « %1 »..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Apparence" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Général" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Auteur :" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Créé :" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modifié :" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Propriétés de la note épinglée" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Propriétés de la machine à écrire" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Propriétés de note en ligne" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Propriétés de ligne droite" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Propriétés de polygone" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Propriétés de forme géométrique" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Propriétés de balise de texte" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Propriétés de tampon" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Propriétés de ligne à main levée" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Propriétés de curseur" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Propriétés des pièces jointes" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Propriétés de son" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Propriétés de film" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Propriétés d'annotation" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modifié : %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Sélectionner un symbole de tampon personnalisé depuis un fichier" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Sélectionner un symbole de tampon personnalisé" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Fichiers d'icônes (*.ico *.png *.xpm *.svg " +"*.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Impossible de charger le fichier %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Fichier non valable" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Couleur :" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacité :" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icône :" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Commentaire" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Aide" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Insérer" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Clé" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nouveau paragraphe" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Note" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragraphe" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Police :" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "Couleur du &texte :" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Alignement :" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Gauche" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centré" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Droite" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Lar&geur de la bordure :" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Approuvé" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Tel quel" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidentiel" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Départemental" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Brouillon" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Expérimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Pour commentaires" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Pour version publique" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Non approuvé" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Non en version publique" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Vendu" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Top secret" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Signet" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informations" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"fonctionnalité expérimentale. Les tampons insérés dans les " +"documents PDF ne seront pas visibles dans les lecteurs PDF autres que Okular." +"" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Symbole de tampon :" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "Larg&eur :" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Début de ligne :" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Fin de ligne :" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Carré" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Cercle" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Losange" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Flèche ouverte" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Flèche fermée" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Aucun" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Bout" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Flèche ouverte vers la droite" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Flèche ferlée vers la droite" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barre oblique" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Longueur de ligne d'en-tête :" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Longueur des extensions de ligne d'en-tête :" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Activé" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Remplissage de la forme :" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Type :" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Surbrillance" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Gribouillis" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Souligné" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Barré" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectangle" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Symbole des pièces jointes :" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graphique" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Épingle" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Trombone" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Marqueur" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fichier" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "Non applicable" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Aucune description disponible." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nom :" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Description :" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Symbole de curseur :" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Aucun" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Fermer cette note" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Options" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Cette annotation peut contenir du code LaTeX.\n" +"Cliquer ici pour en effectuer le rendu." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Impossible de trouver l'exécutable LaTeX." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Le rendu LaTeX a échoué" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Impossible de trouver l'exécutable « dvipng »." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Un problème est survenu durant l'exécution de la commande « latex »." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Un problème est survenu durant l'exécution de la commande « dvipng »." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Un signet" +msgstr[1] "" +"%1\n" +"\n" +"%2 signets" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Signets" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Chercher…" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Uniquement le document courant" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Aller à ce signet" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Renommer un signet" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Supprimer un signet" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Ouvrir un document" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Supprimer des signets" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Version" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Numéro de série" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Émetteur" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Émis le :" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Expire le :" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Sujet" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Clé publique" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Utilisation de la clé" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propriété" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valeur" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Afficheur de certificat" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exporter..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Général" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Émis par" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nom commun (NC)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Adresse mail" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisation(O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Émis pour" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validité" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Empreintes numériques" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Empreinte SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Empreinte SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Détails" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Données du certificat :" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Où voulez-vous enregistrer ce certificat ?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Fichier de certificat (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Impossible d'exporter le certificat" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rouge" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Vert" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Bleu" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Jaune" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Noir" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Blanc" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Dessiner des bordures autour des &images" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Dessiner des bordures autour des &liens" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Modifier les &couleurs" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Attention : ces options peuvent affecter largement les performances " +"d'affichage." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mode de couleurs :" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverser les couleurs" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Modifier la couleur du papier" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Modifier les couleurs sombre et claire" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Convertir en noir et blanc" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Inverser la luminosité" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Inverser la luminance (Linéaire sRGB)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Inverser la luminance (Symétrique)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Décaler la teinte en positif" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Décaler la teinte en négatif" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Couleur du papier :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Couleur sombre :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Couleur claire :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Seuil :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contraste :" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Discours" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Moteur" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identité" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "&Auteur :" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Note : ces informations ne sont utilisées que pour les annotations. " +"Les informations sont enregistrées dans les documents annotés, elles seront " +"par conséquent transmises avec le document." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Outils rapides d'annotations" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Éditeur de texte personnalisé" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Client Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Client LyX" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Définit la commande d'un éditeur de texte personnalisé à lancer.
\n" +"Vous pouvez aussi saisir des chaînes de remplacement :\n" +"
    \n" +"  
  • %f - le nom de fichier
  • \n" +"  
  • %l - la ligne du fichier à atteindre
  • \n" +"  
  • %c - la colonne du fichier à atteindre
  • \n" +"
\n" +"Si l'option « %f » n'est pas indiquée, alors le nom du fichier est ajouté à " +"la commande spécifiée." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Éditeur" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Éditeur :" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Sélectionner l'éditeur à lancer lors de la tentative d'ouverture d'un " +"fichier source par Okular." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Commande :" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Apparence" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Utiliser un défilement doux" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Afficher les &barres de défilement" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Lier chaque vigne&ttes avec sa page" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Afficher les ast&uces et les messages d'informations" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Afficher le titre du document dans la barre de titre, si disponible" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Lorsque le titre du document n'est pas affiché :" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Afficher uniquement le nom du fichier" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Afficher l'emplacement complet du fichier" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Utiliser une couleur de fond personnalisée" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Fonctionnalités du programme" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Ouvrir les nouveaux fichiers dans des &onglets" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Basculer vers un onglet existant si le fichier est déjà ouvert" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obéir aux limitations « DRM »" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Recharger le document si le fichier est modifié" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Afficher la boîte de dialogue de sélection du moteur de rendu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Sens de lecture de droite à gauche" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Options d'affichage" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Colonnes d'aperçus :" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Définit quelle proportion de la zone actuelle d'affichage sera encore " +"visible lors d'un appui sur les touches « Page précédente » / « Page " +"suivante »." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" +"Chevauchement pour les touches « &Page précédente » / « Page suivante » :" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr " %" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Définit le mode de zoom par défaut pour les fichiers n'ayant jamais été " +"encore ouverts.\n" +"Pour les fichiers ayant déjà été ouverts, le dernier niveau de zoom utilisé " +"est appliqué." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Définit le mode de zoom par défaut pour les fichiers qui n'ayant jamais été " +"encore ouverts.\n" +"Pour les fichiers ayant déjà été ouverts, le dernier niveau de zoom utilisé " +"est appliqué." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Zoom par &défaut :" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100 %" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Adapter à la largeur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Adapter à la page" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Adapter automatiquement" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Maintient la quantité de mémoire utilisée aussi faible que possible. Ne ré-" +"utilise rien (pour les systèmes ayant peu de mémoire)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un bon compromis entre l'utilisation de la mémoire et le gain de rapidité. " +"Précharge la prochaine page et accélère les recherches (pour les systèmes " +"possédant généralement 2 Go de mémoire)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Conserve tout en mémoire. Précharge les prochaines pages. Accélère les " +"recherches (pour les systèmes possédant plus de 4 Go de mémoire)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Charge et conserve tout en mémoire. Précharge toutes les pages (utilisera au " +"maximum 50 % de la quantité totale de mémoire ou la mémoire disponible, " +"selon la valeur la plus élevée)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Utilisation du processeur" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Activer les effets de &transparence" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Utilisation de la mémoire" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Faib&le" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Normale (défaut)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Agressive" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Gourmande" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rendu" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Activer l'anticrénelage pour le texte" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Activer l'anticrénelage pour les images" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Activer le lissage du texte" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Écran actuel" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Écran par défaut" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Écran n° %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " seconde" +msgstr[1] " secondes" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigation" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avancer toutes les :" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Boucler après la dernière page" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navigation tactile" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Tapez du côté gauche / droit pour aller en arrière / en avant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Tapez n'importe où pour aller en avant" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Désactivée" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Couleur de l'arrière plan :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Pointeur de la souris :" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Caché après un délai" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Toujours visible" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Toujours caché" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Afficher l'indicateur de &progression" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Afficher la page du so&mmaire" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Activer les transitions" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transition par défaut :" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Rétrécir verticalement" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Rétrécir horizontalement" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Mettre en boîte" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Sortir d'une boîte" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dissoudre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Fondu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Scintillement en bas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Scintillement à droite" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Scintillement en bas et à droite" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transition aléatoire" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Remplacer" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Séparer horizontalement de l'intérieur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Séparer horizontalement de l'extérieur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Séparer verticalement de l'intérieur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Séparer verticalement de l'extérieur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Chiffonner en bas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Chiffonner à droite" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Chiffonner à gauche" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Chiffonner en haut" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Placement" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Écran :" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuration de l'outil de dessin" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Outil de dessin : %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Gomme" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nom :" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Type :" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Note épinglée" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Note intégrée" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Ligne à main levée" + +# unreviewed-context +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Ligne droite" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polygone" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Balise de texte" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forme géométrique" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Tampon" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Machine à écrire" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Outil de création d'annotations" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Outil de modification d'annotations" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "&Couleur :" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Largeur du pinceau :" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Créer un outil de dessin" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Modifier l'outil de dessin" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Inconnue" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Fichiers intégrés" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Affichage" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nom" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Description" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Taille" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Créé" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modifié" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Enregistrer &sous..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Affichage..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Impossible de charger le composant d'aperçu avant impression" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Aperçu avant impression" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Fermer" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "T&rouver :" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Texte à rechercher" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Suivant" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Se déplacer à la correspondance suivante" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Précédent" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Se déplacer à la correspondance suivante" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifier le comportement de recherche" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Sensible à la casse" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "À partir de la page actuelle" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Rechercher au fur et à mesure de la saisie" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Tous les fichiers" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Propriétés de la signature" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Ligne droite avec commentaire" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polygone avec commentaire" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Forme géométrique avec commentaire" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Forme géométrique" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Surbrillance avec commentaire" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Gribouillis avec commentaire" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Souligné avec commentaire" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Barré avec commentaire" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Barré" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Tampon avec commentaire" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Ligne à main levée avec commentaire" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Curseur" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Pièces jointes" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Son" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Écran" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Composant graphique" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Média riche" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Inconnu" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Auteur : %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Où voulez-vous enregistrer %1 ?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" +"Impossible d'ouvrir « %1 » en écriture. Le fichier n'a pas été enregistré." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Options de recherche" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Sensible à la casse" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expression rationnelle" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "Ch&ercher :" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Calques" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "sur" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Redimensionner" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoomer à 100 %" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Fai&re pivoter à droite" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Droite" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Fai&re pivoter à gauche" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Gauche" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientation originale" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "&Rogner l'affichage" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Réduire les &marges" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Rogner à la &sélection" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Adapter à la &largeur" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Adapter à la &page" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Adapter automatiquement" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Adapter la fe&nêtre à la page" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Mode d'&affichage" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Page &unique" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Pages en &face à face" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Pages en face-à-face (&Centrer la première page)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "A&perçu" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continu" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Utiliser la direction de lecture de droite à gauche" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Parcourir" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Active/désactive la modification des couleurs" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Sélection d'une zone" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Sélection de &texte" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Sélection de t&ableau" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Magnifier" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Outils de sélection" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Énoncer vocalement le document entier" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Énoncer vocalement la page actuelle" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Arrêter l'énonciation vocale" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Mettre en pose / Reprendre le discours" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Monter" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Descendre" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Faire défiler la page vers le haut" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Faire défiler la page vers le bas" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Afficher les formulaires" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "Chargement d'un document d'une page." +msgstr[1] "Chargement d'un document de %1 pages." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Texte (1 caractère)" +msgstr[1] "Texte (%1 caractères)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copier dans le presse-papier" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Copie interdite par « DRM »" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Énoncer vocalement le texte" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Image (%1 par %2 pixels)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Enregistrer vers un fichier..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Image [%1 x %2] copiée dans le presse-papier." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Enregistrer le fichier" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Images (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Fichier non enregistré." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Image [%1 x %2] copiée dans le fichier « %3 »." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copier du texte" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Aller à « %1 »" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Recherche de « %1 » avec" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configurer des raccourcis Web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Suivre ce lien" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Jouer ce son" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Arrêter le son" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copier l'adresse du lien" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Chercher « %1 » dans ce document" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Bienvenue" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "" +"Sélectionner une zone à redimensionner. Utiliser le clic droit pour réduire." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Cliquez pour voir la vue magnifiée." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dessiner un rectangle autour du texte ou de l'image à copier." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Sélectionner du texte" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Dessiner un rectangle autour du tableau puis cliquer près des bords pour le " +"diviser. Appuyez sur « Échap » pour effacer." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Dessiner un rectangle autour de la zone de la page à conserver visible." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nouvelle note de texte" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Texte de la nouvelle note :" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Créer un signet avec une annotation" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Insérer un nom personnalisé à l'annotation :" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Dessiner une ellipse (faites la glisser pour sélectionner une zone)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Mettre du texte en surbrillance" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Dessiner une ligne à main levée" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "" +"Annotation de texte en ligne (faites le glisser pour sélectionner une zone)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Insérer une note épinglée" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Dessiner un polygone (pour le fermer, cliquez sur le premier point)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Dessiner un rectangle" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Gribouiller du texte" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Poser un symbole de tampon" + +# unreviewed-context +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Dessiner une ligne droite" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Barrer du texte" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Souligner du texte" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" +"Annotation machine à écrire (faites le glisser pour sélectionner une zone)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Surligneur" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Ajouter une annotation favorite" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nom d'annotation personnalisé :" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fichier" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Configuration" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Aide" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientation" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Signets" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barre de l'afficheur" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Vignettes" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotations" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Ce document contient des annotations ou des données de formulaire qui ont " +"été enregistrées en interne par une version précédente d'Okular. Le stockage " +"interne n'est plus géré.
Veuillez les enregistrer vers un " +"fichier ou les déplacer si vous voulez continuer à éditer ce document." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files.
Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Ce document contient des fichiers intégrés. Cliquer ici pour les afficher ou sélectionnez « Fichier » / " +"« Fichiers intégrés »." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Précédente" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Aller à la page précédente" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Se déplace sur la page précédente du document" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Suivante" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avance à la page suivante" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Se déplace sur la page suivante du document" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Début du document" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Se déplace au début du document" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Fin du document" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Se déplace à la fin du document" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Renommer le signet actuel" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Signet précédent" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Aller au signet précédent" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Signet suivant" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Aller au signet suivant" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configurer Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configurer l'afficheur..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configurer les moteurs d'affichage..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configurer les moteurs de rendu..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "À propos des moteurs de rendu..." + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Rechar&ger" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Recharger le document actuel à partir du disque." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "&Fermer la barre de recherche" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Numéro de page" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Sélectionner tout le texte de la page actuelle" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Aff&icher la barre latérale" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Afficher la barre des &pages" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Afficher le panneau des &Signatures" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Fichi&ers intégrés" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xporter comme" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Partager" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&résentation" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Ouvrir le dossier con&tenant" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importer du format « PostScript » comme du « PDF »..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obtenir des livres à partir d'Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Bascule en mode « Écran noir »" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Effacer les dessins" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configurer les annotations..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Lecture/Pause de la présentation" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Impossible d'ouvrir « %1 » (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Le chargement de %1 a été annulé." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Impossible d'ouvrir « %1 ». Raison : %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configurer les moteurs de rendu de l'afficheur" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configurer les moteurs de rendu" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Impossible de trouver le programme « ps2pdf ». Par conséquent, il est " +"impossible pour Okular de l'utiliser pour importer des fichiers « PS »." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "Impossible de trouver le programme « ps2pdf »" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Fichiers PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" +"Importation de fichier du format « PS » vers « PDF » (ceci peut prendre un " +"certain temps)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Veuillez saisir le mot de passe pour ouvrir le document :" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Mot de passe incorrect, veuillez réessayer :" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Mot de passe du document" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Ce document utilise des formulaires « XFA » qui ne sont pas encore pris " +"en charge." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Ce document contient des formulaires. Cliquer sur le bouton pour interagir " +"avec eux ou utiliser « Affichage » / « Afficher les formulaires »." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Toutes les fonctionnalités interactives et de modification pour ce document " +"sont désactivées. Veuillez enregistrer une copie et rouvrir pour modifier ce " +"document." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Ce document est signé numériquement." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Ce document est signé numériquement. Il y a eu des modifications depuis la " +"dernière signature." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Ce document est signé numériquement. Certaines de ses signatures ne peuvent " +"être correctement validées." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Ce document souhaite être affiché en plein écran.\n" +"Quitter le mode normal et entrer dans le mode présentation ?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Demander avant de changer de mode d'affichage" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Entrer en mode « Présentation »" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Refuser la demande" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Impossible d'ouvrir « %1 ». %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Il y a des changements non enregistrés et le fichier « %1 » a été modifié " +"par un autre programme. Vos changements seront perdus car le fichier ne peut " +"plus être enregistré.
Voulez-vous vraiment recharger le fichier ?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Fichier modifié" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continuer le rechargement" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interrompre le rechargement" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Il y a des changements non enregistrés et le fichier « %1 » a été modifié " +"par un autre programme. Vos changements seront perdus car le fichier ne peut " +"plus être enregistré.
Voulez-vous vraiment fermer le fichier ?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continuer la fermeture" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Annuler la fermeture" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Voulez-vous enregistrer vos modifications dans « %1 » ou les annuler ?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Fermer le document" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Ce lien pointe vers une action de fermeture du document, ne fonctionnant pas " +"lors de l'utilisation de l'afficheur intégré." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Ce lien pointe vers une action de fermeture du document, ne fonctionnant pas " +"lors de l'utilisation de l'afficheur intégré." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Rechargement du document..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contenus" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signatures" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Aller à la page" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Page :" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Saisissez le nouveau nom du signet :" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Renommer ce signet" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Supprimer ce signet" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Enregistrer sous" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Le fichier « %1 » a été modifié par une autre application, ce qui signifie " +"qu'il ne peut plus être enregistré." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Le document courant est protégé par un mot de passe.
Pour enregistrer, " +"le fichier doit être rechargé. Le mot de passe vous sera demandé et votre " +"historique d'annulation sera perdu.
Voulez-vous continuer." + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Enregistrer - Avertissement" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Impossible d'ouvrir le fichier temporaire pour enregistrement." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Après l'enregistrement, le format de document nécessite que le fichier soit " +"rechargé. Votre historique d'annulation sera perdu.
Voulez-vous " +"continuer ?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Impossible d'enregistrer le fichier dans « %1 ». Veuillez essayer de " +"l'enregistrer dans un autre emplacement." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contenus de formulaire remplis" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Annotations de l'utilisateur" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Vous êtes sur le point d'enregistrer des modifications, mais le format " +"courant ne gère pas l'enregistrement des éléments suivants. Veuillez " +"utiliser le format Archive de document Okular pour les conserver." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Avertissement" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Enregistrer comme archive de document Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Vous êtes sur le point d'enregistrer des modifications, mais le format " +"courant ne gère pas l'enregistrement des éléments suivants. Veuillez " +"utiliser le format Archive de document Okular pour les conserver. " +"Cliquez sur Continuer pour enregistrer le document et perdre ces " +"éléments." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Vous êtes sur le point d'enregistrer des modifications, mais le format " +"courant ne gère pas l'enregistrement des éléments suivants. Veuillez " +"utiliser le format Archive de document Okular pour les conserver. " +"Cliquez sur Continuer pour enregistrer le document. Vous perdrez ces " +"éléments et votre historique d'annulation." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continuer" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continuer en perdant les modifications" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Impossible d'enregistrer le fichier dans « %1 ». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Il est impossible à Okular de copier %1 à l'emplacement indiqué.\n" +"\n" +"Le document n'existe plus." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Impossible d'enregistrer le fichier dans « %1 ». Erreur « %2 ». Veuillez " +"essayer de l'enregistrer dans un autre emplacement." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Développer toute la sélection" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Réduire toute la sélection" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Tout développer" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Tout réduire" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Ajouter un signet" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Outils" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Imprimer" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "L'impression de ce document n'est pas autorisée." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Impossible d'imprimer le document. Erreur inconnue. Veuillez rapporter ce " +"bogue à « bugs.kde.org »" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Impossible d'imprimer le document. L'erreur détaillée est « %1 ». Veuillez " +"rapporter ce bogue à « bugs.kde.org »" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Aller à l'emplacement précédent" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Aller à l'emplacement suivant" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"
%1.
" +msgstr "" +"Erreur de fichier ! Impossible de créer le fichier " +"temporaire %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Erreur de fichier ! Impossible d'ouvrir le fichier " +"%1 pour décompression. Le fichier ne sera pas " +"chargé." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Cette erreur arrive habituellement si vous n'avez pas les droits d'accès " +"en lecture sur le fichier. Vous pouvez vérifier le propriétaire, le groupe " +"et les droits d'accès en faisant un clic droit sur le fichier dans le " +"gestionnaire de fichiers Dolphin et ensuite en sélectionnant l'option " +"« Propriétés » puis l'onglet « Permissions » dans la fenêtre alors ouverte. " +"" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Erreur de fichier ! Impossible de décompresser le " +"fichier %1. Le fichier ne sera pas chargé." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Cette erreur arrive habituellement si le fichier est corrompu. Si vous " +"voulez le décompresser malgré tout, essayez de le faire manuellement avec " +"des outils en ligne de commandes." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Aucun signet" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Un problème est survenu lors du partage du document : %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Partager" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Document partagé avec succès" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Vous pouvez trouver le document partagé sur : %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Édition" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Affichage" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Aller" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Ou&tils" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barre principale d'outils" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barre d'outils d'annotation" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Options générales" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibilité" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Accessibilité, aides à la lecture" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Performances" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Optimisation des performances" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configurer l'afficheur" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Présentation" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Options pour le mode de présentation" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Options d'annotations" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Options de l'éditeur" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Trouver le suivant" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "Présentation - %1" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Changer d'écran" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Écran n° %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Sortir du mode « Présentation »" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titre : %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Pages : %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Cliquer pour commencer" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pause" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Lecture" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Il existe deux façons de quitter le mode « Présentation ». Vous pouvez soit " +"appuyer sur la touche « Échap », soit utiliser le bouton de fermeture " +"apparaissant lorsque la souris approche du bord en haut à gauche. Bien sûr, " +"vous êtes toujours en mesure de parcourir les fenêtres ouvertes (par défaut " +"« Alt » + « Tab »)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Fourniture d'une présentation" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Fichier inconnu" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Propriétés de %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1 :" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Polices" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Lecture des informations de police..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Tailles de &page" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extraire une police" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "PK de TeX" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtuel" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Métrique de police de TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX géré comme FreeType" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Inconnu" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Intégré (sous-ensemble)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Complètement intégré" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Non" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Oui (sous-ensemble)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Oui" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (remplacée par %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[Non applicable]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Police inconnue" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Intégré : %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nom" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Type" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fichier" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Page" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Taille" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Aperçu des révisions" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Où voulez-vous enregistrer cette révision ?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Impossible d'enregistrer le fichier %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Impossible d'afficher la révision." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Saisissez au moins 3 lettres pour filtrer les pages" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Sensible à la casse" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Correspondre à la phrase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Correspondre à tous les mots" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Correspondre à l'un des mots" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Options de filtre" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Aucune annotation

Pour créer de nouvelles " +"annotations, veuillez appuyer sur « F6 » ou sélectionnez Outils  " +"Annotations à partir du menu.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Grouper par page" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Grouper par auteur" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Afficher les annotations uniquement pour la page actuelle" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Déplier toutes les éléments" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Replier tous les éléments" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "La signature est valable au niveau du chiffrement." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "La signature est non valable au niveau du chiffrement." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Les signatures ne correspondent pas." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "La structure CMS/PKCS7 de la signature est malformée." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "La signature demandée n'est pas présente dans le document." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Impossible de vérifier la signature." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Le certificat est de confiance." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "L'émetteur du certificat n'est pas de confiance." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "L'autorité de certification est inconnue." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Le certificat a été révoqué." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Le certificat a expiré." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Le certificat n'a pas encore été vérifié." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Erreur inconnue avec ce certificat ou données corrompues." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algorithme inconnu" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Type inconnu" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Signature numérique" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non-répudiation" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Clés de chiffrement" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Déchiffrer les clés" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Accord de clé" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Certificat de signature" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Signer en CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Chiffrer uniquement" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Aucun usage spécifié" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rév. %1: Signé par %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Moment de la signature : %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Non disponible" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Raison : %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Champ : %1 en page %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propriétés" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Le document n'a pas été modifié depuis qu'il a été signé." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"La révision de ce document couverte par la signature n'a pas été modifiée ;\n" +"cependant, des modifications ont été apportées ultérieurement au document." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Le document a été modifié d'une manière non permise par un signataire " +"précédent." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Impossible de mener à bien la vérification d'intégrité." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "État de validité" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validité de la signature :" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modifications du document ;" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Informations supplémentaires" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signé par :" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Moment de la signature :" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Raison :" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Emplacement :" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Version du document" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Révision de document %1 sur %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Voir la version signée..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Voir le certificat..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Afficher uniquement les pages en signet" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Lecture" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pause" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Arrêt" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Ajouter..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "Modifi&er..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "Supprime&r" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Déplacer vers le ha&ut" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "&Déplacer vers le bas" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Outil de dessin par défaut n°%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" +"Il existe déjà un outil avec ce nom. Veuillez utiliser un nom différent." + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nom en doublon" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Page du document à afficher" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Démarre ce document en mode « Présentation »" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Commencer avec la boîte de dialogue d'impression" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" +"Lancer avec la boîte de dialogue d'impression et quitter après l'impression" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Commande de « Session unique »" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Ne pas ouvrir la fenêtre" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Chercher une chaîne dans le texte" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Documents à ouvrir. Utiliser « - » pour lire depuis l'entrée standard." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Erreur : impossible d'ouvrir plus d'un document avec l'option « --unique »" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Erreur : impossible d'ouvrir plus d'un document avec l'option « --" +"presentation »" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Erreur : impossible d'ouvrir plus d'un document avec l'option « --print »" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Erreur : impossible d'ouvrir plus d'un document avec l'option « --page »" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Erreur : impossible d'ouvrir plus d'un document avec l'option « --find »" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Impossible de trouver le composant de Okular : %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Une instance de Okular est déjà en cours d'exécution. Cette instance ne sera " +"plus la seule." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Impossible de trouver le composant de Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Cliquer pour ouvrir un fichier\n" +"Cliquer et maintenir pour ouvrir un fichier récent" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Cliquer pour ouvrir un fichier ou Cliquer et maintenir pour " +"sélectionner un fichier récent" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Onglet suivant" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Onglet précédent" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Annuler la fermeture de l'onglet" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Tous les fichiers (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Tous les fichiers pris en charge (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Ouvrir un document" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirmer la fermeture" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Fermer les onglets" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"Vous êtes sur le point de fermer %1 onglets. Voulez-vous vraiment continuer ?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Me prévenir lorsque je tente de fermer plusieurs onglets" + +#~ msgid "Reviews" +#~ msgstr "Révisions" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Cacher les formulaires" + +#~ msgid "Expired" +#~ msgstr "Expiré" + +#~ msgid "&Review" +#~ msgstr "&Révision" + +#~ msgid "Annotations author" +#~ msgstr "Auteur des annotations" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Veuillez insérer vos noms et vos initiales :" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Afficher la barre de &navigation" + +#~ msgid "Show Text" +#~ msgstr "Afficher le texte" + +#~ msgid "Small Icons" +#~ msgstr "Petites icônes" + +#~ msgid "Normal Icons" +#~ msgstr "Icônes normales" + +#~ msgid "Large Icons" +#~ msgstr "Grandes icônes" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Cliquer pour utiliser l'outil actuel de sélection \n" +#~ "Cliquer sur la flèche pour choisir un autre outil de sélection" + +#~ msgid "Created: %1" +#~ msgstr "Créé : %1" + +#~ msgid "Line Extensions" +#~ msgstr "Extensions de lignes" + +#~ msgid "Style" +#~ msgstr "Style" + +#~ msgid "&Size:" +#~ msgstr "&Taille :" + +#~ msgid "Inner color:" +#~ msgstr "Couleur de remplissage :" + +#~ msgid "Name: %1" +#~ msgstr "Nom : %1" + +#~ msgid "Size: %1" +#~ msgstr "Taille : %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Outil de &navigation" + +#~ msgid "&Zoom Tool" +#~ msgstr "Outil de &redimensionnement" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Redimensionner" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Sélectionner" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Outil de sélection de &texte" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Outil de &sélection de tableau" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Magnifier" + +#~ msgid "Only for PDF documents" +#~ msgstr "Seulement pour les documents PDF" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Aucun" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Ce document a demandé à être lancé en mode « Présentation ».\n" +#~ "Voulez-vous l'autoriser ?" + +#~ msgid "Presentation Mode" +#~ msgstr "Mode « Présentation »" + +#~ msgid "Allow" +#~ msgstr "Autoriser" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Autoriser le mode « Présentation »" + +#~ msgid "Do Not Allow" +#~ msgstr "Ne pas autoriser" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Ne pas autoriser le mode « Présentation »" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Vos modifications d'annotations ne seront pas enregistrées " +#~ "automatiquement. Utilisez « Fichier » / « Enregistrer sous... »\n" +#~ "ou vos modifications seront perdues lors de la fermeture du document." + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Vos annotations sont enregistrées par Okular de manière interne.\n" +#~ "Vous pouvez exporter le document annoté en utilisant « Fichier » / " +#~ "« Exporter comme » / « Archive de document »" + +#~ msgid "Save &Copy As..." +#~ msgstr "Enregistrer une &copie sous..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Vos annotations ne seront pas exportées par Okular.\n" +#~ "Vous pouvez exporter le document annoté en utilisant « Fichier » / " +#~ "« Exporter comme » / « Archive de document »" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "La fin du document a été atteinte.\n" +#~ "Continuer à partir du début ?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Le début du document a été atteint.\n" +#~ "Continuer à partir du bas ?" + +#~ msgid "Current maintainer" +#~ msgstr "Mainteneur actuel" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sec." + +#~ msgid "Pencil color:" +#~ msgstr "Couleur du crayon :" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "Paysage A0 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "Portrait A0 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "Paysage A1 DIN/ISO " + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "Portrait A1 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "Portrait A2 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "Paysage A2 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "Paysage A3 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "Portrait A3 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "Paysage A4 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "Portrait A4 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "Paysage A5 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "Portrait A5 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "Paysage A6 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "Portrait A6 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "Paysage A7 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "Portrait A7 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "Paysage A8 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "Portrait A8 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "Paysage A9 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "Portrait A9 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "Paysage B0 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "Portrait B0 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "Paysage B1 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "Portrait B1 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "Paysage B2 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "Portrait B2 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "Paysage B3 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "Portrait B3 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "Paysage B4 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "Portrait B4 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "Paysage B5 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "Portrait B5 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "Paysage B6 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "Portrait B6 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "Paysage B7 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "Portrait B7 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "Paysage B8 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "Portrait B8 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "Paysage B9 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "Portrait B9 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "Paysage B10 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "Portrait B10 DIN / ISO" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "Paysage Lettre" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "Portrait Lettre" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "Paysage Légal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "Portrait Légal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "Paysage Exécutive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "Portrait Exécutive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "Paysage Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "Portrait Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "Paysage DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "Portrait DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "Paysage Folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "Portrait Folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "Livre" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "Tabloïde" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "Format de papier inconnu en mode « Paysage »" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "Format de papier inconnu en mode « Portrait »" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Activer / Désactiver le mode « Dessin »" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Échec du lancement du service « Jovie » de synthèse vocale : %1" + +#~ msgid "Search Columns" +#~ msgstr "Colonnes de recherche" + +#~ msgid "All Visible Columns" +#~ msgstr "Toutes les colonnes visibles" + +#~ msgid "No document opened." +#~ msgstr "Aucun document ouvert." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Impossible d'ouvrir plus d'un document dans l'instance unique de Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Aucune correspondance trouvée pour « %1 »." + +#~ msgid "Search in progress..." +#~ msgstr "Recherche en cours..." + +#~ msgid "Searching for %1" +#~ msgstr "Recherche de %1" + +#~ msgid "Identity Settings" +#~ msgstr "Réglage de l'identité" + +#~ msgid "Highlight Properties" +#~ msgstr "Propriétés de surbrillance" + +#~ msgid "Ink Properties" +#~ msgstr "Propriétés d'encre" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Annotation de texte" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Encre verte" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Surbrillance jaune" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Surbrillance jaune" + +# unreviewed-context +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Ligne jaune fine" + +#~ msgid "Black Underlining" +#~ msgstr "Souligné noir" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Souligner le texte avec une ligne noire" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Ellipse cyan" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Une ellipse cyan" + +#~ msgid "Ink" +#~ msgstr "Encre" + +#~ msgid "Enable &background generation" +#~ msgstr "Activer la génération en arrière-&plan" + +#~ msgid "Reset Forms" +#~ msgstr "Réinitialiser les formulaires" + +#~ msgid "latex failed." +#~ msgstr "LaTeX a échoué." + +#~ msgid "dvipng failed." +#~ msgstr "dvipng a échoué." + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Se place sur la première page du document" + +#~ msgid "You must set this name:" +#~ msgstr "Vous devez mettre ce nom :" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Alterne entre l'emplacement du fichier et son titre" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1 :" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1 :" diff --git a/po/fr/okular_chm.po b/po/fr/okular_chm.po new file mode 100644 index 0000000..c728240 --- /dev/null +++ b/po/fr/okular_chm.po @@ -0,0 +1,68 @@ +# translation of okular_chm.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mickael Sibelle , 2008. +# xavier , 2013. +# Simon Depiets , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-04-26 14:54+0800\n" +"Last-Translator: Simon Depiets \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.07.70\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mickaël Sibelle, Simon Depiets" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kimael@gmail.com, sdepiets@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Encodage non pris en charge" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"L'encodage de ce livre électronique n'est pas encore pris en charge. " +"Veuillez signaler un bogue sur https://bugs.kde.org pour demander sa prise " +"en charge" + +#~ msgid "CHM Backend" +#~ msgstr "Moteur CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Un moteur de rendu pour fichiers d'aide de Microsoft Windows." + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/fr/okular_comicbook.po b/po/fr/okular_comicbook.po new file mode 100644 index 0000000..b66e3dc --- /dev/null +++ b/po/fr/okular_comicbook.po @@ -0,0 +1,67 @@ +# translation of okular_comicbook.po to french +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Bieuzent Cyrille , 2008. +# Cyrille Bieuzent , 2009. +# xavier , 2013. +# Simon Depiets , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-12-05 15:06+0800\n" +"Last-Translator: Simon Depiets \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 2.0\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Bieuzent Cyrille" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "bieuzent@gmail.com" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Impossible d'ouvrir le document car les programmes « unrar » et " +"« unarchiver » sont absents." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"La version du programme « unrar » sur votre système est inutilisable pour " +"ouvrir des BD." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Format « ComicBook » inconnu" + +#~ msgid "ComicBook Backend" +#~ msgstr "Moteur pour « ComicBook »" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un moteur de rendu pour de multiples formats de BD" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fr/okular_djvu.po b/po/fr/okular_djvu.po new file mode 100644 index 0000000..56ca75f --- /dev/null +++ b/po/fr/okular_djvu.po @@ -0,0 +1,141 @@ +# translation of okular_djvu.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Joëlle Cornavin , 2009. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-06-26 11:20+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Boeglin, Joëlle Cornavin" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "thomas.boeglin@gmail.com, jcornavi@club-internet.fr" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Éditeur" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Diffuseur" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volume" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Type de document" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Inconnu" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Fichiers de composants" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Inconnu" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Page unique" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Intégré" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirect" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Intégré (ancien)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexé (ancien)" + +#~ msgid "DjVu Backend" +#~ msgstr "Moteur DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Moteur DjVu utilisant « Djvulibre »." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Inconnu" diff --git a/po/fr/okular_dvi.po b/po/fr/okular_dvi.po new file mode 100644 index 0000000..497414e --- /dev/null +++ b/po/fr/okular_dvi.po @@ -0,0 +1,815 @@ +# translation of okular_dvi.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mickael Sibelle , 2008. +# Sébastien Renard , 2008. +# Alain Rpnpif , 2008. +# Peter Potrowl , 2013, 2014. +# xavier , 2013, 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2021-01-13 17:30+0100\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.12.0\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Alain Rpnpif, Mickaël Sibelle, Peter Potrowl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "rpnpif@free.fr, kimael@gmail.com, peter.potrowl@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular ne peut pas trouver le programme dvipdfm sur votre " +"ordinateur. Ce programme est essentiel pour le travail de la fonction " +"« Exporter ». Vous pouvez cependant convertir le fichier « DVI » en « PDF » " +"en utilisant la fonction « Imprimer » d'Okular. Cela produira souvent des " +"documents s'imprimant bien mais de qualité inférieure lorsque affichés par " +"« Acrobat Reader ». Il peut être intéressant de mettre à jour votre " +"distribution « TeX » vers une version plus récente incluant le programme " +"dvipdfm

Astuce pour l'administrateur du système qui serait " +"perplexe : Okular utilise la variable d'environnement « PATH » lors de " +"recherche de programmes.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Le programme externe « dvipdfm », servant à l'exportation du fichier, a " +"rapporté une erreur. Vous pourriez souhaiter regarder la boîte de " +"dialogue d'informations du document que vous trouverez dans le menu " +"« Fichier » pour vous fournir un rapport d'erreur précis." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Ce fichier « DVI » se réfère à des fichiers graphiques externes qui ne " +"sont pas au format « PostScript » et ne peuvent pas être traités par le " +"programme dvips que Okular utilise pour imprimer ou exporter vers " +"des fichiers « PostScript ». La fonctionnalité que vous demandez est donc " +"indisponible dans cette version d'Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular ne trouve pas le programme dvips sur votre " +"ordinateur. Ce programme est essentiel pour que l'exportation fonctionne.

Astuce pour l'administrateur de système qui serait perplexe : Okular " +"utilise la variable d'environnement « PATH » lors de recherche de programmes." +"

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Le programme externe « dvips », utilisé pour l'exportation du fichier " +"signale une erreur. Vous pourriez souhaiter voir la boîte de " +"dialogue d'informations du document que vous trouverez dans le menu " +"« Fichier » pour un rapport d'erreur précis." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Le fichier « DVI » ne commence pas avec le préambule." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"Le fichier « DVI » contient la mauvaise version de messages de sortie de " +"« DVI » pour ce programme. Astuce : si vous utilisez le système de " +"composition de documents « Omega », vous devez utiliser un programme spécial " +"comme « oxdvi »." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"Le fichier « DVI » est fortement corrompu. Okular n'a pas été capable de " +"trouver le préambule." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Le préambule ne commence pas par la commande « POST »." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Le préambule contenait une commande autre que « FNTDEF »." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La page %1 ne débute pas par la commande « BOP »." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Impossible de démarrer le programme externe pdf2ps. " +"Le fichier PDF %1 ne peut donc pas être converti en « PostScript ». Certains " +"éléments graphiques de votre document ne pourront donc pas être affichés.

Cause possible : Le programme pdf2ps n'est peut-" +"être pas installé sur votre système ou il est impossible de le trouver à " +"l'emplacement ci-dessous.

Ce que vous pouvez faire : Le " +"programme pdf2ps est normalement inclus dans des " +"distributions du système d'interpréteur de PostScript nommé « ghostscript ». " +"Si « ghostscript » n'est pas installé sur votre système, vous pourriez " +"l'installer maintenant. Si vous êtes sûr que « ghostscript » est installé, " +"veuillez essayer d'utiliser pdf2ps à partir de la ligne de " +"commandes pour vérifier qu'il fonctionne vraiment.

PATH : " +"%2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Impossible de convertir le fichier « PDF » %1 en « PostScript ». En " +"conséquence, certains éléments graphiques de votre document ne pourront être " +"affichés.

Cause possible : Le fichier %1 peut être cassé ou " +"peut ne pas être un fichier « PDF » du tout. Voici la sortie du programme " +"pdf2ps utilisé par Okular :

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Fichier corrompu. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"Tous les fichiers PostScript n'ont pas pu être intégrés dans votre document. " +"%1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"Tous les fichiers PostScript externes ont été intégrés dans votre document." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Le fichier spécifié « %1 » n'existe pas." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Vous avez demandé à Okular de localiser le fichier DVI qui correspond à la " +"ligne %1 dans le fichier Tex %2. Cependant, il semble que le fichier DVI ne " +"contient pas l'information nécessaire à propos du fichier source." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular n'a pas pu localiser le fichier DVI correspondant à la ligne %1 dans " +"le fichier Tex %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "Le code « DVI » définit un caractère d'une police inconnue." + +# unreviewed-context +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"Le code « DVI » se réfère à la police n° %1 qui n'a pas été précédemment " +"définie." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "" +"La pile de données n'était pas vide quand la commande « EOP » a été " +"rencontrée." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "" +"La pile de données n'était pas vide quand la commande « POP » a été " +"rencontrée." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"Le code « DVI » se réfère à une police qui n'a pas été précédemment définie." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Une commande illégale a été rencontrée." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Le code de commande %1 qui a été rencontré est inconnu." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Intégration de %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Page %1 : impossible de convertir en « PostScript » le fichier « PDF » " +"%2.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Page %1 : impossible de trouver le fichier « PostScript » %2.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Impossible d'analyser la donnée de taille de papier « %1 »." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular n'a pas pu trouver tous les fichiers de police nécessaires à " +"l'affichage du fichier « DVI » actuel. Votre document peut être illisible.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

L'exécution de kpsewhich s'est mal déroulée. Par " +"conséquent, certains fichiers de polices n'ont pas pu être trouvés et votre " +"document peut être illisible.
Raisons possibles : le programme " +"kpsewhich n'est peut-être pas installé sur votre système, ou il ne " +"se trouve pas dans l'emplacement de recherche actuel.

PATH:" +" %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"La génération de police par kpsewhich a été annulée (code de " +"fermeture %1, erreur %2). En conséquence, il est probable que certaines " +"polices soient manquantes et que votre document soit illisible." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Génération en cours de %1 à %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Générateur / Date" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Impossible de trouver un fichier de police" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "portrait" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "paysage" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La version de « Ghostview » installée sur cet ordinateur ne contient aucun " +"des pilotes de système de « Ghostview » connus par Okular. La prise en " +"charge de « PostScript » a donc été désactivée dans Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Okular utilise en interne le programme « Ghostview » pour l'affichage " +"des graphiques « PostScript » inclus dans ce fichier « DVI ». Le programme " +"« Ghostview » est généralement capable de produire une sortie dans " +"différents formats. Les sous-programmes qu'il utilise pour ces tâches sont " +"appelés pilotes de système. Il y a un pilote de système par format que le " +"programme « Ghostview » est capable d'écrire. Chaque version de " +"« Ghostview » possède souvent son propre jeu de pilotes de système " +"disponibles. Il semble que la version de « Ghostview » installée sur cet " +"ordinateur ne contienne aucun des pilotes de système connus " +"par Okular.

Il semble malheureusement qu'une installation normale de " +"Ghostview ne contiendrait pas ces pilotes. Cette erreur peut donc pointer " +"une erreur sérieuse de configuration du Ghostview installé sur votre " +"ordinateur.

Si vous voulez corriger les problèmes de Ghostview, vous " +"pouvez utiliser la commande gs --help pour afficher la " +"liste des pilotes de système contenus dans Ghostview. Entre autres, Okular " +"peut utiliser les pilotes « png256 », « jpeg » et « pnm ». Notez que Okular " +"doit être redémarré pour réactiver la prise en charge de PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"Cela fait 25 erreurs. Les messages d'erreurs suivants ne seront pas affichés." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Erreur dans le fichier « DVI » « %1 », page %2. Une commande de tirage de " +"couleurs est émise alors que la pile de couleurs est vide." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Paramètre mal formé dans la commande spéciale « epsf ».\n" +"Un paramètre de type flottant était attendu à la suite de %1 dans %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Impossible de trouver le fichier : \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Erreur dans le fichier « DVI » « %1 », page %2. Impossible d'interpréter " +"l'angle dans la rotation spéciale de texte." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "La commande spéciale « %1 » n'est pas implémentée." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Le fichier de police %1 peut être ouvert et lu mais son format de police " +"n'est pas pris en charge." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Le fichier de police %1 est cassé ou il est impossible de l'ouvrir ou de le " +"lire." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"Le programme « FreeType » rapporte une erreur lors du réglage de la taille " +"de caractère pour le fichier de police %1." + +# unreviewed-context +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"Le programme « FreeType » est incapable de charger le glyphe n° %1 à partir " +"du fichier de police %2." + +# unreviewed-context +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"Le programme « FreeType » est incapable de rendre le glyphe n° %1 à partir " +"du fichier de police %2." + +# unreviewed-context +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Le glyphe n° %1 est vide." + +# unreviewed-context +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Le glyphe n° %1 issu du fichier de police %2 est vide." + +# unreviewed-context +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"Le programme « FreeType » est incapable de charger la métrique pour le " +"glyphe n° %1 à partir du fichier de police %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Impossible d'ouvrir le fichier de police %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[] : caractère %1 non défini dans la police %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 inattendu dans le fichier « PK » %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Le caractère %1 est trop grand dans le fichier %2" + +# unreviewed-context +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Nombre erroné de bits enregistrés : caractère %1, police %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Mauvais fichier « PK » (%1), trop de bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "La police a un coefficient d'aspect non carré " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Impossible de trouver la police %1, fichier %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Incohérence de somme de contrôle pour le fichier de police %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Impossible de reconnaître le format du fichier de police %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Erreur fatale.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Cela signifie probablement que soit vous avez trouvé un bogue \n" +"dans Okular soit que le fichier « DVI » ou des fichiers auxiliaires \n" +" (comme des fichiers de police ou des fichiers de police \n" +"virtuelle) sont gravement endommagés.\n" +"Okular abandonnera après ce message. Si vous pensez que \n" +"vous avez trouvé un bogue ou que Okular devrait mieux se \n" +"comporter dans cette situation, veuillez rapporter ce problème." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "" +"Un octet erroné de commande a été trouvé dans la liste de macro « VF » : %1" + +#~ msgid "DVI Backend" +#~ msgstr "Moteur DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Un moteur de rendu de fichiers « DVI »" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular s'appuie sur le programme kpsewhich pour trouver les " +#~ "fichiers de police sur votre disque dur et pour générer les polices " +#~ "« PK », si nécessaire.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular génère maintenant les polices matricielles (bitmap)..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Abandonne la génération de police. Ne faites pas ça." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular génère actuellement des polices matricielles, nécessaires à " +#~ "l'affichage de votre document. Pour cela, Okular utilise de nombreux " +#~ "programmes externes, tels que « MetaFont ». Vous pourrez trouver plus " +#~ "tard les messages émis par ces programmes dans la boîte de dialogue " +#~ "« Informations du document »." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular génère actuellement les polices. Veuillez patienter." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Boîte de dialogue de progression pour la génération de polices" + +#~ msgid "Abort" +#~ msgstr "Abandonner" + +#~ msgid "What is happening here?" +#~ msgstr "Que se passe t-il ici ?" + +#~ msgid "%v of %m" +#~ msgstr "%v sur %m" + +#~ msgid "Please be patient" +#~ msgstr "Veuillez patienter" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Format de document portable (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Exporte le fichier sous" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Le fichier %1\n" +#~ "existe. Voulez-vous l'écraser ?" + +#~ msgid "Overwrite File" +#~ msgstr "Écraser le fichier" + +#~ msgid "Overwrite" +#~ msgstr "Écraser" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Utilisation de « dvipdfm » pour exporter le fichier en PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular utilise actuellement le programme externe « dvipdfm » pour " +#~ "convertir votre fichier « DVI » en « PDF ». Parfois, cela prend du temps " +#~ "car le programme « dvipdfm » doit générer ses propres polices " +#~ "matricielles. Veuillez patienter." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "En attente de la fin du programme « dvipdfm »..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "" +#~ "Utilisation du programme « dvips » pour exporter le fichier vers " +#~ "« PostScript »" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular utilise actuellement le programme externe « dvips » pour convertir " +#~ "votre fichier « DVI » en un fichier « PostScript ». Parfois, cela peut " +#~ "prendre du temps parce que le programme « dvips » a besoin de générer ses " +#~ "propres polices matricielles. Veuillez patienter." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Attente de la fin du programme « dvips »..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Fonctionnalité indisponible" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Corruption de fichier : Okular ne peut pas " +#~ "interpréter votre fichier « DVI ». La cause la plus fréquente est un " +#~ "fichier corrompu." + +#~ msgid "DVI File Error" +#~ msgstr "Erreur de fichier « DVI »" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Impossible de trouver tous les fichiers de polices" + +#~ msgid "Locating fonts..." +#~ msgstr "Recherche des polices en cours..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Des problèmes sont survenus durant l'exécution de kpsewhich. " +#~ "Certains fichiers de police n'ont pas pu être trouvés et votre document " +#~ "pourrait être illisible.

Cause possible : Le programme " +#~ "« kpsewhich » n'est peut-être pas installé sur votre système ou il est " +#~ "impossible de le trouver dans l'emplacement de recherche actuel.

Ce que vous pouvez faire : Le programme « kpsewhich » est " +#~ "normalement intégré dans les distributions du système de composition de " +#~ "documents « TeX ». Si ce dernier n'est pas installé sur votre système, " +#~ "vous pourriez installer la distribution « TeX Live » (www.tug.org/" +#~ "texlive). Si vous êtes sûr que « TeX » est installé, veuillez essayer " +#~ "d'utiliser le programme « kpsewhich » à partir de la ligne de commandes " +#~ "pour vérifier son bon fonctionnement.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Problème pour trouver des polices" + +#~ msgid "Font generation aborted" +#~ msgstr "Génération de polices abandonnée" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Exporte : %1 en PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Exporte : %1 vers PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "La liste de police est actuellement vide." + +#~ msgid "TeX Name" +#~ msgstr "Nom pour TeX" + +#~ msgid "Family" +#~ msgstr "Famille" + +#~ msgid "Zoom" +#~ msgstr "Grossissement" + +#~ msgid "Type" +#~ msgstr "Type" + +#~ msgid "Encoding" +#~ msgstr "Encodage" + +#~ msgid "Comment" +#~ msgstr "Commentaire" + +#~ msgid "TeX virtual" +#~ msgstr "Un TeX virtuel" + +#~ msgid "TeX Font Metric" +#~ msgstr "Métrique de police de TeX" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/fr/okular_epub.po b/po/fr/okular_epub.po new file mode 100644 index 0000000..b6c1add --- /dev/null +++ b/po/fr/okular_epub.po @@ -0,0 +1,60 @@ +# translation of okular_epub.po to Francais +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mickael Sibelle , 2008. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:44+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mickaël Sibelle" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kimael@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Erreur lors de l'ouverture du document « EPub »" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configuration du moteur EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Moteur EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Un moteur EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/fr/okular_fax.po b/po/fr/okular_fax.po new file mode 100644 index 0000000..b3afd27 --- /dev/null +++ b/po/fr/okular_fax.po @@ -0,0 +1,50 @@ +# translation of okular_fax.po to Francais +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mickael Sibelle , 2008. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:16+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mickaël Sibelle" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kimael@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Impossible de charger le document" + +#~ msgid "Fax Backend" +#~ msgstr "Moteur de fax" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Un moteur de documents pour fax « G3 / G4 »" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fr/okular_fictionbook.po b/po/fr/okular_fictionbook.po new file mode 100644 index 0000000..e22847e --- /dev/null +++ b/po/fr/okular_fictionbook.po @@ -0,0 +1,104 @@ +# translation of okular_fictionbook.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Guillaume Pujol , 2008. +# xavier , 2012, 2013. +# Peter Potrowl , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-28 12:38-0700\n" +"Last-Translator: Peter Potrowl \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Boeglin, Peter Potrowl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "thomas.boeglin@gmail.com, peter.potrowl@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Le document n'est pas dans un format « FictionBook » valable" + +# unreviewed-context +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Impossible d'ouvrir le document : %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Le document n'est pas une archive « ZIP » valable" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Structure du document non valable (le dossier principal est manquant)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Aucun contenu trouvé dans le document" + +# unreviewed-context +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Document XML non valable : %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuration du moteur FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Moteur FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Moteur de rendu des eBooks « FictionBook »" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Creator" +#~ msgstr "Créateur" + +#~ msgid "Title" +#~ msgstr "Titre" + +#~ msgid "Author" +#~ msgstr "Auteur" + +#~ msgid "Producer" +#~ msgstr "Producteur" + +#~ msgid "Created" +#~ msgstr "Date de création" diff --git a/po/fr/okular_ghostview.po b/po/fr/okular_ghostview.po new file mode 100644 index 0000000..160c361 --- /dev/null +++ b/po/fr/okular_ghostview.po @@ -0,0 +1,97 @@ +# translation of okular_ghostview.po to +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Mickael Sibelle , 2008. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 11:03+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Mickaël Sibelle" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kimael@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Utiliser les polices de la plate-forme" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Détermine si Ghostscript peut utiliser les polices de la plate-forme. Si " +"cette option est non sélectionnée, l'utilisation des polices embarquées dans " +"le document sera autorisée." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Configuration générale" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Utiliser les polices de la plate-forme" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuration du moteur Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Version du document" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Niveau du langage" + +#~ msgid "PS Backend" +#~ msgstr "Moteur PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un moteur de rendu de fichier « PostScript »." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Reposant sur la bibliothèque « Spectre »." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/fr/okular_kimgio.po b/po/fr/okular_kimgio.po new file mode 100644 index 0000000..29ba13b --- /dev/null +++ b/po/fr/okular_kimgio.po @@ -0,0 +1,78 @@ +# translation of okular_kimgio.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Florian Guillochon , 2009. +# xavier , 2013. +# Peter Potrowl , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2018-03-04 23:11+0100\n" +"Last-Translator: Peter Potrowl \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 2.0\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Boeglin, Florian Guillochon, Peter Potrowl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"thomas.boeglin@gmail.com, florian.guillochon@gmail.com, peter.potrowl@gmail." +"com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Impossible de charger le document : %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Ce document semble mal formé. Voici la meilleure approximation de " +"l'apparence voulue du document." + +#~ msgid "Image Backend" +#~ msgstr "Moteur d'images" + +#~ msgid "A simple image backend" +#~ msgstr "Un moteur simple d'images" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barre principale d'outils" diff --git a/po/fr/okular_markdown.po b/po/fr/okular_markdown.po new file mode 100644 index 0000000..06b584e --- /dev/null +++ b/po/fr/okular_markdown.po @@ -0,0 +1,57 @@ +# Peter Potrowl , 2017, 2019. +# Simon Depiets , 2018. +# Xavier Besnard , 2021. +msgid "" +msgstr "" +"Project-Id-Version: okular_markdown\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2021-01-13 17:17+0100\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.12.0\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Geoffray Levasseur, Matthieu Robin, Peter Potrowl, Simon Depiets" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"geoffray.levasseurbrandin@numericable.fr, kde@macolu.org, peter." +"potrowl@gmail.com, sdepiets@gmail.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Impossible d'ouvrir le document" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Impossible de compiler le document « Markdown »." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Formatage SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuration du moteur markdown" diff --git a/po/fr/okular_mobi.po b/po/fr/okular_mobi.po new file mode 100644 index 0000000..1abcdd6 --- /dev/null +++ b/po/fr/okular_mobi.po @@ -0,0 +1,68 @@ +# translation of okular_mobi.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Joëlle Cornavin , 2009. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:47+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Joëlle Cornavin" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "jcornavi@club-internet.fr" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Erreur lors de l'ouverture du document « Mobipocket »." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Ce livre est protégé par « DRM » et ne peut être affiché que sur un " +"périphérique prévu à cet effet" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuration du moteur Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Moteur Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Un moteur Mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/fr/okular_plucker.po b/po/fr/okular_plucker.po new file mode 100644 index 0000000..bc5c0f0 --- /dev/null +++ b/po/fr/okular_plucker.po @@ -0,0 +1,51 @@ +# translation of okular_plucker.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Guillaume Pujol , 2008. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:20+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Thomas Boeglin" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "thomas.boeglin@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nom" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Moteur de documents Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un système de rendu pour les eBooks « Plucker »" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/fr/okular_poppler.po b/po/fr/okular_poppler.po new file mode 100644 index 0000000..e0c1293 --- /dev/null +++ b/po/fr/okular_poppler.po @@ -0,0 +1,239 @@ +# translation of okular_poppler.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Guillaume Pujol , 2008. +# Florian Guillochon , 2009. +# xavier , 2012, 2013, 2020. +# Peter Potrowl , 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-04-06 14:24+0100\n" +"Last-Translator: Peter Potrowl \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.12.0\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Xavier Besnard, Thomas Boeglin, Florian Guillochon, Peter Potrowl" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"xavier.besnard@neuf.fr, thomas.boeglin@gmail.com, florian.guillochon@gmail." +"com, peter.potrowl@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Épaissir les lignes fines :" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Non" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solide" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forme" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Options « PDF »" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprimer les annotations" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Insérer les annotations dans le document imprimé" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Insère les annotations dans le document imprimé. Vous pouvez désactiver ceci " +"si vous souhaitez imprimer le document original sans annotation." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Forcer la rastérisation (conversion en image)" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rastériser (convertir en image) avant l'impression" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Forcer la rastérisation (conversion en image) de chaque page avant " +"l'impression. Les résultats obtenus sont en général moins bon, mais cela est " +"utile pour imprimer des documents dont l'impression directe semble " +"incorrecte." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Ajuster à la zone imprimable" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Ajuster à la page entière" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Aucun ; imprimer en taille originale" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Mode de mise à l'échelle pour les pages imprimées" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Mode de mise à l'échelle :" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF version %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Format" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Chiffré" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Non chiffré" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sécurité" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Oui" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimisé" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Utilisation de Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Utilisation de Poppler %1\n" +"\n" +"Construit sur Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuration du moteur PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Non disponible" + +#~ msgid "PDF Backend" +#~ msgstr "Moteur PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Un moteur PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "" +#~ "L'enregistrement de fichiers avec chiffrement n'est pas pris en charge." + +#~ msgid "Unknown" +#~ msgstr "Inconnu" + +#~ msgid "Unknown Date" +#~ msgstr "Date inconnue" + +#~ msgid "Unknown Encryption" +#~ msgstr "Chiffrement inconnu" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optimisation inconnue" + +# unreviewed-context +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Veuillez saisir le mot de passe pour l'ouverture du document :" + +# unreviewed-context +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Mot de passe erroné. Nouvel essai :" + +#~ msgid "Document Password" +#~ msgstr "Mot de passe du document" diff --git a/po/fr/okular_tiff.po b/po/fr/okular_tiff.po new file mode 100644 index 0000000..47b421d --- /dev/null +++ b/po/fr/okular_tiff.po @@ -0,0 +1,25 @@ +# Xavier Besnard , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-13 18:04+0200\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 20.04.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Xavier Besnard" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "xavier.besnard@neuf.fr" diff --git a/po/fr/okular_txt.po b/po/fr/okular_txt.po new file mode 100644 index 0000000..9234796 --- /dev/null +++ b/po/fr/okular_txt.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:35+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Xavier Besnard" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "xavier.besnard@neuf.fr" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuration du moteur Txt" + +#~ msgid "Txt Backend" +#~ msgstr "Moteur TxT" + +#~ msgid "Txt backend." +#~ msgstr "Moteur TxT." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/fr/okular_xps.po b/po/fr/okular_xps.po new file mode 100644 index 0000000..3f3f55d --- /dev/null +++ b/po/fr/okular_xps.po @@ -0,0 +1,67 @@ +# translation of okular_xps.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Thomas Boeglin , 2007, 2008. +# Mickael Sibelle , 2008. +# Guillaume Pujol , 2008. +# Joëlle Cornavin , 2009. +# xavier , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-26 10:39+0200\n" +"Last-Translator: xavier \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.5\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Xavier Besnard, Thomas Boeglin, Joëlle Cornavin, Mickaël Sibelle" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"xavier.besnard@neuf.fr, thomas.boeglin@gmail.com, jcornavi@club-internet.fr, " +"kimael@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Révision" + +#~ msgid "XPS Backend" +#~ msgstr "Moteur XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un moteur XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/fr/org.kde.active.documentviewer.po b/po/fr/org.kde.active.documentviewer.po new file mode 100644 index 0000000..7238fc9 --- /dev/null +++ b/po/fr/org.kde.active.documentviewer.po @@ -0,0 +1,87 @@ +# translation of org.kde.active.documentviewer.po to Français +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Joëlle Cornavin , 2013. +# xavier , 2013, 2020, 2021. +# Yoann Laissus , 2018. +# Simon Depiets , 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: org.kde.active.documentviewer\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2021-01-13 17:26+0100\n" +"Last-Translator: Xavier Besnard \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 20.12.0\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Ouvrir..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Supprimer le signet" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Ajouter cette page aux signets" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Vignettes" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Table des matières" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Signets" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Chercher…" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Aucun résultat n'a été trouvé." + +#~ msgid "Document to open..." +#~ msgstr "Document à ouvrir..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Aucun document n'a été trouvé. Pour commencer à lire, placez quelques " +#~ "fichiers dans le dossier « Document » de votre périphérique." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Afficheur de documents pour Plasma Active utilisant Okular" + +#~ msgid "Reader" +#~ msgstr "Lecteur" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL du fichier à ouvrir" diff --git a/po/ga/okular.po b/po/ga/okular.po new file mode 100644 index 0000000..448fbff --- /dev/null +++ b/po/ga/okular.po @@ -0,0 +1,5738 @@ +# Irish translation of okular +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics/kpdf.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2004-12-03 14:52-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Séamus Ó Ciardhuáin,Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "seoc@iolfree.ie,kscanne@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004-2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004-2009 Albert Astals Cid\n" +"© 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Iarchothaitheoir" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "Forbróir KPDF" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Forbróir KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Uirlis roghnaithe tábla" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Feabhsúcháin ar anótáil" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Téigh go leathanach %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Oscail comhad seachtrach" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Rith '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "An Chéad Leathanach" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "An Leathanach Roimhe Seo" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "An Chéad Leathanach Eile" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "An Leathanach Deireanach" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Siar" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Ar Aghaidh" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Scoir" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Tosaigh an Láithreoireacht" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Cuir Deireadh leis an Láithreoireacht" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Aimsigh..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Téigh go Leathanach..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Seinn fuaim..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Seinn scannán..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Seinn scannán" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stop scannán" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Roghnú Innill" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Aimsíodh níos mó ná inneall amháin le haghaidh an chineáil MIME seo:
%1 (%2).

Roghnaigh ceann acu:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Téigh go leathanach %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, fuzzy, kde-format +#| msgid "%1 x %2 in" +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 × %2 orlach" + +#: core/document.cpp:251 +#, fuzzy, kde-format +#| msgid "%1 x %2 mm" +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 × %2 mm" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Ní féidir breiseán a aimsiú atá in ann an cháipéis seo a láimhseáil." + +#: core/document.cpp:3368 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Láithreoireacht" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Tá an cháipéis ag iarraidh feidhmchlár seachtrach a rith agus, le do " +"shlándáil a chosaint, ní cheadaíonn Okular é sin." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "" +"Níor aimsíodh aon fheidhmchlár atá in ann comhad de chineál MIME %1 a " +"oscailt." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Níorbh fhéidir comhad sealadach a oscailt" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Thuairteáil an próiseas priontála" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Níorbh fhéidir an próiseas priontála a thosú" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Theip ar phriontáil i gcomhad" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Bhí an printéir i staid neamhbhailí" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Ní féidir an comhad le priontáil a aimsiú" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Níorbh fhéidir '%1' a oscailt. Níl an comhad ann" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Teideal" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Ábhar" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Cur Síos" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Údar" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Cruthaitheoir" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Táirgeoir" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Cóipcheart" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Leathanaigh" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Cruthaithe" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Athraithe" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Cineál MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Catagóir" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Lorgfhocail" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Conair" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Méid Comhaid" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Méid an Leathanaigh" + +#: core/documentcommands.cpp:65 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Anótáil" + +#: core/documentcommands.cpp:110 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Láithreoireacht" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Feabhsúcháin ar anótáil" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Anótáil Téacs" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "Anótáil" + +#: core/documentcommands.cpp:328 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Roghnaigh téacs" + +#: core/documentcommands.cpp:390 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Feabhsúcháin ar anótáil" + +#: core/documentcommands.cpp:438 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Feabhsúcháin ar anótáil" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Gnáth-&Théacs..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Téacs OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Roghanna Eagarthóra" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Mód datha:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Dún an teachtaireacht seo" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Foinse: %1" + +#: core/textdocumentsettings.cpp:37 +#, fuzzy, kde-format +#| msgid "&Default Zoom:" +msgid "&Default Font:" +msgstr "Súmáil &Réamhshocraithe:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Ath&luchtaigh" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Ceadaigh" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Scáileán" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Laghdaigh go leithead leathanaigh" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Feabhsúcháin ar anótáil" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Feabhsúcháin ar anótáil" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&Dath:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&Dath:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Turgnamhach" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Select Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "Uirlis &Roghnaithe" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "&Annotations" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Aibhsigh" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Líne Faoi" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Roghnaigh téacs" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Roghnaigh téacs" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Forscríobh" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nóta Inlíne" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "&Oscail Preabnóta" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Airíonna an Scannáin" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Líne Dhíreach Bhuí" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Dronuilleog" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Éilips" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polagán Gorm" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Stampa" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Anótáil" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Láithreoireacht" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Cló:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Feabhsúcháin ar anótáil" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Líne" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&Teimhneacht:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Leathanach %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anótáil" +msgstr[1] "%1 Anótáil" +msgstr[2] "%1 Anótáil" +msgstr[3] "%1 nAnótáil" +msgstr[4] "%1 Anótáil" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Oscail Preabnóta" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Scrios" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Airíonna" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Sábháil '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Cuma" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Ginearálta" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "Úd&ar:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Cruthaithe" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Athraithe" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Pop-up Note Properties" +msgstr "Airíonna an Scannáin" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Typewriter Properties" +msgstr "Airíonna an Scannáin" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Straight Line Properties" +msgstr "Airíonna an Scannáin" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +#| msgid "Sound Properties" +msgid "Polygon Properties" +msgstr "Airíonna Fuaime" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Sound Properties" +msgid "Text Markup Properties" +msgstr "Airíonna Fuaime" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Freehand Line Properties" +msgstr "Airíonna an Scannáin" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Airíonna Fuaime" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Airíonna an Scannáin" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Athraithe: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Dath:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Teimhneacht:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Deilbhín" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Nóta" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Cabhair" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Ionsáigh" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Eochair" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Alt Nua" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nóta" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Alt" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Cló:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Dath:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "" + +#: part/annotationwidgets.cpp:390 +#, fuzzy, kde-format +#| msgctxt "Rotate left" +#| msgid "Left" +msgid "Left" +msgstr "Tuathalach" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "" + +#: part/annotationwidgets.cpp:392 +#, fuzzy, kde-format +#| msgctxt "Rotate right" +#| msgid "Right" +msgid "Right" +msgstr "Deisealach" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Ceadaithe" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Mar Atá" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Faoi Rún" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Rannach" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Dréacht" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Turgnamhach" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Deireanach" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Díolta" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "An-Rúnda" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Leabharmharc" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Eolas" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "Laghdaigh go leithead leathanaigh" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Líne" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Líne" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Leader line length:" +msgstr "Líne Faoi" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Sábháil go Comhad..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Cineál:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Aibhsigh" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Líne Faoi" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Dronuilleog" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Éilips" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Fáiscín páipéar" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Clib" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Comhad" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A/F" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Níl cur síos ar fáil." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "Name" +msgid "Name:" +msgstr "Ainm" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Cur Síos:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Dún an nóta seo" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Roghanna" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Leabharmharc amháin" +msgstr[1] "" +"%1\n" +"\n" +"%2 leabharmharc" +msgstr[2] "" +"%1\n" +"\n" +"%2 leabharmharc" +msgstr[3] "" +"%1\n" +"\n" +"%2 leabharmharc" +msgstr[4] "" +"%1\n" +"\n" +"%2 leabharmharc" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Leabharmharcanna" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "C&uardaigh:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Cáipéis reatha amháin" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Téigh go dtí an Leabharmharc Seo" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Athainmnigh an Leabharmharc" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Bain Leabharmharc" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Oscail an Cháipéis" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Bain Leabharmharcanna" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "Uimhir an Leathanaigh" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "As Dáta" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Ábhar" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Úsáid na Cuimhne" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Airíonna" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "Cumraigh an tAmharcán" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "Ea&spórtáil Mar" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Ginearálta" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Ath&luchtaigh" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "Scáileán" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Ceadaigh" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Athraigh &dathanna" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mód datha:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inbhéartaigh na Dathanna" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Athraigh Dath an Pháipéir" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Athraigh Dathanna Dorcha & Geala" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Tiontaigh go Dubh agus Bán" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Dath an pháipéir:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Dath dorcha:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Tairseach:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Codarsnacht:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Aitheantas" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "Úd&ar:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgid "Quick annotation tools" +msgstr "Feabhsúcháin ar anótáil" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Eagarthóir Téacs Saincheaptha" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Cliant Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Cliant Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Eagarthóir" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Eagarthóir:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Ordú:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Cuma" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Taispeáin scroll&bharraí" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Dath an chúlra:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Roghanna Amhairc" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Súmáil &Réamhshocraithe:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Laghdaigh go leithead leathanaigh" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Laghdaigh go dtí an Leathanach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Úsáid LAP" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Cumasaigh maisíochtaí &trédhearcachta" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Úsáid na Cuimhne" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Ísea&l" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "G&náth (réamhshocrú)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "Te&anntásach" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rindreáil" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Scáileán Reatha" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Scáileán Réamhshocraithe" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Scáileán %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " soicind" +msgstr[1] " shoicind" +msgstr[2] " shoicind" +msgstr[3] " soicind" +msgstr[4] " soicind" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Nascleanúint" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Téigh ar aghaidh gach:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Nascleanúint" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Dath an chúlra:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Cúrsóir luiche:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Infheicthe i gCónaí" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Folaithe i gCónaí" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Tais&peáin táscaire dul chun cinn" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Trasdul réamhshocraithe:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Bosca Isteach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Bosca Amach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Díscaoil" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Trasdul Randamach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Ionadaigh" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Roinn go Cothrománach Isteach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Roinn go Cothrománach Amach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Roinn go hIngearach Isteach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Roinn go hIngearach Amach" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Síobán Anuas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Síobán ón Chlé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Síobán ón Deas" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Síobán Aníos" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Láithriú" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, fuzzy, kde-format +#| msgid "Name" +msgid "&Name:" +msgstr "Ainm" + +#: part/editannottooldialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Type:" +msgid "&Type:" +msgstr "Cineál:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgid "Pop-up Note" +msgstr "&Oscail Preabnóta" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nóta Inlíne" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgid "Straight Line" +msgstr "Líne Dhíreach Bhuí" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgid "Polygon" +msgstr "Polagán Gorm" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +#| msgid "Next Bookmark" +msgid "Text markup" +msgstr "An Chéad Leabharmharc Eile" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Stampa" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgid "Typewriter" +msgstr "Forscríobh" + +#: part/editannottooldialog.cpp:104 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create annotation tool" +msgstr "Láithreoireacht" + +#: part/editannottooldialog.cpp:106 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgid "Edit annotation tool" +msgstr "Feabhsúcháin ar anótáil" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&Dath:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "Laghdaigh go leithead leathanaigh" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr "%" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Create drawing tool" +msgstr "Láithreoireacht" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgid "Edit drawing tool" +msgstr "Feabhsúcháin ar anótáil" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Anaithnid" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Comhaid Leabaithe" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&Amharc" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Ainm" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Cur Síos" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Méid" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Cruthaithe" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Athraithe" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Sábháil Mar..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Amharc" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Níorbh fhéidir comhpháirt réamhamhairc priontála a luchtú" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Réamhamharc Priontála" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Dún" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "A&imsigh:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Téacs le lorg" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "An Chéad Toradh Eile" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Léim go dtí an chéad toradh eile" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Roimhe Seo" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Léim go dtí an ceann roimhe seo" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Athraigh oibriú an chuardaigh" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Cásíogair" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Ón leathanach reatha" + +#: part/findbar.cpp:73 +#, fuzzy, kde-format +#| msgid "Find stopped." +msgid "Find as you type" +msgstr "Stopadh an t-aimsiú." + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Gach Comhad" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Signature Properties" +msgstr "Airíonna an Scannáin" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Straight Line with Comment" +msgstr "Airíonna an Scannáin" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Céimseata" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "Aibhsigh" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Select text" +msgid "Squiggle with Comment" +msgstr "Roghnaigh téacs" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Underline with Comment" +msgstr "Líne Faoi" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Select text" +msgid "Strike Out with Comment" +msgstr "Roghnaigh téacs" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Freehand Line with Comment" +msgstr "Airíonna an Scannáin" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Carait" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Fuaim" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Scannán" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Scáileán" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Anaithnid" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Údar: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Roghanna Cuardaigh" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Cásíogair" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "C&uardaigh:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "as" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Súmáil" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rothlaigh go &Deisealach" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Deisealach" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rothlaigh go &Tuathalach" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Tuathalach" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Treoshuíomh Bunúsach" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&Amharc" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Bearr na hImill" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Roghnú Téacs" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Oiriúnaigh don &Leithead" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Laghdai&gh go dtí an Leathanach" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "Laghdai&gh go dtí an Leathanach" + +# OK +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Mód &Amhairc" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Leathanach Amháin" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Leathanaigh ar aghaigh a chéile" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Leathanaigh ar aghaigh a chéile (an chéad leathanach sa lár)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Foramharc" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Leanúnach" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Brabhsáil" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Súmáil" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &colors" +msgid "&Toggle Change Colors" +msgstr "Athraigh &dathanna" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Roghnú Téacs" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Roghnú Téacs" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "Roghnú Tábla" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Uirlisí Roghnaithe" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Léigh an Cháipéis Iomlán" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Léigh an Leathanach Reatha" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Stad an Léamh" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Scrollaigh Suas" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Scrollaigh Síos" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Scrollaigh Leathanach Suas" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Scrollaigh Leathanach Síos" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Taispeáin Foirmeacha" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Luchtaíodh cáipéis le haon leathanach amháin." +msgstr[1] " Luchtaíodh cáipéis le dhá leathanach." +msgstr[2] " Luchtaíodh cáipéis le %1 leathanach." +msgstr[3] " Luchtaíodh cáipéis le %1 leathanach." +msgstr[4] " Luchtaíodh cáipéis le %1 leathanach." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Téacs (1 charachtar)" +msgstr[1] "Téacs (2 charachtar)" +msgstr[2] "Téacs (%1 charachtar)" +msgstr[3] "Téacs (%1 gcarachtar)" +msgstr[4] "Téacs (%1 carachtar)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Cóipeáil go dtí an Ghearrthaisce" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Cóipeáil faoi chosc ag DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Léigh an Téacs" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Íomhá (%1×%2 picteilíní)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Sábháil go Comhad..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Cóipeáladh íomhá [%1×%2] go dtí an ghearrthaisce." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Sábháil go Comhad..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Níor sábháladh an comhad." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Sábháladh íomhá [%1×%2] i gcomhad %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Cóipeáil Téacs" + +#: part/pageview.cpp:2930 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgid "Go to '%1'" +msgstr "Téigh go leathanach %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Déan cuardach ar '%1' le" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Cumraigh Aicearraí Gréasáin..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Lean an Nasc Seo" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "Seinn fuaim..." + +#: part/pageview.cpp:4179 +#, fuzzy, kde-format +#| msgid "Sound" +msgid "Stop Sound" +msgstr "Fuaim" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Cóipeáil Seoladh an Naisc" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Déan cuardach ar '%1' le" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Fáilte" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Roghnaigh limistéar súmála. Deaschliceáil le súmáil amach." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dear dronuilleog timpeall an téacs/grafaic is mian leat cóipeáil." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Roghnaigh téacs" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Dear dronuilleog timpeall an téacs/grafaic is mian leat cóipeáil." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nóta Nua Téacs" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Téacs an nóta nua:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Bookmark annotation" +msgstr "Anótáil" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Aibhsigh" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Dronuilleog" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Roghnaigh téacs" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "" + +#: part/pageviewannotator.cpp:1039 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Líne Dhíreach Bhuí" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Roghnaigh téacs" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Líne Faoi" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "Aibhsigh" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Add favorite annotation" +msgstr "Anótáil" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Custom annotation name:" +msgstr "Anótáil" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Comhad" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Socruithe" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "Cab&hair" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "Tre&oshuíomh" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Leabharmharcanna" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra Uirlisí Amharcán" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Mionsamhlacha" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotations" +msgstr "Anótáil" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Tá comhaid leabaithe sa cháipéis seo. Cliceáil anseo chun iad a fheiceáil nó téigh go Comhad -> Comhaid " +"Leabaithe." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "An Leathanach Roimhe Seo" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "An Leathanach Roimhe Seo" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Téigh go dtí an leathanach sa cháipéis roimh an gceann seo" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "An Chéad Leathanach Eile" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "An Chéad Leathanach Eile" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Téigh go dtí an chéad leathanach eile sa cháipéis" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Tús na cáipéise" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Téigh go dtí tús na cáipéise" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Deireadh na cáipéise" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Téigh go dtí deireadh na cáipéise" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Athainmnigh an leabharmharc reatha" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "An Leabharmharc Roimhe Seo" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Téigh go dtí an leabharmharc roimhe seo" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "An Chéad Leabharmharc Eile" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Téigh go dtí an chéad leabharmharc eile" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Cumraigh Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Cumraigh an tAmharcán..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Cumraigh Innill Amharcáin..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Cumraigh Innill..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Maidir leis an Inneall" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Ath&luchtaigh" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Athluchtaigh an cháipéis reatha ón diosca." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Uimhir an Leathanaigh" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Léigh an Leathanach Reatha" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show scroll&bars" +msgid "Show S&idebar" +msgstr "Taispeáin scroll&bharraí" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Taispeáin an Painéal &Nascleanúna" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Comhaid Leabaithe" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "Ea&spórtáil Mar" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "L&áithreoireacht" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Iompórtáil PostScript mar PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Fai&gh Leabhair Ón Idirlíon..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Erase Drawing" +msgstr "Láithreoireacht" + +#: part/part.cpp:927 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Annotations..." +msgstr "Cumraigh Innill..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "Láithreoireacht" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Níorbh fhéidir %1 a oscailt" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Cealaíodh luchtú %1." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Níorbh fhéidir %1 a oscailt. Fáth: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Cumraigh Innill Amharcáin" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Cumraigh Innill" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf gan aimsiú" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" + +#: part/part.cpp:1409 +#, fuzzy, kde-format +#| msgid "Moves to the last page of the document" +msgid "Please enter the password to read the document:" +msgstr "Téigh go dtí an leathanach deiridh sa cháipéis" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Focal faire mícheart. Triail arís é:" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +#| msgid "Password" +msgid "Document Password" +msgstr "Focal Faire" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Tá foirmeacha sa cháipéis seo. Cliceáil an cnaipe chun idirghníomhú leo, nó " +"úsáid Amharc -> Taispeáin Foirmeacha." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Níl cead agat an cháipéis seo a phriontáil." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Níl cead agat an cháipéis seo a phriontáil." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Mód Láithreoireachta" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Níorbh fhéidir %1 a oscailt" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&Leanúnach" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&Leanúnach" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Dún an Cháipéis" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Cáipéis á hathluchtú..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Inneachar" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Téigh go Leathanach" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Leathanach:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Athainmnigh an Leabharmharc seo" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename this Bookmark" +msgid "Remove this Bookmark" +msgstr "Athainmnigh an Leabharmharc seo" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "&Sábháil Mar..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "" + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Níorbh fhéidir an comhad a shábháil i '%1'. Bain triail as suíomh eile." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgid "Filled form contents" +msgstr "Feabhsúcháin ar anótáil" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "User annotations" +msgstr "Láithreoireacht" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&Leanúnach" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Níorbh fhéidir an comhad a shábháil i '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Níorbh fhéidir an comhad a shábháil i '%1'. Bain triail as suíomh eile." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Cuir Deireadh leis an Láithreoireacht" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Cuir Leabharmharc Leis" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Uirlisí" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Níl cead agat an cháipéis seo a phriontáil." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Earráid Chomhaid! Ní féidir comhad sealadach " +"%1 a chruthú." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Gan Leabharmharcanna" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Eagar" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Amharc" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Téigh" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Uirlisí" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Príomhbharra Uirlisí" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotation Toolbar" +msgstr "Anótáil" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Roghanna Ginearálta" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Inrochtaineacht" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Áiseanna Inrochtaineachta do Léamh" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Feidhmíocht" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Tiúnadh Oibrithe" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Cumraigh an tAmharcán" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Láithreoireacht" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Roghanna don Mhód Láithreoireachta" + +#: part/preferencesdialog.cpp:50 +#, fuzzy, kde-format +#| msgid "Annotation improvements" +msgid "Annotation Options" +msgstr "Feabhsúcháin ar anótáil" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Roghanna Eagarthóra" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "An Chéad Cheann Eile" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Láithreoireacht" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Scáileán %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Teideal: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Leathanaigh: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Cliceáil chun tosú" + +#: part/presentationwidget.cpp:505 +#, fuzzy, kde-format +#| msgctxt "pause the movie playback" +#| msgid "Pause" +msgctxt "For Presentation" +msgid "Pause" +msgstr "Cuir ar Shos" + +#: part/presentationwidget.cpp:508 +#, fuzzy, kde-format +#| msgctxt "start the movie playback" +#| msgid "Play" +msgctxt "For Presentation" +msgid "Play" +msgstr "Seinn" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Láithreoireacht á taispeáint" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Comhad Anaithnid" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Airíonna %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Clónna" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Faisnéis chló á léamh..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Méid an Leathanaigh" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Cineál 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Cineál 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Cineál 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Cineál 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "Cineál 0 CID" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "Cineál 0C CID" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "Cineál 0C CID (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "TrueType CID" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "TrueType CID (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Anaithnid" + +# boolean: "embedded"? +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Leabaithe (fo-thacar)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Leabaithe go hiomlán" + +# boolean: "embedded"? +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Níl" + +# boolean: "embedded"? +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Fo-thacar" + +# boolean: "embedded"? +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Tá" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a/f]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Cló anaithnid" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Leabaithe: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Ainm" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Cineál" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Comhad" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Leathanaigh" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Méid" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Réamhamharc Priontála" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Níorbh fhéidir %1 a oscailt" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Níorbh fhéidir %1 a oscailt. Fáth: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Cásíogair" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Comhoiriúnaigh Frása" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Comhoiriúnaigh Gach Focal" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Comhoiriúnaigh Focal Ar Bith" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Roghanna Scagaire" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Gan anótáil

Le hanótáil, brúigh F6 nó roghnaigh " +"Uirlisí -> Anótáil ón roghchlár.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Grúpáil de réir leathanaigh" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Grúpáil de réir údair" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Taispeáin anótáil ar an leathanach reatha amháin" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Cló anaithnid" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Comhad Anaithnid" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, fuzzy, kde-format +#| msgid "Encrypted" +msgid "Encrypt Keys" +msgstr "Criptithe" + +#: part/signatureguiutils.cpp:122 +#, fuzzy, kde-format +#| msgid "Unencrypted" +msgid "Decrypt Keys" +msgstr "Gan Criptiú" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, fuzzy, kde-format +#| msgid "Encrypted" +msgid "Encrypt Only" +msgstr "Criptithe" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Níl cur síos ar fáil." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Leathanaigh: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Airíonna" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Modifications:" +msgstr "Cáipéis le hoscailt" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Eolas" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "Anótáil" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgid "Document to open" +msgid "Document Version" +msgstr "Cáipéis le hoscailt" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Taispeáin leathanaigh leabharmharcáilte amháin" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Seinn" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Cuir ar Shos" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stad" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "&Edit..." +msgstr "&Eagar" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, fuzzy, kde-format +#| msgid "Wipe Down" +msgid "Move &Down" +msgstr "Síobán Anuas" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Leathanach na cáipéise le taispeáint" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Tosaigh an cháipéis sa mód láithreoireachta" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "Ní féidir comhpháirt okular a aimsiú." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Ní féidir comhpháirt okular a aimsiú." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Cliceáil chun comhad a oscailt\n" +"Cliceáil agus coinnigh an cnaipe síos chun comhad le déanaí a oscailt" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Cliceáil chun comhad a oscailt nó Cliceáil agus coinnigh an cnaipe " +"síos chun comhad le déanaí a oscailt" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +#| msgid "Next Page" +msgid "Next Tab" +msgstr "An Chéad Leathanach Eile" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +#| msgid "Previous Page" +msgid "Previous Tab" +msgstr "An Leathanach Roimhe Seo" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Gach Comhad" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Oscail Cáipéis" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Dún" + +#: shell/shell.cpp:606 +#, fuzzy, kde-format +#| msgid "" +#| "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"Tá comhad darb ainm \"%1\" ann cheana. An bhfuil tú cinnte gur mian leat " +"scríobh air?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Anótálacha" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Folaigh Foirmeacha" + +#~ msgid "Expired" +#~ msgstr "As Dáta" + +# annotate is much better than "review" or "commentary" or "exegesis" or +# whatever here +#~ msgid "&Review" +#~ msgstr "&Anótáil" + +#~ msgid "Annotations author" +#~ msgstr "Údar na n-anótálacha" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Taispeáin an Painéal &Nascleanúna" + +#~ msgid "Show Text" +#~ msgstr "Taispeáin Téacs" + +#~ msgid "Small Icons" +#~ msgstr "Deilbhíní Beaga" + +#~ msgid "Normal Icons" +#~ msgstr "Gnáthdheilbhíní" + +#~ msgid "Large Icons" +#~ msgstr "Deilbhíní Móra" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Cliceáil chun an uirlis reatha roghnúcháin a úsáid\n" +#~ "Cliceáil agus coinnigh síos chun uirlis roghnúchán eile a úsáid" + +#~ msgid "Created: %1" +#~ msgstr "Cruthaithe: %1" + +#~ msgid "Style" +#~ msgstr "Stíl" + +#~ msgid "&Size:" +#~ msgstr "&Méid:" + +#~ msgid "Name: %1" +#~ msgstr "Ainm: %1" + +#~ msgid "Size: %1" +#~ msgstr "Méid: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Uirlis &Bhrabhsála" + +#~ msgid "&Zoom Tool" +#~ msgstr "Uirlis &Súmála" + +# #-#-#-#-# kdelibs4.po (kdelibs4) #-#-#-#-# +# hopefully this will become view zoom, not just text zoom +# #-#-#-#-# kdvi.po (kdegraphics/kdvi.po) #-#-#-#-# +# #-#-#-#-# kdelibs4.po (kdelibs4) #-#-#-#-# +# hopefully this will become view zoom, not just text zoom +# #-#-#-#-# kxsconfig.po (kxsconfig) #-#-#-#-# +# hopefully this will become view zoom, not just text zoom +# #-#-#-#-# kxsconfig.po (kxsconfig) #-#-#-#-# +# hopefully this will become view zoom, not just text zoom +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Súmáil" + +#~ msgid "&Selection Tool" +#~ msgstr "Uirlis &Roghnaithe" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Roghnú" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Uirlis &Roghnaithe Téacs" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Uirlis &Roghnaithe Tábla" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Deireadh na cáipéise" + +#~ msgid "Allow" +#~ msgstr "Ceadaigh" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Ceadaigh an mód láithreoireachta" + +#~ msgid "Do Not Allow" +#~ msgstr "Ná Ceadaigh" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Ná ceadaigh an mód láithreoireachta" + +#~ msgid "Save &Copy As..." +#~ msgstr "Sábháil &Cóip Mar..." + +#~ msgctxt "A document format, Okular-specific" +#~ msgid "Document Archive" +#~ msgstr "Cartlann Cáipéisí" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Tá deireadh na cáipéise sroichte.\n" +#~ "Lean ar aghaidh ón tús?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Tá tús na cáipéise sroichte.\n" +#~ "Lean ar aghaidh ón deireadh?" + +#~ msgid "Current maintainer" +#~ msgstr "Cothaitheoir reatha" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " s." + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Theip ar thosú sheirbhís Téacs-go-Caint Jovie: %1" + +#~ msgid "Search Columns" +#~ msgstr "Cuardaigh Colúin" + +#~ msgid "All Visible Columns" +#~ msgstr "Gach Colún Infheicthe" + +#~ msgid "No document opened." +#~ msgstr "Níl aon cháipéis oscailte." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Níor aimsíodh aon rud comhoiriúnach do '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Cuardach ar siúl..." + +#~ msgid "Searching for %1" +#~ msgstr "%1 á lorg" + +#~ msgid "Identity Settings" +#~ msgstr "Socruithe Aitheantais" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Anótáil Téacs" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Dúch Uaine" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Peann Aibhsithe Buí" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Aibhsiú Buí" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Líne Dhíreach Bhuí" + +#~ msgid "Black Underlining" +#~ msgstr "Línte Faoi: Dubh" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Éilips Chian" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Éilips chian" + +#~ msgid "Ink" +#~ msgstr "Dúch" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Téigh go dtí an chéad leathanach sa cháipéis" + +#~ msgid "You must set this name:" +#~ msgstr "Ní mór duit an t-ainm seo a shocrú:" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Forscríobh" + +#~ msgid "Pages:" +#~ msgstr "Leathanaigh:" + +#~ msgid "Green Highlighter" +#~ msgstr "Peann Aibhsithe Uaine" + +#~ msgid "okular" +#~ msgstr "okular" + +#~ msgid "&Properties..." +#~ msgstr "&Airíonna..." + +#~ msgctxt "Annotation tool" +#~ msgid "Pink Ink" +#~ msgstr "Dúch Bándearg" + +#~ msgid "Pink Highlighter" +#~ msgstr "Peann Aibhsithe Bándearg" + +#~ msgid "&Advanced" +#~ msgstr "&Casta" + +#~ msgid "Contents:" +#~ msgstr "Ábhar:" + +#~ msgid "" +#~ "File Error! Could not create temporary file." +#~ msgstr "" +#~ "Earráid Chomhaid! Ní féidir comhad sealadach a " +#~ "chruthú." + +#~ msgid "okularpart" +#~ msgstr "okularpart" + +#~ msgid "Wilco Greven" +#~ msgstr "Wilco Greven" + +#~ msgid "Hide &Navigation Panel" +#~ msgstr "Folaigh an Painéal &Nascleanúna" + +#~ msgid "page %1" +#~ msgstr "leathanach %1" + +#~ msgid "Form" +#~ msgstr "Foirm" + +#~ msgid "DlgGeneral" +#~ msgstr "DlgGeneral" + +#~ msgid "Reading Aids" +#~ msgstr "Áiseanna Léimh" + +#~ msgid "Christophe Devriese" +#~ msgstr "Christophe Devriese" + +#~ msgid "Laurent Montel" +#~ msgstr "Laurent Montel" + +#~ msgid "&Watch file" +#~ msgstr "Coinnigh &súil ar chomhad" + +#~ msgid "Topic" +#~ msgstr "Topaic" + +#~ msgid "&Two Pages" +#~ msgstr "&Dhá Leathanach" + +#~ msgid "Security" +#~ msgstr "Slándáil" + +#~ msgid "Optimized" +#~ msgstr "Optamaithe" + +#~ msgid "Unknown Encryption" +#~ msgstr "Scéim Anaithnid Criptiúcháin" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optamúchán Anaithnid" + +#~ msgid "unknown" +#~ msgstr "anaithnid" + +#~ msgid "-" +#~ msgstr "-" + +#~ msgid "KPDF::Part" +#~ msgstr "KPDF::Páirt" + +#~ msgid "Text found: \"%1\"." +#~ msgstr "Aimsíodh téacs: \"%1\"." + +#~ msgid "Text not found: \"%1\"." +#~ msgstr "Téacs gan aimsiú: \"%1\"." + +#~ msgctxt "PDF v. " +#~ msgid "PDF v. %1" +#~ msgstr "PDF leagan %1" + +#~ msgid "Xpdf author" +#~ msgstr "Údar Xpdf" diff --git a/po/ga/okular_chm.po b/po/ga/okular_chm.po new file mode 100644 index 0000000..b765b7f --- /dev/null +++ b/po/ga/okular_chm.po @@ -0,0 +1,62 @@ +# Irish translation of okular_chm +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_chm package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "Inneall CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Rindreálaí comhad cabhrach Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Title" +#~ msgstr "Teideal" diff --git a/po/ga/okular_comicbook.po b/po/ga/okular_comicbook.po new file mode 100644 index 0000000..4980365 --- /dev/null +++ b/po/ga/okular_comicbook.po @@ -0,0 +1,58 @@ +# Irish translation of okular_comicbook +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_comicbook package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics/okular_comicbook.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2008-03-22 08:52-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Ní féidir an cháipéis a oscailt, 'unrar' gan aimsiú." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Níl an leagan de 'unrar' atá agat oiriúnach do leabhair ghrafacha a oscailt." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Formáid anaithnid ComicBook." + +#~ msgid "ComicBook Backend" +#~ msgstr "Inneall ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Ríomhchlár a rindreálann formáidí éagsúla de leabhair ghrafacha" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ga/okular_djvu.po b/po/ga/okular_djvu.po new file mode 100644 index 0000000..c433b3b --- /dev/null +++ b/po/ga/okular_djvu.po @@ -0,0 +1,148 @@ +# Irish translation of okular_djvu +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_djvu package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Eagarthóir" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Foilsitheoir" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Imleabhar" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Cineál na cáipéise" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Anaithnid" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Comhaid Chomhpháirte" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Anaithnid" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Leathanach Aonair" + +# FRTF: bundled software bogearraí mpl cuachta +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Cuachta" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indíreach" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Cuachta (sean)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Innéacsaithe (sean)" + +#~ msgid "DjVu Backend" +#~ msgstr "Inneall DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Inneall DjVu bunaithe ar DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgid "A DjVu backend" +#~ msgstr "Inneall DjVu" + +#~ msgid "Title" +#~ msgstr "Teideal" + +#~ msgid "Author" +#~ msgstr "Údar" + +#~ msgid "Year" +#~ msgstr "Bliain" diff --git a/po/ga/okular_dvi.po b/po/ga/okular_dvi.po new file mode 100644 index 0000000..391aaed --- /dev/null +++ b/po/ga/okular_dvi.po @@ -0,0 +1,572 @@ +# Irish translation of okular_dvi +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_dvi package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "" + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "" + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "" + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "" + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, fuzzy, kde-format +#| msgid "" +#| "File not found: \n" +#| " %1" +msgid "File corruption. %1" +msgstr "" +"Comhad gan aimsiú: \n" +" %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "" + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "" + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "" + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "" + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "" + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "" + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "%1 á leabú" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "" + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Gineadóir/Dáta" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Comhad cló gan aimsiú" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "portráid" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "tírdhreach" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Comhad gan aimsiú: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "" + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Is folamh í glif #%1." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "" + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Ní féidir comhad cló %1 a oscailt." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 gan choinne i gcomhad PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Droch-chomhad pk (%1), an iomarca giotáin" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Ní féidir cló %1, comhad %2 a aimsiú." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Earráid mharfach.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "" + +#~ msgid "Abort" +#~ msgstr "Tobscoir" + +#~ msgid "%v of %m" +#~ msgstr "%v as %m" + +#~ msgid "Please be patient" +#~ msgstr "Fan go fóill, le do thoil..." + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Formáid Doiciméad Iniompartha (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Easpórtáil Comhad Mar" + +#~ msgid "Overwrite File" +#~ msgstr "Forscríobh Comhad" + +#~ msgid "Overwrite" +#~ msgstr "Forscríobh" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Ag úsáid dvipdfm chun an comhad a easpórtáil go PDF" + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Ag feitheamh le dvipdfm..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Ag úsáid dvips chun an comhad a easpórtáil go PostScript" + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Ag feitheamh le dvips..." + +#~ msgid "Not All Font Files Found" +#~ msgstr "Níorbh fhéidir gach cló a aimsiú" + +#~ msgid "Locating fonts..." +#~ msgstr "Clónna á lorg..." + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Easpórtáil: %1 go PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Easpórtáil: %1 go PostScript" + +#~ msgid "TeX Name" +#~ msgstr "Ainm TeX" + +#~ msgid "Zoom" +#~ msgstr "Súmáil" + +#~ msgid "Type" +#~ msgstr "Cineál" + +#~ msgid "Encoding" +#~ msgstr "Ionchódú" + +#~ msgid "Comment" +#~ msgstr "Nóta" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Ní féidir an comhad DVI a luchtú." + +#~ msgid " in font file " +#~ msgstr " i gcomhad cló " + +#~ msgid "Virtual character " +#~ msgstr "Carachtar fíorúil " + +#~ msgid " in font " +#~ msgstr " i gcló " + +#~ msgid " ignored." +#~ msgstr ": rinneadh neamhshuim air." + +#~ msgid "Fatal Error" +#~ msgstr "Earráid Mharfach" + +#~ msgid "KDVI: Information" +#~ msgstr "KDVI: Eolas" + +#~ msgid "Do not show this message again" +#~ msgstr "Ná taispeáin an teachtaireacht seo arís" + +#~ msgid "File Error" +#~ msgstr "Earráid Chomhaid" + +#~ msgid "Pages" +#~ msgstr "Leathanaigh" diff --git a/po/ga/okular_epub.po b/po/ga/okular_epub.po new file mode 100644 index 0000000..f60fb18 --- /dev/null +++ b/po/ga/okular_epub.po @@ -0,0 +1,56 @@ +# Irish translation of okular_epub +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_epub package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdereview/okular_epub.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-03-22 08:52-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Earráid agus an cháipéis EPub á hoscailt." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "" + +#: generator_epub.cpp:33 +#, fuzzy, kde-format +#| msgid "EPub Backend" +msgid "EPub Backend Configuration" +msgstr "Inneall EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Inneall EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Inneall EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/ga/okular_fax.po b/po/ga/okular_fax.po new file mode 100644 index 0000000..921316a --- /dev/null +++ b/po/ga/okular_fax.po @@ -0,0 +1,45 @@ +# Irish translation of okular_fax +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_fax package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics/okular_fax.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-01-20 10:11-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Ní féidir an cháipéis a luchtú" + +#~ msgid "Fax Backend" +#~ msgstr "Inneall Facs" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Inneall cáipéisí facs G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ga/okular_fictionbook.po b/po/ga/okular_fictionbook.po new file mode 100644 index 0000000..691d375 --- /dev/null +++ b/po/ga/okular_fictionbook.po @@ -0,0 +1,97 @@ +# Irish translation of okular_fictionbook +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_fictionbook package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Ní comhad bailí FictionBook é seo" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Ní féidir an cháipéis a oscailt: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Ní cartlann bhailí ZIP é seo" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Struchtúr neamhbhailí cáipéise (príomhchomhadlann ar iarraidh)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Níor aimsíodh inneachar ar bith sa cháipéis" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Cáipéis neamhbhailí XML: %1" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook" +msgstr "Inneall FictionBook" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook Backend Configuration" +msgstr "Inneall FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Inneall FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Rindreálaí r-leabhair FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Creator" +#~ msgstr "Cruthaitheoir" + +#~ msgid "Title" +#~ msgstr "Teideal" + +#~ msgid "Author" +#~ msgstr "Údar" + +#~ msgid "Producer" +#~ msgstr "Táirgeoir" + +#~ msgid "Created" +#~ msgstr "Cruthaithe" diff --git a/po/ga/okular_ghostview.po b/po/ga/okular_ghostview.po new file mode 100644 index 0000000..1248987 --- /dev/null +++ b/po/ga/okular_ghostview.po @@ -0,0 +1,119 @@ +# Irish translation of okular_ghostview +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_ghostview package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics/okular_ghostview.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-06-27 10:27-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Úsáid Clónna an Chórais" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"An bhfuil cead ag Ghostscript clónna an chórais a úsáid? Mura bhfuil, ní " +"úsáidfear ach na clónna atá leabaithe sa cháipéis." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Socruithe Ginearálta" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "Ú&sáid clónna an chórais" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Cumraíocht Innill Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Leagan na cáipéise" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Leibhéal Teanga" + +#~ msgid "PS Backend" +#~ msgstr "Inneall PostScript" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Rindreálaí comhad PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Bunaithe ar an leabharlann Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "Feabhsaíonn frithailiasáil cuma na dtorthaí, ach tógfaidh an taispeáint " +#~ "seal níos faide" + +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "&Cumasaigh frithailiasáil de chlónna" + +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "&Cumasaigh frithailiasáil d'íomhánna" + +#~ msgid "" +#~ "Ghostscript is the basic renderer (the program which draws the " +#~ "picture)
\n" +#~ "In case of problems you might want to see its error messages" +#~ msgstr "" +#~ "Is é Ghostscript an bunchlár rindreála (an clár a tharraingíonn an " +#~ "pictiúr)
\n" +#~ "Má tá fadhbanna ann, ba chóir duit na hearráidí ó Ghostscript a scrúdú" + +#~ msgid "&Show Ghostscript messages in a separate box" +#~ msgstr "Tai&speáin teachtaireachtaí Ghostscript i mbosca faoi leith" + +#~ msgid "Ghostscript Configuration" +#~ msgstr "Cumraíocht Ghostscript" diff --git a/po/ga/okular_kimgio.po b/po/ga/okular_kimgio.po new file mode 100644 index 0000000..1cb4bd7 --- /dev/null +++ b/po/ga/okular_kimgio.po @@ -0,0 +1,67 @@ +# Irish translation of okular_kimgio +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_kimgio package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: kdegraphics/okular_kimgio.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2007-06-27 10:27-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Ní féidir an cháipéis a luchtú: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Inneall Íomhá" + +#~ msgid "A simple image backend" +#~ msgstr "Inneall simplí íomhá" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Príomhbharra Uirlisí" diff --git a/po/ga/okular_mobi.po b/po/ga/okular_mobi.po new file mode 100644 index 0000000..e7e4c50 --- /dev/null +++ b/po/ga/okular_mobi.po @@ -0,0 +1,65 @@ +# Irish translation of okular_mobi +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_mobi package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: playground-graphics/okular_mobi.po\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-01-20 10:11-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Earráid agus cáipéis Mobipocket á hoscailt." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Tá an leabhar seo faoi chosaint ag DRM agus ní féidir é a thaispeáint ach ar " +"ghléas ceadaithe" + +#: generator_mobi.cpp:28 +#, fuzzy, kde-format +#| msgid "Mobipocket Backend" +msgid "Mobipocket" +msgstr "Inneall Mobipocket" + +#: generator_mobi.cpp:28 +#, fuzzy, kde-format +#| msgid "Mobipocket Backend" +msgid "Mobipocket Backend Configuration" +msgstr "Inneall Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Inneall Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Inneall mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/ga/okular_plucker.po b/po/ga/okular_plucker.po new file mode 100644 index 0000000..6c18f96 --- /dev/null +++ b/po/ga/okular_plucker.po @@ -0,0 +1,54 @@ +# Irish translation of okular_plucker +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_plucker package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Ainm" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Inneall Cáipéise Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Rindreálaí r-leabhair Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Title" +#~ msgstr "Teideal" + +#~ msgid "Author" +#~ msgstr "Údar" + +#~ msgid "Created" +#~ msgstr "Cruthaithe" diff --git a/po/ga/okular_poppler.po b/po/ga/okular_poppler.po new file mode 100644 index 0000000..384302a --- /dev/null +++ b/po/ga/okular_poppler.po @@ -0,0 +1,261 @@ +# Irish translation of okular_poppler +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_poppler package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "" + +# boolean: optimized? +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Níl" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Roghanna PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Prionáil anótálacha" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Cuir anótálacha san áireamh sa cháipéis phriontáilte" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Cuir anótálacha san áireamh sa cháipéis phriontáilte. Díchumasaigh an rogha " +"seo más mian leat an bhuncháipéis gan anótálacha a phriontáil." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Fórsáil rastarú" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rastaraigh roimh phriontáil" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Tiontaigh gach leathanach go híomhá rastair sula bpriontálfar é. Go hiondúil " +"tugann sé seo torthaí beagán níos measa, ach tá sé áisiúil nuair nach " +"bpriontálann an cháipéis mar is ceart." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF leagan %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formáid" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Criptithe" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Gan Criptiú" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Slándáil" + +# boolean: optimized? +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Tá" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optamaithe" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "" + +#: generator_pdf.cpp:1470 +#, fuzzy, kde-format +#| msgid "PDF Backend" +msgid "PDF Backend Configuration" +msgstr "Inneall PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "Inneall PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Rindreálaí comhad PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Ní féidir comhaid a shábháil le /Encrypt." + +#~ msgid "Unknown" +#~ msgstr "Anaithnid" + +#~ msgid "Unknown Date" +#~ msgstr "Dáta Anaithnid" + +#~ msgid "Unknown Encryption" +#~ msgstr "Scéim Anaithnid Criptiúcháin" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optamúchán Anaithnid" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Iontráil an focal faire chun an cháipéis a léamh:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Focal faire mícheart. Triail arís é:" + +#~ msgid "Document Password" +#~ msgstr "Focal Faire na Cáipéise" + +#~ msgid "unknown" +#~ msgstr "anaithnid" + +#~ msgid "Type 1" +#~ msgstr "Cineál 1" + +#~ msgid "Type 3" +#~ msgstr "Cineál 3" + +#~ msgid "Title" +#~ msgstr "Teideal" + +#~ msgid "Subject" +#~ msgstr "Ábhar" + +#~ msgid "Author" +#~ msgstr "Údar" + +#~ msgid "Keywords" +#~ msgstr "Lorgfhocail" + +#~ msgid "Creator" +#~ msgstr "Cruthaitheoir" + +#~ msgid "Producer" +#~ msgstr "Táirgeoir" + +#~ msgid "Created" +#~ msgstr "Cruthaithe" + +#~ msgid "Modified" +#~ msgstr "Athraithe" + +#~ msgid "Pages" +#~ msgstr "Leathanaigh" diff --git a/po/ga/okular_xps.po b/po/ga/okular_xps.po new file mode 100644 index 0000000..9cbb3ec --- /dev/null +++ b/po/ga/okular_xps.po @@ -0,0 +1,83 @@ +# Irish translation of okular_xps +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the okular_xps package. +# Kevin Scannell , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-04-15 19:05-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kevin Scannell" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kscanne@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Leasú" + +#~ msgid "XPS Backend" +#~ msgstr "Inneall XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Inneall XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Title" +#~ msgstr "Teideal" + +#~ msgid "Subject" +#~ msgstr "Ábhar" + +#~ msgid "Description" +#~ msgstr "Cur Síos" + +#~ msgid "Author" +#~ msgstr "Údar" + +#~ msgid "Category" +#~ msgstr "Catagóir" + +#~ msgid "Created" +#~ msgstr "Cruthaithe" + +#~ msgid "Modified" +#~ msgstr "Athraithe" + +#~ msgid "Keywords" +#~ msgstr "Lorgfhocail" + +#~ msgid "Pages" +#~ msgstr "Leathanaigh" diff --git a/po/ga/org.kde.active.documentviewer.po b/po/ga/org.kde.active.documentviewer.po new file mode 100644 index 0000000..de3a790 --- /dev/null +++ b/po/ga/org.kde.active.documentviewer.po @@ -0,0 +1,69 @@ +# Irish translation of org.kde.active.documentviewer +# Copyright (C) 2012 This_file_is_part_of_KDE +# This file is distributed under the same license as the org.kde.active.documentviewer package. +# Kevin Scannell , 2012. +msgid "" +msgstr "" +"Project-Id-Version: org.kde.active.documentviewer\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2012-11-29 14:59-0500\n" +"Last-Translator: Kevin Scannell \n" +"Language-Team: Irish \n" +"Language: ga\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? " +"3 : 4\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Leabharmharcanna" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Mionsamhlacha" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Clár ábhair" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Leabharmharcanna" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Níor aimsíodh aon rud." + +#~ msgid "Reader" +#~ msgstr "Léitheoir" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "© 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL an chomhaid le hoscailt" diff --git a/po/gl/docs/okular/index.docbook b/po/gl/docs/okular/index.docbook new file mode 100644 index 0000000..a4921c5 --- /dev/null +++ b/po/gl/docs/okular/index.docbook @@ -0,0 +1,2107 @@ + + + + KPDF"> + PDF"> + + +]> + + + + Manual do &okular; + + Albert Astals Cid
aacid@kde.org
+
+
+ Pino Toscano
pino@kde.org
+
+
+ XoséCalvo
Tradutor do proxecto Trasno
+
+ &FDLNotice; + 2009-05-22 + 0.9 + + + O &okular; é un visor universal de documentos para o &kde; baseado no código do &kpdf;. + + + KDE + okular + pdf + ps + postscript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + mobipocket + plucker + annotation + +
+ + Introdución + O &okular; é un visor universal de documentos parao &kde; baseado no código da aplicación &kpdf;. Apesar de se basear no código do &kpdf;, o &okular; ten certas características únicas, como o modo XXX, XXX e que permite anotación. + + + + Uso básico + + Abrir ficheiros + To view any supported file in &okular;, select FileOpen... , choose a supported file in the dialog and click Open. Your file should now be displayed in the main window. + Se xa se teñen aberto ficheiros no &okular;, pódese chegar rápido a eles seleccionándoos no menú FicheiroAbir recente. + Despois de abrir un ficheiro, o máis seguro e que o queira ler e, polo tanto, navegar por el. Vaia á vindeira sección para aprender máis sobre isto. + + + Navegación + Esta sección describe como se pode navegar por un documento no &okular;. + + Existen varias maneiras de se desprazar pola área de visualización. Unha é empregar as teclas Frecha para riba e Frecha para baixo. Tamén se pode empregar a barra de desprazamento, a rodiña do rato ou as teclas Retroceder páxina e Avanzar páxina. + Outra maneira é manter premido o &LMB; en calquera sitio do documento ao tempo que se arrastra o rato en sentido oposto ao que se quere mover. Este procedemento só funciona se a ferramenta Navegación está activada, o que se pode facer escollendo FerramentasFerramenta Navegación. + O panel de navegación da parte esquerda da pantalla permite dúas maneiras máis de navegar por un documento: + + + Cando se preme a miniatura dunha páxina, a área de visualización pasa para esa páxina. + + + If the document has a table of contents, clicking on a table of contents item will bring the document to the page linked to that item. + + + Some documents have links. In this case you can click on them and the view will change to the page it links to. If the link is to a web page or some other document the default &kde; handler for that format will be invoked. For example, clicking on a link pointing to http://www.kde.org will open the web page in the default &kde;'s web browser. + Alén disto, pódese empregar a funcionalidade seguinte para se mover rapidamente a lugares específicos do documento: + + + You can go to the first page of the document using &Ctrl;Home or using Go First Page . + + + You can go to the last page of the document using &Ctrl;End or using Go Last Page . + + + You can go forward in the document using Space or Page Down. To go to the next page of the document use the Next Page Toolbar button or Go Next Page in the menubar. + + + You can go back in the document using &Backspace; or Page Up. To go to the previous page of the document use Previous Page Toolbar button or Go Previous Page in the menubar. + + + + + Modo de presentación + O modo de presentación representa outra maneira de ver os documentos no &okular;. Pódese activar en VistaPresentación. Mostra o documento páxina tras páxina. As páxinas móstranse ocupando toda a páxina, quérese dicir que é visíbel toda a páxina. + + Os documentos &PDF; poden mesmo especificar que se abran sempre no modo de presentación. + + No modo de presentación pode haber unha barra de axuda situada na parte superior da pantalla. Só hai que mover o cursor para a parte superior da pantalla para que apareza. + Para se desprazar estre as páxinas pódense empregar o &LMB; (páxina seguinte ) e o &RMB; (páxina anterior), a rodiña do rato, as iconas das frechas ou a liña de edición da barra superior ou as teclas que se especifican na sección Navegación. + You can exit presentation mode at any time by pressing the &Esc; key or clicking the Quit icon in the top bar. + You can also draw on the current page with a pencil. Click on the Toggle Drawing Mode icon in the top bar to enable or disable the possibility of draw in the presentation mode. The drawings are cleared automatically when switching to another page, or manually selecting the Erase Drawings icon in the top bar. + O modo de presentación permite máis de unha pantalla nunha configuración con varios monitores. Con máis de unha pantalla aparece un botón novo da barra superior coa icona dunha pantalla: esta é unha caixiña que permite mover a presentación para calquera das outras pantallas disponíbeis. + O modo de presentación ten algunhas opcións de configuración, cuxa descrición se pode atopar no capítulo Configuración do &okular;. + + + + + Características avanzadas do &okular; + + Ficheiros embebidos + Se o documento actual ten ficheiros embebidos dentro, cando se tente abrir aparece unha barra amarela por riba da visualización da páxina para notificar sobre os ficheiros incrustados. + + A barra de ficheiros incrustrados + + + + + + A barra de ficheiros incrustrados + + + + Neste caso, pódese premer a ligazón do texto da barra ou escoller FicheiroFicheiros incrustrados para abrir o diálogo de ficheiros incrustados. O diálogo permite ver e extraer os ficheiros incrustrados. + + + Anotacións + &okular; allows you to review and annotate your documents. Annotations created in &okular; are automatically saved in the internal local data folder for each user. &okular; does not implicitly change any document it opens. + Since &kde; 4.2, &okular; has the "document archiving" feature. This is an &okular;-specific format for carrying the document plus various metadata related to it (currently only annotations). You can save a "document archive" from the open document by choosing FileExport AsDocument Archive. To open an &okular; document archive, just open it with &okular; as it would be ⪚ a &PDF; document. + + Debido a limitacións de DRM (tipicamente cos documentos &PDF;), non vai ser posíbel engadir, modificar algunhas propiedades ou eliminar anotacións. + + + Engadir anotacións + Para engadir anotacións ao documento hai que activar a barra de ferramentas de anotacións. Isto faise seleccionando FerramentasRevisar ou premendo F6. Cando apareza a barra de ferramentas de anotacións abonda con premer un dos botóns para comezar a construir esa anotación. + + A barra de ferramentas de anotacións pódese ancorar en calquer lateral da área de visualización: simplemente arrástrea para movela para outro lugar. + + + Activating the annotating toolbar will make you switch to the Normal Mode. + + You can stop the construction any time by pressing again on the button of the annotation you are constructing, or by pressing the &Esc; key. + A nova anotación construída ten como autor o autor que se designe na páxina Identidade do diálogo de &okular;configuración do . + + + Eliminación das anotacións + Para eliminar unha anotación abonda con premela co &RMB; e seleccionar Borrar. + Cando se elimina unha anotación féchase a súa xanela, se estaba aberta. + + Esta opción non se puido activar porque o documento non permite eliminar as anotacións. + + + + Modificación das anotacións + To edit an annotation, click on it with the &RMB; and select Properties. A dialog will appear with the general annotation settings (like color and opacity, author, &etc;) and the settings specific to that annotation type. + Para mover unha anotación, manteña premida a tecla &Ctrl;, mova o punteiro do rato sobre ela e comece a arrastrala co &LMB;. + + Dependendo dos permisos do documento (tipicamente cos documentos &PDF;), algunhas opcións poden estar desactivadas. + + + + + + + A barra de menú + + + The <guimenu +>File</guimenu +> Menu + + + + &Ctrl;O Ficheiro Abrir... + + + Open a supported file or &okular; archive. If there is already an opened file it will be closed. For more information, see the section about Opening Files. + + + + + + Ficheiro Abrir un recente + + + Abrir, mediante un submenú, un ficheiro que xa se usara . Se nese momento se está a mostrar un ficheiro, este féchase. Para máis información consulte a sección sobre como abrir ficheiros. + + + + + + File Import PostScript as &PDF;... + + + Abrir un ficheiro PostScript e convertelo en &PDF;. + + + + + + Ficheiro Gardar como... + + + Gravar o ficheiro aberto cun nome diferente empregando o proceso de fondo para ese documento. Co proceso de fondo dos &PDF; (requírese Popler +>=0.8), é posíbel gravar o documento cos valores modificados dos campos dos formularios. + + + + + + Ficheiro Gardar unha copia como... + + + Save a copy of the currently open file under a different name without using the current document backend. + + + + + + F5 Ficheiro Cargar de novo + + + Volver a cargar o ficheiro que está aberto. + + + + + + &Ctrl;P Ficheiro Imprimir... + + + Imprimir o documento que se está a mostrar. + + + + + + Ficheiro Antever o impreso... + + + Mostrar unha previsualización de como se imprimiría o documento actual coas opcións predeterminadas. + + + + + + Ficheiro Propiedades + + + Mostrar información básica acerca do documento, como o título, o autor, a data de creación e detalles acerca dos tipos de letra empregados. A información disponíbel depende do tipo de documento. + + + + + Ficheiro Ficheiros incrustrados... + + + Mostrar os ficheiros incrustrados no documento, se tiver algún. Para máis información consulte a sección sobre os ficheiros incrustados. + + + + + + Ficheiro Exportar como + + + O elemento contén os formatos de exportación aos que se pode exportar o documento. A primeira entrada para todos os tipos de documentos é sempre Texto simple... + The second entry is Document Archive, which allows you to save the document with your annotations into an &okular;-specific archive format. Thus it is easily possible to share the original document and your annotations with other &okular; users or work with them collaboratively. + + + + + + &Ctrl;Q Ficheiro Sair + + + Fechar o &okular; + + + + + + + The <guimenu +>Edit</guimenu +> Menu + + + + &Ctrl;C Editar Copiar + + + Copiar para o portarretallos o texto seleccionado no modo Selección de texto. + + + + + + + + &Ctrl;A Editar Seleccionar todo + + + Selecciona todo o texto (se o documento tiver). Isto só funciona no mdoo Selección de texto. + + + + + + + + &Ctrl;F Editar Procurar... + + + Mostrar a barra de pesquisas na parte inferior da área de visualización, que permite procurar unha cadea no documento. + + + + + + F3 Editar Procurar a seguinte + + + Tentar atopar de novo a cadea que se procurou no documento. + + + + + + &Shift;F3 Edit Find Previous + + + Goes to the previous occurrence of the search string in the document. + + + + + + + The <guimenu +>View</guimenu +> Menu + + + + &Ctrl;&Shift;P Vista Presentación + + + Activa o modo Presentación. Para máis información consulte a sección sobre o modo Presentación. + + + + + &Ctrl;+Vista Achegar + + + Incrementar o aumento da vista do documento. + + + + + + &Ctrl;-Vista Alonxar + + + Diminuir o aumento da vista do documento. + + + + + Vista Axustar ao ancho + + + Mudar o aumento da vista do documento para un valor que faga que a largura das páxinas sexa igual á largura da vista do documento. + + + + + Vista Axustar á páxina + + + Mudar o aumento da vista do documento para un valor que faga visíbel ao menos unha páxina enteira. + + + + + Vista Continuo + + + Activar o modo de páxina continuo. No modo continuo móstranse todas as páxinas e pódese andar por elas sen ter que empregar as opcións Ir Páxina anterior e IrPáxina seguinte. + + + + + Vista Modo da vista + + + This submenu makes you choose the view mode for the pages. The possible options are: Single Page (only one page per row), Facing Pages (two pages per row, in a book style) and Overview (the number of columns is the one specified in the &okular; settings). + + + + + Vista Orientación + + + Este submenú permite mudar a orientación das páxinas do documento. + + A rotación aplícase á orientación de todas as páxinas. + + Pódese seleccionar Orientación orixinal para volver á orientación orixinal do documento, rexeitando todas as rotacións que se aplicasen manualmente. + + + + + Vista Tamaño da páxina + + + Muda o tamaño das páxinas do documento. + + Este submenú só está activo se o tipo de documento permite tamaños de páxina diferentes. + + + + + + View Trim Margins + + + Eliminar o bordo branco das páxinas ao velas. + + + + + Vista Mostrar/Acochar os formularios + + + Mostrar ou acochar a visualización dos campos de formulario do documento. + + Este elemento do menú só está activo se o documento ten campos de formulario. + + + + + + + + The <guimenu +>Go</guimenu +> Menu + + + + &Backspace; Go Previous Page + + + Ver a páxina anterior do documento. + + + + + Space Go Next Page + + + Ver a páxina seguinte do documento. + + + + + &Ctrl;Home Go First Page + + + Go to the first page of the document. + + + + + &Ctrl;End Go Last Page + + + Go to the last page of the document. + + + + + Go Back in the Document + + + Recuar para a vista anterior do documento. + + + + + Go Forward in the Document + + + Avanzar para a seguinte vista do documento. Isto só funciona se xa se recuou antes. + + + + + &Ctrl;G Ir Ir á páxina... + + + Abrir un diálogo que permite ir a calquera páxina do documento. + + + + + + + The <guimenu +>Bookmarks</guimenu +> Menu + + + + &Ctrl;B Marcadores Engadir/Eliminar un marcador + + + Engadir ou eliminar un marcador da páxina actual. + + + + + Marcadores Anterior marcador + + + Ir á páxina marcada anterior ou non facer nada se non hai páxinas marcadas antes da actual. + + + + + Marcadores Seguinte marcador + + + Ir á seguinte páxina marcada ou non facer nada se non hai páxinas marcadas despois da actual. + + + + + Marcadores Sen marcadores + + + Esta é unha acción que está sempre desactivada que aparece neste menú só se o documento actual non ten marcadores. Se non, aquí aparece unha lista de todas as páxinas marcadas. Premer estes marcadores permite ir directamente ás páxinas asociadas. + + + + + + + The <guimenu +>Tools</guimenu +> Menu + + + + &Ctrl;1 Ferramentas Ferramenta de navegación + + + The mouse will have its normal behavior, &LMB; for dragging the document and following links and &RMB; for adding bookmarks and fit to width. + + + + + &Ctrl;2 Ferramentas Ferramenta de ampliación + + + O rato funciona como ferramenta de ampliación. Premer o &LMB; arrastrar amplía a vista para a área seleccionada, premer &RMB; devolve o documento á ampliación anterior. + + + + + &Ctrl;3 Ferramentas Ferramenta de selección + + + O rato funciona como ferramenta de selección. Neste modo, premer o &LMB; e arrastrar dá a opción de copiar o texto ou imaxe da área seleccionada para o portarretallos, ler un texto ou gravar unha imaxe nun ficheiro. + + + + + &Ctrl;4 Ferramentas Ferramenta de selección de texto + + + O rato funciona como ferramenta de selección de texto. Neste modo, premer o &LMB; e arrastrar dá a opción de seleccionar o texto do documento. Despois, simplemente preme co &RMB; para copiasr para o portarretallos ou para ler a selección. + + + + + F6 Ferramentas Revisar + + + Abrir a barra de ferramentas de revisión. A barra de ferramentas de revisión permite engadir anotacións ao documento que se está a ler. Para máis información consulte a selección sobre as anotación. + + + + + Ferramentas Ler todo o documento + + + Ferramentas Ler a páxina actual + + + Ferramentas Deter a locución + + + These items allow you to speak the whole document or just the current page and stop speaking using the &kde; Text-to-Speech system KTTS. + The Speak ... actions are enabled only if KTTS is available in the system. + + + + + + + The <guimenu +>Settings</guimenu +> Menu + + + + &Ctrl;M Configuración Mostrar a barra de menú + + + Toggle the Menubar display on and off. Once hidden it can be made visible using the shortcut &Ctrl;M again. + + + + + Configuración Mostrar barra de ferramentas + + + Conmutar que se vexa a barra de ferramentas. + + + + + F7 Configuración Mostrar o panel de navegación + + + Conmutar que se vexa o panel de navegación. + + + + + &Ctrl;&Shift;F Configuración Modo a pantalla completa + + + Activa o modo a pantalla completa. Lembre que o modo a pantalla completa é diferente do modo de presentación polo feito de que a única peculiaridade do modo a pantalla completa é que este acocha as decoracións da xanela, a barra de menú e a barra de ferramentas. + + + + + Configuración Configurar os atallos de teclado... + + + Abre unha xanela que permite configurar os atallos do teclado para moitos comandos do menú. + + + + + Configuración Configurar as barras de ferramentas... + + + Abre unha xanela que permite escoller as iconas que ficarán visíbeis na barra de ferramentas. + + + + + Configuración Configurar as infraestruturas... + + + Abre a xanela Configuración das infraestruturas + + + + + Configuración Configurar &okular;... + + + Abre a xanela de configuración. + + + + + + + The <guimenu +>Help</guimenu +> Menu +&help.menu.documentation; + + + + Configuración do &okular; + + Configuración xeral + You can configure &okular; by choosing Settings Configure &okular;.... The configuration dialog is split into six sections. This chapter describes the available options in detail. + + + General + + + Accessibility + + + Performance + + + Presentation + + + Identity + + + Editor + + + + The configuration dialog + + + + + + The configuration dialog + + + + Depending on the currently installed backends, the Settings Configure Backends... menu item could be enabled. This particular configuration dialog holds the configurations of the backends that can actually be configured. + + + Xeral + + + Mostrar barras de desprazamento + + Se mostrar as barras de desprazamento na vista do documento. + + + + Ligar as miniaturas coa páxina + + Se a vista de miniaturas debería mostrar a páxina actual ou non. + + + + Mostrar os consellos e mensaxes de información + + Se mostrar algunhas mensaxes informativas ao incio, cando se cargue un ficheiro, &etc;. + + + + Obedecer as limitacións DRM + + Se o &okular; debe obedecer as restricións de DRM (Xestión de dereitos dixitais, Digial Rights Management). As limitacións DRM empréganse para que sexa imposíbel realizar determinadas accións cos documentos &PDF;, como copiar o contido para o portarretallos. Nalgunhas configuracións do &okular; non se dispón desta opción. + + + + Cargar de novo o documento ao cambiar de ficheiro + + Se hai que comprobar automaticamente se se modificaron os ficheiros abertos e actualizalos, de ser o caso. + + + + Mostrar o diálogo de escolla de infraestrutura + + Se o &okular; lle debe preguntar ao usuario que infraestrutura empregar no caso de que se dispoña de máis dunha para abrir o ficheiro. Se non se selecciona, o &okular; emprega a infraestrutura que teña maior prioridade. + + + + Center first page + + Whether the first page should be centered or aligned to the left when displaying the pages in facing and overview mode. + + + + Colunas de resumo + + Esta opción representa o número de columnas que se han empregar no modo de resumo. + + + + + + Accesibilidade + + + Debuxar un bordo arredor das ligazóns + + Se debuxar un bordo arredor das ligazóns. + + + + Change colors + + Activa as opcións para alterar as cores. + + + + Invert Colors + + Inverte as cores na visualización, &ie; os obxectos negros móstranse en branco. + + + + Change Paper Color + + Muda a cor do papel, &ie; o fondo do documento. + + + + Cambiar as cores escuras e claras + + Muda a cor escura e a clara ao que prefira vostede, o que significa que o negro non se mostra como negro, senón como a cor escura seleccionada, e o branco non se mostra como branco, senón como a cor clara seleccionada. + + + + Converter a branco e negro + + Converts the document to black and white. You can set the threshold and the contrast. Setting the threshold to a higher value will result in darker grays used. + + + + + + Rendemento + + + Habilitar os efectos de transparencia + + Debuxar as seleccións e outros gráficos especiais empregando efectos de transparencia. Desactive esta opción para que se debuxen con estilos de bordo e de recheo opacos e se incremente a velocidade das seleccións. + + + + Habilitar a xeración de fondo + + Empregar un fío de fondo para xerar as páxinas. Se se desactiva esta opción a interface do usuario tórnase menos áxil (bloquéase se é preciso), mais as páxinas móstranse un pouco máis rápido. + + + + Memory Usage + + O &okular; pode lograr o mellor desempeño se se axusta o uso da memoria baseándose no sistema e nos gostos do usuario. Canta máis memoria se lle permita empregar, máis rápido se comportará o programa. O perfil Normal é bon para todos os sistemas, mais pódese evitar que o &okular; empregue máis memoria da precisa seleccionando o perfil Baixo ou permitir obter o máximo do sistema co Agresivo. + + + + + + Presentación + + + Avanzar cada + + Activa o avanzo automático das páxinas dado un período de tempo. + + + + Recomezar despois da última páxina + + Nos modos de navegación e de presentación, cando se passa da derradeira páxina aparece a primeira. + + + + Cor do fondo + + A cor que enche a parte da pantalla que non cobre a páxina no modo de presentación. + + + + Cor do lapis + + A cor do lapis que se emprega cando se debuxa nas páxinas durante o modo de presentación. + + + + Cursor do rato + + Se o rato debe estar sempre acochado, sempre visíbel ou se debe acocharse despois dun breve período de inactividade. + + + + Mostrar o indicador de progreso + + Whether to show a progress circle that shows the current page and the total number of pages on the upper right corner of the presentation screen every time you change the page. + + + + Mostrar a páxina de resumo + + Se mostrar unha páxina de resumo ao comezo da presentación co título, autor e número de páxinas do documento. + + + + Transición por omisión + + O efecto de transición entre páxina e páxina se o documento non especifica un. Configure isto como Transición aleatoria para que o &okular; escolla un dos efectos disponíbeis ao chou. + + + + Situación + + Nesta sección pódese seleccionar a Pantalla que se quere empregar para mostrar a presentación. + Pantalla actual é a mesma pantalla da xanela do &okular; que inicia o modo de presentación. + Pantalla predeterminada é a pantalla marcada por omisión na configuración do xinerama. + Pantalla 0, Pantalla 1, &etc; son as pantallas disponíbeis. + + + + + + Identidade + + + Autor + + The author of the contents added on a document. + + + + + + Editor + + + Editor + + Choose the editor you want to launch when &okular; wants to open a source file. This is the case when the document has references to the various points (usually row and column number) of sources it was generated from. The &DVI; format supports natively the addition of the information about the sources the LaTeX document was generated from. A similar system exists for &PDF; documents, called pdfsync, which stores these extra information in an external file named after the &PDF; file itself (for example mydocument.pdfsync for mydocument.pdf). + + + + Command + + This is the command and its parameters to invoke the selected editor with the source file of the actual document. + + + + + + + Créditos e licenza + + + Copyright do programa: + Albert Astals Cidaacid@kde.org + Pino Toscano pino@kde.org Mantedor actual + Enrico Roseros.kde@email.it programador de &kpdf; + + + + Copyright da documentación: + Albert Astals Cidaacid@kde.org Autor + Titus Laskatitus.laska@gmx.de Algunhas actualizacións e engadidos + Pino Toscano pino@kde.org + + Xosé Calvo xose.calvo@gmail.com +&underFDL; &underGPL; + + + Instalación + + Como obter o &okular; +&install.intro.documentation; + + Compilación e instalación + + Se está a ler esta axuda no &khelpcenter;, o &okular; xa está instalado neste sistema e non hai por que instalalo máis. + &install.compile.documentation; + + &documentation.index; +
+ + + diff --git a/po/gl/okular.po b/po/gl/okular.po new file mode 100644 index 0000000..042b107 --- /dev/null +++ b/po/gl/okular.po @@ -0,0 +1,5837 @@ +# translation of okular.po to galician +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Xabi García , 2003. +# Martina Ramilo Pereira , 2004, 2005. +# Xabi G. Feal , 2006, 2007. +# mvillarino , 2007, 2008, 2009. +# Xosé , 2008, 2012. +# Marce Villarino , 2009. +# Miguel Branco , 2010, 2013. +# Marce Villarino , 2012, 2013, 2014. +# Adrián Chaves Fernández , 2015, 2016, 2017. +# Adrián Chaves (Gallaecio) , 2017, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-03-07 08:25+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.08.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Martina Ramilo Pereira, mvillarino, Xosé Calvo, Adrián Chaves Fernández" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"martina.ramilo@hispalinux.es, mvillarino@gmail.com, proxecto@trasno.gal, " +"adrian@chaves.io" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un visor universal de documentos" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004-2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004-2017 Albert Astals Cid\n" +"© 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Anterior mantedor" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Moito traballo no framework, infraestruturas para ODT e FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Desenvolvedor." + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Creou Okular a partir de código de KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Desenvolvedor de KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Traballo gráfico das anotacións" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Ferramenta de selección de táboas" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Melloras nas anotacións" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Ir á páxina %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Abrir un ficheiro externo" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Executar «%1»…" + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Primeira páxina" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Páxina anterior" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Seguinte páxina" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Última páxina" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Atrás" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Adiante" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Saír" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Comezar a presentación" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Finalizar a presentación" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Atopar…" + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Ir á páxina…" + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reproducir un son…" + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script de JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reproducir un filme…" + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Reproducir un filme" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Parar o filme" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Parar o filme…" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Continuar o filme" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Escolla da infraestrutura" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Atopouse máis dunha infraestrutura para o tipo mime:
%1 (%2)." +"

Escolla a que queira usar:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Ir á páxina %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Retrato %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Apaisado %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1×%2 polgadas (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1×%2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Continúase a busca polo principio." + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Continuar a busca desde o final" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Non se pode atopar un complemento que sexa capaz de xestionar o documento " +"que se pasou." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Retirar as anotacións" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"O documento intenta executar unha aplicación externa e para a súa seguranza " +"Okular non llo permite." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Non se atopou unha aplicación para abrir o ficheiro de tipo mime %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Non se puido acceder a un ficheiro temporal" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Fallou a conversión da impresión" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "O proceso de impresión quebrou" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Non se puido comezar o proceso de impresión" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Fallou a impresión nun ficheiro" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "A impresora estaba nun estado incorrecto" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Non se pode atopar o ficheiro que imprimir" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Non había ficheiro que imprimir" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Non se puido atopar un binario axeitado para imprimir. Asegúrese de que o " +"binario lpr de CUPS estea dispoñíbel" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "O tamaño de impresión da páxina é incorrecto." + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Non se puido abrir «%1». Non existe ese ficheiro." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Título" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Asunto" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Descrición" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creador" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Produtor" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Páxinas" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Creado" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificado" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Tipo mime" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoría" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Palabras clave" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Ruta ao ficheiro" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Tamaño do ficheiro" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Tamaño da páxina" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "Engadir unha anotación" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Retirar a anotación" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Modificar as propiedades da anotación" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Traducir a anotación" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "axustar a anotación" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Editar o texto" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Editar o contido da anotación" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "Editar o contido do formulario" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "Editar a selección da lista do formulario" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "Editar a selección do combo do formulario" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "Editar os estados do botón do formulario" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Te&xto simple…" + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Texto de OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opcións de impresión" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Axustar á zona imprimíbel" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Axustar á páxina completa" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de cambio de dimensións:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Falta o tipo de alerta" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Non volver mostrar esta mensaxe" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Fonte: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Fonte &predeterminada:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Red" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Vermello" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Yellow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Amarelo" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgid "Green" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verde" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, fuzzy, kde-format +#| msgid "Blue" +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Azul" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, fuzzy, kde-format +#| msgid "White" +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Branco" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, fuzzy, kde-format +#| msgid "Black" +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Negro" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "&Width:" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "&Anchura:" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "V%1" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "V%1" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Opcións das anotacións" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Ferramentas de anotación" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Ferramentas de anotación" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Ferramentas de anotación" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Ferramentas de anotación" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Anotación" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opcións das anotacións" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Cor:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Cor:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgctxt "@info" +#| msgid "" +#| "experimental feature.Stamps inserted in PDF documents are " +#| "not visible in PDF readers other than Okular." +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"Funcionalidade experimental.Os selos inseridos en documentos " +"PDF non se poden ver noutros lectores de PDF, só en Okular." + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Experimental" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "Utilidade de &selección" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "Anotacións" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlighter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Realzador" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Subliñado" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Borrancho" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Riscado" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Typewriter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Campo para completar" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota incluída" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota emerxente" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Liña a man alzada" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Liña recta" + +#: part/annotationactionhandler.cpp:529 +#, fuzzy, kde-format +#| msgid "Open Arrow" +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Frecha aberta" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectángulo" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipse" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polígono" + +#: part/annotationactionhandler.cpp:534 +#, fuzzy, kde-format +#| msgid "Geometrical shape" +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Forma xeométrica" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Selo" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anotacións" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Engadir unha anotación" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Ferramenta de creación de anotacións" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Fonte:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Opcións das anotacións" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line end:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Fin de liña:" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&Opacidade:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Páxina %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anotación" +msgstr[1] "%1 anotacións" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Abrir a nota emerxente" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Eliminar" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Propiedades" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Gardar «%1»…" + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Aparencia" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Xeral" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Creado:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificado:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Propiedades da nota emerxente" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Propiedades dos campos para completar" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Propiedades da nota incluída" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Propiedades da liña recta" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Propiedades do polígono" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Propiedades da forma xeométrica" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Propiedades das etiquetas de texto" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Propiedades do selo" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Propiedades da liña a man alzada" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Propiedades do cursor" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Propiedades do ficheiro anexo" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Propiedades do son" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Propiedades do filme" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Propiedades da anotación" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificado: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Seleccionar un símbolo de selo personalizado dun ficheiro" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Seleccionar un símbolo de selo personalizado" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Ficheiros de iconas (*.ico *.png *.xpm *." +"svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Non se puido cargar o ficheiro %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "Ficheiro incorrecto" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Cor:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacidade:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icona:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Comentario" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Axuda" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Inserir" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Chave" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Novo parágrafo" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Parágrafo" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Fonte:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Cor do texto:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Aliñado:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Á esquerda" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centrar" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Á dereita" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "&Anchura do bordo:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Aprobado" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Como é" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidencial" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Compartimentado" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Borrador" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Para comentar" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Para publicar" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Non aprobado" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Non publicar" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Vendido" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Máximo segredo" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Marcador" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Información" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"Funcionalidade experimental.Os selos inseridos en documentos " +"PDF non se poden ver noutros lectores de PDF, só en Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Símbolo do selo:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Anchura:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Inicio de liña:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Fin de liña:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Cadrado" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Círculo" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Rombo" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Frecha aberta" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Frecha pechada" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Nada" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Cu" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Frecha aberta dereita" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Frecha pechada dereita" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra inclinada" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Lonxitude da liña directriz:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Lonxitude das extensión da liña directriz:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Activada" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Recheo da forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipo:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Realzar" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Borrancho" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Subliñado" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Riscado" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectángulo" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Símbolo de ficheiro anexo:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Gráfico" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Chincheta" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Clip" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiqueta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Ficheiro" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/D" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Non hai ningunha descrición dispoñíbel." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nome:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Descrición:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Símbolo do cursor:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ningún" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Pechar esta nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcións" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Esta anotación pode conter texto en LaTeX.\n" +"Prema aquí para mostralo." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Non se pode atopar o executábel de latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Fallou o debuxado de LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Non se pode atopar o executábel de dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Produciuse un problema durante a execución da orde «latex»." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Produciuse un problema durante a execución da orde dvipng»." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Un marcador" +msgstr[1] "" +"%1\n" +"\n" +"%2 marcadores" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Marcadores" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Buscar…" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Só o documento actual" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Ir a este marcador" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Renomear o marcador" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Retirar o marcador" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Abrir un documento" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Retirar os marcadores" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versión" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Número de serie" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emisor" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emitido o" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Caduca o" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Asunto" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Chave pública" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Uso de chave" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Propiedade" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valor" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Visor de certificados" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exportar…" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Xeral" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emitido por" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nome común (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Correo electrónico" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organización (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emitido a" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validez" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Pegadas dixitais" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Pegada dixital SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Pegada dixital SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detalles" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Datos do certificado:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Onde quere gardar o certificado?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "Ficheiro de certificado (*.cer)" + +#: part/certificateviewer.cpp:321 +#, fuzzy, kde-format +#| msgid "Unable to export certificate!" +msgid "Could not export the certificate" +msgstr "Non se pode exportar o certificado!" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Vermello" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verde" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Azul" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Amarelo" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Negro" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Branco" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Debuxar un bordo arredor das &imaxes" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Debuxar un bordo arredor das &ligazóns" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Cambiar as &cores" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Coidado: estas opcións de debuxado poden afectar negativamente á velocidade." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Modo de cor:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverter as cores" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Cambiar a cor do papel" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Cambiar as cores escuras e claras" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Converter a branco e negro" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Cor do papel:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Cor escura:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Cor clara:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Limiar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contraste:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Fala" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identidade" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota: esta información úsase só para anotacións. A información " +"gárdase en documentos anotados, e polo tanto transmitirase xunto co " +"documento." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "Ferramenta de edición de anotacións" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor de texto personalizado" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Cliente do Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Cliente Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Indique a orde do editor de texto personalizado a iniciar.
\n" +"Tamén pode empregar caracteres de substitución:\n" +"
    \n" +"
  • %f : o nome do ficheiro
  • \n" +"
  • %l : a liña a acadar no ficheiro
  • \n" +"
  • %c : a columna a acadar no ficheiro
  • \n" +"
\n" +"Se non se especifica %f, entón engadirase o nome do ficheiro á orde " +"fornecida." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Escolla o editor que queira iniciar cando Okular queira abrir un ficheiro " +"fonte." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Orde:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Aparencia" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Mostrar barras de &desprazamento" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Ligar as &miniaturas coa páxina" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Mostrar os &consellos e mensaxes de información" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Mostrar o título do documento na barra de título de estar dispoñíbel." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Cando non se mostre o título do documento:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Mostrar só o nome do ficheiro" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Mostrar a ruta completa ao ficheiro" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usar unha cor de fondo personalizada." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Funcionalidades do programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Abrir os ficheiros novos en separadores" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obedecer as limitacións DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Cargar de novo o documento ao cambiar de ficheiro" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Mostrar o diálogo de escolla de infraestrutura" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Dirección de lectura de dereita a esquerda." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opcións da vista" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Columnas de resumo:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Define a porcentaxe da área de visualización actual que debería ser visíbel " +"ao premer as teclas Páxina arriba/abaixo." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Sola&pamento de páxina arriba/abaixo:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Define o modo de ampliación predeterminado dos ficheiros que non se abrisen " +"nunca antes.\n" +"Para os ficheiros que se abrisen antes emprégase o modo de ampliación " +"anterior." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Define o modo de ampliación predeterminado dos ficheiros que non se abrisen " +"nunca antes.\n" +"Para os ficheiros que se abrisen antes emprégase o modo de ampliación " +"anterior." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Ampliación predeterminada:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Axustar á anchura" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Axustar á páxina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Axuste automático" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Mantén a memoria empregada tan baixa como sexa posíbel. Non reutiliza nada. " +"(Para sistemas con pouca memoria)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un bo compromiso entre a memoria empregada e o aumento de velocidade. " +"Precargar a seguinte páxina e tamén as buscas. (Tipicamente para sistemas " +"con 2 GB de memoria)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Mantén todo na memoria. Precargar as páxinas seguintes. Acelerar as buscas " +"(Para sistemas con máis de 4 GB de memoria)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carga e mantén todo na memoria. Precargar todas as páxinas ñ(emprega un " +"máximo do 50% da memoria total ou da memoria libre, a que sexa maior)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Uso da CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Activar os efectos de &transparencia" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Uso da memoria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Baixo" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (predeterminado)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Agr&esivo" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "Cobi&zoso" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Debuxado" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Activar o suavizado do texto." + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Activar o suavizado das imaxes." + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Activar o axuste do texto." + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Pantalla actual" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Pantalla predeterminada" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla: %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " segundo" +msgstr[1] " segundos" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navegación" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avanzar cada:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Recomezar despois da última páxina" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navegación táctil:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Tocar os lados esquerdo e dereito para ir cara atrás e cara adiante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Toque en calquera parte para ir cara adiante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Desactivada" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Cor do fondo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Cursor do rato:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Agochar despois do retardo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Sempre visíbel" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Sempre agochado" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Mostrar o indicador de &progreso" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Mostrar a páxina de re&sumo" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Activar as transicións" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transición predeterminada:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Contras verticais" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Contras horizontais" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Caixa cara dentro" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Caixa cara fóra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Disolver" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Esvaer" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Cortina baixando" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Cortina cara á dereita" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Cortina dereita e baixando" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transición aleatoria" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Substituír" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Dividir horizontalmente" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Saír da división horizontal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Dividir verticalmente" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Saír da división vertical" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Limpar cara a abaixo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Limpar cara a dereita" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Limpar cara a esquerda" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Limpar cara a arriba" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Situación" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Pantalla:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuración da ferramenta de debuxo" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Ferramenta de debuxo: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Borrador" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nome:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipo:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota emerxente" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota incluída" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Liña a man alzada" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Liña recta" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polígono" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Etiquetas de texto" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma xeométrica" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Selo" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Campo para completar" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Ferramenta de creación de anotacións" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Ferramenta de edición de anotacións" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Cor:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Anchura do &bolígrafo:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Ferramenta de creación de debuxos" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Ferramenta de edición de debuxos" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Descoñecido" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Ficheiros incrustados" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Ver" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nome" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Descrición" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Tamaño" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Creado" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificado" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Gardar &como…" + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Ver…" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Non se puido cargar a compoñente de previsualización do impreso" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Vista previa do impreso" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Pechar" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Atopar:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Texto a buscar" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Seguinte" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Salta á coincidencia seguinte" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Anterior" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Saltar á coincidencia anterior" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modificar o comportamento da busca" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Distinguir as maiúsculas" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Da páxina actual" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Atopar a medida que escribe" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Todos os ficheiros" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Propiedades da sinatura" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Liña recta con comentario" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polígono con comentario" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Xeometría con comentario" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Xeometría" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Realzar con comentario" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Borrancho con comentario" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Subliñar con comentario" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Riscar con comentario" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Riscado" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Selo con comentario" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Liña a man alzada con comentario" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Cursor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Anexo do ficheiro" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Son" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Filme" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Pantalla" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Trebello" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Multimedia" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Descoñecido" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Onde quere gardar %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Non se puido abrir «%1» para escritura. Non se gardou o ficheiro." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opcións da busca" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Distinguir as maiúsculas" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expresión regular" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Buscar:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Capas" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "de" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Ampliar" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Ampliar ao 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rota&r á dereita" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Á dereita" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotar á &esquerda" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Á esquerda" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientación orixinal" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Axus&tar a vista" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Recor&tar as marxes" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Axustar á &selección" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Axustar á &anchura" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Axustar á &páxina" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Axuste automático" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Axustar a &xanela á páxina" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Modo da &vista" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Páxina única" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Páxinas opostas" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Páxinas opostas (Centrar a primeira páxina)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Resumo" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continuo" + +#: part/pageview.cpp:637 +#, fuzzy, kde-format +#| msgid "Right to left reading direction" +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Dirección de lectura de dereita a esquerda." + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Examinar" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Ampliar" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "C&onmutar o cambiar as cores" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selección de zona" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selección de &texto" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selección de &táboas" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lupa" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Ferramentas de selección" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Pronunciar todo o documento" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Pronunciar a páxina actual" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Deixar de pronunciar" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Deter ou continuar a pronuncia" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Desprazar cara riba" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Desprazar cara embaixo" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Desprazarse unha páxina cara riba" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Desprazarse unha páxina cara baixo" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Mostrar os formularios" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Cargouse un documento dunha páxina." +msgstr[1] " Cargouse un documento de %1 páxinas." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Texto (1 carácter)" +msgstr[1] "Texto (%1 caracteres)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copiar no portapapeis" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "O DRM prohibe a copia" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Pronunciar o texto" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Imaxe (%1 por %2 píxeles)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Gardar nun ficheiro…" + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "A imaxe [%1x%2] copiouse no portapapeis." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Gardar o ficheiro" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Imaxes (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Ficheiro non gardado." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "A imaxe [%1x%2] gardouse no ficheiro %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copiar o texto" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Ir a «%1»" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Buscar «%1» con" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configurar os atallos da web…" + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Seguir esta ligazón" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Reproducir este son" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Deter o son" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copiar o enderezo da ligazón" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Buscar «%1» no documento" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Benvida" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Seleccione a zona para ampliar. Faga clic dereito para afastar." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Prema para usar a vista de lupa." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Debuxe un rectángulo arredor do texto ou dos gráficos a copiar." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Escolla texto" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Debuxe un rectángulo arredor da táboa e a continuación prema preto dos " +"bordos para dividir; prema Esc para limpar." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Debuxe un rectángulo arredor da zona da páxina que quere manter visíbel." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nova nota de texto" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "O texto da nova nota:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "Engadir unha anotación" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Debuxar unha elipse (arrastre para escoller unha zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Realzar texto" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Debuxar unha liña a man alzada" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Anotación de texto na liña (arrastre para escoller unha zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Colocar unha nota emerxente" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Debuxar un polígono (prema o primeiro punto para pechalo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Debuxar un rectángulo" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Debuxar un borrancho" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Pór un selo" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Debuxar unha liña recta" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Riscar texto" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Subliñar texto" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Anotación de campo para completar (arrastre para escoller unha zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Realzador" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "Engadir unha anotación" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Change an annotation's size" +#| msgid "adjust annotation" +msgid "Custom annotation name:" +msgstr "axustar a anotación" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Ficheiro" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Configuración" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Axuda" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientación" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Marcadores" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra de ferramentas do visor" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniaturas" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anotacións" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Este documento contén anotacións ou datos de formulario que se gardaron " +"internamente cunha versión anterior de Okular. O almacenamento interno xa " +"non se permite.
Garde nun ficheiro para mover eses datos se quere " +"continuar editando o documento." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Este documento ten ficheiros incrustados. Prema aquí para velos ou vaia a «Ficheiro → Ficheiros incrustados»." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Anterior" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Ir á páxina anterior" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Moverse á páxina anterior do documento" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Seguinte" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avanzar para a seguinte páxina" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Moverse á vindeira páxina do documento" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Inicio do documento" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Móvese ao inicio do documento" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Final do documento" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Móvese ao final do documento" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Renomear este marcador" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Marcador anterior" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Ir ao marcador anterior" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Marcador seguinte" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Ir ao seguinte marcador" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configurar Okular…" + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configurar o visor…" + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configurar as infraestruturas do visor…" + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configurar as infraestruturas…" + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Sobre a infraestrutura" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Cargar de &novo" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Recargar o documento actual do disco." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Pechar a barra de &atopar" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Número de páxina" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Seleccionar todo o texto da páxina actual" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Mostrar a barra de &páxina" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Mostrar a barra de &páxina" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Mostrar o panel das sinaturas" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Ficheiros &incrustados" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xportar como" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Compartir" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentación" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Abrir o cartafol con&tedor" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importar un PostScript como PDF…" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obter libros de Internet…" + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Cambiar o modo de pantalla en negro" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Borrar o debuxo" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configurar as anotacións…" + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reproducir ou deter a presentación" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Non se puido abrir «%1» (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Cancelouse a carga de %1." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Non se puido abrir %1. Razón: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configurar as infraestruturas do visor" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configurar as infraestruturas" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Non se atopou o programa «ps2pdf», polo que Okular non pode importar " +"ficheiros PS mediante el." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "non se atopou ps2pdf" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Ficheiros PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Estase a importar o ficheiro PS como PDF (pode tardar un tempo)…" + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Insira o contrasinal para ler o documento:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "O contrasinal é incorrecto. Vólvao intentar:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Contrasinal do documento" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Este documento ten formularios XFA, que actualmente non se permiten." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Este documento ten formularios. Prema o botón para acceder a eles ou use " +"«Vista → Mostrar os formularios»." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Desactiváronse todas as funcionalidades de edición e interacción deste " +"documento. Garde unha copia e reábrao para editar o documento." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Este documento está asinado dixitalmente." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "This document is digitally signed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Este documento está asinado dixitalmente." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Este documento solicita mostrarse a pantalla completa.\n" +"Quere saír do modo normal e entrar no modo de presentación?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Solicitude para cambiar o modo de visualización" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Entrar no modo de presentación" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Denegar a solicitude" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Non se puido abrir %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Hai cambios sen gardar, e outro programa modificou o ficheiro «%1». Os seus " +"cambios perderanse, porque o ficheiro xa non se pode gardar.
Quere " +"continuar recargando o ficheiro?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Ficheiro cambiado" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continuar recargando" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interromper a recarga" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Hai cambios sen gardar, e outro programa modificou o ficheiro «%1». Os seus " +"cambios perderanse, porque o ficheiro xa non se pode gardar.
Quere " +"continuar pechando o ficheiro?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continuar pechando" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Interromper o peche" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Quere gardar os cambios que fixo en «%1» ou descartalos?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Pechar o documento" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Esta ligazón apunta a unha acción de peche de documento que non funciona " +"cando se usa o visor incrustado." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Esta ligazón apunta a unha acción de saída da aplicación que non funciona " +"cando se usa o visor incrustado." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Estase a recargar o documento…" + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contido" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Sinaturas" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Ir á páxina" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Páxina:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Insira o novo nome do marcador:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Renomear este marcador" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Retirar este marcador" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Gardar como" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Outro programa modificou o ficheiro «%1», o que significa que xa non se pode " +"gardar." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"O documento actual está protexido cun contrasinal.
Para gardar hai que " +"recargar o ficheiro. Preguntaráselle o contrasinal de novo e prederá o " +"historial de desfacer e refacer.
Quere continuar?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Gardar — Aviso" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Non se puido abrir o ficheiro temporal para gardar." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Tras gardar, o formado do documento actual require recargar o ficheiro. " +"Perderá o seu historial de desfacer e refacer.
Quere continuar?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Non se puido gardar o ficheiro en «%1». Inténteo gardar noutro sitio." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Campos de formulario completados." + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Anotacións de usuario." + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Está a piques de gardar cambios, pero o formato de ficheiro actual non " +"permite gardar os seguintes elementos. Use o formato de arquivo de " +"documento de Okular para preservalos." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Aviso" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Gardar como arquivo de documento de Okular…" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Está a piques de gardar cambios, pero o formato de ficheiro actual non " +"permite gardar os seguintes elementos. Use o formato de arquivo de " +"documento de Okular para preservalos. Prema Continuar para gardar " +"o documento e descartar estes elementos." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Está a piques de gardar cambios, pero o formato de ficheiro actual non " +"permite gardar os seguintes elementos. Use o formato de arquivo de " +"documento de Okular para preservalos. Prema Continuar para " +"gardar, pero perderá tanto estes elementos como o historial de desfacer e " +"refacer." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continuar" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continuar perdendo os cambios." + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Non se puido gardar o ficheiro en «%1». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular non pode copiar %1 no lugar especificado.\n" +"\n" +"O documento non existe máis." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Non se puido gardar o ficheiro en «%1». Erro: «%2». Inténteo gardar noutro " +"sitio." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expandir toda a sección" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Pregar toda a sección" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expandilas todas" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Pregalas todas" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Engadir un marcador" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Ferramentas" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Imprimir" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Non se permite imprimir este documento." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Non se puido imprimir o documento. Descoñécese este erro. Por favor, envíe " +"un informe de erro a bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Non se puido imprimir o documento. O erro detallado é «%1». Por favor, envíe " +"un informe de erro a bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Ir a onde estaba antes" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Ir a onde estivo despois" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Erro de ficheiro! Non se puido crear o ficheiro " +"temporal %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Erro de ficheiro! Non se puido abrir o ficheiro " +"%1 para descomprimilo. Non se puido cargar o " +"ficheiro." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Este erro ocorre polo xeral se non ten permisos de abondo para ler o " +"ficheiro. Pode comprobar a propiedade e permisos se fai clic dereito no " +"ficheiro en Dolphin, escoller a opción «Propiedades» e seleccionar o " +"separador «Permisos» na xanela que se abre." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Erro de ficheiro! Non se puido descomprimir o ficheiro " +"%1. Non se puido cargar o ficheiro." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Este erro ocorre polo xeral se o ficheiro está corrompido. Se quere " +"asegurarse, probe a descomprimilo manualmente usando ferramentas da liña de " +"ordes." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Sen marcadores" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Produciuse un problema ao compartir o documento: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Compartir" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Compartiuse o documento." + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Pode atopar o documento compartido en %1." + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Editar" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Vista" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Ir a" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Utilidades" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra de ferramentas principal" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Ferramentas de anotación" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opcións xerais" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accesibilidade" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Axudas para facer accesíbel a lectura" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Rendemento" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Optimización do rendemento" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configurar o visor" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentación" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opcións para o modo de presentación" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Opcións das anotacións" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Configuración do editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Atopar a seguinte" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentación" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Cambiar de pantalla" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Pantalla %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Saír do modo de presentación" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Título: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Páxinas: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Premer para comezar" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Deter" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reproducir" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Hai dous xeitos de saír do modo de presentación: pode premer a tecla ESC ou " +"premer o botón de saír que aparece cando se pon o rato na esquina superior " +"dereita. Por suposto, tamén pode circular polas xanelas (Alt+Tab de maneira " +"predeterminada)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Estase a facer unha presentación" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Ficheiro descoñecido" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Propiedades de %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fontes" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Lendo a información da fonte…" + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Tamaño da páxina" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extraer a fonte" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipo 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipo 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tipo 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipo 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tipo 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tipo 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tipo 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Métrica de fonte de TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX manexado por FreeType" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Descoñecida" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Incrustada (subconxunto)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Incrustada por completo" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Non" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Si (subconxunto)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Si" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (substituíndo por %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Fonte descoñecida" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Incrustada: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nome" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipo" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Ficheiro" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Páxinas" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Tamaño" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Vista previa da revisión" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Onde quere gardar a revisión?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Non se puido gardar o ficheiro %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Non se puido ver a revisión." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Insira polo menos tres letras para filtrar as páxinas" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Distinguir as maiúsculas" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Coincidir coa frase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Coincidir con todas as palabras" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Coincidir con calquera palabra" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opcións de filtro" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Sen anotacións

Para crear novas anotacións prema " +"F6 ou escolla Utilidades -> Revisar no menú.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Agrupar segundo a páxina" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Agrupar segundo o autor" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Mostrar só as revisións da páxina actual" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Despregar todos os elementos" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Pregar todos os elementos" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "A sinatura ten validez criptográfica." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "A sinatura é incorrecta a nivel criptográfico." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Produciuse un conflito de resumos." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "A estrutura CMS ou PKCS7 da sinatura é incorrecta." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "A sinatura solicitada non está presente no documento." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Non se puido verificar a sinatura." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Confíase no certificado." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Non se confía no emisor do certificado." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Descoñécese o emisor do certificado." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "O certificado revogouse." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "O certificado caducou." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Aínda non se verificou o certificado." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Problema descoñecido co emisor ou datos corruptos." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Descoñécese o algoritmo" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipo descoñecido" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Sinatura dixital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non repudiación" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Cifrar chaves" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Descifrar chaves" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Acordo de chave" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Asinar o certificado" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Asinar o CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Só cifrar" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Non se indicou ningún uso" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: asinada por %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Hora da sinatura: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Non dispoñíbel" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Razón: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Campo: %1 na páxina %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Propiedades" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "O documento non se modificou desde que se asinou." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"A revisión do documento que recibiu esta sinatura non se modificou;\n" +"porén o documento recibiu cambios subsecuentes." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"O documento modificouse dun xeito que o autor dunha sinatura anterior non " +"permite." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Non puido completarse a verificación da integridade do documento." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Estado da validez" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validez da sinatura:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modificacións do documento:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Información adicional" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Asinado por:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Hora da sinatura:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Razón:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Lugar:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versión do documento" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisión %1 de %2 do documento" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Ver a versión asinada…" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Ver o certificado…" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Mostrar só as páxinas marcadas" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reproducir" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pausar" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Deter" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Engadir…" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Editar…" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Retirar" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "&Subir" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "&Baixar" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Ferramenta de debuxo predeterminada núm. %1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Xa hai unha ferramenta con ese nome. Usarase un nome predeterminado." + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nome duplicado" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Páxina a mostrar do documento" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Iniciar o documento no modo presentación" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Iniciar co diálogo de impresión" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Iniciar co diálogo de impresión e saír tras imprimir." + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Control de «sesión única»" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Non elevar a xanela" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Atopar unha cadea no texto" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Os documentos para abrir. Indique «-» para ler da entrada estándar." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Erro: Non é posíbel abrir máis dun documento coa opción «--unique»." + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Erro: Non é posíbel abrir máis dun documento coa opción «--presentation»." + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Erro: Non é posíbel abrir máis dun documento coa opción «--print»." + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Erro: Non é posíbel abrir máis dun documento coa opción «--page»." + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Erro: Non é posíbel abrir máis dun documento coa opción «--find»." + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Non se pode atopar o compoñente de Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Xa se está a executar unha instancia de Okular única. Esta instancia non " +"será a única." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Non se pode atopar o compoñente de Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Prema para abrir un ficheiro\n" +"Prema e manteña premido para abrir un ficheiro recente" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Prema para abrir un ficheiro ou Prema e manteña premido para " +"escoller un ficheiro recente" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Seguinte separador" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Separador anterior" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Desfacer o peche de separador" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Todos os ficheiros (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Todos os ficheiros compatíbeis (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Abrir un documento" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirmar o peche" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Pechar os separadores" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Está a piques de pechar %1 separadores. Seguro que quere continuar?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Avisarme cando intente pechar varios separadores." + +#~ msgid "Reviews" +#~ msgstr "Revisións" + +#, fuzzy +#~| msgid "V%1" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "V%1" + +#~ msgid "Hide Forms" +#~ msgstr "Agochar os formularios" + +#~ msgid "Expired" +#~ msgstr "Caducado" + +#~ msgid "&Review" +#~ msgstr "&Revisar" + +#~ msgid "Annotations author" +#~ msgstr "Autor das anotacións" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Insira o seu nome ou iniciais:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Mostrar o panel de &navegación" + +#~ msgid "Show Text" +#~ msgstr "Mostrar o texto" + +#~ msgid "Small Icons" +#~ msgstr "Iconas pequenas" + +#~ msgid "Normal Icons" +#~ msgstr "Iconas normais" + +#~ msgid "Large Icons" +#~ msgstr "Iconas grandes" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Prema para usar a utilidade de selección escollida\n" +#~ "Prema na frecha para escoller outra utilidade de selección" + +#~ msgid "Created: %1" +#~ msgstr "Creado: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Extensión da liña" + +#~ msgid "Style" +#~ msgstr "Estilo" + +#~ msgid "&Size:" +#~ msgstr "Dimen&sións:" + +#~ msgid "Inner color:" +#~ msgstr "Cor interna:" + +#~ msgid "Name: %1" +#~ msgstr "Nome: %1" + +#~ msgid "Size: %1" +#~ msgstr "Tamaño: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Utilidade de &navegación" + +#~ msgid "&Zoom Tool" +#~ msgstr "Utilidade de &liación" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Ampliar" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Selección" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Utilidade de selección de te&xto" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Utilidade de &selección de táboas" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Lupa" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Final do documento" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Ningún" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "O documento pediu ser iniciado en modo de presentación.\n" +#~ "Quere permitirllo?" + +#~ msgid "Presentation Mode" +#~ msgstr "Modo de presentación" + +#~ msgid "Allow" +#~ msgstr "Permitir" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Permite o modo de presentación" + +#~ msgid "Do Not Allow" +#~ msgstr "Non permitir" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Non permitir o modo presentación" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Os cambios nas anotacións non se van gardar automaticamente. Empregue " +#~ "«Ficheiro → Gardar como…»\n" +#~ "ou os cambios perderanse ao pechar o documento." + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Okular garda automaticamente as anotacións.\n" +#~ "Pode exportar o documento anotado empregando «Ficheiro → Exportar como → " +#~ "Arquivo de documento»." + +#~ msgid "Save &Copy As..." +#~ msgstr "Gardar unha &copia como…" + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "As anotacións non se exportarán.\n" +#~ "Pode exportar o documento anotado empregando «Ficheiro → Exportar como → " +#~ "Arquivo de documento»." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Acadouse a fin do documento.\n" +#~ "Desexa continuar desde o inicio?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Acadouse o comezo do documento.\n" +#~ "Desexa continuar desde o final?" + +#~ msgid "Current maintainer" +#~ msgstr "Mantedor actual" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " seg." + +#~ msgid "Pencil color:" +#~ msgstr "Cor do lapis:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "DIN/ISO A0 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "DIN/ISO A0 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "DIN/ISO A1 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "DIN/ISO A1 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "DIN/ISO A2 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "DIN/ISO A2 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "DIN/ISO A3 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "DIN/ISO A3 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "DIN/ISO A4 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "DIN/ISO A4 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "DIN/ISO A5 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "DIN/ISO A5 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "DIN/ISO A6 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "DIN/ISO A6 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "DIN/ISO A7 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "DIN/ISO A7 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "DIN/ISO A8 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "DIN/ISO A8 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "DIN/ISO A9 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "DIN/ISO A9 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "DIN/ISO B0 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "DIN/ISO B0 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "DIN/ISO B1 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "DIN/ISO B1 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "DIN/ISO B2 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "DIN/ISO B2 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "DIN/ISO B3 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "DIN/ISO B3 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "DIN/ISO B4 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "DIN/ISO B4 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "DIN/ISO B5 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "DIN/ISO B5 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "DIN/ISO B6 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "DIN/ISO B6 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "DIN/ISO B7 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "DIN/ISO B7 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "DIN/ISO B8 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "DIN/ISO B8 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "DIN/ISO B9 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "DIN/ISO B9 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "DIN/ISO B10 horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "DIN/ISO B10 vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "Carta horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "Carta vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "Legal horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "Legal vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "Executivo horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "Executivo vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "Comm10E horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "Comm10E vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "DLE horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "DLE vertical" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "Folio horizontal" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "Folio vertical" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "Libro maior" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "Tabloide" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "Folla horizontal de tamaño descoñecido" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "Folla vertical de tamaño descoñecido" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Conmutar o modo de debuxo" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Fallou o arranque do servizo Jovie de texto lido: %1" + +#~ msgid "Search Columns" +#~ msgstr "Columnas de busca" + +#~ msgid "All Visible Columns" +#~ msgstr "Todas as columnas visíbeis" + +#~ msgid "No document opened." +#~ msgstr "Non hai ningún documento aberto." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Non é posíbel abrir máis de un documento na instancia única de Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Non se atoparon coincidencias con «%1»." + +#~ msgid "Search in progress..." +#~ msgstr "Busca en marcha..." + +#~ msgid "Searching for %1" +#~ msgstr "Estase a buscar %1" + +#~ msgid "Identity Settings" +#~ msgstr "Configuración da identidade" + +#~ msgid "Highlight Properties" +#~ msgstr "Propiedades do realce" + +#~ msgid "Ink Properties" +#~ msgstr "Propiedades da tinta" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Anotación de texto" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Tinta verde" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Realzado amarelo" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Realzado amarelo" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Liña recta amarela " + +#~ msgid "Black Underlining" +#~ msgstr "Subliñado en negro" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Subliñar o texto cunha liña negra" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Elipse cian" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Unha elipse cian" + +#~ msgid "Ink" +#~ msgstr "Tinta" diff --git a/po/gl/okular_chm.po b/po/gl/okular_chm.po new file mode 100644 index 0000000..82dc1fd --- /dev/null +++ b/po/gl/okular_chm.po @@ -0,0 +1,64 @@ +# translation of okular_chm.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# mvillarino , 2007, 2008. +# Marce Villarino , 2009. +# Adrián Chaves (Gallaecio) , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-03-07 08:22+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.08.3\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codificación incompatíbel" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"A codificación deste libro electrónico aínda non é compatíbel. Informe do " +"fallo en https://bugs.kde.org para engadirmos compatibilidade" + +#~ msgid "CHM Backend" +#~ msgstr "Infraestrutura para CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Un visor de ficheiros de axuda de Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/gl/okular_comicbook.po b/po/gl/okular_comicbook.po new file mode 100644 index 0000000..a9336b4 --- /dev/null +++ b/po/gl/okular_comicbook.po @@ -0,0 +1,60 @@ +# translation of okular_comicbook.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2008. +# Xosé , 2008. +# Marce Villarino , 2009, 2014. +# Adrián Chaves (Gallaecio) , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-17 20:29+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Non se pode abrir o documento, non se atoparon nin unrar nin unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "A versión de unrar no sistema non é axeitada para abrir comicbooks." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Formato ComicBook descoñecido." + +#~ msgid "ComicBook Backend" +#~ msgstr "Infraestrutura para ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un visor de varios formatos de banda deseñada" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/gl/okular_djvu.po b/po/gl/okular_djvu.po new file mode 100644 index 0000000..00a957c --- /dev/null +++ b/po/gl/okular_djvu.po @@ -0,0 +1,136 @@ +# translation of okular_djvu.po to Galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008. +# Marce Villarino , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2009-11-30 00:39+0100\n" +"Last-Translator: Miguel Branco \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Publicador" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volume" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipo de documento" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Descoñecido" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Ficheiros compoñentes" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Descoñecido" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Páxina única" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Feixe" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirecto" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Feixe (vello)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexado (vello)" + +#~ msgid "DjVu Backend" +#~ msgstr "Infraestrutura para DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Infraestrutura de DjVu baseada en DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Descoñecida" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Descoñecido" diff --git a/po/gl/okular_dvi.po b/po/gl/okular_dvi.po new file mode 100644 index 0000000..a835dd1 --- /dev/null +++ b/po/gl/okular_dvi.po @@ -0,0 +1,740 @@ +# translation of okular_dvi.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008, 2009. +# Marce Villarino , 2009, 2013, 2014. +# Adrián Chaves Fernández , 2015, 2017. +# Adrián Chaves (Gallaecio) , 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-11-17 09:21+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino, Xosé Calvo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net, xosecalvo@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular non puido localizar o programa dvipdfm no computador. " +"Ese programa é esencial para que funcione a exportación. Porén, pode " +"converter o ficheiro DVI nun PDF usando a función de impresión de Okular, " +"pero iso a miúdo dá ficheiros que se imprimen correctamente pero teñen unha " +"calidade menor se son vistos no Acrobat Reader. Poida que lle conveña anovar " +"a unha versión máis moderna da súa distribución TeX que inclúa o programa " +"dvipdfm.

Axuda para administradores sorprendidos: Okular usar " +"a variábel de contorno PATH para atopar os programas.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"O programa externo «dvipdfm», usado para exportar o ficheiro, informou " +"dun erro. Se desexa un informe preciso do erro o atopará no diálogo " +"de información do documento." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Este ficheiro DVI refírese a ficheiros gráficos externos que non están " +"en formato PostScript, e o programa dvips non pode manexalo, que " +"Okular usa internamente para imprimir ou exportar a PostScript. A " +"funcionalidade que vostede require non está dispoñíbel nesta versión de " +"Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular non puido atopar no computador o programa dvips. Ese " +"programa é esencial para a función de exportación.

Axuda para o " +"administrador sorprendido: Okular usa a variábel de contorno PATH para " +"atopar os programas.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"O programa externo «dvips», que se usou para exportar o ficheiro, " +"informou dun erro. Se desexa un informe de erro preciso, consulte o " +"diálogo de información do ficheiro que pode atopar no menú " +"Ficheiro." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "O ficheiro DVI non comeza polo preámbulo." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"O ficheiro DVI contén a versión errada para este programa da saída de DVI. " +"Consello: Se usa o sistema de configuracións de tipos Omega, terá que usar " +"un programa especial, como oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"O ficheiro DVI está corrompido. Okular non foi capaz de atopar o postámbulo." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "O postámbulo non comeza pola orde POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "O postámbulo contiña unha orde distinta de FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "A páxina %1 non comeza pola orde BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Non se puido iniciar o programa externo pdf2ps. Como " +"resultado, non se puido converter o ficheiro PDF %1 en PostScript. Polo " +"tanto non se mostrarán algúns dos elementos gráficos do documento.

Posíbel causa: Poida que o programa pdf2ps non " +"estea instalado ou que non se poida atopar na ruta de busca actual.

Como solucionalo: Polo xeral o programa pdf2ps " +"vai incluído nas distribucións do sistema intérprete de PostScript " +"«ghostscript». Se non ten «ghostscript» instalado no sistema, instáleo. Se " +"ten a certeza de que «ghostscript» está instalado, probe a usar " +"pdf2ps na liña de ordes para comprobar se realmente " +"funciona.

Ruta de busca (variábel «PATH»): %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Non se puido converter o ficheiro PDF %1 en PostScript. Polo tanto " +"algúns elementos gráficos do documento non se mostrarán.

Posíbel " +"razón: Poida que o ficheiro %1 estea estragado, ou que non sexa un " +"ficheiro PDF. Esta é a saída do programa pdf2ps que Okular " +"usa:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Corrupción no ficheiro. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"Non todos os ficheiros PostScript externos se incorporaron ao documento. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Todos os ficheiros PostScript externos se incorporaron ao documento." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "O ficheiro indicado, «%1», non existe." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Pediulle a Okular que atope o lugar do ficheiro DVI que corresponde coa liña " +"%1 do ficheiro de TeX %2. Aparentemente, o ficheiro DVI non contén a " +"información necesaria sobre o ficheiro fonte." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular non foi capaz de atopar o lugar do ficheiro DVI que corresponde á " +"liña %1 no ficheiro de TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "O código DVI definiu un carácter dunha fonte descoñecida." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"O código DVI referíase á fonte n.º %1, que non se definiu con anterioridade." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "A meda non estaba baleira cando se atopou a orde EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "A meda estaba baleira cando se atopou unha orde POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "O código DVI referíase a unha fonte non definida previamente." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Atopouse unha orde inaceptábel." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Atopouse o código de operación descoñecido %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Estase a incrustar %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Páxina %1: Non se puido converter o ficheiro PDF %2 en " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Páxina %1: Non se puido atopar o ficheiro PostScript %2.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Non se puideron procesar os datos de tamaño de papel «%1»." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular non foi capaz de atopar todos os ficheiros de fonte que son " +"precisos para mostrar este ficheiro DVI. O documento pode ser ilexíbel.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Producíronse problemas ao executar kpsewhich. En " +"consecuencia, non se puideron atopar algúns ficheiros de fonte e o documento " +"podería non ser lexíbel.
Posíbel causa: O programa kpsewhich " +"podería non estar instalado no sistema ou non pode atoparse na ruta de busca " +"actual.

Ruta de busca (variábel «PATH»): %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Interrompeuse a xeración das fontes mediante kpsewhich(código " +"de saída %1, erro %2). En consecuencia, non se puideron atopar algúns " +"ficheiros de fonte e o documento podería ser ilexíbel." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Xerando %1 con %2 ppp…" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Xerador/Data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Non se atopou o ficheiro da fonte" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "retrato" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "apaisado" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"A versión de Ghostview que está instalada neste computador non contén ningún " +"dos controladores de dispositivo de Ghostview que coñece Okular. Polo tanto " +"desactivouse a compatibilidade con PostScript en Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

O programa Ghostview, que se usa internamente para mostrar os " +"gráficos PostScript que se inclúen neste ficheiro DVI, polo xeral é capaz de " +"escribir a súa saída en distintos formatos. Os subprogramas que Ghostview " +"usa para estas tarefas son chamados «controladores de dispositivo»; hai un " +"destes por cada formato que poida escribir Ghostview. Distintas versións de " +"Ghostview a miúdo teñen conxuntos de controladores distintos. Semella que a " +"versión que está instalada neste computador non contén ningún dos controladores coñecidos por Okular.

É moi improbábel que " +"unha instalación normal de Ghostview non conteña ningún destes " +"controladores. Este erro pode en consecuencia indicar un problema grave na " +"configuración da instalación de Ghostview no computador.

Se quere " +"corrixir os problemas con Ghostview, pode usar a orde gs --help para mostrar a lista de controladores contidos en Ghostview. Entre " +"outros, Okular pode usar «png256», «jpeg» e «pnm». Lembre que Okular precisa " +"reiniciarse para activar de novo a compatibilidade con PostScript.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"Con este son 25 erros. Non se imprimirán as mensaxes de erro que sigan." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Erro no ficheiro DVI «%1», páxina %2. Emitiuse unha orde «pop» de cor pero a " +"pila de cores está baleira." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Parámetro mal formado na orde especial «epsf».\n" +"Agardábase un valor de coma flotante tras %1 en %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Ficheiro non atopado: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Erro no ficheiro DVI «%1», páxina %2. Non se puido interpretar o ángulo na " +"rotación do texto especial." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "A orde especial «%1» non está realizada." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Foi posíbel abrir e ler o ficheiro de fonte %1, pero o formato de fonte non " +"se permite." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "O ficheiro de fonte %1 está estragado ou non se puido abrir ou lelo." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType informou dun erro ao axustar o tamaño dos caracteres do ficheiro de " +"fonte %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType non pode cargar o glifo n.º %1 do ficheiro de fonte %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType non pode cargar o glifo n.º %1 do ficheiro de fonte %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "O glifo n.º %1 está baleiro." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "O glifo n.º %1 do ficheiro de fonte %2 está baleiro." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType non pode cargar a métrica do glifo n.º %1 do ficheiro de fonte %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Non se pode abrir o ficheiro de fonte %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: O carácter %1 non está definido na fonte %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 inesperado no ficheiro PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "O carácter %1 é grande de máis no ficheiro %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Número incorrecto de bits almacenados: car. %1, fonte %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Ficheiro pk incorrecto (%1), demasiados bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "A fonte ten unhas proporcións non cadradas" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Non se pode atopar a fonte %1, ficheiro %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Erro na suma de comprobación do ficheiro de fonte %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Non se pode recoñecer o formato do ficheiro de fonte %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Erro fatal.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Isto probabelmente signifique que ou atopou un fallo en Okular,\n" +"ou que o ficheiro DVI, ou os auxiliares (como ficheiros de fonte ou de fonte " +"virtual) estaban realmente corruptos.\n" +"Okular vaise interromper tras esta mensaxe. Se pensa que acabade atopar un " +"fallo ou que\n" +"Okular debería comportarse dun modo distinto nesta situación, informe do\n" +"problema." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "" +"Atopouse un byte incorrecto de orde na lista de macro da fonte virtual: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Infraestrutura de DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Un visor de ficheiros DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular depende do programa kpsewhich para localizar os " +#~ "ficheiros de tipos de letra no disco duro e para xerar os tipos PK, se é " +#~ "preciso.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular está a xerar as fontes tipográficas en mapa de bits..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Interrompe a xeración da fonte tipográfica. Non o faga." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular está a xerar as fontes tipográficas de mapas de bit precisas para " +#~ "mostrar o documento. Para isto Okular usa varios programas externos, como " +#~ "MetaFont. Pode atopar a saída destes programas máis tarde no diálogo de " +#~ "información do documento." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular está a xerar as fontes tipográficas. Agarde un momento." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Diálogo de progreso da xeración das fontes tipográficas" + +#~ msgid "Abort" +#~ msgstr "Interromper" + +#~ msgid "What is happening here?" +#~ msgstr "Que está a pasar?" + +#~ msgid "%v of %m" +#~ msgstr "%v de %m" + +#~ msgid "Please be patient" +#~ msgstr "Agarde, por favor" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Formato de documento portábel (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Exportar o ficheiro como" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Xa existe o ficheiro %1.\n" +#~ "Desexa sobrescribilo?" + +#~ msgid "Overwrite File" +#~ msgstr "Sobrescribir o ficheiro" + +#~ msgid "Overwrite" +#~ msgstr "Sobrescribir" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Estase a usar dvipdfm para exportar o ficheiro a PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular está a usar o programa externo «dvipdfm» para converter o ficheiro " +#~ "DVI en PDF. Ás veces iso pode levar un tempo porque dvipdfm precisa xerar " +#~ "os seus propios mapas de bits das fontes tipográficas. Teña paciencia." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Á espera de que dvipdfm remate..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Estase a usar dvips para exportar o ficheiro a PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular está a usar o programa externo «dvips» para converter o ficheiro " +#~ "DVI en PostScript. Ás veces iso pode tardar porque dvips precisa xerar os " +#~ "seus propios mapas de bits das fontes tipográficas, sexa paciente." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Á espera de que dvips termine..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funcionalidade non dispoñíbel" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Ficheiro corrupto Okular non foi capaz de " +#~ "interpretar o ficheiro DVI. Polo xeral isto é causado por un ficheiro " +#~ "corrompido." + +#~ msgid "DVI File Error" +#~ msgstr "Erro no ficheiro DVI" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Non se atoparon todas as fontes tipográficas" + +#~ msgid "Locating fonts..." +#~ msgstr "Estanse a localizar as fontes tipográficas..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Xurdiron problemas ao executar kpsewhich. Como resultado, non " +#~ "foi posíbel localizar algúns tipos de letra e o documento podería ser " +#~ "ilexíbel.

Posíbeis razóns: Pode ser que non teña instalado o " +#~ "programa kpsewhich ou que non se poda atopar na dirección actual indicada." +#~ "

Que pode facer: Polo xeral ese programa está contido nas " +#~ "distribucións do sistema de configuración de tipos de TeX. Se non ten " +#~ "instalado a TeX no sistema, pode instalar a distribución TeX Live(www.tug." +#~ "org/texlive). Se está seguro de ter a TeX instalado, probe a usar o " +#~ "programa kpsewhich desde a liña de ordes para ver se funciona realmente." + +#~ msgid "Problem locating fonts" +#~ msgstr "Problemas ao localizar fontes tipográficas" + +#~ msgid "Font generation aborted" +#~ msgstr "Interrompeuse a xeración de fontes tipográficas" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Exportar: %1 para PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Exportar: %1 a PostScript" diff --git a/po/gl/okular_epub.po b/po/gl/okular_epub.po new file mode 100644 index 0000000..3ce0e17 --- /dev/null +++ b/po/gl/okular_epub.po @@ -0,0 +1,56 @@ +# translation of okular_epub.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2008. +# Marce Villarino , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-08-10 11:24+0200\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Ocorreu un erro ao abrir o documento EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configuración da infraestrutura de EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Infraestrutura de EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Unha infraestrutura para EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/gl/okular_fax.po b/po/gl/okular_fax.po new file mode 100644 index 0000000..54f42b7 --- /dev/null +++ b/po/gl/okular_fax.po @@ -0,0 +1,48 @@ +# translation of okular_fax.po to Galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2008. +# Xosé , 2008. +# Marce Villarino , 2009. +# Marce Villarino , 2012. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2012-01-09 13:10+0100\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino, Xosé Calvo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@kde-espana.es, proxecto@trasno.gal" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Non se pode cargar o documento" + +#~ msgid "Fax Backend" +#~ msgstr "Infraestrutura de fax" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Unha infraestrutura de documentos de fax G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/gl/okular_fictionbook.po b/po/gl/okular_fictionbook.po new file mode 100644 index 0000000..ae8a1b5 --- /dev/null +++ b/po/gl/okular_fictionbook.po @@ -0,0 +1,81 @@ +# translation of okular_fictionbook.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008. +# Marce Villarino , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-28 22:11+0100\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "O documento non é un FictionBook correcto." + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Non se pode abrir o documento: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "O documento non é un arquivo ZIP correcto." + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "A estrutura do documento é incorrecta, falta o directorio principal." + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Non se atopou contido no documento." + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Documento XML incorrecto: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuración da infraestrutura de FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Infraestrutura para libros FictionBook" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un visor de libros electrónicos FictionBook." + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/gl/okular_ghostview.po b/po/gl/okular_ghostview.po new file mode 100644 index 0000000..eb17a7a --- /dev/null +++ b/po/gl/okular_ghostview.po @@ -0,0 +1,94 @@ +# translation of okular_ghostview.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# mvillarino , 2007, 2008. +# Marce Villarino , 2009. +# Adrián Chaves (Gallaecio) , 2017, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2019-11-17 09:18+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "mvillarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usar as fontes da plataforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina se debe permitírselle a Ghostscript usar as fontes da plataforma. " +"Se é falso só se permitirá utilizar as fontes incrustadas no documento." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Configuración xeral" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usar as fontes da plataforma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuración da infraestrutura de Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Versión do documento" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivel da linguaxe" + +#~ msgid "PS Backend" +#~ msgstr "Infraestrutura para PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un renderizador de ficheiros PostScript" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Baseado na biblioteca Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/gl/okular_kimgio.po b/po/gl/okular_kimgio.po new file mode 100644 index 0000000..efa97a1 --- /dev/null +++ b/po/gl/okular_kimgio.po @@ -0,0 +1,71 @@ +# translation of okular_kimgio.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007. +# Marce Villarino , 2009. +# Adrián Chaves (Gallaecio) , 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2018-01-07 17:20+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Non se pode cargar o documento: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Este documento parece estar malformado. Esta é a mellor aproximación á " +"aparencia intencionada do documento." + +#~ msgid "Image Backend" +#~ msgstr "Infraestrutura de imaxe" + +#~ msgid "A simple image backend" +#~ msgstr "Unha infraestrutura simple para imaxes" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra de ferramentas Principal" diff --git a/po/gl/okular_markdown.po b/po/gl/okular_markdown.po new file mode 100644 index 0000000..ef0bd4c --- /dev/null +++ b/po/gl/okular_markdown.po @@ -0,0 +1,52 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Adrián Chaves (Gallaecio) , 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-04-04 20:26+0200\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Adrian Chaves (Gallaecio)" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "adrian@chaves.io" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Non se puido compilar o documento de Markdown" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Non se puido compilar o documento de Markdown." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Activar o formatado SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuración da infraestrutura de Markdown" diff --git a/po/gl/okular_mobi.po b/po/gl/okular_mobi.po new file mode 100644 index 0000000..5abee64 --- /dev/null +++ b/po/gl/okular_mobi.po @@ -0,0 +1,64 @@ +# translation of okular_mobi.po to Galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2008. +# Marce Villarino , 2009, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-10-28 22:29+0100\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino, Xosé" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net, xosecalvo@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Ocorreu un erro ao abrir o documento Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Este libro está protexido por DRM e só se pode mostrar no dispositivo " +"designado" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuración da infraestrutura para Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Infraestrutura para Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Unha infraestrutura para mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/gl/okular_plucker.po b/po/gl/okular_plucker.po new file mode 100644 index 0000000..b9ed43d --- /dev/null +++ b/po/gl/okular_plucker.po @@ -0,0 +1,46 @@ +# translation of okular_plucker.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008. +# Marce Villarino , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-06-22 21:43+0200\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nome" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Infraestrutura para documentos Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un visor de libros electrónicos Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/gl/okular_poppler.po b/po/gl/okular_poppler.po new file mode 100644 index 0000000..2627145 --- /dev/null +++ b/po/gl/okular_poppler.po @@ -0,0 +1,235 @@ +# translation of okular_poppler.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008. +# Marce Villarino , 2009, 2013. +# Xosé , 2012. +# Adrián Chaves (Gallaecio) , 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-01-15 20:44+0100\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Marce Villarino,\n" +"Xosé Calvo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" +"mvillarino@users.sourceforge.net,\n" +"xosecalvo@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Mellorar as liñas delgadas:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Non" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Sólido" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opcións de PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprimir as anotacións" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Incluír as anotacións no documento impreso" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Inclúe as anotacións no documento impreso. Isto pódese desactivar se se " +"quere imprimir o documento sen anotacións orixinal." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Forzar o debuxado" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Plasmar nunha imaxe antes de imprimir" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Obriga a que se converta cada páxina nunha imaxe antes de imprimila. Isto dá " +"polo xeral peores resultados, pero é útil cando se imprimen documentos que " +"parecen mal ao ser impresos." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Axustar á zona imprimíbel" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Axustar á páxina completa" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Ningún; imprimir co tamaño orixinal" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Modo de cambio de dimensións das páxinas impresas" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de cambio de dimensións:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Cifrado" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Descifrado" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Seguranza" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Si" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimizado" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Usando Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Usando Poppler %1\n" +"\n" +"Construído con Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuración da infraestrutura de PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Non dispoñíbel" + +#~ msgid "Select rasterization to enable this!" +#~ msgstr "Seleccione debuxado para activar isto!" + +#~ msgid "PDF Backend" +#~ msgstr "Infraestrutura de PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Un visor de ficheiros PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Non é posíbel gardar ficheiros con /Encrypt." + +#~ msgid "Unknown" +#~ msgstr "Descoñecido" + +#~ msgid "Unknown Date" +#~ msgstr "Data descoñecida" + +#~ msgid "Unknown Encryption" +#~ msgstr "Cifrado descoñecido" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optimización descoñecida" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Insira o contrasinal para ler o documento:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "O contrasinal é incorrecto. Ténteo de novo:" + +#~ msgid "Document Password" +#~ msgstr "Contrasinal do documento" diff --git a/po/gl/okular_txt.po b/po/gl/okular_txt.po new file mode 100644 index 0000000..613568f --- /dev/null +++ b/po/gl/okular_txt.po @@ -0,0 +1,49 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Marce Villarino , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-05 08:16+0200\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@kde-espana.es" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuración da infraestrutura para Txt" + +#~ msgid "Txt Backend" +#~ msgstr "Infraestrutura para txt" + +#~ msgid "Txt backend." +#~ msgstr "Infraestrutura para txt." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/gl/okular_xps.po b/po/gl/okular_xps.po new file mode 100644 index 0000000..52003bb --- /dev/null +++ b/po/gl/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to galician +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# mvillarino , 2007, 2008. +# Marce Villarino , 2009. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-06-22 21:44+0200\n" +"Last-Translator: Marce Villarino \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marce Villarino" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "mvillarino@users.sourceforge.net" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisión" + +#~ msgid "XPS Backend" +#~ msgstr "Infraestrutura para XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Unha infraestrutura para XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/gl/org.kde.active.documentviewer.po b/po/gl/org.kde.active.documentviewer.po new file mode 100644 index 0000000..05566a1 --- /dev/null +++ b/po/gl/org.kde.active.documentviewer.po @@ -0,0 +1,85 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Marce Villarino , 2013. +# Miguel Branco , 2013. +# Adrián Chaves (Gallaecio) , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-10 08:22+0200\n" +"Last-Translator: Adrián Chaves (Gallaecio) \n" +"Language-Team: Galician \n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 19.04.1\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Abrir…" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Retirar o marcador" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Marcar esta páxina" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniaturas" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Táboa de contido" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Marcadores" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Buscar…" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Non se atopou ningún resultado." + +#~ msgid "Document to open..." +#~ msgstr "Documento para abrir…" + +#~ msgid "Open Android..." +#~ msgstr "Abrir Android…" + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Non se atoparon documentos. Para comezar a ler, coloque ficheiros no " +#~ "cartafol de documentos do dispositivo." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Visualizador de documentos para Plasma Active empregando Okular" + +#~ msgid "Reader" +#~ msgstr "Lector" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL do ficheiro para abrir" diff --git a/po/he/okular.po b/po/he/okular.po new file mode 100644 index 0000000..e9cf34a --- /dev/null +++ b/po/he/okular.po @@ -0,0 +1,5433 @@ +# translation of okular.po to Hebrew +# translation of kpdf.po to +# Igal , 2004. +# Diego Iastrubni , 2004. +# Garry Lachman , 2004. +# Diego Iastrubni , 2005, 2006, 2009, 2012, 2013. +# Ely Levy , 2007. +# Elkana Bardugo , 2017. #zanata +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2017-05-24 08:35-0400\n" +"Last-Translator: Elkana Bardugo \n" +"Language-Team: Hebrew \n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Launchpad-Export-Date: 2010-12-24 00:32+0000\n" +"X-Generator: Zanata 3.9.6\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" +"Koala - גארי לכמן, ,Launchpad Contributions:,Diego Iastrubni,Ofir Klinger" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "koala@linux.net,garry@nunex.co.il,,,klinger.ofir@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, מציג מסמכים אוניברסלי" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2009 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "מתחזק קודם" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "הרבה עבודה על קוד המסגרת, ומנגנוני ODT ו־FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "מפתח" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "ייצר את Okular מקוד הבסיס של KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "מפתח KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "עבודת אומנות של הסברי הצד" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "כלי לבחירת טבלאות" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "שיפורי הערות צד" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "מעבר לעמוד %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "פתיחת קובץ חיצוני" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "הרץ '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "עמוד ראשון" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "עמוד קודם" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "עמוד הבא" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "עמוד אחרון" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "אחורה" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "קדימה" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "יציאה" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "התחלת המצגת" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "סיום המצגת" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "חיפוש..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "מעבר לעמוד..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "ניגון קטע שמע..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "סקריפט JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "ניגון סרט..." + +#: core/action.cpp:547 +#, fuzzy, kde-format +msgid "Play movie" +msgstr "ניגון סרט..." + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "" + +#: core/action.cpp:551 +#, fuzzy, kde-format +msgid "Pause movie" +msgstr "ניגון סרט..." + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "בחירת מנגנון" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"קיים יותר ממנגנון אחד לסוג הקובץ:
%1 (%2).

יש " +"לבחור באיזה להשתמש:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "מעבר לעמוד %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, fuzzy, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 אינץ'" + +#: core/document.cpp:251 +#, fuzzy, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 מ\"מ" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "לא ניתן למצוא תוסף אשר יכול לטפל במסמך שהועבר." + +#: core/document.cpp:3368 +#, fuzzy, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "מצגת" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "המסמך מנסה להריץ יישום חיצוני, ולמען ביטחונך, Okular לא מרשה זאת." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "לא נמצא יישום לפתיחה של קובץ מסוג %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "לא ניתן לפתוח קובץ זמני" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "המרה להדפסה נכשלה" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "תהליך ההדפסה קרס" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "לא ניתן להתחיל את תהליך ההתחלה" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "ההדפסה לקובץ נכשלה" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "המדפסת הייתה במצב לא תקין" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "לא ניתן למצוא את הקובץ להדפסה" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "לא היה שום קובץ להדפסה" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"לא ניתן למצוא קובץ הפעלה בינארי להדפסה. יש לוודא שהקובץ ה־lpr הבינארי של " +"CUPS זמין." + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, fuzzy, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "לא ניתן לפתוח את \"%1\" לכתיבה. הקובץ לא נשמר." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "כותרת" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "נושא" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "תיאור" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "מחבר" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "יוצר" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "מפיק" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "זכויות יוצרים" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "עמודים" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "נוצר" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "שונה" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "טיפוס נתונים" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "קטגוריה" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "מילות מפתח" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "נתיב הקובץ" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "גודל הקובץ" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "גודל הדף" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "הוסף הערת צד" + +#: core/documentcommands.cpp:110 +#, fuzzy, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "מצגת" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "מאפייני הערת צד" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "הסבר צד עם טקסט" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "הערת צד" + +#: core/documentcommands.cpp:328 +#, fuzzy, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "בחירת טקסט" + +#: core/documentcommands.cpp:390 +#, fuzzy, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "מאפייני הערת צד" + +#: core/documentcommands.cpp:438 +#, fuzzy, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "מאפייני הערת צד" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "טקסט &פשוט..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument Text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "אפשרויות עורך" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "מצב צבע:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "מקור: %1" + +#: core/textdocumentsettings.cpp:37 +#, fuzzy, kde-format +msgid "&Default Font:" +msgstr "מעבר ברירת מחדל:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "&טעינה מחדש" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "איפשור" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "מסך:" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "התאמה לרוחב" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "מאפייני הערות צד" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "כלי הערות צד" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "כלי הערות צד" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "כלי הערות צד" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "כלי הערות צד" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "הערת צד" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "מאפייני הערות צד" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&צבע:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&צבע:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "ניסוי" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "כלי &בחירה" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "הערות צד" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "הדגשה" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "קו תחתון" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "שרבוט" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "קו חוצה" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "מאפייני סרט" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "הערה פנימית" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "&פתיחת הערה בחלונית" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "קו ירוק בציור חופשי" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "קו צהוב ישר" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "מלבן" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "אליפסה" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "מצולע כחול" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "חותמת" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "הערות צד" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "הוסף הערת צד" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "צור כלי הערות צד" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "גופן:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "מאפייני הערות צד" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "התאמה לרוחב" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "&שקיפות:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "עמוד %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "הערת צד" +msgstr[1] "%1 הערות צד" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&פתיחת הערה בחלונית" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&מחיקה" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "מ&אפיינים" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&שמירת '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "מ&ראה" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&כללי" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&מחבר:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "נוצר" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "שונה" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +msgid "Pop-up Note Properties" +msgstr "מאפייני הערה" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Movie Properties" +msgid "Typewriter Properties" +msgstr "מאפייני סרט" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "מאפייני הערה פנימית" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +msgid "Straight Line Properties" +msgstr "מאפייני קו" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +msgid "Polygon Properties" +msgstr "מאפייני שמע" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "מאפייני גאומטריה" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +msgid "Text Markup Properties" +msgstr "מאפייני חותמת" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "מאפייני חותמת" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +msgid "Freehand Line Properties" +msgstr "מאפייני קו" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "מאפייני קובץ מצורף" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "מאפייני שמע" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "מאפייני סרט" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "מאפייני הערת צד" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "שונה: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "חותמת" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&צבע:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&שקיפות:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "סמל" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "הערה" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "עזרה" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "הוספה" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "מפתח" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "פסקה חדשה" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "הערה" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "פסקה" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "גופן:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&צבע:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "" + +#: part/annotationwidgets.cpp:390 +#, fuzzy, kde-format +msgid "Left" +msgstr "שמאלה" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "" + +#: part/annotationwidgets.cpp:392 +#, fuzzy, kde-format +msgid "Right" +msgstr "ימינה" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "אושר" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "כמו שהוא" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "חסוי" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "מחלקתי" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "טיוטה" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "ניסוי" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "סופי" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "להערות" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "לקהל הרחב" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "לא מאושר" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "לא לקהל הרחב" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "נמכר" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "סודי ביותר" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "סימנייה" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "מידע" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "סמל חותמת" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +msgid "&Width:" +msgstr "התאמה לרוחב" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "ללא" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +msgid "Leader line length:" +msgstr "קו תחתון" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +msgid "Shape fill:" +msgstr "שמירה לקובץ..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "סוג:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "הדגשה" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, fuzzy, kde-format +msgid "Squiggle" +msgstr "שרבוט" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "קו תחתון" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "קו חוצה" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "מלבן" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "אליפסה" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "סמל הקובץ המצורף" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "תרשים" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "נעץ" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "מהדק" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "תגית" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "קובץ" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "לא קיים" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "אין תיאור זמין." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +msgid "Name:" +msgstr "שם" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "תיאור:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "ללא" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "סגירת הערה" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "אפשרויות" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"סימנייה אחת" +msgstr[1] "" +"%1\n" +"\n" +"%2 סימניות" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "סימניות" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "&חיפוש" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "מסמך נוכחי בלבד" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "מעבר לסימנייה הזו" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "שינוי שם הסימנייה" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "הסרת הסימנייה" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "פתיחת מסמך" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "הסרת הסימניות" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +msgid "Serial Number" +msgstr "גודל הדף" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "פג תוקף" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "נושא" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "שימוש בזיכרון" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "מ&אפיינים" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "הגדרת המציג..." + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "ייצ&וא כקובץ" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "כללי" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "היכן יש לשמור את %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +msgid "Red" +msgstr "&טעינה מחדש" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +msgid "Green" +msgstr "מסך:" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +msgid "Yellow" +msgstr "איפשור" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "ציור מסגרת מסביב ל&תמונות" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "ציור מסגרת מסביב ל&קישורים" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "שינוי &צבעים" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "אזהרה: אפשרויות אלו יכולות לפגוע במהירות הצביעה באופן חמור." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "מצב צבע:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "היפוך צבעים" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "שינוי צבע הדף" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "המרה לצבעים כהים ובהירים" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "המרה לצבעי שחור ולבן" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "צבע העמוד:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "צבע כהה:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "צבע בהיר:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "סף:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "ניגודיות:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "זהות" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&מחבר:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"יש לשים לב: המידע כאן משמש רק עבור הערות וסקירות. מידע שהוכנס כאן לא " +"יועבר מבלי לידע אותך." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "ערוך גלי הערות צד" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "עורך טקסט מותאם אישית" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "לקוח Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "לקוח Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"

    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"הגדרת הפקודה שתריץ עורך טקסט מותאם אישית.
\n" +"ניתן להוסיף גם כן כמה שומרי מקום:\n" +"
    \n" +"
  • %f - עבור שם הקובץ
  • \n" +"
  • %l - השורה שאליה יש להגיע בתוך הקובץ
  • \n" +"
  • %c - העמודה שאליה יש להגיע בתוך הקובץ
  • \n" +"
\n" +"אם לא צויין שומר המקום %f, שם הקובץ יתווסף לסוף הפקודה שצויינה." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "עורך" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "עורך:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "יש לבחור בעורך שישוגר כאשר Okular רוצה לפתוח קובץ מקור." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "פקודה:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "מראה" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "הצגת &פסי גלילה" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "קישור התמונות ה&ממוזערות של העמודים עם העמודים" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "הצגת &רמזים והודעות מידע" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "הצג כותרת מסמך בסרגל הכותרת אם זמין" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "כשלא מציג את כותרת המסמך:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "הצג את שם הקובץ" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "הצג את נתיב הקובץ המלא" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "צבע רקע:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "מאפייני היישום" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "פתח קבצים חדשים בכרטיסיות" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&אכיפת הגנות DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&טעינה מחדש של המסמך כשהקובץ משתנה" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "הצגת דיאלוג בחירת מנגנון" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "כיוון קריאה מימין לשמאל" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "אפשרויות תצוגה" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "סקירת עמודות:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"הגדר כמה מאיזור הצפיה הנוכחי יהיה מוצג בעת גלילה באמצעות מקשי Page Up/Down." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "חפיפת Page Up/Down" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "הגדלה ברירת מחדל" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "התאמה לרוחב" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "התאמה לעמוד" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "התאמה אוטומטית" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"כמה שפחות זיכרון בשימוש. לא נעשה שימוש חוזר בפריטים. (עבור מערכות עם מגבלת " +"זיכרון.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"הפשרה הטובה ביותר בין שימוש בזיכרון למהירות. הדף הבא נטען מראש והחיפוש מואץ. " +"(לרוב, עבור מערכות עם 2G זיכרון)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"הכל נשמר בזיכרון. הדפים הבאים נטענים מראש. החיפוש מואץ. (עבור מערכות עם יותר " +"מ־4G זיכרון)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "שימוש במעבד" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "איפשור אפקטי &שקיפות" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "שימוש בזיכרון" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&נמוך" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "רגיל (ברירת מחדל)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&אגרסיבי" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "חמדני" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, fuzzy, kde-format +msgid "Rendering" +msgstr "קו תחתון" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, fuzzy, kde-format +msgid "Enable Text Antialias" +msgstr "איפשור מעברים" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, fuzzy, kde-format +msgid "Enable Graphics Antialias" +msgstr "איפשור מעברים" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, fuzzy, kde-format +msgid "Enable Text Hinting" +msgstr "איפשור מעברים" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "המסך הנוכחי" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "מסך ברירת המחדל" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "מסך %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " שניה" +msgstr[1] " שניות" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "ניווט" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "התקדמות כל:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "חזרה בלולאה אחרי הדף האחרון" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "ניווט" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "צבע רקע:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "סמן העכבר:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "הסתרה לאחר זמן מסויים" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "תמיד נראה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "תמיד מוסתר" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "הצגת פס הת&קדמות" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "הצגת דף &סיכום" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "איפשור מעברים" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "מעבר ברירת מחדל:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "התמזגות אופקית" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "התמזגות אנכית" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "מסגור פנימה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "מסגור החוצה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "התמוססות" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "נצנוץ מטה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "נצנוץ ימינה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "נצנןץ ימינה־מטה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "מעבר אקראי" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "החלפה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "פיצול אופקית פנימה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "פיצול אנכית החוצה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "פיצול אנכית פנימה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "פיצול אופקית החוצה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "מחיקה מטה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "מחיקה ימינה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "מחיקה שמאלה" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "מחיקה מעלה" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "מיקום" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "מסך:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +msgid "Eraser" +msgstr "מחיקת ציורים" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, fuzzy, kde-format +msgid "&Name:" +msgstr "שם" + +#: part/editannottooldialog.cpp:72 +#, fuzzy, kde-format +msgid "&Type:" +msgstr "סוג:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, fuzzy, kde-format +msgid "Pop-up Note" +msgstr "&פתיחת הערה בחלונית" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "הערה פנימית" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, fuzzy, kde-format +msgid "Freehand Line" +msgstr "קו ירוק בציור חופשי" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, fuzzy, kde-format +msgid "Straight Line" +msgstr "קו צהוב ישר" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, fuzzy, kde-format +msgid "Polygon" +msgstr "מצולע כחול" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +msgid "Text markup" +msgstr "הסימנייה הבאה" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "חותמת" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "צור כלי הערות צד" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "ערוך גלי הערות צד" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +msgid "Color:" +msgstr "&צבע:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +msgid "&Pen Width:" +msgstr "התאמה לרוחב" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +msgid "Create drawing tool" +msgstr "מצגת" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +msgid "Edit drawing tool" +msgstr "מאפייני הערת צד" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "לא ידוע" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "קבצים משובצים" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "&תצוגה" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "שם" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "תיאור" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "גודל" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "נוצר" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "שונה" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&שמירה בשם..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&תצוגה" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "אין אפשרות לטעון את רכיב התצוגה המקדימה" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "תצוגה מקדימה לפני הדפסה" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "סגירה" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&חיפוש:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "טקסט לחיפוש" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "הבא" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "מעבר לתוצאה הבאה" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "הקודם" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "קפיצה לתוצאה הבאה" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "שינוי התנהגות החיפוש" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "תלוי רישיות" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "מהדף הנוכחי" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|כל הקבצים" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +msgid "Signature Properties" +msgstr "מאפייני קו" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +msgid "Straight Line with Comment" +msgstr "מאפייני קו" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "להערות" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "גאומטריה" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +msgid "Highlight with Comment" +msgstr "הדגשה" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +msgid "Squiggle with Comment" +msgstr "שרבוט" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +msgid "Underline with Comment" +msgstr "קו תחתון" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +msgid "Strike Out with Comment" +msgstr "קו חוצה" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +msgid "Strike Out" +msgstr "קו חוצה" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +msgid "Freehand Line with Comment" +msgstr "מאפייני קו" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "קובץ מצורף" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "שמע" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "סרט" + +#: part/guiutils.cpp:121 +#, fuzzy, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "מסך:" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "לא ידוע" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "מחבר: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "היכן יש לשמור את %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "לא ניתן לפתוח את \"%1\" לכתיבה. הקובץ לא נשמר." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "אפשרויות חיפוש" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "תלוי רישיות" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "ביטוי רגולרי" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&חיפוש" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "מתוך" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "הגדלה" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "סיבוב &ימינה" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "ימינה" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "סיבוב &שמאלה" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "שמאלה" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "כיוון תצוגה מקורי" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +msgid "&Trim View" +msgstr "&תצוגה" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&הורדת שוליים" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +msgid "Trim To &Selection" +msgstr "בחירת טקסט" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "התאמה &לרוחב" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "התאמה ל&עמוד" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "התאמה ל&עמוד" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "מצב &תצוגה" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "עמוד יחיד" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "עמודים אחד אל מול השני" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "עמודים אחד אל מול השני (מירכוז העמוד הראשון)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "סקירה כללית" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&מתמשך" + +#: part/pageview.cpp:637 +#, fuzzy, kde-format +#| msgid "Right to left reading direction" +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "כיוון קריאה מימין לשמאל" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "עיון" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "הגדלה" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +msgid "&Toggle Change Colors" +msgstr "שינוי &צבעים" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "בחירת טקסט" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "בחירת טקסט" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +msgid "T&able Selection" +msgstr "בחירת טקסט" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "כלי בחירה" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "הקראת המסמך כולו" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "הקראת העמוד הנוכחי" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "הפסקת הקראה" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "דפדוף כלפי מעלה" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "דפדוף כלפי מטה" + +#: part/pageview.cpp:759 +#, fuzzy, kde-format +msgid "Scroll Page Up" +msgstr "דפדוף כלפי מעלה" + +#: part/pageview.cpp:765 +#, fuzzy, kde-format +msgid "Scroll Page Down" +msgstr "דפדוף כלפי מטה" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "הצגת טפסים" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " נטען מסמך של עמוד אחד." +msgstr[1] " נטען מסמך של %1 עמודים." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "טקסט (תו אחד)" +msgstr[1] "טקסט (%1 תווים)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "העתקה ללוח הגזירים" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "העתקה אסורה על־ידי ה־DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "הקראת הטקסט" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "תמונה (%1 על %2 פיקסלים)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "שמירה לקובץ..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "התמונה [%1x%2] הועתקה ללוח הגזירים." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +msgid "Save file" +msgstr "שמירה לקובץ..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "הקובץ לא נשמר." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "התמונה [%1x%2] נשמרה לקובץ %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "העתקת הטקסט" + +#: part/pageview.cpp:2930 +#, fuzzy, kde-format +msgid "Go to '%1'" +msgstr "מעבר לעמוד %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "חיפוש אחר '%1' בעזרת" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "הגדרת קיצורי רשת..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "מעקב אחרי הקישור הזה" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +msgid "Play this Sound" +msgstr "ניגון קטע שמע..." + +#: part/pageview.cpp:4179 +#, fuzzy, kde-format +msgid "Stop Sound" +msgstr "שמע" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "העתקת כתובת הקישור" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "חיפוש אחר '%1' בעזרת" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "ברוכים הבאים" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "בחירת אזור להגדלה. קליק ימני להקטנה." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "יש לצייר מלבן סביב הטקסט/הגרפיקה להעתקה." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "בחירת טקסט" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "יש לצייר מלבן סביב הטקסט/הגרפיקה להעתקה." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "יש לצייר מלבן סביב הטקסט/הגרפיקה להעתקה." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "הערת טקסט חדשה" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "טקסט להערה החדשה:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "הוסף הערת צד" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "הסבר צד עם טקסט פנימי (גרירה לבחירת אזור)" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "הדגשה" + +#: part/pageviewannotator.cpp:1025 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "קו ירוק בציור חופשי" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "הסבר צד עם טקסט פנימי (גרירה לבחירת אזור)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "ציור מצולע (יש ללחוץ על הנקודה הראשונה כדי לסגור אותו)" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "מלבן" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "שרבוט" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "חותמת" + +#: part/pageviewannotator.cpp:1039 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "קו צהוב ישר" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "קו חוצה" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "קו תחתון" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "הסבר צד עם טקסט פנימי (גרירה לבחירת אזור)" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +msgid "Highlighter" +msgstr "הדגשה" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "הוסף הערת צד" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +msgid "Custom annotation name:" +msgstr "הערת צד" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&קובץ" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&הגדרות" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "ע&זרה" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&כיוון תצוגה" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&סימניות" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, fuzzy, kde-format +msgid "Viewer Toolbar" +msgstr "סרגל הכלים הראשי" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "תמונות ממוזערות" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "הערות צד" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"מסמך זה מכיל קבצים משובצים. ניתן ללחוץ כאן " +"כדי לראות אותם או ללכת לתפריט קובץ -> קבצים משובצים." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "הקודם" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "חזרה לדף הקודם" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "מעבר לדף הקודם במסמך" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "הבא" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "מעבר לדף הבא" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "מעבר לדף הבא במסמך" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "תחילת המסמך" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "מעבר לתחילת המסמך" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "סוף המסמך" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "מעבר לסוף המסמך" + +#: part/part.cpp:687 +#, fuzzy, kde-format +msgid "Rename the current bookmark" +msgstr "טעינה מחדש של המסמך הנוכחי מהדיסק" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "הסימנייה הקודמת" + +#: part/part.cpp:693 +#, fuzzy, kde-format +msgid "Go to the previous bookmark" +msgstr "חזרה לדף הקודם עם סימנייה" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "הסימנייה הבאה" + +#: part/part.cpp:699 +#, fuzzy, kde-format +msgid "Go to the next bookmark" +msgstr "מעבר לדף הבא עם סימנייה" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "הגדרת Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "הגדרת מציג..." + +#: part/part.cpp:735 +#, fuzzy, kde-format +msgid "Configure Viewer Backends..." +msgstr "הגדרת מנגנונים..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "הגדרת מנגנונים..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "אודות המנגנון" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&טעינה מחדש" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "טעינה מחדש של המסמך הנוכחי מהדיסק" + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "סגירת &סרגל החיפוש" + +#: part/part.cpp:791 +#, fuzzy, kde-format +msgid "Page Number" +msgstr "גודל הדף" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "הקראת העמוד הנוכחי" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "הצגת סרגל &עמוד" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "הצגת סרגל &עמוד" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "הצגת סרגל &ניווט" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&קבצים משובצים" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "ייצ&וא כקובץ" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&מצגת" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&ייבוא PostScript כ־PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "הורדת &ספרים מהאינטרנט..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "החלפת מצב מסך שחור" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "מחיקת ציורים" + +#: part/part.cpp:927 +#, fuzzy, kde-format +msgid "Configure Annotations..." +msgstr "הגדרת מנגנונים..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +msgid "Play/Pause Presentation" +msgstr "מצגת" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +msgid "Could not open '%1' (%2) " +msgstr "לא ניתן לפתוח %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "הטעינה של %1 בוטלה." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "לא ניתן לפתוח את %1. הסיבה: %2" + +#: part/part.cpp:1186 +#, fuzzy, kde-format +msgid "Configure Viewer Backends" +msgstr "הגדרת מנגנונים" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "הגדרת מנגנונים" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "היישום \"ps2pdf\" לא נמצא, ומסיבה זו Okular לא יכול לייבא קבצי PS." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf לא נמצא" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "ייבוא קובץ PS כקובץ PDF (יכול לקחת זמן מה)..." + +#: part/part.cpp:1409 +#, fuzzy, kde-format +msgid "Please enter the password to read the document:" +msgstr "עובר לעמוד האחרון של המסמך" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +msgid "Document Password" +msgstr "ארכיון מסמך" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"מסמך זה מכיל טפסים. ניתן ללחוץ על הלחצן כדי להשתמש בהם, או להשתמש בתפריט " +"תצוגה -> הצגת טפסים." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "הדפסת המסמך הזה אסורה." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "הדפסת המסמך הזה אסורה." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "יציאה ממצב מצגת" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "לא ניתן לפתוח %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&מתמשך" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&מתמשך" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +msgid "Close Document" +msgstr "פתיחת מסמך" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "הקישור מצביע על פעולת סגירת מסמך, אשר לא עובדת בשימוש במציג המשובץ." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "הקישור מצביע על פעולת יציאה מיישום, אשר לא עובדת בשימוש במציג המשובץ." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "המסמך נטען מחדש..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "תכנים" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "מעבר לעמוד" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&עמוד:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, fuzzy, kde-format +msgid "Rename this Bookmark" +msgstr "שינוי שם הסימנייה" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +msgid "Remove this Bookmark" +msgstr "שינוי שם הסימנייה" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "&שמירה בשם..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "לא ניתן לפתוח את הקובץ הזמני לשמירה." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "לא ניתן לשמור את הקובץ ב־'%1'. ניתן לנסות לשמור אותו במיקום אחר." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +msgid "Filled form contents" +msgstr "מאפייני הערת צד" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +msgid "User annotations" +msgstr "מצגת" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&מתמשך" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "הקובץ לא ניתן לשמירה ב־'%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular לא יכול להעתיק את %1 למיקום המבוקש.\n" +"\n" +"המסמך לא קיים יותר." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "לא ניתן לשמור את הקובץ ב־'%1'. ניתן לנסות לשמור אותו במיקום אחר." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "סיום המצגת" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "הוספת סימנייה" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "כלים" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "הדפסת המסמך הזה אסורה." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"לא ניתן להדפיס את המסמך. שגיאה לא ידועה. מומלץ לדווח זאת לאתר שבכתובת bugs." +"kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"לא ניתן להדפיס את המסמך. השגיאה המפורטת היא \"%1\". מומלץ לדווח זאת לאתר " +"שבכתובת bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "מעבר למיקום הקודם שהיית בו" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "מעבר למיקום הבא שהיית בו" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"שגיאת קובץ! לא ניתן ליצור קובץ זמני %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"שגיאת קובץ! לא ניתן לפתוח את הקובץ %1 לפריסה. הקובץ לא יטען." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"שגיאה זו מתרחשת בדרך כלל אם אין בידך הרשאות מספיקות כדי לקרוא את הקובץ. " +"ניתן לבדוק בעלות והרשאות על הקובץ דרך מנהל הקבצים דולפין, לחיצה ימנית על " +"הקובץ ובחירה במאפיינים." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"שגיאת קובץ! לא ניתן לפרוש את הקובץ %1. הקובץ לא יטען." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"שגיאה זו מתרחשת בדרך כלל כשהקובץ פגום. על מנת לוודא זאת, ניתן לפרוש את " +"הקובץ ידנית בעזרת כלי שורת־הפקודה." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "אין סימניות" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&עריכה" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&תצוגה" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&מעבר אל" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "כ&לים" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "סרגל הכלים הראשי" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "כלי הערות צד" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "אפשרויות כלליות" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "נגישות" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "עזרי קריאה" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "ביצועים" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "כיוונון ביצועים" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "הגדרת המציג..." + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "מצגת" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "אפשרויות עבור מצב מצגת" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "מאפייני הערות צד" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "אפשרויות עורך" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "חיפוש הבא" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - מצגת" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "החלפת מסך" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "מסך %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "יציאה ממצב מצגת" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "כותרת: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "עמודים: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "לחץ להתחלה" + +#: part/presentationwidget.cpp:505 +#, fuzzy, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "השהייה" + +#: part/presentationwidget.cpp:508 +#, fuzzy, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "ניגון" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"ישנן שתי דרכים לצאת ממצב מצגת. ניתן ללחוץ על המקש ESC או ללחוץ על הלחצן " +"יציאה שמופיעה כאשר ממקמים את הסמן של העכבר בקצה הימני־עליון. כמובן שניתן " +"לעבור בין חלונות (Alt+TAB כברירת מחדל)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "הצגת מצגת" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "קובץ לא ידוע" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "מאפיינים של %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&גופנים" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "מידע אודות הגופן בטעינה..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&גודל הדף" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&חילוץ גופן" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "סוג 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "סוג 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "סוג 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "סוג 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID סוג 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID סוג 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID סוג 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "לא ידוע" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "משובץ (תת־קבוצה)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "משובץ מלא" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "לא" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "כן (תת־קבוצה)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "כן" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "לא זמין" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "גופן לא ידוע" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "משובץ: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "שם" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "סוג" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "קובץ" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "עמודים" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "גודל" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "תצוגה מקדימה לפני הדפסה" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "היכן יש לשמור את %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "לא ניתן לפתוח %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "לא ניתן לפתוח את %1. הסיבה: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "יש להכניס לפחות של אותיות לסינון דפים" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "תלוי רישיות" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "חיפוש ביטוי" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "התאמה לכל המילים ביחד" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "התאמה לכל מלה" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "אפשרויות סינון" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

אין הערות צד

על מנת ליצור הערות צד חדשות יש ללחוץ " +"על F6 או לבחור בתפריט כלים -> סקירה.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "קיבוץ על־פי דף" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "קיבוץ על־פי מחבר" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "הצגת סקירות עבור הדף הנוכחי בלבד" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "גופן לא ידוע" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "קובץ לא ידוע" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "אין תיאור זמין." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "עמודים: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "מ&אפיינים" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "מידע" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "הערת צד" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "ארכיון מסמך" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "הצגת דפים עם סימניות בלבד" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "ניגון" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "השהייה" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "הפסקה" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, fuzzy, kde-format +msgid "&Edit..." +msgstr "&עריכה" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, fuzzy, kde-format +msgid "Move &Down" +msgstr "מחיקה מטה" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Page of the document to be shown" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "פתיחת המסמך במצב מצגת" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "\"Unique instance\" control" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Document to open. Specify '-' to read from stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "לא ניתן למצוא את הרכיב Okular." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "לא ניתן למצוא את הרכיב Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"לחיצה לפתיחת קובץ\n" +"לחיצה והחזקה לפתיחת קובץ שנפתח לאחרונה" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"לחיצה לפתיחת קובץ או לחיצה והחזקה לפתיחת קובץ שנפתח לאחרונה" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +msgid "Next Tab" +msgstr "עמוד הבא" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +msgid "Previous Tab" +msgstr "עמוד קודם" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +msgid "All files (*)" +msgstr "*|כל הקבצים" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "פתיחת מסמך" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "סגירה" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "סקירות" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "הסתרת טפסים" + +#~ msgid "Expired" +#~ msgstr "פג תוקף" + +#~ msgid "&Review" +#~ msgstr "&סקירה" + +#~ msgid "Annotations author" +#~ msgstr "מחבר הערות צד" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "יש להכניס את השם או ראשי־התיבות:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "הצגת סרגל &ניווט" + +#~ msgid "Show Text" +#~ msgstr "הצג טקסט" + +#~ msgid "Small Icons" +#~ msgstr "סמלים קטנים" + +#~ msgid "Normal Icons" +#~ msgstr "סמלים רגילים" + +#~ msgid "Large Icons" +#~ msgstr "סמלים גדולים" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "לחיצה כדי להשתמש בכלי הבחירה הנוכחי\n" +#~ "לחיצה והחזקה כדי לבחור כלי בחירה אחר" + +#~ msgid "Created: %1" +#~ msgstr "נוצר: %1" + +#~ msgid "Style" +#~ msgstr "סגנון" + +#~ msgid "&Size:" +#~ msgstr "&גודל:" + +#~ msgid "Inner color:" +#~ msgstr "צבע פנימי:" + +#~ msgid "Name: %1" +#~ msgstr "שם: %1" + +#~ msgid "Size: %1" +#~ msgstr "גודל: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "כלי &עיון" + +#~ msgid "&Zoom Tool" +#~ msgstr "כלי ה&גדלה" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "הגדלה" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "בחירה" + +#~ msgid "&Text Selection Tool" +#~ msgstr "כלי בחירת &טקסט" + +#, fuzzy +#~ msgid "T&able Selection Tool" +#~ msgstr "כלי &בחירה" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "סוף המסמך" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "ללא" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "המסמך מבקש לעבור למצב מצגת.\n" +#~ "האם לאפשר זאת?" + +#~ msgid "Presentation Mode" +#~ msgstr "מצב מצגת" + +#~ msgid "Allow" +#~ msgstr "איפשור" + +#~ msgid "Allow the presentation mode" +#~ msgstr "איפשור מעבר למצב מצגת" + +#~ msgid "Do Not Allow" +#~ msgstr "מניעה" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "מניעת המעבר למצב מצגת" + +#~ msgid "Save &Copy As..." +#~ msgstr "שמירת עו&תק בשם..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "זהו סוף המסמך.\n" +#~ "האם להמשיך מההתחלה?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "זהו תחילת המסמך.\n" +#~ "האם להמשיך מהסוף?" diff --git a/po/hi/okular.po b/po/hi/okular.po new file mode 100644 index 0000000..c3df40e --- /dev/null +++ b/po/hi/okular.po @@ -0,0 +1,5539 @@ +# translation of okular.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +# rawkoder , 2020. +# Raghavendra Kamath , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-09-19 10:03+0530\n" +"Last-Translator: Raghavendra Kamath \n" +"Language-Team: kde-hindi\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Lokalize 20.08.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "रविशंकर श्रीवास्तव, जी. करूणाकर, राॅकोडर, राघवेंद्र कामत" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "raviratlami@aol.in, rawkoder@fastmail.in, raghu@raghukamath.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "ऑकुलर" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "ऑकुलर, एक सार्वजनीन दस्तावेज़ प्रदर्शक" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 विल्को ग्रेवेन, क्रिस्टोफ़ डेवराइस\n" +"(C) 2004-2005 एनरिको रोस\n" +"(C) 2005 पियोत्र स्जाइमंस्की\n" +"(C) 2004-2017 अलबर्ट एस्टल्स सिड\n" +"(C) 2006-2009 पिनो तोस्कानो" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "भूतपूर्व अनुरक्षक" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "अनेक फ्रेमवर्क कार्य, ओडीटी तथा फ़िक्शनबुक बैकएण्ड" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "विकासकर्ता" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "केपीडीएफ कोडबेस से ऑकुलर निर्मित किया" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "केपीडीएफ़ विकासकर्ता" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "टीका संबंधित कलाकृति" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "तालिका चयन उपकरण" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "टीका सुधार" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "पृष्ठ %1 पर जाएं" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "बाहरी फ़ाइल खोलें" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "चलाएँ '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "प्रथम पृष्ठ" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "पिछला पृष्ठ" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "अगला पृष्ठ" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "अंतिम पृष्ठ" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "पीछे" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "आगे" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "बाहर जाएँ" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "प्रस्तुतीकरण चालू करें" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "प्रस्तुतीकरण बन्द करें" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "ढूंढें..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "पृष्ठ पर जाएं..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "ध्वनि बजाएं..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "जावास्क्रिप्ट स्क्रिप्ट" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "चलचित्र चलाएँ..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "चलचित्र चलाएँ" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "चलचित्र बंद करें" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "चलचित्र रोकें" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "बैकएण्ड चयन" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "अधिकतर पृष्ठ %1 आकार के हैं।" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "खड़ा %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "आड़ा %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 इंच (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 मिमी (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "प्रारंभ से खोज चालू कर रहें हैं" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "अंत से खोज चालू कर रहें हैं" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "टीकाएं हटाएँ" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "माइमप्रकार %1 युक्त फ़ाइल को खोलने के लिए कोई अनुप्रयोग नहीं मिला." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "एक अस्थायी फ़ाइल को नहीं खोला जा सका" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "छापने हेतु फ़ाइल ढूंढ पाने में अक्षम" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "%1 को खोला नहीं जा सका। फ़ाइल अस्तित्व में नहीं है" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "शीर्षक" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "विषय" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "वर्णन" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "लेखक" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "निर्माता" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "निर्माता" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "सर्वाधिकार सुरक्षित" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "पृष्ठ" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "निर्मित" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "परिवर्धित" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "माइम प्रकार" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "श्रेणी" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "संकेतशब्द" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "फ़ाइल पथ" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "फ़ाइल आकार" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "पृष्ठ आकार" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "टीका जोड़ें" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "टीकाएं हटाएँ" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "एन्नोटेशन गुण" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "पाठ एन्नोटेशन" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "टीका समायोजित करें" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "पाठ संपादन" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "टीका विषय संपादित करें" + +#: core/documentcommands.cpp:438 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "एन्नोटेशन गुण" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "सादा पाठ... (&T) " + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "पीडीएफ" + +# This is a document format like ODF +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "मुक्त-दस्तावेज़ पाठ" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "एचटीएमएल" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "छपाई के विकल्प" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "आकार विधि :" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "इस संदेश को बंद करें" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "स्रोत: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "तयशुदा फ़ॉन्ट (&D):" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Red" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "लाल" + +#: part/annotationactionhandler.cpp:138 +#, fuzzy, kde-format +#| msgid "Orange" +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "नारंगी" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Yellow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "पीला" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgid "Green" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "हरा" + +#: part/annotationactionhandler.cpp:141 +#, fuzzy, kde-format +#| msgid "Cyan" +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "सियान" + +#: part/annotationactionhandler.cpp:142 +#, fuzzy, kde-format +#| msgid "Blue" +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "नीला" + +#: part/annotationactionhandler.cpp:143 +#, fuzzy, kde-format +#| msgid "Magenta" +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "रानी रंग" + +#: part/annotationactionhandler.cpp:144 +#, fuzzy, kde-format +#| msgid "White" +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "सफेद" + +#: part/annotationactionhandler.cpp:145 +#, fuzzy, kde-format +#| msgid "Gray" +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "धूसर" + +#: part/annotationactionhandler.cpp:146 +#, fuzzy, kde-format +#| msgid "Black" +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "काला" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "चौड़ाई %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "एन्नोटेशन गुण" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "टीका पाठ रंग" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "एनोटेशन" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "टीका रंग" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "एनोटेशन" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "टीका फ़ॉन्ट" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "एन्नोटेशन गुण" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "रंग" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "भराव रंग" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "तदनुकूल रंग..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "परीक्षणाधीन" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "रंग चुनें" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "टीकाएं (&A)" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "छुपाएँ" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "उभारें" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "रेखांकित" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "टेढ़ा मेढ़ा" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "लिखकर काटें" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "टाईपराइटर" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "इनलाइन टिप्पणी" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "पॉपअप टिप्पणी" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "रेखा गुण" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Straight Yellow Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "सीधी पीली लकीर" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "तीर" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "चतुर्भुज" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "दीर्घवृत्त" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "बहुभुज" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "मुद्रांकन" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "द्रुत टीकाएं" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "द्रुत टीकाओं में जोड़ें" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "प्रस्तुतीकरण" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "फ़ॉन्टः" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "एन्नोटेशन गुण" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "लकीर की चौड़ाई" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "अपारदर्शिता" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "पृष्ठ %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "टीका" +msgstr[1] "%1 टीकाएं" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "पॉप अप नोट खोलें (&O)" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "मिटाएँ (&D)" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "गुण (&P)" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "'%1' को संरक्षित करें (&S)" + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "रूप (&A)" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "सामान्य (&G)" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "लेखकः (&A)" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "निर्मित :" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "परिवर्धित :" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Pop-up Note Properties" +msgstr "नोट गुण" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "टाईपराइटर गुण" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "इनलाइन नोट गुण" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line Properties" +msgstr "रेखा गुण" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "बहुभुज गुण" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "ज्यामितीय गुण" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Stamp Properties" +msgid "Text Markup Properties" +msgstr "स्टैम्प गुण" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "मुद्रांकन गुण" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line Properties" +msgstr "रेखा गुण" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "हंसपद गुण" + +#: part/annotationpropertiesdialog.cpp:141 +#, fuzzy, kde-format +#| msgid "Inline Note Properties" +msgid "File Attachment Properties" +msgstr "इनलाइन नोट गुण" + +#: part/annotationpropertiesdialog.cpp:144 +#, fuzzy, kde-format +#| msgid "Ink Properties" +msgid "Sound Properties" +msgstr "स्याही गुण" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "चलचित्र के गुण" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "एन्नोटेशन गुण" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "परिवर्धित : %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "तदनुकूल मुद्रांकन चिह्न फ़ाइल से चुने" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "तदनुकूल मुद्रांकन चिह्न चुने" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "अमान्य फ़ाइल" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "रंग (&C) :" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr " %" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "अपारदर्शिता: (&O)" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "प्रतीक :" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "टिप्पणी" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "सहायता" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "प्रविष्ट" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "कुंजी" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "नया अनुच्छेद" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "टिप्पणी" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "पैराग्राफ" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "फ़ॉन्टः" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "पाठ रंग (&C) :" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "संरेखण करें: (&A)" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "बाएँ" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "मध्य" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "दाएँ" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "स्वीकृत" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "जैसा है" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "गोपनीय" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "विभागीय" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "प्रारूप" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "परीक्षणाधीन" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "अंतिम" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "टिप्पणियों के लिए" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "सार्वजनिक प्रकाशन करने के लिए" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "स्वीकृत नहीं" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "सार्वजनिक प्रकाशन करने के लिए नहीं" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "बिक गया" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "अत्यंत गुप्त" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "पुस्तचिन्ह" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "जानकारी" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "केडीई" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "मुद्रांकन चिह्न :" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "चौड़ाई: (&W)" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "रेखा प्रारंभ" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "रेखा समाप्त:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "वर्ग" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "वृत्त" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "हीरा" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "कुछ भी नहीं" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "बट" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "स्लैश" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "लीडर लाइन लंबाई:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "लीडर लाइन एक्सटेंशन लंबाई:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "सक्षम" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "फ़ाइल में सहेजें..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "प्रकार :" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "उभारें" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr " टेढ़ा मेढ़ा" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "रेखांकित" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "लिखकर काटें" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "चतुर्भुज" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "दीर्घवृत्त" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "Inline Note Properties" +msgid "File attachment symbol:" +msgstr "इनलाइन नोट गुण" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "लेखाचित्र\t" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "पुश पिन" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "कागज़ क्लिप" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "टैग" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "फ़ाइल" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "लागू नहीं" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "" + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "नाम:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "वर्णन :" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "हंसपद चिन्ह" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "कुछ भी नहीं" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Close this note" +msgstr "इस संदेश को बंद करें" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "विकल्प" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"%2 पुस्तचिन्ह" +msgstr[1] "" +"%1\n" +"\n" +"%2 पसंदीदा" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "पुस्तचिन्ह" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "ढूंढें..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "सिर्फ वर्तमान दस्तावेज़" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "इस पुस्तचिन्ह पर जाएँ" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "पुस्तचिन्ह का नाम बदलें" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "पुस्तचिन्ह हटाएँ" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "दस्तावेज़ खोलें" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "पुस्तचिन्ह हटाएँ" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "संस्करण" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Pages Size" +msgid "Serial Number" +msgstr "पृष्ठ आकार" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "जारीकर्ता" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "मियाद ख़त्म" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "विषय" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "सार्वजनिक चाभी:" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "मेमोरी उपयोग" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "सं%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "गुण" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "मूल्य" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Certificate Viewer" +msgstr "प्रदर्शक कॉन्फ़िगर करें..." + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "निर्यात..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "सामान्य" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "ईमेल" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "वैधता" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "विवरण" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "%1 को आप कहाँ सहेजना चाहते हैं?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "लाल" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "हरा" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "नीला" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "पीला" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "काला" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "सफेद" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "छवियों के चारों ओर सीमारेखा बनाएँ (&I)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "कड़ियों के चारों ओर सीमारेखा बनाएँ (&L)" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "रंग बदलें (&C)" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "चेतावनी: ये विकल्प दस्तावेज़ प्रदर्शन की गति को बुरी तरह प्रभावित करेंगे।" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "रंग रीति :" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, fuzzy, kde-format +#| msgid "Invert colors" +msgid "Invert Colors" +msgstr "रंग उलटें" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "कागज़ का रंग बदलें" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, fuzzy, kde-format +#| msgid "Change dark and light colors" +msgid "Change Dark & Light Colors" +msgstr "गहरे तथा हल्के रंग बदलें" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, fuzzy, kde-format +#| msgid "Convert to black and white" +msgid "Convert to Black & White" +msgstr "श्वेत श्याम में बदलें" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "उजालापन उलटें" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "लूमा उलटें (एसआरजीबी लिनियर)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "लूमा उलटें (सममित)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "कागज़ का रंग:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "गहरा रंग:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "हल्का रंग:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "देहलीज :" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "रंगभेद :" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "कथन" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "इंजन" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "पहचान" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "लेखक (&t):" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"ध्यान दें: इस जानकारी का उपयोग केवल टीकाकरण हेतु किया जाता है। यह जानकारी " +"टीकाकृत दस्तावेज़ में संरक्षित की जाती है और इसलिए दस्तावेज़ के संग ही प्रसारित की जाएगी।" + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "द्रुत टीका औज़ार" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "तदनुकूल पाठ संपादक" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "केट" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "काइल" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "साइटीइ" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "इमैक्स क्लाएंट" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "लिक्स क्लाएंट" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "टैकस्टूडियो" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "टैकिफ़ाइ आई-डी-ई-ए" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "संपादक" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "संपादक:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "वह संपादक चुनें जिसका उपयोग ऑकुलर स्रोत फ़ाइल खोलने हेतु करेगा।" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "कमांडः" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "रूप" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "स्क्रॉल पट्टियाँ दिखाएँ (&b)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "लघुछवियों को पृष्ठ से जोड़े (&t)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "संकेत तथा जानकारी संदेश दिखाएँ (&h)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "दस्तावेज़ का शीर्षक, यदि उपलब्ध हो, शीर्षक पट्टी में दिखाएँ" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "जब दस्तावेज़ का शीर्षक नहीं दिखा रहें हो तब:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "केवल फ़ाइल का नाम दिखाएँ" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "फ़ाइल का पूर्ण पथ दिखाएँ" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "तदनुकूल पृष्ठभूमि रंग का प्रयोग करें" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "अनुप्रयोग विशेषताएँ" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "नई फ़ाइलें नए टैब में खोलें (&t)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "यदि फ़ाइल पहले से खुली है तो वर्तमान टैब में जाएँ" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "डीआरएम सीमाएँ मानें (&O)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "फ़ाइल बदलने पर दस्तावेज़ को पुनः लोड करें (&R)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "बैकएण्ड चयन संवाद दिखाएँ" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "दाँए से बाँए पढ़ने की दिशा" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "विकल्प दिखाएँ" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "विहंगावलोकन स्तम्भ (&c):" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "तयशुदा जूम (&d):" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "१००%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "चौड़ाई फिट करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "पृष्ठ में फिट करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "स्वतः फिट" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"प्रयोग की मेमोरी को न्यूनतम बनाए रखता है। पुनः प्रयोग नहीं करता। (कम मेमोरी युक्त तंत्रों " +"हेतु)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"प्रयोग की मेमोरी को न्यूनतम बनाए रखता है. फिर से इस्तेमाल कुछ नहीं करें (कम मेमोरी युक्त " +"सिस्टम के लिए)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "सीपीयू उपयोग" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "पारदर्शिता प्रभाव को सक्षम करें (&t)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "मेमोरी उपयोग" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "कम (&L)" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "सामान्य (तयशुदा) (&N)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "आक्रामक (&e)" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "लोभी (&r)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "रेंडरिंग" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "पाठ ऐंटीऐलिय्स सक्षम करें" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "ग्राफ़िक्स ऐंटीऐलिय्स सक्षम करें" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "पाठ संकेत सक्षम करें" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "वर्तमान स्क्रीन" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "तयशुदा स्क्रीन" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "स्क्रीन %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " सेकंड" +msgstr[1] " सेकंड" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "नेविगेशन" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "प्रत्येक के बाद आगे बढ़ें:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "अंतिम पृष्ठ के बाद लूप करें" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "नेविगेशन" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "आगे/पीछे जाने हेतु पर भी दाएँ/बाएँ थपथपाएँ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "आगे बढ़ने हेतु कहीं पर भी थपथपाएँ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "निष्क्रिय" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "पृष्ठभूमि का रंगः" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "माउस संकेतक:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "थोड़ी देरी के पश्चात छिपें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "हमेशा दृष्टिगोचर" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "हमेशा छिपे रहें" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "प्रगति सूचक दिखाएं (&p)" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "सारांश पृष्ठ दिखाएँ (&u)" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, fuzzy, kde-format +msgid "Enable transitions" +msgstr "डिफ़ॉल्ट ट्रांज़ीशन:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "डिफ़ॉल्ट ट्रांज़ीशन:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "लंबवत चकाचौंध" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "क्षितिजिय चकाचौंध" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "बॉक्स इन" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "बॉक्स आउट" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "विलय" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "विवर्ण" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "ग्लिटर नीचे" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "ग्लिटर दायाँ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "ग्लिटर नीचे, दायाँ" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "रेंडम ट्रांज़ीशन" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "बदलें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "आड़े में भीतरी ओर विभाजित करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "आड़े में बाहरी ओर विभाजित करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "खड़े में भीतरी ओर विभाजित करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "खड़े में बाहरी ओर विभाजित करें" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "नीचे की तरफ वाइप" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "दायीं तरफ से वाइप" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "बायीं तरफ से वाइप" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "ऊपर की तरफ वाइप" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "स्क्रीन :" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, fuzzy, kde-format +#| msgid "Drawing" +msgid "Drawing Tool: %1" +msgstr "ड्राइंग" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "रबड़" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "नाम (&N):" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "प्रकार (&T):" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "पॉप अप नोट" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "इनलाइन टिप्पणी" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "मुक्तहस्त रेखा" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "सीधी रेखा" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "बहुभुज" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "पाठ मार्कअप" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "मुद्रांकन" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "टाईपराइटर" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "टीका उपकरण बनाएँ" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "टीका उपकरण संपादित करें" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "रंग:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "लेखनी की चौड़ाई: (&P)" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " पीएक्स" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "चित्रकला उपकरण बनाएँ" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "चित्रकला उपकरण संपादित करें" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "अज्ञात" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "सन्निहित फ़ाइलें" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "देखें" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "नाम" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "वर्णन" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "आकार" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "निर्मित" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "परिवर्धित" + +#: part/embeddedfilesdialog.cpp:152 +#, fuzzy, kde-format +#| msgid "Save As..." +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "ऐसे सहेजें..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "दृश्य... (&V)" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "बंद करें" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "ढूंढें: (&i)" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "ढूंढा जाने वाला पाठ" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "अगला" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "अगले मेल-खाते पाठ में जाएँ" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "पिछला" + +#: part/findbar.cpp:62 +#, fuzzy, kde-format +#| msgid "Jump to next match" +msgid "Jump to previous match" +msgstr "अगले मेल-खाते पाठ में जाएँ" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "खोज व्यवहार परिवर्धित करें" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "केस सेंसिटिव" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "आप टाइप करते हुए पाठ ढूंढें" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|सभी फ़ाइलें" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Signature Properties" +msgstr "नोट गुण" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line with Comment" +msgstr "रेखा गुण" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "टिप्पणी के संग बहुभुज" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "टिप्पणियों के लिए" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "ज्यामिति" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "उभारें" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle with Comment" +msgstr "स्क्विग्ली" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Underline with Comment" +msgstr "रेखांकित" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Strike out" +msgid "Strike Out with Comment" +msgstr "लिखकर काटें" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "लिखकर काटें" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "टिप्पणी संग मुद्रांकित करें" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line with Comment" +msgstr "रेखा गुण" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "हंसपद" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "ध्वनि" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "चलचित्र" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "स्क्रीन" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "विजेट" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "अज्ञात" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "लेखक: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "%1 को आप कहाँ सहेजना चाहते हैं?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "फ़ाइल \"%1\" को खोला नहीं जा सका। फ़ाइल को संरक्षित नहीं किया गया।" + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "खोज के विकल्प" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "अक्षर संवेदनशील" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "रेगुलर एक्सप्रेशन" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "ढूंढें: (&e)" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "परतें" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "का" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "ज़ूम" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, fuzzy, kde-format +#| msgid "Rotate Right" +msgid "Rotate &Right" +msgstr "दाएँ मुड़ें" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "दाएँ" + +#: part/pageview.cpp:554 +#, fuzzy, kde-format +#| msgid "Rotate Left" +msgid "Rotate &Left" +msgstr "बाएँ मुड़ें" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "बाएँ" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "मूल दिशा" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "देखें (&V)" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "चयन के अनुसार काट-छाँट करें" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "चौड़ाई में फिट करें (&W)" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "पृष्ठ में फिट करें (&P)" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&स्वतः फिट" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "पृष्ठ में फिट करें (&P)" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "दृश्य मोड (&V)" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "एकल पृष्ठ" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "आमने सामने के पृष्ठ" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Center &first page" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "प्रथम पृष्ठ बीचोंबीच करें (&f)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "विहंगावलोकन (&O)" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "लगातार (&C)" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "विचरण (&B)" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "ज़ूम (&Z)" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &Colors" +msgid "&Toggle Change Colors" +msgstr "रंग बदलें (&C)" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "क्षेत्र का चयन (&S)" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "पाठ चयन (&T)" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "तालिका चयन (&a)" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "चयन औज़ार" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "पुरे दस्तावेज़ को पढ़कर सुनाएं" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "ऊपर स्क्रॉल करें" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "नीचे स्क्रॉल करें" + +#: part/pageview.cpp:759 +#, fuzzy, kde-format +#| msgid "Scroll Up" +msgid "Scroll Page Up" +msgstr "ऊपर स्क्रॉल करें" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "पृष्ठ नीचे स्क्रॉल करें" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "फ़ॉर्म दिखाएँ" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " पृष्ठ का दस्तावेज़ लोड किया गया." +msgstr[1] " %1 पृष्ठों का दस्तावेज़ लोड किया गया." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "पाठ (%1 अक्षर)" +msgstr[1] "पाठ (%1 अक्षर)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "क्लिपबोर्ड पर नकल बनाएं" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "डीआरएम द्वारा नक़ल किया जाना प्रतिबंधित है" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "पाठ बोलें" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "छवि (%1 x %2 पिक्सेल्स)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "फ़ाइल में सहेजें..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "छवि [%1x%2] क्लिपबोर्ड पर नक़ल किया गया." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "फ़ाइल सहेजें" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "फ़ाइल को सहेजा नहीं गया." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "छवि [%1x%2] को %3 फ़ाइल में सहेजा." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "पाठ की नक़ल बनाएं" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "'%1' पर जाएं" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "'%1' को ढूंढें इसके साथ" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "वेब शार्टकटों को विन्यस्त करें..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "इस लिंक पर जाएँ" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "यह ध्वनि बजाएं..." + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "ध्वनि बन्द करें" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "कड़ी का पता नक़ल करें" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "इस दस्तावेज़ में %1 को ढूंढें" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "सुस्वागतम" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "जूमिंग क्षेत्र चुनें. ज़ूम-आउट होने के लिए क्लिक करें." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "नक़ल करने के लिए पाठ/चित्र के चारों ओर एक आयताकार बनाएँ." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "पाठ चुनें" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "नक़ल करने के लिए पाठ/चित्र के चारों ओर एक आयताकार बनाएँ." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "नक़ल करने के लिए पाठ/चित्र के चारों ओर एक आयताकार बनाएँ." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "नया पाठ नोट" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "नए नोट का पाठ:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "पुस्तचिन्ह टीका" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "इनलाइन पाठ एन्नोटेशन (किसी जोन को चुनने के लिए माउस क्लिक कर खींचें)" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "उभारें" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "इनलाइन पाठ एन्नोटेशन (किसी जोन को चुनने के लिए माउस क्लिक कर खींचें)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "पॉलीगान बनाएं (इसे बन्द करने के लिए पहले बिन्दु पर क्लिक करें)" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "चतुर्भुज" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "स्क्विग्ली" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "एक मुद्रांकन चिह्न लगाएँ" + +#: part/pageviewannotator.cpp:1039 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Straight Yellow Line" +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "सीधी पीली लकीर" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +#| msgid "Strike out" +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "लिखकर काटें" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "रेखांकित" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "टाईपराइटर टीका (किसी जोन को चुनने के लिए माउस क्लिक कर खींचें)" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "उभारें" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "पसंदीदा टीका जोड़ें" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +msgid "Custom annotation name:" +msgstr "एनोटेशन" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "फ़ाइल (&F)" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "विन्यास (&S)" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "सहायता (&H)" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "दिशा-स्थिति (&O)" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "पुस्तचिन्ह (&B)" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, fuzzy, kde-format +#| msgid "Main Toolbar" +msgid "Viewer Toolbar" +msgstr "मुख्य औज़ार पट्टी" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "लघु छवि" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "टीकाएं" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"दस्तावेज़ में सन्निहित फ़ाइलें हैं. उन्हें देखने के लिए यहाँ " +"क्लिक करें या फ़ाइल -> सन्निहित फ़ाइलें में जाएँ." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "पिछला" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "पिछले पृष्ठ पर जाएँ" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "दस्तावेज़ के पिछले पृष्ठ पर जाता है" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "अगला" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "अगले पृष्ठ में जाएँ" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "दस्तावेज़ के अगले पृष्ठ पर जाता है" + +#: part/part.cpp:668 +#, fuzzy, kde-format +#| msgid "Reloading the document..." +msgid "Beginning of the document" +msgstr "दस्तावेज़ को रीलोड किया जा रहा है..." + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "दस्तावेज़ के प्रारंभ पर ले जाता है" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "दस्तावेज़ का अंत" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "दस्तावेज़ के अंत पर ले जाता है" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "वर्तमान पुस्तचिन्ह का नाम बदलें" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "पिछला पुस्तचिन्ह" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "पिछले पुस्तचिन्ह पर जाएँ" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "अगला पुस्तचिन्ह" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "अगले पुस्तचिन्ह पर जाएँ" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "ऑकुलर को विन्यस्त करें..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "प्रदर्शक विन्यस्त करें..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "प्रदर्शक बैकएण्ड्स विन्यस्त करें..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "बैकएण्ड्स विन्यस्त करें..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "बैकएण्ड के बारे में..." + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "पुनः लोड करें (&d)" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "वर्तमान दस्तावेज़ डिस्क से पुनः लोड करें।" + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "खोज पट्टी बन्द करें (&F)" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "पृष्ठ क्रमांक" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "बाजूपट्टी दिखाएँ (&i)" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "हस्ताक्षरों का फलक दिखाएँ (&S)" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "सन्निहित फ़ाइलें (&E)" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "इस रूप में निर्यात करें (&x)" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "साझा करें (&h)" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "प्रेजेन्टेशन (&r)" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, fuzzy, kde-format +#| msgid "&Import Postscript as PDF..." +msgid "&Import PostScript as PDF..." +msgstr "पोस्ट-स्क्रिप्ट को पीडीएफ के रूप में आयात करें...(&I)" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "इंटरनेट से किताबें लाएँ... (&G)" + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "ड्राइंग मिटाएँ" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "टीका विन्यस्त करें..." + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "प्रस्तुतीकरण" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "\"'%1\" को खोल नहीं सकते (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "" + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "%1 को खोला नहीं जा सका. कारण: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "प्रदर्शक बैकएण्ड्स विन्यस्त करें" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "बैकएण्ड्स विन्यस्त करें" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf नहीं मिला" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" +"पीएस फ़ाइल को पीडीएफ़ के रूप में आयात किया जा रहा है (इसमें कुछ समय लग सकता है)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "दस्तावेज़ को पढ़ने के लिए कूटशब्द को प्रविष्ट करें :" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "गलत कूटशब्द। फिर से कोशिश करें :" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "दस्तावेज़ कूटशब्द" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "यह दस्तावेज़ डिजिटल रूप से हस्ताक्षरित है।" + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "This document is digitally signed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "यह दस्तावेज़ डिजिटल रूप से हस्ताक्षरित है।" + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "प्रस्तुतीकरण मोड से बाहर हों" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "\"'%1\" को खोल नहीं सकते। %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "फिर से लोड करना जारी रखें" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "लगातार (&C)" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +#| msgid "Open a document" +msgid "Close Document" +msgstr "दस्तावेज़ खोलें" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "दस्तावेज़ को रीलोड किया जा रहा है..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "विषय सूची" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "हस्ताक्षरें" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "पृष्ठ पर जाएं" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "पृष्ठ: (&P)" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "पुस्तचिन्ह के लिए नया नाम प्रविष्ट करें :" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "इस पुस्तचिन्ह का नाम बदलें" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "यह पुस्तचिन्ह हटाएँ" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "ऐसे सहेजें" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "संरक्षण - चेतावनी" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "अस्थायी फ़ाइल को सहेजने के लिए नहीं खोला जा सका।" + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Filled form contents" +msgstr "एन्नोटेशन गुण" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "उपयोक्ता टीकाएं" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "चेतावनी" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "जारी रखें" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "फ़ाइल को '%1' में सहेजा नहीं जा सका. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File not saved." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "फ़ाइल को सहेजा नहीं गया." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "प्रस्तुतीकरण बन्द करें" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "सभी फैलाएँ" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "पुस्तचिन्ह जोड़ें" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "औज़ार" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "छापें" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "इस दस्तावेज़ को छापने की अनुमति नहीं है।" + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "दस्तावेज़ छापा नहीं जा सका। अज्ञात त्रुटि। कृपया bugs.kde.org में रिपोर्ट दर्ज करें." + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"दस्तावेज़ छापा नहीं जा सका। विस्तृत त्रुटि है \"%1\" । कृपया bugs.kde.org में रिपोर्ट दर्ज " +"करें।" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "उस जगह पर जाएं जहाँ आप पहले जा चुके हैं" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "उस जगह पर जाएँ जहाँ आप जाना चाहते हैं" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"फ़ाइल त्रुटि! अस्थायी फ़ाइल तैयार नहीं कर सका%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"फ़ाइल त्रुटि! फ़ाइल %1को " +"असंपीडित करने के लिए खोल नहीं सका. फ़ाइल को लोड नहीं किया जा सका." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"फ़ाइल त्रुटि! फ़ाइल %1 को " +"असंपीडित नहीं किया जा सकता. फ़ाइल को लोड नहीं किया जा सका." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "कोई पसंदीदा नहीं" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "साझा करें" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "दस्तावेज़ सफलतापूर्वक साझा किया गया" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "संपादन (&E)" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "दृश्य (&V)" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "जाएँ (&G)" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "औज़ार (&T)" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "मुख्य औज़ारपट्टी" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "टीका औज़ारपट्टी" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "सामान्य विकल्प" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "पहुँच" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "पढ़ने में सहायक" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "परफार्मेंस" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "परफ़ॉर्मेंस ट्यूनिंग" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "प्रदर्शक विन्यस्त करें" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "प्रस्तुतीकरण" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "प्रेजेन्टेशन मोड के लिए विकल्प" + +#: part/preferencesdialog.cpp:50 +#, fuzzy, kde-format +msgid "Annotation Options" +msgstr "टीकाकरण संबंधी विकल्प" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "संपादक संबंधी विकल्प" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "अगला ढूंढें" + +#: part/presentationwidget.cpp:169 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "प्रस्तुतीकरण" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "स्क्रीन %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "प्रस्तुतीकरण मोड से बाहर हों" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "शीर्षक: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "पृष्ठ: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "प्रारंभ करने के लिए क्लिक करें" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "रोकें" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "चलाएँ" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "प्रस्तुतीकरण दिया जा रहा है" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "अज्ञात फ़ाइल" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 गुण" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "फ़ॉन्ट्स (&F)" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "फ़ॉन्ट जानकारी पढ़ी जा रही है..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "पृष्ठ आकार (&P)" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "" + +# type is font +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "टाइप १" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "टाइप १सी" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "टाइप १सी (ओटी)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "टाइप ३" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "ट्रू-टाइप" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "ट्रूटाइप (ओटी)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "सीआईडी टाइप o" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "सीआईडी टाइप 0सी" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "सीआईडी टाइप 0सी (ओटी)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "सीआईडी ट्रूटाइप" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "सीआईडी ट्रू टाइप (ओटी)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "टैक पीके" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "अज्ञात" + +#: part/propertiesdialog.cpp:332 +#, fuzzy, kde-format +#| msgid "Yes (subset)" +msgid "Embedded (subset)" +msgstr "हाँ (सबसेट)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "पूर्णता: सन्निहित" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "नहीं" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "हाँ (सबसेट)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "हाँ" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[लागू नहीं]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "अज्ञात फ़ॉन्ट" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "सन्निहित : %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "नाम" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "प्रकार" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "फ़ाइल" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "पृष्ठ" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "आकार" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "%1 को आप कहाँ सहेजना चाहते हैं?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "%1 फ़ाइल को सहेज नहीं सका।" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "%1 को खोला नहीं जा सका. कारण: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "पृष्ठों को फिल्टर करने के लिए कम से कम तीन अक्षर भरने होंगे" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "केस सेंसिटिव" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "वाक्यांश मिलाएँ" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "सभी शब्दों को मिलाएँ" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "कोई भी शब्द को मिलाएँ" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "फ़िल्टर विकल्प" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "पृष्ठ आधार पर समूहबद्ध करें" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "लेखक के आधार पर समूहबद्ध करें" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "सिर्फ वर्तमान पृष्ठ के लिए रीव्यू दिखाएं" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "एमडी२" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "एमडी५" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "एसएचए१" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "एसएचए२५६" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "एसएचए३८४" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "एसएचए५१२" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "एसएचए२२४" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Unknown author" +#| msgid "Unknown" +msgid "Unknown Algorithm" +msgstr "अज्ञात" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "आरएसए" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "डीएसए" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "अज्ञात प्रकार" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "डिजिटल हस्ताक्षर" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "सीआरएल हस्ताक्षरित करें" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "उपलब्ध नहींं" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "कारण : %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "गुण" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "वैधता स्थिति" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "हस्ताक्षर की वैधता :" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "अतिरिक्त जानकारी" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "हस्ताक्षरित :" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "कारण :" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "स्थान :" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "दस्तावेज़ संस्करण" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "दस्तावेज़ संशोधन, %2 में से %1" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "हस्ताक्षरित संस्करण देखें..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "प्रमाणपत्र देखें..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "केवल पुस्तचिन्हित पृष्ठों को ही दिखाएँ" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "चलाएँ" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "रोकें" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "बंद करें" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "जोड़ें... (&A)" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "संपादन... (&E)" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "हटाएँ (&R)" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "ऊपर की ओर ले जाएँ" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "नीचे ले जाएँ (&D)" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "तयशुदा चित्रकला औज़ार #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "दस्तावेज़ का दिखाया जाने वाला पृष्ठ" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "दस्तावेज को प्रस्तुतीकरण मोड में प्रारंभ करें" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find the Okular component: %1" +msgstr "ऑकुलर पार्ट ढूंढ पाने में अक्षम." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, fuzzy, kde-format +#| msgid "Unable to find okular part." +msgid "Unable to find the Okular component." +msgstr "ऑकुलर पार्ट ढूंढ पाने में अक्षम." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"किसी फ़ाइल को खोलने के लिए क्लिक करें\n" +"किसी हालिया फ़ाइल को खोलने के लिए क्लिक कर दबाए रखें" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"किसी फ़ाइल को खोलने के लिए क्लिक करें या फिर किसी हालिया फ़ाइल को चुनने के लिए " +"क्लिक कर दबाए रखें" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "अगला टैब" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "पिछला टैब" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "सभी फ़ाइलें (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "दस्तावेज़ खोलें" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "टैबों को बंद करें" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "आप %1 टैबों को बंद करने वाले हैं। क्या आप वाकई जारी रखना चाहते हें?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "समीक्षा" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "फ़ॉर्म छुपाएँ" + +#~ msgid "Expired" +#~ msgstr "मियाद ख़त्म" + +#~ msgid "&Review" +#~ msgstr "समीक्षा (&R)" + +#~ msgid "Annotations author" +#~ msgstr "एन्नोटेशन लेखक" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "कृपया अपना नाम या आद्याक्षर भरें:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "नेविगेशन फलक दिखाएँ (&N)" + +#~ msgid "Show Text" +#~ msgstr "पाठ दिखाएँ" + +#, fuzzy +#~| msgid "Icon" +#~ msgid "Large Icons" +#~ msgstr "प्रतीक" + +#~ msgid "Created: %1" +#~ msgstr "निर्मित: %1" + +#~ msgid "Line Extensions" +#~ msgstr "लाइन एक्सटेंशन्स" + +#, fuzzy +#~| msgid "Title" +#~ msgid "Style" +#~ msgstr "शीर्षक" + +#, fuzzy +#~| msgid "Size" +#~ msgid "&Size:" +#~ msgstr "आकार" + +#~ msgid "Inner color:" +#~ msgstr "आंतरिक रंग:" + +#, fuzzy +#~| msgid "Pages: %1" +#~ msgid "Name: %1" +#~ msgstr "पृष्ठ: %1" + +#, fuzzy +#~| msgid "Size" +#~ msgid "Size: %1" +#~ msgstr "आकार" + +#~ msgid "&Browse Tool" +#~ msgstr "ब्राउज़ औज़ार (&B)" + +#~ msgid "&Zoom Tool" +#~ msgstr "ज़ूम औज़ार (&Z)" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "ज़ूम" + +#, fuzzy +#~| msgid "Selection Tools" +#~ msgid "&Selection Tool" +#~ msgstr "चयन औज़ार" + +#, fuzzy +#~| msgctxt "Select Tool" +#~| msgid "Select" +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "चुनें" + +#~ msgid "&Text Selection Tool" +#~ msgstr "पाठ चयन औजार (&T)" + +#, fuzzy +#~| msgid "Selection Tools" +#~ msgid "T&able Selection Tool" +#~ msgstr "चयन औज़ार" + +#, fuzzy +#~| msgid "Reloading the document..." +#~ msgid "Only for PDF documents" +#~ msgstr "प्रलेख को रीलोड किया जा रहा है..." + +#, fuzzy +#~| msgid "Note" +#~ msgid " None" +#~ msgstr "टिप्पणी" + +#, fuzzy +#~| msgid "Exit Presentation Mode" +#~ msgid "Presentation Mode" +#~ msgstr "प्रस्तुतीकरण मोड से बाहर हों" + +#, fuzzy +#~| msgid "Exit Presentation Mode" +#~ msgid "Allow the presentation mode" +#~ msgstr "प्रस्तुतीकरण मोड से बाहर हों" + +#, fuzzy +#~| msgid "Start the document in presentation mode" +#~ msgid "Do not allow the presentation mode" +#~ msgstr "दस्तावेज को प्रस्तुतीकरण मोड में प्रारंभ करें" + +#, fuzzy +#~| msgid "Save As..." +#~ msgid "Save &Copy As..." +#~ msgstr "ऐसे सहेजें..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "प्रलेख का अंत आ पहुँचा\n" +#~ "प्रारंभ से जारी रखें?" + +#, fuzzy +#~| msgid "" +#~| "End of document reached.\n" +#~| "Continue from the beginning?" +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "प्रलेख का अंत आ पहुँचा\n" +#~ "प्रारंभ से जारी रखें?" + +#~ msgid "Current maintainer" +#~ msgstr "वर्तमान मेंटेनर" + +#~ msgid "Pino Toscano" +#~ msgstr "पिनो टोसकानो" + +#~ msgid "Tobias Koenig" +#~ msgstr "टॉबियस कोएनिग" + +#~ msgid "Albert Astals Cid" +#~ msgstr "अलबर्ट एस्टल्स सिड" + +#~ msgid "Piotr Szymanski" +#~ msgstr "पियोत्र स्जाइमंस्की" + +#~ msgid "Enrico Ros" +#~ msgstr "एनरिको रॉस" + +#~ msgid " sec." +#~ msgstr " सेक." + +#~ msgid "Pencil color:" +#~ msgstr "पेंसिल रंग:" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "ड्राइंग मोड टॉगल करें" + +#, fuzzy +#~| msgid "Starting KTTSD Failed: %1" +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "केटीटीएसडी शुरु करने में असफल: %1" + +#~ msgid "Search Columns" +#~ msgstr "खोज स्तम्भ" + +#~ msgid "All Visible Columns" +#~ msgstr "सभी द्ष्टिगोचर स्तम्भ" + +#~ msgid "No document opened." +#~ msgstr "कोई प्रलेख खुला नहीं." + +#~ msgid "No matches found for '%1'." +#~ msgstr " '%1' के लिए कोई जोड़ नहीं मिला." + +#~ msgid "Search in progress..." +#~ msgstr "ढूंढा जा रहा है..." + +#~ msgid "Searching for %1" +#~ msgstr "%1 के लिए ढूंढा जा रहा है" + +#~ msgid "Identity Settings" +#~ msgstr "पहचान विन्यास" + +#~ msgid "Highlight Properties" +#~ msgstr "गुणों को उभारें" + +#~ msgid "Ink Properties" +#~ msgstr "स्याही गुण" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "पाठ एन्नोटेशन" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "हरी स्याही" + +#, fuzzy +#~| msgctxt "Annotation tool" +#~| msgid "Yellow Highlight" +#~ msgid "Yellow Highlighter" +#~ msgstr "पीला उभारें" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "पीला उभारें" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "सीधी पीली लकीर" + +#, fuzzy +#~| msgid "Underline" +#~ msgid "Black Underlining" +#~ msgstr "रेखांकित" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "पाठ को काली लकीर से रेखांकित करें" + +#, fuzzy +#~| msgctxt "Annotation tool" +#~| msgid "A cyan ellipse" +#~ msgid "Cyan Ellipse" +#~ msgstr "क्यान दीर्घवृत्त" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "क्यान दीर्घवृत्त" + +#~ msgid "Ink" +#~ msgstr "स्याही" + +#~ msgid "Enable &background generation" +#~ msgstr "पृष्ठभूमि बनाना सक्षम करें (&b)" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "फ़ॉर्म छुपाएँ" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "प्रलेख के प्रथम पृष्ठ पर जाता है" + +#~ msgid "You must set this name:" +#~ msgstr "आपको यह नाम सेट करना आवश्यक है:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "Overwrite" +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "मिटाकर लिखें" + +#~ msgid "Pages:" +#~ msgstr "पृष्ठ:" + +#, fuzzy +#~| msgid "Highlight" +#~ msgid "Green Highlighter" +#~ msgstr "उभारें" + +#~ msgid "okular" +#~ msgstr "ऑकुलर" + +#~ msgid "&Properties..." +#~ msgstr "गुण...(&P)" + +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "प्रलेख देखने के लिए आवश्यक प्लगइन को लोड नहीं कर सकता." + +#~ msgid "Fit &Text" +#~ msgstr "पाठ के अनुसार फिट करें (&T)" + +#~ msgid "Copy Link Location" +#~ msgstr "लिंक स्थान नक़ल करें" + +#~ msgid "*|All the Files" +#~ msgstr "*|सभी फ़ाइलें" + +#~ msgctxt "Annotation tool" +#~ msgid "Pink Ink" +#~ msgstr "गुलाबी स्याही" diff --git a/po/hi/okular_chm.po b/po/hi/okular_chm.po new file mode 100644 index 0000000..1239541 --- /dev/null +++ b/po/hi/okular_chm.po @@ -0,0 +1,57 @@ +# translation of okular_chm.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2007-12-27 17:15+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "रविशंकर श्रीवास्तव, जी. करूणाकर" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "raviratlami@aol.in," + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "सीएचएम बैकएण्ड" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "माइक्रोसॉफ़्ट विंडोज मदद फ़ाइल रेंडरर" + +#, fuzzy +#~| msgid "© 2005-2007 Piotr Szymański" +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "(C) 2005-2007 पियोत्र स्जाइमंस्की" + +#~ msgid "Piotr Szymański" +#~ msgstr "पियोत्र स्जाइमंस्की" diff --git a/po/hi/okular_djvu.po b/po/hi/okular_djvu.po new file mode 100644 index 0000000..ea0ae51 --- /dev/null +++ b/po/hi/okular_djvu.po @@ -0,0 +1,153 @@ +# translation of okular_djvu.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-12-27 17:16+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "रविशंकर श्रीवास्तव, जी. करूणाकर" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "raviratlami@aol.in," + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "संपादक" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "प्रकाशक" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "आवाज़ निर्धारक" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "दस्तावेज़ का प्रकार" + +#: generator_djvu.cpp:138 +#, fuzzy, kde-format +#| msgid "Unknown" +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "अज्ञात" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "अवयव फ़ाइलें" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "अज्ञात" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "एकल पृष्ठ" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "बंडल्ड" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "अप्रत्यक्ष" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "बंडल्ड (पुराना)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "इंडेक्स्ड (पुराना)" + +#~ msgid "DjVu Backend" +#~ msgstr "डीजेवीयू बैकएण्ड" + +#, fuzzy +#~| msgid "© 2006-2007 Pino Toscano" +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "(C) 2006-2007 पिनो टोस्कानो" + +#~ msgid "Pino Toscano" +#~ msgstr "पिनो टोसकानो" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#, fuzzy +#~| msgid "Unknown" +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#~ msgid "A DjVu backend" +#~ msgstr "एक डीजेवीयू बैकएण्ड" diff --git a/po/hi/okular_dvi.po b/po/hi/okular_dvi.po new file mode 100644 index 0000000..f989217 --- /dev/null +++ b/po/hi/okular_dvi.po @@ -0,0 +1,664 @@ +# translation of okular_dvi.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-12-27 17:17+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "डीवीआई फ़ाइल प्रीएम्बल के साथ प्रारंभ नहीं होती." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" + +#: dviFile.cpp:151 +#, fuzzy, kde-format +#| msgid "" +#| "The DVI file is badly corrupted. KDVI was not able to find the postamble." +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "डीवीआई फ़ाइल बहुत ज्यादा खराब है. केडीवीआई को पोस्टेम्बल नहीं मिला." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "पोस्टेम्बल - पोस्ट कमांड के साथ प्रारंभ नहीं होता." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "पोस्टएम्बल में कमांड FNTDEF के बजाए अन्य कमांड है." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "पृष्ठ %1 बीओपी कमांड के साथ प्रारंभ नहीं होता है." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, fuzzy, kde-format +#| msgid "" +#| "File not found: \n" +#| " %1" +msgid "File corruption. %1" +msgstr "" +"फ़ाइल नहीं मिलाः\n" +"%1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, fuzzy, kde-format +#| msgid "The special command '%1' is not implemented." +msgid "The specified file '%1' does not exist." +msgstr "विशेष कमांड '%1' कार्यान्वित नहीं है." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "अज्ञात फ़ॉन्ट का डीवीआई कोड सेट अक्षर." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "जब ईओपी कमांड से सामना हुआ, स्टैक खाली नहीं था." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "जब पीओपी कमांड से सामना हुआ, स्टैक खाली था." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "डीवीआई कोड में फ़ॉन्ट संदर्भ है जो कि पहले से पारिभाषित नहीं है." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "एक अवैध कमांड से सामना हुआ." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "अज्ञात ऑप-कोड %1 से सामना हुआ." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "सन्निहित किया जा रहा है %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"पृष्ठ %1: पीडीएफ फ़ाइल %2 को पोस्टस्क्रिप्ट में परिवर्ति नहीं किया जा " +"सकता.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "पृष्ठ %1: पोस्टस्क्रिप्ट फ़ाइल %2 नहीं मिला.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "पेपरसाइज डाटा '%1' पार्स नहीं की जा सकी." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" + +#: fontpool.cpp:462 +#, fuzzy, kde-format +#| msgid "Currently generating %1 at %2 dpi" +msgid "Currently generating %1 at %2 dpi..." +msgstr "वर्तमान में बनाया जा रहा है %1 को %2 डीपीआई पर" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "जेनरेटर/तारीख़" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "फ़ॉन्ट फ़ाइल नहीं मिला" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "खड़ा" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "आड़ा" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "इसे मिलाकर 25 त्रुटियाँ हो गईं. अब आगे के त्रुटि संदेशों को छापा नहीं जाएगा." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"फ़ाइल नहीं मिलाः\n" +"%1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "विशेष कमांड '%1' कार्यान्वित नहीं है." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "फ़ॉन्ट फ़ाइल %1 टूटा है, या इसे खोला या पढ़ा नहीं जा सकता." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"फ़ॉन्ट फ़ाइल %1 के लिए अक्षर आकार सेट करने के दौरा फ्रीटाइप ने एक त्रुटि की रपट दी." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "फ्रीटाइप ग्लिफ #%1 को फ़ॉन्ट फ़ाइल %2 से लोड करने में अक्षम है." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "फ्रीटाइप ग्लिफ #%1 को फ़ॉन्ट फ़ाइल %2 से रेंडर करने में अक्षम है." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glyph #%1 खाली है" + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "ग्लिफ़ #%1 फ़ॉन्ट फ़ाइल %2 में खाली है." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "फ़ॉन्ट फ़ाइल %2 से ग्लिफ #%1 को लोड करने में फ्रीटाइप असफल रहा." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "फ़ॉन्ट फ़ाइल %1 खोल नहीं सका." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: अक्षर %1 फ़ॉन्ट %2 में पारिभाषित नहीं है" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "अप्रत्याशित %1 पीके फ़ाइल %2 में" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "अक्षर %1 फ़ाइल %2 में बहुत बड़ा है" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "भंडारित किए बिट्स की गलत संख्या: अक्षर. %1, फ़ॉन्ट %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "खराब पीके फ़ाइल (%1), बहुत सारे बिट्स" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "फ़ॉन्ट में नॉन-स्कवेयर आस्पेक्ट रेशो है" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "फ़ॉन्ट फ़ाइल %1 ढूंढ नहीं सका %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "फ़ॉन्ट फ़ाइल %1 के लिए चेकसम मिसमैच" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "फ़ाइल %1 के लिए फ़ॉन्ट फ़ाइल प्रारूप पहचाना नहीं जा सकता" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"गंभीर त्रुटि.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "वीएफ मेक्रो सूची : %1 में गलत कमांड बाइट मिला" + +#, fuzzy +#~| msgid "DVI File Error" +#~ msgid "A DVI file renderer" +#~ msgstr "डीवीआई फ़ाइल त्रुटि" + +#, fuzzy +#~| msgid "KDVI is currently generating bitmap fonts..." +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "केडीवीआई वर्तमान में बिटमैप फ़ॉन्ट तैयार कर रहा है..." + +#, fuzzy +#~| msgid "Aborts the font generation. Don't do this." +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "फ़ॉन्ट तैयार करना छोड़ें. इसे नहीं बनाएँ." + +#, fuzzy +#~| msgid "KDVI is generating fonts. Please wait." +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "कृपया रूकें... केडीवीआई फ़ॉन्ट तैयार कर रहा है." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "फ़ॉन्ट जनरेशन प्रगति संवाद" + +#~ msgid "Abort" +#~ msgstr "छोड़ें" + +#, fuzzy +#~| msgid "What's going on here?" +#~ msgid "What is happening here?" +#~ msgstr "यहाँ क्या चल रहा है?" + +#~ msgid "%v of %m" +#~ msgstr "%m का %v " + +#~ msgid "Please be patient" +#~ msgstr "कृपया धैर्य रखें" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|पोर्टेबल दस्तावेज़ फॉर्मेट (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "फ़ाइल ऐसे निर्यात करें" + +#, fuzzy +#~| msgid "" +#~| "The file %1\n" +#~| "exists. Do you want to overwrite that file?" +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "फ़ाइल %1 \n" +#~ "पहले से ही मौजूद है. क्या आप इसके ऊपर लिखना चाहते हैं?" + +#~ msgid "Overwrite File" +#~ msgstr "फ़ाइल के ऊपर लिखें" + +#~ msgid "Overwrite" +#~ msgstr "मिटाकर लिखें" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "" +#~ "फ़ाइल को पीडीएफ़ में निर्यात करने के लिए डीवीआईपीडीएफएम इस्तेमाल किया जा रहा है" + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "डीवीआईपीडीएफएम पूरा होने के इंतजार में..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|पोस्टस्क्रिप्ट (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "" +#~ "फ़ाइल को पोस्टस्र्किप्ट में निर्यात करने के लिए डीवीआईपीएस इस्तेमाल किया जा रहा है" + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "डीवीआईपीएस पूरा होने के इंतजार में..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "फंक्शनलिटी अनुपलब्ध" + +#~ msgid "DVI File Error" +#~ msgstr "डीवीआई फ़ाइल त्रुटि" + +#~ msgid "Not All Font Files Found" +#~ msgstr "सभी फ़ॉन्ट फ़ाइलें नहीं मिलीं" + +#~ msgid "Locating fonts..." +#~ msgstr "फ़ॉन्ट्स लोकेट किया जा रहा है..." + +#, fuzzy +#~| msgid "Problem locating fonts - KDVI" +#~ msgid "Problem locating fonts" +#~ msgstr "फ़ॉन्ट ढूंढने में समस्या - केडीवीआई" + +#, fuzzy +#~| msgid "Font generation aborted - KDVI" +#~ msgid "Font generation aborted" +#~ msgstr "फ़ॉन्ट बनाना छोड़ा - केडीवीआई" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "%1 को पीडीएफ में निर्यात करें" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "%1 को पोस्टस्क्रिप्ट में निर्यात करें" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "फ़ॉन्टलिस्ट वर्तमान में खाली है." + +#~ msgid "TeX Name" +#~ msgstr "टीईएक्स नाम" + +#~ msgid "Family" +#~ msgstr "परिवार" + +#~ msgid "Zoom" +#~ msgstr "ज़ूम" + +#~ msgid "Type" +#~ msgstr "क़िस्म" + +#~ msgid "Encoding" +#~ msgstr "एनकोडिंग" + +#~ msgid "Comment" +#~ msgstr "टिप्पणी" + +#~ msgid "TeX virtual" +#~ msgstr "TeX काल्पनिक" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX फ़ॉन्ट मीट्रिक" + +#~ msgid "FreeType" +#~ msgstr "फ्री-टाइप" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "फ़ॉन्ट ढांचा के लिए मेमोरी आबंटित नहीं की जा सकती" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "DVI फ़ाइल को लोड करने के लिए पर्याप्त मेमोरी नहीं है" + +#~ msgid "Could not load the DVI-file." +#~ msgstr "DVI फ़ाइल लोड नहीं कर सका." + +#~ msgid "Checksum mismatch" +#~ msgstr "चेकसम मिसमैच" + +#~ msgid " in font file " +#~ msgstr "फ़ॉन्ट फ़ाइल में" + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "मेक्रो टेबल के लिए मेमोरी आवंटित नहीं की जा सकती." + +#~ msgid "Virtual character " +#~ msgstr "आभासी कैरेक्टर" + +#~ msgid " in font " +#~ msgstr "फ़ॉन्ट में" + +#~ msgid " ignored." +#~ msgstr "उपेक्षित." + +#~ msgid "Fatal Error" +#~ msgstr "गंभीर त्रुटि" + +#~ msgid "KDVI: Information" +#~ msgstr "केडीवीआईः जानकारी" + +#~ msgid "Do not show this message again" +#~ msgstr "यह संदेश फिर से न दिखाएँ" + +#~ msgid "Explain in more detail..." +#~ msgstr "अधिक विवरण के साथ स्पस्ट करें... " + +#~ msgid "File Error" +#~ msgstr "फ़ाइल त्रुटि" + +#~ msgid "Could Not Find Reference" +#~ msgstr "सन्दर्भ नहीं मिला" diff --git a/po/hi/okular_fictionbook.po b/po/hi/okular_fictionbook.po new file mode 100644 index 0000000..1b04b2e --- /dev/null +++ b/po/hi/okular_fictionbook.po @@ -0,0 +1,84 @@ +# translation of okular_fictionbook.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-12-27 17:17+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "दस्तावेज़ एक वैध फिक्शनबुक नहीं है" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "दस्तावेज़ खोलने में असफल: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "दस्तावेज़ वैध जिप आर्काइव नहीं है" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "अवैध दस्तावेज़ स्ट्रक्चर (मुख्य डिरेक्ट्री गुम है)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "दस्तावेज़ में कोई सामग्री नहीं मिली" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "अवैध एक्सएमएल दस्तावेज़: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "" + +#~ msgid "Creator" +#~ msgstr "निर्माता" + +#~ msgid "Title" +#~ msgstr "शीर्षक" + +#~ msgid "Author" +#~ msgstr "लेखक" + +#~ msgid "Producer" +#~ msgstr "निर्माता" + +#~ msgid "Created" +#~ msgstr "निर्मित" diff --git a/po/hi/okular_ghostview.po b/po/hi/okular_ghostview.po new file mode 100644 index 0000000..7629a22 --- /dev/null +++ b/po/hi/okular_ghostview.po @@ -0,0 +1,103 @@ +# translation of okular_ghostview.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-12-27 17:18+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, fuzzy, kde-format +#| msgid "&Use platform fonts" +msgid "Use Platform Fonts" +msgstr "प्लेटफ़ॉर्म फ़ॉन्ट्स उपयोग में लें (&U)" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "सामान्य विन्यास" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "प्लेटफ़ॉर्म फ़ॉन्ट्स उपयोग में लें (&U)" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "घोस्ट-स्क्रिप्ट" + +#: generator_ghostview.cpp:84 +#, fuzzy, kde-format +#| msgid "Ghostscript backend configuration" +msgid "Ghostscript Backend Configuration" +msgstr "घोस्टस्क्रिप्ट बैकएण्ड कॉन्फिगरेशन" + +#: generator_ghostview.cpp:248 +#, fuzzy, kde-format +#| msgid "DSC version" +msgid "Document version" +msgstr "डीएससी संस्करण" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "भाषा स्तर" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "एंटीएलियासिंग से परिणाम बेहतर दिखता है, परंतु इससे डिस्प्ले दिखाने में लंबा समय लेता है." + +#, fuzzy +#~| msgid "&Enable anti-aliasing of fonts and images" +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "फ़ॉन्ट्स तथा छवियों के एन्टीअलाएसिंग सक्षम करें (&E)" + +#, fuzzy +#~| msgid "&Enable anti-aliasing of fonts and images" +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "फ़ॉन्ट्स तथा छवियों के एन्टीअलाएसिंग सक्षम करें (&E)" + +#~ msgid "&Show Ghostscript messages in a separate box" +#~ msgstr "अलग बक्से में घोस्टस्क्रिप्ट संदेश दिखाएँ (&S)" + +#~ msgid "Ghostscript Configuration" +#~ msgstr "घोस्टस्क्रिप्ट कॉन्फ़िगरेशन" + +#~ msgid "Additional parameters to Ghostscript" +#~ msgstr "घोस्टस्क्रिप्ट के लिए अतिरिक्त पैरामीटर" diff --git a/po/hi/okular_kimgio.po b/po/hi/okular_kimgio.po new file mode 100644 index 0000000..3c992d6 --- /dev/null +++ b/po/hi/okular_kimgio.po @@ -0,0 +1,73 @@ +# translation of okular_kimgio.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2007-12-27 17:18+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "रविशंकर श्रीवास्तव, जी. करूणाकर" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "raviratlami@aol.in," + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "दस्तावेज लोड करने में अक्षम:%1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "इमेज बैकएण्ड" + +#~ msgid "A simple image backend" +#~ msgstr "एक सरल चित्र बैकएण्ड" + +#, fuzzy +#~| msgid "" +#~| "© 2005 Albert Astals Cid\n" +#~| "© 2006-2007 Pino Toscano\n" +#~| "© 2006-2007 Tobias Koenig" +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005 अलबर्ट एस्टल्स सिड\n" +#~ "© 2006-2007 पिनो टोस्कानो\n" +#~ "© 2006-2007 टॉबियस कोएनिग" + +#~ msgid "Albert Astals Cid" +#~ msgstr "अलबर्ट एस्टल्स सिड" + +#~ msgid "Pino Toscano" +#~ msgstr "पिनो टोसकानो" + +#~ msgid "Tobias Koenig" +#~ msgstr "टॉबियस कोएनिग" + +#~ msgid "Main Toolbar" +#~ msgstr "मुख्य औज़ार पट्टी" diff --git a/po/hi/okular_plucker.po b/po/hi/okular_plucker.po new file mode 100644 index 0000000..8cdaf99 --- /dev/null +++ b/po/hi/okular_plucker.po @@ -0,0 +1,34 @@ +# translation of okular_plucker.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-12-27 17:20+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "नाम" diff --git a/po/hi/okular_poppler.po b/po/hi/okular_poppler.po new file mode 100644 index 0000000..47ba7c3 --- /dev/null +++ b/po/hi/okular_poppler.po @@ -0,0 +1,216 @@ +# translation of okular_poppler.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2007-12-27 17:20+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "नहीं" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "पीडीएफ़ विकल्प" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "रास्टराइजेशन बाध्य करें" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "छपाई से पहले छवि में रास्टराइज करें" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, fuzzy, kde-format +#| msgctxt "PDF v. " +#| msgid "PDF v. %1" +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "पीडीएफ सं. %1" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "फॉर्मेट" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "एनक्रिप्टेड" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "अनएनक्रिप्टेड" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "सुरक्षा" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "हाँ" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "ऑप्टीमाइज़्ड" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "Unknown" +#~ msgstr "अज्ञात" + +#~ msgid "Unknown Date" +#~ msgstr "अज्ञात तारीख़" + +#~ msgid "Unknown Encryption" +#~ msgstr "अज्ञात एनक्रिप्शन" + +#~ msgid "Unknown Optimization" +#~ msgstr "अज्ञात ऑप्टीमाइज़ेशन" + +#, fuzzy +#~| msgid "Please insert the password to read the document:" +#~ msgid "Please enter the password to read the document:" +#~ msgstr "दस्तावेज़ को पढ़ने के लिए कृपया पासवर्ड प्रविष्ट करें:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "गलत पासवर्ड. कृपया पुनः कोशिश करें:" + +#~ msgid "Document Password" +#~ msgstr "दस्तावेज़ पासवर्ड" + +#~ msgid "Aspect ratio change" +#~ msgstr "आस्पेक्ट रेशो परिवर्तन" + +#~ msgid "Print with specified margins" +#~ msgstr "निर्दिष्ट हाशिया के साथ छापें" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "ऑस्पेक्ट रेशो को बनाए रखते हुए हाशिया के साथ छापें" diff --git a/po/hi/okular_xps.po b/po/hi/okular_xps.po new file mode 100644 index 0000000..b18590d --- /dev/null +++ b/po/hi/okular_xps.po @@ -0,0 +1,58 @@ +# translation of okular_xps.po to Hindi +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Ravishankar Shrivastava , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2007-12-27 17:22+0530\n" +"Last-Translator: Ravishankar Shrivastava \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "रविशंकर श्रीवास्तव, जी. करूणाकर" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "raviratlami@aol.in," + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "" + +#~ msgid "XPS Backend" +#~ msgstr "एक्सपीएस बैकएण्ड" + +#~ msgid "An XPS backend" +#~ msgstr "एक एक्सपीएस बैकएण्ड" + +#, fuzzy +#~| msgid "" +#~| "© 2006-2007 Brad Hards\n" +#~| "© 2007 Jiri Klement" +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 ब्रैड हैर्ड्स\n" +#~ "© 2007 जिरि क्लीमेंट" + +#~ msgid "Brad Hards" +#~ msgstr "ब्रेड हार्ड्स" + +#~ msgid "Jiri Klement" +#~ msgstr "जिरि क्लीमेंट" diff --git a/po/hr/okular.po b/po/hr/okular.po new file mode 100644 index 0000000..c7ac1ac --- /dev/null +++ b/po/hr/okular.po @@ -0,0 +1,5743 @@ +# Translation of okular to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010, 2011. +# Andrej Dundovic , 2010. +# Marko Dimjašević , 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2011-08-25 19:25+0200\n" +"Last-Translator: Marko Dimjašević \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 1.2\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +# pmap: =/nom=Okular/gen=Okulara/dat=Okularu/aku=Okular/lok=Okularu/ins=Okularom/_r=m/_b=j/ +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, univerzalni preglednik dokumenata" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2009 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Bivši održavatelj" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Puno rada u \"frameworku\", pozadinski servisi za ODT i FictionBook" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "Razvijatelj KPDF-a" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Izradio Okular iz kôda KPDF-a" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Razvijatelj KPDF-a" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Ilustracije napomena" + +#: aboutdata.h:40 +#, fuzzy, kde-format +#| msgid "&Text Selection Tool" +msgid "Table selection tool" +msgstr "Alat za označavanje &teksta" + +#: aboutdata.h:41 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation improvements" +msgstr "Svojstva opaske" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Idi na stranicu %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Otvori vanjsku datoteku" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Izvrši '%1'…" + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Prva stranica" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Prethodna stranica" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Sljedeća stranica" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Zadnja stranica" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Nazad" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Naprijed" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Izlaz" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Pokreni prezentaciju" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Završi prezentaciju" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Traži…" + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Idi na stranicu…" + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reproduciraj zvuk…" + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Skripta u JavaScriptu" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reproduciraj film…" + +#: core/action.cpp:547 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Play movie" +msgstr "Reproduciraj film…" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "" + +#: core/action.cpp:551 +#, fuzzy, kde-format +#| msgid "Play movie..." +msgid "Pause movie" +msgstr "Reproduciraj film…" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Odabir pozadinskog servisa" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Pronađen je više od jednog pozadinskog servisa za MIME-vrstu:
" +"%1 (%2).

Molim odaberite koji želite koristiti:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Idi na stranicu %1" + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "" + +#: core/document.cpp:249 +#, fuzzy, kde-format +#| msgid "%1 x %2 in" +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in" + +#: core/document.cpp:251 +#, fuzzy, kde-format +#| msgid "%1 x %2 mm" +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Ne mogu pronaći priključak koji može obraditi proslijeđen dokument." + +#: core/document.cpp:3368 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "Prezentacija" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokument pokušava izvršiti vanjsku aplikaciju pa to Okular, radi vaše " +"sigurnosti, ne dozvoljava." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Nije pronađena aplikacija za otvaranje datoteke mime-vrste %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Nije moguće otvoriti privremenu datoteku" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Konverzija ispisa nije uspjela" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Proces ispisa se srušio" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Proces ispisivanja nije moguće pokrenuti" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Ispis u datoteku nije uspio" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Pisač je bio u neispravnom stanju" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Nije moguće pronaći datoteku za ispis." + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Nema datoteke za ispis" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Ne mogu pronaći prikladan program za ispis. Pobrinite se da je CUPS-ov " +"program lpr dostupan" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Nije moguće otvoriti '%1'. Datoteka ne postoji" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Naslov" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Predmet" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Opis" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Stvaralac" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Producent" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Autorska prava" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Stranice" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Izrađeno" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Mijenjano" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Mime-vrsta" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategorija" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Ključne riječi" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Putanja datoteke" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Veličina datoteke" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Veličina stranice" + +#: core/documentcommands.cpp:65 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "%1 opaska" + +#: core/documentcommands.cpp:110 +#, fuzzy, kde-format +#| msgid "Presentation" +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "Prezentacija" + +#: core/documentcommands.cpp:156 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "Svojstva opaske" + +#: core/documentcommands.cpp:190 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "Tekstualna opaska" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "%1 opaska" + +#: core/documentcommands.cpp:328 +#, fuzzy, kde-format +#| msgid "Select text" +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "Označi tekst" + +#: core/documentcommands.cpp:390 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "Svojstva opaske" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Čisti &tekst…" + +# pmap: =/nom=PDF/gen=PDF-a/dat=PDF-u/aku=PDF/lok=PDF-u/ins=PDF-om/_r=m/_b=j/ +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument Text" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Opcije uređivača" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Način boja:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Zatvori ovu poruku" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Izvor: %1" + +#: core/textdocumentsettings.cpp:37 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Font:" +msgstr "Zadan prijelaz:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Ponovno &učitaj" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Dopusti" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Green Ink" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Zelena tinta" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Prilagodi širini" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Svojstva opaske" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Svojstva opaske" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "&Boja:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "&Boja:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Eksperimentalno" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "Alat za označa&vanje" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "&Annotations" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Označeno" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Podvuci" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Črčkarija" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Prekriži" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Svojstva uspravne strelice" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Unutarlinijske bilješke" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "&Otvori skočnu bilješku" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Green Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Zelena linija prostom rukom" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Ravna žuta linija" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Pravokutnik" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Plavi poligon" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Pečat" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "%1 opaska" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Tekstualna opaska" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Pismo:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Svojstva opaske" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Linija" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Nepr&ozirnost:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Stranica %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "%1 opaska" +msgstr[1] "%1 opaske" +msgstr[2] "%1 opaski" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Otvori skočnu bilješku" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Izbriši" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Svojstva" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Spremi '%1'…" + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Izgled" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Općenito" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Izrađeno" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Mijenjano" + +#: part/annotationpropertiesdialog.cpp:111 +#, fuzzy, kde-format +#| msgid "Note Properties" +msgid "Pop-up Note Properties" +msgstr "Svojstva bilješke" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "Svojstva uspravne strelice" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Svojstva unutarlinijskih bilješki" + +#: part/annotationpropertiesdialog.cpp:121 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line Properties" +msgstr "Svojstva linije" + +#: part/annotationpropertiesdialog.cpp:123 +#, fuzzy, kde-format +#| msgid "Sound Properties" +msgid "Polygon Properties" +msgstr "Svojstva zvuka" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Geometrijska svojstva" + +#: part/annotationpropertiesdialog.cpp:129 +#, fuzzy, kde-format +#| msgid "Stamp Properties" +msgid "Text Markup Properties" +msgstr "Svojstva pečata" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Svojstva pečata" + +#: part/annotationpropertiesdialog.cpp:135 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line Properties" +msgstr "Svojstva linije" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Svojstva uspravne strelice" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Svojstva datotečnog privitka" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Svojstva zvuka" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Svojstva filma" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Svojstva opaske" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Izmijenjeno: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Stavi pečatni simbol" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Boja:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgctxt "Suffix for the opacity level, eg '80 %'" +#| msgid " %" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr " %" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Nepr&ozirnost:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Ikona" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Komentar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Pomoć" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Umetni" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Ključ" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Novi odlomak" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Bilješka" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Odlomak" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Pismo:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Boja:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "" + +#: part/annotationwidgets.cpp:390 +#, fuzzy, kde-format +#| msgctxt "Rotate left" +#| msgid "Left" +msgid "Left" +msgstr "Ulijevo" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "" + +#: part/annotationwidgets.cpp:392 +#, fuzzy, kde-format +#| msgctxt "Rotate right" +#| msgid "Right" +msgid "Right" +msgstr "Udesno" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Odobren" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Kakav je" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Povjerljivo" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Resorno" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Nacrt" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Eksperimentalno" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Završno" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Za komentiranje" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Za javno izdavanje" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Nije odobreno" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Nije za javno izdavanje" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Prodano" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Stroga tajna" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Oznaka" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informacije" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Pečatni simbol" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "Prilagodi širini" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Linija" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Linija" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Ništa" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Duljina uvodne linije:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Duljina nastavaka uvodne linije:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Spremi u datoteku…" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Vrsta:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Označeno" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle" +msgstr "Črčkarija" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Podvuci" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Prekriži" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Pravokutnik" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Elipsa" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "Simbol datotečnog privitka" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graf" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Pribadača" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Spajalica" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Oznaka" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Datoteka" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Nedostupan opis." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "Name" +msgid "Name:" +msgstr "Ime" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Opis:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "Simbol uspravne strelice" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Ništa" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Zatvori ovu bilješku" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opcije" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "" + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "" + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "" + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "" + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"%2 oznaka" +msgstr[1] "" +"%1\n" +"\n" +"%2 oznake" +msgstr[2] "" +"%1\n" +"\n" +"%2 oznaka" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Oznake" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "&Traži:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Samo trenutni dokument" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Idi na ovu oznaku" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Preimenuj oznaku" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Ukloni oznaku" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Otvori dokument" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Ukloni oznake" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Size" +msgid "Serial Number" +msgstr "Veličina stranice" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Isteklo" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Predmet" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Iskorištenost memorije" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Svojstva" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Certificate Viewer" +msgstr "Konfiguriraj preglednik…" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "I&zvezi kao" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Opće" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Gdje želite spremiti %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Ponovno &učitaj" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Green Ink" +msgid "Green" +msgstr "Zelena tinta" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Dopusti" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Iscrtaj rub oko sl&ika" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Iscrtaj rub oko &linkova" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Promijeni &boje" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Upozorenje: ove opcije mogu poprilično negativno utjecati na brzinu " +"iscrtavanja." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Način boja:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Obrni boje" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Promijeni boju papira" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Promijeni tamne i svijetle boje" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Pretvori u crno – bijelo" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Boja papira:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Tamna boja:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Svijetla boja:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Prag:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontrast:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitet" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&Autor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Napomena: informacije se ovdje koriste samo za komentare i osvrte. " +"Ovdje umetnute informacije neće se slati bez vašeg znanja." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Annotations author" +msgid "Quick annotation tools" +msgstr "Autor opaski" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Posebni uređivač teksta" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs-klijent" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx-klijent" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Postavlja naredbu prilagođenog uređivača teksta koju treba izvršiti.
\n" +"Ovdje također možete staviti nekoliko mjesnih simbola:\n" +"
    \n" +"
  • %f – ime datoteke
  • \n" +"
  • %l – linija datoteke koju treba doseći
  • \n" +"
  • %c – stupac datoteke kojeg treba doseći
  • \n" +"
\n" +"Ako %f nije naveden, ime datoteke bit će nadodano navedenoj naredbi." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Uređivač" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Uređivač:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Izaberite uređivač koji želite da se pokrene kad Okular želi otvoriti " +"izvornu datoteku." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Naredba:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Izgled" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Prikaži &klizač" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Poveži &sličice sa stranicom" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Prikaži sa&vjete i informacijske poruke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, fuzzy, kde-format +#| msgid "Display document title in title bar" +msgid "Display document title in titlebar if available" +msgstr "Prikaži naslov dokumenta u naslovnoj traci" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, fuzzy, kde-format +#| msgid "Display document title in title bar" +msgid "When not displaying document title:" +msgstr "Prikaži naslov dokumenta u naslovnoj traci" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Boja pozadine:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Mogućnosti programa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "P&okori se ograničenjima DRM-a" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "Ponovno učitaj dokument kad se p&romijeni datoteka" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Prikaži dijalog pozadinskog servisa za odabir" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Prikaži opcije" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, fuzzy, kde-format +#| msgid "Overview columns:" +msgid "Overview &columns:" +msgstr "Prikaz stupaca:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, fuzzy, no-c-format, kde-format +#| msgctxt "Suffix for the opacity level, eg '80 %'" +#| msgid " %" +msgid "%" +msgstr " %" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, fuzzy, kde-format +#| msgid "Default transition:" +msgid "&Default Zoom:" +msgstr "Zadan prijelaz:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Prilagodi širini" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Prilagodi stranici" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Drži korištenu memoriju na najnižoj mogućoj razini. Nemoj išta ponovno " +"koristiti (za sustave s malo memorije)." + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Dobar kompromis između korištene memorije i brzine izvođenja. Unaprijed " +"učitaj sljedeću stranicu i ubrzaj pretraživanje (tipično za sustave s 256MB " +"memorije)." + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Sve čuva u memoriji. Unaprijed učitava stranice. Ubrzava pretraživanje (za " +"sustave s više od 512MB memorije)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Iskorištenost CPU-a" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Omogući efekte &transparentnosti" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Iskorištenost memorije" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Nis&ko" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "&Normalno (zadano)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "&Agresivno" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Rendering" +msgstr "Podvuci" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Text Antialias" +msgstr "Omogući prijelaze" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Graphics Antialias" +msgstr "Omogući prijelaze" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, fuzzy, kde-format +#| msgid "Enable transitions" +msgid "Enable Text Hinting" +msgstr "Omogući prijelaze" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Trenutni zaslon" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Zadani zaslon" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Zaslon %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekunda" +msgstr[1] " sekunde" +msgstr[2] " sekundi" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigacija" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Pomakni naprijed svakih:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Ponavljaj nakon zadnje stranice" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Navigacija" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Boja pozadine:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Pokazivač miša:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Sakriven nakon odgode" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Uvijek vidljiv" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Uvijek sakriven" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Prikaži indikator na&pretka" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Prikaži stranic&u sa sažetkom" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Omogući prijelaze" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Zadan prijelaz:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Uspravne rolete" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Vodoravne rolete" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Dolazeći okvir" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Odlazeći okvir" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Rastopi" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Blijesak prema dolje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Blijesak prema desno" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Blijesak prema dolje-desno" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Nasumičan prijelaz" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Zamijeni" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Razdvoji vodoravno prema unutra " + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Razdvoji vodoravno prema van" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Razdvoji uspravno prema unutra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Razdvoji uspravno prema van" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Briši prema dolje" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Briši prema desno" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Briši prema lijevo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Briši prema gore" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Položaj" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Zaslon:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "Izbriši crteže" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, fuzzy, kde-format +#| msgid "Name" +msgid "&Name:" +msgstr "Ime" + +#: part/editannottooldialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Type:" +msgid "&Type:" +msgstr "Vrsta:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, fuzzy, kde-format +#| msgid "&Open Pop-up Note" +msgid "Pop-up Note" +msgstr "&Otvori skočnu bilješku" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Unutarlinijske bilješke" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, fuzzy, kde-format +#| msgid "Green Freehand Line" +msgid "Freehand Line" +msgstr "Zelena linija prostom rukom" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, fuzzy, kde-format +#| msgid "Straight Yellow Line" +msgid "Straight Line" +msgstr "Ravna žuta linija" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, fuzzy, kde-format +#| msgid "Blue Polygon" +msgid "Polygon" +msgstr "Plavi poligon" + +#: part/editannottooldialog.cpp:96 +#, fuzzy, kde-format +#| msgid "Next Bookmark" +msgid "Text markup" +msgstr "Sljedeća oznaka" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Pečat" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "" + +#: part/editannottooldialog.cpp:104 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Text Annotation" +msgid "Create annotation tool" +msgstr "Tekstualna opaska" + +#: part/editannottooldialog.cpp:106 +#, fuzzy, kde-format +#| msgid "Annotations author" +msgid "Edit annotation tool" +msgstr "Autor opaski" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "&Boja:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "Prilagodi širini" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Create drawing tool" +msgstr "Izbriši crteže" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Nepoznat" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Ugrađene datoteke" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "&Prikaz" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Ime" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Opis" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Veličina" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Izrađeno" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Izmijenjeno" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Spremi kao…" + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Prikaz" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Ne mogu učitati dio za izgled ispisa" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Pogled prije ispisa" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Zatvori" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "Traž&i:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Tekst koji treba tražiti" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Sljedeće" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Skoči na sljedeće podudaranje" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Prethodno" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Skoči na prijašnje podudaranje" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Izmijeni ponašanje pretrage" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Osjetljivost na veličinu slova" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Od trenutne stranice" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Sve datoteke" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "Svojstva uspravne strelice" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Straight Line with Comment" +msgstr "Svojstva linije" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "Za komentiranje" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometrija" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlight with Comment" +msgstr "Označeno" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgid "Squiggle with Comment" +msgstr "Črčkarija" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgid "Underline" +msgid "Underline with Comment" +msgstr "Podvuci" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Strike out" +msgid "Strike Out with Comment" +msgstr "Prekriži" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgid "Strike out" +msgid "Strike Out" +msgstr "Prekriži" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Line Properties" +msgid "Freehand Line with Comment" +msgstr "Svojstva linije" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Uspravna strelica" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Datotečni privitak" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Zvuk" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, fuzzy, kde-format +#| msgid "Screen:" +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Zaslon:" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Nepoznat" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Gdje želite spremiti %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Ne mogu otvoriti \"%1\" za pisanje. Datoteka nije spremljena." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opcije pretraživanja" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Osjetljivost na veličinu slova" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regularni izraz" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Traži:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "od" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Ok&reni udesno" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Udesno" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Okreni u&lijevo" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Ulijevo" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Prvobitna orijentacija" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "&Prikaz" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "O&dreži margine" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Označavanje teksta" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Prilagodi širi&ni" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "&Prilagodi stranici" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "&Prilagodi stranici" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Način pri&kaza" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Jedna stranica" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Nasuprotne stranice" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Nasuprotne stranice (centriraj prvu stranicu)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Pregled" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Neprekidno" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Listanje" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:662 +#, fuzzy, kde-format +#| msgid "Change &colors" +msgid "&Toggle Change Colors" +msgstr "Promijeni &boje" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Označavanje teksta" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Označavanje teksta" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "T&able Selection" +msgstr "Označavanje teksta" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Alati za odabir" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Izgovori cijeli dokument" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Izgovori trenutnu stranicu" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Prestani izgovarati" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Kliži prema gore" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Kliži prema dolje" + +#: part/pageview.cpp:759 +#, fuzzy, kde-format +#| msgid "Scroll Up" +msgid "Scroll Page Up" +msgstr "Kliži prema gore" + +#: part/pageview.cpp:765 +#, fuzzy, kde-format +#| msgid "Scroll Down" +msgid "Scroll Page Down" +msgstr "Kliži prema dolje" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Prikaži obrasce" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Učitan je dokument od %1 stranice." +msgstr[1] " Učitan je dokument od %1 stranice." +msgstr[2] " Učitan je dokument od %1 stranica." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Tekst (%1 znak)" +msgstr[1] "Tekst (%1 znaka)" +msgstr[2] "Tekst (%1 znakova)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Kopiraj u odlagalište." + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Kopiranje je zabranio DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Izgovori tekst" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Slika (%1 sa %2 piksela)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Spremi u datoteku…" + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Slika [%1x%2] je kopirana u odlagalište." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Spremi u datoteku…" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Datoteka nije spremljena." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Slika [%1x%2] je spremljena u datoteku %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Kopiraj tekst" + +#: part/pageview.cpp:2930 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgid "Go to '%1'" +msgstr "Idi na stranicu %1" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Traži '%1' pomoću" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Podesi web kratice…" + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Slijedi ovaj link" + +#: part/pageview.cpp:4177 +#, fuzzy, kde-format +#| msgid "Play sound..." +msgid "Play this Sound" +msgstr "Reproduciraj zvuk…" + +#: part/pageview.cpp:4179 +#, fuzzy, kde-format +#| msgid "Sound" +msgid "Stop Sound" +msgstr "Zvuk" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Kopiraj adresu linka" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Traži '%1' pomoću" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Dobrodošli" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Označite područje uvećanja. Desni klik za umanjenje." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "" + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Nacrtaj pravokutnik oko teksta/grafike koje treba kopirati." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Označi tekst" + +#: part/pageview.cpp:4780 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "Nacrtaj pravokutnik oko teksta/grafike koje treba kopirati." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Nacrtaj pravokutnik oko teksta/grafike koje treba kopirati." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nova tekstualna bilješka" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Tekst nove bilješke:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Bookmark annotation" +msgstr "%1 opaska" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Unutarlinijska tekstualna opaska (povuci za označavanje područja)" + +#: part/pageviewannotator.cpp:1023 +#, fuzzy, kde-format +#| msgid "Highlight" +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Označeno" + +#: part/pageviewannotator.cpp:1025 +#, fuzzy, kde-format +#| msgid "Green Freehand Line" +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Zelena linija prostom rukom" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Unutarlinijska tekstualna opaska (povuci za označavanje područja)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Nacrtaj poligon (kliknite na prvu točku da ga zatvorite)" + +#: part/pageviewannotator.cpp:1033 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Pravokutnik" + +#: part/pageviewannotator.cpp:1035 +#, fuzzy, kde-format +#| msgid "Squiggly" +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Črčkarija" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Stavi pečatni simbol" + +#: part/pageviewannotator.cpp:1039 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Straight Yellow Line" +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Ravna žuta linija" + +#: part/pageviewannotator.cpp:1041 +#, fuzzy, kde-format +#| msgid "Strike out" +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Prekriži" + +#: part/pageviewannotator.cpp:1043 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Podvuci" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Unutarlinijska tekstualna opaska (povuci za označavanje područja)" + +#: part/pageviewannotator.cpp:1089 +#, fuzzy, kde-format +#| msgid "Highlight" +msgid "Highlighter" +msgstr "Označeno" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Add favorite annotation" +msgstr "%1 opaska" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Custom annotation name:" +msgstr "%1 opaska" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Datoteka" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Po&stavke" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "Po&moć" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orijentacija" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Oznake" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, fuzzy, kde-format +#| msgid "Main Toolbar" +msgid "Viewer Toolbar" +msgstr "Glavna alatna traka" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Sličice" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotations" +msgstr "%1 opaska" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Ovaj dokument ima ugrađene datoteke. Ovdje " +"kliknite kako biste ih vidjeli ili idite na Datoteke → Ugrađene datoteke." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Prethodna" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Idi na prethodnu stranicu" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Pomiče se na prethodnu stranicu dokumenta" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Sljedeća" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Idi na sljedeću stranicu" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Pomiče se na sljedeću stranicu dokumenta" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Početak dokumenta" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Pomiče se na početak dokumenta" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Kraj dokumenta" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Pomiče se na kraj dokumenta" + +#: part/part.cpp:687 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Rename the current bookmark" +msgstr "Preimenuj oznaku" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Prethodna oznaka" + +#: part/part.cpp:693 +#, fuzzy, kde-format +#| msgid "Go to the previous bookmarked page" +msgid "Go to the previous bookmark" +msgstr "Idi na prethodnu označenu stranicu" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Sljedeća oznaka" + +#: part/part.cpp:699 +#, fuzzy, kde-format +#| msgid "Go to the next bookmarked page" +msgid "Go to the next bookmark" +msgstr "Idi na sljedeću označenu stranicu" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Konfiguriraj Okular…" + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Konfiguriraj preglednik…" + +#: part/part.cpp:735 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Viewer Backends..." +msgstr "Konfiguriraj pozadinske servise…" + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Konfiguriraj pozadinske servise…" + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "O pozadinskom servisu" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Ponovno &učitaj" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Ponovno učitavaj trenutni dokument s diska." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Zatvori &traku za pretraživanje" + +#: part/part.cpp:791 +#, fuzzy, kde-format +#| msgid "Page Size" +msgid "Page Number" +msgstr "Veličina stranice" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Izgovori trenutnu stranicu" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Prikaži traku is&pod stranice" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Prikaži traku is&pod stranice" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Prikaži &navigacijski panel" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Ugrađ&ene datoteke" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "I&zvezi kao" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&rezentacija" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "Uvez&i PostScript kao PDF…" + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Dohvati knji&ge s Interneta…" + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Zamijeni način Blackscreena" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Izbriši crteže" + +#: part/part.cpp:927 +#, fuzzy, kde-format +#| msgid "Configure Backends..." +msgid "Configure Annotations..." +msgstr "Konfiguriraj pozadinske servise…" + +#: part/part.cpp:932 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "Play/Pause Presentation" +msgstr "Prezentacija" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Ne mogu otvoriti %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Učitavanje %1 je prekinuto." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Ne mogu otvoriti %1. Razlog: %2" + +#: part/part.cpp:1186 +#, fuzzy, kde-format +#| msgid "Configure Backends" +msgid "Configure Viewer Backends" +msgstr "Konfiguriraj pozadinske servise" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Konfiguriraj pozadinske servise" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Program \"ps2pdf\" nije pronađen pa Okular pomoću njega ne može uvesti " +"datoteke vrste PS." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf nije pronađen" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Uvozim datoteke PS kao PDF (ovo može potrajati)…" + +#: part/part.cpp:1409 +#, fuzzy, kde-format +#| msgid "Moves to the last page of the document" +msgid "Please enter the password to read the document:" +msgstr "Pomiče se na zadnju stranicu dokumenta" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "" + +#: part/part.cpp:1416 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Password" +msgstr "Document Archive" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Ovaj dokument ima obrasce. Kliknite na gumb za interakciju ili koristite " +"Prikaz → Prikaži obrasce" + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Ispisivanje dokumenta nije dozvoljeno." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Ispisivanje dokumenta nije dozvoljeno." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Izađi iz prezentacijskog načina" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Ne mogu otvoriti %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&Neprekidno" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&Neprekidno" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +#| msgid "Open Document" +msgid "Close Document" +msgstr "Otvori dokument" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Ovaj link pokazuje na akciju za zatvaranje dokumenta koja ne radi kad se " +"koristi ugrađeni preglednik." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Ovaj link pokazuje na akciju za izlaz iz aplikacije koja ne radi kad se " +"koristi ugrađeni preglednik." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Ponovno učitavam dokument…" + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Sadržaj" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Idi na stranicu" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Stranica:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "" + +#: part/part.cpp:2367 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Rename this Bookmark" +msgstr "Preimenuj oznaku" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename Bookmark" +msgid "Remove this Bookmark" +msgstr "Preimenuj oznaku" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "&Spremi kao…" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Ne mogu otvoriti privremenu datoteku za spremanje." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Datoteku nije moguće spremiti u '%1'. Pokušajte ju spremiti na drugo mjesto." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgid "Presentation" +msgid "User annotations" +msgstr "Prezentacija" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&Neprekidno" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Datoteka nije mogla biti spremljena u '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular ne može kopirati %1 na navedeno mjesto.\n" +"\n" +"Dokument više ne postoji." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Datoteku nije moguće spremiti u '%1'. Pokušajte ju spremiti na drugo mjesto." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Završi prezentaciju" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Dodaj oznaku" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Alati" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Ispisivanje dokumenta nije dozvoljeno." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Ne mogu ispisati dokument. Nepoznata pogreška. Molim prijavite ovo na bugs." +"kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Ne mogu ispisati dokument. Detaljna pogreška je \"%1\". Molim prijavite ovo " +"na bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Idi na mjesto gdje si bio prije" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Idi na mjesto gdje si bio nakon" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Pogreška datoteke! Ne mogu stvoriti privremenu datoteku " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Pogreška datoteke! Ne mogu otvoriti datoteku " +"%1 za dekompresiju. Datoteka neće biti učitana." +"" + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Ova pogreška tipično se pojavljuje ako nema dovoljno prava za čitanje " +"datoteke. Možete provjeriti vlasništvo i prava ako desno kliknete na " +"datoteku u upravitelju datoteka Dolphin i tada odaberete stavku 'Svojstva'." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Pogreška datoteke! Ne mogu dekomprimirati datoteku " +"%1. Datoteka neće biti učitana." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Ova pogreška tipično se pojavljuje ako je datoteka oštećena. Ako želite " +"biti sigurni, pokušajte ručno dekomprimirati datoteku koristeći alate " +"komandne linije." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Nema oznaka" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Uredi" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Prikaz" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Kreni" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Alati" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Glavna alatna traka" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Annotation Toolbar" +msgstr "%1 opaska" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opće opcije" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Pristupačnost" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Pomoć za pristupačnost pri čitanju" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Performanse" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Podešavanje performansi" + +#: part/preferencesdialog.cpp:44 +#, fuzzy, kde-format +#| msgid "Configure Viewer..." +msgid "Configure Viewer" +msgstr "Konfiguriraj preglednik…" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Prezentacija" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opcije za prezentacijski način" + +#: part/preferencesdialog.cpp:50 +#, fuzzy, kde-format +#| msgid "Annotation Properties" +msgid "Annotation Options" +msgstr "Svojstva opaske" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opcije uređivača" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Nađi sljedeći" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Prezentacija" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Zamijeni zaslon" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Zaslon %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Izađi iz prezentacijskog načina" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Naslov: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Stranica: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Kliknite za početak" + +#: part/presentationwidget.cpp:505 +#, fuzzy, kde-format +#| msgctxt "pause the movie playback" +#| msgid "Pause" +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pauziraj" + +#: part/presentationwidget.cpp:508 +#, fuzzy, kde-format +#| msgctxt "start the movie playback" +#| msgid "Play" +msgctxt "For Presentation" +msgid "Play" +msgstr "Reproduciraj" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Postoje dva načina za izlaz iz prezentacijskog načina – možete pritisnuti " +"ili tipku ESC ili kliknuti na gumb za izlaz koji se pokaže kad pomaknete miš " +"u gornji-desni kut. Možete i kružiti kroz prozore (zadano je Alt+TAB)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Prezentacija u tijeku" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Nepoznata datoteka" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Svojstva %1 |/|Svojstva $[gen %1]" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Pisma" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Čitam informacije o pismu…" + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "Veličina &stranice" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Otpakiraj pismo" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Vrsta 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Vrsta 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Vrsta 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Vrsta 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Metrika pisma TeXa" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "Rukovan TeX FreeTypeom" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Nepoznata" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Ugrađeno (podskup)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Potpuno ugrađeno" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Ne" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Da (podskup)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Da" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Nepoznato pismo" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Ugrađeno: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Ime" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Vrsta" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Datoteka" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Stranice" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Veličina" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Pogled prije ispisa" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Gdje želite spremiti %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Ne mogu otvoriti %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Ne mogu otvoriti %1. Razlog: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Unesite barem 3 slova za filtriranje stranica" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Osjetljivost na veličinu slova" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Podudaranje u izrazu" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Podudaranje u svim riječima" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Podudaranje u bilo kojoj riječi" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opcije filtra" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Nema opaski

Da biste dodali opaske, pritisnite F6 " +"ili iz izbornika odaberite Alati → Osvrt.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Grupiraj po stranici" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Grupiraj po autoru" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Prikaži pregled samo za trenutnu stranicu" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Nepoznato pismo" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Nepoznata datoteka" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Nedostupan opis." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Stranica: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Svojstva" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Informacije" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "%1 opaska" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "Document Archive" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Prikaži samo označene stranice" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reproduciraj" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pauziraj" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Zaustavi" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, fuzzy, kde-format +#| msgid "&Edit" +msgid "&Edit..." +msgstr "&Uredi" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, fuzzy, kde-format +#| msgid "Wipe Down" +msgid "Move &Down" +msgstr "Briši prema dolje" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Stranica dokumenta koju treba prikazati" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Pokreni dokument u prezentacijskom načinu" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Kontrola \"Jedinstvena instanca\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +#| msgid "Document to open. Specify '-' to read from stdin." +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Dokument kojeg treba otvoriti. Navedite '-' za čitanje iz stdin-a." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "Nije moguće pronaći komponentu Okulara." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Nije moguće pronaći komponentu Okulara." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Kliknite za otvaranje datoteke\n" +"Kliknite i zadržite za otvaranje nedavne datoteke" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Kliknite za otvaranje datoteke ili kliknite i zadržite za " +"odabir nedavne datoteke" + +#: shell/shell.cpp:366 +#, fuzzy, kde-format +#| msgid "Next Page" +msgid "Next Tab" +msgstr "Sljedeća stranica" + +#: shell/shell.cpp:372 +#, fuzzy, kde-format +#| msgid "Previous Page" +msgid "Previous Tab" +msgstr "Prethodna stranica" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Sve datoteke" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Otvori dokument" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Zatvori" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Osvrti" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Sakrij obrasce" + +#~ msgid "Expired" +#~ msgstr "Isteklo" + +#~ msgid "&Review" +#~ msgstr "Osv&rt" + +#~ msgid "Annotations author" +#~ msgstr "Autor opaski" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Molim unesite vaše ime ili inicijale:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Prikaži &navigacijski panel" + +#~ msgid "Show Text" +#~ msgstr "Prikaži tekst" + +#~ msgid "Small Icons" +#~ msgstr "Male ikone" + +#~ msgid "Normal Icons" +#~ msgstr "Normalne ikone" + +#~ msgid "Large Icons" +#~ msgstr "Velike ikone" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Kliknite za korištenje trenutnog alata za označavanje\n" +#~ "Kliknite i zadržite za odabir drugog alata za označavanje" + +#~ msgid "Created: %1" +#~ msgstr "Izrađeno: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Nastavci linije" + +#~ msgid "Style" +#~ msgstr "Stil" + +#~ msgid "&Size:" +#~ msgstr "&Veličina:" + +#~ msgid "Inner color:" +#~ msgstr "Unutarnja boja:" + +#~ msgid "Name: %1" +#~ msgstr "Ime: %1" + +#~ msgid "Size: %1" +#~ msgstr "Veličina: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Alat za &listanje" + +#~ msgid "&Zoom Tool" +#~ msgstr "Alat za &zoom" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Označavanje" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Alat za označavanje &teksta" + +#, fuzzy +#~| msgid "&Selection Tool" +#~ msgid "T&able Selection Tool" +#~ msgstr "Alat za označa&vanje" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Kraj dokumenta" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Ništa" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Dobiven je zahtjev za pokretanje dokumenta u prezentacijskom načinu.\n" +#~ "Želite li ga odobriti?" + +#~ msgid "Presentation Mode" +#~ msgstr "Prezentacijski način" + +#~ msgid "Allow" +#~ msgstr "Dopusti" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Dozvoli prezentacijski način" + +#~ msgid "Do Not Allow" +#~ msgstr "Ne dopusti" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Nemoj dozvoliti prezentacijski način" + +#~ msgid "Save &Copy As..." +#~ msgstr "Spremi &kopiju kao…" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Dosegnut je kraj dokumenta.\n" +#~ "Da li da nastavim od početka?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Dosegnut je početak dokumenta.\n" +#~ "Da li da nastavim od dna?" + +#~ msgid "Current maintainer" +#~ msgstr "Trenutni održavatelj" + +#~ msgid "Identity Settings" +#~ msgstr "Postavke identiteta" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Sakrij obrasce" + +#~ msgid "No matches found for '%1'." +#~ msgstr "Nisu pronađene podudarnosti za '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Pretraživanje u tijeku…" + +#~ msgid "Searching for %1" +#~ msgstr "Tražim %1" + +#~ msgid "Ink" +#~ msgstr "Tinta" + +#~ msgid "Highlight Properties" +#~ msgstr "Svojstva označavanja" + +#~ msgid "Ink Properties" +#~ msgstr "Svojstva tinte" + +#~ msgid "Search Columns" +#~ msgstr "Pretraži stupce" + +#~ msgid "All Visible Columns" +#~ msgstr "Svi vidljivi stupci" + +#~ msgid "No document opened." +#~ msgstr "Nije otvoren nijedan dokument." + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Neuspjelo pokretanje usluge Jovie za pretvorbu teksta u govor: %1" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Promijeni način crtanja" + +#~ msgid "Enable &background generation" +#~ msgstr "Omogući stvaranje po&zadine" + +#~ msgid " sec." +#~ msgstr " sec." + +#~ msgid "Pencil color:" +#~ msgstr "Boja olovke:" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Žuta označnica" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Podcrtava tekst crnom linijom" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Cijan elipsa" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Žuta označnica" + +#~ msgid "Black Underlining" +#~ msgstr "Crno podcrtavanje" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Cijan elipsa" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Pomiče se na prvu stranicu dokumenta" + +#~ msgid "You must set this name:" +#~ msgstr "Morate postaviti ovo ime:" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Mijenja se između putanje datoteke i naslova" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" diff --git a/po/hr/okular_chm.po b/po/hr/okular_chm.po new file mode 100644 index 0000000..2db45c8 --- /dev/null +++ b/po/hr/okular_chm.po @@ -0,0 +1,63 @@ +# Translation of okular_chm to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2010-01-22 23:44+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "Podrška CHM-a" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Preglednik za datoteke pomoći iz Microsoft Windowsa" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/hr/okular_comicbook.po b/po/hr/okular_comicbook.po new file mode 100644 index 0000000..71d1cb2 --- /dev/null +++ b/po/hr/okular_comicbook.po @@ -0,0 +1,62 @@ +# Translation of okular_comicbook to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2010-01-22 23:50+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Nije moguće otvoriti dokument, unrar nije pronađen." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Inačica unrara na vašem sustavu nije odgovarajuća za otvaranje stripova." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Nepoznati oblik ComicBooka." + +#~ msgid "ComicBook Backend" +#~ msgstr "Podrška za ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Preglednik za razne oblike stripova" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hr/okular_djvu.po b/po/hr/okular_djvu.po new file mode 100644 index 0000000..897e14c --- /dev/null +++ b/po/hr/okular_djvu.po @@ -0,0 +1,139 @@ +# Translation of okular_djvu to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2010-02-25 18:58+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Uređivač" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Izdavač" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Svezak" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Vrsta dokumenta" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Nepoznat" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Datoteke komponente" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Nepoznato" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Jednostrani dokument" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Grupiran" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirektan" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Grupiran (staro)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indeksiran (staro)" + +#~ msgid "DjVu Backend" +#~ msgstr "Podrška za DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Podrška za DjVu bazirana na DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006–2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Nepoznat" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Nepoznat" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Nepoznat" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Nepoznat" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Nepoznat" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Nepoznato" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Nepoznata" diff --git a/po/hr/okular_dvi.po b/po/hr/okular_dvi.po new file mode 100644 index 0000000..5ecb062 --- /dev/null +++ b/po/hr/okular_dvi.po @@ -0,0 +1,607 @@ +# Translation of okular_dvi to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +# Andrej Dundovic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2010-06-05 20:38+0200\n" +"Last-Translator: Andrej Dundovic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Datoteka DVI ne započinje početnim nizom." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "Datoteka DVI je veoma oštećena. Okular nije mogao pronaći završni niz." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Završni niz ne započinje naredbom POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Završni niz sadržavao je naredbu koja nije FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Stranica %1 ne počinje naredbom BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, fuzzy, kde-format +#| msgid "" +#| "File not found: \n" +#| " %1" +msgid "File corruption. %1" +msgstr "" +"Datoteka nije pronađena:\n" +" %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "" + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI-kôd postavio je znak nepoznatog pisma." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI-kôd je upućivao na pismo #%1 koje nije prethodno definirano." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Stog nije bio prazan kada je pozvana naredba EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Stog je bio prazan kada je pozvana naredba POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI-kôd je upućivao na pismo koje nije prethodno definirano." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Naiđena je nedopuštena naredba." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Naiđen je nepoznati op-kôd %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Ugrađujem %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Stranica %1: datoteka PDF %2 ne može se pretvoriti u " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Stranica %1: datoteka PostScript %2 nije pronađena.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Podaci o veličini papira '%1' ne mogu biti obrađeni." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" + +#: fontpool.cpp:462 +#, fuzzy, kde-format +#| msgid "Currently generating %1 at %2 dpi" +msgid "Currently generating %1 at %2 dpi..." +msgstr "Trenutno stvaram %1 u %2 dpi" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generator/Datum" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Datoteka pisma nije pronađena" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "uspravno" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "vodoravno" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "" +"To je ukupno 25 pogreški. Daljnje poruke o pogreškama neće se ispisati." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Pogreška u DVI-datoteci '%1', stranica %2. Naiđena je naredba za preuzimanje " +"boje kad je stog boja bio prazan." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Izobličen parametar u posebnoj naredbi epsf.\n" +"Očekivano je da nakon %1 slijedi \"float\" u %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Datoteka nije pronađena:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Pogreška u DVI-datoteci '%1', stranica %2. Ne mogu interpretirati kut u " +"posebnoj rotaciji teksta." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "" + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "" + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "" + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Ne mogu otvoriti datoteku pisma %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: znak %1 nije definiran u pismu %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Neočekivano %1 u PK datoteci %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Loša datoteka pk (%1), previše bitova" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "" + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Nije moguće naći pismo %1, datoteku %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Nije moguće prepoznati format datoteke pisma %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Fatalna pogreška.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "" + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Dijalog napretka stvaranja pisama" + +#~ msgid "Abort" +#~ msgstr "Prekid" + +#~ msgid "What is happening here?" +#~ msgstr "Što se ovdje događa?" + +#~ msgid "%v of %m" +#~ msgstr "%v od %m" + +#~ msgid "Please be patient" +#~ msgstr "Molim budite strpljivi" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Izvezi datoteku kao" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Datoteka %1\n" +#~ "postoji. Želite li ju prepisati?" + +#~ msgid "Overwrite File" +#~ msgstr "Prepiši datoteku" + +#~ msgid "Overwrite" +#~ msgstr "Prepiši" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Koristim dvipdfm za izvoz datoteke u PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular trenutno koristi vanjski program 'dvipdfm' za pretvorbu vaše DVI-" +#~ "datoteke u PDF. Ponekad to može potrajati jer dvipdfm treba stvoriti " +#~ "vlastita bitmap-pisma. Molim bude strpljivi." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Čekam da dvipdfm završi…" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Izvoz: %1 u PDF" + +#~ msgid "Functionality Unavailable" +#~ msgstr "Nedostupna funkcionalnost" + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Koristim dvips za izvoz datoteke u PostScript" + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Čekam da dvips završi…" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Izvoz: %1 u PostScript" + +#~ msgid "DVI Backend" +#~ msgstr "Pozadinski servis za DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Preglednik datoteka vrste DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Oštećenje datoteke Okular nije uspio protumačiti " +#~ "vašu DVI-datoteku. Najčešći razlog tome je oštećena datoteka." + +#~ msgid "DVI File Error" +#~ msgstr "Pogreška datoteke DVI" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular trenutno stvara bitmap-pisma…" + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Prekida stvaranje pisama. Nemojte to činiti." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular stvara pisma. Molim pričekajte." + +#~ msgid "Not All Font Files Found" +#~ msgstr "Nisu pronađene sve datoteke pisama" + +#~ msgid "Locating fonts..." +#~ msgstr "Lociram pisma…" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular se oslanja na program kpsewhich za lociranje datoteka " +#~ "pisama na vašem tvrdom disku i za stvaranje PK-pisama ako je to potrebno." +#~ "

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Problem u lociranju pisama" + +#~ msgid "Font generation aborted" +#~ msgstr "Prekinuto stvaranje pisama" diff --git a/po/hr/okular_epub.po b/po/hr/okular_epub.po new file mode 100644 index 0000000..4236c11 --- /dev/null +++ b/po/hr/okular_epub.po @@ -0,0 +1,57 @@ +# Translation of okular_epub to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-26 16:15+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Greška pri otvaranju dokumenta vrste EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "" + +#: generator_epub.cpp:33 +#, fuzzy, kde-format +#| msgid "EPub Backend" +msgid "EPub Backend Configuration" +msgstr "Podrška za EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Podrška za EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/hr/okular_fax.po b/po/hr/okular_fax.po new file mode 100644 index 0000000..a72a9f5 --- /dev/null +++ b/po/hr/okular_fax.po @@ -0,0 +1,49 @@ +# Translation of okular_fax to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-28 21:03+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Neuspjelo učitavanje dokumenta" + +#~ msgid "Fax Backend" +#~ msgstr "Podrška za faks" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Podrška za dokumente faksa grupa G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hr/okular_fictionbook.po b/po/hr/okular_fictionbook.po new file mode 100644 index 0000000..6098226 --- /dev/null +++ b/po/hr/okular_fictionbook.po @@ -0,0 +1,83 @@ +# Translation of okular_fictionbook to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-28 21:07+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Dokument nije valjani FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Neuspjelo otvaranje dokumenta: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Dokument nije valjana arhiva tipa ZIP" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Nevaljana struktura dokumenta (nedostaje glavni direktorij)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "U dokumentu nije pronađen sadržaj" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Nevaljan dokument tipa XML: %1" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook" +msgstr "Podrška za Fiction Book" + +#: generator_fb.cpp:29 +#, fuzzy, kde-format +#| msgid "Fiction Book Backend" +msgid "FictionBook Backend Configuration" +msgstr "Podrška za Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Preglednik za e-knjige FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hr/okular_ghostview.po b/po/hr/okular_ghostview.po new file mode 100644 index 0000000..f6b1c15 --- /dev/null +++ b/po/hr/okular_ghostview.po @@ -0,0 +1,96 @@ +# Translation of okular_ghostview to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-30 15:52+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Koristi platformsko pismo" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Određuje smije li Ghostscript koristiti platformska pisma. Ako nije " +"omogućeno, koristit će se samo pisma ugrađena u dokument." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Opće postavke" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Koristi platformska pisma" + +# pmap: =/nom=Ghostscript/gen=Ghostscripta/dat=Ghostscriptu/aku=Ghostscript/lok=Ghostscriptu/ins=Ghostscriptom/_r=m/_b=j/ +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Konfiguracija podrške za Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Inačica dokumenta" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Razina jezika" + +#~ msgid "PS Backend" +#~ msgstr "Podrška za PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Preglednik za datoteke tipa PostScript" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007–2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Bazirano na biblioteci Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/hr/okular_kimgio.po b/po/hr/okular_kimgio.po new file mode 100644 index 0000000..50f8cc3 --- /dev/null +++ b/po/hr/okular_kimgio.po @@ -0,0 +1,71 @@ +# Translation of okular_kimgio to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2010-01-28 20:49+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Neuspjelo učitavanje dokumenta: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Podrška za sliku" + +#~ msgid "A simple image backend" +#~ msgstr "Jednostavna podrška za sliku" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Glavna alatna traka" diff --git a/po/hr/okular_mobi.po b/po/hr/okular_mobi.po new file mode 100644 index 0000000..68a98c4 --- /dev/null +++ b/po/hr/okular_mobi.po @@ -0,0 +1,66 @@ +# Translation of okular_mobi to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-28 21:11+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Greška pri otvaranju dokumenta tipa Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Ova knjiga je pod DRM-om i stoga može biti prikazana samo na određenom " +"uređaju" + +#: generator_mobi.cpp:28 +#, fuzzy, kde-format +#| msgid "Mobipocket Backend" +msgid "Mobipocket" +msgstr "Podrška za Mobipocket" + +#: generator_mobi.cpp:28 +#, fuzzy, kde-format +#| msgid "Mobipocket Backend" +msgid "Mobipocket Backend Configuration" +msgstr "Podrška za Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Podrška za mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008–2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/hr/okular_plucker.po b/po/hr/okular_plucker.po new file mode 100644 index 0000000..ccaf747 --- /dev/null +++ b/po/hr/okular_plucker.po @@ -0,0 +1,49 @@ +# Translation of okular_plucker to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-26 16:21+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Ime" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Podrška za dokumente vrste Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Preglednik za e-knjige vrste Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007–2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hr/okular_poppler.po b/po/hr/okular_poppler.po new file mode 100644 index 0000000..7dcbc69 --- /dev/null +++ b/po/hr/okular_poppler.po @@ -0,0 +1,224 @@ +# Translation of okular_poppler to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2010-05-12 11:07+0200\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Ne" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opcije PDF-a" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Nametni rasterizaciju" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasteriziraj u sliku prije ispisa" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Prije ispisa nameće rasterizaciju svake stranice u sliku. Ovo uglavnom daje " +"lošije rezultate, no korisno je pri ispisu dokumenata koji se nepravilno " +"ispisuju." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, fuzzy, kde-format +#| msgctxt "PDF v. " +#| msgid "PDF v. %1" +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Oblik" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Kriptirano" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Nekriptirano" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sigurnost" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Da" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimizirano" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "" + +#: generator_pdf.cpp:1470 +#, fuzzy, kde-format +#| msgid "PDF Backend" +msgid "PDF Backend Configuration" +msgstr "Podrška za PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "A PDF file renderer" +#~ msgstr "Preglednik datoteka tipa PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005–2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Unesite zaporku kako biste čitali dokument:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Netočna zaporka. Pokušajte ponovno:" + +#~ msgid "Document Password" +#~ msgstr "Zaporka dokumenta" + +#~ msgid "Unknown" +#~ msgstr "Nepoznato" + +#~ msgid "Unknown Date" +#~ msgstr "Nepoznat datum" + +#~ msgid "Unknown Encryption" +#~ msgstr "Nepoznato kriptiranje" + +#~ msgid "Unknown Optimization" +#~ msgstr "Nepoznata optimizacija" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Spremanje datoteka s /Kriptiraj nije podržano." diff --git a/po/hr/okular_xps.po b/po/hr/okular_xps.po new file mode 100644 index 0000000..3bd493e --- /dev/null +++ b/po/hr/okular_xps.po @@ -0,0 +1,61 @@ +# Translation of okular_xps to Croatian +# +# Zarko Pintar , 2009. +# Marko Dimjasevic , 2010. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2010-01-22 23:55+0100\n" +"Last-Translator: Marko Dimjasevic \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Environment: kde\n" +"X-Accelerator-Marker: &\n" +"X-Text-Markup: kde4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Marko Dimjašević" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "marko@dimjasevic.net" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Izdanje" + +#~ msgid "XPS Backend" +#~ msgstr "Podrška za XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Podrška za XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/hu/okular.po b/po/hu/okular.po new file mode 100644 index 0000000..b71f8ce --- /dev/null +++ b/po/hu/okular.po @@ -0,0 +1,5969 @@ +# +# Tamas Szanto , 2003. +# Kiszel Kristóf , 2010. +# Kristóf Kiszel , 2010, 2011, 2012. +# Balázs Úr , 2012, 2013, 2014, 2015. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.3\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2015-02-26 16:03+0100\n" +"Last-Translator: Balázs Úr \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Szántó Tamás" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "tszanto@interware.hu" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular dokumentumnézegető" + +#: aboutdata.h:26 +#, fuzzy, kde-format +#| msgid "" +#| "(C) 2002 Wilco Greven, Christophe Devriese\n" +#| "(C) 2004-2005 Enrico Ros\n" +#| "(C) 2005 Piotr Szymanski\n" +#| "(C) 2004-2009 Albert Astals Cid\n" +#| "(C) 2006-2009 Pino Toscano" +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© Wilco Greven, Christophe Devriese, 2002.\n" +"© Enrico Ros, 2004-2005.\n" +"© Piotr Szymanski, 2005.\n" +"© Albert Astals Cid, 2004-2009.\n" +"© Pino Toscano, 2006-2009." + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Korábbi karbantartó" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Sok kód a keretrendszerhez, az ODT- és a FictionBook-modulhoz" + +#: aboutdata.h:36 +#, fuzzy, kde-format +#| msgid "KPDF developer" +msgid "Developer" +msgstr "KPDF-fejlesztő" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "A KPDF-ből kiindulva létrehozta az Okular alapkódját" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF-fejlesztő" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "A megjegyzések grafikájának készítője" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Táblázatkijelölő eszköz" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Megjegyzés tökéletesítések" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Ugrás a(z) %1. oldalra" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Külső fájl megnyitása" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Végrehajtás: „%1”…" + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Első oldal" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Előző oldal" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Következő oldal" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Utolsó oldal" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Vissza" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Előre" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Kilépés" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Bemutató" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "A bemutató leállítása" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Keresés..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Ugrás egy oldalra..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Hang lejátszása..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Javascript-fájl" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Film lejátszása..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Film lejátszása" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Film leállítása" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Film szüneteltetése" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Film folytatása" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Háttérmodul kiválasztása" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Egynél több lehetséges megjelenítőmodul található ehhez a MIME-típushoz:" +"
%1 (%2).

Válasszon ki egyet:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Ugrás a(z) %1. oldalra" + +#: core/document.cpp:224 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "portrait C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "álló C5E" + +#: core/document.cpp:226 +#, fuzzy, kde-format +#| msgctxt "paper size" +#| msgid "landscape C5E" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "fekvő C5E" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 hüvelyk (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Nem található a dokumentum kezelésére alkalmas modul." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "megjegyzések eltávolítása" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"A dokumentum egy külső alkalmazást próbált elindítani, ezt biztonsági " +"okokból a program nem engedélyezi." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Nincs kezelőalkalmazás %1 MIME-típusú fájlokhoz." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Nem sikerült megnyitni egy ideiglenes fájlt" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "A nyomtatáskonverzió nem sikerült" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "A nyomtatási folyamat összeomlott" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Nem sikerült elindítani a nyomtatási folyamatot" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Nem sikerült nyomtatni a fájlba" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "A nyomtató érvénytelen állapotban voltcén" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Nem található nyomtatandó fájlfájl a ny" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Nem volt nyomtatandó fájl" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Nem található megfelelő bináris a nyomtatáshoz. Ellenőrizze hogy a CUPS lpr " +"bináris elérhető-e" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Az oldal nyomtatási mérete érvénytelen" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Nem sikerült megnyitni ezt a fájlt: „%1”. A fájl nem létezik" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Cím" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Tárgy" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Leírás" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Szerző" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Létrehozó" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Készítő" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Szerzői jog" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Oldalszám" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Létrehozási dátum" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Utolsó módosítás" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME-típus" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategória" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Kulcsszavak" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Fájl útvonalaó" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Fájlméret" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Oldalméret" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "megjegyzés hozzáadása" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "megjegyzés eltávolítása" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "megjegyzés tulajdonságainak módosítása" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "megjegyzés fordítása" + +#: core/documentcommands.cpp:261 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "megjegyzés hozzáadása" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "szöveg szerkesztése" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "megjegyzés tartalmának szerkesztése" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "űrlap tartalmának szerkesztése" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "listaűrlap választásainak szerkesztése" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "lenyíló űrlap kijelölés szerkesztése" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "űrlap gombok állapotának szerkesztése" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Egyszerű szöveg..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Szöveges OpenDocument-fájl" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Szerkesztőbeállítások" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Színmód:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Az üzenet bezárása." + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Forrás: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Alapértelmezett betűkészlet:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Új&ratöltés" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Allow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Engedélyezem" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Képernyő" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Teljes szélességre" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Megjegyzés tulajdonságai" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Megjegyzés eszközök" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Megjegyzés eszközök" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Megjegyzés eszközök" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Megjegyzés eszközök" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "%1 megjegyzés" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Megjegyzés tulajdonságai" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "S&zín:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "&Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "S&zín:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Kísérleti" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "Ki&jelölő" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "Megjegyzések" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlighter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Kiemelő" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Aláhúzott" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Cikkcakkos" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Áthúzott" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Felülírás" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Beszúrt megjegyzés" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Felugró megjegyzés" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Szabadkézi vonal" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Egyenes vonal" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Téglalap" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipszis" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Sokszög" + +#: part/annotationactionhandler.cpp:534 +#, fuzzy, kde-format +#| msgid "Geometrical shape" +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Geometrikus alakzat" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Pecsét" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Megjegyzések" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "megjegyzés hozzáadása" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Megjegyzés eszköz létrehozása" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Betűtípus:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Megjegyzés tulajdonságai" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Vonal" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Á&tlátszatlanság:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "%1. oldal" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "%1 megjegyzés" +msgstr[1] "%1 megjegyzés" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "Megnyitás felb&ukkanó ablakban" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Törlés" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Tulajdonságok" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Men&tés: „%1”…" + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "Meg&jelenés" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "Á<alános" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "Sze&rző:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Létrehozási dátum" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Utolsó módosítás" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Felugró megjegyzés tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "A kurzor tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "A beszúrt megjegyzés tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Egyenes vonal tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Sokszög tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "A geometria tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Szövegjelölő tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "A pecsét tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Szabadkézi vonal tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "A kurzor tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "A csatolás tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Hangbeállítások" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Videóbeállítások" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "A megjegyzés tulajdonságai" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Utolsó módosítás: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Pecsétszimbólum" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "S&zín:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Á&tlátszatlanság:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Ikon" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Megjegyzés" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Súgó" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Beszúrás" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Kulcs" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Új bekezdés" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Megjegyzés" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Bekezdés" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Betűtípus:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "S&zín:" + +#: part/annotationwidgets.cpp:389 +#, fuzzy, kde-format +#| msgid "Align:" +msgid "&Align:" +msgstr "Igazítás:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Balra" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Középre" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Jobbra" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Jóváhagyva" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Így ahogy van" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Bizalmas" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Szervezeti egységi" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Vázlat" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Kísérleti" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Végleges" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Megjegyzésre" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Nyilvános kibocsátásra" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Nincs jóváhagyva" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Nem bocsátható nyilvánosságra" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Eladva" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Szigorúan titkos" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Könyvjelző" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Információ" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Pecsétszimbólum" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Width:" +msgstr "Teljes szélességre" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Vonal" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Vonal" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Nincs" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Vezérvonal hossza:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Vezérvonal kiterjesztésének hossza:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Shape fill:" +msgstr "Mentés fájlba..." + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Típus:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Kiemelés" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Cikkcakkos" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Aláhúzott" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Áthúzott" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Téglalap" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipszis" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "Csatolásjelző" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafikon" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Rajzszög" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Iratkapocs" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Címke" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Fájl" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "-" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Nincs leírás." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "&Name:" +msgid "Name:" +msgstr "&Név:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Leírás:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "Kurzorjel" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Nincs" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Bezárás" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Beállítások" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Ez a magyarázat LaTeX kódot tartalmazhat.\n" +"Kattintson ide a rendereléshez." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Nem található végrehajtható latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "A LaTeX renderelés nem sikerült" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Nem található végrehajtható dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Probléma történt a „latex” parancs végrehajtása közben." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Probléma történt a „dvipng” parancs végrehajtása közben." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Egy könyvjelző" +msgstr[1] "" +"%1\n" +"\n" +"%2 könyvjelző" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Könyvjelzők" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "K&eresés:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Csak az aktuális dokumentum" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Ugrás" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Könyvjelző átnevezése" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Könyvjelző eltávolítása" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Dokumentum megnyitása" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Könyvjelzők eltávolítása" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "Oldalszám" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Lejárt" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Tárgy" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Memóriahasználat" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Tulajdonságok" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "A megjelenítő beállítása" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "E&xportálás mint" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Általános" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Hová szeretné menteni: %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, fuzzy, kde-format +#| msgid "Reloa&d" +msgid "Red" +msgstr "Új&ratöltés" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, fuzzy, kde-format +#| msgctxt "Caption for a screen annotation" +#| msgid "Screen" +msgid "Green" +msgstr "Képernyő" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, fuzzy, kde-format +#| msgid "Allow" +msgid "Yellow" +msgstr "Engedélyezem" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "&Keret rajzolása a képek körül" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Keret &rajzolása a linkek körül" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "A színek mó&dosítása" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Figyelem: ezek az opciók le tudják lassítani a kirajzolási sebességet." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Színmód:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "A színek invertálása" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Más háttérszín" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "A sötét és világos színek felcserélése" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Konvertálás fekete-fehérre" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Háttérszín:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Sötét szín:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Világos szín:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Küszöbérték:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontraszt:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Azonosító" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "Sze&rző:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Megjegyzés: ez a szöveg csak megjegyzésként lesz felhasználva, " +"jóváhagyás nélkül nem továbbítódik semmilyen formában sem." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "Megjegyzés eszköz szerkesztése" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Más szövegszerkesztő" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs-kliens" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx-kliens" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"A használni kívánt szövegszerkesztő indítóparancsa.
\n" +"Az alábbi szimbólumok használhatók:\n" +"
    \n" +"
  • %f - fájlnév
  • \n" +"
  • %l - sorszám a szövegben
  • \n" +"
  • %c - oszlopszám a szövegben
  • \n" +"
\n" +"Ha az %f nincs megadva, akkor a fájlnév hozzá lesz főzve az indítóparancshoz." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Szövegszerkesztő" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Szerkesztő:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Válassza ki, melyik szövegszerkesztő induljon el forrásfájl megnyitásakor." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Parancs:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Megjelenés" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Gör&dítősávok" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "A gyorsnézeti képek k&apcsolása az oldalhoz" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Tippek és &tájékoztató üzenetek megjelenítése" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "A dokumentum címének megjelenítése a címsoron, ha elérhető" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Ha nem jelenik meg a dokumentum címe:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Csak fájlnév megjelenítése" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Teljes elérési út megjelenítése" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, fuzzy, kde-format +#| msgid "Background color:" +msgid "Use custom background color" +msgstr "Háttérszín:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "A program jellemzői" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Új fájlok megnyitása &lapokon" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "A &DRM-korlátozások betartása" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "A dokumentum új&ratöltése, ha a fájl megváltozik" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Választóablak a háttérmodul kijelöléséhez" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Nézetbeállítások" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Áttekintő &oszlopok:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Meghatározza, hogy a jelenlegi nézetterületből mennyi látszódjon még a " +"PageUp/Down gombok lenyomásakor." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Oldal fel/le átfedés:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Meghatározza az alapértelmezett nagyítási módot azokra a fájlokra, amelyek " +"még nem voltak eddig megnyitva.\n" +"A korábban már megnyitott fájlokra az előző nagyítás lesz alkalmazva." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Meghatározza az alapértelmezett nagyítási módot azokra a fájlokra, amelyek " +"még nem voltak eddig megnyitva.\n" +"A korábban már megnyitott fájlokra az előző nagyítás lesz alkalmazva." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Alapértelmezett nagyítás:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Teljes szélességre" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Teljes oldal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Automatikus igazítás" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"A memóriahasználat minimalizálása. Az újrafelhasználás kikapcsolása. (Kevés " +"memóriájú gépeknél ajánlott.)" + +#: part/dlgperformance.cpp:53 +#, fuzzy, kde-format +#| msgid "" +#| "A good compromise between memory usage and speed gain. Preload next page " +#| "and boost searches. (For systems with 256MB of memory, typically.)" +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Közepes memóriaigény, kompromisszum a kis memóriahasználat és a sebesség " +"között. A következő oldal előre betöltése és a keresések felgyorsítása. (Kb. " +"256 MB memória esetén ajánlott.)" + +#: part/dlgperformance.cpp:56 +#, fuzzy, kde-format +#| msgid "" +#| "Keeps everything in memory. Preload next pages. Boost searches. (For " +#| "systems with more than 512MB of memory.)" +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Megnövelt memóriahasználat a sebesség érdekében. A következő oldal előre " +"betöltése és a keresések felgyorsítása. (512 MB memória fölött ajánlott.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Betölt és mindent a memóriában tart. Minden oldal előtöltése. (Maximum a " +"teljes memória 50%-át vagy a szabad memóriát használja, amelyik nagyobb.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "CPU-használat" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Á&tlátszóság engedélyezése" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Memóriahasználat" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Alacsony" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, fuzzy, kde-format +#| msgid "&Normal (default)" +msgid "Nor&mal (default)" +msgstr "N&ormál (alapértelmezés)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, fuzzy, kde-format +#| msgid "&Aggressive" +msgid "Aggr&essive" +msgstr "Me&gnövelt" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, fuzzy, kde-format +#| msgid "&Greedy" +msgid "G&reedy" +msgstr "&Mohó" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Renderelés" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Szöveg élsimításának engedélyezése" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Grafika élsimításának engedélyezése" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Szövegutalás engedélyezése" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "A jelenlegi képernyő" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Az alapértelmezett képernyő" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "%1. képernyő" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " másodperc" +msgstr[1] " másodperc" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigáció" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Léptetési időköz:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Az utolsó oldal után folytatás az elsőtől" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Navigáció" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Háttérszín:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Egérmutató:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Várakozás, majd elrejtés" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Mindig látható" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Mindig rejtett" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Á&llapotjelző mutatása" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "&Áttekintő oldal mutatása" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Átmenetek engedélyezése" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Alapértelmezett átmenet:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Kioltás függőlegesen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Kioltás vízszintesen" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Doboz be" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Doboz ki" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Feloldás" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Ragyogás lefelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Ragyogás jobbra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Ragyogás jobbra, lefelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Véletlenszerű átmenet" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Csere" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Vízszintes megosztás befelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Vízszintes megosztás kifelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Függőleges megosztás befelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Függőleges megosztás kifelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Törlés lefelé" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Törlés jobbra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Törlés balra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Törlés felfelé" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Elhelyezés" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Képernyő:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Eraser" +msgstr "Rajz törlése" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Név:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Típus:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Felugró megjegyzés" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Beszúrt megjegyzés" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Szabadkézi vonal" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Egyenes vonal" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Sokszög" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Szövegjelölő" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Geometrikus alakzat" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Pecsét" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, fuzzy, kde-format +#| msgid "Overwrite" +msgid "Typewriter" +msgstr "Felülírás" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Megjegyzés eszköz létrehozása" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Megjegyzés eszköz szerkesztése" + +#: part/editdrawingtooldialog.cpp:53 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Color:" +msgstr "S&zín:" + +#: part/editdrawingtooldialog.cpp:60 +#, fuzzy, kde-format +#| msgid "Fit Width" +msgid "&Pen Width:" +msgstr "Teljes szélességre" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr "%" + +#: part/editdrawingtooldialog.cpp:81 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgid "Create drawing tool" +msgstr "Megjegyzés eszköz létrehozása" + +#: part/editdrawingtooldialog.cpp:86 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Edit drawing tool" +msgstr "Megjegyzés eszköz szerkesztése" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Ismeretlen" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Beágyazott fájlok" + +#: part/embeddedfilesdialog.cpp:62 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:button" +msgid "View" +msgstr "Né&zet" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Név" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Leírás" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Méret" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Létrehozási dátum" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Utolsó módosítás" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Mentés más&ként..." + +#: part/embeddedfilesdialog.cpp:153 +#, fuzzy, kde-format +#| msgid "&View" +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "Né&zet" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Nem sikerült betölteni a nyomtatási előnézet objektumát" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "nyomtatási előnézet" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Bezárás" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Keresés:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "A keresett szöveg" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Következő" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Következő találat" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Előző" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Ugrás az előző találatra" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "A keresési beállítások módosítása" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Nagybetűérzékeny" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Az aktuális oldaltól" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Minden fájl" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "A kurzor tulajdonságai" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Straight Line Properties" +msgid "Straight Line with Comment" +msgstr "Egyenes vonal tulajdonságai" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "Megjegyzésre" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Highlight text" +msgid "Highlight with Comment" +msgstr "Szöveg kiemelése" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Squiggle text" +msgid "Squiggle with Comment" +msgstr "Cikkcakkos szöveg" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Underline text" +msgid "Underline with Comment" +msgstr "Szöveg aláhúzása" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Strike out text" +msgid "Strike Out with Comment" +msgstr "Szöveg áthúzása" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Áthúzott" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Freehand Line Properties" +msgid "Freehand Line with Comment" +msgstr "Szabadkézi vonal tulajdonságai" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Kurzor" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Csatolás" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Hang" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Videó" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Képernyő" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Widget" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Ismeretlen" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Szerző: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Hová szeretné menteni: %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" +"Nem sikerült megnyitni olvasásra ezt a fájlt: „%1”. A fájl nem lett elmentve." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Keresési beállítások" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Nagybetűérzékeny" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Reguláris kifejezés" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "K&eresés:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "/" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Nagyítás" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Forgatás &jobbra" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Jobbra" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Forgatás &balra" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Balra" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Eredeti tájolás" + +#: part/pageview.cpp:565 +#, fuzzy, kde-format +#| msgid "&View" +msgid "&Trim View" +msgstr "Né&zet" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Keskeny szegélyek" + +#: part/pageview.cpp:576 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Trim To &Selection" +msgstr "Szövegkijelölő" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Te&ljes szélesség" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Teljes ol&dal" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Automatikus igazítás" + +#: part/pageview.cpp:594 +#, fuzzy, kde-format +#| msgid "Fit &Page" +msgid "Fit Wi&ndow to Page" +msgstr "Teljes ol&dal" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Né&zetmód" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Egy oldal" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Két oldal" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Két oldal (első oldal középre)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Áttekintő" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Folyamatos" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Böngésző" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Nagyítás" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Színek &módosításának váltása" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Szövegkijelölő" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Szövegkijelölő" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "Táblázatkijelölés" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Nagyító" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Kijelölő eszközök" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Felolvasás (a teljes dokumentumot)" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Felolvasás (a jelenlegi oldalt)" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Állj" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Gördítés felfelé" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Gördítés lefelé" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Egy oldallal feljebb görgetés" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Egy lappal lejjebb görgetés" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Az űrlapok megjelenítése" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Betöltve egy 1 oldalas dokumentum." +msgstr[1] " Betöltve egy %1 oldalas dokumentum." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Szöveg (%1 karakter)" +msgstr[1] "Szöveg (%1 karakter)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Másolás a vágólapra" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "DRM-korlátozás miatt nem lehet másolni" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "A szöveg felolvasása" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Kép (%1 x %2 képpont)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Mentés fájlba..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Egy kép (%1 x %2) kimásolva a vágólapra." + +#: part/pageview.cpp:2696 +#, fuzzy, kde-format +#| msgid "Save to File..." +msgid "Save file" +msgstr "Mentés fájlba..." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "A fájl nincs elmentve." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Egy kép (%1 x %2) elmentve ebbe a fájlba: %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "A szöveg másolása" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Ugrás erre: „%1”" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "%1 keresése ezzel:" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Keresőazonosítók beállítása…" + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "A link követése" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Hang lejátszása" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Hang leállítása" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "A link címének másolása" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "%1 keresése ezzel:" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Üdvözlet" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Válassza ki a kinagyítandó területet. Kicsinyítés: jobb kattintással." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Kattintson a nagyított nézet megtekintéséhez." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Húzzon keretet a másolandó szöveg vagy grafika köré." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Szöveg kijelölése" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Rajzoljon egy téglalapot a tábla köré, majd kattintson a sarkok közelébe a " +"felosztáshoz; nyomja meg az Esc gombot a törléshez." + +#: part/pageview.cpp:4911 +#, fuzzy, kde-format +#| msgid "Draw a rectangle around the text/graphics to copy." +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Húzzon keretet a másolandó szöveg vagy grafika köré." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Következő megjegyzés" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "A következő megjegyzés szövege:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "megjegyzés hozzáadása" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Ellipszis rajzolása (zóna kijelölése húzással)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Szöveg kiemelése" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Szabadkézi vonal rajzolása" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Közvetlen megjegyzések (zóna kijelölése húzással)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Felugró megjegyzés elhelyezése" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Sokszög rajzolása (bezáráshoz kattintson az első pontra)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Téglalap rajzolása" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Cikkcakkos szöveg" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Pecsétszimbólum" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Egyenes vonal rajzolása" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Szöveg áthúzása" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Szöveg aláhúzása" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Közvetlen megjegyzések (zóna kijelölése húzással)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Kiemelő" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "megjegyzés hozzáadása" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Custom annotation name:" +msgstr "megjegyzés hozzáadása" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Fájl" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "&Beállítások" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Súgó" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Tájolás" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Könyvjelzők" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Megjelenítő eszköztár" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Gyorsnézeti képek" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Megjegyzések" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"A dokumentum beágyazott fájlt is tartalmaz. Kattintson ide azok megtekintéséhez vagy válassza a Fájl -> " +"Beágyazott fájlok menüpontot." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Előző" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Ugrás az előző oldalra" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Visszalépés a dokumentum előző oldalára" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Következő" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Következő oldal" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Előrelépés a dokumentum következő oldalára" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "A dokumentum eleje" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Előrelépés a dokumentum elejére" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "A dokumentum vége" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Előrelépés a dokumentum végére" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "A jelenlegi könyvjelző átnevezése" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Előző könyvjelző" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Ugrás az előző könyvjelzőre" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Következő könyvjelző" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Ugrás a következő könyvjelzőre" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Beállítóablak: Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "A megjelenítő beállítása..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Megjelenítő háttérmodul beállítása…" + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "A háttérmodul beállítása..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "A háttérmodul névjegye" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Új&ratöltés" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "A dokumentum újratöltése." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "A keresősáv be&zárása" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Oldalszám" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Felolvasás (a jelenlegi oldalt)" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "&Oldalsáv megjelenítése" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "&Oldalsáv megjelenítése" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "A na&vigációs panel megjelenítése" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Beá&gyazott fájlok" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xportálás mint" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&Bemutató" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "Postscript-fájl importálása P&DF formátumban..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Könyv &letöltése az internetről..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Váltás feketeképernyő-módba" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Rajz törlése" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Megjegyzések beállítása…" + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Bemutató indítása/szüneteltetése" + +#: part/part.cpp:1092 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open '%1' (%2) " +msgstr "Nem sikerült megnyitni: %1" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "A(z) %1 betöltése meg lett szakítva.vetö" + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Nem sikerült megnyitni: %1. A hiba oka: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Megjelenítő háttérmodul beállítása" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Háttérmodul beállítása" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Nem található a „ps2pdf” programfájl, ezért az Okular nem tud PS-fájlokat " +"importálni." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "Nem található a ps2pdf programfájl" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "PS-fájl importálása PDF formátumban (sokáig eltarthat)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Adja meg a jelszót a dokumentum olvasásához:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Hibás jelszó. Próbálja újra:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Dokumentumjelszó" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Ennek a dokumentumnak XFA űrlapjai vannak, amelyek jelenleg nem " +"támogatottak." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"A dokumentum űrlapot is tartalmaz. A gombra kattintva (vagy a Nézet -> " +"Űrlapok menüponttal) lehet kezelni őket." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "A dokumentum nyomtatása nincs engedélyezve." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "A dokumentum nyomtatása nincs engedélyezve." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, fuzzy, kde-format +#| msgid "Exit Presentation Mode" +msgid "Enter Presentation Mode" +msgstr "Kilépés bemutató módból" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Nem sikerült megnyitni: %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "" + +#: part/part.cpp:1765 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Reloading" +msgstr "&Folyamatos" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue Closing" +msgstr "&Folyamatos" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "" + +#: part/part.cpp:1778 +#, fuzzy, kde-format +#| msgid "Do you want to save your annotation changes or discard them?" +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Szeretné elmenteni a megjegyzés változásait vagy elveti őket?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Dokumentum bezárása" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Ez a link dokumentumbezárási műveletre mutat, mely nem működik beágyazott " +"megjelenítő használatakor." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Ez a link alkalmazáskilépési műveletre mutat, mely nem működik beágyazott " +"megjelenítő használatakor." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "A dokumentum újratöltése..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Tartalom" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Ugrás egy oldalra" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Oldalszám:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Adja meg a könyvjelző új nevét:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Könyvjelző átnevezése" + +#: part/part.cpp:2370 +#, fuzzy, kde-format +#| msgid "Rename this Bookmark" +msgid "Remove this Bookmark" +msgstr "Könyvjelző átnevezése" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, fuzzy, kde-format +#| msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +#| msgid "%1 (%2)" +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, fuzzy, kde-format +#| msgctxt "@action:inmenu" +#| msgid "&Save As..." +msgid "Save As" +msgstr "Mentés más&ként..." + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Nem sikerült megnyitni egy ideiglenes fájlt mentésre." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Nem sikerült elmenteni a fájlt ide: „%1”. Próbálja máshová menteni." + +#: part/part.cpp:2557 +#, fuzzy, kde-format +#| msgctxt "Edit an form's text contents" +#| msgid "edit form contents" +msgid "Filled form contents" +msgstr "űrlap tartalmának szerkesztése" + +#: part/part.cpp:2559 +#, fuzzy, kde-format +#| msgctxt "remove a collection of annotations from the page" +#| msgid "remove annotations" +msgid "User annotations" +msgstr "megjegyzések eltávolítása" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "" + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, fuzzy, kde-format +#| msgid "&Continuous" +msgid "Continue" +msgstr "&Folyamatos" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Nem sikerült elmenteni a fájlt ide: „%1”. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Nem sikerült átmásolni a megadott helyre ezt a fájlt: %1.\n" +"\n" +"Nem létezik ilyen nevű dokumentum." + +#: part/part.cpp:2677 +#, fuzzy, kde-format +#| msgid "File could not be saved in '%1'. Try to save it to another location." +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "Nem sikerült elmenteni a fájlt ide: „%1”. Próbálja máshová menteni." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "A bemutató leállítása" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Könyvjelző hozzáadása" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Eszközök" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "A dokumentum nyomtatása nincs engedélyezve." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Ismeretlen hiba miatt nem sikerült kinyomtatni a dokumentumot. Kérjük " +"jelentse be a hibát itt: bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"A következő hiba miatt nem sikerült kinyomtatni a dokumentumot: „%1”. Kérjük " +"jelentse be a hibát itt: bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Ugrás az előző pozícióra" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Ugrás a következő pozícióra" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Fájlhiba Nem sikerült létrehozni ezt az ideiglenes " +"fájlt: %1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Fájlhiba Nem sikerült megnyitni ezt a fájlt " +"kitömörítésre: %1. A fájlt nem sikerült " +"betölteni." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Ez a hiba általában akkor fordul elő, ha nincs jogosultsága a fájl " +"megnyitásához. Ha a jobb gombbal rákattint a fájlra a Konqueror " +"fájlkezelőben, megtekintheti a jogosultságot(\"Tulajdonságok\" menü)." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Fájlhiba Nem sikerült kitömöríteni a fájlt " +"%1. A fájlt nem sikerült betölteni." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Ez a hiba általában akkor jelentkezik, ha a fájl megsérült. A fájl " +"integritásának ellenőrzéséhez tömörítse ki azt parancssoros eszközökkel." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Nincs könyvjelző" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "S&zerkesztés" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "Né&zet" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Ugrás" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "&Eszközök" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Alap eszköztár" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Megjegyzés eszközök" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Általános beállítások" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Kezelési segítség" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Olvasási segítség" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Teljesítmény" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Teljesítménytuning" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "A megjelenítő beállítása" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Bemutató" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "A bemutató-mód beállításai" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Megjegyzés tulajdonságai" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Szerkesztőbeállítások" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Következő találat" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - bemutató" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Képernyőváltás" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "%1. képernyő" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Kilépés bemutató módból" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Cím: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Oldalszám: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Kattintson ide a kezdéshez" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Szünet" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Indítás" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Két módon lehet kilépni a bemutatóból: nyomja meg az Esc billentyűt vagy " +"kattintson az egérrel a Kilépés gombra, mely a jobb felső sarokban jelenik " +"meg, ha odaviszi az egérmutatót. Az ablakváltás is használható természetesen " +"(Alt+Tab alapértelmezés szerint)." + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Egy bemutató tart" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Ismeretlen fájl" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 - tulajdonságok" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Betűtípusok" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "A betűtípusok jellemzőinek feldolgozása folyik..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Oldalméret" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "Betűtípus ki&bontása" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Ismeretlen" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Beágyazott (részben)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Beágyazott" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Nem" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Igen (részben)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Igen" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[-]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Ismeretlen betűtípus" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Beágyazott: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Név" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Típus" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Fájl" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Oldalszám" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Méret" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "nyomtatási előnézet" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Hová szeretné menteni: %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Nem sikerült megnyitni: %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Nem sikerült megnyitni: %1. A hiba oka: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Oldalszűrés legalább 3 betűvel" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Nagybetűérzékeny" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Kifejezés illesztése" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Minden szó illeszkedjen" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Elég egy szó illeszkedése is" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Szűrőbeállítások" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Nincs megjegyzés

Új megjegyzés készítéséhez nyomja " +"meg az F6 billentyűt vagy válassza az Eszközök -> Ellenőrzés " +"menüpontot.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Csoportosítás oldalanként" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Csoportosítás szerzőnként" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Csak az aktuális oldal megjegyzéseinek mutatása" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Ismeretlen betűtípus" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Ismeretlen fájl" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Nincs leírás." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Oldalszám: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Tulajdonságok" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Információ" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "%1 megjegyzés" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "Dokumentumarchívum" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Csak a könyvjelzős oldalak mutatása" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Lejátszás" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Szünet" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Állj" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Hozzáadás…" + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "S&zerkesztés…" + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Eltávolítás" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Mozgatás &felfelé" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Mozgatás &lefelé" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "A megjelenítendő dokumentum egy oldala" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Bemutató indítása a dokumentummal" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Kezdés a nyomtatás párbeszédablakkal" + +#: shell/main.cpp:78 +#, fuzzy, kde-format +#| msgid "Start with print dialog" +msgid "Start with print dialog and exit after printing" +msgstr "Kezdés a nyomtatás párbeszédablakkal" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "„Egyedi példány” kezelése" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Ne hozza előre az ablakot" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, fuzzy, kde-format +#| msgid "Document to open. Specify '-' to read from stdin." +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "" +"A megnyitandó dokumentum. '-' megadása esetén a standard bemenetről olvas." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Hiba: Nem lehet egynél több dokumentumot megnyitni a --unique kapcsolóval" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Hiba: Nem lehet egynél több dokumentumot megnyitni a --presentation " +"kapcsolóval" + +#: shell/okular_main.cpp:136 +#, fuzzy, kde-format +#| msgid "" +#| "Error: Can't open more than one document with the --presentation switch" +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Hiba: Nem lehet egynél több dokumentumot megnyitni a --presentation " +"kapcsolóval" + +#: shell/okular_main.cpp:142 +#, fuzzy, kde-format +#| msgid "Error: Can't open more than one document with the --unique switch" +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Hiba: Nem lehet egynél több dokumentumot megnyitni a --unique kapcsolóval" + +#: shell/okular_main.cpp:148 +#, fuzzy, kde-format +#| msgid "" +#| "Error: Can't open more than one document with the --presentation switch" +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Hiba: Nem lehet egynél több dokumentumot megnyitni a --presentation " +"kapcsolóval" + +#: shell/shell.cpp:95 +#, fuzzy, kde-format +#| msgid "Unable to find the Okular component." +msgid "Unable to find the Okular component: %1" +msgstr "Nem található az Okular objektum." + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "Már fut egy egyedi Okular példány. Ez a példány nem lesz egyedi." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Nem található az Okular objektum." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Kattintson ide fájl megnyitásához\n" +"Kattintson ide és tartsa lenyomva a gombot nemrég használt fájl megnyitásához" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Kattintson ide fájl megnyitásához vagy kattintson ide és tartsa " +"lenyomva a gombot nemrég használt fájl kiválasztásához" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Következő lap" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Előző lap" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, fuzzy, kde-format +#| msgid "*|All Files" +msgid "All files (*)" +msgstr "*|Minden fájl" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Dokumentum megnyitása" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "" + +#: shell/shell.cpp:599 +#, fuzzy, kde-format +#| msgid "Close" +msgid "Close Tabs" +msgstr "Bezárás" + +#: shell/shell.cpp:606 +#, fuzzy, kde-format +#| msgid "" +#| "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Már létezik \"%1\" nevű fájl. Felül szeretné írni?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "" + +#~ msgid "Reviews" +#~ msgstr "Áttekintők" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Az űrlapok elrejtése" + +#~ msgid "Expired" +#~ msgstr "Lejárt" + +#~ msgid "&Review" +#~ msgstr "&Ellenőrzés" + +#~ msgid "Annotations author" +#~ msgstr "A megjegyzések készítője" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Adja meg nevét vagy monogramját:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "A na&vigációs panel megjelenítése" + +#~ msgid "Show Text" +#~ msgstr "A szöveg megjelenítése" + +#~ msgid "Small Icons" +#~ msgstr "Kis ikonok" + +#~ msgid "Normal Icons" +#~ msgstr "Normál ikonok" + +#~ msgid "Large Icons" +#~ msgstr "Nagy ikonok" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Kattintson ide az aktuális kijelölő használatához\n" +#~ "Kattintson ide és tartsa lenyomva a gombot más kijelölő választásához" + +#~ msgid "Created: %1" +#~ msgstr "Létrehozási dátum: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Vonalkiterjesztések" + +#~ msgid "Style" +#~ msgstr "Stílus" + +#~ msgid "&Size:" +#~ msgstr "Mé&ret:" + +#~ msgid "Inner color:" +#~ msgstr "Belső szín:" + +#~ msgid "Name: %1" +#~ msgstr "Név: %1" + +#~ msgid "Size: %1" +#~ msgstr "Méret: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Bön&gésző" + +#~ msgid "&Zoom Tool" +#~ msgstr "Na&gyító" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Nagyító" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Kijelölő" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Szö&vegkijelölő" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Táblázatki&jelölő eszköz" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Nagyító" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "A dokumentum vége" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Nincs" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "A dokumentum bemutatóként fog megnyílni.\n" +#~ "Biztosan ezt szeretné?" + +#~ msgid "Presentation Mode" +#~ msgstr "Bemutató mód" + +#~ msgid "Allow" +#~ msgstr "Engedélyezem" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Bemutató mód engedélyezése" + +#~ msgid "Do Not Allow" +#~ msgstr "Nem engedélyezem" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "A bemutató mód tiltása" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "A megjegyzés változásai nem lesznek automatikusan elmentve. Használja a " +#~ "Fájl -> Mentés másként...\n" +#~ "menüt, különben a változásai elvesznek a dokumentum bezárásakor" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "A megjegyzései az Okularon belül lettek elmentve.\n" +#~ "Exportálhatja a megjegyzéssel ellátott dokumentumot a Fájl -> Exportálás " +#~ "mint > Dokumentumarchívum használatával." + +#~ msgid "Save &Copy As..." +#~ msgstr "Másolat m&entése..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "A megjegyzései nem lesznek exportálva.\n" +#~ "Exportálhatja a megjegyzéssel ellátott dokumentumot a Fájl -> Exportálás " +#~ "mint > Dokumentumarchívum használatával" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "A dokumentum végére ért a keresés.\n" +#~ "Folytatni szeretné a dokumentum elejétől?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "A dokumentum elejére ért a keresés.\n" +#~ "Folytatni szeretné a dokumentum végétől?" + +#~ msgid "Current maintainer" +#~ msgstr "Jelenlegi karbantartó" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " mp." + +#~ msgid "Pencil color:" +#~ msgstr "A ceruza színe:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "fekvő DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "álló DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "fekvő DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "álló DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "fekvő DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "álló DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "fekvő DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "álló DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "fekvő DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "álló DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "fekvő DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "álló DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "fekvő DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "álló DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "fekvő DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "álló DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "fekvő DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "álló DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "fekvő DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "álló DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "fekvő DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "álló DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "fekvő DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "álló DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "fekvő DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "álló DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "fekvő DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "álló DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "fekvő DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "álló DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "fekvő DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "álló DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "fekvő DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "álló DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "fekvő DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "álló DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "fekvő DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "álló DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "fekvő DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "álló DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "fekvő DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "álló DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "fekvő levél" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "álló levél" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "fekvő legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "álló legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "fekvő vezető" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "álló vezető" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "fekvő Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "álló Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "fekvő DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "álló DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "fekvő ívlap" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "álló ívlap" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "ismeretlen fekvő papírméret" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "ismeretlen álló papírméret" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Rajzolás mód" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Nem sikerült elindítani a Jovie szövegfelolvasó szolgáltatást: %1" + +#~ msgid "Search Columns" +#~ msgstr "Oszlop keresése" + +#~ msgid "All Visible Columns" +#~ msgstr "Minden látható oszlop" + +#~ msgid "No document opened." +#~ msgstr "Nincs megnyitva dokumentum." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Nem lehet egynél több dokumentumot megnyitni az egyedi Okular példányban." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Nincs találat: „%1”." + +#~ msgid "Search in progress..." +#~ msgstr "Keresés folyik..." + +#~ msgid "Searching for %1" +#~ msgstr "Keresés: %1" + +#~ msgid "Identity Settings" +#~ msgstr "Az azonosító beállításai" + +#~ msgid "Highlight Properties" +#~ msgstr "A kiemelés tulajdonságai" + +#~ msgid "Ink Properties" +#~ msgstr "A tinta tulajdonságai" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Megjegyzések" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Zöld tinta" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Sárga színű kiemelés" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Sárga színű kiemelés" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Sárga egyenes vonal" + +#~ msgid "Black Underlining" +#~ msgstr "Fekete aláhúzás" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Szöveg aláhúzása fekete vonallal" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Ciánkék ellipszis" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Ciánkék ellipszis" + +#~ msgid "Ink" +#~ msgstr "Tinta" + +#~ msgid "Enable &background generation" +#~ msgstr "A háttérgenerálás bekap&csolása" + +#~ msgid "Reset Forms" +#~ msgstr "Az űrlapok törlése" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Ugrás a dokumentum első oldalára" + +#~ msgid "You must set this name:" +#~ msgstr "Ezt a nevet be kell állítani:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "&Felülírás" + +#~ msgid "Pages:" +#~ msgstr "Oldalszám:" + +#~ msgid "Green Highlighter" +#~ msgstr "Zöld színű kiemelés" diff --git a/po/hu/okular_chm.po b/po/hu/okular_chm.po new file mode 100644 index 0000000..fc15473 --- /dev/null +++ b/po/hu/okular_chm.po @@ -0,0 +1,62 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-12-30 11:15+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Nem támogatott kódolás" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Az e-könyv kódolása nem támogatott még. Küldjön egy hibajelentést a https://" +"bugs.kde.org-on a támogatás hozzáadásához" + +#~ msgid "CHM Backend" +#~ msgstr "CHM modul" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Megjelenítő Microsoft Windows súgófájlokhoz" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "(c) Piotr Szymański, 2005-2007.\n" +#~ "(c) Albert Astals Cid, 2008." + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/hu/okular_comicbook.po b/po/hu/okular_comicbook.po new file mode 100644 index 0000000..e97a506 --- /dev/null +++ b/po/hu/okular_comicbook.po @@ -0,0 +1,61 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2009. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2020-12-30 11:16+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Nem sikerült megnyitni a dokumentumot, sem az „unrar”, sem az „unarchiver” " +"program nem található." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"A telepített „unrar” program nem megfelelő verziójú ComicBook-fájlok " +"kezeléséhez." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Ismeretlen ComicBook-formátum." + +#~ msgid "ComicBook Backend" +#~ msgstr "ComicBook-kezelő" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Megjelenítőmodul különféle képregényformátumokhoz" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "(c) Tobias Koenig, 2007-2008." + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hu/okular_djvu.po b/po/hu/okular_djvu.po new file mode 100644 index 0000000..c9ee1f9 --- /dev/null +++ b/po/hu/okular_djvu.po @@ -0,0 +1,136 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-12-30 11:16+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Szerkesztő" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Kiadó" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Kötet" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Dokumentumtípus" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Ismeretlen" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Összetett fájlok" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Ismeretlen" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Egy oldal" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Kötegelt" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Közvetett" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Kötegelt (régi)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indexelt (régi)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu modul" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu-kezelő a DjVuLibre programkönyvtár felhasználásával." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "(c) Pino Toscano, 2006-2008." + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" diff --git a/po/hu/okular_dvi.po b/po/hu/okular_dvi.po new file mode 100644 index 0000000..3cb92da --- /dev/null +++ b/po/hu/okular_dvi.po @@ -0,0 +1,732 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2010, 2020. +# Balázs Úr , 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.3\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-12-30 11:18+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Nem található a dvipdfm nevű program. Erre a programra " +"szükség van exportálásnál. A nyomtatási funkcióval ugyan minden DVI-fájl " +"átalakítható PDF formátumúvá, de sok esetben a kapott fájl Acrobat Readerben " +"megtekintve gyenge minőségű. Célszerű a TeX lehető legújabb változatát " +"használni, amelyben biztosan megtalálható a dvipdfm program.

Megjegyzés: a programok keresése mindig az elérési útban (PATH változó " +"értéke) történik.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"A fájl exportálását végző „dvipdfm” program hibajelzést adott. A pontos " +"hibaüzenet megtalálható a Fájl menü dokumentumjellemzők " +"ablakában." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Ez a DVI-fájl külső, nem PostScript formátumú grafikus fájlokra " +"hivatkozik, ezeket nem tudja kezelni a dvips program, mely a fájlok " +"kinyomtatását és PostScript formátumú exportálását végzi. A kért funkció " +"ezért nem érhető el az Okular ezen verziójában." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Nem található a dvips nevű program. Erre szükség van " +"exportálási műveletekhez.

Megjegyzés: a program az elérési útban (PATH " +"változó) keresi a programokat.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"A fájl exportálását végző „dvips” nevű program hibajelzést adott. A " +"pontos hibaüzenet a Fájl menü Dokumentumjellemzők ablakában " +"található." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "A DVI-fájl nem preamble résszel kezdődik." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"A DVI-fájl nem kezelhető verziójú DVI-adatokat tartalmaz. Tipp: ha az Omega " +"szerkesztőprogramot használja, speciális megjelenítőre van szükség, például " +"az oxdvi-re." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "A DVI-fájl hibás, nem található a postamble rész." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "A postamble rész nem POST paranccsal kezdődik." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "A postamble rész az FNTDEF-től eltérő parancsot tartalmaz." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "A(z) %1 oldal nem BOP paranccsal kezdődik." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Nem sikerült elindítani a pdf2ps nevű programot, " +"ezért a(z) %1 PDF-fájlt nem sikerült PostScript formátumúra alakítani. " +"Emiatt a dokumentum egyes grafikai elemei esetleg nem jelennek meg.

A hiba lehetséges okai: a pdf2ps program nincs " +"telepítve vagy nem szerepel az elérési útban.

Elhárítási mód: a " +"pdf2ps program általában a Ghostscript csomag része, ezért " +"azt telepíteni kell. Ha az telepítve van, ellenőrizze egy terminálban, hogy " +"a pdf2ps program működik-e.

Elérési út: %2" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

A(z) %1 PDF-fájlt nem sikerült PostScript formátumúra konvertálni, " +"ezért a dokumentum néhány grafikai eleme esetleg nem fog megjelenni.

A hiba lehetséges okai: A fájl (%1) megsérült vagy valójában nem " +"is PDF-fájl. A pdf2ps program kimenete ez volt:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Fájl sérülés. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Nem minden PostScript fájl ágyazható be a dokumentumba. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Minden külső PostScript fájl be lett ágyazva a dokumentumba." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "A megadott „%1” fájl nem létezik." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Arra kérte az Okular programot, hogy keresse meg a DVI-fájlban azt a helyet, " +"amely a(z) %2 TeX-fájl %1. sorának felel meg. Habár úgy tűnik, a DVI-fájl " +"nem tartalmazza a szükséges forrásfájl információkat." + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Az Okular nem volt képes megtalálni azt a helyet a DVI-fájlban, amely a(z) " +"%2 nevű TeX fájl %1. sorának felel meg." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "A DVI-kód ismeretlen betűtípusú karakterre vonatkozik." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "A DVI-kód olyan betűtípusra hivatkozik (#%1), amely nincs definiálva." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "A verem nem volt üres egy EOP utasítás előtt." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "A verem üres volt egy POP utasítás előtt." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "A DVI-kód nem definiált betűtípusra hivatkozik." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Érvénytelen parancs." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Ismeretlen műveletkód: %1" + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Beágyazás: %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"%1. oldal: a PDF-fájlt (%2) nem sikerült PostScript " +"formátumúra alakítani.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "%1. oldal: a PostScript-fájl (%2) nem található.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "A papírméret értékét nem sikerült értelmezni („%1”)." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Az Okular nem volt képes a DVI-fájl megjelenítéséhez szükséges összes " +"betűtípust megtalálni, ezért esetleg a dokumentumot nem lehet olvasni.

ÚTVONAL: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Problémák adódtak a kpsewhich futtatásakor. Ennek " +"eredményeként néhány betűkészlet fájlt nem sikerült megtalálni, és a " +"dokumentumai olvashatatlanok lehetnek.
Lehetséges ok: a kpsewhich program talán nincs telepítve a rendszerre, van nem található a " +"jelenlegi keresési útvonalon.

ÚTVONAL: %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"A kpsewhich megszakította a betűtípus előállítást (kilépési " +"kód: %1, hiba: %2). Ennek eredményeképpen néhány betűtípusfájl nem " +"található, és a dokumentum olvashatatlan lehet." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Betűtípus készítése: %1 (%2 dpi)…" + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Készítő/dátum" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Nem található egy betűtípusfájl" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "álló" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "fekvő" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"A számítógépre telepített Ghostview verziója semmilyen Ghostview " +"eszközmeghajtót sem tartalmaz, amelyet az Okular ismerne. Ezért a PostScript-" +"támogatás ki lesz kapcsolva a programban." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

A Ghostview program, mely a DVI-fájlban levő PostScript formátumú " +"grafikus adatok megjelenítését végzi, több formátumban képes kimenetet " +"készíteni. Ezeket a kimeneti egységeket eszközmeghajtónak nevezik. Minden " +"támogatott, írható formátumhoz tartozik egy eszközmeghajtó. Különböző " +"verziójú Ghostscript programok eltérő eszközmeghajtókat tartalmazhatnak. A " +"telepített Ghostview egyetlen, az Okularral kompatibilis " +"eszközmeghajtót sem tartalmaz.

Nem valószínű, hogy a disztribúció " +"Ghostscript csomagja nem tartalmaz megfelelő eszközmeghajtót, ezért " +"feltehetően valamilyen telepítési hiba történhetett.

A hiba " +"elhárításához adja ki a gs --help parancsot, melynek " +"hatására kiíródnak a tartalmazott eszközmeghajtók. Az Okular a \"png256\", " +"\"jpeg\" és \"pnm\" nevű eszközmeghajtókat tudja kezelni. A PostScript-" +"támogatás csak a program újraindítása után aktiválódik.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "25-nél több hiba történt, nem jelenik meg több hibaüzenet." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Hiba a(z) „%1” nevű DVI-fájlban (%2. oldal). A színverem üres volt egy " +"színre vonatkozó POP művelet előtt." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Hibás paraméter szerepel egy epsf speciális parancsban.\n" +"Lebegőpontos számnak kell következnie %1 után ebben: %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Nem található ez a fájl: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Hiba a(z) „%1” nevű DVI-fájlban (%2. oldal). Nem sikerült értelmezni a " +"szöget egy szövegforgatási műveletben." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Nem támogatott speciális parancs: „%1”." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Hibás betűtípusfájl: %1. Sikerült megnyitni a fájlt, az olvasás is sikerült, " +"de nem támogatott formátumú betűtípust tartalmaz." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Hibás betűtípusfájl: %1. A fájl hibás adatokat tartalmaz vagy megnyitási/" +"olvasási hiba történt." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "FreeType-hiba történt a betűméret beállításakor. Betűtípusfájl: %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"A FreeType nem tudja beolvasni a(z) #%1 karaktert a(z) %2 betűtípusfájlból." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"A FreeType nem tudja megjeleníteni a(z) #%1 karakert a(z) %2 " +"betűtípusfájlból." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "#%1 karakter: üres." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Üres a(z) #%1 karakter a(z) %2 betűtípusfájlban." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"A FreeType nem tudta betölteni a metrikát. Karakter: #%1, betűtípusfájl: %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Nem sikerült megnyitni ezt a betűtípusfájlt: %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: nincs %1 karakter a(z) %2 betűtípusban" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Nem várt %1 a(z) %2 PK-fájlban" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Túl nagy karakter: %1 (fájlnév: %2)" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Hibás számú bit van eltárolva. Karakter: %1, betűtípus: %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Hibás PK-fájl (%1): túl sok bit" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "A betűtípus nem 1:1 arányú " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Nem található betűtípus: %1. Fájlnév: %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Hibás ellenőrző összeg: %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Ismeretlen formátumú betűtípusfájl: %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Végzetes hiba.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Ha nem programhibáról van szó, akkor\n" +"vagy a DVI-fájl vagy a kiegészítő fájlok (virtuális vagy nem virtuális\n" +"betűtípusfájlok) valamelyike feltehetően megsérült.\n" +"A program futása befejeződik. Ha úgy gondolja, hogy programhibát talált,\n" +"vagy nem találja megfelelőnek a hiba kezelési módját, kérjük készítsen\n" +"hibajelentést." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Hibás parancsbájt található a VF makrólistában: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI-modul" + +#~ msgid "A DVI file renderer" +#~ msgstr "DVI-fájlmegjelenítő" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "(c) Luigi Toscano, 2006." + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Szükség van a kpsewhich nevű programra a megfelelő betűtípusok " +#~ "megkereséséhez és a szükséges PK típusú betűtípusok elkészítéséhez.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Bittérképes betűtípusok készítése folyik..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "" +#~ "Megszakítja a betűtípusok készítését (csak indokolt esetben használandó)." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Bittérképes betűtípusok készítése folyik. Ezek szükségesek a dokumentum " +#~ "megjelenítéséhez. A készítés során külső programok (például a MetaFont) " +#~ "is végrehajtódnak. Később a dokumentum tulajdonságablakában " +#~ "megtekinthetők a külső programok üzenetei." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Betűtípusok készítése folyik, egy kis türelmet..." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Betűtípuskészítési állapot" + +#~ msgid "Abort" +#~ msgstr "Állj" + +#~ msgid "What is happening here?" +#~ msgstr "Állapotjelző" + +#~ msgid "%v of %m" +#~ msgstr "%v / %m" + +#~ msgid "Please be patient" +#~ msgstr "Egy kis türelmet" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|PDF-fájl (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Exportálás mint" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Már létezik %1\n" +#~ "nevű fájl, felül szeretné írni?" + +#~ msgid "Overwrite File" +#~ msgstr "A fájl felülírása" + +#~ msgid "Overwrite" +#~ msgstr "Felülírás" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Exportálás PDF formátumban a dvipdfm program segítségével" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "A program PDF formátumúra konvertálja a DVI-fájlt a 'dvipdfm' program " +#~ "használatával. A művelet sokáig eltarthat, mert a dvipdfm létrehozza a " +#~ "szükséges betűtípusokat. Egy kis türelmet..." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "A dvipdfm konvertálóprogram fut..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript-fájl (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Exportálás PostScript formátumban a dvips programmal" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "A DVI-fájl PostScript formátumúvá alakítása folyik a 'dvips' program " +#~ "használatával. A művelet sokáig eltarthat, mert a dvips létrehozza előbb " +#~ "a szükséges betűtípusokat. Egy kis türelmet..." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Program végrehajtása: dvips..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Nem érhető el egy funkció" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Hibás DVI-fájl Nem sikerült feldolgozni ezt a DVI-" +#~ "fájlt, lehet, hogy a fájl megsérült." + +#~ msgid "DVI File Error" +#~ msgstr "DVI fájlhiba" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Nem található minden szükséges betűtípusfájl" + +#~ msgid "Locating fonts..." +#~ msgstr "Betűtípusok betöltése..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Nem található néhány betűtípus" + +#~ msgid "Font generation aborted" +#~ msgstr "A betűtípusok készítése megszakadt" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Exportálás PDF formátumban: %1" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Exportálás PostScript formátumban: %1" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "A betűtípuslista üres." + +#~ msgid "TeX Name" +#~ msgstr "TeX-név" + +#~ msgid "Family" +#~ msgstr "Betűcsalád" + +#~ msgid "Zoom" +#~ msgstr "Nagyítás" + +#~ msgid "Type" +#~ msgstr "Típus" + +#~ msgid "Encoding" +#~ msgstr "Kódolás" + +#~ msgid "Comment" +#~ msgstr "Megjegyzés" + +#~ msgid "TeX virtual" +#~ msgstr "TeX virtuális" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX betűmetrika" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/hu/okular_epub.po b/po/hu/okular_epub.po new file mode 100644 index 0000000..2369093 --- /dev/null +++ b/po/hu/okular_epub.po @@ -0,0 +1,57 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2009. +# Balázs Úr , 2013. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:18+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Hiba történt egy EPub-dokumentum megnyitásakor." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "EPub háttérprogram beállítás" + +#~ msgid "EPub Backend" +#~ msgstr "EPub-megjelenítő" + +#~ msgid "An EPub backend" +#~ msgstr "EPub-kezelő modul" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "Ely Levy, 2008." + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/hu/okular_fax.po b/po/hu/okular_fax.po new file mode 100644 index 0000000..072cbdc --- /dev/null +++ b/po/hu/okular_fax.po @@ -0,0 +1,46 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2009. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:18+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Nem sikerült betölteni a dokumentumot" + +#~ msgid "Fax Backend" +#~ msgstr "Faxkezelő modul" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Kezelőmodul G3/G4 formátumú faxokhoz" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "(c) Tobias Koenig, 2008." + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hu/okular_fictionbook.po b/po/hu/okular_fictionbook.po new file mode 100644 index 0000000..1b96d69 --- /dev/null +++ b/po/hu/okular_fictionbook.po @@ -0,0 +1,82 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Balázs Úr , 2013. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:18+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Nem FictionBook-formátumú a dokumentum" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Nem sikerült megnyitni: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "A dokumentum nem ZIP formátumú" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Érvénytelen dokumentumstruktúra (az alapkönyvtár hiányzik)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Nincs adattartalom a dokumentumban" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Érvénytelen XML-dokumentum: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "FictionBook háttérprogram beállítás" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Kezelőmodul FictionBook-fájlokhoz" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Megjelenítő FictionBook eBook-dokumentumokhoz" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "(c) Tobias Koenig, 2007-2008." + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hu/okular_ghostview.po b/po/hu/okular_ghostview.po new file mode 100644 index 0000000..f6ad7e9 --- /dev/null +++ b/po/hu/okular_ghostview.po @@ -0,0 +1,92 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.3\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:18+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "A platform betűtípusainak használata" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Eldönti, hogy a Ghostscript használni tudja-e a platform betűtípusait. Ha " +"nem, akkor csak a dokumentumba ágyazott betűtípusokat fogja használni." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Általános beállítások" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "A &platform betűtípusainak használata" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Beállítások: Ghostscript-megjelenítő modul" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Dokumentumverzió" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nyelvi szint" + +#~ msgid "PS Backend" +#~ msgstr "PS-kezelő modul" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Megjelenítő PostScript-fájlokhoz." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "(c) Albert Astals Cid, 2007-2008." + +#~ msgid "Based on the Spectre library." +#~ msgstr "A modul a Spectre programkönyvtárra épül." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/hu/okular_kimgio.po b/po/hu/okular_kimgio.po new file mode 100644 index 0000000..f3748ed --- /dev/null +++ b/po/hu/okular_kimgio.po @@ -0,0 +1,70 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2010, 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:19+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Nem sikerült megnyitni ezt a dokumentumot: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"A dokumentum formázása hibásnak tűnik. Itt van a legjobb közelítése a " +"dokumentum szándékolt megjelenésének." + +#~ msgid "Image Backend" +#~ msgstr "Képmegjelenítő modul" + +#~ msgid "A simple image backend" +#~ msgstr "Egyszerű képmegjelenítő" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "(c) Albert Astals Cid, 2005, 2009.\n" +#~ "(c) Pino Toscano, 2006-2007.\n" +#~ "(c) Tobias Koenig, 2006-2007." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Alap eszköztár" diff --git a/po/hu/okular_markdown.po b/po/hu/okular_markdown.po new file mode 100644 index 0000000..3e9ca21 --- /dev/null +++ b/po/hu/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-12-30 11:28+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "A dokumentum megnyitása meghiúsult" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "A Markdown dokumentum fordítása meghiúsult." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "SmartyPants formázás engedélyezése" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Markdown háttérprogram beállítás" diff --git a/po/hu/okular_mobi.po b/po/hu/okular_mobi.po new file mode 100644 index 0000000..49b8bb0 --- /dev/null +++ b/po/hu/okular_mobi.po @@ -0,0 +1,65 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2009. +# Balázs Úr , 2013. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.3\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:20+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Hiba történt a Mobipocket-dokumentum megnyitásakor." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"A könyv jogvédett, csak a jogvédelem kezelésére alkalmas eszközön tekinthető " +"meg." + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Mobipocket háttérprogram beállítás" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket-modul" + +#~ msgid "A mobipocket backend" +#~ msgstr "Egy Mobipocket-modul" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "(c) Jakub Stachowski, 2008-2009." + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/hu/okular_plucker.po b/po/hu/okular_plucker.po new file mode 100644 index 0000000..08b1b9b --- /dev/null +++ b/po/hu/okular_plucker.po @@ -0,0 +1,46 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:20+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Név" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Kezelőmodul Plucker-fájlokhoz" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Megjelenítő Plucker eBook-fájlokhoz" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "(c) Tobias Koenig, 2007-2008." + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/hu/okular_poppler.po b/po/hu/okular_poppler.po new file mode 100644 index 0000000..36af69a --- /dev/null +++ b/po/hu/okular_poppler.po @@ -0,0 +1,227 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2010, 2020. +# Balázs Úr , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-12-30 11:24+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Vékony vonalak növelése:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Nem" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Egyszínű" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Alakzat" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF-beállítások" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Megjegyzések nyomtatása" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Megjegyzések felvétele a nyomtatott dokumentumba" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Megjegyzések felvétele a nyomtatott dokumentumba. Letilthatja ezt, ha az " +"eredeti, megjegyzés nélküli dokumentumot akarja nyomtatni." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Raszterizálás mindig" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Raszterizált kép készítése nyomtatás előtt" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Nyomtatás előtt a program mindenből raszterizált képet készít. Ez néha " +"minőségcsökkenést okoz, de így egyes esetekben kiküszöbölhetők más " +"nyomtatási hibák." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Illesztés a nyomtatási területhez" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Illesztés teljes oldalra" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Nincs; nyomtatás eredeti méretben" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "A nyomtatott oldalak méretezési módja" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Méretezési mód:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formátum" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Titkosított" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Nem titkosított" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Biztonság" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Igen" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimalizált" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "A Poppler %1 használata" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"A Poppler %1 használata\n" +"\n" +"A Poppler %2 verziójával fordítva" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "PDF háttérprogram beállítás" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Nem érhető el" + +#~ msgid "PDF Backend" +#~ msgstr "PDF-kezelő" + +#~ msgid "A PDF file renderer" +#~ msgstr "Megjelenítő PDF-fájlokhoz" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "(c) Albert Astals Cid, 2005-2008." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Fájlok mentése /Encrypt-tel nem támogatott." + +#~ msgid "Unknown" +#~ msgstr "Ismeretlen" + +#~ msgid "Unknown Date" +#~ msgstr "Ismeretlen dátum" + +#~ msgid "Unknown Encryption" +#~ msgstr "Ismeretlen titkosítás" + +#~ msgid "Unknown Optimization" +#~ msgstr "Ismeretlen titkosítás" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Adja meg a jelszót a dokumentum olvasásához:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "A jelszó hibás, próbálja meg még egyszer:" + +#~ msgid "Document Password" +#~ msgstr "Jelszó" diff --git a/po/hu/okular_tiff.po b/po/hu/okular_tiff.po new file mode 100644 index 0000000..e49b892 --- /dev/null +++ b/po/hu/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-12-30 11:28+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" diff --git a/po/hu/okular_txt.po b/po/hu/okular_txt.po new file mode 100644 index 0000000..6f2d785 --- /dev/null +++ b/po/hu/okular_txt.po @@ -0,0 +1,51 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Balázs Úr , 2013. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:25+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Txt háttérprogram beállítás" + +#~ msgid "Txt Backend" +#~ msgstr "Txt háttérprogram" + +#~ msgid "Txt backend." +#~ msgstr "Txt háttérprogram." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© Azat Khuzhin, 2013." + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/hu/okular_xps.po b/po/hu/okular_xps.po new file mode 100644 index 0000000..7bea21f --- /dev/null +++ b/po/hu/okular_xps.po @@ -0,0 +1,58 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Tamas Szanto , 2008. +# Kristóf Kiszel , 2020. +msgid "" +msgstr "" +"Project-Id-Version: KDE 4.2\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2020-12-30 11:25+0100\n" +"Last-Translator: Kristóf Kiszel \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 21.03.70\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Kiszel Kristóf" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "kiszel.kristof@gmail.com" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Verzió" + +#~ msgid "XPS Backend" +#~ msgstr "XPS-megjelenítő modul" + +#~ msgid "An XPS backend" +#~ msgstr "XPS-kezelő" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "(c) Brad Hards, 2006-2007.\n" +#~ "(c) Jiri Klement, 2007.\n" +#~ "(c) Pino Toscano, 2008." + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/hu/org.kde.active.documentviewer.po b/po/hu/org.kde.active.documentviewer.po new file mode 100644 index 0000000..60f5974 --- /dev/null +++ b/po/hu/org.kde.active.documentviewer.po @@ -0,0 +1,72 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Balázs Úr , 2012. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2012-11-09 22:58+0100\n" +"Last-Translator: Balázs Úr \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Könyvjelzők" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Bélyegképek" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Tartalomjegyzék" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Könyvjelzők" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Nincs találat." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Dokumentummegjelenítő a Plasma Aktívhoz az Okular használatával" + +#~ msgid "Reader" +#~ msgstr "Olvasó" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright Marco Martin, 2012." + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Ez a megnyitandó fájl URL-je" diff --git a/po/ia/okular.po b/po/ia/okular.po new file mode 100644 index 0000000..baed491 --- /dev/null +++ b/po/ia/okular.po @@ -0,0 +1,5781 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2014, 2016, 2017, 2020, 2021. +# Marinella , 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2021-01-16 17:39+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, un visor universal de documento" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Mantenitor Precedente" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "" +"Multe travalio sur le structura, ODT e retro administration de FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Developpator" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Creava Okular ex codice basic de KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Developpator de KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Graphica de annotationes" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Instrumento de selection de tabula" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Melioramentos de annotation" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Va a pagina %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Aperi file externe" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Executa '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Prime Pagina" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Pagina Precedente" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Pagina Proxime" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Ultime pagina" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Retro" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Avante" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Quita" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Initia presentation" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Termina presentation" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Trova..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Va a pagina..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Reproduce sono..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script de Javascript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Reproduce film" + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Reproduce film" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stoppa film" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Pausa film" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Resume film" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Selection de retroadministration" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Il trovava plus que un retroadministration pro le typo MIME
%1(%2).

Pro favor inserta qual tu vole usar.
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Plus paginas es %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Vertical %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Orientation horizontal %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Continuante le cerca ab le initio" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Continuante le cerca ab le fundo" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Non poite trovar un plugin que es capace de manear le documento que es " +"passate." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "remove annotationes" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Le documento es essayanteexecutar un appliocation externe e, pro tu " +"securitate, Okular non permitte lo." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "il non trovava alcun application pro aper file de typo mime %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Il non pote aperir un file temporanee" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Il falleve conversion de imprimer" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Processo de imprimer fracassava" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Processo de imprimer non startava" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Il falleva imprimer a un file" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Imprimitor essev in un stato invalide" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Incapace de tovar le file de imprimer" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Il non habeva alcun file de imprimer" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Il non pote trovar un binari convenibile pro imprimer. Tu assecura te que le " +"codice binari lpr de CUPS es disponibile" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Le grandor de pagina de imprimer es invalide" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Non pote aperir '%1': Le file non existe" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titulo" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Subjecto" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Description" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autor" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creator" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Productor" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Paginas" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Create" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificate" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Typo Mime" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Parolas clave" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Percurso de file" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Grandor de file" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Dimension de Pagina" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "adde annotation" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "remove annotation" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "modifica proprietates de annotation" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "traduce annotation" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "adjusta annotation" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "modifica texto" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "modifica contentos de annotation" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "modifica contentos de formulario" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "modifica selectiones de formulario de lista" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "modifica selection de formulario combinate" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "modific statos de button del formulario" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Texto simplice..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Texto de OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Optiones de imprimer" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Adapta a area imprimibile" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Adapta a pagina complete" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de scalar:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Mancante typo de alerta" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Non monstra iste message de nove" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Fonte: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Font pre&definite:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rubie" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Orange" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Jalne" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verde" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Cyano" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blau" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Blanco" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Gris" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Nigre" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Latitude %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Largessa de linea de annotation 8nulle annotation seligite)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Color de Annotation (nulle annotation seligite)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Color de reimpler de Annotation (nulle annotation seligite)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacitate de annotation (nulle annotation seligite)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Font de Annotation (nulle annotation seligite)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Adde le annotation currente al menu de annotationes rapide (Nulle annotation " +"selectionate)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Constringe rata de forma a 1:1 o angulo de linea a passos de 15° (Nulle " +"annotation selectionate)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Preferentias avantiate per le instrumento de annotation currente (nulle " +"annotation seligite)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Largessa de linea de annotation " + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Largessa de linea de annotation (annotation non ha largessa de linea)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Color de texto de annotation " + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Color de bordo de annotation " + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Color de annotation " + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Color de reimpler de annotation" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Color de reimpler de annotation (Annotation currente non ha color de " +"reimpler)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Font de annotation" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Font de reimpler de annotation (Annotation currente non ha font)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Constringe angulo de linea a passos de 15° " + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Constringe rata de aspecto 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Constringe rata de forma 1:1 o angulo de linea a passos de 15° (Non " +"supportate per annotation currente)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacitate de annotation" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Adde le annotation currente al menu de annotationes rapide" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Preferentias avantiate per le instrumento de annotation currente" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Color" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Reimple Color" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparente" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Color personalisate..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"timpros isertate in documentos PDF non es visibile in lectores PDF altere " +"que Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Characteristica Experimental" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Selectiona Color" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotationes" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Cela" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Evidentiator" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Sublinea" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Linea a serpentin" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Strike Out" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Mono-spatio" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota in linea" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota de popup" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Linea a mano libere" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Linea recte" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Flecha" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rectangulo" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Polygono" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Formas geometric" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Timbro" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Annotationes rapide" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Selige un instrumento de annotation ex le annotationes rapide" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Adde a annotationes rapide" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantene active" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantene le instrumento de annotation active postea usage" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Instrumentos de annotationes d constringer ratio e angulo" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Font" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Preferentias de annotation" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Largessa de linea" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacitate" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Pagina %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotation" +msgstr[1] "%1 Annotationes" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Aperi un nota de popup" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Dele" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Proprietates" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Salveguarda '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Apparentia" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&General" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autor:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Create:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificate:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Proprietates de nota de popup" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Proprietates de Typewriter" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Proprietates de nota in linea" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Proprietates de linea recte" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Proprietates de polygono" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Proprietates de geometria" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Proprietates de marcation de texto" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Proprietates de timbro" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Proprietates de linea a mano libere" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Proprietates del signo de omission (caret)" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Proprietates de attachamento de file" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Proprietates de sono" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Proprietates de film" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Proprietates de annotation" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificate: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Selig un symbolo de timbro personalisate ex file" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Selige un symbolo de timbro personaliste" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Non poteva cargar file %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "File invalide" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Color:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacitate:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icone:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Commento" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Adjuta" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Inserta" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Clave" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nove paragrapho" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragrapho" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Font:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Color de texto :" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Alinea :" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Sinistra" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Al centro" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Dextera" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Largessa de &bordo:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Approbate" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Como es" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidential" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departimental" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Version provisori" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Pro commento" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Pro liberation public" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Non approbate" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Non pro liberation public" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Vendite" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Secrete Maxime" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Marcator de libro" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Information" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"characteristica experimental.Timbros isertate in documentos " +"PDF non es visibile in lectores PDF altere que Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Symbolo de timbro:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "Lar&gessa:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Initio de Linea:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Fin de Linea" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Quadrato" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Circulo" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamante (Quadro)" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Aperi flecha" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Flecha claudite" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Necun" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Botte (Butt)" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Flecha aperite dextere" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Flecha claudite dextere" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra oblique" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Longitude de linea principal:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Longitude de extensiones de linea principal:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Habilitate" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Reimple forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Typo:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Evidentia" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Linea a serpentin" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Sublinea" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Strike Out" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rectangulo" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellipse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Symbolo de attachamento de file:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graphico" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Spinula de premer" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Crampa de papiro" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etiquetta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "File" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "n/d" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Nulle description disponibile." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nomine:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Description:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Symbolo de omission (caret):" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Necun" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Claude iste nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Optiones" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Iste annotation pote continer codice LaTeX.\n" +"Pulsa hic pro render lo." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Non pote trovar executabile de latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Il falleva render LaTeX" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Non pote trovar executabile de dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Un problema occurreva durante que on executava le commando 'latex'." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Un problema occurreva durante que on executava le commando 'dvipng'." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Un marcator de libro" +msgstr[1] "" +"%1\n" +"\n" +"%2 marcatores de libro" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Marcatores de libro" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Il cerca ..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Solmente documento currente" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Va a iste marcator" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Renomina marcator de libro" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Remove iste marcator de libro" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Aperi documento " + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Remove marcatores de libro" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Version" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Numero serial" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emettitor" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emittite le" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Termina le" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Subjecto" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Clave public" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Uso de Clave" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bits)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Proprietate" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valor" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Certifica Visor" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Exporta..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "General" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emittite per" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nomine commun (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "E-posta" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organization (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emittite a" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validitate" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Impressiones digital" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Impression digital SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Impression digital SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Detalios" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Datos de certificato:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Ubi tu vole salveguardar iste certificato?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "File de Certificato (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Non poteva exportar le certificato" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rubie" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verde" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blau" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Jalne" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Nigre" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Blanco" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Designa bordo circa &imagines" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Designa bordo circa &ligamines" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Cambia &colores" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Aviso: iste optiones pote afficer de mal modo le velocitate de designar." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Modo de color:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverte colores" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Cambia color de papiro" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Cambia colorer Obscur & Clar" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Converte in blanco & nigre" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Inverte brillantia" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Inverte nitor (Luma) (sRGB Linear)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Inverte nitor (Luma) (Symmetric)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Displacia Tinta Positive" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Displacia Tinta Negative" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Color de papiro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Color obscur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Color clar:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Limine:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contrasto:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Voce" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motor" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitate" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tor:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota: Le information hic es usate solmente pro annotationes. Le " +"information es salveguardate in documentos annotte, e assi essera " +"transmittite insimul le documento." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Instrumentos de annotation rapide" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor de texto personalisate" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Cliente de Emacs" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Cliente de Lyx" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Fixa le commando de un editor de texto personalisate que on debe lancear." +"
\n" +"Tu anque pote poner alcun substitutos:\n" +"
    \n" +"
  • %f - le nomine de file
  • \n" +"
  • %l - le linea del file que on debe attinger
  • \n" +"
  • %c - le columna del file que on debe attinger
  • \n" +"
\n" +"Si %f non es specificate, alora le nomine de file es appendite al commando " +"specificate." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Selige le editor que tu vole lancear quando Okular vole aperir un file de " +"fonte." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Commando:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Apparentia" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Usa Rolar lisie" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Monstra &barras de rolar" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Liga le minia&turas con le pagina" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Monstra &insinuationes e messages de information" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Monstra titulo de documento in l ebarra de titulo, si disponibile" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Quando non monstrante titulo de documento:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Monstra solmente nomine de file" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Monstra percurso complete de file" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usa color de fundo personalisate" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Characteristicas de programma" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Aperi nove filess in sc&hedas" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Displacia a scheda existente si ja aperite" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Obedi a restrictiones de DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Recarga le documento quando on modifica le file" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Monstra le dialogo de selection de retroadministration" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Direction de lectura ex dextra a sinistra" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Optiones de vista" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Vision de juncto de &columnas" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Il define quanto del area de vision currente ancora essera visibile quando " +"on pressa le clave de Pagina in Alto/Pagina a Basso." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Imbrication de &Pagina in alto/Pagina a basso:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Il define le modo de zoom predefinite pro file que jammais esseva aperite " +"ante.\n" +"Pro files que esseva aperite ante il applica le previe zoom." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Il define le modo de zoom predefinite pro file que jammais esseva aperite " +"ante.\n" +"Pro files que esseva aperite ante il applica le previe zoom." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Zoom predefinite:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Adapta in largessa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Adapta al pagina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Adjusta automaticamente" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Il mantene le memoria usate le plus basse possibile. No reusa alcun cosa " +"(pro systemas con basse memoria)." + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un bon compromisso inter usage de memoria e ganio de velocitate. Precarga " +"proxime pagina e stimula cercas (typicamente pro systemas con memoria de " +"2GB)." + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Mantene toto in memoria. Precarga proxime paginas. Stimula cercas (pro " +"systemas con un memoria de plus que 4GB)." + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carga e mantene toto in memoria. Precarga omne paginas (il usara al maximo " +"le 50% de tu memoria tortal o de tu memoria libere, qualcunque grande illo " +"es)." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Uso de CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Habilita effectos de &trasnparentia" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Uso de Memoria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Basse" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (predefinite)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Aggr&essive" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "A&vide" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Rendition" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Habilita antialias de texto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Habilita antialias de graphiches" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "habilita insinuar de texto" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Schermo currente" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Schermo predefinite" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Schermo %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " secunda" +msgstr[1] " secundas" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigation" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avantia cata:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Anella post le ultime pagina" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navigation per Touch:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Tocca latere sinistre/dextere per vader retro/avante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Tocca ubique per vader avante" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Dishabilitate" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Color de fundo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Cursor de mus:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Celate post retardo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Sempre visibile" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Sempre celate" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Monstra indicator de &progresso" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "onstra pagina de s&ummario" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Habilita transitiones" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transitione predefinite:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Cortinas vertical" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Cortinas horizontal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Restringe (Box in)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Expande (Box out)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dissolve" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Distinger" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Reluce a basso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Reluce in alto" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Reluce a dextere a basso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transition casual" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Reimplacia" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Divide horizontalmente (Split in)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Divide horizontalmente (split out)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Divide verticalmente (split in)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Divide verticalmente (split out)" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Netta a basso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Netta a dextera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Netta a sinistra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Netta in alto" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Placiamento" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Schermo:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configuration deinstrumento de designar" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Instrumento de designar: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Eradicator" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nomine:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Typo:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota de popup" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota in linea" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Linea a mano libere" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Linea recte" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Polygono" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Marcation de texto" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geometric" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Timbro" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Mono-spatio" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Crea instrumento de annotation" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Modifica instrumento de annotation" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Color:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Largessa de &Pluma:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr "px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Crea instrumento de designar" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Modifica instrumento de designar" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Incognite" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Files incorporate" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Vista" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nomine" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Description" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Dimension" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Create" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificate" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Salveguarda como..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Vista" + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Il non pote cargar le parte de le vista preliminari de impression" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Vista preliminari de imprimer" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Claude" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "Tro&va:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Texto de cercar" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Proxime" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Salta al proxime objecto coincidente" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Precedente" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Salta al previe objecto coincidente" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modificar comportamento de cerca" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Sensibile al differentia inter majusculas e minusculas" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Ex le pagina currente" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Trova durante que tu typa" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Omne Files" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Proprietates del signatura" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Linea recte con commento" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Polygono con commento" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Gometria con commento" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Evidentia con commento" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Squiggle con commento" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Sublinea con commento" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Strike Out con commento" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Strike Out" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Timbro con commento" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Linea a mano libere con commento" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Symbolo de omission (caret)" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Attachamento de file" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Sono" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Film" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Schermo" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Widget" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rich Media" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Incognite" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autor: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Ubi tu vole salveguardar %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Non pote aperir \"%1\" pro scriber. Le file non esseva salveguardate." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Optiones de cerca" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Sensibile al differentia inter majusculas e minusculas" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Expression Regular" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "C&erca:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Stratos o layers" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "de" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Exeque zoom a 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rota a &dextera" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Dextera" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rota a &sinistra" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Sinistra" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientation original" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Vista de pu&tar" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Tonde margines" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Putar a &Selection" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Adapta in &largessa" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Adapta al &pagina" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Adjusta automaticamente" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Adapta Fe&nestra a Pagina" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Modo de &Vider" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Pagina &singule" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Paginas &flancate" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Paginas flancate (prime pagina al ¢ro)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Vision de &juncto" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continue" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Usa direction de lectura ex dextra a sinistra" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Naviga " + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom (aggrandir)" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Commu&ta Cambia colores" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selection de Area" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selection de &Texto" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selection de T&abula" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Aggranditor" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Instrumentos de selection" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Pronuncia le documento complete" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Pronuncia le pagina currente" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Stoppa pronunciar" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Pausa/Restabili Pronunciar" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Rola in alto" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Rola a basso" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Rola pagina in alto" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Rola pagina a basso" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Monstra formularios" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Cargate un documento de un pagina." +msgstr[1] " Cargate un documento de %1-paginas" + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Texto(1 character)" +msgstr[1] "Texto(%1 characteres)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copia in area de transferentia" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Copia prohibite per DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Pronuncia texto" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Imagine (%1 per %2 pixeles)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Salveguarda a File..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Imagine [%1x%2] copiate in area de transferentia." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Salveguarda file" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Images (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "File non salveguardate." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Imagine [%1x%2] salveguardate in file %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copia texto" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Va a '%1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Cerca de '%1' con" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configura vias breve de Web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Seque iste ligamine" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Reproduce iste sono..." + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Stoppa sono" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copia adresse de ligamine" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Cerca de '%1' in iste documento" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Benvenite" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Selige area de zoom. Pulsa a dextere pro aggrandir." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Pulsa pro vider le vista aggrandite." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Designa un rectangulo circa le texto/graphiches de copiar." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Selectiona texto" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Designa un rectangulo circa le tabula, post pulsa bordos vicin pro divider; " +"pressa Esc pro nettar." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Designa un rectangulo circa le area de pagina que tu vole mantener visibile" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nove nota de texto" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Texto del nove nota" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Annotation de marcator de libro" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Inserta un nomine personalisate per le annotation:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Designa un ellipse (trahe pro seliger un zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Evidentia texto" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Designa un linea a mano libere" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Annotation de texto in linea (trahe pro seliger un zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Mitte un nota de popup" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Designa un polygono (pulsa sur le prime puncto pro clauder lo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Designa un rectangulo" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Texto a serpentin" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Placia un symbolo de timbro" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Designa un linea recte" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Pone le texto in Strike Out" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Sublinea texto" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Annotation de texto in linea (Typewriter) (trahe pro seliger un zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Evidentiator" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Adde annotation favorite" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nomine personalisate de annotation:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&File" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Preferentia&s" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "Ad&juta" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientation" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "Marcatores de li&bro" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "barra de instrumento de visor" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniaturas" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotationes" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Iste documento contine annotationes o datos de formulaio que essera " +"salveguardate internemente per un previe version de Okular. Immagazinage " +"interne es non plus supportate.
Pro favor salveguarda a un file " +"per mover los si tu vole continuar a modificar le documento." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Isto documento ha files incorporate. Pulsa " +"ci pro vider los o va a File->Files Incorporate." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Precedente" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Va retro al pagina previe" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Il move al pagina precedente del documento" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Proxime" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Avantia al proxime pagina" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Il move al pagina proxime del documento" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Initio del documento" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Move al initio del documento" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Fin del documento" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Move al fin del documento" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Renomina le marcator currente" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Previe marcator de libro" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Va al previe marcator de libro" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Proxime marcator de libro" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Va al proxime marcator de libro" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configura Okular ..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configura visor..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configura retroadministrationes de visor..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configura retroadministrationes..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Re retroadministration" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "Recar&ga" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Recarga le documento currente ex le disco." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Claude barra de &trovar" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Numero de Pagina" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Selige omne texto sur le pagina currente" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Monstra barra &lateral" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Monstra barra de &pagina" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Monstra pannello de &Signaturas" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "Files incorporat&e" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "E&xporta como" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "I&mparti" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentation" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Aperi dossier con&tinente" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importa PostScript como PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Obtene libros ex internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Commuta modo de schermo nigre" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Rade designos" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configura annotationes..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Reproduce/Pausa Presentation" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Non pote aperir \"'%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Le cargamento de %1 ha essite cancellate." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Non pote aperir %1: Motivo: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configura retroadministrationes de visor" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configura retroadministrationes" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Le programma \"ps2pdf\"non esseva trovate, dunque Okular non pote importar " +"files PS per usar illo." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf non trovate" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "Files PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Importante file PS como PDF (isto pote prender del tempore)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Pro favor inserta le contrasigno per leger le documento:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Contrasigno incorrecte. Essaya de nove:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Contrasigno de documento" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Isto documento ha formularios XFA, que currentemente non es supportate." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Isto documento ha formularios. Pulsa sur le button pro interager con illos, " +"o usa Vista->Monstra formularios." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Omne characteristicas interactive e de modificar per iste documento es " +"dishabilitate. Pro favor salveguarda un copia e reaperi per modificar iste " +"documento." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Iste documento es signate digitalmente." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Iste documento es signate digitalmente. Il ha essite modificationes usque le " +"ultime signate." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Iste documento es signate digitalmente. Alcun del signaturas poteres non " +"esser validate propriemente." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Iste documentovole esser monstrate a schermo plen.\n" +"Lassa modo normal e inserta modo de presentation?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Requesta per cambiar modo de vider" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Inserta modo de presentation" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Nega requesta" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Non pote aperir %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Il ha modificationes non salveguardate, e le file '%1' ha essite modificate " +"per un altere programma. Tu modificationes essera perdite, proque le file " +"pote non jam esser saveguardate.
Tu vole continuar a recarcar iste file?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "File modificate" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continua recargar" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Abandona recargar" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Il ha modificationes non salveguardate, e le file '%1' ha essite modificate " +"per un altere programma. Tu modificationes essera perdite, proque le file " +"pote non jam esser salveguardate.
Tu vole continuar a clauder le file? " + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continue cluder" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Abndona clauder" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Tu vole salveguardar tu modificationes \"%1\" o annullar los?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Claude documento" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Isto ligamine puncta a un action de clauder documento que non functiona " +"quando on usa le visor incorporate." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Isto ligamine puncta a un action de clauder application que non functiona " +"quando on usa le visor incorporate." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Recargante le documento..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contentos" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Signaturas" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Va a pagina" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Pagina:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Inserta le nove nomine del marcator de libro:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Renomina iste marcator de libro" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Remove iste marcator de libro" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Salveguarda como" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Le file '%1' ha essite modificate per un altere programma, que significa que " +"illo non pote plus esser salveguardate." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Le documento currente es protegite con un contrasigno.
Pro " +"salveguardar, le file necessita esser recargate. Tu essere demandate de novo " +"de contrasigno e tu chronologia de annullar/refacer essera perdite,
Tu " +"vole continuar?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Salveguarda - Aviso" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Il nonpote aperir le file temporanee pro salveguardar." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Postea salveguardar, le formto de documento currente require que le file es " +"recargate. Tu chronologia de annullar/refacer essera perdite.
Tu vole " +"continuar?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"File non poteva esser salveguardate in '%1'. Essaya salveguardar lo in un " +"altere location." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contentos de formulario plene" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Annotationes de usator" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Tu es per salveguardar modificationes, ma le formato de file currente non " +"supporta salveguardar le elementos sequente. Pro favor usa le formato de " +"archivo de docuento de Okular per preservar los." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Aviso" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Salveguarda como archivo de documento de Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Tu es per salveguardar modificationes, male formato de file currente non " +"supporta salveguardar le elementos sequente. Pro favor usa le formato " +"archivo de documento de Okular per preservar los. Pulsa Continua per salveguardar le documento e abandona iste elementos." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Tu es per salveguardar mdificationes, ma le formato de file currente non " +"supporta salveguardar le elementos sequente. Pro favor usa le formato " +"archivo de documento de Okular per preservar los. Pulsa Continua per salveguardar, ma tu perdera tanto iste elementos como le chronologia " +"de annullar/refacer." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continua" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continua perder modifiationes" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "File non poteva esser salveguardate in '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okula non pote copiar %1 in location specificate.\n" +"\n" +"Le documento non existe plus." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"File non poteva esser salveguardate in '%1'. Error: '%2' .Essaya " +"salveguardar lo in un altere location." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Expande complete section" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Plica section integre" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Expande omne" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Plica omne" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Adde marcator de libro" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Instrumentos" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Imprime" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Il non es permittite imprimer iste documento." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Non pote imprimer le documento. Error incognite. Pro favor tu reporta le " +"falta a bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Non pote imprimer le documento Error detaliate es \"%1\". Pro favor tu " +"reporta le falta a bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Vade al placia ubi tu esseva ante" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Vade al placia ubi tu esseva post" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Error de File! Non pote crear file temporanee " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Error de File! Non pote aperir le file " +"%1 pro decomprimer lo. Le file non essera cargate." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Iste error typicamente occurre si tu non ha assatis permissiones pro " +"leger le file. Tu pote verificar tu permissiones e proprietate si tu pulsa " +"con le clave dextere sur le file in le gerente de file Dolphin e post selige " +"le scheda de \"Proprietates\" e selige le scheda 'Permissiones' in le " +"fenestra aperite" + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Error de File! Nonn pote decomprimer le file " +"%1. Le file non essera cargate." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Iste error typicamente occurre si le file es corrumpite. Si tu vole " +"esser secur, essaya decomprimer le file manualmente per usar le instrumentos " +"de commando de linea." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Necun marcator de libros" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Il ha un problema a impartir le documento: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Impartir" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Documento impartite con successo" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Tu pote trovar le documento impartite in: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Edita" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Vide" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Vade" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Ins&trumentos" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra de instrumento principal" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barra de Instrumentos de Annotation" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Optiones General" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibilitate" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Auxilios de lectura pro accessibilitate" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Prestation" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Syntonisation de prestation" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configura visor" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentation" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Optiones pro modo de presentation" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Optiones de annotation" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Optiones de editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Trova proxime" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentation" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Commuta schermo" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Schermo %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Termina modo de presentation" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titulo: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Paginas: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Pulsa pro initiar" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Pausa" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Reproduce" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Il ha duo modos pro exir del modo de presentation, tu pote pressar o le " +"clave de ESC o pressa le button de abandonar que appare quando on placia le " +"mus in le angulo in alto a dextera. Naturalmente tu pote cyclar fenestras " +"(Alt+TAB como modo predefinite)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Da un presentation" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "File incognite" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Proprietates" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Fonts" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Legente information de font..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Dimensiones de &Pagina" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extrahe font" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Typo 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Typo 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Typo 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Typo 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Metric de Font de TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX maneate per Typo libere " + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Incognite" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Incorporate (subinsimul)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Completemente incorporate" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Si(subinsimul)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Si" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (substituente con %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Font incognite" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Incorporate: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nomine" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Typo" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "File" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Pagina" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Dimension" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Vista preliminari de revision" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Ubi tu vole salveguardar iste revision?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Il non pote salveguardar file '%1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Non pote vider iste revision." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Inserta al minus 3 litteras pro filtrar paginas" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Sensibile al differentia inter majusculas e minusculas" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Phrase in correspondentia" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Omne parolas in correspondentia" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Ulle parolas in correspondentia" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Optiones de filtro" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Nulle annotationes

Pro crear nove annotationes " +"pressa F6 o selectiona Instrumentos -> Annotationes ex le menu." + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Gruppa per pagina" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Gruppa per autor" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Monstra annotationes solmente pro pagina currente" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Expande omne elementos" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Plica omne elementos" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Le signatura es cryptographicamente valide." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Le signatura es cryptographicamente invalide." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Il occurreva un discrepantia de summario." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Le structura de signatura CMS/PKCS7 es malformate." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Le requirite signatura non es presente in le documento." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Le signatura non poteva esser verificate." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Certificato es digne de fide." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Emissor de certificato non es digne de fide." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Emissor de certificato es incognoscite" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Certificato ha essite revocate." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Certificato ha expirate." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Certificato ancora non ha essite verificate." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Emissor incognoscite con Certificato o datos corrumpite." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algoritmo incognite" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Typo incognite" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Signatura digital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non-Repudiation" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Crypta claves" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "DEcrypta claves" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Accordo de clave" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Signa certificato" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Signa CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Crypta solmente" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Nulle uso specificate" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Signate per %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Tempore de signar: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Non disponibile" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Motivo: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Campo:%1 sur pagina %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Proprietates" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Le documento non ha essite modificate proque illo esseva signate." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Le revisione del documento que esseva coperite per iste signatura non ha " +"essite modificate;\n" +"totevia il ha essite modificationes subsequente al documento." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Le documento ha essite modificate in un modo non permittite per un previe " +"signator." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" +"Le veification de integritate del documento non poteva esser completate." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Stato valide" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validitate de signatura:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modificationes de documento:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Information additional" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Signate per :" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Tempore de signar:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Motivo:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Location:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Version de documento" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revision de documento %1 de %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Vide version signate..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Vide certificato..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Monstra solmente paginas que es ponite in marcatores de libro" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Reproduce" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Pausa" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stoppa" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Adde..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Edita..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Remove" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Move in &alto" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Move a &basso " + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Instrumento de designar predefinita: #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "In ha ja un instrumento con illo nomine. On usa lo que es predefinite" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nomine duplicate" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Pagina del documento que on debe monstrar" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Initia le documento in modo de presentation" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Initia con dialogo pro imprimer" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Initia con dialogo pro imprimer e abandona post imprimer" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Controlo de \"Instantia unic\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Non altia fenestra" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Trova una catena sur le texto" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Documento de aperir. Specifica '-' pro leger ex stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Error: Il non pote aperir plus que un documento con le commutator --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: Il non pote aperir plus que un documento con le commutator --" +"presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Error: Il non pote aperir plus que un documento con le commutator --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" +"Error: Il non pote aperir plus que un documento con le commutator --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" +"Error: Il non pote aperir plus que un documento con le commutator --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Incapace de trovar le componente de Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Il ha ja un unic instantia de Okular executante. Iste instantia non essera " +"le unic." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Incapace de trovar le componente de Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Pulsa pro aperir un file\n" +"Pulsa a mentene pro aperir un file recente" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Pulsa pro aperir un file o Pulsa e mentene pro seliger un file " +"recente" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Proxime scheda" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Previe scheda" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Annulla operation de clauder scheda" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Omne files (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Omne files supportate (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Aperi documento " + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Confirma Clausura" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Claude schedas" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Tu es per clauder %1 schedas. Tu es secur que tu vole continuar?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Adverte me quando on cerca clauder multiple schedas" + +#~ msgid "Reviews" +#~ msgstr "Revisiones" + +#, fuzzy +#~| msgid "V%1" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "V%1" + +#~ msgid "Hide Forms" +#~ msgstr "Cela formularios" + +#~ msgid "Expired" +#~ msgstr "Expirate" + +#~ msgid "&Review" +#~ msgstr "&Revide" + +#~ msgid "Annotations author" +#~ msgstr "Autor de annotation" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Pro favor inserta tu nomine o initiales:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Monstra pannello de &navigation" + +#~ msgid "Show Text" +#~ msgstr "Monstra texto" + +#~ msgid "Small Icons" +#~ msgstr "Icones parve" + +#~ msgid "Normal Icons" +#~ msgstr "Icones normal" + +#~ msgid "Large Icons" +#~ msgstr "Icones grande" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Pulsa pro usar le instrumento de selection currente\n" +#~ "Pulsa sur le flecha pro seliger un altere instrumento de selection" + +#~ msgid "Created: %1" +#~ msgstr "Create: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Extensiones de linea" + +#~ msgid "Style" +#~ msgstr "Stilo" + +#~ msgid "&Size:" +#~ msgstr "Dimen&sion:" + +#~ msgid "Inner color:" +#~ msgstr "Color Interne:" + +#~ msgid "Name: %1" +#~ msgstr "Nomine: %1" + +#~ msgid "Size: %1" +#~ msgstr "Dimension: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Instrumento de &navigation" + +#~ msgid "&Zoom Tool" +#~ msgstr "Instrumento de &Zoom" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Selection" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Instrumento de selection de &Texto" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Instrumento de selection de t&abula" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Aggranditor" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Fin del documento" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Necun" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Le documento requiriva esser lanceate de modo presentation.\n" +#~ "Tu vole permitter lo?" + +#~ msgid "Presentation Mode" +#~ msgstr "Modo de presentation" + +#~ msgid "Allow" +#~ msgstr "Permitte" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Permitte l emodo de presentation" + +#~ msgid "Do Not Allow" +#~ msgstr "Non permitte" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Non permitte le modo de presentation" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Tu cambios de annotation non essera salveguardate automaticamente. Usa " +#~ "File-> Salveguarda como..\n" +#~ "O tu modificationes essera perdite un vice que le deocumento es claudite." + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Tu annotationes es salveguardate internemente per Okular.\n" +#~ "Tu pote exportar le documento annotate per usar File -> Exporta como -> " +#~ "Archivo de documento" + +#~ msgid "Save &Copy As..." +#~ msgstr "Salveguarda &Copia como..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Tu annotationes non essera exportate.\n" +#~ "Tu pote exportar le documento annotate per usar File -> Exporta como -> " +#~ "Archivo de documento" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Fin de documento attingite.\n" +#~ "On continua ab le initio?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Initio de documento attingite.\n" +#~ "On continua ab le fin?" + +#~ msgid "Current maintainer" +#~ msgstr "Mantenitor Currente" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymański" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio d'Urso" + +#~ msgid " sec." +#~ msgstr "sec." + +#~ msgid "Pencil color:" +#~ msgstr "Color de stilo:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "horizontal (landscape) DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "vertical (portrait) DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "horizontal (landscape) DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "vertical (portrait) DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "horizontal (landscape) DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "vertical (portrait) DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "horizontal (landscape) DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "vertical (portrait) DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "horizontal (landscape) DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "vertical (portrait) DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "horizontal (landscape) DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "vertical (portrait) DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "horizontal (landscape) DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "vertical (portrait) DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "horizontal (landscape) DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "vertical (portrait) DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "horizontal (landscape) DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "vertical (portrait) DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "horizontal (landscape) DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "vertical (portrait) DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "horizontal (landscape) DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "vertical (portrait) DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "horizontal (landscape) DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "vertical (portrait) DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "horizontal (landscape) DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "vertical (portrait) DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "horizontal (landscape) DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "vertical (portrait) DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "horizontal (landscape) DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "vertical (portrait) DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "horizontal (landscape) DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "vertical (portrait) DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "horizontal (landscape) DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "vertical (portrait) DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "horizontal (landscape) DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "vertical (portrait) DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "horizontal (landscape) DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "vertical (portrait) DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "horizontal (landscape) DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "vertical (portrait) DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "horizontal (landscape) DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "vertical (portrait) DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "horizontal (landscape) littera" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "vertical (portrait) littera" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "horizontal (landscape) legal" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "vertical (portrait) legal" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "horizontal (landscape) executive" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "vertical (portrait) executive" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "horizontal (landscape) Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "vertical (portrait) Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "horizontal (landscape) DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "vertical (portrait) DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "folio horizontal (landscape)" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "folio vertical (portrait)" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "libro major" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "grandor de papiro horizontal (landscape) incognite" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "dimension de papiro vertical (portrait) incognite" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Commuta modo de designar" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Il falleva a initiar le servicio texto-a-Voce Jovie: %1" + +#~ msgid "Search Columns" +#~ msgstr "Cerca columnas" + +#~ msgid "All Visible Columns" +#~ msgstr "Tote le columnas visibile" + +#~ msgid "No document opened." +#~ msgstr "Necun documento aperite" + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Il non pote aperir plus que un documento in le instantia de unic de " +#~ "Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Necun Objecto equal trovate pro '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Cerca in progresso..." + +#~ msgid "Searching for %1" +#~ msgstr "Cercante %1" + +#~ msgid "Identity Settings" +#~ msgstr "Preferentias de identitate" + +#~ msgid "Highlight Properties" +#~ msgstr "Proprietates de evidentiation" + +#~ msgid "Ink Properties" +#~ msgstr "Proprietates de tinta" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Annotation de texto" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Tinta verde" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Evidentiator jalne" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Evidentia in jalne" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Linea jalne recte" + +#~ msgid "Black Underlining" +#~ msgstr "Sublinea nigre" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Sublinea le texto con un linea nigre" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Ellypse Azur" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Un ellipse azur" + +#~ msgid "Ink" +#~ msgstr "Tinta" diff --git a/po/ia/okular_chm.po b/po/ia/okular_chm.po new file mode 100644 index 0000000..9a89602 --- /dev/null +++ b/po/ia/okular_chm.po @@ -0,0 +1,61 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-05-10 21:10+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codification non supportate" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"Le codification de iste ebook non es jam supportate. Pro favor aperi un bug " +"in https://bugs.kde.org nam supporto debe eser addite" + +#~ msgid "CHM Backend" +#~ msgstr "Retro-Administration de CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Un rendition de file de adjuta de Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/ia/okular_comicbook.po b/po/ia/okular_comicbook.po new file mode 100644 index 0000000..d9eed50 --- /dev/null +++ b/po/ia/okular_comicbook.po @@ -0,0 +1,59 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +# Marinella , 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2019-09-27 10:26+0100\n" +"Last-Translator: Marinella \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Non pote aperir documento, il non trovava ni unrar ni unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Le version de unrar sur tu systema non es convenibile pro aperir libros de " +"comic" + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Formato incognite de libros de comic" + +#~ msgid "ComicBook Backend" +#~ msgstr "Retro-Administration de libros de comic" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un rendition pro varie formatos de libros comic" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ia/okular_djvu.po b/po/ia/okular_djvu.po new file mode 100644 index 0000000..0a857fb --- /dev/null +++ b/po/ia/okular_djvu.po @@ -0,0 +1,135 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2013-02-07 10:35+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Editor (Publisher)" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Tomo" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Typo de documento" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Incognite" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Files de componente" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Incognite" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Pagina singule" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Impacchettate" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indirecte" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Impacchettate(vetere)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indicisate (vetere)" + +#~ msgid "DjVu Backend" +#~ msgstr "Retro-Administration de DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Retro-Administration de DjVu basate sur DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Incognite" diff --git a/po/ia/okular_dvi.po b/po/ia/okular_dvi.po new file mode 100644 index 0000000..a492761 --- /dev/null +++ b/po/ia/okular_dvi.po @@ -0,0 +1,743 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-09-09 14:14+0200\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular poterea non locar le programma dvipdfmsur tu " +"computator. Isto programma es essential proque le function de exportar " +"functiona. Totevia, tu pote converter le file DVI in PDF per usar le " +"function de imprimer de Okular, ma illo producera un documento que essera " +"imprimite ben, ma que il essera de qualitate inferior si visualisate con " +"Acrobat Reader. Il poterea esser bon cosa actualisar tu version de " +"distribution de TeX que includerea un version plus recente del programma " +"dvipdfm.

Insinuation pro un administrator de systema " +"perplexe: Okular usa le variabile de ambiente PATH quando il cerca " +"programmas.

" + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Le programma externe 'dvipdfm', que esseva usate pro exportar le file, " +"reportava un error. Tu poterea desirar guardar le dialogo de info de " +"documento que tu trovara in le Menu de file pro un precise reporto " +"de error." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Iste file DVI refere se al files graphic externe que non es in formato " +"PostScript, e que non pote esser maneate per le programma dvips que " +"Okular usa internemente pro imprimer o exportar in PostScript. Le " +"functionalitate que tu require ergo non es disponibile in iste version de " +"Okular." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular non poteva locar le programma dvips sur tu " +"computator. Celle programma es essential proque le function de exportar pote " +"functionar.

I

Insinuation pro le administrator de systema perplexe: " +"Okular usa le variabile de ambiente PATH quando il cerca programmas.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Le programma externe 'dvips', que esseva usate pro exportar le file, " +"reportava un error. Tu poterea desirar guardar le dialogo de info de " +"documento que tu trovara in le Menu de file pro un precise reporto " +"de error." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Le file DVI initia con le preambulo." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"Le file DVI contine le version errate de exito de DVI pro iste programma. " +"Insinuation: si tu usa le systema de dactylographar Omega, tu debe usar un " +"programma special tal como oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"Le file DVI es corrumpite de mal modo. Okular non esseva capace de trovar " +"le postambulo." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Le postambulo non initia con le commando POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Le posambulo contineva un commando a parte que FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Le pagina %1 non initia con le commando BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Le programma externe pdf2ps non poteva esser " +"initiate. Como exito, le file-PDF %1 non poteva esser convertite a " +"PostScript. Alcun elementos graphic in tu documento dunque non essera " +"monstrate.

Possibile ration: Le programma pdf2ps poterea non esser installate sur tu systema, o non pote esser " +"trovate in le percurso currente de cerca.

Cosa tu pote facer: " +"Le programma pdf2ps normalmente es continite in " +"distributiones del systema interprete de PostScript ghostscript. Si " +"ghostscript non es installate sur tu systema, tu poterea installar lo nunc. " +"Si tu es secur que ghostscript es installate, essaya usar pdf2ps ab le linea de commando pro verificar si illo functiona vermente.

PATH: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Le file-PDF %1 non poteva esser convertite in PostScript. Alcun " +"elementos graphic in tu documento dunque non essera monstrate.

Possibile ration: Le file %1 poterea esser corrumpite, o " +"poterea non esser un file-PDF del toto. Isto es le exito del programma " +"pdf2ps que Okular usava:

%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Corruption de file. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Non omne files Postscript poterea esser includite in tu documento, %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Omne files externe de Postscript esseva includite in tu documento," + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Le commando specificate '%1' non es actuate." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Tu demandava Okular de locar le placia in le file DVI que corresponde al " +"rango %1 il le file de TeX %2. Totevia, il sembla que le file DVI non " +"contine le necessari information de file de fonte. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular esseva incapace de locar le placia de le file DVI que corresponde al " +"rango %1 in le file de TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "Le codice DVI fixava un character de un font incognite." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"Le codice de DVI refereva al font #%1, que non esseva definite previemente." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Le pila non esseva vacue quando on incontrava le commando EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Le pila non esseva vacue quando on incontrava le commando POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"Le codice de DVI refereva aun font que non esseva definite previemente." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Il incontrava un commando illegal." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Il incontrava le op-code incognite %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "&Embedding (Il lo pone interne) %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Pagina %1: Le file PDF %2non pote esser convertite a " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "" +"Pagina %1: Le file Postscript %2 non poteva esser trovate." +"
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "" +"Le dato de dimension de papiro (papersize) '%1' non poteva esser analysate." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular non esseva capace de locar omne files de font que es necessari " +"pro monstrar le file DVI currente. Tu documento poterea esser illegibile.

PATH: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Il habeva un problema quando on executava kpsewhich. Como " +"resultato, alcun files de fonte non poterea esser locate, e tu documento " +"poterea esser illegibile.
Motivation possibile: Le programma " +"kpsewhich forsan non es installate sur tu systema, o il non pote " +"esser trovate in le percurso de cerca.

PATH; %1

%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Le generation de font per kpsewhich esseva abortate (codice de " +"exito %1, error %2). Como exito, alcun files de font non poterea esser " +"locate, e tu documento poterea esser illegibile." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Currentemente generante %1 a %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generator/Data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "File de font non trovate" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "vertical" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "horizontal" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Le version de Ghostview que es installate sur iste computator non contine " +"alcun del drivers de dispositivo de Ghostsript que es conoscite per Okular. " +"Supporto de Postscript, dunque, ha essite dishabilitate in Okular" + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Le programma Ghostview, que Okular usa internemente pro monstrar le " +"graphicos de PostScript que es includite in iste file DVI, es generalmente " +"capace de scriber su exitos in un varietate de formatos. Le sub-programmas " +"que Ghostview usa pro iste cargas es appellate ' device drivers' (drivers de " +"dispositivo), il ha un device driver pro omne formato que Ghostview es " +"capace de scriber. Versiones differente de Ghostview sovente ha differente " +"insimules de device drivers disponibile. Il appare que le version de " +"Ghostview que es installate sur iste computator non contine alcun del device drivers que es cognoscite ab Okular.

Il appare " +"improbabile que un installation regular de Ghostview non contine iste " +"drivers. Dunque iste error pote indicar un serie mal configuration del " +"installation de Ghostscript sur tu computator.

Si tu vole fixar le " +"problemas con Gjostview, tu poite usar le commando gs --help pro monstrar le lista de device drivers continite in Ghostview. " +"Inter alteres, Okular pote usar le drivers 'png256','jpeg' e 'pnm'. Nota que " +"okular necessita un re-initio pro re-habilitar le supporto de PostScript." + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Isto da 25 errores. Ulterior messages de errores non essera imprimite." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Error in file DVI '%1', pagina %2. Commando de pop de color emettite quando " +"le pila de color es vacue." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Paramatro malformate in le commando special epsf.\n" +"On expectava que un float sequeva %1 in %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"File non trovate:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Errot in file DVI '%1', pagina %2. Il non pote interpretar le angulo in le " +"special rotation de texto." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Le commando special '%1' non es actuate." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Le file de font %1 poteva esser aperite e legite, ma su formato de font non " +"es supportate." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "" +"Le file de font %1 es imperfecte, o il non poteva esser aperite o legite." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType reportava un error quando on fixava le grandor de character per le " +"file de font %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType es incapace de cargar glypho #%1 ex file de font %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType es incapace de render glypho #%1 ex file de font %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glypho #%1 es vacue." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glypho #%1 ex fil de font %2 es vacue." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType es incapace de cargar metric pro glypho #%1 ex file de font %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Il non pote aperir file de font %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Character %1 non definite in font %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Inexpectate %1 in file PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Le character %1 es troppo grande in le file %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Numero errate de bits immagazinate: char. %1, font %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Mal file PK (%1), nimie bits" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Font non ha rata de aspecto non-quadrate " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Il non pote trovar font %1, file %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Discrepantia de summa de controlo pro le file de font %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Non pote recognoscer formato pro fil de font %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Error fatal.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Isto probabilemente significa que o tu ha trovate un falta in Okular,\n" +"o que le file DVI, o su files auxiliari (tal como files de font, o files de\n" +"font virtual) esseva vermente corrumpite de mal modo.\n" +"Okular abortara post iste message. Si tu crede que tu ha trovate\n" +"un falta, o que Okular deberea comportar se de modo melior in\n" +"iste situation pro favor tu reporta le problema." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Il trovava byte de commando errate in lista de macro VF %1" + +#~ msgid "DVI Backend" +#~ msgstr "Retro-administration de DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Un renditor de file de DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Pino Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular conta super le programma kpsewhich pro locar files de " +#~ "font sur tu disco dur e pro generar fonts PK, si necessari.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular es currentemente generante fonts de bitmap..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Aborta le generation de font. Non facer isto." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular es currentemente generante fonts de bitmap que es necessari pro " +#~ "monstrar tu documento. Pro isto, Okular usa un quantitate de programmas " +#~ "externe, tal como MetaFont. Tu pote trovar le exito de iste programmas " +#~ "plus tarde in le dialogo de information de documento." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular es currentemente generante fonts. Pro favor tu attende." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Dialogo de progresso de generation de font" + +#~ msgid "Abort" +#~ msgstr "Aborta" + +#~ msgid "What is happening here?" +#~ msgstr "Cosa accade hic?" + +#~ msgid "%v of %m" +#~ msgstr "%v de %m" + +#~ msgid "Please be patient" +#~ msgstr "Pro favor, tu sia patiente" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Exporta file como" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Le file %1\n" +#~ "existe. Tu vole super scriber lo?" + +#~ msgid "Overwrite File" +#~ msgstr "Super scribe file" + +#~ msgid "Overwrite" +#~ msgstr "Super scribe" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Usante dvipdfm pro exportar le file in PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular currentemente es usante le programma externe 'dvipdfm' pro " +#~ "converter tu file DVI in PDF. Tal vice illo pote prender un pauc de " +#~ "tempore proque dvipdfm necessita generar su proprie font de bitmap. Tu " +#~ "sia patiente, pro favor." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Attendente que dvipdfm fini ..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "usante dvips pro exportar le file a PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular currentemente es usante le programma externe 'dvips' pro converter " +#~ "tu file DVI in PostScript. Tal vice illo pote prender un pauc de tempore " +#~ "proque dvipdfm necessita generar su proprie font de bitmap. Tu sia " +#~ "patiente, pro favor." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Attendente que dvips fini ..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Functionalitate non disponibile" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Corruption de file Okular non pteva interpretar tu " +#~ "file DVI. Isto es plus communemente causate per un file corrupte." + +#~ msgid "DVI File Error" +#~ msgstr "Error de file de DVI" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Il non trovava omne files de font." + +#~ msgid "Locating fonts..." +#~ msgstr "Locante fonts..." + +#~ msgid "" +#~ "

There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

" +#~ msgstr "" +#~ "

Il habeva problemas quando on executava kpsewhich. Como exito, " +#~ "alcun files non poteva esser locate, e tu documento poterea esser " +#~ "illegibile.

Ration possibile: Le programma kpsewhich forsan " +#~ "non es installate sur tu systema, o il non pote esser trovate in le " +#~ "percurso currente de cerca.

Cosa tu pote facer: Le programma " +#~ "kpsewhich normalmente es continite in distributiones del systema de " +#~ "dactylographar TeX. Si TeX non es installate sur tu systema, tu poterea " +#~ "installar le distribution TexLive (www.tug.org/texlive). Si tu es secur " +#~ "que TeX es installate, pro favor tu essaya usar le programma kpsewhich ab " +#~ "le linea de commando pro overificar si illo functiona realmente.

" + +#~ msgid "Problem locating fonts" +#~ msgstr "Il ha problemas durante que on locava fonts" + +#~ msgid "Font generation aborted" +#~ msgstr "Generation de font abortite" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Exporta %1 a PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Exporta: %1 a PostScript" diff --git a/po/ia/okular_epub.po b/po/ia/okular_epub.po new file mode 100644 index 0000000..cc13526 --- /dev/null +++ b/po/ia/okular_epub.po @@ -0,0 +1,55 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 18:59+0200\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Error durante que on aperiva le documento EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Retro-Administration de configuration de EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Retro-Administration de EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Un retro-administration de EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/ia/okular_fax.po b/po/ia/okular_fax.po new file mode 100644 index 0000000..cdbbdfd --- /dev/null +++ b/po/ia/okular_fax.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-02-07 10:36+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Incapace de cargar documento" + +#~ msgid "Fax Backend" +#~ msgstr "Retro-Administration de fax" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "UN retro-administration de documento fax G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ia/okular_fictionbook.po b/po/ia/okular_fictionbook.po new file mode 100644 index 0000000..bb92475 --- /dev/null +++ b/po/ia/okular_fictionbook.po @@ -0,0 +1,80 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 19:00+0200\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Le docuemnto non es un valide FictionBook" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Incapace de aperir documento: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Documento non es un valide archivo ZIP" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Structura de documento invalide (directorio principal es mancante)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Il non trovava alcun contento in le documento" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Invalide documento XML: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "Fiction Book" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configuration de retro administration de Fiction Book" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Retro adminisration de Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un rendition pro eBooks (Libros electronic) de FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ia/okular_ghostview.po b/po/ia/okular_ghostview.po new file mode 100644 index 0000000..8d1c05b --- /dev/null +++ b/po/ia/okular_ghostview.po @@ -0,0 +1,92 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-02-07 10:39+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usa fonts de platteforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina si a Ghostscript deberea esser permittite de usar fonts de " +"platteforma, si false solmente le fonts includite in le documento essera " +"permittite." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Preferentias General" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usa fonts de platteforma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configuration de retro-administration de Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Version de documento" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Nivello de linguage" + +#~ msgid "PS Backend" +#~ msgstr "Retro-Administration de PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un rendition de file de PostScript" + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Basate sur le bibliotheca Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/ia/okular_kimgio.po b/po/ia/okular_kimgio.po new file mode 100644 index 0000000..8ddfc4b --- /dev/null +++ b/po/ia/okular_kimgio.po @@ -0,0 +1,69 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2020-05-10 21:14+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Incapace de cargar documento: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Iste documento appare malformate. Hic il ha un melior approximation del " +"apparentia intendite del documento." + +#~ msgid "Image Backend" +#~ msgstr "Retro-Administration de Image" + +#~ msgid "A simple image backend" +#~ msgstr "Un simplice retroadministration de image" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra de instrumento principal" diff --git a/po/ia/okular_markdown.po b/po/ia/okular_markdown.po new file mode 100644 index 0000000..4983fa5 --- /dev/null +++ b/po/ia/okular_markdown.po @@ -0,0 +1,54 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# giovanni , 2017. +# Marinella , 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-09-27 10:26+0100\n" +"Last-Translator: Marinella \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Falleva aperir le documento " + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Falleva compilar le documento de Markdown." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Habilita formattation de SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configuration de Retro-administration de Markdown" diff --git a/po/ia/okular_mobi.po b/po/ia/okular_mobi.po new file mode 100644 index 0000000..39de55e --- /dev/null +++ b/po/ia/okular_mobi.po @@ -0,0 +1,63 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 19:01+0200\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Error durante que on aperiva le documento Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Iste libro es protegite per DRM e pote esser monstrate solmente sur un " +"dispositivo designate" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configuration de retro-administration de Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Retro-administration de Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Un retro-administration de Mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr " Jakub Stachowski" diff --git a/po/ia/okular_plucker.po b/po/ia/okular_plucker.po new file mode 100644 index 0000000..bb908c0 --- /dev/null +++ b/po/ia/okular_plucker.po @@ -0,0 +1,45 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-02-07 10:40+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nomine" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Un retro-administration de documento Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un rendition pro eBooks (Libros electronic) de Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/ia/okular_poppler.po b/po/ia/okular_poppler.po new file mode 100644 index 0000000..096d068 --- /dev/null +++ b/po/ia/okular_poppler.po @@ -0,0 +1,225 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2020. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2020-10-19 09:29+0200\n" +"Last-Translator: giovanni \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 20.04.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Intensifica lineas tenue:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Solido" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Forma" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Optiones de PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Imprime annotationes" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Include annotationes in le documento imprimite" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Include annotationes in le documento imprimite. Tu pote dishabilitar isto si " +"tu vole imprimer le documento original sin annotationes." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Fortia le rasterization" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "rasteriza in un imagine ante imprimer" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Fortia le rasterization de cata pagina in un image ante imprimer lo. Isto " +"usualmente da tal vice mal exitos, ma il es utile quando on imprime " +"documentos que pare imprimer se incorrectemente." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Adapta a area imprimibile" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Adapta a pagina complete" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Necun; imprime grandor original" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Modo de scalar per le paginas imprimite" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Modo de scalar:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Cryptate" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Non cryptate" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Securitate" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Si" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Optimisate" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "Usante Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"Usante Poppler %1\n" +"\n" +"Construite contra Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configuration de Retro-administration de PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Non disponibile" + +#~ msgid "PDF Backend" +#~ msgstr "Retro-administration de PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Un renditor de file de PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Il non es supportate salveguardar files con /Encrypt." + +#~ msgid "Unknown" +#~ msgstr "Incognite" + +#~ msgid "Unknown Date" +#~ msgstr "Data incognite" + +#~ msgid "Unknown Encryption" +#~ msgstr "Cryptation incognite" + +#~ msgid "Unknown Optimization" +#~ msgstr "Optimisation incognite" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Pro favor tu entra un contrasigno pro leger le documento" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Contrasigno incorrecte. Essaya de nove:" + +#~ msgid "Document Password" +#~ msgstr "Contrasigno de documento" diff --git a/po/ia/okular_tiff.po b/po/ia/okular_tiff.po new file mode 100644 index 0000000..5a355f3 --- /dev/null +++ b/po/ia/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# +# Giovanni Sora , 2020. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-09-23 23:13+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" diff --git a/po/ia/okular_txt.po b/po/ia/okular_txt.po new file mode 100644 index 0000000..e5d5202 --- /dev/null +++ b/po/ia/okular_txt.po @@ -0,0 +1,50 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-05-21 19:03+0200\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Ttxt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configuration de Retro-administration de Txt" + +#~ msgid "Txt Backend" +#~ msgstr "Retro-administration per Txt " + +#~ msgid "Txt backend." +#~ msgstr "Retro-administration per Txt ." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/ia/okular_xps.po b/po/ia/okular_xps.po new file mode 100644 index 0000000..e028f21 --- /dev/null +++ b/po/ia/okular_xps.po @@ -0,0 +1,57 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-02-07 10:41+0100\n" +"Last-Translator: Giovanni Sora \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Giovanni Sora" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "g.sora@tiscali.it" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revision" + +#~ msgid "XPS Backend" +#~ msgstr "Retro-Administration de XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un retro-administration de XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/ia/org.kde.active.documentviewer.po b/po/ia/org.kde.active.documentviewer.po new file mode 100644 index 0000000..4b098b4 --- /dev/null +++ b/po/ia/org.kde.active.documentviewer.po @@ -0,0 +1,81 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Giovanni Sora , 2013, 2017. +# Marinella , 2019. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-09-27 10:54+0100\n" +"Last-Translator: Marinella \n" +"Language-Team: Interlingua \n" +"Language: ia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 2.0\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Aperi..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Remove marcator de libro" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Adjunge iste pagina al marcatores de libro" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniaturas" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Indice o Tabula de contentos" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Marcatores de libro" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Cerca..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Necun resultatos trovate." + +#~ msgid "Document to open..." +#~ msgstr "Documento de aperir..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Necun documento trovate. Po initiar leger, pone alcun files in le dossier " +#~ "de Documentos de tu dispositivo." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Visor de documento pro Plasma Avtive usante Okular" + +#~ msgid "Reader" +#~ msgstr "Lector" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "URL del file de aperir" diff --git a/po/id/okular.po b/po/id/okular.po new file mode 100644 index 0000000..e59aea4 --- /dev/null +++ b/po/id/okular.po @@ -0,0 +1,5372 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Wantoyo , 2016, 2018, 2019, 2020, 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2021-02-08 08:32+0700\n" +"Last-Translator: Wantoyo \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.12.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Wantoyo" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "wantoyek@gmail.com" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, sebuah peninjau dokumen universal" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Pemelihara yang dahulu" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Banyaknya kerja framework, ODT dan backend FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Pengembang" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Okular diciptakan dari codebase KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Pengembang KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Karya seni anotasi" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Alat pemilihan tabel" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Perbaikan anotasi" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Menuju ke halaman %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Buka file external" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Eksekusi '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Halaman Pertama" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Halaman Sebelumnya" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Halaman Selanjutnya" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Halaman Terakhir" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Kembali" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Maju" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Berhenti" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Mulai Presentasi" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Akhiri Presentasi" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Temukan..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Menuju Ke Halaman..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Play suara..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Skrip JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Play filem..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Play filem" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stop filem" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Jeda filem" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Melanjutkan filem" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Pemilihan Backend" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Lebih dari satu backend ditemukan untuk tipe MIME:
%1 (%2)." +"

Silakan pilih salah satu yang mana untuk digunakan:
" + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Sebagian besar halaman %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Potret %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Lanskap %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Meneneruskan pencarian dari awal" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Meneruskan pencarian dari bagian bawah" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Tak bisa menemukan plugin yang mampu menangani dokumen yang sedang berlalu." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "hapus anotasi" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Dokumen telah mencoba untuk mengeksekusi sebuah aplikasi external dan, untuk " +"keamananmu, Okular tidak membolehkan hal itu." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Tidak ada aplikasi yang ditemukan untuk membuka file dari mimetype %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Tidak bisa membuka file temporer" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Konversi cetak gagal" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Proses pencetakan mogok" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Proses pencetakan tidak bisa mulai" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Pencetakan ke file gagal" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Pencetak telah dalam keadaan tak valid" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Tak mampu menemukan file untuk cetak" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Tidak adanya file untuk mencetak" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Tidak bisa menemukan biner yang cocok untuk pencetakan. Pastikan biner CUPS " +"lpr telah tersedia" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Ukuran cetak halaman tak valid" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Tidak bisa membuka file '%1'. File tidak ada" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Judul" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Subjek" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Deskripsi" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Penulis" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Pencipta" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Produsen" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Hak Cipta" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Halaman" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Diciptakan" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Dimodifikasi" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Mime Type" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Kategori" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Katakunci" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Alur File" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Ukuran File" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Ukuran Halaman" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "tambah anotasi" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "hapus anotasi" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "modifikasi properti anotasi" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "terjemah anotasi" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "sesuaikan anotasi" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "edit teks" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "edit daftar konten anotasi" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "edit daftar konten formulir" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "edit daftar dari pilihan" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "edit combo daro pilihan" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "edit formulir keadaan tombol" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Tanam &Teks..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "Teks OpenDocument" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opsi Cetak" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Paskan ke area dapat-dicetak" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Paskan ke halaman penuh" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Mode skala:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Tipe sinyal hilang" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Jangan tampilkan pesan ini lagi" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Sumber: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "&Font Baku:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Merah" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Jingga" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Kuning" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Hijau" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Sian" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Biru" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Putih" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Kelabu" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Hitam" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Lebar %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Lebar garis anotasi (Tidak ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Warna anotasi (Tidak ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "Isi warna anotasi (Tidak ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opasitas anotasi (Tidak ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Font anotasi (Tidak ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Tambahkan anotasi saat ini ke menu anotasi cepat (Tidak ada anotasi yang " +"dipilih)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Batasi rasio bentuk hingga 1:1 atau sudut garis hingga 15° langkah (Tidak " +"ada anotasi yang dipilih)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Lebar garis anotasi" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Warna teks anotasi" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Warna tepi anotasi" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Warna anotasi" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Warna isi anotasi" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Font anotasi" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opasitas anotasi" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Warna" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Warna Isi" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Transparan" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Warna Kustom..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Fitur eksperimental" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Pilih warna" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Anotasi" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Sembunyikan" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Penyorot" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Garis bawah" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Berlekuk-lekuk" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Garis Tengah" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Tulisan ketik" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Catatan Dalam Baris" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Catatan Sembul" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Garisan Tangan" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Garis Lurus" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Panah" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Persegi" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Bulatan" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Segibanyak" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Bentuk geometri" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Stempel" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Anotasi Cepat" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Tambahkan ke Anotasi Cepat" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Biarkan alat anotasi aktif setelah digunakan" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Font" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Pengaturan Anotasi" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Lebar garis" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opasitas" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Halaman %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Anotasi" +msgstr[1] " %1 Anotasi" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Buka Catatan Sembul" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Hapus" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Properti" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Simpan '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Penampilan" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Umum" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Penulis:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Diciptakan:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Dimodifikasi:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Properti Catatan Sembul" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Properti Mesin-ketik" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Properti Catatan Dalam Baris" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Properti Garis Lurus" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Properti Segibanyak" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Properti Geometri" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Properti Tanda Baca Teks" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Properti Cap" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Properti Garis Bidang Tangan" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Properti Tanda Sisipan" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Properti Lampiran File" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Properti Suara" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Properti Filem" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Properti Anotasi" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Dimodifikasi: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Pilih simbol stempel kustom" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Warna:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opasitas:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Ikon:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Komentar" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Bantuan" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Sisispkan" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Kunci" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Paragraf baru" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Catatan" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragraf" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Font:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Warna teks:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "Se&jajar:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Kiri" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Pusat" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Kanan" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "&Lebar bingkai:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Diperkenankan" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Apa Adanya" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Diberi Kepercayaan" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Departemen" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Draft" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Experimental" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Final" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Untuk Komentar" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Untuk Rilis Publik" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Tidak Diperkenankan" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Tidak Untuk Rilis Publik" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Terjual" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Sangat Rahasia" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Markah" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informasi" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Simbol Stempel:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Lebar:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Awal Baris:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Akhir Baris:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Persegi" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Lingkaran" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Berlian" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Panah Buka" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Panah Tutup" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Nihil" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Gagang" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Panah Buka Kanan" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Panah Tutup Kiri" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Setrip" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Panjang garis leader:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Panjang ekstensi garis leader:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Difungsikan" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Isi bentuk:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipe:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Sorot" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Garis Berlekuk-lekuk" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Garisbawahi" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Garis tengah" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Persegi" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Bulat" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Simbol lampiran file:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Graph" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Push Pin" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Paperclip" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Tag" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "File" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "T/A" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Tidak ada deskripsi yang tersedia." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nama:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Deskripsi:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Simbol tanda sisipan:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Nihil" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Tutup catatan ini" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opsi" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Anotasi ini mungkin berisi kode LaTeX.\n" +"Klik di sini untuk me-render." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Tak bisa menemukan latex yang dapat dieksekusi." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Pe-render-an LaTeX gagal" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Tak bisa menemukan dvipng yang dapat dieksekusi." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Masalah terjadi selagi pengeksekusian perintah 'latex'." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Masalah terjadi selagi pengeksekusian perintah 'dvipng'." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Satu markah" +msgstr[1] "" +"%1\n" +"\n" +"%2 markah" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Markah" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Cari..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Hanya dokumen saat ini" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Menuju ke Markah Ini" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Ubah Nama Markah" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Buang Markah" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Buka Dokumen" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Buang Markah" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versi" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Nomor Serial" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Penerbit" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Diterbitkan Pada" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Kedaluwarsa Pada" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Subjek" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Kunci Publik" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Penggunaan Kunci" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bit)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Properti" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Nilai" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Penampil Sertifikat" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Ekspor..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Umum" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Diterbitkan Oleh" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nama Umum (CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Email" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organisasi (O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Diterbitkan Kepada" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Keabsahan" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Sidikjari" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Sidikjari SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Sidikjari SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Perincian" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Data Sertifikat:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Di mana kamu ingin menyimpan sertifikat ini?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "File Sertifikat (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Tidak bisa mengekspor sertifikat" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Merah" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Hijau" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Biru" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Kuning" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Hitam" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Putih" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Gambari bingkai sekitar &Citra" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Gambari bingkai sekitar &Tautan" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Ubah &warna" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "" +"Peringatan: pilihan tersebut bisa mempengaruhi kecepatan menggambar secara " +"buruk." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Mode warna:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Warna Kebalikan" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Ubah Warna Kertas" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Ubah Warna Gelap & Terang" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Convert ke Hitam & Putih" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Warna kertas:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Warna gelap:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Warna terang:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Ambang:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Kontras:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Ucapan" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Mesin" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identitas" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Pe&nulis:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Catatan: informasi di sini hanya digunakan untuk komentar dan " +"tinjauan. Informasi yang tersisip di sini tidak akan dipancarkan tanpa " +"sepengetahuanmu." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Alat anotasi cepat" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Custom Text Editor" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs client" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx client" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Set perintah pada suai pengedit teks untuk diluncurkan.
\n" +"Kamu juga bisa menaruh beberapa placeholders:\n" +"
    \n" +"
  • %f - nama file
  • \n" +"
  • %l - garis dari file untuk tercapai
  • \n" +"
  • %c - kolom dari file untuk tercapai
  • \n" +"
\n" +"Jika %f tidak ditentukan, maka nama file ditambahkan ke perintah yang " +"ditentukan." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Pengedit" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Pengedit:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Pilihlah pengedit yang ingin kamu luncurkan ketika Okular hendak membuka " +"sebuah file sumber." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Perintah:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Penampilan" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Tampilkan &bilah-gulir" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Tautan &gambar-mini dengan halaman" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Tampilkan &petunjuk dan pesan info" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Tampilkan judul dokumen di bilah judul jika tersedia" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Ketika tidak menampilkan judul dokumen:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Tampilkan hanya nama file " + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Tampilkan alur file penuh" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Gunakan kustom warna latarbelakang" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Fitur Program" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Buka file baru di &tab" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Keterbatasan Obey DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Muat ulang dokumen saat perubahan file " + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Tampilkan dialog pemilihan backend" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Arah pembacaan kanan ke kiri" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opsi Tampilan" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "Kolom &ikhtisar:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Menegaskan berapa banyak area peninjauan saat ini yang akan selalu terlihat " +"ketika menekan tuts Halaman Naik/Turun." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Overlap halaman Naik/Turun:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Menentukan mode zoom baku untuk file yang sebelumnya tidak pernah dibuka.\n" +"Untuk file yang sebelumnya dibuka sebelum zoom diterapkan." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Menentukan mode zoom baku untuk file yang sebelumnya tisak pernah dibuka.\n" +"Untuk file yang sebelumnya dibuka zoom sebelumnya diterapkan." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "&Zoom Baku:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Paskan Lebar" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Paskan Halaman" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Paskan Otomatis" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Memori serendah mungkin tetap digunakan. Jangan gunakan apa pun. (Untuk " +"sistem dengan memori rendah.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Kompromi yang baik antara penggunaan memori dan raih kecepatan. Permuat " +"halaman selanjutnya dan meningkatkan pencarian. (Untuk sistem dengan memori " +"2GB, khususnya.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Jaga semuanya di memori. Pramuat halaman selanjutnya. Percepat pencarian. " +"(Untuk sistem dengan memori lebih dari 4GB.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Muat dan tetap segalanya di memori. Permuat semua halaman. (Akan menggunakan " +"di maksimum 50% pada memori totalmu atau memori bebasmu, apa pun yang lebih " +"besar.)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Penggunaan CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Fungsikan &efek transparan" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Penggunaan Memori" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "Ren&dah" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&mal (baku)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "&Lahap" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "&Rakus" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Perenderan" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Fungsikan Antialias Teks" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Fungsikan Antialias Grafik" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Fungsikan Hinting Teks" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Layar Saat Ini" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Layar Baku" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Layar %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " detik" +msgstr[1] " detik" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigasi" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Lanjut setiap:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Lambung setelah halaman terakhir" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navigasi sentuh:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Ketuk sisi kiri/kanan untuk menuju mundur/maju" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Ketuk di mana saja untuk menuju maju" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Dinonfungsikan" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Warna latar-belakang:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Kursor mouse:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Sembunyi Setelah Tunda" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Selalu Terlihat" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Selalu Sembunyi" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Tampilkan &indikator progres" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Tampilkan halaman &ringkasan" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Fungsikan transisi" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transisi baku:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Krepyak Vertical" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Krepyak Horizontal" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Kotak Masuk" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Kotak Keluar" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Larut" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Lesap" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Kerlap Turun" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Kerlap Kanan" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Kerlap Kanan-Turun" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transisi Acak" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Ganti" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Belah Mendatar Masuk" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Belah Mendatar Keluar" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Belah Tegak Masuk" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Belah Tegak Keluar" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Usap Turun" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Usap Kanan" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Usap Kiri" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Usap Naik" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Penempatan" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Layar:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Konfigurasi Alat Penggambaran" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Alat Menggambar: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Penghapus" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nama:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipe:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Catatan Sembul" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Catatan Dalam Baris" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Garis Bidang Tangan" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Garis Lurus" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Segibanyak" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Tanda baca teks" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Bentuk geometri" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Cap" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Mesin-ketik" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Ciptakan alat anotasi" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Edit alat anotasi" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "&Warna:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Lebar &Pena:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Ciptakan alat penggambaran" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Edit alat penggambaran" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Tak diketahui" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "File Tersemat" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Tampilan" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nama" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Deskripsi" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Ukuran" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Diciptakan" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Dimodifikasi" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Simpan Sebagai..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Tampilan..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Tidak dapat memuat bagian pratinjau cetak" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Pratinjau Cetak" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Tutup" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "T&emukan:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Teks untuk pencarian" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Selanjutnya" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Lompat ke cocok selanjutnya" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Sebelumnya" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Lompat ke cocok sebelumnya" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifikasi perilaku pencarian" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Sensitif huruf" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Dari halaman saat ini" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Temukan ketikan kamu" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Semua File" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Properti Tandatangan" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Garis Lurus dengan Komentar" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Segibanyak dengan Komentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometri dengan Komentar" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometri" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Sorotan dengan Komentar" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Garis-lekuk dengan Komentar" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Garis-bawah dengan Komentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Garis-tengah dengan Komentar" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Garis-tengah" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Stempel dengan Komentar" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Garis-bidang dengan Komentar" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Tanda Sisipan" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Lampiran File" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Suara" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Filem" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Layar" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Widget" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Media Rich" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Tak diketahui" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Penulis: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Di mana kamu ingin menyimpan %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Tidak bisa membuka \"%1\" untuk penulisan. File tidak akan disimpan." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Pilihan Pencarian" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Sensitif Huruf" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Ekspresi Reguler" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "&Cari:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Lapisan" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "dari" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom " + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Zoom ke 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Rotasikan &Kanan" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Kanan" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Rotasikan &Kiri" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Kiri" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientasi Asli" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Tampilan &Trim" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "&Trim Pinggiran" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Trim Ke &Pilihan" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Paskan &Lebar" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Paskan &Halaman" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Paskan Otomatis" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Paskan &Window ke Halaman" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Mode Tampilan" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Halaman Tunggal" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Halaman Ganda" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Halaman Ganda (Halaman Pertama di Tengah)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Ikhtisar" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Terus-menerus" + +#: part/pageview.cpp:637 +#, fuzzy, kde-format +#| msgid "Right to left reading direction" +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Arah pembacaan kanan ke kiri" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "&Telusuri" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "&Toggle Perubahan Warna" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "Pemilihan &Area" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Pemilihan &Teks" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Pemilihan Ta&bel" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Suryakanta" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Peralatan Pemilihan" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Bicara Seluruh Dokumen" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Bicara Halaman Saat Ini" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Hentikan Bicara" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Gulir Naik" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Gulir Turun" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Gulir Halaman Naik" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Gulir Halaman Turun" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Tampilkan Formulir" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Termuat satu-halaman dokumen." +msgstr[1] " Termuat %1-halaman dokumen." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Teks (1 karakter)" +msgstr[1] "Teks (%1 karakter)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Salin ke Papan-klip" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Salinan dilarang oleh DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Teks Bicara" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Citra (%1 oleh %2 pixel)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Simpan ke File..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Citra [%1x%2] disalin ke papan-klip." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Simpan file" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Citra (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "File tidak tersimpan." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Citra [%1x%2] disimpan ke %3 file." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Salin Teks" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Menuju ke '%1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Pencarian untuk '%1% dengan" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Konfigurasikan Pintasan Web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Ikuti Tautan Ini" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Bunyikan Suara ini" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Hentikan Suara" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Salin Alamat Tautan" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Pencarian untuk '%1% dengan" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Selamat Datang" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Pilih area pengezooman. Klik kanan untuk mengezoom perkecil." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Klik untuk melihat tinjauan diperbesar." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Gambari sebuah persegi di sekitar teks/grafik untuk menyalin." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Pilih teks" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Gambari sebuah persegi di sekitar tabel, kemudian klik dekat pinggiran untuk " +"membaginya; tekan Esc untuk membersihkan." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "" +"Gambari sebuah persegi di sekitar area halaman yang kamu inginkan untuk " +"tetap terlihat" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Catatan Teks Baru" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Teks dari catatan baru:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "tambah anotasi" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Gambari sebuah bulatan (seret untuk memilih wilayah)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Sorot teks" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Gambari sebuah garis bidang tangan" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Anotasi Teks Dalam Baris (seret untuk memilih wilayah)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Taruh sebuah catatan sembul" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Gambari sebuah segibanyak (klik pada titik pertama untuk menutupnya)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Gambari sebuah persegi" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Garis-lekuk teks" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Taruh sebuah simbol cap" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Gambari sebuah garis lurus" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Garis-tengah teks" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Garis-bawah teks" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Anotasi Mesin-ketik (seret untuk memilih zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Penyorot" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "tambah anotasi" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Change an annotation's size" +#| msgid "adjust annotation" +msgid "Custom annotation name:" +msgstr "sesuaikan anotasi" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&File" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Peng&aturan" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Bantuan" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientasi" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Markah" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Bilah Alat Penampil" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Gambar-mini" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Anotasi" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Dokumen ini berisi anotasi atau data formulir yang disimpan secara internal " +"oleh versi Okular sebelumnya. Penyimpanan internal adalah tidak lagi " +"didukung.
Silakan simpan ke sebuah file untuk memindahkan mereka " +"jika kamu ingin terus mengedit dokumen." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Dokumen ini memiliki file tersemat. Klik " +"di sini untuk melihatnya atau menuju ke File -> File Tersemat." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Sebelumnya" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Menuju kembali ke Halaman Sebelumnya" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Pindah ke halaman sebelumnya dari dokumen" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Selanjutnya" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Lanjut ke Halaman Selanjutnya" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Pindah ke halaman selanjutnya di dokumen" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Pangkal dokumen" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Pindah ke pangkal dari dokumen" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Ujung dokumen" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Pindah ke ujung dari dokumen" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Ubah nama markah saat ini" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Markah Sebelumnya" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Menuju ke markah sebelumnya" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Markah Selanjutnya" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Menuju ke markah selanjutnya" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Konfigurasikan Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Konfigurasikan Penampil..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Konfigurasikan Backend Penampil..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Konfigurasikan Backend..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Tentang Backend" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Muat ulang" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Muat ulang dokumen saat ini dari disk." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Tutup &Bilah Temukan" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Nomor Halaman" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Pilih Semua Teks pada Halaman Saat Ini" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Tampilkan &Bilah Halaman" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Tampilkan &Bilah Halaman" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Tampilkan Panel &Tandatangan" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&File-file Tertanam" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "&Ekspor Sebagai" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Bagikan" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentasi" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Import PostScript sebagai PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "&Dapatkan Buku Dari Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Peralihan Mode Blackscreen" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Hapus Penggambaran" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Konfigurasikan Anotasi..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Play/Jeda Presentasi" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Tidak bisa membuka '%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Pemuatan %1 telah dibatalkan." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Tidak bisa membuka %1. Alasan: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Konfigurasikan Backend Penampil" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Konfigurasikan Backend" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Program \"ps2pdf\" tidak ditemukan, sehingga Okular tidak bisa mengimport " +"file PS menggunakan itu." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf tidak ditemukan" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "File PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" +"Pengimporan file PS sebagai PDF (ini mungkin memakan waktu beberapa saat)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Silakan masukkan sandi untuk membaca dokumen:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Sandi salah. Coba lagi:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Sandi Dokumen" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Dokumen ini memiliki formulir XFA, yang baru-baru ini tidak didukung." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Dokumen ini memiliki formulir. Klik pada tombol untuk berinteraksi " +"dengannya, atau gunakan Tampilan -> Tampilkan Formulir." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"Semua fitur pengeditan dan interaktif untuk dokumen ini dinonfungsikankan. " +"Silahkan simpan salinan dan buka kembali untuk mengedit dokumen ini." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Dokumen ini telah ditandatangani secara digital." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "This document is digitally signed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Dokumen ini telah ditandatangani secara digital." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Dokumen ini ingin ditampilkan pada layar penuh.\n" +"Biarkan mode normal dan masuk ke mode presentasi?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Minta untuk Mode Menampilkan Perubahan" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Masuk Mode Presentasi" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Sangkal Permintaan" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Tidak bisa membuka %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" +"Ada perubahan yang tak tersimpan, dan file '%1' telah dimodifikasi oleh " +"program lainnya. Perubahanmu akan hilang, karena filnya tidak bisa lagi " +"disimpan.
Apakah kamu ingin meneruskan pemuatan ulang file ?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "File Terubah" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Teruskan Pemuatan-ulang" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Gugurkan Pemuatan-ulang" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" +"Ada perubahan yang tak tersimpan, dan file '%1' telah dimodifikasi oleh " +"program lainnya. Perubahanmu akan hilang, karena filnya tidak bisa lagi " +"disimpan.
Apakah kamu ingin meneruskan penutupan file ?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Teruskan Penutupan" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Gugurkan Penutupan" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Apakan kamu ingin menyimpan perubahan \"%1\" atau membuangnya?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Tutup Dokumen" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Titik tautan ini untuk tindakan menutup dokumen yang tidak bekerja ketika " +"menggunakan peninjau tersemat." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Titik tautan ini untuk tindakan mengeluarkan aplikasi yang tidak bekerja " +"ketika menggunakan peninjau tersemat." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Memuat ulang dokumen..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Daftar Isi" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Tandatangan" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Menuju ke Halaman" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Halaman:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Masukkan nama barunya markah:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Ubah nama Markah ini" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Buang Markah ini" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Simpan Sebagai" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"File '%1' telah dimodifikasi oleh program lainnya, yang berati itu tidak " +"bisa lagi disimpan." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Dokumen saat ini diproteksi dengan sandi.
Agar bisa menyimpan, file " +"tersebut perlu dimuat ulang. Kamu akan dimintai sandi lagi dan histori " +"urungkan/lanjurkan kamu akan hilang.
Apakah kamu ingin meneruskan?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Simpan - Peringatan" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Tidak bisa membuka file temporer untuk penyimpanan." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" +"Setelah menyimpan, format dokumen saat ini memerlukan file untuk dimuat " +"ulang. Histori urungkan/lanjurkanmu akan hilang.
Apakah kamu ingin " +"meneruskan?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"File tidak bisa disimpan di '%1'. Coba untuk menyimpannya ke lokasi yang " +"lain." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Pengisian formulir konten" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Anotasi pengguna" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Kamu akan menyimpan perubahan, namun format file saat ini tidak mendukung " +"penyimpanan elemen ini. Silakan gunakan format arsip dokumen Okular " +"untuk mengamankannya." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Peringatan" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Simpan sebagai arsip dokumen Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Kamu akan menyimpan perubahan, namun format file saat ini tidak mendukung " +"penyimpanan elemen ini. Silakan gunakan format arsip dokumen Okular " +"untuk mengamankannya. Klik Teruskan untuk menyimpan dokumen dan " +"membuang elemen tersebut." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Kamu akan menyimpan perubahan, namun format file saat ini tidak mendukung " +"penyimpanan elemen ini. Silakan gunakan format arsip dokumen Okular " +"untuk mengamankannya. Klik Teruskan untuk menyimpannya, tapi kamu " +"akan kehilangan elemen ini serta histori urungkan/lanjurkan." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Terus" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Teruskan kehilangan perubahan" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "File tidak bisa disimpan di '%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular tidak bisa menyalin %1 ke lokasi yang ditentukan.\n" +"\n" +"Dokumen sudah tidak ada lagi." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"File tidak bisa disimpan di '%1'. Error: '%2'. Cobalah untuk menyimpannya ke " +"lokasi yang lain." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Bentangkan seluruh bagian" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Ciutkan seluruh bagian" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Bentangkan semua" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Ciutkan semua" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Tambah Markah" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Peralatan" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Cetak" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Mencetak dokumen ini tidak dibolehkan." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Tidak bisa mencetak dokumen. Galat tidak diketahui. Silakan laporkan ke bugs." +"kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Tidak bisa mencetak dokumen. Rincian error adalah \"%1\". Silakan laporkan " +"ke bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Menuju ke tempat di mana kamu sebelumnya" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Menuju ke tempat di mana kamu sesudahnya" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Error File! Tidak bisa menciptakan file temporer " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Error File! Tidak bisa membuka file %1 untuk uncompression. File tidak akan dimuat." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Errot ini khas terjadi jika kamu tidak memiliki perizinan yang cukup " +"untuk membaca file . Kamu bisa memeriksa kepemilikan dan perizinan jika kamu " +"klik kanan pada file di pengelola file Dolphin, kemudian pilihlah opsi " +"'Properti', dan pilih tab 'Perizinan' di dalam window yang terbuka." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Error File! Tidak bisa meng-uncompress file " +"%1. File tidak akan dimuat." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Galat ini khususnya terjadi jika file telah korup. Jika kamu ingin " +"memastikan, coba decompress file secara manual menggunakan alat baris-" +"perintah." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Tidak ada Markah" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Ada masalah berbagi dengan dokumen: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Bagikan" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Sukses membagikan dokumen" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Kamu bisa menemukan dokumen yang dibagikan di: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Edit" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Tampilan" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Menuju" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Pera&latan" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Bilah Alat Utama" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Alat anotasi" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Pilihan Umum" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Aksesibilitas" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Aksesibilitas Alat Bantu Pembacaan" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Kinerja" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Tala Kinerja" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Konfigurasikan Penampil" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentasi" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Pilihan untuk Mode Presentasi" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Pilihan Anotasi" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Pilihan Pengedit" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Temukan Selanjutnya" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – Presentasi" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Saklar Layar" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Layar %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Keluarkan Mode Presentasi" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Judul: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Halaman: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Klik untuk lagi" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Jedakan" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Putarkan" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Ada dua cara mode mengeluarkan presentasi, kamu bisa antara menekan tombol " +"ESC atau dengan mengeklik tombol berhenti yang muncul ketika mouse " +"ditempatkan di sudut atas kanan. Tentu saja kamu bisa mendaur window (Alt" +"+TAB menurut baku)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Memberikan sebuah presentasi" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "File Tak Diketahui" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 Properti" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Font" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Membaca informasi fon..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Ukuran Halaman" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Extract Font" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipe 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipe 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tipe 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipe 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Tipe 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Tipe 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Tipe 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtual" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX Font Metric" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-handled" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Tak diketahui" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Tersemat (subset)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Tersemat secara penuh" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Tidak" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Ya (subset)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Ya" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[t/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Fon tak diketahui" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Tersemat: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nama" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipe" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "File" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Halaman" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Ukuran" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Pratinjau Revisi" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Di mana kamu ingin menyimpan revisi ini?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Tidak bisa menyimpan file %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Tidak bisa menampilkan revisi." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Masukkan setidaknya 3 huruf untuk memfilter halaman" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Sensitif Huruf" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Frasa Cocok" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Cocok Semua Kata" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Cocok Kata Apapun" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Pilihan Filter" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Tidak ada anotasi

Untuk menciptakan anotasi baru " +"tekan F6 atau pilih Peralatan -> Tinjauan dari menu.
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Kelompok oleh Halaman" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Kelompok oleh Penulis" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Tampilkan tinjauan hanya halaman saat ini" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Bentangkan semua elemen" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Ciutkan semua elemen" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "Tandatangan ini adalah kriptografikal yang absah." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "Tandatangan ini adalah kriptografikal yang tidak absah." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Terjadi Ketidakcocokan Intisari." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "Struktur tandatangan CMS/PKCS7 telah salah bentuk." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "Tandatangan yang diminta tidak ada dalam dokumen." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "Tandatangan tidak bisa diverifikasi." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Sertifikat telah Dipercaya." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "Penerbit sertifikat tidaklah Terpercaya." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "Penerbit sertifikat takdiketahui." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Sertifikat telah Dicabut Kembali." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Sertifikat telah Kedaluwarsa." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Sertifikat belum diverifikasi." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Takdiketahuinya penerbit Sertifikat atau data terkorup." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algoritma Takdiketahui" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipe Takdiketahui" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Tandatangan Digital" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non Penyangkalan" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Enkripsi Kunci" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Dekripsi Kunci" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Kunci Perjanjian" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Tandatangan Sertifikat" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "Tandatangan CRL" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Hanya Enkripsi" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Tidak Ada Penggunaan Yang Ditentukan" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: Ditandatangani Oleh %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Waktu Penadatanganan: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Tidak tersedia" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Alasan: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Bidang: %1 pada halaman %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Properti" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Dokumen belum dimodifikasi sejak ditandatangani." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"Revisi dokumen yang dicakup oleh tandatangan ini belum dimodifikasi;\n" +"namun ada perubahan selanjutnya pada dokumen." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Dokumen telah dimodifikasi dengan cara tidak diizinkan oleh penandatangan " +"sebelumnya." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Verifikasi integritas dokumen tidak dapat diselesaikan." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Status Keabsahan" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Keabsahan Tandatangan:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modifikasi Dokumen:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Informasi Tambahan" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Ditandatangani Oleh:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Waktu Penadatanganan:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Alasan:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Lokasi:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versi Dokumen" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisi Dokumen %1 dari %2" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Tampilan Versi Tertandatangan" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Tampilan Sertifikat..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Tampilkan hanya halaman yang dimarkahi" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Putarkan" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Jeda" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Henti" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Tambah..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Edit..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Hapus" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Pindah &Naik" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Pindah &Turun" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Alat Penggambaran Baku #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Sudah ada alat dengan nama itu. Gunakanlah bakunya" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nama Terduplikat" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Halaman dokumen untuk ditampilkan" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Mulai dokumen dalam mode presentasi" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Mulai dengan dialog cetak" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Jalankan dengan dialog cetak dan keluarkan sesudah pencetakan" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Kendali \"hal unik\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Tidak angkat window" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Temukan string pada teks" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Dokumen kebuka. Tentukan '-' untuk membaca dari stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" +"Error: Tidak bisa membuka lebih dari satu dokumen dengan --unique switch" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Error: Tidak bisa membuka lebih dari satu dokumen dengan --presentation " +"switch" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" +"Error: Tidak bisa membuka lebih dari satu dokumen dengan --print switch" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Error: Tidak bisa membuka lebih dari satu dokumen dengan --page switch" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Error: Tidak bisa membuka lebih dari satu dokumen dengan --find switch" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Tak bisa menemukan komponen Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"Sudah ada sebuah hal Okular unik yang berjalan. Hal ini tidak akan menjadi " +"salah satu yang unik." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Tak mampu menemukan komponen Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Klik untuk membuka file\n" +"Klik dan tahan untuk membuka file saat ini" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Klik untuk membuka sebuah file atau Klik dan tahan untuk " +"memilih sebuah file yang terkini" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Tab Selanjutnya" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Tab Sebelumnya" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Urungkan penutupan tab" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Semua file (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Semua file didukung (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Buka Dokumen" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Konfirmasi Penutupan" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Tutup Tab" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Kamu akan menutup %1 tab. Apakah kamu yakin ingin meneruskan?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Ingatkanku ketika aku berusaha menutup multipel tab" + +#~ msgid "Reviews" +#~ msgstr "Tinjauan" + +#, fuzzy +#~| msgid "V%1" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "V%1" + +#~ msgid "Hide Forms" +#~ msgstr "Sembunyikan Formulir" + +#~ msgid "Expired" +#~ msgstr "Kadaluarsa" + +#~ msgid "&Review" +#~ msgstr "&Tinjauan" + +#~ msgid "Annotations author" +#~ msgstr "Penulis anotasi" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Silakan sisipkan nama atau inisialmu:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Tampilkan &Panel Navigasi" + +#~ msgid "Show Text" +#~ msgstr "Tampilkan Teks" + +#~ msgid "Small Icons" +#~ msgstr "Ikon Kecil" + +#~ msgid "Normal Icons" +#~ msgstr "Ikon Normal" + +#~ msgid "Large Icons" +#~ msgstr "Ikon Besar" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Klik untuk menggunakan alat pemilihan saat ini\n" +#~ "Klik pada panah untuk memilih alat pemilihan lainnya" + +#~ msgid "Created: %1" +#~ msgstr "Diciptakan: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Ekstensi Garis" + +#~ msgid "Style" +#~ msgstr "Gaya" + +#~ msgid "&Size:" +#~ msgstr "&Ukuran:" + +#~ msgid "Inner color:" +#~ msgstr "Warna dalam:" + +#~ msgid "Name: %1" +#~ msgstr "Nama: %1" + +#~ msgid "Size: %1" +#~ msgstr "Ukuran: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Alat Telusur" + +#~ msgid "&Zoom Tool" +#~ msgstr "&Alat Zoom " + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom " + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Pemilihan" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Alat Pemilihan Teks" + +#~ msgid "T&able Selection Tool" +#~ msgstr "&Alat Pemilihan Tabel" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Suryakanta" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Ujung dokumen" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Nihil" diff --git a/po/is/okular.po b/po/is/okular.po new file mode 100644 index 0000000..7ad89ca --- /dev/null +++ b/po/is/okular.po @@ -0,0 +1,5841 @@ +# translation of okular.po to Icelandic +# íslensk þýðing okular.po +# Stígur Snæsson , 2004. +# Þröstur Svanbergsson , 2004. +# Arnar Leosson , 2005. +# Arnar Leósson , 2005. +# Björgvin Ragnarsson , 2005. +# Sveinn í Felli , 2008, 2009, 2010, 2011, 2014, 2016, 2017, 2018. +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2018-01-10 08:56+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Arnar Leósson, Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "leosson@frisurf.no, sv1@fellsnet.is" + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, fjölhæfur skjalaskoðari" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Fyrrverandi umsjónarmaður" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Mikið af kerfisvinnu, ODT og FictionBook bakendar" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Forritari" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Bjó til Okular út frá KPDF kóða" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "KPDF forritari" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Skreyting á glósum" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Töfluvalsverkfæri" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Endurbætur á glósum" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Fara á síðu %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Opna utanaðkomandi skrá" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Framkvæma '%1'..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Fyrsta síða" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Fyrri síða" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Næsta síða" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Síðasta síða" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Til baka" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Áfram" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Hætta" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Byrja kynningu" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Enda kynningu" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Finna..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Fara á síðu..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Spila hljóð..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "JavaScript skrifta" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Spila kvikmynd..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Spila myndskeið" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Stöðva myndskeið" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Gera hlé á myndskeiði" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Halda áfram með myndskeið" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Val bakenda" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
%1 (%2).

Please select which one to use:
" +msgstr "" +"Meira einn bakendi fannst fyrir MIME-tegundina:
%1 (%2).

Vinsamlegast veldu hvern þeirra eigi að nota:
" + +#: core/document.cpp:205 +#, fuzzy, kde-format +#| msgid "Go to page %1" +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "Fara á síðu %1" + +#: core/document.cpp:224 +#, fuzzy, kde-format +#| msgctxt "paper type and orientation (eg: Portrait A4)" +#| msgid "Portrait %0" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Lóðrétt %0" + +#: core/document.cpp:226 +#, fuzzy, kde-format +#| msgctxt "paper type and orientation (eg: Portrait A4)" +#| msgid "Landscape %0" +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Lárétt %0" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 tommur (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "Halda leit áfram frá byrjun" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "Halda leit áfram að neðan" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "Finn ekki neitt íforrit sem meðhöndlað getur skjalið sem um ræðir." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "fjarlægja glósu" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Skjalið er að reyna að keyra utanaðkomandi forrit og af öryggisástæðum " +"leyfir Okular það ekki." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Ekkert forrit fannst sem getur opnað skrá af tegundinni %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Get ekki opnað bráðabirgðaskrá" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Umbreyting fyrir prentun mistókst" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Prentferlið hrundi" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Ekki var hægt að ræsa prentferlið" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Prentun í skrá mistókst" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "Prentarinn var í óþekktu ástandi" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Get ekki fundið skrá til að prenta" + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Það var engin skrá til að prenta" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Gat ekki fundið hentugt forrit til að prenta með. Gakktu úr skugga um að " +"CUPS lpr tvíundaskráin (forritið) sé tiltæk" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "Prentstærð síðunar er ógild" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Gat ekki opnað '%1'. Skráin er ekki til." + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titill" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Efni" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Lýsing" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Höfundur" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Forrit" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Framleiðandi" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Höfundarréttur" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Síður" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Búið til" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Breytt" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "MIME tegund" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Flokkur" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Stikkorð" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Slóð á skrá" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Skráarstærð" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Blaðsíðustærð" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "bæta við glósu" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "fjarlægja glósu" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "breyta eiginleikum glósu" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "þýða glósu" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "laga glósu" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "breyta texta" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "breyta efni glósu" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "breyta innihaldi forms" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "Hreinn &texti..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument texti" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, fuzzy, kde-format +#| msgid "Editor Options" +msgid "Print Options" +msgstr "Valmöguleikar ritils" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: core/printoptionswidget.cpp:28 +#, fuzzy, kde-format +#| msgid "Color mode:" +msgid "Scale mode:" +msgstr "Litahamur:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "" + +#: core/script/kjs_app.cpp:214 +#, fuzzy, kde-format +#| msgid "Close this message" +msgid "Do not show this message again" +msgstr "Loka þessum skilaboðum" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Uppruni: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Sjálf&gefið letur:" + +#: part/annotationactionhandler.cpp:137 +#, fuzzy, kde-format +#| msgid "Red" +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rautt" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "" + +#: part/annotationactionhandler.cpp:139 +#, fuzzy, kde-format +#| msgid "Yellow" +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Gult" + +#: part/annotationactionhandler.cpp:140 +#, fuzzy, kde-format +#| msgid "Green" +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Grænt" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "" + +#: part/annotationactionhandler.cpp:142 +#, fuzzy, kde-format +#| msgid "Blue" +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blátt" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "" + +#: part/annotationactionhandler.cpp:144 +#, fuzzy, kde-format +#| msgid "White" +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Hvítt" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "" + +#: part/annotationactionhandler.cpp:146 +#, fuzzy, kde-format +#| msgid "Black" +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Svart" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, fuzzy, kde-format +#| msgid "&Pen Width:" +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "&Pennabreidd:" + +#: part/annotationactionhandler.cpp:240 +#, fuzzy, kde-format +#| msgid "%1:" +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1:" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" + +#: part/annotationactionhandler.cpp:296 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Valkostir fyrir glósur" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "" + +#: part/annotationactionhandler.cpp:302 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Verkfæri fyrir glósur" + +#: part/annotationactionhandler.cpp:304 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Verkfæri fyrir glósur" + +#: part/annotationactionhandler.cpp:306 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Verkfæri fyrir glósur" + +#: part/annotationactionhandler.cpp:310 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Verkfæri fyrir glósur" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" + +#: part/annotationactionhandler.cpp:316 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Glósa" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" + +#: part/annotationactionhandler.cpp:329 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Valkostir fyrir glósur" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "" + +#: part/annotationactionhandler.cpp:382 +#, fuzzy, kde-format +#| msgid "Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Litur:" + +#: part/annotationactionhandler.cpp:384 +#, fuzzy, kde-format +#| msgid "Color:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Litur:" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" + +#: part/annotationactionhandler.cpp:431 +#, fuzzy, kde-format +#| msgid "Experimental" +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Á tilraunastigi" + +#: part/annotationactionhandler.cpp:475 +#, fuzzy, kde-format +#| msgid "&Selection Tool" +msgctxt "@title:window" +msgid "Select color" +msgstr "&Valverkfæri" + +#: part/annotationactionhandler.cpp:513 +#, fuzzy, kde-format +#| msgid "Annotations" +msgid "&Annotations" +msgstr "Glósur" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "" + +#: part/annotationactionhandler.cpp:518 +#, fuzzy, kde-format +#| msgid "Highlighter" +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Uppljómun" + +#: part/annotationactionhandler.cpp:519 +#, fuzzy, kde-format +#| msgid "Underline" +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Undirstrikað" + +#: part/annotationactionhandler.cpp:520 +#, fuzzy, kde-format +#| msgid "Squiggle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Beygla" + +#: part/annotationactionhandler.cpp:521 +#, fuzzy, kde-format +#| msgid "Strike Out" +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Gegnumstrikað" + +#: part/annotationactionhandler.cpp:523 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Eiginleikar innskotsmerkis (caret)" + +#: part/annotationactionhandler.cpp:524 +#, fuzzy, kde-format +#| msgid "Inline Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Innfelldur minnismiði" + +#: part/annotationactionhandler.cpp:525 +#, fuzzy, kde-format +#| msgid "Pop-up Note" +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Sprett-athugasemd" + +#: part/annotationactionhandler.cpp:526 +#, fuzzy, kde-format +#| msgid "Freehand Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Fríhendislína" + +#: part/annotationactionhandler.cpp:528 +#, fuzzy, kde-format +#| msgid "Straight Line" +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Bein lína" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "" + +#: part/annotationactionhandler.cpp:530 +#, fuzzy, kde-format +#| msgid "Rectangle" +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rétthyrningur" + +#: part/annotationactionhandler.cpp:531 +#, fuzzy, kde-format +#| msgid "Ellipse" +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Sporbaugur" + +#: part/annotationactionhandler.cpp:532 +#, fuzzy, kde-format +#| msgid "Polygon" +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Marghyrningur" + +#: part/annotationactionhandler.cpp:534 +#, fuzzy, kde-format +#| msgid "Geometrical shape" +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Rúmfræðilögun" + +#: part/annotationactionhandler.cpp:578 +#, fuzzy, kde-format +#| msgid "Stamp" +msgctxt "@action" +msgid "Stamp" +msgstr "Stimpill" + +#: part/annotationactionhandler.cpp:595 +#, fuzzy, kde-format +#| msgid "Annotations" +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Glósur" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "" + +#: part/annotationactionhandler.cpp:602 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "bæta við glósu" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "" + +#: part/annotationactionhandler.cpp:606 +#, fuzzy, kde-format +#| msgid "Create annotation tool" +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Búa til verkfæri fyrir glósur" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "" + +#: part/annotationactionhandler.cpp:617 +#, fuzzy, kde-format +#| msgid "Font:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Letur:" + +#: part/annotationactionhandler.cpp:618 +#, fuzzy, kde-format +#| msgid "Annotation Options" +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Valkostir fyrir glósur" + +#: part/annotationactionhandler.cpp:621 +#, fuzzy, kde-format +#| msgid "Line" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Lína" + +#: part/annotationactionhandler.cpp:630 +#, fuzzy, kde-format +#| msgid "&Opacity:" +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Óge&gnsæi:" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Síða %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Glósa" +msgstr[1] "%1 glósur" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Opna sprett-athugsemd" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Eyða" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Eiginleikar" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "Vi&sta '%1'..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "Ú&tlit" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Almennt" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Höfundur:" + +#: part/annotationpropertiesdialog.cpp:72 +#, fuzzy, kde-format +#| msgid "Created" +msgid "Created:" +msgstr "Búið til" + +#: part/annotationpropertiesdialog.cpp:77 +#, fuzzy, kde-format +#| msgid "Modified" +msgid "Modified:" +msgstr "Breytt" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Eiginleikar sprett-minnismiða" + +#: part/annotationpropertiesdialog.cpp:114 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Typewriter Properties" +msgstr "Eiginleikar innskotsmerkis (caret)" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Eiginleikar innfellds minnismiða" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Eiginleikar beinnar línu" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Eiginleikar marghyrnings" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Eiginleikar forms" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Eiginleikar textamerkingar" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Eiginleikar stimpils" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Eiginleikar fríhendislínu" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Eiginleikar innskotsmerkis (caret)" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Eiginleikar viðhengis" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Eiginleikar hljóðs" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Eiginleikar kvikmyndar" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Eiginleikar glósu" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Afritaði: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "" + +#: part/annotationwidgets.cpp:154 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Put a stamp symbol" +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Setja stimpilmerki" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Litur:" + +#: part/annotationwidgets.cpp:270 +#, fuzzy, kde-format +#| msgid "%" +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "Óge&gnsæi:" + +#: part/annotationwidgets.cpp:358 +#, fuzzy, kde-format +#| msgid "Icon" +msgid "Icon:" +msgstr "Táknmynd" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Athugasemd" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Hjálp" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Setja inn" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Lykill" + +#: part/annotationwidgets.cpp:363 +#, fuzzy, kde-format +#| msgid "New Paragraph" +msgid "New paragraph" +msgstr "Ný málsgrein" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Minnismiði" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Málsgrein" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Letur:" + +#: part/annotationwidgets.cpp:382 +#, fuzzy, kde-format +#| msgid "&Color:" +msgid "Text &color:" +msgstr "&Litur:" + +#: part/annotationwidgets.cpp:389 +#, fuzzy, kde-format +#| msgid "Align:" +msgid "&Align:" +msgstr "Jafna:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Vinstri" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Miðjað" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Hægri" + +#: part/annotationwidgets.cpp:400 +#, fuzzy, kde-format +#| msgid "Border Width:" +msgid "Border &width:" +msgstr "Breidd jaðars:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Samþykkt" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Í núverandi ástandi" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Trúnaðarmál" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Deild" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Uppkast" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Á tilraunastigi" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Lokaútgáfa" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Fyrir athugasemdir" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Fyrir almenna útgáfu" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Ósamþykkt" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Ekki fyrir almenna útgáfu" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Selt" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Algjört leyndarmál" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Bókamerki" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Upplýsingar" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" + +#: part/annotationwidgets.cpp:449 +#, fuzzy, kde-format +#| msgid "Stamp Symbol" +msgid "Stamp symbol:" +msgstr "Stimpiltákn" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, fuzzy, kde-format +#| msgid "&Pen Width:" +msgid "&Width:" +msgstr "&Pennabreidd:" + +#: part/annotationwidgets.cpp:502 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line start:" +msgstr "Lína" + +#: part/annotationwidgets.cpp:504 +#, fuzzy, kde-format +#| msgid "Line" +msgid "Line end:" +msgstr "Lína" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:512 +#, fuzzy, kde-format +#| msgctxt "Symbol for caret annotations" +#| msgid "None" +msgid "None" +msgstr "Enginn" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "" + +#: part/annotationwidgets.cpp:529 +#, fuzzy, kde-format +#| msgid "Leader Line Length:" +msgid "Leader line length:" +msgstr "Lengd bendilínu:" + +#: part/annotationwidgets.cpp:531 +#, fuzzy, kde-format +#| msgid "Leader Line Extensions Length:" +msgid "Leader line extensions length:" +msgstr "Lengd viðbótarbendilínu:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, fuzzy, kde-format +#| msgid "Save file" +msgid "Shape fill:" +msgstr "Vista skrá" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tegund:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Upplitun" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Beygla" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Undirstrikað" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Yfirstrikað" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rétthyrningur" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Sporbaugur" + +#: part/annotationwidgets.cpp:743 +#, fuzzy, kde-format +#| msgid "File Attachment Symbol" +msgid "File attachment symbol:" +msgstr "Tákn fyrir viðhengi" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Línurit" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Teiknibóla" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Bréfaklemma" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Merki" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "Skrá" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "ekki tiltækt" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Engin lýsing tiltæk." + +#: part/annotationwidgets.cpp:771 +#, fuzzy, kde-format +#| msgid "&Name:" +msgid "Name:" +msgstr "&Heiti:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Lýsing:" + +#: part/annotationwidgets.cpp:840 +#, fuzzy, kde-format +#| msgid "Caret Symbol" +msgid "Caret symbol:" +msgstr "Innskotstákn (caret)" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Enginn" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Loka þessum minnismiða" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Valkostir" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Þessi glósa gæti innihaldið LaTeX-kóða.\n" +"Smelltu hér til að myndgera." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Fann ekki latex keyrsluskrána." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "LaTeX myndgerð mistókst" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Fann ekki dvipng keyrsluskrána." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Vandamál kom upp við keyrslu á 'latex' skipuninni." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Vandamál kom upp við keyrslu á 'dvipng' skipuninni." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Eitt bókamerki" +msgstr[1] "" +"%1\n" +"\n" +"%2 bókamerki" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Bókamerki" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, fuzzy, kde-format +#| msgid "S&earch:" +msgid "Search..." +msgstr "L&eita:" + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Eingöngu núverandi skjal" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Fara á þetta bókamerki" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Endurnefna bókamerki" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Fjarlægja bókamerki" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Opna skjal" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Fjarlægja bókamerki" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "" + +#: part/certificateviewer.cpp:123 +#, fuzzy, kde-format +#| msgid "Page Number" +msgid "Serial Number" +msgstr "Blaðsíðutal" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, fuzzy, kde-format +#| msgid "Expired" +msgid "Expires On" +msgstr "Útrunnið" + +#: part/certificateviewer.cpp:131 +#, fuzzy, kde-format +#| msgid "Subject" +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Efni" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "" + +#: part/certificateviewer.cpp:135 +#, fuzzy, kde-format +#| msgid "Memory Usage" +msgid "Key Usage" +msgstr "Minnisnotkun" + +#: part/certificateviewer.cpp:144 +#, fuzzy, kde-format +#| msgid "%1:" +msgid "V%1" +msgstr "%1:" + +#: part/certificateviewer.cpp:156 +#, fuzzy, kde-format +#| msgctxt "File type name and pattern" +#| msgid "%1 (%2)" +msgid "%1 (%2 bits)" +msgstr "%1 (%2)" + +#: part/certificateviewer.cpp:199 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Property" +msgstr "&Eiginleikar" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "" + +#: part/certificateviewer.cpp:214 +#, fuzzy, kde-format +#| msgid "Configure Viewer" +msgid "Certificate Viewer" +msgstr "Stilla skoðara" + +#: part/certificateviewer.cpp:217 +#, fuzzy, kde-format +#| msgid "E&xport As" +msgid "Export..." +msgstr "Fl&ytja út sem" + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Almennt" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "" + +#: part/certificateviewer.cpp:315 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this certificate?" +msgstr "Hvar viltu vista %1?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rautt" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Grænt" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blátt" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Gult" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Svart" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Hvítt" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Teikna ramma í kr&ingum myndir" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Teikna ramma í kringum teng&la" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Breyta &litum" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Athugið: þessir valkostir geta hægt umtalsvert á teiknihraða." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Litahamur:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Snúa við litum" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Breyta blaðsíðulit" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Breyta dökkum og ljósum litum" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Umbreyta í svarthvítt" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Blaðsíðulitur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Dökkur litur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Ljós litur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Þröskuldur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Birtuskil:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Auðkenni" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, fuzzy, kde-format +#| msgid "&Author:" +msgid "Au&thor:" +msgstr "&Höfundur:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, fuzzy, kde-format +#| msgid "" +#| "Note: the information here is used only for comments and reviews. " +#| "Information inserted here will not be transmitted without your knowledge." +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +" Athugsemd: upplýsingarnar hér eru aðeins notaðar fyrir athugasemdir " +"og yfirferð. Það sem hér er sett inn verður ekki sent öðrum án þíns " +"samþykkis." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, fuzzy, kde-format +#| msgid "Edit annotation tool" +msgid "Quick annotation tools" +msgstr "Breyta verkfæri fyrir glósur" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Sérsniðinn textaritill" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs biðlari" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx biðlari" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
\n" +"You can also put few placeholders:\n" +"
    \n" +"
  • %f - the file name
  • \n" +"
  • %l - the line of the file to be reached
  • \n" +"
  • %c - the column of the file to be reached
  • \n" +"
\n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Setur skipun fyrir sérsniðinn textaritil sem á að ræsa.
\n" +"Þú getur líka sett inn nokkrar ígildisbreytur:\n" +"
    \n" +"
  • %f - nafn á skrá
  • \n" +"
  • %l - lína í skrá sem á að meðhöndla
  • \n" +"
  • %c - dálkur í skrá sem á að meðhöndla
  • \n" +"
\n" +"Ef %f er ekki tekið fram, þá verður nafninu bætt við tilgreinda skipun." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Ritill" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Ritill:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Veldu hvaða ritil á að nota þegar Okular þarf að opna skrá með upprunakóða." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Skipun:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Útlit" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Birta s&krunstikur" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "&Tengja smámyndirnar við síðuna" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Birta &vísbendingar og upplýsingaskilaboð" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Birta titil skjals í titilslá ef tiltækur" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Þegar ekki er birtur titil skjals:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Birta einungis skráarheiti" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Birta fulla slóð skráa" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Nota sérsniðinn bakgrunnslit" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Hæfileikar forrits" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Opna nýjar skrár í &flipum" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "Fylgja &DRM takmörkunum" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "Endu&rhlaða skjali við breytingu á skrá" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Birta glugga með vali bakenda" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Lesið frá hægri-til-vinstri" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Valmöguleikar skoðunar" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Yfirlitsdálkar:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "&Upp/Niður skörun síðna:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Sjálfgefinn að&dráttur:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Passa á breidd" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Passa á síðu" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Aðlaga sjálfvirkt" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Heldur minnisnotkun í lágmarki. Ekki endurnota neitt. (Fyrir kerfi með lítið " +"minni.)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Góð málamiðlun á milli minnisnotkunar og hraða. Forhlaða næstu síðu og bæta " +"leitir. (Venjulega fyrir kerfi með 2GB af minni.)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Setja allt í minni. Forhlaða næstu síðu. Auka leitir. (Fyrir kerfi með meira " +"en 4GB af minni.)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Örgjörvanotkun" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "&Leyfa gegnsæi" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Minnisnotkun" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Lítil" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "&Venjuleg (sjálfgefið)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "M&ikil" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "G&ráðug" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Myndgerð" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Virkja afstöllun texta" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Virkja afstöllun myndefnis" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Virkja hnikun texta" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Núverandi skjár" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Sjálfgefinn skjár" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Skjár %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " sekúnda" +msgstr[1] " sekúndur" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Leiðarstýring" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Áfram hverja:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Endurtaka eftir síðustu síðu" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, fuzzy, kde-format +#| msgid "Navigation" +msgid "Touch navigation:" +msgstr "Leiðarstýring" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Bakgrunnslitur:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Músarbendill:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Falinn eftir töf" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Alltaf sýnilegur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Alltaf falinn" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Birta &framvinduvísi" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Birta yfirlit&ssíðu" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Virkja umskiptingar" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Sjálfgefin umskipting:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Lóðréttar gardínur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Láréttar gardínur" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Kassi inn" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Kassi út" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Leysa upp" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Deyfa út" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Glóð niður" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Glóð til vinstri" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Glóð hægri niður" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Slembin umskipting" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Skipta út" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Kljúfa lárétt inn" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Kljúfa lárétt út" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Kljúfa lóðrétt inn" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Kljúfa lóðrétt út" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Fletta niður" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Fletta til hægri" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Fletta til vinstri" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Fletta upp" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Staðsetning" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Skjár:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Uppsetning teikniverkfæris" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Teikniverkfæri: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Strokleður" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Heiti:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tegund:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Sprett-athugasemd" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Innfelldur minnismiði" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Fríhendislína" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Bein lína" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Marghyrningur" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Textamerking" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Rúmfræðilögun" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Stimpill" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Búa til verkfæri fyrir glósur" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Breyta verkfæri fyrir glósur" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Litur:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "&Pennabreidd:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Búa til teikniverkfæri" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Breyta teikniverkfæri" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Óþekkt" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Innbyggðar skrár" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Skoða" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Heiti" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Lýsing" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Stærð" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Búin til" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Breytt" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "Vista &sem..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "S&koða..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Gat ekki opnað prentforskoðunarhlutann" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Forskoða útprentun" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Loka" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "F&inna:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Texti til að leita eftir" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Næsta" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Hoppa í næstu samsvörun" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Fyrri" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Hoppa í fyrri samsvörun" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Breyta leitarhegðun" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Háð há/lágstöfum" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Frá núverandi síðu" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Leita að texta meðan þú skrifar" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Allar skrár" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, fuzzy, kde-format +#| msgid "Caret Properties" +msgid "Signature Properties" +msgstr "Eiginleikar innskotsmerkis (caret)" + +#: part/guiutils.cpp:79 +#, fuzzy, kde-format +#| msgid "Straight Line Properties" +msgid "Straight Line with Comment" +msgstr "Eiginleikar beinnar línu" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "" + +#: part/guiutils.cpp:84 +#, fuzzy, kde-format +#| msgid "For Comment" +msgid "Geometry with Comment" +msgstr "Fyrir athugasemdir" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Form" + +#: part/guiutils.cpp:89 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Highlight text" +msgid "Highlight with Comment" +msgstr "Uppljóma texta" + +#: part/guiutils.cpp:92 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Squiggle text" +msgid "Squiggle with Comment" +msgstr "Beygla texta" + +#: part/guiutils.cpp:95 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Underline text" +msgid "Underline with Comment" +msgstr "Undirstrika texta" + +#: part/guiutils.cpp:98 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Strike out text" +msgid "Strike Out with Comment" +msgstr "Yfirstrika texta" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Gegnumstrikað" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "" + +#: part/guiutils.cpp:106 +#, fuzzy, kde-format +#| msgid "Freehand Line Properties" +msgid "Freehand Line with Comment" +msgstr "Eiginleikar fríhendislínu" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Innskotsmerki (caret)" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "Viðhengi" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Hljóð" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Kvikmynd" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Skjár" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Græja" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Rich Media" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Óþekkt" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Höfundur: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Hvar viltu vista %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "Gat ekki opnað \"%1\" til skrifunar. Skráin var ekki vistuð." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Leitarvalmöguleikar" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Háð há/lágstöfum" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Regluleg segð" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "L&eita:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Lög" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "af" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Aðdráttur" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Snúa til hæg&ri" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Hægri" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Snúa ti&l vinstri" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Vinstri" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Upprunaleg stefna" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "S&kera sýn" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "S&kera af spássíðum" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Skera að vali" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "&Passa á breidd" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "Passa á &síðu" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Aðlaga sjálfvirkt" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Gluggi &passi á síðu" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "&Skoðunarhamur" + +#: part/pageview.cpp:613 +#, fuzzy, kde-format +#| msgid "Single Page" +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Ein síða" + +#: part/pageview.cpp:614 +#, fuzzy, kde-format +#| msgid "Facing Pages" +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Mótstæðar síður" + +#: part/pageview.cpp:615 +#, fuzzy, kde-format +#| msgid "Facing Pages (Center First Page)" +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Mótstæðar síður (fyrsta síða miðjuð)" + +#: part/pageview.cpp:618 +#, fuzzy, kde-format +#| msgid "Overview" +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Yfirlit" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "Á&framhaldið" + +#: part/pageview.cpp:637 +#, fuzzy, kde-format +#| msgid "Right to left reading direction" +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Lesið frá hægri-til-vinstri" + +#: part/pageview.cpp:646 +#, fuzzy, kde-format +#| msgctxt "Browse Tool" +#| msgid "Browse" +msgid "&Browse" +msgstr "Flakka" + +#: part/pageview.cpp:654 +#, fuzzy, kde-format +#| msgid "Zoom" +msgid "&Zoom" +msgstr "Aðdráttur" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Víxla li&tabreytingum" + +#: part/pageview.cpp:676 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "Area &Selection" +msgstr "Textaval" + +#: part/pageview.cpp:685 +#, fuzzy, kde-format +#| msgctxt "Text Selection Tool" +#| msgid "Text Selection" +msgid "&Text Selection" +msgstr "Textaval" + +#: part/pageview.cpp:693 +#, fuzzy, kde-format +#| msgctxt "Table Selection Tool" +#| msgid "Table Selection" +msgid "T&able Selection" +msgstr "Töfluval" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Skjástækkun" + +#: part/pageview.cpp:715 +#, fuzzy, kde-format +#| msgid "Selection Tools" +msgctxt "@action" +msgid "Selection Tools" +msgstr "Valverkfæri" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Lesa upp allt skjalið" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Lesa upp núverandi síðu" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Stöðva tal" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Renna upp" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Renna niður" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Renna síðu upp" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Renna síðu niður" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Birta form" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] " Hlóð inn einnar síðu skjali." +msgstr[1] " Hlóð inn %1-síðu skjali." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Texti (1 stafur)" +msgstr[1] "Texti (%1 stafir)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Afrita á klippispjald" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Afritun bönnuð með DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Tala texta" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Mynd (%1 x %2 punktar)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Vista í skrá..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Mynd [%1x%2] afrituð á klippispjald." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Vista skrá" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Myndir (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Skrá ekki vistuð." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Mynd [%1x%2] vistuð í %3 skrá." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Afrita texta" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Fara á '%1'" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Leita að '%1' með" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Stilla vefskammstafanir..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Fylgja þessum tengli" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Spila þetta hljóð" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Stöðva hljóð" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Afrita vistfang tengils" + +#: part/pageview.cpp:4205 +#, fuzzy, kde-format +#| msgid "Search for '%1' with" +msgid "Search for '%1' in this document" +msgstr "Leita að '%1' með" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Velkomin(n)" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "Veldu stækkunarsvæði. Hægrismelltu til að renna frá." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Smelltu til að sjá stækkaða sýn." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Dragðu kassa yfir textann/myndina sem þú vilt afrita." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Velja texta" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Dragðu ferhyrnt svæði í kringum töfluna, smelltu nálægt jöðrum til að skipta " +"upp; ýttu á Esc til að hreinsa." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Dragðu kassa yfir svæðið á síðunni sem þú vilt halda sýnilegu." + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nýr textaminnismiði" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Texti á nýjum minnismiða:" + +#: part/pageviewannotator.cpp:963 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Bookmark annotation" +msgstr "bæta við glósu" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Teikna sporbaug (draga til að velja svæði)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Uppljóma texta" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Teikna fríhendislínu" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Innfelld textaglósa (draga til að velja svæði)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Setja inn sprett-athugasemd" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Draga marghyrning (smella á fyrsta punkt til að loka)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Teikna rétthyrning" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Beygla texta" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Setja stimpilmerki" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Teikna beina línu" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Yfirstrika texta" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Undirstrika texta" + +#: part/pageviewannotator.cpp:1045 +#, fuzzy, kde-format +#| msgctxt "Annotation tool" +#| msgid "Inline Text Annotation (drag to select a zone)" +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Innfelld textaglósa (draga til að velja svæði)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Uppljómun" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Add an annotation to the page" +#| msgid "add annotation" +msgid "Add favorite annotation" +msgstr "bæta við glósu" + +#: part/pageviewannotator.cpp:1389 +#, fuzzy, kde-format +#| msgctxt "Change an annotation's size" +#| msgid "adjust annotation" +msgid "Custom annotation name:" +msgstr "laga glósu" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&Skrá" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "S&tillingar" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "&Hjálp" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "S&tefna" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "&Bókamerki" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Verkfærastika fyrir skoðara" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Smámyndir" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Glósur" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Þetta skjal inniheldur innfelldar skrár. Smelltu hér til að sjá þær eða farðu í 'Skrá -> Innfelldar skrár'." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Fyrri" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Fara til baka á síðuna sem þú varst áður á" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Fer á fyrri síðu skjalsins" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Næsta" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Áfram á næstu síðu" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Fer á næstu síðu skjalsins" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Upphaf skjalsins" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Fer á upphaf skjalsins" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Endir skjalisins" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Fer á enda skjalsins" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Endurnefna þetta bókamerki" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Fyrra bókamerki" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Fara á fyrra bókamerki" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Næsta bókamerki" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Fara á næsta bókamerki" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Stilla Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Stilla skoðara..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Stilla skoðunarbakenda..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Stilla bakenda..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Um bakenda" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "En&durlesa" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Endurhlaða skjalinu frá diski." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Loka &leitarslá" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Blaðsíðutal" + +#: part/part.cpp:827 +#, fuzzy, kde-format +#| msgid "Speak Current Page" +msgid "Select All Text on Current Page" +msgstr "Lesa upp núverandi síðu" + +#: part/part.cpp:840 +#, fuzzy, kde-format +#| msgid "Show &Page Bar" +msgid "Show S&idebar" +msgstr "Birta &blaðsíðustiku" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Birta &blaðsíðustiku" + +#: part/part.cpp:854 +#, fuzzy, kde-format +#| msgid "Show &Navigation Panel" +msgid "Show &Signatures Panel" +msgstr "Birta stjór&nunarspjald" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "&Innfelldar skrár" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "Fl&ytja út sem" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "&Deila" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "&Kynning" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Flytja inn PostScript sem PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Sæ&kja bækur af internetinu..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Skipta um ham svartskjás" + +#: part/part.cpp:922 +#, fuzzy, kde-format +#| msgid "Erase Drawings" +msgid "Erase Drawing" +msgstr "Eyða teikningum" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Stilla glósur..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Spila/gera hlé á kynningu" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Gat ekki opnað '%1' (%2) " + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Hætt hefur verið við hleðslu %1." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Gat ekki opnað %1. Ástæða: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Stilla skoðunarbakenda" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Stilla bakenda" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Forritið \"ps2pdf\" fannst ekki, þannig að Okular getur ekki notað það til " +"að flytja inn PS skrár." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf fannst ekki" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "PostScript-skrár (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "Flyt inn PS-skrá sem PDF (þetta gæti teki tíma)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Gefðu upp lykilorðið til að lesa skjalið:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Rangt lykilorð. Reyndu aftur:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Lykilorð á skjali" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Þetta skjal inniheldur form. Smelltu á hnappinn til að vinna með þau, eða " +"notaðu 'Skoða -> Sýna form'." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" + +#: part/part.cpp:1560 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "This document is digitally signed." +msgstr "Prentun af skjalinu er ekki leyfð." + +#: part/part.cpp:1563 +#, fuzzy, kde-format +#| msgid "Printing this document is not allowed." +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "Prentun af skjalinu er ekki leyfð." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Fara í kynningarham" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Hafna beiðni" + +#: part/part.cpp:1734 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not open %1. %2" +msgstr "Gat ekki opnað %1" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue reloading the file?" +msgstr "" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "Skrá breytt" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Halda áfram með endurlestur" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Hætta við endurlestur" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
Do you want to continue closing the file?" +msgstr "" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Halda áfram með lokun" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Hætta við lokun" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Viltu vista breytingar þínar á \"%1\" eða henda þeim?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Loka skjali" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Þessi tengill bendir á aðgerð sem lokar skjali og virkar ekki með ívöfnum " +"skoðara." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Þessi tengill bendir á aðgerð sem lokar forritun og virkar ekki með ívöfnum " +"skoðara." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Endurles skjalið..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Innihald" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Fara á síðu" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Síða:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Sláðu inn nýja heitið á bókamerkinu:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Endurnefna þetta bókamerki" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Fjarlægja þetta bókamerki" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Vista sem" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Skránni '%1' hefur verið breytt af öðru forriti, sem þýðir að ekki er lengur " +"hægt að vista hana." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Vistun - Aðvörun" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Get ekki opnað bráðabirgðaskrá fyrir vistun." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
Do you want to continue?" +msgstr "" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "" +"Ekki tókst að vista skrána í '%1'. Reyndu að vista hana á annarri " +"staðsetningu." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Innihald útfyllts forms" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Glósur notandans" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Aðvörun" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Vista sem Okular skjalasafnskrá..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Áfram" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Halda áfram og tapa breytingum" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Ekki tókst að vista skrána í ''%1'. %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular getur ekki afritað %1 á tilgreinda staðsetningu.\n" +"\n" +"Skjalið virðist ekki vera til lengur." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Ekki tókst að vista skrána í '%1'. Villa: '%2'. Reyndu að vista hana á " +"annarri staðsetningu." + +#: part/part.cpp:2929 +#, fuzzy, kde-format +#| msgid "End Presentation" +msgid "Expand whole section" +msgstr "Enda kynningu" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Setja bókamerki" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Verkfæri" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Prenta" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "Prentun af skjalinu er ekki leyfð." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Gat ekki prentað skjalið. Óþekkt villa. Sendu inn villuskýrslu til bugs.kde." +"org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Gat ekki prentað skjalið. Útlistuð villa var \"%1\". Sendu inn villuskýrslu " +"til bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Fara þangað sem þú varst síðast" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Fara þangað sem þú varst eftir" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Skráarvilla! Gat ekki búið til bráðabirgðaskrá " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Skráarvilla! Gat ekki opnað skrá %1 til að afþjappa hana. Skránni verður ekki hlaðið inn." + +#: part/part.cpp:3345 +#, fuzzy, kde-format +#| msgid "" +#| "This error typically occurs if you do not have enough permissions to " +#| "read the file. You can check ownership and permissions if you right-click " +#| "on the file in the Dolphin file manager and then choose the 'Properties' " +#| "tab." +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Þessi villa gerist venjulega ef þú ert ekki með nægar heimildir til að " +"lesa skrána. Þú getur athugað með eiganda og heimildir með því að " +"hægrismella á skrána í Dolphin skráastjóranum og velja síðan flipann " +"'Eiginleikar'." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Skráarvilla! Gat ekki afþjappað skrána " +"%1. Skránni verður ekki hlaðið inn." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Þessi villa kemur venjulega upp þegar skráin er skemmd. Ef þú vilt " +"fullvissa þig um það, reyndu að afþjappa hana með því að nota skipunarlínu-" +"tól." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Engin bókamerki" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Vandamál kom upp við að deila skjalinu: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Deila" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Tókst að deila skjali" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Þú getur fundið deilda skjalið á: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Breyta" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "S&koða" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Fara" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "Verk&færi" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Aðalverkfæraslá" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, fuzzy, kde-format +#| msgid "Annotation tools" +msgid "Annotation Toolbar" +msgstr "Verkfæri fyrir glósur" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Almennir valkostir" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Aðgengi" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Hjálpartæki fyrir lestraraðgengi" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Afköst" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Fínstilling afkasta" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Stilla skoðara" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Kynning" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Stillingar fyrir kynningarham" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Valkostir fyrir glósur" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Valmöguleikar ritils" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Finna næsta" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 - Kynning" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Skipta um skjá" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Skjár %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Fara úr kynningarham" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titill: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Síður: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Smelltu til að byrja" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Gera hlé" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Afspilun" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Það eru tvær leiðir til að hætta í kynningarham. Þú getur annað hvort smellt " +"á ESC hnappinn eða smellt á hnappinn sem kemur fram þegar músin er færð í " +"hægra hornið uppi. Auðvitað getur þú hringað gluggum (Alt + TAB er " +"sjálfgefið til þess)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Halda kynningu" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "Óþekkt skrá" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "%1 eiginleikar" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Letur" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Les upplýsingar um letur..." + +#: part/propertiesdialog.cpp:160 +#, fuzzy, kde-format +#| msgid "&Page Size" +msgid "&Page Sizes" +msgstr "&Blaðsíðustærð" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "Afþjappa l&etri" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Type 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Type 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Type 1C (OT)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Type 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OT)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID Type 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID Type 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID Type 0C (OT)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OT)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX sýndar" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "TeX leturmálsetningar" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX FreeType-meðhöndlað" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Óþekkt" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Innfellt (aðeins notaðir stafir - subset)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Allt innfellt" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "Nei" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Já (aðeins notaðir stafir - subset)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Já" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/a]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Óþekkt letur" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Innfellt %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Heiti" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tegund" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "Skrá" + +#: part/propertiesdialog.cpp:489 +#, fuzzy, kde-format +#| msgid "Pages" +msgid "Page" +msgstr "Síður" + +#: part/propertiesdialog.cpp:492 +#, fuzzy, kde-format +#| msgctxt "@title:column" +#| msgid "Size" +msgid "Size" +msgstr "Stærð" + +#: part/revisionviewer.cpp:44 +#, fuzzy, kde-format +#| msgid "Print Preview" +msgid "Revision Preview" +msgstr "Forskoða útprentun" + +#: part/revisionviewer.cpp:56 +#, fuzzy, kde-format +#| msgid "Where do you want to save %1?" +msgid "Where do you want to save this revision?" +msgstr "Hvar viltu vista %1?" + +#: part/revisionviewer.cpp:59 +#, fuzzy, kde-format +#| msgid "Could not open %1" +msgid "Could not save file %1." +msgstr "Gat ekki opnað %1" + +#: part/revisionviewer.cpp:78 +#, fuzzy, kde-format +#| msgid "Could not open %1. Reason: %2" +msgid "Could not view revision." +msgstr "Gat ekki opnað %1. Ástæða: %2" + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Sláðu inn að minsta kosti 3 stafi til að sía síðurnar" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Háð há/lágstöfum" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Passar við setningu" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Passar við öll orð" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Passar við eitthvað orð" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Valmöguleikar síu" + +#: part/side_reviews.cpp:68 +#, fuzzy, kde-format +#| msgid "" +#| "

No annotations

To create new annotations press " +#| "F6 or select Tools -> Review from the menu.
" +msgid "" +"

No annotations

To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
" +msgstr "" +"

Engar glósur

Til að búa til nýjar glósur ýttu á " +"F6 eða veldu Verkfæri -> Yfirfara frá aðalvalmyndinni
" + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Hópa eftir síðu" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Hópa eftir höfundi" + +#: part/side_reviews.cpp:153 +#, fuzzy, kde-format +#| msgid "Show reviews for current page only" +msgid "Show annotations for current page only" +msgstr "Aðeins sýna yfirferð fyrir núverandi síðu" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "" + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "" + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "" + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "" + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "" + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "" + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "" + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "" + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "" + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "" + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "" + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "" + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "" + +#: part/signatureguiutils.cpp:92 +#, fuzzy, kde-format +#| msgid "Unknown font" +msgid "Unknown Algorithm" +msgstr "Óþekkt letur" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, fuzzy, kde-format +#| msgid "Unknown File" +msgid "Unknown Type" +msgstr "Óþekkt skrá" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr "" + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, fuzzy, kde-format +#| msgid "No description available." +msgid "Not Available" +msgstr "Engin lýsing tiltæk." + +#: part/signaturemodel.cpp:145 +#, fuzzy, kde-format +#| msgid "Pages: %1" +msgid "Reason: %1" +msgstr "Síður: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "" + +#: part/signaturepanel.cpp:97 +#, fuzzy, kde-format +#| msgid "&Properties" +msgid "Properties" +msgstr "&Eiginleikar" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:74 +#, fuzzy, kde-format +#| msgid "Information" +msgid "Additional Information" +msgstr "Upplýsingar" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:80 +#, fuzzy, kde-format +#| msgid "Annotation" +#| msgid_plural "%1 Annotations" +msgid "Location:" +msgstr "Glósa" + +#: part/signaturepropertiesdialog.cpp:90 +#, fuzzy, kde-format +#| msgctxt "A document format, Okular-specific" +#| msgid "Document Archive" +msgid "Document Version" +msgstr "Safnskrá skjals" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "" + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "" + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Aðeins sýna bókamerktar síður" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Spila" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Gera hlé" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Stöðva" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "Bæt&a við..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "Br&eyta..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Fjarlægja" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Færa &upp" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Færa &niður" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Sjálfgefið teikniverkfæri #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "Það finnst þegar verkfæri með þessu nafni. Nota sjálfgefið" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Endurtekið nafn" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Síða skjals sem á að sýna" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Ræsa skjalið í kynningarham" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Byrja með prentglugga" + +#: shell/main.cpp:78 +#, fuzzy, kde-format +#| msgid "Start with print dialog" +msgid "Start with print dialog and exit after printing" +msgstr "Byrja með prentglugga" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Stjórnun fyrir \"Sértækt tilvik\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Ekki lyfta glugga" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "Skjal til opna. Tilgreindu '-' til að lesa frá stdin." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Get ekki fundið Okular einingu: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Get ekki fundið Okular einingu." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Smelltu til að opna skrá\n" +"Smelltu og haltu niðri til að opna nýlega skrá" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Smelltu til að opna skrá eða smelltu og haltu niðri til að " +"velja nýlega opnaða skrá" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Næsti flipi" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Fyrri flipi" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Allar skrár (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Allar studdar skrár (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Opna skjal" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Staðfesta lokun" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Loka flipum" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "" +"Þú ert að fara að loka %1 flipum. Ertu viss um að þú viljir halda áfram?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Aðvara þegar mörgum flipum er lokað" + +#~ msgid "Reviews" +#~ msgstr "Umsagnir" + +#, fuzzy +#~| msgid "%1:" +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1:" + +#~ msgid "Hide Forms" +#~ msgstr "Fela form" + +#~ msgid "Expired" +#~ msgstr "Útrunnið" + +#~ msgid "&Review" +#~ msgstr "&Yfirfara" + +#~ msgid "Annotations author" +#~ msgstr "Höfundur glósa" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Settu inn nafn þitt eða upphafsstafi:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Birta stjór&nunarspjald" + +#~ msgid "Show Text" +#~ msgstr "Birta texta" + +#~ msgid "Small Icons" +#~ msgstr "Litlar táknmyndir" + +#~ msgid "Normal Icons" +#~ msgstr "Venjulegar táknmyndir" + +#~ msgid "Large Icons" +#~ msgstr "Stórar táknmyndir" + +#, fuzzy +#~| msgid "" +#~| "Click to use the current selection tool\n" +#~| "Click and hold to choose another selection tool" +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Smella til að nota núverandi valverkfæri\n" +#~ "Smelltu og haltu niðri til að velja annað valverkfæri" + +#~ msgid "Created: %1" +#~ msgstr "Búið til: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Línuviðbætur" + +#~ msgid "Style" +#~ msgstr "Stíll" + +#~ msgid "&Size:" +#~ msgstr "&Stærð:" + +#~ msgid "Inner color:" +#~ msgstr "Innri litur:" + +#~ msgid "Name: %1" +#~ msgstr "Nafn: %1" + +#~ msgid "Size: %1" +#~ msgstr "Stærð: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "&Skoðunarverkfæri" + +#~ msgid "&Zoom Tool" +#~ msgstr "S&tækkunarVverkfæri" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Aðdráttur" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Val" + +#~ msgid "&Text Selection Tool" +#~ msgstr "&Textavalsverkfæri" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Töfluv&alsverkfæri" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Skjástækkun" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Endir skjalisins" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Enginn" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Þessi skrá verður opnuð í kynningarham því skráin bað um það.\n" +#~ "Viltu leyfa það?" + +#~ msgid "Presentation Mode" +#~ msgstr "Kynningarhamur" + +#~ msgid "Allow" +#~ msgstr "Leyfa" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Leyfa kynningarham" + +#~ msgid "Do Not Allow" +#~ msgstr "Ekki leyfa" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Ekki leyfa kynningarham" + +#~ msgid "Save &Copy As..." +#~ msgstr "&Vista afrit sem..." + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Enda skjals náð.\n" +#~ "Halda áfram frá byrjun?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Byrjun skjals náð.\n" +#~ "Halda áfram frá enda?" + +#~ msgid "Current maintainer" +#~ msgstr "Núverandi umsjónarmaður" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sek." + +#~ msgid "Pencil color:" +#~ msgstr "Blýantslitur:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "lárétt DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "lóðrétt DIN/ISO A0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "lárétt DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "lóðrétt DIN/ISO A1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "lárétt DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "lóðrétt DIN/ISO A2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "lárétt DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "lóðrétt DIN/ISO A3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "lárétt DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "lóðrétt DIN/ISO A4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "lárétt DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "lóðrétt DIN/ISO A5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "lárétt DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "lóðrétt DIN/ISO A6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "lárétt DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "lóðrétt DIN/ISO A7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "lárétt DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "lóðrétt DIN/ISO A8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "lárétt DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "lóðrétt DIN/ISO A9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "lárétt DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "lóðrétt DIN/ISO B0" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "lárétt DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "lóðrétt DIN/ISO B1" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "lárétt DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "lóðrétt DIN/ISO B2" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "lárétt DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "lóðrétt DIN/ISO B3" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "lárétt DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "lóðrétt DIN/ISO B4" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "lárétt DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "lóðrétt DIN/ISO B5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "lárétt DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "lóðrétt DIN/ISO B6" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "lárétt DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "lóðrétt DIN/ISO B7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "lárétt DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "lóðrétt DIN/ISO B8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "lárétt DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "lóðrétt DIN/ISO B9" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "lárétt DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "lóðrétt DIN/ISO B10" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "lárétt bréfsefni (letter)" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "lóðrétt bréfsefni (letter)" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "lárétt löggilt" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "lóðrétt löggilt" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "lárétt formlegt (executive)" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "lóðétt formlegt (executive)" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "lárétt Comm10E" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "lóðétt Comm10E" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "lárétt DLE" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "lóðétt DLE" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "lárétt folio" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "lóðétt folio" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "höfuðbók (ledger)" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "dagblaðssnið (tabloid)" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "óþekkt lárétt pappírsstærð" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "óþekkt lóðrétt pappírsstærð" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Víxla teikniham af/á" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Ræsing Jovie Texti-í-tal þjónustunnar mistókst: %1" + +#~ msgid "Search Columns" +#~ msgstr "Leitardálkar" + +#~ msgid "All Visible Columns" +#~ msgstr "Allir sýnilegir dálkar" + +#~ msgid "No document opened." +#~ msgstr "Ekkert skjal opnað." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Engar samsvaranir fundust fyrir '%1'." + +#~ msgid "Search in progress..." +#~ msgstr "Leit í gangi..." + +#~ msgid "Searching for %1" +#~ msgstr "Leita að %1" + +#~ msgid "Identity Settings" +#~ msgstr "Stillingar auðkennis" + +#~ msgid "Highlight Properties" +#~ msgstr "Eiginleikar upplitunar" + +#~ msgid "Ink Properties" +#~ msgstr "Eiginleikar bleks" + +#~ msgctxt "Annotation tool" +#~ msgid "Text Annotation" +#~ msgstr "Athugasemd" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Grænt blek" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Gul áherslustrikun" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Gul áherslustrikun" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Bein gul lína" + +#~ msgid "Black Underlining" +#~ msgstr "Svört undirlína" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Undirstrika texta með svartri línu" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Blágrænn sporbaugur" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Blágrænn sporbaugur" + +#~ msgid "Ink" +#~ msgstr "Blek" + +#~ msgid "Enable &background generation" +#~ msgstr "Leyfa &bakgrunnsvinnslu" + +#~ msgid "Reset Forms" +#~ msgstr "Frumstilla eyðublað" diff --git a/po/is/okular_chm.po b/po/is/okular_chm.po new file mode 100644 index 0000000..3d804c1 --- /dev/null +++ b/po/is/okular_chm.po @@ -0,0 +1,62 @@ +# translation of okular_chm.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" + +#~ msgid "CHM Backend" +#~ msgstr "CHM bakend" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Myndgerir Microsoft Windows hjálparskjöl" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/is/okular_comicbook.po b/po/is/okular_comicbook.po new file mode 100644 index 0000000..b5b0b37 --- /dev/null +++ b/po/is/okular_comicbook.po @@ -0,0 +1,61 @@ +# translation of okular_comicbook.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: document.cpp:98 +#, fuzzy, kde-format +#| msgid "Cannot open document, unrar was not found." +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "Gat ekki opnað skjalið, unrar fannst ekki" + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"Útgáfan af unrar á vélinni þinni er ekki nothæf til að opna comicbook skrár." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Óþekkt ComicBook snið." + +#~ msgid "ComicBook Backend" +#~ msgstr "ComicBook bakendi" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Myndgerir ýmsar tegundir comic book skráasniða" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/is/okular_djvu.po b/po/is/okular_djvu.po new file mode 100644 index 0000000..7d06813 --- /dev/null +++ b/po/is/okular_djvu.po @@ -0,0 +1,138 @@ +# translation of okular_djvu.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Ritill" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Útgefandi" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Bindi" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tegund skjals" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Óþekkt" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "Byggt á skrám" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Óþekkt" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Ein síða" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Vöndlað" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Óbeint" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Vöndlað (gamalt)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Flokkað (gamalt)" + +#~ msgid "DjVu Backend" +#~ msgstr "DjVu bakendi" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "DjVu bakendi byggður á DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Óþekkt" diff --git a/po/is/okular_dvi.po b/po/is/okular_dvi.po new file mode 100644 index 0000000..26f7919 --- /dev/null +++ b/po/is/okular_dvi.po @@ -0,0 +1,738 @@ +# translation of okular_dvi.po to icelandic +# Copyright (C) 2008, 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2009, 2013, 2014, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

" +msgstr "" +"

Okular gat ekki fundið dvipdfm forritið á tölvunni. Þetta " +"forrit er nauðsynlegt til að útflutningur skráa virki sem skyldi. Þú gæti " +"hinsvegar umbreytt DVI-skránni í PDF með því að nota 'prentun í skrá' skipun " +"Okular, en það býr hinsvegar til skjöl sem vissulega prentast ágætlega, en " +"eru ekki í neitt sérstökum gæðum þegar þau eru skoðuð í forriti eins og " +"Acrobat Reader. Það gæti verið gáfulegt að uppfæra TeX dreifinguna þína, sem " +"ætti að innihalda dvipdfm forritið.

Vísbending til ráðvilltra " +"kerfisstjóra: Okular notar PATH umhverfisbreytuna við að leita að forritum." + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Forritið 'dvipdfm' sem var notað til að flytja út DVI skrána skilaði " +"villu. Þú gætir viljað líta á upplýsingar um skjal sem þú " +"finnur í Skrá-valmyndinnitil að fá nákvæma villumeldingu. " + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Þessi DVI skrá er með tilvísanir í myndefni sem ekki eru á PostScript " +"formi, og er því ekki hægt að meðhöndla með dvips forritinu sem " +"Okular notar til að prenta eða umbreyta myndum í PostScript. Það er á áætlun " +"að bæta þessari virkni við síðar." + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

" +msgstr "" +"

Okular gat ekki fundið dvips á tölvunni. Þetta forrit er " +"nauðsynlegt til að útflutningur skráa virki sem skyldi.\n" +"Vísbending til ráðvilltra kerfisstjóra: Okular notar PATH umhverfisbreytuna " +"við að leita að forritum.

" + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Forritið 'dvips' sem var notað til að flytja út DVI skrána skilaði " +"villu. Þú gætir viljað líta á upplýsingar um skjal sem þú " +"finnur í Skrá-valmyndinnitil að fá nákvæma villumeldingu. " + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Formála (e. preamble) vantar í DVI skrána." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"DVI skráin inniheldur ranga útgáfu af DVI úttaki fyrir þetta forrit. " +"Vísbending: Ef þú notar letursetningarkerfið Omega, verðurðu að nota " +"sérstakt forrit, eins og oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "" +"DVI skráin er illa skemmd. KDVI gat ekki fundið eftirmálann (e. postamble)." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Eftirmáli (e. postamble) byrjar ekki á POST skipun." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Eftirmálinn (e. postamble) innihélt aðra skipun en FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "Síðan %1 hefst ekki með BOP skipun." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

PATH: %2

" +msgstr "" +"

Ekki tókst að ræsa ytra forrritið pdf2ps. Þar af " +"leiðandi tókst ekki að umbreyta PDF-skránni %1 yfir í PostScript. Sumt af " +"myndefninu í skjalinu þínu verður því ekki birt.

Hugsanleg ástæða: Forritið pdf2ps er kannski ekki uppsett á kerfinu þínu, " +"eða að það finnst ekki á gildri leitarslóð.

Það sem þú getur gert: Forritið pdf2ps fylgir venjulega með í helstu dreifingum " +"ghostscript PostScript túlkunarkerfisins. Ef ghostscipt er ekki uppsett á " +"kerfinu þínu, þá gætirðu sett það upp núna. Ef þú ert viss um að ghostscript " +"sé þegar uppsett, reyndu að slá inn pdf2ps á skipanalínu " +"til að athuga hvort það virki í raun og veru.

SLÓÐ: %2

" + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

%2

" +msgstr "" +"

Ekki var hægt að umbreyta PDF-skránni %1 yfir í PostScript. Eitthvað " +"af myndefni skjalsins verður því ekki birt.

Hugsanleg ástæða: " +"Skráin %1 gæti verið skemmd, eða er kannski alls ekki PDF-skrá. Þetta er " +"úttak pdf2ps forritsins sem Okular notaði:

" +"%2

" + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "Skemmd skrá. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "Ekki var hægt að ígræða allar PostScript-skrár í skjalið þitt. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "Allar ytri PostScript-skrár voru felldar inn í skjalið þitt." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Umbeðna skráin '%1' er ekki til." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Þú vildir að Okular fyndi staðinn í DVI-skránni sem samsvarar línunni %1 í " +"TeX-skránni %2. Það lítur hinsvegar út fyrir að DVI-skráin innihaldi ekki " +"allar nauðsynlegar upplýsingar hvað það varðar. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular tókst ekki að finna staðinn í DVI-skránni sem samsvarar línunni %1 í " +"TeX-skránni %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "DVI kóði setti tákn af óþekktri leturgerð." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "DVI kóðinn vísaði í leturgerð #%1, sem hefur ekki verið skilgreind." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Staflinn var ekki tómur þegar komið var að EOP skipuninni." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Staflinn var tómur þegar komið var að POP skipuninni." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "DVI kóðinn vísaði í leturgerð sem hefur ekki verið skilgreind." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "Ólögleg skipun fundin." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "Óþekkti op-kóðinn %1 fannst." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Innfelli %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
" +msgstr "" +"Síða %1: Ekki tókst að umbreyta PDF skránni %2 yfir í " +"PostScript.
" + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
" +msgstr "Síða %1: PostScript skráin %2 fannst ekki.
" + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "Ekki tókst að þátta pappírsstærð '%1'." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

PATH: %1

%2

" +msgstr "" +"

Okular gat ekki fundið allar þær leturskrár sem til þurfti til " +"birtingar á þessari DVI skrá. Skjalið þitt gæti verið ólesanlegt.

SLÓÐ: %1

%2

" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

PATH: %1

%2

" +msgstr "" +"

Það voru vandamál við keyrslu kpsewhich. Þar af leiðandi " +"fundust ekki allar þær leturskrár sem til þurfti, skjalið þitt gæti verið " +"ólesanlegt.
Hugsanleg ástæða: Kannski er kpsewhich forritið " +"ekki sett upp á kerfinu þínu, nú eða að það finnst ekki á núverandi " +"leitarslóð (search path).

SLÓÐ: %1

" +"%2

" + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"Gerð leturs með kpsewhich var hætt (exit code %1, villa %2). Af " +"því leiðir að sumar leturskrár fundust ekki og skjalið þitt gæti hugsanlega " +"verið ólesanlegt." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Bý nú til %1 í %2 pát..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Höfundur/dagsetning" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Leturskrá fannst ekki" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "lóðrétt" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "lárétt" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"Útgáfan af Ghostview sem er uppsett á tölvunni er ekki með neinum Ghostview " +"tækjareklum (device drivers) sem Okular þekkir. Þess vegna hefur PostScript " +"stuðningur verið gerður óvirkur í Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

" +msgstr "" +"

Ghostview forritið, sem Okular notar til að sýna PostScript myndirnar " +"sem eru í DVI skránni, er venjulega fært um að skrifa útkomuna í margar " +"gerðir skráasniða. Undirforritin sem Ghostview notar til slíkra aðgerða eru " +"oftast kölluð tækjareklar eða 'device drivers'; það er semsagt einn " +"tækjarekill fyrir hvert snið sem Ghostview getur skrifað. Mismunandi útgáfur " +"Ghostview innihalda oft mismunandi 'sett' af þessum reklum. Það lítur út " +"fyrir að sú útgafa Ghostview sem er uppsett á þessari tölvu innihaldi " +"engann af þeim tækjareklum sem Okular þekkir.

Það er " +"ólíklegt að nokkur almenn útgáfa af Ghostview myndi ekki innihalda þessa " +"rekla. Þar með gæti þessi villa bent til alvarlegra vandamála eða galla á " +"Ghostview uppsetningunni á tölvunni.

Til að fá nánari hugmynd um " +"vandamálið gætirðu gefið skipunina gs --help til að sjá " +"hvaða reklar eru uppsettir fyrir Ghostview. Meðal rekla sem Okular getur " +"notað eru 'png256', 'jpeg' og 'pnm' reklarnir. Athugaðu að Okular verður að " +"endurræsa til að koma á PostScript stuðningi.

" + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Það gera 25 villur. Fleiri villuboð verða ekki prentuð." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Villa í DVI skrá '%1', síða %2. Skipun um að tína lit af stafla þegar " +"litastafli er tómur." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Gallað viðfang í epsf-sérskipuninni.\n" +"Átti von á tölu á eftir %1 í %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"Skráin fannst ekki:\n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Villa í DVI skrá '%1', síða %2. Gat ekki túlkað horn í sérstökum " +"textasnúningi." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Sérskipunin '%1' er ekki studd." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Leturgerðaskráin %1 var opnuð og lesin, en enginn stuðningur er fyrir sniðið " +"á henni." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "Leturgerðarskráin %1 er biluð eða ekki hægt að opna hana eða lesa." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType tilkynnti villu við að setja táknastærð fyrir leturgerðaskrá %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "FreeType getur ekki hlaðið inn stafbrigði #%1 úr leturskrá %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "FreeType getur ekki gengið frá stafbrigði #%1 úr leturskrá %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Stafbrigðið #%1 er tómt." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Stafbrigðið #%1 úr leturgerðaskrá %2 er tóm." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType getur ekki hlaðið inn leturmálum fyrir stafbrigði #%1 úr " +"leturgerðaskrá %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Get ekki opnað leturskrá %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "TexFont_PK::operator[]: Táknið %1 er ekki til í letri %2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "Óvænt %1 í PK skránni %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Táknið %1 er of stórt í skránni %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Rangur fjöldi bita: stafur %1, letur %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "Gölluð PK-skrá (%1), of margir bitar" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Letrið er ekki í fernings-hlutföllum " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Get ekki fundið letur %1, skrá %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Gátsumma stemmir ekki fyrir leturskrá %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Þekki ekki snið leturskrárinnar %1" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Banvæn villa.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Þetta þýðir að öllum líkindum að annaðhvort hefur þú fundið galla í Okular,\n" +"eða þá að DVI skráin, eða aukaskrár (svo sem leturskrár, \n" +"eða sýndarletur) eru verulega skemmdar.\n" +"Okular mun slökkva á sér eftir þessi skilaboð. Ef þú heldur að þú \n" +"hafir vundið galla, eða að Okular ætti að haga sér öðruvísi við þessar " +"aðstæður\n" +"þá ættirðu að senda villuskýrslu." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "Ógilt skipanabæti fannst í VF-fjölvalista: %1" + +#~ msgid "DVI Backend" +#~ msgstr "DVI bakendi" + +#~ msgid "A DVI file renderer" +#~ msgstr "Myndgerð DVI skráa" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

" +#~ msgstr "" +#~ "

Okular treystir á kpsewhich forritið til að finna leturskrár á " +#~ "harða disknum þínum og til að búa til PK letur ef það er nauðsynlegt.

" + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular er núna að búa til bitamyndaletur..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Hættir við aðgerðina. Ekki gera það." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular er núna að búa til bitamyndaletur sem er nauðsynlegt til að birta " +#~ "skjalið. Okular þarf að nota ymis ytri forrit til þessarar aðgerðar, svo " +#~ "sem MetaFont. Hægt er að sjá síðar tilkynningar frá þessum forritum, í " +#~ "upplýsingaglugga skjalsins." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular er að búa til letur. Vinsamlega bíða." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Samskiptagluggi leturgerðarframvindu" + +#~ msgid "Abort" +#~ msgstr "Hætta við" + +#~ msgid "What is happening here?" +#~ msgstr "Hvað er í gangi hérna?" + +#~ msgid "%v of %m" +#~ msgstr "%v af %m" + +#~ msgid "Please be patient" +#~ msgstr "Sýndu þolinmæði" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Flytja skrá út sem" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Skráin %1\n" +#~ "er þegar til. Viltu skrifa yfir hana?" + +#~ msgid "Overwrite File" +#~ msgstr "Skrifa yfir skrá" + +#~ msgid "Overwrite" +#~ msgstr "Yfirskrifa" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Nota dvipdfm til að flytja skrána út sem PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular er að nota ytra forritið 'dvipdfm' til að umbreyta DVI-skránni " +#~ "yfir í PDF. Stundum tekur þetta þó nokkurn tíma því dvipdfm þarf að útbúa " +#~ "sér bitamyndaletur (e.bitmap fonts). Vinsamlega sýndu þolinmæði." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Bíð eftir að dvipdfm ljúki vinnslu..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Nota dvips til að flytja skrána út sem PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular er að nota ytra forritið 'dvips' til að umbreyta DVI-skránni yfir " +#~ "í PostScript. Stundum tekur þetta þó nokkurn tíma því dvips þarf að útbúa " +#~ "sér bitamyndaletur (e.bitmap fonts). Vinsamlega sýndu þolinmæði." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Bíð þess að dvips ljúki vinnslu..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Aðgerð ekki tiltæk" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "Skemmd skrá Okular tókst ekki að túlka DVI skrána. " +#~ "Þessu veldur venjulega skemmd í skrá." + +#~ msgid "DVI File Error" +#~ msgstr "DVI skráarvilla" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Ekki fundust allar leturskrár" + +#~ msgid "Locating fonts..." +#~ msgstr "Leita að letri..." + +#~ msgid "Problem locating fonts" +#~ msgstr "Vandamál við staðsetningu leturs" + +#~ msgid "Font generation aborted" +#~ msgstr "Hætt við leturgerð" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Flytja út: %1 sem PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Flytja út: %1 sem PDF" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "Leturlistinn er tómur í augnablikinu." + +#~ msgid "TeX Name" +#~ msgstr "TeX heiti" + +#~ msgid "Family" +#~ msgstr "Leturgerð" + +#~ msgid "Zoom" +#~ msgstr "Aðdráttur" + +#~ msgid "Type" +#~ msgstr "Tegund" + +#~ msgid "Encoding" +#~ msgstr "Stafatafla" + +#~ msgid "Comment" +#~ msgstr "Athugasemd" + +#~ msgid "TeX virtual" +#~ msgstr "TeX sýndar" + +#~ msgid "TeX Font Metric" +#~ msgstr "TeX leturmálsetningar" + +#~ msgid "FreeType" +#~ msgstr "FreeType" diff --git a/po/is/okular_epub.po b/po/is/okular_epub.po new file mode 100644 index 0000000..04195b9 --- /dev/null +++ b/po/is/okular_epub.po @@ -0,0 +1,58 @@ +# translation of okular_epub.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2014, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Villa við að opna EPub skjal." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Stillingar EPub bakenda" + +#~ msgid "EPub Backend" +#~ msgstr "EPub bakend" + +#~ msgid "An EPub backend" +#~ msgstr "EPub bakendi" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/is/okular_fax.po b/po/is/okular_fax.po new file mode 100644 index 0000000..63c160f --- /dev/null +++ b/po/is/okular_fax.po @@ -0,0 +1,48 @@ +# translation of okular_fax.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Get ekki hlaðið inn skjalinu" + +#~ msgid "Fax Backend" +#~ msgstr "Fax bakendi" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "G3/G4 faxskjala bakendi" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/is/okular_fictionbook.po b/po/is/okular_fictionbook.po new file mode 100644 index 0000000..8d5cdf0 --- /dev/null +++ b/po/is/okular_fictionbook.po @@ -0,0 +1,83 @@ +# translation of okular_fictionbook.po to icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2014, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Skjalið er ekki gild FictionBook skrá" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Get ekki opnað skjalið %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Skjalið er ekki gild ZIP-safnskrá" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Ógild uppbygging skjals (aðalmöppuna vantar)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Ekkert innihald fannst í skjalinu" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Ógilt XML skjal: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "Fiction Book" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Stillingar Fiction Book bakenda" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Fiction Book bakendi" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Myndgerð FictionBook eBóka" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/is/okular_ghostview.po b/po/is/okular_ghostview.po new file mode 100644 index 0000000..73e8b0f --- /dev/null +++ b/po/is/okular_ghostview.po @@ -0,0 +1,94 @@ +# translation of okular_ghostview.po to icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2009, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Nota letur kerfisins" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Skilgreinir hvort Ghostscript eigi að fá að nota letur kerfisins, ef ekki er " +"eingöngu notast við það letur sem er ígrætt í viðkomandi skrá." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Almennar stillinga" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Nota letur kerfisins" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Stillingar Ghostscript bakenda" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Útgáfa skjals" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Stig túlkunarmáls" + +#~ msgid "PS Backend" +#~ msgstr "PS bakendi" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Myndgerð PostScript skráa." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Byggt á Spectre aðgerðasafninu." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/is/okular_kimgio.po b/po/is/okular_kimgio.po new file mode 100644 index 0000000..ec52752 --- /dev/null +++ b/po/is/okular_kimgio.po @@ -0,0 +1,70 @@ +# translation of okular_kimgio.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2009, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Get ekki opnað skjalið %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" + +#~ msgid "Image Backend" +#~ msgstr "Myndbirtingarbakend" + +#~ msgid "A simple image backend" +#~ msgstr "Einfaldur myndbyrtingarbakendi" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Aðaltækjaslá" diff --git a/po/is/okular_mobi.po b/po/is/okular_mobi.po new file mode 100644 index 0000000..30c868f --- /dev/null +++ b/po/is/okular_mobi.po @@ -0,0 +1,66 @@ +# translation of okular_mobi.po to Icelandic +# Copyright (C) 2009 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2009, 2014, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Villa við að opna Mobipocket skjal." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Þessi bók er varin með rétthafalæsingu (DRM) og verður ekki lesin nema á " +"tilgreindu tæki" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Stillingar Mobipocket bakenda" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Mobipocket bakendi" + +#~ msgid "A mobipocket backend" +#~ msgstr "Mobipocket bakendi" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/is/okular_plucker.po b/po/is/okular_plucker.po new file mode 100644 index 0000000..5eb3141 --- /dev/null +++ b/po/is/okular_plucker.po @@ -0,0 +1,48 @@ +# translation of okular_plucker.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nafn" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Plucker skjala bakend" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Myndgerð Plucker eBóka" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/is/okular_poppler.po b/po/is/okular_poppler.po new file mode 100644 index 0000000..78a3bc5 --- /dev/null +++ b/po/is/okular_poppler.po @@ -0,0 +1,225 @@ +# translation of okular_poppler.po to Icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2008, 2009, 2010, 2013, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Bæta gæði mjórra lína:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "Nei" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Gegnheilt" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Lögun" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "PDF valkostir" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Prenta athugasemdir" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Hafa athugasemdir með í útprentun" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Lætur athugasemdir fylgja með í útprentuðu skjali. Þú getur slökkt á þessu " +"ef þú vilt halda skjalinu sem upprunalegustu." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Þvinga röstun" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Rasta yfir í mynddíla fyrir prentun" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Þvingar röstun á hverri síðu þannig að punktamynd verður til fyrir prentun. " +"Þetta gefur yfirleytt lélegri útkomu, en getur bjargað prentun á skrám sem " +"ekki prentast rétt." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF útg. %1. %2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Snið" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Dulritað" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Ódulritað" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Öryggi" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Já" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Bestað" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Stillingar PDF bakenda" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "" + +#~ msgid "PDF Backend" +#~ msgstr "PDF bakendi" + +#~ msgid "A PDF file renderer" +#~ msgstr "Myndgerð PDF skráa" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Vistun skráa með dulritun er ekki stutt." + +#~ msgid "Unknown" +#~ msgstr "Óþekkt" + +#~ msgid "Unknown Date" +#~ msgstr "Óþekkt dagsetning" + +#~ msgid "Unknown Encryption" +#~ msgstr "Óþekkt dulritun" + +#~ msgid "Unknown Optimization" +#~ msgstr "Óþekkt bestun" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Vinsamlega gefðu upp lykilorðið til að lesa skjalið:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Rangt lykilorð. Reyndu aftur:" + +#~ msgid "Document Password" +#~ msgstr "Lykilorð á skjali" diff --git a/po/is/okular_xps.po b/po/is/okular_xps.po new file mode 100644 index 0000000..374cc09 --- /dev/null +++ b/po/is/okular_xps.po @@ -0,0 +1,60 @@ +# translation of okular_xps.po to icelandic +# Copyright (C) 2008 This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2007, 2008, 2015. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2015-01-29 09:07+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" +"\n" +"\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Sveinn í Felli" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "sv1@fellsnet.is" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revision" + +#~ msgid "XPS Backend" +#~ msgstr "XPS bakendi" + +#~ msgid "An XPS backend" +#~ msgstr "XPS bakendi" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/is/org.kde.active.documentviewer.po b/po/is/org.kde.active.documentviewer.po new file mode 100644 index 0000000..076c720 --- /dev/null +++ b/po/is/org.kde.active.documentviewer.po @@ -0,0 +1,72 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Sveinn í Felli , 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2013-04-24 21:32+0000\n" +"Last-Translator: Sveinn í Felli \n" +"Language-Team: Icelandic \n" +"Language: is\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "" + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "" + +#: package/contents/ui/MainView.qml:36 +#, fuzzy +#| msgid "Bookmarks" +msgid "Bookmark this page" +msgstr "Bókamerki" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Smámyndir" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Efnisyfirlit" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Bókamerki" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "" + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Engar niðurstöður fundust." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Skjalaskoðari fyrir Plasma Active byggður á Okular" + +#~ msgid "Reader" +#~ msgstr "Lesari" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Höfundarréttur 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Slóð skrárinnar sem á að opna" diff --git a/po/it/docs/okular/annotation-properties.png b/po/it/docs/okular/annotation-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..257bf9adfca7189262509ea10ceb01f0c1b91b7f GIT binary patch literal 14835 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 DLfB?g literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/annotations.png b/po/it/docs/okular/annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0ab558cc71801799fd436b825af3aabe9b9234 GIT binary patch literal 85212 zcmd41cQo8j_%AMciQb8bh~9#P=!ry$9yKfxqPNwpXhB3LdheYeQFfKpJJGvk^=`2` ztK5~(_x{d3zjN;Y_kA2^cXr-0Pn((7>zOB1LrsC0kbw{b1B3Xz;yX+W^1{NDW z7P>{k5*dvCf}x?JEhne0tNqCW-T43P^Web)OiWBHEG%qnY#baMJUl#VY7BgQd_qFP zhYuf;kdTm(kqHQ3P*6}%Q&ZE?(b03$GcqzVGc&WWusnPAjFp|^{^8>0;o;$b{+ySO zUz1l*P)JBf_{9qm(N|*PqOV?wNlHBze=8v&At@~_BlG(88`-yS-@R5)k&}~CR8&+_ zR#s6{)6me+(qvLsC;9jhL&KBEEQs{u-N!dwntUq)7_WoLRiio0G5{71U+i6VKU--V zTWT9wY8hE*8kuPtntee30lsJ$n5yfWsD1pbrf00GXQZNQq^xVGqz!nlrO&Tnt)vCe z)Y4MW&}-z8(ALrY_)*``$msKD6Eib2OG`@|8(Vi6q32b>-k5fbF@>+R|8=4@|cVfx8HOHWN+SyoEy1^07y)+ZDs zkLYO#a32z4Q(!*8pj=}=$9V8w|NXl++Mv0;rfnC->5K!!CDy)p=qjI6ci&$#_IkHX z&rt*3lqrK;{0~cPubr`D*%jfMQk74|qT?7P5(^??@ED!`P!_k#w#Fs7l$m0Ge{ZOb zPewOWf%lFa2YZm4uzpKks4pVvT{zq2g3Hi06Vdyh@$bS~DwVLWT+j7U-iN!!S<;&& zcSP8j{;#8D)!$Hmd;Ns$kOuwr8{`QYJ~k#i;Q!k2+A9F!hlhR z4~I0biO`)IVY2&LjhFx{ax#3^CpoAQ5YaF63$61A%JY(pC3j{0YXS7AHOw`tThiEY zcLjiz7#aS__goKDr;m+S4bDiw>ujuu1qAtd31Z1zqWA`YR%0%0j>Hv$HDBZ&1b+Py z-T&RVhh7M3V#t~(8$CK6MxzABzShFByYP%GBU(HT+J-bTk0R*8Pw+Pbv>>h7jVw+c z-LOcF8_@KMcah~qm_{rl28ZRum|kAf0^UfCyGQn@Jz;w zZO#3e11*0LKL{2Ez_Ei^4Ey4tgWxO-Y;nN-vyt4$TQ|n*+?@-g`QXaLWC6( zT9@Gu!vWqol+~>-;4^)ORlM^fMhAqK9H6ygzPgpt14gs21*>roTLoj;Npzf6qJzom zpjbFSf<@1I#ocn*AqHX}3Am)JvY5jBg4Vv-94PEUtv)=LQU}{a6xP`n+EdyA1W|nV z78tO>0Rq;*EDp4-3naiaBLblrk+d4dgabD8uU}8*DBR6|IFv<}VeIoG-6?m$L15=8 zhlEnU2lv6P1YmQD%YezwNAk`ikh<0j{Z2fLm{adyL-|38xac6p>~P)zv+>iHj9|`N z5P5h(?VZ>a>vTqR9j3wld*Sy%M>~nzipn0l*hs`xZJHQ8{x6$i{1B2hiWD5eiV;MLZg%vnAz%4E5dHseGqmw z1f!WJtkIzZGd)KU-)ri%gYhXSrR<4=!jee6W8+47JJdc9){^K5!-lESqul<}H@-== zH{ly<8tsIkyx&srekW9u#eBat55&g59BpW0p^pyRBIJ4x<_~Hy&Q6~uu$Z5>1I|#M|O;|lEDDuTX+gZIi^J@uxoxNdQV+SDRSa(DD zVhYlXw7erl$Gp_#RW6>;5bCkzLZ zs9A->fZ=sM+q*L8wUr&1UD@&s^Bl(H-#AJZRDP_x52fz$Z#o$xl6iVnvh8=PJ}!|9 zzaqb1Szm5O8Z``z1^7UIoVZP|<$t`FHtY*(B!cRIfGs`8x`*tCbvNO(w|Jwyci|_g z#f*3N^Pg2d5=+z@V)@>5Nc+@LF1p=g{R@?W@yf(%X<~_dha^FU4{rS8ux0LYG3(Ok>Wq$c z{b2{(PAI+r7_i?{;zhve%|Ubo6qgV8>%d@PUu|Q5bF&nD=+km@aMV^|SFcfsbg?+>d%6pSfE=P-Lo!dU-CRyg>S{RzBTHU9?K(Q&65etLY6CsWx( zj9DL6!g-}AH_Ht5ajVxHv1 z+MG@EEOQgcHE6OjAJ;=FtAH&`2K7(Vy%T)2LPUSl-JU*`-r@5o02TPS>uwwxFAg$8 zo5(y-{YqO16*~J$iN#MLO*a-*nuA6@D4V`&gMc4iPuB~j=4nY04s+`{Qjbjp{K|hz zI(p7m@jSbz2l`ewDVWfDqC}Mr_$=XsbvNBE(;+Xg7}R>9a(>2*xR~`ynPauKdZl`^ z%!XbI$5Xont+i!)?TkR)VPlu_yqo2dTHAe|Y1y*rit?`&gX_kAth61QO-9Lg$OP|% z?@uqSDbmtzkUD3nEv|Bs^hn(hQ4OQIqqp7@(P94U_2ByYc5%hEm&3I|y`+Srw$nl; zHBI|a@He%?+r#pSmD;k?`AO02Xdg&i$h9n$Jk^*SL)UZY`8*h9-+oU_>z<6;*nRo*eN$ zJ+)Eb4r>auaW^w`h9weaJ>bZsx^L5?(`XkEmLCQi)%Snp+45dqE87FeLjAeVPcwLs z5W{6~{hQ6W;jp`mpnAiHJ_Acw(-~HAd-xWkf+SX84qg0`>#V7zLZ)&kTidYDTMUQe za7G&YqOU6UpdNs50MsrM{ z=W!xn!2j?pW%r%UB*v)B^)>3^%bxhX*;=YL_zYXx(XOanl9<+t+0~ncR2q|RR7mVt z`APan8Po-|R~Q?g8VY!QKdz{fY4G&{E6K)GOw3=fX1olzKVO_TrvJyy=tF7UGGeL1$gF_&7pfy|IsCRob6Mkn&9)%YbfuV z06DnnQW&no_|M;WV`j_!IgMgK>f`6!O%RYtu%!c83F<1842TTg$3+XgP#05z3p6zG zJHa~Ji7cD!jV#-%WfTplX9P|diB@QjiLR6|PJh{pWGu^Mbh#`O{nQdR-1sTN$V&>q zmhQw%`$$ zvRi4XbXlLfx)4GaQe+Hzv)pFy&Urn^e|YA#vV|?_ z5-^tb#ydAh`hKA(D=`@ShR`f?+6mp?37ez0=mbnO8YpuicPsHc{2>ARER zkgHnCboh-zzDJKA?me2<(<`{7t0Xir_R17?G~P2?5)pH3TrS^gPEgNijclTBf(*;t zz2s;0Ta;;4zB%`kdHx)85C?sLR{QR#{rXi|`D|Y1CZ!X$Y5v&os8dBcR5lz7Vhiub zTl7`v2Ee^g*VV>B?hnwgTh`d;%(E?!2YDvJ_tw#)9S|h(=CT4y27Krs9Oh{l!=mJu#9Ifnrkng_V7RC5BRXWB(2ZD!D$0TC$mU%3gyN;o$$st#U~gM^00hW$aLyC_`{ngXR+hCJC#O88BsRQXoevp24O9T z!#Wi@;vb&jga66=8rp?h(F$t;m2_ZLw=D1j)AYuyojEZ6={)N9wV^9#q^5L;{|G$k zgZeA1e#c>jjTTh{g!*eiGM{k>9$zEKMbUuJ^o!&n(41tRM2k~W8}3W|uLU32a>nV& z!;5(0vIt(b_bry)rGdnHd7A;`B40?Q%sU}2>4Cv*@doZ?I8_E3=^leI6GTX&yPEK`5=Uves2oiMBFi8$=>8o zC?vyFMdi#^Rjh&TAgq?NN){D1w4}Z$-0`Mkx)beHm{^F`@ zh45i!P@JqCot33y>3M%HTtgVUr($|ALhTtcTN{CCARaQ@YIey&!A;mk!%XyNYQ~aW z)-pJGxvxKXNf=M4*ZI-tT>p0nCt-$~s8zPT_`>f}L-1}*H%Y{Cqr4{mV^-fzSg!rY z)ps*0Ta)Y%VoP?BxyrPzlzzaZP4v%qsI=|pNn&>whwpNaE4#^nKaSW8C&~sN#K-gJ zGrnLg(-db+U|nQp7@bpg^|do`g=$6UQ~%*+WvCtMK-)Z|!%{PvL#o378!U9?sQcZu zRDLp~Vq`ms;FyN#Rjxa)YDtlhtM4<(+&8n?zhX~@bifF9QX|0aH{vAuA0`58ij2#`39P@pR(}MP!>e%q*1mtJ+f4QK zc(uw>bQzKBUcZy#kYyhpU0D9fdo7^i-KNshPfFpFV;{Ab_*5&SC}dhA(h4_ubO3nA z!w2bdUMm~;E9HGUT!Vi{g8aqA%UPfWt6%xGw4yY*1fGrRKA^Pp<_LFn{3Q&OS~bHn zZeMvFq2B+YBzfVeS`esHaa1}hw<(b7%yct1X-!mbd7f+Ph!+N(G$ZTup4@AtK)j6S zW{*x*lhfJq=6DSXj~%k@cGfAv@vDrF;QuN|S+ddnwgy;epz88L@g-v__v)h|hOqTk z#US^Ggrk3!p3pHH1OMLdPVX_QQM&kNlmJ-s>QJ+v;J&h~&yJivXW-kY!I;5ne zMV|1v7&%?-+7{!;$Wfjf{fBMo>>)sJ9O&m+9||B7$;zh@7t+S|LN(}M2~Uk12~s4Q zPtJ`0#~<6ak|jRiyQBB6&!NXqmz1Frk;Aa>96ho+Ip3dg(W()qEV5Kz+qDDi9@vgr zT42cx?CkwyX**7Q#Cb%c^I9n=Ook~(;itZoD0^Ww4m>x15I^zw%l!HG#Hf|OxsMd& zS9DT0%QdR??Gx7=snQNO1%sJ{DmDjw8AW( z1MdRUA=O=`fBqg%eP5OsxkbL0iz8HZk>9K`+Ku^JUyx!QsJmkC{jlRzrQ9DX!yns! zqM!wXqwS73NRg7Z(K6>|`XN7_RlZp{qI=bD256OCCoR)6HSM>8)S@oGQz*SpAgD95 zq=Y~H$X`}!c7Q9Wn}-!H2^?^Se-(=w?dB{WBO$d_=yV0Q0$j7%LL4hst71Or_~_OM z3kJ~HjRn$li2`REKo2Q5WVqV|iwW4ba`NbQs`ag}kA7)aML6?+T;3UhFXkZI>H zEM#=EkR0fe?gJqBqW+_?ues}xCf2I5zEA(1`kgj;*B_)-%eVKOCUi14$Byq!NcxA^ zp@ZZdu{^u-f(DkJ@D;2}!Vib;Rxva?9^ugPeo%N7IrGNfA+jOCj4A$~Xa!CUtoVax zq6&j4(vGGc@lp}?_V##=WG99lLlX)fU`lyHeH^Aed5H0}9;#cdAjZ}GPI;I-(?$xn zluF+=Yc=>&JDW)>=zT~!H7Ko7PvBy)<&xn&ni3j_A;z*2dZ(w7;RzVEN)iNG=ap57 ze<>oua{B72xZRTBTCSTI^lYw7=oJk|dSMf~TPStEexM#FiyF7+Go-G&$Z~nLrck}e zhQ0frkMC_LU0XFOobisRbC=4ee-`NpnTpql!-;`R31cJ(8j%~QYbzTbxs9<-(_2Es+Po_g9>X%oP}5V4 zP*0UW0m)foq^Ma|DPO$hH|rhRoh;0bg@}b4AgE)vo)pmtas%l^-@VB2w4FNHl{EkJ zouH|ED;C5f!FcS>{o*?wu3azeB>wAbX1Nqm8$;;muwF8yREQC zkNwJ)?ES11cVC~ziWK)~2+Jwdhzro-7+2H0EZv|RGMSY4RlBw|2->ZUiw?yf>KMz1 zlgXmv+?Ms<#?cSkl!G^)ID*PPrs*+|6fPkiBu>{tjv)mmt!Si33HMd)gNZ2b?6Cv8 zmLbEKK%6eU?e&})_z){P!8`X7E?xHM8xhnezRG4YuURTn0S!26fFKmpJ@CMUyDuR; z&{>I=?M}euj@R?1kf9iL-(W_j3kB{`mNU8MJax`G!YaB z5iG)EHWvLc1#{wtau{aGEDpTeX*~v~f0`*$(j(;t5^eW9!PtMWiZGUX2=^`H1KusP zZ8vV~xM!8dOBX{2B}w2G7%F&SkVQpp<*kv6=LIUGZ!6=t-I2yaCLu0u3X zf>N{NW5F@eFcq!CzXlw5z&D7|(V6G}bddTD_3^DlidcKOPJUL#1U4>}m%fiaOJ&<$ zmRU(s=z(=P+H@}oMtVJF0bVkkUFIJ&>Lo-&PrpID;vjv?Yk6fqf-`3*y8&PG27`xS z3h`eV;oTgDdCfI~@l!?Um->vel-9lQ*Ky`Bfy`nK%)ZX8Fpl=DrPD&DoEp{`5&goq z(TR{o08F`*4K0&<(e?4{V@5|K-=*^GzB4y^VUJ%`#W6#qIwF!^J%TFY2Py12U_T|8 z@biuOPPENToGC4aY~v6fGlu9)(tg7%wX8V%qqM`R~MsPb=OAZ4Pfoe1K6k?QtIJek!9e|C$5 zGNo|RHPdH?P`4YX%H&27pZtYHZMj2BZlASoDy#OVLp~^Cq?oBuUyuZ}zyY=YVwZ|_ z5~gmnoe2T=p7G8n_&XNR@yI;%lQk3#^xOp)8c(u9&-83+83v*fJEXzIl?TMF6*ZmU!U@or>zzsa3DOn&bN-&S-%8E&h#yjbI!c>!sGWGznkpWdk>FPxxQ)de(p|KN zqh^)Qs9aZ1J{Q*T2up2_+$!w%b^vf0(QSjUV6iOvq6cWk05Wp`VGFRl3Kc!=lVQzltW;)#mfpA`>}MHTxz(Y(i_k20o%Tmv_9 zK?T{^mtfnh&k}Hk#Id#$Lvbc0lttI`O7TwQRQdQ;z&3#Z;e^*pX@RS^fz-xy;dmQC z`Ba7)DKT*g$2bi~l~d8gTh7l@LV2Tqd2<9(bjS`K$SCGO-!i(D)fF)r8c#Y)|E|M zPj=eUjq}a8JE@Vuuf*=Gc#sH&tmDt zRqQc%jj@ajZX;Aoc~v^=&n8|PrkxbL`COZ5M}w`UU5|ZdjA-sfQ}NItl<(Yf%QUKT zZBXUYyaC|>>oVeV*rz>(q#q^)E7~k@5o(9@DNs7~KEMrQfxlV3R>Ng}j6)tR^(te?D5m|)^? zOB2nO`Qdr*6!=!fM$K`ZQ@%so)W&}<*}F&4q+*O7!p(rggdI227P`Y{T1V0EjLQ-!tP{$_k^m8Lw}` zGJF7G0u4xL=v2vTE(3`F0`PV;xXn;13R_!rbDOm$*)fS^+>|;gSm(NF!JGDO?J2Z8 zp6I)Yh!l2cZJxl~GbxH5zV9HOI@b>N_}3&0>#5euN^b~`?5CyMEZ|W+W6L?;*7V6d zca<6K0%TY!lmt$C#?>gVz*Kr{!O`B+oq!Qh{=YxC)%y|Wwd%Lt+!@S zg}vELUMgi{B;z!ljW!EGPNL4-vI!!j7mx#RObGK-PL&Xpg*@2z??g0z{nU-5aoc>p zDA+qJVV}1CFxmQ~$DYz7ci`=sJ&4B$!n9sqU4v^x<7Bs30e<%0p~kV2m%*a%G+1roZiZpu`N=^Ht+cd+kh>e?4bsdmq!s{iJ6ecKzC-g8Y<}4w(%7%mZ`^J|;tn zbiyEIl0Zaf^C=-zt}uR}Q_tD*uKcLH7z|~4Gs0B@f~RIsi<_-fGR1)k90^vyjPO{W zG?HX9p!COesH&GjjL&Z7N0lBjU|>VB`}-PT;GC=LlUOy|j_vOv{YbaO8A#ky;NXzG zq(JyiuMwt*(00!Ei%@}UbXX!4nM*f_q+!P7z7K;Os$W&LyK&xICph2oXP*!yJttU|dB zR%6l`3r-og##=$ePOY_O1{IvteX%w%NF#YDP!L$^IH&lV`wD0&2mkS6)RlXV33#0P z4ky&5H0pg;+7UQ+9oJ{QhPvxmXgR=D$_m~$v3%e6bD^o7D^n2?&zVvF-?PHwSKc5}SY!?Uh@|O6j*a0A0=a`}iI;(IkkT<4Y%0=?l#geux zU6zKR&5sD{=Gew{d%Ju;`DbmVZzU+`mORtwvR(wU{U2t7s;Y)SuB)ZlfSY){+jXBr zw>$W;gSoqrBGNC5U988sjz{u4=%Px01pl}|62$G0s~fD@&xwj;|8YNW4$QJ69n(4Z zJr#h@?d{MH7;+kDbkgCY^&Tz!up4KH73)B`HNEZn_)+E0?-~R5>?z7+JjS8h4ZXpI z%SVQ*F;0AWz)&;oNpx_$uK;(~5Dm12?EGG62k27kIBnWbos_oEVBQT<&hLDjTbg<7 zmE~dciLUTD@xd_~Gvhg$G^g$_3TPq7;b2v%xbj4)uU{daX=f@&9j)o3<&MJXiUMlG zt==!QrG^2?(M|%xJ)CMk>JsR0+|wXoFJMK|GC5PJNgi1c>tQnEjTzm#Z3c!B1Dem$ z@+0s~1SMNC&^rrE|5ua*^Z!Q`FoAFWHUkmJsq#Ro@e2#nzoNCf$9`{m`8i&hHIX4#4Zb zXJ=@pgC;hw?}bHw#(aQg8o;s~-rx6x>;Vv+uHs)KsvY{Hx$ybDD^wuQ858ht5HJy3 zcfri0FcC@E7Bi&Cf-*ha5x-}3aQ6<_xBldcwe}Yoq?d;)!?&He0^0dnls1*og>lWF z-#pB-95ulK#_sWWZu*!16QR)!t{ePdti}P~$0mI0)^~vl@n-QQJxj#n z=i{yh>l~;fZqok|3^D|R+WhcN40gS&0#N6;m3oTj6OR5M-^;5_6uzMmjM(Ix#rsb) zSOq9eN9;mfK$Uj%heJf6ixrme%i=1O_ge$Ohxh8E>!8rpGVjfwWWE3Xp&_?ww1F!W zB0Y%_tNXA6s`{Uq58VO711hDjZaGa`+5`GIknSOco7x|oBgjM|W*(sn0Pel~CL5~{ zFv&jm6SDmvVb-3x2*I7^p=d-lYop~UnK1fb`qv=a5B;l~HkM8Rl=Oe5UO*-e{e5_D zTkhH=^-IM389>CAE;;vDIMqM2m@ZMcOhM8{=6_UKQvY^Id0({kA0I_mVkFBvKo7GZ z^#=p{zR~LmD9uSN4YMpP`{E=;bNqvCUm~Sm)s}iKc>IJXPl0Hi&0?_P4_G-{fA>R@ zNq5$!bNyJ2u;n%pu$o2};%nFM>QGYF3&|>9=v9T;?8TSJSHb1xSZ?Uo&8x@Gls@b& zc2id+s}#hBUaqOKuNZ!DZlfoAP4Y!XO$RBCE{e zBIlTmYc$@b6gqVEoAN0z>vza`^t?RldP;#*oclb4fxPi$tI*a=ni{26e!Cd8y=_L~hbLp#KJzkPvaC(me+w5}QhFaTfADzmviiJh$ zyVi`rBad-0la3ZI3sv8GmP+~@owa(C{5cC6gszw7#nK!>+0LJ|rd`#Pl>u{6fW2@c zeuc1i{4eRf#ZS@n3#uSZW4TV=VZ-O3$ec`yYUyMn5oRtS zuE5W!BX8;1eNOg3LP8@0*@xcFhnT>nBgWIE?a>qsjfLvJ6YM^mVf466wv$=I^qd)j zLo-bH?|VQZp2L}t?;W%#5S)FYOeOxDehGUDi{ppohJ`Wsc*sHtbQV|mD3i1ta-mlYfft1=MdhJg zEVE%zmBJ;I4uUqfRPhw;&MOw%W;+H=iAa0{G zhJ`BgR$Ea@D@r(tk`*VOP@5NicUE0AW4ID#)3)S%E~@caiB>^hTjW-ptW=JMLTF=P zSvVPD+U6J-q8GNO!9tEs&B|?@E6b6b6X)R0LRjdd z3$^2^-zVjin#=oljjFkxnFbWza7egg{PIL!hNe4_Z5T#o(btK6wfg#|E<`qt>TW`R ze&m$3@ypFT_Ns(`09NocJzj!|kP5+hV%Ha2PRA2o8A3ZMnPTTdXnB^rg~e)3I4p?r zGwvV0FWalK7MyJi0=c|-`w|jb9E>v!3}m42XnMJ8!#wtsDiGel%Ew2v0+!d5XD0W|X}mssP+EQ%q%zN&P@K_)>rSH+ojm!fs;SCN?lg$& z1dB#dv1iFHL7jiaIHE(0#ReJwNgJmup8PH)VaVz8@K-ts_g|bzVX5Q>a{a`cgqyao zLXPz%nL3-!GtS!YynPK%wPfq*PL4M_AmX-lm;%dYv0Efh`3><*YeQHDq|DP9R?4-X zw`(Dl$VsUwW3CCpo`$0eo&p?IyUn0XzmvUmM_)cYno_^iXk<2!AX{w{VJ63gE-0)5 zU6P6?MwM?htWJK-`+2oTi(Aau%52Bg!woHezLZ#RU38SG;4swf)P%G40wdyrZ-h6K z|5P_?SmBQLxcxX@%!RMKif+Mu9{Ud7fDUgimnT$`J<-%p2p)b>x>7sx*opsKQOGIK zALsjXeWeRJi4Qd=e1K|w2G@|xlu!cmKZz?QJ?`{;ll^NsV&3y_hT$@wHS7iOqgMb6 zGqquEKeR{tuMK8Weok@o6+NRYE-O=DH8qEfvKV)(0$+w~)mzE&t>D*^!4rK#(lp1q z`oi92iuEiMHWEsw^%T4vevXrhVZL_aAGIx%IBDk^L7l@AZq`G8yyiF?Nxq9yzlGA` z+?9WPzWG#Mni9zdSuaAaIbTpU`gtt zU$b^Ob3Z*2;(RT1R(oGwS(rCj)%WO!MUF|5X!*2hhAJIDq!M`rpDUsp{4A1IHt}6r z9c24zfLDzee_8NgzRf&@y_ z1J&cU9&s={1qQ`YN_PIJQxG0{n_^et8YkRLMxm*x`+o2jPieGM#>au5X_&Wk>2Vk) z9SrNMd5LN)v)eAtbQHrZZn4y$vSRd3nmdDzA0Amw$_rB=SeHG= zFB)urTf=)U@$way5uRyA7|T3g@Es>B^)Ei)XpZSqRVZ~B?|u?>Juz^XSPZDZwd?&< zIS>sn8nZx*thlnb_/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°*&E{nu{2JR=DX-^ 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ž^UG`Mc=0qrm<_?Tu#!;X$X2kZAukZ2WD!JnC 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 literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/bookmark-management.png b/po/it/docs/okular/bookmark-management.png new file mode 100644 index 0000000000000000000000000000000000000000..64d9ad7288a0a5bc0abdd6400519012c7ddbfcfd GIT binary patch literal 42239 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μ7(=HQZM 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

H;)~H>L8JhY#By|v$&)u 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 literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/configure-annotations.png b/po/it/docs/okular/configure-annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..7c983501352224faa3ebeb77540876e56924f9fa GIT binary patch literal 29100 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

    =hyeX<5DXVa`4FPo7(k(Jo z7@p&Yw*bo=bU)e+Npg78kR+NIwZ!81rf>YV*%q2#t@@^?gSlObVUM@zn8JO4FK8Q6 zsyP)weh-u{U2n$eY*`^x+?MWK125`{LR7LE+^5iQ9<(A+hHBp}Y0O5KFH5+i_EU0~q)I2dv;|GuLLjs0h|2?EKW?N_W%y zq`VMVvE4>fO;k}EQK)E}Xg=@JSUo)Gf4$Pb5Jb&3YZ<@Wqw`-`xSsLl@!R}m6BqCF|O9G1!WLewm|fhzopsfnmU zucuD21WRERNZUZqfP6XA=nUJ;)E@lb(!Ql2U^D%HQSgG|*$%mpCd#lNF1aN@+dQWS zN9=+DgRG$JFUn7V*u)6yez|gSYHzIx3tkNaum2ftK%{P(GU4mDwaO2uR9P?bA9I`x zYHWRwVum$RqI*$nw+YN`CWC|RIkX960#;d2L_R;S*4kd{eoNnv7QgAIE;H!+h(!?A4}{xSf?Sptw-f*Loc_ zStzU~wVkNNdywE#`?w7AKk4O$KDtL+_>HE<6g+sLBzvvXX2J%zKf!Rj{I4*0olShF z4MAQcwmc`ixP!bek3uNXe(%Km+`K1(UyrI1*u}*%E1N;B@_IQ@EB@mlQlAb^eN9=S zqU!TrD4jEUYIsBcX}Z))&?yC7vN@PF6++H$>bTe-8_esVuPx*qnl*k~qq4RI4P<`R zcR7nApec3YZiabJ4oT?;@#_Z-sijUF*V!6^+?~~^GQSMBZ-G$gj-bXqzD5W#P<3;{ zx2;Ait2K32E|qLmU|@f$16!do+!jDx zu|nHR{!Q%pGh-I6Hfh2qv^i*kBE*#X6Co_#M!|nCjA7t5BRrYsf^j2{N#W%S^awwj zwZQ1s`E)tYwZ~bEE-kU>-(@oi){6)1SLf*@u$0PX^n=|jHVX@%Q_$r3A_a;! zrW>4n1u$J&uQ_4s1){V)^_EVn1;~E!4f>X^pA#pz52gM|(tgCKVr)#<{0?eD-G3Zw z3!jg!&kkajCiEVOQPnJNSu&dX^L;&(f+o3=z1g3%dnl|fjaB3pMBo6e+LGHvG45Bt zdpkBv$-6qfpE2~xUJM|up{u*tz&Ja;q5yn=T{B0%CuW&&K0J8f*>Lkl7h7+==yG=5 zN{^UgB9ss)gZayrm~gTpHT`pDw(F(g{Fyw7t@U2EH47GpNG{+les|(%#?CDxQjiRZ z$pPBrKltESS|m8kq5_Z(dWzKreExbb$Xqjr*og^KYR+Vo;m#fn&+Jv1B1V z%yMUI!&vcIDK8_?vPa(Ll_BTWN(_8ta0@gqUNW3FG{%krIjhjb8>kX0%7C&BCflbt z*2EL^^90nuxPYaUcCb^-M8&Tiu=7}k_~nD)q4ENI&#}Pp+W8r+;*}Wtq_e)Qc>|lQ zv>a6%Y{n2^*j(+ak-!X?dD4fS2$dcXQ5uBZ(JJ9k*U{U^O#@NmgpWVLs?=SqrB>3Qw$@3k2iDPx{su#O7_P83}#g5|1(m%MGq?4 zj`p~2E6gxF__)WfdhBa>04lY;2as-DU8$Bg3VuYoR{zvVSiBF9;5G?h2WWi#2Y5Jo z!^F6Hqo`qqi{R^#mtu$>1Z{ zDX7@tx+14*=8u01-A%OPk@l!6W_2UDMV^QYN0jHHW3hlLH@b+7DfMh~EPhw#7cf=- zb1`RQj|2$5H`a4Jm0#PVv$~4(I&cs}ShB+TvBmfW1|y0^-0VG}txdZ?L#VU4xwrSi z_?5R!t@*T8@fL{y`y+Tl$y2PE7jn&fU}%gT*mQPRl*;fan=NYqyW8D^bn^ptzd?`S z0x}Ji`7N&V@CGzy{CL2V4PLW3d3Cl43r^%{UrjebxNyw_6I|3AU_i&8AHNKs_J05p zB@C91i!u_yY?cA7PiNY0$Us6kiKr9pmE7MnC(MJ~C5wpc{1zXlSs!UV zyui-9ufE2lWoJAe_0_;Gjz5prGA`M3%XLoUI-54^`|H?e2I7AcOYjTK*w;}p85t_C z>BsK7q_bLRb_tTFQS)Tzn0KM9>|kQFfCO;mjWxoca(qMPE-w-%ddS(q=34=12u z%l)XD%^Lo*O%f@Lbw8}6LEIHjD)cv^D0peBe|B;-Rr^=TNLNB=?(5D%VXJZplwi|0V}w#VX2)RluYqHd zJqY^hy<-@*Xj}L$g%aS~T|p>W`R6@0(p6_Jckhc#Q|6;Iv|-_{-We= zT0yvlTJxxHK0asD44icprX!k?0>^6B1W4Z^FYyQa6sa_m=i^F;h}v9a%-rQNWur1aUv?O#dZ%I@C_u9{8Cb_!jbO+t-;Vmc^uF+St%?ulkuUjdWA-KLVn-M zJTl`$Sn>*CN!wA%%jYkail$>1UP1dQCJMwRna5bG8;9SOPaVO*I%A0BM`J5cQEs#D zrjo8T`5F@`B?u@JFM8-N!u5*OL$OG!n!DU=^LnI9iu_RDKHspK)aRHED~3XcBhqW| zl50{s;sM$7dI!TSH`9*zx{{(~b>kn^u{LLS#N%25{z8OnNYg(UmXZePGz5rr*O|qi zlnCS^%tEaJ>Lk(A#9@WT^RWwq*Noqz`v@$#zSUM?LaCBsEK9I7Cg2;GtBv`)!7}n}0J{c#Xz{ov(U_=u^H@Yk`wfK@+rQ@5=>fcV3Y_ z%=FvRcnZo_d4w<$p>!uV9yCCf6sCn{+fUJP3=Pm;reIG@(xukU{V|oOAiK0hCYmdo zx_``lCEdjr*AqUF+0i5X=ZC9vwZtrAshwSEmO7F0X3CL$46Ewfk5CnhQRXo^gZpZD z#lgJZzN+dTpOX@syTU(tTX(5|bnYXtr$Q&blM^O7V*9f42}wQ6-(ts^Vkn!(lKE?=oVM(;YnxC3wFBdJ4V4r!plGZ{@ z!nr|3Ke;=n;%763riZFqDo`BEc5G?b)>^^-@#If{{TI?vI{)}}ylQPAV<|TH0hS1@ ziW4?x8Hqq2Sp);vB;kP!f!+T{;9~ z>>26W8e@$@Tha$0T$Qh>dXq)nI-8uxqemY}KVhowWFp1csD*Yl+R&Nzs274a%V!MP&{$GAK2m>D>>3(kh z(l-E92yQ=Wl=;|^7neULk)CP3_#9naD#QO_!x|M#QZ{z8LBPsr=k=Kk z8!}%=&|(r;y)zw(NPJ!z_XQ;_(G#b|1O)80zcy7(6@=8D2cA4aIVBL#KYrN`A&KRD zgnZ&|{x`zS8nP6Tn887+9^2JX(-@IkZ7_QNDvui_C(T@OhcAfKbNk^Wm+;!V=3y(^bOcxF^8F_EDgbw*fJN~imzom}B zzMb;1BfBV@xVfj$y0hC*E%9?6A?7{3)K`khPo1oV*vL`zM2^#mh+xIHwX|?F&ucb} z!J0&3mpms4F(v4p<*zMDrakaiS31=u8={k)1)Hjy*E%)FGp-sViGBR~RKRftE_eo? z^z?HE2uNIKKCLlZ0b-D9G#9I}HVz3TaQ0fkb~n!lLuwElAp1D};P5`WT*Q5iw7k-w z+(3x}k6v+j)nl6EFHK!Woa-^`UA|R!k$;*qpU&C#=M|-umqmby&AH+EQ(19E#gkcL z20+Frojhem%!9zw*7zSyf~Z|?&L#|yQ<{O28vjB zU~16JQ!}rpA3rhat7QTAl%)b+H_S&cc(1;rCojsq2_2@YJ->xJwo0d^A#o3_S(|Ia zj&w9~T;(tRG^GkRMx4Ir9DD%59&|uQc_=Ct=gg1IPEE~jY&euUIN`NV#vK6)ol4hX zSPkk}%m25>nn6rs_-3i*L~&Z!YLtFzEHTV&VzGcEEH>3zU^i>XPd^To z9gfY~4wK2T?gfPHr~d1|_D+C%lt(IpF4qwe22qk)v= zX3C7`HF8HDL<*c7?;N|I!^cq8)xt0Df>5sFbk>jG2hW0{j@#vqBHO5X5$aJ<8ej#i zFAcgM8QA@=Bc;70MNrVvC?rHk!L{h9w37Z|pr&TVTA0O13K)b+O9RO{>w{kka4j)*7Xwe{6b%Vzn0F;_-H>mAgN@ujW_2bWT0jnB9O&KU<2&|Rk+H;V4E-zgoI2D{k2c7Q)rJc5;?JH=Tjj7&@3&Y z1M7YOs@}8;mu~&Sgb#4)#2*~Uov}iOSV6RqmmpAqo9e|36_qsN(|ptG^5fqW7f}LL zJKT+eKM(9yh+}K0!)UN|w;!+1h0}jymT(RvGN|uC)Hb3c=uWStfiHZ?n*KJF;DMea zYRfm9%UWHQN3pW6e5^a+>3cN*ZvE3yfsJYA&jA*gGT*u2j|_NDSBNVW21+~a8Z%OnbNWr zF(fEj)$jZq(|Q%O-Yfu22NMB5i&a}bgSS^r7T^!-&^%b0YfoM;AB23L3RA zIeKPnb)fTQ?5}C4YM%VWCS|r>c9{AG!V1;>A?8BpLj7Li5n|z@vL9_lzoR+*wXd|4 zGq1F45bd;6e$HmirWr8u0U9Ju{glz=a^;++N*q~>MMTgPwwI7}a>T~ap7)`P3yS`eoiOQkXW5Ap zFj_T`{$f9HEI|e!0b2R@u!wZW%CQBz=;!$utLSMy&z7fUx_yPgc?r2qhMY+Go4IuB zMJ--kSGS?tGbM*G*7p&iZ=obiG$i!cGhlF-`tQuViDCB{yQ9I!lrw}NHR43kS`vC+ z;aS268#@m>RUeOgj2muR7I}{U)Go!L*3o@@ux3o6_6vKXS?>H#s^)v-@i35?QRf!v zZT<6U92xp1+{Q2ckPb@jP~@7HplxX#A2H~rASFBp!D17_JlOJlVKHD9i>jrOI5%M( zvwT0d=Gy|7W&#`F3dN`>uoS7v2B1W*-GyhYVHbC1sIo)#NGZa}3hmXXg|( zg>4tMaNr_LKif>BtV9ptpKNSw94eU-CD!($cmdk;#|w+Ms=X=z&itHErZ@yCNr8*EQO1fjqMh*nH6WIQ^$`ZCMc`)|%1>nd?o zV;{b8K2D?S>Dd@VQ2G>$#{CPyy=B>mj=&z-L2I^P`@faL@;be16Uaa=+FD^9gaon1 z9O;-|l&a2VZfRLv^GVGw^Dc8X?iWkhL!QUKikN2m61DqVj1&Gd1$U+htpO3zcEW(D ze{0(7JOzt&kig%|Z@zoeznVqXv~Yf&gc_e+n!{YQW;ZQpJ^M)jVdsHA4;x70(A)`Q z0T|hflN}*l548;Wv95q1qPQhA5x6`&@ykpcV4iJc&B*ZkShx-ryR=m%a|e4KVieKC z4OrBR`Zs3mweAIk8#WF!x_Iy40G3pYL02VxpH_l&Y$1gU1S3feJ7oqdG(YE_RhnU~ zfH6Y>*cp1nK)*67^J{})04lCPulOzN#LMhzRbba-ddjU6=IHEoE-1K!3-6jxB9?3rz=VgV%!UO@98Hf-Dl6hqt@7&PiG?%zTueC@&y zKq0jw|MB8?X&~$XI4aBfF@?L;Gy!(~<%nlXh&;soTVz*niRZyBJhfE0L`V`3)vR$- z=C~zl6HMIojGC2AtP)K~)AJ_71o5~%XKA1F7U6>6HJ870KbuT!gj!+YFa0Q0clS7>1xJ*OfSdW@_U$u7{m8dZHZo$V}<+-FIt%E5XI z6E)7a$Sr5PrhfVu6z=D-I;m@PMs*ea`{rD{cJF`WcDhCIgu_rcMy`MW;zh7Sez3v<8 zy`y6A2?4Oo1^>@`@?G}NZa_&222Ih{rRkz_qvK}bPTHu|t71!o!2RiD|W zT^jE)`|Xb1GBk4*7=V&Uh)Fv?A0NgZWceo<&J*xd{y7IDWZqlg0byfZ8Q9{czlp~- z{W+OW0Zo2b^ySyk+CF(=#9KBgiVxCc8?|l6L3Qr|AJ{M3*xq932`K{)m!W+xBv4NCF_8@i*+= zY{1KD%j%^!}q^`a1`o0Ou&%`fN?B3 zdWC0_`ZyJW??-E~E@+iZIY%MW)QQPr3!Dk@JhS-fsGGQeSqG@v7{CCJBwF zkF&Yj(~nU6UfA^445K*yn^+rF43F{w>PA1PgS*Lo{g1`>2T8 zB90JdcY1~|_(t@yC+kzNXPnrJ%agBCM~HBEq0Rfnx?u048l;i;S&god_oVGW>k4Zo z`tKHDkpgwGyGx3x-K)KX%WR8tkAIVUKUQ5n9HBPh(nY7SPeZjdlKLbZaoUElTGDp! z_2?|)VH9nf&KUE3j~sUdoc zmP8vt5E4AdNYS1UCKyDGZbpwTg6JY)q6a~=5oH*?cOuG|C{ac?O7zZmhCJo{-u16< z{cD|N8Ju(ObDw=*_ul)u_I8UIbRih0r;TAH4DWhf%q~K%`jCZ5$1cekB~e;dCN4!h zAzgJN{m;bJHRBlitS9zKPL2RglT|8Z>(e>dOcVkwJlFNWm#ne$+jlb8ty1!g#)YL- z3+rdZUOh1<3KYUw4+@`zYI<13G@+W6%mvbREfQX6f8s(269(=9s}}4O%CffjHJ!Ro zso^w903uK)tlHhh#`K3cEdH8)X1@ZUKLjd7RY}jQ=8qL33^Tf!3XVqxN5xw8k@fpG z!g>I28Avz>Yn0{0Ci50~mro)Js@6M!xtx(?W29vQ&UT0L@{*E{^^H^Oy}=07dP?oM zu>iimIyAkp-@=-)Hub73sCi_?(&5CtQTQ^*-D($jwT{=&I2vqw@7h9Vn=dVz%li9n zw?KkKl2mc_>aR)mi!Bc#G@<%x*gGvlK!SYIq2xu~+HPyWJ6_ru23LZQ`}-h5>Rx=#E(EL``s>BJIWV=?VqP8NFf7Aznf-)4V! z9=aBcclypMmz5)H!pLH9pU$(M*5S+a}rN3){PY_digVoPfG)R_o+!%7=H@42yJO zeY5F3qlcV6Ny7E^GrGP4#!$7a&U=e%n;sZ%%(7O}1-&}DtgHay81qo-A=i*`3W`L| z6S>aTJDDa$lvEU78`{Aa?PPf2%lE|H0?XfpzQyj*7)uq>PlPZc8fTvBgPcoz+t%+^ zFS96!TWp$QCtgJQOJm*Y(dc&--@c{=ib~hN{o1#LE{i|M9QD%s@LE)4prG=-^0#hD z!kqT%mS%vu*G>0}n{Le2pmbEsv5(@!pn}xy&u7Ki+GE!TC;Nh4@qBIbY4PJ|&t~ON zNW7Zb82&zimVH%L*P$0ty}9(==L@{>t!I)@y*&!`>m1~P>Y7?of1tK93^n~Bl!fO8 z`YotfD7yH7hq*-oHzawTZ*2{Fei9ejhTU1yYt;4ae7#yOQ4-kV?B+Z}0K*?`QBLT# z_ z<$W|Z{m@EuCQj`Eq-5KT#^*2I`)u-|1GohjLkV{GQ9M3;$ms7iI8vMel zI9-#VVGNB{uBwY)5{K^NfkcJGUx^AYMQc4h>-6+mR82P>HQ?oX6caJz>;LWM=1tOQ z>J?o{NccgRQE?FYh_o2X9f>zJ{58CtN*We*U_G+sY%Q4*=iADSyqWyvaV4oyqw@va zb>jEnwtpaK0dMK!#IWx%A!`vkrEz01hQh?(7WhC2NfFW|_4&z(FpA3RZtOu zInfn~NXszVDM#?W41+G&%X6SG!ON$D%HM0Ah@oYUpwj-=LEtO@IsO3>A|z9owcrCK zm?_}hfg?Jva+#nH0ai}H0g5gKB+h@~)!DhoACvoXM5k%yLO!4(5bfK^{4aJ6Y@I75{^p6i8kt^E^b((kRTvsJ01QiY_|s%!mApUY$Z)lp`V{ zDJ^sw5cn}x*1hLS4vWB+hsp-{zwdC~8Arl4@yN02GDOq<7;qT#^eL)!z{W6BX<|T) zaK~$Lcyl=RaPz_*>uq0a?I|lOHtFmNUA8L)PJF71&mUfge*U)Ql3(;Y8MibvTcT#W zIP4%{P~=I;SSOwff3@E_+882g&^OJtmBXF<6vYQ?Z(iB3K!qlQV1>7dd>A8W4!AaktSDLPnwCBefoNjaqh);{M;1VzIn+nOtn(I09E0(};MsU}sv zN1@3C+G8aGmC!5o&+rJdg#fQ9uLa{&rM93~M%F3^Om|(1cET5kZtH~+u6j(7SumR+ zJuuCr^)nhlH%1rRFJr%s;1gl#H${Q>W~RDEh>V6)-K$B{X=&$Y0hPHK6R7pk)LYSk zS%(rT_8fbFXD3GPS_%Ps{%?ypW5Lfpev|yy#s%16!#lFScnX4M=4_if{R$XX29UY^ zH^0mX@&W8Ngp~m)M7Yc8@!zH$jfPI8hcD-=+J@(c^j#oaUVG9(T7T?mWY&1@cCKB) z;_2C;FexZIW=7*7*;~QL{th)@|Nomw<$egHWG+n)|V`uQMPxcI#$e_Q|0xNR9!$E3KS znP4tpmao^|0CS))+3~zqw(?Cz3C}qIasN(7Jmx3^YGYUpl63nA-Us+a0scW4I$k$O zEeEL`)F7b$&K3y_-x2AYi z$4+t6487!{ATYC&O$6(8AB;7Q2$7BL2kK#pg1?`G*707bW!Z3Rr9<%K&AX&A3bZ`j_A1o{ab4p{BY$fJ}k#WRezD4~&b4 zG+d$+9>em7TJ*?t-g^=_?JSBq;C^)1u);PywA!U*eX0ay1W@oHqi!;?M_k^V3gqhO zM1IHYHXF@b4c~YO?>FQELYXZdmV5Iiw9&4>u|X9s^YHz)InD1gUTIdjHi%`qd@-=E zpKp4QO9UBq>`9$IwGo8LzbUgtw1L}3ciEUbZIA?D$1xPlf<4vX=s-ml0JRjL?WZKIj3Z?pz0;Y*`vAkooycz}^X3KmPMBH^5U~#HM)BP-A;z z=(>MS4Y#=nNzLHQ`Ozw3fc9!offgh&QK;}R5(?m_zH*IFyTLcRrfVXz)4xM7&kya( z-Jh$tU4=542uXQbWFvm(+51X>8d-t&>^n$bawwMtPXNq_^2NuQQ{46)dC$&@yhOS$ z3D${Q|3hFy&YXcil5%&pc(b)s^UiTgN`s`pxU~1Nu0`2W;G&GiyWC&TVe{($_66R% z4&+9-DPc0}@&kZs1IVn5aL!c1gtK}Bxxvos6+5beab#j`hD zxU)XOd$XU|{{$)@N~*+uKi-klAH*f}(HoTmA?AZub}jvZx{u+`z3`95E#NGmY|Pyv z!ALv9Qi%lpUH5Hg${8T~3V`5z|KE%TU_m;8og#gA)5uZftjqpEi!7%B1qJh8X8A80 zBZe}j5Nfslwr9fX`~8uy`TxhSJ`_?j)xRUGM=8+5w_&FN7qSgLIjr#SbCg>#e{PJ7 zA8(JhpI9@WTC6lQsrJZKrgr%hT!EKOt6Q6Y|NHkP3%k32K2Es2re-+O`{&~Xwk=8WxWq)U!vT~r8n5%PYv$V`X{~|FC zmrk-}YU23_fDyh#dSDy^fQNpOgGOh%uJ&XwESFcH-L7mkO7S$B(rnP0+aZM%%OTm^ z+XJT9fPg6k9pBgl?jheme1FG1B*Y@-aIeLL6kuXno$IKue(kUsp=BE>gI4J|l(U^EBgE>rfTW`+LG#e05&j#3GY3g_X@;l}X`A^1(`76O zSA}!Hq{$)S53A9K*~Rs}-~XiDUB77vJ<~=W#txQ$7?UPkC}g@pzkdf>@-45#xWtEAZ9PXstEBL7b~Jq;+C@0?oj-_~<#QY7fxvj0dA{x?3JR{8t`oqVTaf&UXMTgBOL z6U>@U246`rhpj8X*x*D9Nzg=P8^Xl!9Y00j1&~4 zoKezoWt5Z#GqEv=!!=IwJyCa2jgnfA4P@pN-gN*_d%9l%n{skE`mvD{Z$P4zJLlsG zLz!0BU6>fQ5g-o`a8sB9(&bO}$Pi!cQRHadk>mpo4ydwAFOB&T4PheV_jjP@DdnK~ z5kx8PcwK8BIoWuMgidsHKT;bS>$>n^6w_o!RWOz$e-ZJyQ4KlN!roE-DB`R<)Kb%Z z9r0afH_f`H<2lf|Gh}OKV1-ipT~|});ICHTA;gZaP|$*Ejr2MfdQ%KPD#F-u?Y`+h zRSZ&CK~9zZRaN^Z6qoujl+Lx1c^{~cThx3cGUxyWRY;>Ug9Xa~Vqyr5JC}s!D~?vB ziv*y;{MJ8&GYRr_VT3Qb^qM4xj^=yKTRrE4N!ESG*$tGZZJ}fBu(hE5A+7{7$9Q;0 z&N4+NxP2OsAzxdkw=q_`YDnfoP-rUtLruqbn_G6AgCb|@SXg=B>q+_PfkWA=z43;p7yU7kfP4}OF z#d<$`r5oVkrRBspjrG_l|CEX0#L`+bJno4uw-wWL84)bF+$||LZm@il?`%~Cf)~0c z#hC)CUT1C&7G~oJF-e-FMU+Vr>mdn*%C@mHhiA^EeOv!f;v7f{VIefSoo3Y0qTFJ{HP#9^$4yxGqcfQ(5mf9dp#$kDbQ1pT|Ng$)1v=$_ z7Zf!wc9#ay2*0um*_d7T%diR*{oQzk5 zd9k3QnwrJuJSTKFC;Yw9$hX4KlyaHa7MUMc)5RZd85zg#uU%HAt+aJxAMAqZPX^)Z zFEZ$a;Da9?!S&hf(W6LV!S1L7r?5d*Oi-|8i@I*5y;?*{GTh^#UU8i>N)GujH2rLyRO1qN2-kP?uLIg8#^UzZ zG?k!acc2@L$WGvW(y(A>$g%e+u*BTREN>ebq@JBIdfsde9?-eStvc=n|CP~sb_?i6 zz%_>ITgej@3$Yuo@h;rRP@hXsfOYD{by+}*?lH7FSEA6~#&uihI_H}(-rJx^3>v5s z!>jq>;pb1gFbqYZk!EO6FgG;iAj80`)z0T({>lBc`AT)Q!nJFj-p687K%Jbwo8ZW# ztaZ&Vnn3(;6goMa9INgOjTD?lucV{x($UBSBD770nezQCb&uE&F~eO2o8}O3pfWXC zX0E+6`0ncaGN;;7Qx}JQd?n>R=u5$MH5e*VFBl(nZyU^xmfe-&b7(O&w}R~(BNx;cMTA6>NnT_BkYsXTWHDrtpYnM1ReGGa~0v211I zE_l^I0oPhuIrO4e8i%H(zC4LPJeyg`u_D^*OWx#sWKj8ViEblI6lZ@ zmuFs#oapJsM6PiLFWKkN39i!NnW=8R5ta%^G1uGBhl6wy>KYDvCwt$DiWKE{IzNwy z)x~36@3+%#*1t5fnx|tKt2>biLr*(bO8$Iuk4qC8368|SlfA{hV z()B)RX;EsbsGi>(o0P5cS}e}HLNyYZXZp}J0&wsRd<5@F%`6Y|;T$?HZf&tZv@lqE zwGl)0VXF?H7u&$Y%072;maF3|CKTOgjrcxq61c>x-W%&_SJ>}AmQrm1&Pw?PeW zbxK#fk$Qd_N0irXub$TPNJ{_wF;qaB|^L_dxh$y z@4T?`HNlFL?yZ_~_0F%x*YrfjkvM}DueA%aTAkuPt#3k|AJnLC$9V2ea#*4-(UZYs zzD^jxkNT_db`y{l16Db7RgFiFcg2|OGebGk0y$fT_h(h>CQabX@9mX~YNm8M35Xra z17uvBgU`|c%=sl<^vP;Yft!LgFP}r{^!grHTYACrhWlGvDYRY)$ zB2{#frGde?mqW<%g#1gKvp2=rJB{2yMAQ@i?_(M!KdVagvM0(UG|od~9nv;&}y48STTQ zj`+~dcO(VIyGGFonauefrs#M{UV&P-vwrq`?-2`XHRrY$9=}rqzp8Iyu4h|~CtF}E za74}Ie~Fg{6`72h>kSjEV%+$2q*oBSgThYLQ?-p=u(j%*@w%57U>l(e57@LuCfN7G zWRR2lg@K__!PJOddYuUxL#LnDb?@L98LUHYx|Z-ItEUEZ)%))?SJ_Q}j!8bw(?1Gw z180Bn;YU-dc`i8(q2ktMXH{~NfJoWG8JXryi`-lsW7YP*>lUSboswNH15>`+e-8cQ zBG6RTHmBQ7t?hY+O+k8ofc`az$8q10W~*~lUUx}8>WHiCLrwF%k131P!=@XQ0r=t~ z8f2%zcHB6n>XA*=Tf0C@#Hmt0d5xv$Yx2`%$#2?n;@*Pe8VrHK^vJ z=~%%NOZuNr9kez%YdOm*Ek_V;N(nU@xw61OHC^i9w z$4y;^)He6J8am-q>2Bd=RczooGVWzJ^K5UG4LmFTsO52UH@;T#A<&g+R?kjy%6*n; z@cHhYN*hULXkH)6qSs$Hv?X5>9|M|@mW!i9<4jiP(Ix!Y?lP-oCMuBbXXo{@E7JU=;BQyviVC8@CX+H`D_LlE)Fs5)O)K`7=;>Pu z>s17w#|R!=tkAeC-x9kE^cr^hjDFxaskyY+@R0r0GbibH5QYx>3ZT&wXK4CrjbeWa zQ>69m5?lG~YNvhqbWA{6V|)4%gS^k?fM!wQZDS}AGW6zLfaLfs;jmhuSWVy^{9SPa zi+$$H03u{?BsBxRFJm$d80TUGX-Qvm?E=kQKwZqAXyfhlelcn+cs(!5s}r0HB?me( z59y>vgc|5D$|6&ao1QJu2r;kk;FypCQx_30n}%)gr=2+Twv~+Z$*I`*9JQM*tDmbF zZ4|QuXziN$C;1)Vo-0QqV#(h7H|0=Quv3x2-`ZUJ$fm$$?>U+%kn)k(J{9t$h~D`0 z{o5klpD>MUO*SlQP2SxM!7Dd5qj&FtB~4Sd!`{MzlaJ-DGW_xG36?f3>*TdZFmf+V zB>9>?0=P;yMnQ>Ahx3{g2Ifc+}iie)Y_%YJ7$P?PUj%JWI4fMnzzVTh4&^*Sb@HrlKHQCokalm zJTBC%zPabhWn?S+vH}>n%`MbHiuI^J1klr3m44nyKwfk6TigCj02xR0azKeDgK$M# z@Z@Nyk6SNz{A6sW=HMrp@Zq3j?H<+1FDjpt@Y;jQlcU;`ofED-AGc$B#baTTxIo58 zdHC}_?hmYAe0E&NcRd__cyA<(SNv)KS{r$c9~^@jj(*|FH$O)i7JJ;wh6k4_z_r^z zg5*Caq*$R#4Q_h}R-q4ioy)YH3MImG=L}vo(>a1FH*w0|b??098pvvogm7W<2M4t$ z7Yess!&o{`6rwEO-ar0PzZ-5Jb^g8I{%l#z)-o_s%7Ujjkg6}f{K-AJo>b6ZX2Vc_*SG2E|%K&NI?Cd<7c zpxt@iO~f`YR|@(F zXWOe#@6n@bDnTygtc;N~ebpb2Q&U@<<%G~p)a08G4Eeaj5rAf0VC+=Ue41Qgi#quN zr2X?!#UcP?)cSIVM7h3C4N7*?YS6%t90^0(@7+;d3F$}+pic+q>d5VK7K+cU3m~~> z1~H@b_xP$dKsqoPI}kdpj@N@bVVI0TrfHvh+*PFfNUD%z0zJtm*Tdb#(9NBl=mQ6+Q+ z3@I-+n`7AZ57&@~UpjM?=^ItB^54aio_k~qTYkOO#iAG`!o6`5i7tE=iyAbQ&X9XH zZ@VDQO^-PKAYd1;1*vR=&D;#1!9&(C&7qte;wp$3?9stH#JPS-O|wfy{`2RKwV+4g zL7El;ewg8q()o||%0`~>YWM1{9;WlKxUUyLdruMG%mo;&1zh^%oL(W5x*)1_icVzLk z+*#^Vh&^NU#~yVjv4M5z#O{xfUt6?$#zt3l)F|Xzf>UJU9>#Z7f2AC&Z7ne`R?HXr zd0BmS16*?rbaZjePQb>ic!UKqOlIP|#?gOUUp>MfWIz#vt=Z#x!LJfb*FkNX*Fylag(!u-Gy>7X@#aC43=LbyKpe^!eDx9W~;!b!&1@f>et{8jLn}o+uAt)O!VloYFHJFZO#Cfpi7r7aM;L%mTpdk z6`_%kBQ*yK?u5+LmKHWjXb~CyIVEu_x8D;~Nl8DXP7&zZL0+#zh_-sruLSe@YK@#&&+T zhBLd#q*hjKL#SO$8~9BxiMm{iDVLUxw!Ph!hCg`!2j1zOO?6mxGsn_;850;z=d)u; z4H_Yn%Yrb-RgTq&=_69B3>XWtngn*QY&i>(r8)h0$LX=zrlT0OhMQBr5v>C^W9yfG zWS`%EUD>i4?Z)S-Py{~d|5S2K7mm?0k_4T+N;oZr0#nVA z1@oc8tgXGzGs)$ZBDy|NPG4>m)!83#C}|tis-Zn@9qI_NHh~^za$HeJEg6G_!BP z7Kxf9Oq>$--WOuDU>RQ@X{%Y6dtxo|>UCzAj2@&00|GK;5GPFE(nJzx>UW*{rfQ1H zl$i63nOQzBN^22w)HBZ5=+aU6*u9Ae#U3!hjs|81U7_vt-+Ju=mRBnqTP-pLq?;wY9=Zw zs3D>#9%ah~r7tM0k&5it1_Lx#L4p3yjNH`az)^#O00aP53SnWSrc7caL-H0^dbBX4 zRP!0_G`a=lC>!p9n6J5IHOMp!8N$aUrlO?k0|Emfp%3O0?Us5S#wzC{9o^FL;;|*K zu7(~ef7ajnI?_r+rDD{I@m0GEqnFeRn$V>F?xITW%n9`a%9>9FY;6tkB z7h*iYFK&c|JBuhr^>P(6KHT7Ma41?TY3gA9{98q^-qdsTX1MHiK? z3YXFcyVA|fyb3NLQF;5yROgo=BNO&1eVnRf9!GTEquiW)bNl?S;^Yv)f~MTbP~TTZ z5kswNwwD~N+b?`g{6Iy@}0CsKCpWV1WPOcrzTOv_} z3AaXpdU7{;>$pU+$mLg_^f@h}z3tkqdKYc2DUd3V`rPdqKd`Zs7)dz`d@3${d5c+x zDc?>H4|87BFo-K)eZCBw_CVLsUB8pxlA;hr4?*VQVh%zY;+v?ak+af{C=Fm~CgpFT zujq>lZ_xRHjs6JqnQ^dr7Dx;?K09Ylc;S7%|OysT`^KMz2xAk5r*$5JT{@#^MYflqaMB8hs;0$EGc>Ql^(B8eu{Aj3z_@yprWX0{QzwYN$3GK)#0Y+>?@ z#E`OJvNq~Z6=u*s0?%QDre2Fp2hoeufJpXIfi9Z=kN>PTZhTC&?ME5!Rd6^+_+NC7 M!D5h2><{9 literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/configure-backends.png b/po/it/docs/okular/configure-backends.png new file mode 100644 index 0000000000000000000000000000000000000000..74e5500b93c2bdea5f1b90253a6069b02d362cf4 GIT binary patch literal 18125 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 JF6*2Ung9!Tav1;s literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/configure-editor.png b/po/it/docs/okular/configure-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..ea406d7d258b3ff80d9d8692021b4408ae59b01e GIT binary patch literal 21564 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 literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/embedded-files-bar.png b/po/it/docs/okular/embedded-files-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..181577292ad191088c17576cb832b053f2026ee0 GIT binary patch literal 2978 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 Y2bGhykyM!VZ~y=R07*qoM6N<$g2{LJ!vFvP literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/forms-bar.png b/po/it/docs/okular/forms-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..020daa11ea3032c20ffa445014a9e8985e63652c GIT binary patch literal 3870 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 +KPDF"> + + +]> + + + + Manuale di &okular; + + Albert Astals Cid
    &Albert.Astals.Cid.mail;
    +
    +
    + Pino Toscano
    pino@kde.org
    +
    +
    + Enrico Ros
    eros.kde@email.it
    Traduzione della documentazione
    Nicola Ruggero
    nicola@nxnt.org
    Revisione della documentazione
    LuigiToscano
    luigi.toscano@tiscali.it
    Revisione della documentazione (kpdf->okular)
    +
    + &FDLNotice; + 2020-06-05 + 1.11 (Applications 20.08) + + + &okular; è un visualizzatore universale di documenti per &kde; basato sul codice di &kpdf;. + + + KDE + okular + pdf + ps + postscript + tiff + djvu + dvi + chm + xps + comicbook + fictionbook + markdown + mobipocket + plucker + annotazione + +
    + + Introduzione + &okular; è un visualizzatore universale di documenti per &kde; basato sul programma &kpdf;. Nonostante tragga origine dal codice di &kpdf;, &okular; ha delle funzionalità uniche, come la modalità panoramica, un miglior supporto per le presentazioni e supporto per le annotazioni. + &okular; supporta molti formati diversi come &PDF;, &PostScript;, Tiff, CHM, DjVU, immagini (png, jpg, &etc;), XPS, Open Document (ODT), Fiction Books, Comic Book, Plucker, EPub, Fax e Markdown. Per l'elenco dei formati supportati e delle relative funzionalità consultare la pagina dei gestori dei formati di documenti di &okular;. + + La finestra principale di &okular; + + + + + + La finestra principale di &okular; + + + + + + Uso di base + + Apertura dei file + Per vedere un qualsiasi file supportato in &okular;, scegli FileApri... , scegli un file supportato nella finestra di dialogo e fai clic sul pulsante Apri. Dovresti vedere ora il tuo file nella finestra principale. + + Il nuovo documento sarà aperto in una scheda se è selezionata l'opzione Apri i nuovi file nelle schede nella pagina di configurazione Generale. + Puoi chiudere le schede facendo clic su di esse con il &MMB;. + Il documento chiuso in precedenza nella scheda può essere riaperto usando la voce di menu &Ctrl;&Shift;TFile Annulla chiusura scheda. + + Se hai già aperto file in &okular;, puoi accedere velocemente ad essi selezionandoli nel menu FileApri recenti. + &okular; è il programma &kde; predefinito per i file &PDF; e &PostScript;, eseguito quando fai clic con il &LMB; su file di questo tipo nel gestore dei file. Se vuoi aprire un qualsiasi file il cui formato è supportato da &okular;, usa Apri con...&okular; dal menu contestuale nel gestore dei file. + Dopo avere aperto un file probabilmente vorrai leggerlo, e per questo motivo dovrai navigarci all'interno. Vai alla sezione successiva per saperne di più. + + + Navigazione + Questa sezione descrive come muoversi all'interno di un documento con &okular;. + Ci sono diversi modi di muoverti nell'area di visualizzazione. Uno è di usare i tasti &Up; e &Down;. Puoi anche usare la barra di scorrimento, la rotella del mouse o i tasti &PgUp; e &PgDn;. + Puoi anche usare i tasti di navigazione in stile vim, e in particolare H per spostarti all'estremità superiore della pagina precedente, L per spostarti all'estremità superiore della pagina successiva, J per spostarti in basso di una riga, e K per spostarti in alto di una riga. + Un altro modo è quello di premere il &LMB; su una qualunque parte del documento mentre trascini il mouse nella direzione opposta a quella in cui ti vuoi muovere. Questa procedura funziona solo se lo «Strumento navigazione» è attivato. In caso non lo fosse, puoi attivarlo da StrumentiNavigazione. + + Quando visualizzi un documento in modalità presentazione usa i tasti &Up; e &Down; per passare tra pagine o diapositive. Il numero e la posizione della diapositiva sarà mostrato nell'angolo in alto a destra del pannello a comparsa. + + Se vuoi leggere un documento con molte pagine puoi usare la funzione di scorrimento automatico di &okular;. Avvia lo scorrimento automatico con &Shift;&Down; o &Shift;&Up;. Quindi usa questi tasti per aumentare o diminuire la velocità di scorrimento. Puoi avviare o fermare temporaneamente lo scorrimento automatico premendo il tasto &Shift;; la pressione di un qualsiasi altro tasto disabilita questa funzione. + Un altro modo per navigare in un documento con svariate pagine prevede l'uso del puntatore del mouse. Trascina la pagina in alto o in basso, continua a trascinare anche dopo aver raggiunto e superato l'estremo inferiore o superiore. Quando superi il bordo di una pagina il puntatore appare nuovamente nell'estremità superiore o inferiore e puoi così semplicemente continuare a trascinare. + Attraverso la barra laterale a sinistra è possibile spostarsi nel documento in altri due modi: + + + Se fai clic sulla miniatura di una pagina, questa diverrà la pagina attiva. + + + Se il documento ha in indice dei contenuti, facendo clic su un elemento si andrà alla pagina corrispondente. + + + Se il documento ha livelli, puoi controllare quelli visualizzati selezionando o deselezionando gli elementi nell'elenco Livelli. + + + Se il documento ha dei segnalibri, abilita la vista Segnalibri e fai clic su di essi per accedere alla pagine associate. Se i segnalibri visualizzati non sono relativi solo al documento attuale, puoi passare rapidamente tra i segnalibri di tutti i file usati di recente. + + + Se il documento contiene delle annotazioni, abilita la vista Annotazioni e fai clic sulle annotazioni o selezionale con i tasti freccia &Up; e &Down; e premi &Enter; per andare alla pagina associata. + + + In alcuni documenti sono presenti dei collegamenti. In questo caso si può fare clic su di essi e la vista verrà spostata alla posizione a cui fanno riferimento. Se il collegamento punta ad una pagina web o qualche altro documento, verrà lanciato il gestore &kde; per quel tipo di documento. Ad esempio, facendo clic su un collegamento che punta a https://www.kde.org si aprirà questa pagina web nel browser web predefinito di &kde;. + + I collegamenti interni del documento funzionano solo quando viene usato lo Strumento navigazione. + + In più, puoi usare le seguenti funzioni per spostarti velocemente a parti specifiche del documento: + + + Puoi spostarti all'inizio del documento premendo &Ctrl;Home oppure usando Vai Inizio del documento . + + + Puoi spostarti alla fine del documento premendo &Ctrl;Fine oppure usando Vai Fine del documento . + + + Puoi spostarti in avanti nel documento premendo &Space; o &PgDn;. Per andare alla pagina successiva del documento puoi usare il pulsante Pagina successiva della barra degli strumenti oppure la voce di menu Vai Pagina successiva . + + + Puoi spostarti indietro nel documento premendo &Backspace; o &PgUp;. Per andare alla pagina precedente del documento puoi usare il pulsante Pagina precedente della barra degli strumenti oppure la voce di menu Vai Pagina precedente . + + + Puoi tornare indietro nel documento alle posizioni di provenienza in ordine cronologico. Ad esempio, stai leggendo la frase Come mostrato in [15], …, e vuoi controllare rapidamente la fonte [15]. Fai quindi clic su di essa, e &okular; passa all'elenco delle fonti. Usando &Alt;&Shift;&Left; o Vai Indietro nella barra dei menu verrai portato indietro alla posizione da dove sei arrivato. + + + Puoi spostarti avanti nel documento dopo il salto all'indietro descritto in precedenza usando &Alt;&Shift;&Right; oppure usando Vai Avanti nella barra dei menu. + + + Puoi spostarti alla corrispondenza successiva di una ricerca usando i tasti F3 o &Enter; (quando è evidenziato il campo di testo Trova) o la voce di menu Modifica Trova successivo ; o spostarti indietro alla corrispondenza precedente usando i tasti &Shift;F3 o &Shift;&Enter; (quando è evidenziato il campo di testo Trova) o la voce di menu Modifica Trova precedente . + + + + + Modalità Presentazione + La modalità presentazione rappresenta un altro modo di vedere i documenti in &okular;, e può essere attivata in VisualizzaPresentazione. Visualizza il documento pagina dopo pagina. Le pagine vengono visualizzate adattandole allo schermo, questo significa che ogni pagina è mostrata completamente. + + I documenti &PDF; possono anche specificare che devono essere aperti sempre in modalità di presentazione. + + In modalità presentazione è disponibile una barra di aiuto posizionata nella parte alta dello schermo. Basta muovere il puntatore del mouse nella parte alta dello schermo per farla apparire. + + &okular; in modalità presentazione + + + + + + &okular; in modalità presentazione + + + + Per muoverti tra le pagine puoi usare &LMB; (pagina successiva) e &RMB; (pagina precedente), la rotellina del mouse, le icone a forma di freccia o la casella di testo che appaiono quando sposti il puntatore nella parte più alta dello schermo, o con i tasti specificati nella sezione Navigazione. + Usa il pulsante Riproduci/metti in pausa nella barra superiore per avviare la presentazione o metterla in pausa, rispettivamente. + Puoi uscire dalla modalità presentazione in qualunque momento premendo il tasto &Esc; o facendo clic sull'icona Esci nella barra superiore. + Puoi anche disegnare con una matita sulla pagina corrente. Fai clic sull'icona Commuta modalità disegno nella barra in alto per abilitare o disabilitare la possibilità di disegnare in modalità presentazione. Gli schizzi saranno cancellati automaticamente uscendo dalla modalità presentazione. Puoi anche fare clic sull'icona Cancella disegni per rimuovere i disegni nella pagina corrente. + La modalità presentazione supporta la presenza di più schermi in configurazione multi-monitor. Se è presente più di uno schermo, sarà disponibile un ulteriore pulsante nella barra superiore, con l'icona di uno schermo: si tratta di una casella a cascata che consente di spostare la presentazione su uno degli schermi disponibili. + La modalità presentazione è configurabile. Puoi trovare ulteriori dettagli nel capitolo Configurare &okular;. + + + + Ricerca inversa tra editor &latex; e &okular; + + La ricerca inversa è una funzionalità utile quando scrivi un documento &latex;. Se tutto è a posto, puoi fare clic nella finestra di &okular; con il tasto sinistro del mouse tenendo premuto &Shift;. Dopodiché, l'editor caricherà il file sorgente &latex; e salterà al paragrafo giusto. + + La ricerca inversa non può funzionare a meno che: + + + Il file sorgente sia stato compilato correttamente. + &okular; sappia quale editor vuoi usare. + Lo «Strumento navigazione» sia attivato. In caso non lo fosse, puoi attivarlo da StrumentiNavigazione. + + + Con questa funzionalità di &okular;, un clic sul &LMB; tenendo premuto &Shift; nel documento &DVI; o &PDF; farà aprire all'editor il documento &latex; corrispondente, e gli farà cercare di raggiungere la riga corrispondente. Ricordati di dire a &okular; di usare un editor appropriato, tramite la voce ImpostazioniConfigura Okular... (sulla pagina Editor) del menu di &okular;. + + Per maggiori informazioni sulla configurazione dell'editor fai riferimento alla sezione corrispondente di questo manuale. + + + Configurazione di &okular; + + + + + + Configurazione dell'editor in &okular; + + Configurazione dell'editor in &okular; + + + + + + + Funzionalità avanzate di &okular; + + Allegati + Se il documento corrente contiene degli allegati, in fase di apertura apparirà una barra sopra la vista della pagina per informarti riguardo gli allegati presenti. + + La barra degli allegati + + + + + + La barra degli allegati + + + + In questo caso puoi fare clic sul collegamento nel testo della barra o scegliere FileAllegati per aprire la finestra di dialogo degli allegati. La finestra di dialogo consente di visualizzare gli allegati e di estrarli. + + + Moduli + Se il documento corrente contiene dei moduli, in fase di apertura apparirà una barra sopra la vista della pagina da cui potrai abilitare i moduli. + + La barra dei moduli + + + + + + La barra dei moduli + + + + In questo caso puoi fare clic su Mostra moduli nella barra o scegliere VisualizzaMostra moduli per inserire i dati nei campi del modulo. + + + Firme + Se il documento corrente contiene delle firme, apparirà una barra sopra la vista della pagina dopo l'apertura del documento. Permette ti aprire il pannello Firme. + + La barra delle firme + + + + + + La barra delle firme + + + + Usando il pannello Firme puoi esaminare la firma del documento ed il suo certificato. + + Il pannello delle firme + + + + + + Il pannello delle firme + + + + + Questa funzione è disponibile solo per documenti &PDF;. Devi installare almeno la versione 0.51 di Poppler per ottenere la maggior parte delle informazioni sulla firma, la versione 0.68 per ottenere le informazioni sulla posizione e motivazione della firma, e la versione 0.73 per ottenere le informazioni sul certificato di firma. + + + + Annotazioni + &okular; ti permette di revisionare e annotare i tuoi documenti. + + Le annotazioni in &okular; + + + + + + Le annotazioni in &okular; + + + + &okular; mette a disposizione due tipi di annotazioni: + Annotazioni del testo come l'evidenziatore giallo e la sottolineatura nera per i file contenenti testo come ⪚ i &PDF;. + Annotazioni grafiche come la nota, la nota in linea, la linea a mano libera, la linea retta, il poligono, il timbro e l'ellisse e macchina da scrivere per tutti i formati supportati da &okular;. + Usando il menu contestuale nella vista Annotazioni della barra laterale o nella finestra principale puoi aprire una nota a comparsa per ogni tipo di annotazione e aggiungere o modificare i commenti. + Le annotazioni non sono limitate ai soli file &PDF;, ma possono essere usate in ogni formato di file supportato da &okular;. + &okular; dispone della funzione di "archiviazione del documento". Si tratta di un formato specifico di &okular; per immagazzinare il documento ed i relativi metadati (attualmente solo annotazioni). Puoi salvare un "archivio di documento" tramite la voce di menu FileSalva come e selezionando Archivio di documento Okular nel selettore Filtro. I documenti così salvati useranno .okular come estensione nel nome del file. Per aprire un archivio di documento di &okular; basta semplicemente aprirlo con &okular; come se fosse ⪚ un documento &PDF;. + Puoi anche salvare le annotazioni direttamente nei file &okular;. Puoi utilizzare File Salva per sovrascrivere il file attuale o File Salva come... per salvarlo in un nuovo file. + + A causa delle limitazioni DRM (normalmente nei documenti &PDF;), l'aggiunta, la modifica di alcune proprietà o la rimozione delle annotazioni potrebbe non essere possibile. + + + Ogni azione sulle annotazioni (creazione e rimozione di annotazioni, modifica di proprietà arbitrarie di annotazioni, spostamento di annotazioni usando &Ctrl;+trascinamento, e modifica del contenuto del testo di un'annotazione) puoi essere annullata o rifatta usando la voce corrispondente del menu Modifica. È anche possibile annullare l'azione premendo &Ctrl;Z e rifare l'azione annullata premendo &Ctrl;&Shift;Z. + + Puoi configurare le proprietà e l'aspetto predefiniti per ogni strumento di annotazione. Fai riferimenti alla sezione corrispondente in questa documentazione. + + Aggiunta di annotazioni + Per aggiungere delle annotazioni ad un documento, devi usare il pulsante Annotazioni veloci nella barra degli strumenti principale di &okular; o attivare la barra degli strumenti delle annotazioni. Si può fare selezionando StrumentiAnnotazioni o premendo F6. Una volta che la barra degli strumenti di annotazione è visualizzata, è sufficiente premere uno dei suoi pulsanti o usare le scorciatoie di tastiera (i tasti da 1 a 9) per iniziare a costruire la relativa annotazione. + La barra degli strumenti di annotazione ti aiuta a creare delle annotazioni con disegni, forme e messaggi di testo. Puoi usare la barra degli strumenti di annotazione per contrassegnare un documento (⪚ aggiungere linee, ellissi, poligoni, timbri, evidenziatori, sottolineature, &etc;). La tabella di seguito descrive il comportamento dell'insieme predefinito di pulsanti della barra degli strumenti di annotazione. + + + + + Pulsante + Nome dello strumento + Descrizione + + + + + + + + + + + + + + + Evidenziatore + + + Per evidenziare del testo nel documento con un determinato colore di sfondo. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per segnare l'inizio del frammento di testo evidenziato; infine trascina il puntatore del mouse per evidenziarlo. + È possibile definire il tipo (evidenziato, scarabocchiato, sottolineato o barrato), il colore e l'opacità per l'evidenziatore. Fai clic con il tasto destro del mouse sul testo evidenziato e seleziona la voce di menu Proprietà. + + + + + + + + + + + + + + Sottolineatura + + + Per sottolineare del testo. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per segnare l'inizio del frammento di testo sottolineato; infine trascina il puntatore del mouse per sottolinearlo. + È possibile definire il tipo (evidenziato, scarabocchiato, sottolineato o barrato), il colore e l'opacità per il testo sottolineato. Fai clic con il tasto destro del mouse sul testo sottolineato e seleziona la voce di menu Proprietà. + + + + + + + + + + + + + + Scarabocchiato + + + Per sottolineare del testo con una linea scarabocchiata. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per segnare l'inizio del frammento di testo sottolineato; infine trascina il puntatore del mouse per sottolinearlo. + È possibile definire il tipo (evidenziato, scarabocchiato, sottolineato o barrato), il colore e l'opacità per il testo sottolineato. Fai clic con il tasto destro del mouse sul testo sottolineato e seleziona la voce di menu Proprietà. + + + + + + + + + + + + + + Barrato + + + Per barrare del testo. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per segnare l'inizio del frammento di testo sottolineato; infine trascina il puntatore del mouse per sottolinearlo. + È possibile definire il tipo (evidenziato, scarabocchiato, sottolineato o barrato), il colore e l'opacità per il testo sottolineato. Fai clic con il tasto destro del mouse sul testo sottolineato e seleziona la voce di menu Proprietà. + + + + + + + + + + + + + + Macchina da scrivere + + + La macchina da scrivere fornisce lettere opache su uno sfondo trasparente, ed è pertanto utile per riempire dei moduli non interattivi. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare l'angolo superiore sinistro della nota; infine trascina il puntatore del mouse per posizionare l'angolo inferiore destro. Inserisci il testo della nota e fai clic sul pulsante OK per salvare la nota, Annulla per annullare la creazione della nota o Pulisci per cancellare il testo della nota. + È possibile definire il carattere ed il colore del testo per il testo. Basta fare clic con il pulsante destro sul testo creato e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Nota in linea + + + Per disegnare una nota in linea. La nota sarà mostrata in linea così com'è. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare l'angolo superiore sinistro della nota; infine trascina il puntatore del mouse per posizionare l'angolo inferiore destro. Inserisci il testo della nota e fai clic sul pulsante OK per salvare la nota, Annulla per annullare la creazione della nota o Pulisci per cancellare il testo della nota. + È possibile definire il colore, l'opacità l'icona, il carattere, l'allineamento e la larghezza del bordo per la nota. Basta fare clic con il pulsante destro sull'icona della nota creata e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Nota a comparsa + + + Per disegnare una nota su più righe. La nota sarà visualizzata facendo doppio clic sulla relativa icona nel documento. + Fai clic sul pulsante dello strumento, quindi fai clic sulla posizione del documento dove aggiungere la nota a comparsa. Inserisci il testo della nota, quindi fai clic sul pulsante Chiudi questa nota nell'angolo superiore destro della finestra a comparsa. + È possibile definire il colore, l'opacità e l'icona per la nota. Basta fare clic con il pulsante destro sull'icona della nota creata e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Linea a mano libera + + + Per disegnare delle linee a mano libera. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare l'inizio della linea; infine trascina il puntatore del mouse per tracciare la linea. + È possibile definire il colore, l'opacità e la larghezza per la linea. Basta fare clic con il pulsante destro sulla linea creata e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Freccia (elenco a discesa) + + + Per marcare con una freccia. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare il punto iniziale della linea; infine trascina il puntatore del mouse per posizionare il punto finale della linea e fai nuovamente clic. + È possibile definire il colore, l'opacità, la larghezza, l'inizio dalla linea, la fine della linea, la Lunghezza linea direzionale e la lunghezza estensioni linea direzionale per la linea. Basta fare clic con il pulsante destro sulla linea creata e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Linea retta (elenco a discesa) + + + Per marcare con una linea. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare il punto iniziale della linea; infine trascina il puntatore del mouse per posizionare il punto finale della linea e fai nuovamente clic. + È possibile definire il colore, l'opacità, la larghezza, l'inizio dalla linea, la fine della linea, la Lunghezza linea direzionale e la lunghezza estensioni linea direzionale per la linea. Basta fare clic con il pulsante destro sulla linea creata e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Rettangolo (elenco a discesa) + + + Per disegnare un rettangolo attorno ad un'area scelta. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare l'angolo superiore sinistro del rettangolo; infine trascina il puntatore del mouse per posizionare l'angolo inferiore destro. + È possibile definire il tipo( rettangolo o ellisse), il colore, l'opacità, il riempimento forma (ed il suo colore) e la larghezza per il bordo. Basta fare clic con il pulsante destro sul bordo creato e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Ellisse (elenco a discesa) + + + Per disegnare un'ellisse o un rettangolo attorno ad un'area scelta. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare l'angolo superiore sinistro del rettangolo che racchiude l'ellisse; infine trascina il puntatore del mouse per posizionare l'angolo inferiore destro. + È possibile definire il tipo( rettangolo o ellisse), il colore, l'opacità, il riempimento forma (ed il suo colore) e la larghezza per il bordo. Basta fare clic con il pulsante destro sul bordo creato e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Poligono (elenco a discesa) + + + Per tracciare una figura piana chiusa a partire da tre o più segmenti. La nota corrispondente può essere visualizzata facendo doppio clic all'interno del poligono. + Fai clic sul pulsante dello strumento, quindi fai clic con il &LMB; e tienilo premuto per posizionare il primo vertice del poligono; infine trascina per posizionare il secondo vertice. Procedi così finché non ha tracciato l'intero poligono fino al primo vertice. Fai clic due volte se vuoi aggiungere una nota al poligono. Inserisci il testo della nota e fai clic sul pulsante OK per salvare la nota, Annulla per annullare la creazione della nota o Pulisci per cancellare il testo della nota. + È possibile definire il colore, l'opacità, il riempimento forma (ed il suo colore) e la larghezza per il poligono. Basta fare clic con il pulsante destro sul poligono creato e selezionare la voce di menu Proprietà. + + + + + + + + + + + + + + Timbro + + + Per marcare del testo o un'immagine con una forma predefinita. + Fai clic sul pulsante dello strumento per scegliere il timbro dall'elenco a discesa, quindi fai clic con il &LMB; per posizionare il timbro. + Un singolo clic posiziona esattamente un timbro quadrato (utile per le icone). Per aggiungere un timbro rettangolare puoi fare clic con il &LMB; e tenere premuto per posizionare il punto superiore sinistro, quindi trascinare per posizionare quello in basso a destra. + È possibile definire l'Opacità ed il Disegno del timbro per il timbro. Basta fare clic con il pulsante destro sull'icona del timbro creato e selezionare la voce di menu Proprietà. + + Questa funzione è sperimentale. I timbri personalizzati inseriti nei documenti &PDF; non saranno visibili in lettori &PDF; diversi da &okular;. + + + + + + + Queste sono le annotazioni predefinite fornite da &okular;. Usando la pagina Annotazioni della finestra di dialogo di configurazione puoi aggiungere delle annotazioni a tua scelta come timbri personalizzati, marcatori di testo, forme geometriche con un colore interno per evidenziare delle regioni, &etc; + + È possibile aggiungere del codice &latex; nel testo delle annotazioni. Aggiungi $$codice$$ nel testo di una annotazione, dove codice è una qualsiasi equazione &latex; valida, e segui le istruzioni sullo schermo perché tale equazione sia resa correttamente tramite una distribuzione &latex; installata nel sistema. + + È possibile configurare le opzioni dello strumento corrente usando la stessa barra degli strumenti delle annotazioni. La tabella di seguito descrive esattamente cosa fanno i pulsanti predefiniti di configurazione della barra degli strumenti delle annotazioni. + + + + + Pulsante + Nome opzione + Descrizione + + + + + + + + + + + + + + + Spessore della linea + + + Fai clic sul pulsante dello strumento per scegliere lo spessore dalla barra dall'elenco a discesa. + + + + + + + + + / + + + + + + + Colore dell'annotazione + + + Fai cli sul pulsante dello strumento per scegliere il colore del testo o del bordo dell'annotazione. Puoi scegliere uno dei colori predefiniti o fare clic su Colore personalizzato... per aprire la finestra di selezione del colore. + + + + + + + + + + + + + + Colore di riempimento dell'annotazione + + + Fai cli sul pulsante dello strumento per scegliere un colore di riempimento per l'annotazione. Puoi scegliere uno dei colori predefiniti o fare clic su Colore personalizzato per aprire la finestra di selezione del colore. + + + + + + + + + + + + + + Opacità dell'annotazione + + + Fai clic sul pulsante dello strumento per scegliere il livello di opacità dell'annotazione dall'elenco a discesa) (100% corrisponde ad annotazioni opache). + + + + + + + + + + + + + + Carattere dell'annotazione + + + Fai clic sul pulsante dello strumento per aprire la finestra di selezione dei caratteri. + + + + + + + + + + + + + + Impostazioni avanzate per lo strumento di annotazione attuale + + + Fai clic sul pulsante degli strumenti per aprire la finestra di dialogo generale per la tua annotazione. + + + + + + Ci sono tre ulteriori pulsante di utilità nella barra degli strumenti predefinita delle annotazioni. + + + + + Pulsante + Descrizione + + + + + + + + + + + + + + + Aggiungi l'annotazione attuale al menu Annotazioni veloci nella barra degli strumenti principale. + + Puoi usare le scorciatoie predefinite da &Alt;9 a &Alt;0 per selezionare le azioni di annotazione veloce quando vuoi, anche quando la relativa barra degli strumenti è nascosta. + + + + + + + + + + + + + + + Quando è selezionato, mantiene attivo lo strumento di annotazione attuale dopo l'uso. + + + + + + + + + + + + + + Nasconde la barra delle annotazioni. + + + + + + Premendo &Shift; puoi vincolare l'angolo di annotazioni di tipo linea e poligono a passi di 15°, ed il rapporto delle annotazioni di tipo forma (⪚ rettangolo, ellisse) ad 1:1. Puoi anche ottenere un pulsante della barra degli strumenti da Configure barre degli strumenti.... + I contenuti del menu Annotazioni veloci possono essere configurati usando la pagina Annotazioni della finestra di configurazione di &okular;. Questa pagina può essere aperta facendo clic sul pulsante Annotazioni veloci, selezionando quindi Configura annotazioni... dal menu a comparsa. + + L'attivazione della barra degli strumenti di annotazione fa tornare in modalità navigazione. + + Puoi fermare la costruzione in un qualsiasi momento premendo nuovamente il pulsante dell'annotazione che stai costruendo, o premendo il tasto &Esc;. + L'annotazione appena costruita avrà come autore quello che hai impostato nella pagina Annotazioni della finestra di dialogo di configurazione di &okular;. La pagina Annotazioni può essere usata anche per configurare il contenuto della barra degli strumenti di annotazione. + + + Rimozione della annotazioni + Per rimuovere un'annotazione, fai clic su di essa con il &RMB; e seleziona Elimina o seleziona un'annotazione usando il &LMB; e premi il pulsante ∇. + Quando un'annotazione viene rimossa, la sua finestra verrà chiusa se aperta. + + Questa opzione non può essere attivata perché il documento non consente la rimozione delle annotazioni. + + + + Modifica della annotazioni + Per modificare un'annotazione, fai clic su di essa con il &RMB; e seleziona Proprietà. Sarà mostrata una finestra di dialogo con le impostazioni, sia generali per tutti i tipi di annotazioni (come colore e opacità, autore, &etc;) che specifiche per quel tipo di annotazione. + + La finestra delle proprietà delle annotazioni + + + + + + La finestra delle proprietà delle annotazioni + + + + Per spostare un'annotazione, tieni premuto il tasto &Ctrl;, sposta il puntatore del mouse su di essa e trascinala con il &LMB;. + Se fai clic con il &LMB; su un'annotazione, questa viene selezionata. Maniglie di ridimensionamento appariranno nel rettangolo di selezione. Quando il cursore viene spostato su una delle otto maniglie di ridimensionamento agli angoli o ai bordi, la forma del cursore cambia per indicare la modalità di ridimensionamento. Fai clic su qualunque altro punto nell'annotazione per spostarlo. La pressione del tasto &Esc; o un clic del mouse su un'area fuori dall'annotazione annulla la selezione. + Il ridimensionamento è applicabile solo per le annotazioni di tipo nota in linea, macchina da scrivere, timbro ed ellisse. + + + In base ai permessi del documento (in particolare con i documenti &PDF;) alcune opzioni potrebbero essere disabilitate. + + + + + Gestione dei segnalibri + &okular; dispone di un sistema di segnalibri molto flessibile. &okular; salva in ogni segnalibro la posizione nella pagina e permette di definire più di un segnalibro per pagina. + Per gestire i segnalibri in &okular; puoi usare la vista Segnalibri dalla Barra laterale, dal menu Segnalibri o dal menu contestuale della vista del documento (fai clic con il &RMB; per aprirlo). + + La vista segnalibri + Per aprire la vista Segnalibri fai clic sulla scheda Segnalibri nella Barra laterale. Se la Barra laterale non è visibile, fai clic sul pulsante Mostra la barra laterale nella barra degli strumenti, o usa la voce di menu F7 ImpostazioniMostra la barra laterale per renderlo visibile. + + Menu contestuale della vista segnalibri + + + + + + Menu contestuale della vista segnalibri + + + + La barra dei filtri nella parte alta della vista dei Segnalibri può essere usata per filtrare il contenuto del pannello della lista dei segnalibri usando il testo nella casella. + Il pannello con l'elenco consente di visualizzare la lista dei segnalibri in stile albero: ogni documento nella lista può essere espanso o contratto facendo clic sull'icona < o v accanto ad essa. + Fai clic sull'icona sotto la lista per mostrare solo i segnalibri del documento attuale. + Il menu che appare facendo clic con il pulsante destro su una voce relativa ad un documento permette di aprire il documento, rinominare la voce relativa o rimuoverla dalla lista. Tieni conto che la rimozione di una voce di documento provoca la rimozione di tutti i segnalibri del corrispondente documento. + Il menu che appare facendo clic con il pulsante destro su un singolo segnalibro permette di passare a quel segnalibro, rinominarlo o rimuoverlo. + Il menu che appare con un clic del pulsante destro del mouse sugli elementi dell'indice dei contenuti può essere usato per creare segnalibri o passare al segnalibro precedente o successivo. + + + + + Opzioni dalla riga di comando + Anche se la maggior parte delle volte si lancia &okular; dal menu dei programmi di &kde; o da un'icona del desktop, può anche essere aperto dalla riga di comando in una finestra del terminale. Ci sono diverse opzioni utili disponibili in questa modalità. + + Specifica un file + Specificando il percorso e il nome di un particolare file l'utente può far sì che &okular; apra quel file immediatamente all'avvio. Questa opzione può assomigliare a questa: + % okular + + + Nel caso di documenti &PDF; il nome può essere specificato come nome_documento#nome_destinazione, dove nome_destinazione è l'identificativo di una destinazione presente nel documento. + + + + Altre opzioni dalla linea di comando + Sono disponibili le seguenti opzioni di aiuto dalla riga di comando + + + okular + Apre la pagina del documento identificata dal numero fornito. È disponibile anche attraverso okular + + + okular + Apre il documento in modalità presentazione + + + okular + Avvia mostrando la finestra di stampa. + + + okular + Avvia mostrando la finestra di stampa e termina dopo la stampa. + + + okular + Controllo "istanza unica". + + + okular + Permette di evitare che la finestra di &okular; si rialzi dopo l'avvio. + + + okular + Cerca di trovare ed evidenziare una stringa nel documento. Funziona solo viene passato un singolo documento come argomento del comando okular. + + + + + + Adatta finestra alla pagina + La funzione «Adatta finestra alla pagina» ridimensiona la finestra in modo che abbia la stessa dimensione della pagina al valore di ingrandimento attuale. Se la pagina non entra del tutto nello schermo, la finestra viene allargata in modo che venga massimizzata la parte di immagine mostrata. + Si può accedere a questa funzione tramite la scorciatoia di tastiera &Ctrl;J. + + + + + La barra dei menu + + + Il menu File + + + + &Ctrl;O File Apri... + + + Apre un file supportato od un archivio di documento &okular;. Se c'è già un file aperto, questo verrà chiuso. Per maggiori informazioni, vedi la sezione che riguarda l'apertura dei file. + + + + + + File Apri recenti + + + Apre un file che è stato usato di recente selezionandolo da una lista in un sottomenu. Se c'è già un file aperto, questo verrà chiuso. Per maggiori informazioni, vedi la sezione riguardante l'apertura dei file. + + + + + + File Importa PostScript come &PDF;... + + + Apre un file &PostScript; e lo converte in formato &PDF;. + + + + + + &Ctrl;&Shift;T File Annulla chiusura scheda + + + Riapre l'ultimo documento chiuso. Questa azione è attiva solo se hai chiuso qualche documento nelle schede durante la sessione corrente. + + + + + + File Apri cartella contenitore + + + Apre la cartella che contiene il documento attuale nel tuo gestore dei file preferito. Questa azione è utile in particolare nel caso in cui hai scaricato da Internet un file &PDF; che si apre in &okular;. La posizione di questo file potrebbe non essere chiara o facile da trovare senza questa funzione. + + + + + + &Ctrl;S File Salva + + + Salva il documento visualizzato incluse tutte le modifiche (annotazioni, contenuto dei moduli, &etc;), se il backend relativo ne supporta il salvataggio. Se il backend non supporta il salvataggio delle modifiche l'utente potrà scegliere di scartarle o salvare insieme al documento in un archivio di documento &okular;. + + + + + + &Ctrl;&Shift;S File Salva come... + + + Salva il documento visualizzato con un altro nome incluse tutte le modifiche (annotazioni, contenuto dei moduli, &etc;), se il backend relativo ne supporta il salvataggio. Se il backend non supporta il salvataggio delle modifiche l'utente potrà scegliere di scartarle o salvare insieme al documento in un archivio di documento &okular;. + + Nota bene che, per il modo in cui questa azione viene attuata, anche il file non ha modifiche, il nuovo file potrebbe non essere una copia esatta (bit per bit) del file originale (⪚ può avere un hash SHA-1 differente, &etc;). + + + + + + + F5 File Ricarica + + + Ricarica il documento aperto attualmente. + + + + + + &Ctrl;P File Stampa... + + + Stampa il documento attualmente visualizzato. Bisogna considerare che &okular; mette a disposizione alcune opzioni specifiche per la stampa di &PDF; che sono disponibili tramite il pulsante Opzioni +> +>, e quindi selezionando Opzioni &PDF;. Usa queste opzioni per stampare le tue annotazioni o configurare la modalità di trasformazione se hai dei problemi nella stampa di alcuni simboli o devi cambiare la modalità di scalatura. + + Le opzioni relative alla modalità di scalatura sono disponibili solo quando viene selezionata l'opzione Forza trasformazione. + + + + + + + File Anteprima di stampa... + + + Visualizza un'anteprima di come verrà stampato il documento con le opzioni di stampa di default. + + + + + + &Alt;Invio File Proprietà + + + Mostra alcune informazioni basilari sul documento, come il titolo, l'autore, la data di creazione, e dettagli sul tipo di carattere utilizzato. Le informazioni disponibili dipendono dal tipo del documento. + + Fai attenzione sulle informazioni sulla sostituzione dei caratteri nella scheda Caratteri nella finestra Proprietà. Vari problemi legati alla resa dei caratteri possono esseri risolti installando dei caratteri sostitutivi. + + + + + + File Allegati... + + + Mostra gli allegati nel documento, se presenti. Per maggiori informazioni, consulta la sezione sugli allegati. + + + + + + File Esporta come + + + Questa voce di menu mostra i formati verso cui è possibile esportare il documento corrente. La prima voce per qualsiasi tipo di documento è sempre Testo semplice.... + La seconda voce è Archivio di documento, che ti consente di salvare il documento con le annotazioni in un tipo di archivio specifico di &okular; In questo modo diventa semplice condividere con altri utenti di &okular;, e lavorare in collaborazione con loro, il documento originale e le tue annotazioni. + + + + + + File Condividi + + + Questa voce di menu contiene i servizi che possono essere usati per condividere il documento attuale con altre persone per inviarlo a dei dispositivi. Le voci in questo sotto-menu sono controllate dal sistema. Dipendono dal formato del documento attuale e dalle estensioni di KPurpose. + + + + + + &Ctrl;Q File Esci + + + Esce da &okular;. + + + + + + + Il menu Modifica + + + + + &Ctrl;Z Modifica Annulla + + + Annulla l'ultimo comando di modifica delle annotazioni (creazione e rimozione di annotazioni, modifica di proprietà arbitrarie di annotazioni, spostamento di annotazioni usando &Ctrl;+trascinamento, e modifica del contenuto del testo di un'annotazione). + + + + + + &Ctrl;&Shift;Z Modifica Rifai + + + Riesegue l'ultima annullamento durante la modifica delle annotazioni. + + + + + + + + &Ctrl;C Modifica Copia + + + Copia negli appunti il testo selezionato in modalità Selezione testo. + + + + + + + + &Ctrl;A Modifica Seleziona tutto + + + Seleziona tutto il testo (se presente nel documento). Funziona solo in modalità Selezione testo. + + + + + + + + Modifica Seleziona tutto il testo della pagina corrente + + + Seleziona tutto il testo (se presente nel documento) della pagina corrente. + + + + + + + + &Ctrl;F Modifica Trova... + + + Mostra una finestra di dialogo nella parte bassa dell'area di visualizzazione che ti permette di cercare del testo nel documento. + + + + + + F3 Modifica Cerca successivo + + + Cerca lo stesso testo cercato in precedenza nel documento. + + + + + + &Shift;F3 Modifica Trova precedente + + + Passa all'occorrenza precedente del testo cercato nel documento. + + + + + + + Il menu Visualizza + + + + &Ctrl;&Shift;P Visualizza Presentazione + + + Attiva la modalità di presentazione. Per maggiori informazioni, consulta la sezione sulla modalità presentazione. + + + + + &Ctrl;&Shift;F Visualizza Modalità a tutto schermo + + + Abilita la modalità schermo intero. Tale modalità è diversa dalla modalità presentazione, in quanto la peculiarità del modo schermo intero è che nasconde il bordo della finestra, il menu e la barra degli strumenti. + + + + + &Ctrl;+ Visualizza Zoom avanti + + + Aumenta l'ingrandimento del documento. + + + + + + &Ctrl;- Visualizza Zoom indietro + + + Diminuisce l'ingrandimento del documento. + + + + + Visualizza Ingrandisci al 100% + + + Ingrandisce la dimensione dell'immagine all'immagine reale come specificato nei parametri del documento. + + + + + Visualizza Larghezza pagina + + + Cambia l'ingrandimento del documento così da permettere alle pagine di riempire la dimensione orizzontale dello schermo. + + + + + Visualizza Pagina intera + + + Cambia l'ingrandimento del documento così da visualizzare completamente ciascuna pagina nello spazio disponibile. + + + + + Visualizza Adattamento automatico + + + Cambia l'ingrandimento della vista del documento in modo che, in base alla relazione tra le dimensioni della pagina e dell'area di visualizzazione, la larghezza della pagina sia uguale alla larghezza della vista del documento (adatta alla larghezza), oppure l'altezza della pagina sia uguale all'altezza della vista del documento (adatta all'altezza) oppure l'intera pagina sia visible (adatta alla pagina). + + + + + Visualizza Modalità di visualizzazione + + + Questo sottomenu ti consente di scegliere la modalità di visualizzazione per le pagine. Le possibili scelte sono: Pagina singola (una sola pagina per riga), Pagine affiancate (due pagine per riga, come in un libro), Pagine affiancate (centra la prima pagina) e Panoramica (il numero delle colonne è quello specificato nelle impostazioni di &okular;). + Inoltre puoi abilitare la modalità continua. Nella modalità continua vengono mostrate tutte le pagine del documento, e puoi scorrere in modo fluido tra di loro. Quando non è attiva viene mostrata solo una pagina (o una riga di pagine) alla volta. + + + + + Visualizza Orientazione + + + Questo sottomenu ti consente di cambiare l'orientazione delle pagine del documento. + + La rotazione è applicata all'orientazione di ogni pagina. + + Puoi selezionare Orientazione iniziale per ripristinare l'orientazione del documento, annullando tutte le rotazioni applicate manualmente. + + + + + Visualizza Ritaglia vista + + + Questo sottomenu permette di rimuovere i bordi bianchi dalle pagine durante la visualizzazione (voce Ritaglia margini) o ritagliare alla selezione l'area visualizzata (voce Ritaglia alla selezione). + La modalità ritaglia alla selezione ti permette di tracciare la selezione nella pagina per definire il riquadro visibile da applicare a tutte le pagine del documento. Selezionando un riquadro di ritaglio piccolo viene comunque forzata una dimensione minima (20% della dimensione totale della pagina). + La modalità ritaglia margini persiste al riavvio di &okular;. La modalità ritaglio alla selezione si annulla al riavvio di &okular;. + Quando cambi, in &okular;, dalla modalità ritaglia margini a ritaglia alla selezione, la vista esce dalla modalità ritaglia margini per la selezione interattiva del riquadro. + La modalità di ritaglio può essere disattivata selezionando nuovamente la stessa voce di menu che l'attiva. + + + + + Visualizza Mostra moduli + + + Mostra o nascondi i moduli del documento. + + Questo menu è attivo solo se il documento corrente contiene dei moduli. + + + + + + + + + Il menu Vai + + + + Vai Pagina precedente + + + Vedi la pagina precedente del documento. + + + + + Vai Pagina successiva + + + Vai all'ultima pagina del documento. + + + + + &Ctrl;&Home; Vai Inizio del documento + + + Vai all'inizio del documento. + + + + + &Ctrl;&End; Vai Fine del documento + + + Vai alla fine del documento. + + + + + &Alt;&Shift;&Left; Vai Indietro + + + Vai indietro alla vista precedente del documento. + + + + + &Alt;&Shift;&Right; Vai Avanti + + + Vai avanti alla vista successiva del documento. Funziona solo se ti sei già spostato all'indietro. + + + + + &Ctrl;G Vai Va alla pagina... + + + Apre una finestra di dialogo che ti fa andare su di una qualunque pagina a tua scelta del documento. + + + + + + + Il menu Segnalibri + + + + &Ctrl;B Segnalibri Aggiungi/Rimuovi segnalibro + + + Aggiungi o rimuovi un segnalibri per la posizione corrente. + + + + + Segnalibri Rinomina segnalibro + + + Rinomina un segnalibro per la posizione corrente. + + + + + Segnalibri Segnalibro precedente + + + Vai al segnalibro precedente, o non eseguire alcuna azione se non ci sono segnalibri precedenti a quello corrente. + + + + + Segnalibri Segnalibro successivo + + + Vai al segnalibro successivo, o non eseguire alcuna azione se non ci sono segnalibri successivi a quello corrente. + + + + + Segnalibri Nessun segnalibro + + + Si tratta di un'azione sempre disabilitata che appare in questo menu solo se non ci sono segnalibri per il documento corrente. In caso contrario qui viene mostrata la lista dei segnalibri. Facendo clic su ciascuno di questi segnalibri puoi spostarti direttamente alla posizione associata. + + + + + + + Il menu Strumenti + + + + &Ctrl;1 Strumenti Navigazione + + + Il mouse avrà il suo comportamento normale, &LMB; per scorrere il documento ed attivare i link e &RMB; per aggiungere i segnalibri e adattare alla dimensione della pagina. + + + + + &Ctrl;2 Strumenti Zoom + + + Il mouse servirà da strumento per lo zoom. Facendo clic con &LMB; e trascinando si attiverà lo zoom sull'area selezionata, con &RMB; invece sarà possibile riportare il documento al precedente livello di ingrandimento. + + + + + &Ctrl;3 Strumenti Selezione area + + + Il mouse servirà come strumento per la selezione di una regione rettangolare. In questa modalità, facendo clic con il &LMB; e trascinando verrà disegnato un rettangolo di selezione e si potrà copiare il contenuto selezionato negli appunti, pronunciarlo tramite sintesi vocale, o trasformare la regione selezionata in un'immagine e salvarla in un file. + + + + + &Ctrl;4 Strumenti Selezione testo + + + Il mouse servirà da strumento per la selezione del testo. Facendo clic con &LMB; e trascinando si potrà selezionare la porzione di documento dal quale selezionare il testo. Quindi, basta fare clic con il &RMB; per scegliere: il testo selezionato può essere copiato negli appunti oppure può anche essere pronunciato. + + + + + &Ctrl;5 Strumenti Selezione tabella + + + Disegna un rettangolo attorno al testo per la tabella, quindi usa il &LMB; per dividere il blocco di testo in righe e colonne. Un clic con il &LMB; su una linea esistente la rimuove e unisce le righe o colonne adiacenti. + + + + + &Ctrl;6 Strumenti Lente d'ingrandimento + + + Attiva la modalità «ingrandimento» per il puntatore del mouse. Premi e tieni premuto il &LMB; per attivare la lente d'ingrandimento, sposta il puntatore per scorrere nel documento. Lo strumento riscala ogni pixel del documento in 10 pixel nella lente d'ingrandimento. + + + + + F6 Strumenti Annotazioni + + + Apri la barra degli strumenti delle annotazioni. La barra degli strumenti delle annotazioni ti consente di aggiungere annotazioni al documento che stai consultando. Per maggiori informazioni, consulta la sezione sulle annotazioni. + + + + + Strumenti Leggi tutto il documento + + + Strumenti Leggi la pagina corrente + + + Strumenti Interrompi lettura + + + Strumenti Metti in pausa/riprendi lettura + + + Queste voci di menu consentono di leggere l'intero documento o la sola pagina corrente, e di fermare la lettura, tramite il sistema di sintesi vocale di sistema. Il servizio è fornito da una libreria &Qt; che astrae da speech-dispatcher su &Linux;, e dal sistema di sintesi vocale nativo su altre piattaforme. È possibile scegliere la voce attuale tramite la pagina di configurazione Accessibilità di &okular;. + Le azioni Leggi... sono abilitate solo se un servizio di sintesi vocale è disponibile nel sistema. + + + + + + + I menu Impostazioni ed Aiuto + Oltre ai menu comuni di &kde; Impostazioni e Aiuto descritti nel capitolo Menu della documentazione Fondamentali di &kde;, &okular; contiene anche le seguenti voci di menu specifiche per il programma: + + + + F7 Impostazioni Mostra la barra laterale + + + Mostra o nasconde la barra laterale. + + + + + Impostazioni Mostra la barra delle pagine + + + Attiva o disattiva la barra delle pagine sul fondo dell'area del documento per risparmiare spazio verticale nella finestra di &okular;. Nota come i numeri di pagina verranno mostrati comunque nella barra degli strumenti predefinita. + + + + + Impostazioni Configura backend.. + + + Apre la finestra di configurazione backend. + + + + + + + + Configurazione dei backend di &okular; + Puoi configurare i backend di &okular; scegliendo Impostazioni Configura backend... . Attualmente sono disponibili delle opzioni di configurazione solo per i backend EPub, &PostScript;, FictionBook, Txt (testo), OpenDocument Text e &PDF;. + + La finestra di configurazione dei backend + + + + + + La finestra di configurazione dei backend + + + + Usando le pagine di configurazione dei backend per EPub, FictionBook, Mobipocket, Markdown, TXT e OpenDocument Text puoi definire il tipo di carattere per visualizzare il documento nel formato corrispondente. Il pulsante Scegli... in queste pagine apre la finestra standard di configurazione dei caratteri di &kde;. Fai riferimento al documento dei Fondamentali di &kde; per maggiori dettagli. + La descrizione delle pagine di configurazione dei backend Markdown, &PostScript; e &PDF; può essere consultata di seguito. + + Configurazione del backend Markdown + Puoi configurare il backend Markdown di visualizzazione per &okular; basato su Discount scegliendo Markdown dell'elenco nella parte sinistra della finestra di dialogo di configurazione. Un'ulteriore opzione configurabile è descritta di seguito. + + + + + Abilita la formattazione SmartyPants + + + Quando è selezionata, questa opzione permette ad &okular; di elaborare la formattazione SmartyPants. Tale formattazione può causare problemi nei testi tecnici per delle sostituzioni non volute (⪚ sostituisce (C) con un simbolo di copyright). Questa opzione è abilitata come impostazione predefinita. + + + + + + + Configurazione del backend &PostScript; + Puoi configurare il backend &PostScript; di visualizzazione per &okular; basato su Ghostscript scegliendo Ghostscript dell'elenco nella parte sinistra della finestra di dialogo di configurazione. L'unica opzione configurabile è descritta di seguito. + + + + + Usa i caratteri della piattaforma + + + Questa opzione determina se Ghostscript è autorizzato a usare i caratteri della piattaforma; se non marcata è permesso l'uso dei soli caratteri inseriti nel documento. L'opzione è attiva in modo predefinito. + + + + + + + Configurazione del backend &PDF; + Puoi configurare il backend &PDF; di visualizzazione per &okular; basato su Poppler scegliendo &PDF; dell'elenco nella parte sinistra della finestra di dialogo di configurazione. L'unica opzione configurabile è descritta di seguito. + + + + + Ottimizza linee sottili + + + Il disegno delle linee in &okular; è implementato in due passi: la generazione del tracciato di ritaglio ed il suo riempimento. Quando la linea nel documento originale è più stretta di un pixel l'esecuzione di questi due passi può causare dei problemi. Per queste linee il tracciato di ritaglio è riempito con un colore di riempimento legato allo spessore della parte della linea all'interno dell'area di ritaglio. Se la parte della linea dentro l'area di ritaglio diventa molto piccola, il contrasto tra la figura e il colore di sfondo può diventare troppo basso perché la linea sia riconoscibile. Le griglie di queste linee assumono quindi un aspetto poco gradevole. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Linea sottile (rossa), il relativo tracciato di ritaglio (linea tratteggiata) e i confini dei pixel (linee piene nere) + Linea sottile mostrata a basso contrasto + + + + + Per migliorare l'aspetto delle linee sottili &okular; implementa due opzioni. + La prima opzione è Pieno. Con questa opzione &okular; aggiusta il tracciato di ritaglio e la posizione della linea in modo tale che il tracciato di ritaglio e la linea condividano il confine dei pixel, &ie; &okular; ingrandisce la linea sottile ad un pixel sul dispositivo di output. Questo modo è simile alla modalità Ottimizza linee sottili in Adobe Reader. Se questa opzione viene selezionata, le linee sottili sono sempre allargate. + + + + + + + + Linea sottile con ottimizzazione Pieno + + + Linea sottile con ottimizzazione Pieno + + + + + La seconda opzione è Figura. Con questa opzione il tracciato di ritaglio e la linea sono ugualmente aggiustati al confine del pixel, ma l'intensità della linea è corretta in base alla sua larghezza. + + + + + + + + Linea sottile con ottimizzazione Figura + + + Linea sottile con ottimizzazione Figura + + + + + L'impostazione predefinita è non migliorare le linee sottili (opzione No). + + + + + + + + Configurazione di &okular; + + Configurazione generale + Puoi configurare &okular; scegliendo Impostazioni Configura &okular;.... La finestra di configurazione è divisa in sei sezioni. Questo capitolo descrive in dettaglio le opzioni disponibili. + + + Generale + + + Accessibilità + + + Prestazioni + + + Presentazione + + + Annotazioni + + + Editor + + + + La finestra di configurazione + + + + + + La finestra di configurazione + + + + In base ai backend installati, la voce di menu Impostazioni Configura backend... potrebbe essere abilitata o meno. Questa particolare finestra mantiene le impostazioni dei backend che possono essere configurati. + + + Generale + + + Usa scorrimento fluido + + Mostra o nasconde le transizioni animate allo scorrimento con la rotellina del mouse e la tastiera. + + + + Mostra barre di scorrimento + + Mostra o nasconde le barre di scorrimento della pagina per la vista del documento. + + + + Collega le miniature con la pagina + + Collega o meno lo scorrimento della lista delle miniature con la pagina corrente. + + + + Mostra messaggi di avviso ed informazione + + Mostra o nasconde i messaggi informativi all'avvio, al caricamento di un file, &etc; + + + + Mostra il titolo del documento, se disponibile, nella barra del titolo + + Mostra o meno il titolo del documento aperto nella barra del titolo della finestra di &okular;. Se il documento non contiene i metadati relativi al titolo o questo elemento non è attivato in &okular;, mostra il nome del file del documento. + + + + Quando non viene mostrato il titolo del documento + + Puoi scegliere una delle due opzioni, Mostra solo il nome del file o Mostra il percorso completo del file. + + + + Usa un colore di sfondo personalizzato + + Abilita la scelta del colore di sfondo del documento (il colore attorno alla pagina visualizzata). Il valore predefinito usato quando questa opzione è deselezionata è quello delle librerie &Qt;. + + + + Apri i nuovi file nelle schede + + Se aprire nuovi documenti in schede. Come valore predefinito, le schede sono disabilitate. + Le scorciatoie predefinite per passare tra le schede sono &Ctrl;. (Scheda successiva) e &Ctrl;, (Scheda precedente). + + + + Passa alla scheda esistente se il file è già aperto + + Controlla se &okular; debba passare alla scheda esistente quando un file è già aperto invece di creare una nuova scheda. Questa opzione è disabilitata come scelta predefinita. Può essere modificata solo se Apri i nuovi file nelle schede è abilitata. + + + + Rispetta le limitazioni DRM + + Fai in modo che &okular; obbedisca o meno alle restrizioni imposte dai DRM (Digital Rights Management, Gestione dei Diritti Digitali). Le limitazioni dei DRM sono usate per rendere impossibile effettuare alcune operazioni con i documenti &PDF;, come per esempio copiare del contenuto negli appunti. Nota che in alcune configurazione di &okular;, questa opzione potrebbe non essere disponibile. + + + + Ricarica il documento se il file viene modificato + + Se il file aperto deve essere sorvegliato per rilevare modifiche e aggiornamenti, se necessario. + + + + Mostra la finestra per la scelta del backend + + Se &okular; deve chiedere all'utente quale backend usare nel caso in cui più di un backend è in grado di aprire il file corrente. Se non marcata, &okular; userà il backend con la priorità più alta. + + + + Direzione di lettura da destra a sinistra + + Se impostare in modo predefinito la direzione di lettura da destra a sinistra quando viene aperto un file. Può essere utile per alcuni sistemi di scrittura. + + + + Colonne in modalità panoramica + + Questa opzione rappresenta il numero di colonne da usare in modalità panoramica. + + + + Sovrapposizione PaginaSu/PaginaGiù + + Da qui puoi definire la percentuale dell'area di visualizzazione attuale che deve essere ancora visibile dopo la pressione dei tasti &PgUp;/&PgDn;. + + + + Ingrandimento predefinito + + Questa opzione specifica la modalità di ingrandimento predefinita per i file che non sono mai stati aperti in precedenza. Per i file che sono stati già aperti in passato viene usata la modalità di ingrandimento precedentemente usata. + + + + + + Accessibilità + + + Disegna il bordo attorno ai collegamenti + + Contorna o meno i collegamenti con un bordo colorato. + + + + Cambia i colori + + Abilita le opzioni di cambiamento del colore. + + + + Inverti i colori + + Inverte i colori delle pagine. &ie; il nero sarà visualizzato bianco. + + + + Cambia il colore della carta + + Cambia il colore della carta, &ie; il colore di sfondo del documento. + + + + Cambia i colori chiari e scuri + + Cambia i colori chiari e scuri. Questo significa che il nero non verrà visualizzato come nero ma sarà sostituito dal colore che tu imposti come colore scuro ed il bianco dal colore che imposti come colore chiaro. Le tonalità intermedie assumeranno un valore intermedio tra il colore chiaro e quello scuro. + + + + Converti in bianco e nero + + Converte il documento in bianco e nero. Puoi impostare la soglia e il contrasto. Se si imposta la soglia ad un valore più alto spostandola sulla destra, verranno usati dei toni di grigio più chiari. + + + + Inverte chiarezza + + Inverte la chiarezza di tutti i colori. I colori chiari e scuri saranno scambiati, ma tonalità e saturazione non saranno toccate. Il contrasto delle immagini sarà normalmente peggiore di quanto non sia con l'uso di Inverte luma (sRGB lineare). + + + + Inverte luma (sRGB lineare) + + Inverte il luma di tutti i colori. Chiari e scuri saranno scambiati, ma tonalità e saturazione non saranno toccate. Il contrasto delle immagini si preserva meglio rispetto all'uso di Inverte chiarezza, ma grafica e segni di marcatura di testo variopinti normalmente hanno un aspetto peggiore. Usa i coefficienti luma sRGB, ma senza correzione del gamma. + + + + Inverte luma (simmetrico) + + Inverte il luma di tutti i colori, usando coefficienti simmetrici luma. Chiari e scuri saranno scambiati, ma tonalità e saturazione non saranno toccate. Molto simile a Inverte chiarezza, ma il contrasto è migliore in alcuni casi. + + + + Sposta tonalità positivamente + + Sposta la tonalità di tutti colori di 120 gradi. Può mitigare alcuni problemi di contrasto con grafica variopinta. + + + + Sposta tonalità negativamente + + Sposta la tonalità di tutti colori di 240 gradi. Può mitigare alcuni problemi di contrasto con grafica variopinta. + + + + Motore + + Permette di scegliere il motore di sintesi vocale (text-to-speech, TTS) che &okular; usa. Il valore predefinito è speechd TTS, ma puoi usare tutte le lingue e le voci in base ai sintetizzatori disponibili per la tua piattaforma. Su &Linux; speech-dispatcher viene usato in modo predefinito per trovare le voci disponibili. + + + + + + Prestazioni + + + Abilita trasparenze + + Visualizza le selezioni ed altri elementi grafici usando le trasparenze. Disabilitare l'opzione per una visualizzazione opaca o del solo contorno della selezione ed aumentare la velocità di selezione. + + + + Utilizzo della memoria + + &okular; può ottimizzare le prestazioni, tramite la regolazione dell'utilizzo di memoria, basata sul tuo computer e le tue preferenze. Più memoria gli permetterai di usare, più veloce sarà il comportamento del programma. Il profilo predefinito è perfetto per tutti i computer, ma è possibile fare in modo che &okular; usi solo la memoria indispensabile selezionando il profilo Minimo, o ottenere di più dal proprio computer con il profilo Aggressivo. Usa il profilo Ingordo per precaricare tutte le pagine senza rischio di riempire tutte la memoria del sistema (sarà usato solo il 50% della memoria totale o della memoria libera). + + + + Visualizzazione + + Tramite questo gruppo di opzioni puoi migliorare la resa del testo e delle immagini in &okular;. Il risultato dipende dal dispositivo usato per mostrare il documento. Le voci Abilita antialias del testo e Abilita antialias della grafica possono essere usate per attivare e disattivare l'antialiasing rispettivamente di testo e immagini nel documento. La voce Abilita antialias del testo è fatto per cambiare l'hinting del testo. L'antialias e l'hinting cambiano il modo in cui il documento viene mostrato, puoi modificarle secondo le tue preferenze. + + + + + + Presentazione + + + Avanza ogni + + Abilita l'avanzamento automatico delle pagine dopo un certo tempo. + + + + Torna all'inizio dopo l'ultima pagina + + Nella modalità presentazione dopo l'ultima pagina riparte dalla pagina iniziale. + + + + Navigazione tattile + + Ti permette di regolare la navigazione tattile tramite tocchi nella presentazione usando i seguenti tre possibili valori: + + + Tocco sul lato sinistro/destro per andare indietro/avanti: un tocco sulla metà sinistra (destra) dello schermo passa alla slide precedente (successiva) della presentazione. + + + Tocco in un qualsiasi punto per andare avanti (predefinito): un tocco sullo schermo passa alla slide successiva della presentazione, indipendentemente dalla posizione del tocco sullo schermo. + + + Disabilitato: un tocco sullo schermo non provoca nessun effetto. + + + + + + Colore di sfondo + + Imposta il colore che riempirà lo spazio lasciato vuoto dalle pagine. + + + + Puntatore del mouse + + Imposta se il puntatore dovrà essere sempre visibile, sempre invisibile oppure visibile ma nascosto dopo qualche secondo di inattività. + + + + Mostra l'indicatore di avanzamento + + Mostra o nasconde un indicatore circolare nell'angolo in alto a destra dello schermo della presentazione che visualizza il numero della pagina corrente ed il totale delle pagine ogni volta che cambi pagina. + + + + Mostra la pagina di riepilogo + + Mostra o nasconde una pagina che riepiloga le informazioni sulla presentazione che sta per iniziare. Le informazioni comprendono il titolo del documento, l'autore ed il numero di pagine del documento. + + + + Abilita transizioni + + Usa questa casella per abilitare o disabilitare gli effetti di transizione tra le pagine. + + + + Transizione predefinita + + Imposta l'effetto di transizione tra una pagina e la successiva se non definito nel documento. Imposta questo valore a Transizione casuale per fare sì che &okular; scelga a caso uno tra gli effetti disponibili. + + + + Posizionamento + + In questa sezione puoi selezionare lo Schermo da utilizzare per mostrare la presentazione. + Schermo corrente avvia la modalità presentazione nello stesso schermo in cui è presente la finestra di &okular;. + Schermo predefinito è lo schermo marcato come predefinito nella configurazione di xinerama. + Schermo 0, Schermo 1 &etc; sono gli schermi disponibili. + + + + Configurazione dello strumento di disegno + + Gestisce i colori della matita usata quando si disegna sulle pagine in modalità presentazione. + + + + + + Annotazioni + + La pagina Annotazioni della finestra di configurazione + + + + + + La pagina Annotazioni della finestra di configurazione + + + + + + Autore + + L'autore dei contenuti aggiunti al documento. Il valore predefinito è il nome dalla pagina Password e account utente del modulo delle &systemsettings; Dettagli dell'account. + + + + Strumenti per le annotazioni + + Questo pannello è usato per configurare la tua barra degli strumenti di annotazione. + Ci sono cinque pulsanti (Aggiungi, Modifica, Rimuovi, Sposta in alto, Sposta in basso) ed una lista (che elenca i contenuti dell'attuale barra degli strumenti delle annotazioni) che sono usati per configurare la barra degli strumenti. + Se devi aggiungere alcuni pulsanti di strumenti nella barra degli strumenti, fai clic sul pulsante Aggiungi. Puoi scegliere il nome, il tipo e l'aspetto dello strumento appena creato. + + Ricordati che gli strumenti di annotazione in &okular; sono molto configurabili. Ad esempio, puoi avere due pulsanti con lo stesso strumento ma con colori diversi. Non esitare a sperimentare per scegliere un insieme di pulsanti che si adatta perfettamente al tuo modo di lavorare. + + Fai clic su alcuni elementi nell'elenco, quindi fai clic sul corrispondente pulsante nella parte destra della pagina per modificare, rimuovere, spostare in alto o in basso l'elemento. La scorciatoia di tastiera dello strumento (un tasto tra 1 e 9) dipende dalla posizione nell'elenco della barra di strumenti delle annotazioni. + + + + Usa timbri personalizzati + + + Crea l'icona che vuoi usare per i tuoi timbri e salvarla in uno dei formati grafici supportati da &okular; + Fai clic sul pulsante Aggiungi, seleziona il tipo Timbro ed inserisci un nome per il timbro. + Inserisci il percorso completo per l'icona personalizzata nella lista a cascata nel gruppo Disegno del timbro + + + + + + + Editor + + + Editor + + Scegli l'editor da eseguire quando &okular; cerca di aprire un file sorgente.Questo si verifica quando il documento contiene riferimenti a vari punti (solitamente numeri di riga e di colonna) del sorgente da cui è stato generato. Il formato &DVI; supporta in modo nativo la presenza di informazioni sui sorgenti del documento &latex; da cui è stato generato. Un sistema analogo esiste anche per i documenti &PDF;: si tratta di pdfsync, che memorizza queste ulteriori informazioni in un file esterno con un nome legato a quello del file &PDF; corrispondente (ad esempio miodocumento.pdfsync per miodocumento.pdf). + &okular; contiene impostazioni preconfigurate per i seguenti editor: &kate;, Kile, SciTE, client &Emacs;, LyX, TeXstudio e TeXiFy IDEA. + + Per usare la ricerca inversa in &kile; devi compilare il file &latex; usando la configurazione Moderna. + + + + + Comando + + Questo è il comando, con i relativi parametri, per invocare l'editor scelto con il file sorgente del documento corrente. + Questo campo sarà riempito automaticamente se usi uno degli editor preconfigurati. Altrimenti, scegli Editor di testo personalizzato nell'elenco a comparsa Editor e fai riferimento alla documentazione del tuo editor preferito per trovare il comando appropriato. + Puoi usare i seguenti segnaposti: + + + %f - il nome del file + + + %l - la riga da raggiungere nel file + + + %c - la colonna da raggiungere nel file + + + Se %f non è specificato, il nome del documento verrà aggiunto al comando specificato. + + + + + + + Riconoscimenti e licenza + + + Copyright del programma: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Responsabile attuale + Pino Toscano pino@kde.org + Enrico Ros eros.kde@email.it Sviluppatore di &kpdf; + + + + Copyright della documentazione: + &Albert.Astals.Cid; &Albert.Astals.Cid.mail; Autore + Titus Laska titus.laska@gmx.de Alcuni aggiornamenti ed aggiunte + Pino Toscano pino@kde.org + + Enrico Ros eros.kde@email.it (Traduzione della documentazione per &kpdf;)Riccardo Iaconelli ruphy@fsfe.org (Seconda traduzione della documentazione per &kpdf;)Nicola Ruggero nicola@nxnt.org(Revisione della documentazione per &kpdf;)Luigi Toscano luigi.toscano@tiscali.it(Transizione &kpdf;->&okular;, manutenzione e revisione documentazione di &okular;) &underFDL; &underGPL; + + &documentation.index; +
    + + + diff --git a/po/it/docs/okular/mainwindow.png b/po/it/docs/okular/mainwindow.png new file mode 100644 index 0000000000000000000000000000000000000000..9e4a2571f4eb2b54d06a541085eecabe399a08bd GIT binary patch literal 34133 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 + +]> + + + + +Manuale utente di Okular +YuriChornoivan Pagina di manuale di Okular. yurchor@ukr.net +2019-02-14 +Okular 1.7 +KDE Applications + + + +okular +1 + + + +okular +un visualizzatore universale di documenti + + + +okular opzioni di Okular URL + + + +Descrizione +okular ha lo scopo di mostrare documenti in vari formati. + + + +Opzioni di Okular + + + + + +Apre una pagina specificata del documento. + + + + + + +Apre il documento in modalità presentazione + + + + + + +Avvia mostrando la finestra di stampa. + + + + + + +Avvia mostrando la finestra di stampa e termina dopo la stampa. + + + + + + +Controllo "istanza unica". + + + + + + +Permette di evitare che la finestra di Okular si rialzi dopo l'avvio. + + + + + + +Trova una stringa nel testo. + + + + + +Argomenti + + + + +L'indirizzo del documento da aprire. Nel caso di documenti PDF, il nome può essere specificato come nome_documento#nome_destinazione, dove nome_destinazione è l'identificativo di una destinazione presente nel documento. + + + + + +Segnalazioni +Su IRC, irc.freenode.net #okular o tramite posta elettronica, okular-devel@kde.org o sul web, <https://okular.kde.org/>. + + + +Vedi anche + +Documentazione utente più dettagliata è disponibile da help:/okular (inserisci questo come URL in &konqueror;, o esegui khelpcenter help:/okular). +kf5options(7) +qt5options(7) +Ulteriori informazioni sono disponibili presso https://okular.kde.org/ + + + +Copyright +Copyright © 2002 Wilco Greven, Christophe Devriese +Copyright © 2004-2005 Enrico Ros +Copyright © 2005 Piotr Szymanski +Copyright © 2004-2012 Albert Astals Cid +Copyright © 2006-2009 Pino Toscano +Licenza: GNU General Public Version 2 <https://www.gnu.org/licenses/gpl-2.0.html> + + + diff --git a/po/it/docs/okular/presentation.png b/po/it/docs/okular/presentation.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d2bc47cbb3bc5d3b809fe1d7aa59b1dbdf56d6 GIT binary patch literal 14722 zcmdVBcUaTiwlIhV6%?_62vSr67<%tTQNU1z(5omAiZtmZASluVG&F%gqy|Eh-id&K zw9q@D354EBfDriN`=0N7_nf(R=FZF?-^_maV?DpU*?YCU_G$@#p{YVc%|uN>K|uq0 z{!E90;v$lQ;ynJ!1@f0nQ%WuhiVGAk)OD3kPfsb%DBR8{0?sJ<&L}p|D2~o3NM{tM zXB20D{%)O}shpmso}SL0o)S(^N#t>Mc19!;kB^TJ{~CBaet&;|Z*OmVdwXMJV|{&n zb#--ld3kYhaejV&c6N4pdU|SVYGPtyY;0_JczAGdu)n{*x3{;ar>CQ%qphv&=g*(b z&CO^ux}l+=uCA`Sy1KHmvb?;!w6wIOq@<{*sGy)AKR-V&FE2MYHzy}2J3BiwGxOWG zYy=`RBO~M6w{K}_X>d3^IXO8iAtfvJE9y&PdR!tRE|EOq;uB(HV_~q^FJEFmfBqa9 z6B88`9T6EB78dsHLwMHv@Uo!r?BKBU;INR8koWK32L%N|gFie@X?Rey&Q^WQR&vCO zI%LTtu%sO@C+{&Q?BDym&m6sV@6#Sr*d9~J9#in%y`UwIPpvF=6|Aq3JT3|M^<&sI zTzM@56%4Hn4UNpq%wE2H`RdgxD=RA-8wkYK?$2=eGv2&;Jz2skDsbMd-hC0QCU$@QT~aNf`WqFy{5 zrWOKDuh zSHF8PMar`^;k%=KBWr~6*wO68Q0GJL`SXV3&(2xjzVU_c^XJEv9o;07D-NSBUV20E z-JZX!aq|MEXVFIXXsTm@B{PPpz)c~)SmvDVFLljx6w;Iw?$i{i=l=$N2z8m2^+a8b z;Px{ZQn`b?{TS+nsv^V+SD9{arN%o>&95Gb9sfcDPlE?(X9bIiz61+%d`^a{NVY|U zJ^o7~VXJ55vWxdx-ZTk;kqTy$!mX4@&-0*Cxc%A{c&ZBrGV>ng#y75$rl_4vjK|v` z`Yw}P@kNh$syFI7#pN5EG-uz1U4GudeCpS9)1@STev(v{-=D`0&-10Gzs{kp7ZAbD zs>lHsWTxUb*cb(?$b!Xa^@`c>yHbUN>ezfF>IA^RUw*cJuZOCo{}pS4I!H=ubXf|u zcPcHL)N5#F!!33&{S#GbZ1mEkgQ`XQw|qnrYA2#oHghsU!U#NUmXkH)N86BbtQ$0I zGQKBiZELue=i8|pWuPnE`%*(MF$sn;)TXDCoN43Zel(kv{-6-K$_K9S7ETq@OSM7m z(htAu-0bioy=bTA@z+Vu$MvP6+SP}b>H^|W{33cs2H!gyjk-IYvX~go=|JZwL)UdH zgohV84tiM&UudIhyN5Pa)4m-W4p^Q`d@`%LbV|EqLI9SZa=kR0n4)3{37ZG)k;)YePQ7i4!LBb zayTC-F613?&|hfdh)OEA0?U1K2)J3D_@$%=220wtY5(0bx5D{ zdTY`T*S@^tt9lwDO4+LbUEEtv7iM=0Y z(Xz)))ao@Q+Lcb zypA>`TmN8tnB~y>@laPR*UD870h!s&Ob2S7N$J(hWEN8|eJ}-T@kJ`?WoOQTWh!(* zOY(>U)w)1O@eNGz7)j9w{9k~i;x#thw@W%wl)3lnq$msib(Xw-neHF!{|3mm>OTek zHe=+ee*^xfVf&|r`x|&iwtRn0{SAp$+ARy{C_$@=YshSs63)!KXfH^I z{O;fY`*UyTD{lJDrz1U zO?A&%&>9Y9Yv9D8c+Zn%%Bu3Rt?w;|g5SWB(?8Wzmsd=|8lTJaMzl`X^X5q-=EPo_ zKr&1R_gv(!Ez?C;(d*&QvT*N5kC0-i?2ALb7C|WS zE9PsAfoNZ|pGq^YC(cmVHhB6#>hSOYX@Eq}VxwMDHy--=u5XsHkPdTi z{s52}Azlz~E(pkbonn-30uCjW2TYzMz;tA$8g>cV63!FVc?gbHt7sn|D7e+?`q$bb zpB0*x3>DJ%fUbGZFNyvQ`p#pr$PfTya(5-q!8778vlrywv!h=7?xg4;CjSXyK?riq*KTzdnT6ALZ-8(gL}< zYJ}Y8Dvug&*Yd6>AXWHnGlC?<4(jHS1aoBhjvNQj!@u|Ky^mQvF*N|fTo=Q^QBw^^ zz{F8Z!Ky#HfqC`lS$-JqYqD>ag<>Fai(WO%&HRp~d|>N^t&RS1EqE45XB2JqXgB2p zlbG*#@N`-e-zCN(E=+jhR(3!qZm`3bx*b`Ok_AkN>t77-bL>f5cYR&O%VDMJbuCU4 z-DuV(Gmtv4)Rh1l80nH1sIs&T*#}KT&N#EJjjH1klp`@`T|*pT;uv4bpv-Qj1ni-C zar|vpSBR|Fj*`H}m!$(3fNy2#MHdr!vw_Y?UPck1?);8jmx z+57$O$vNjTC@CV2K$};SrMS{Uqu(zHRHB9oI2jz#yswoQmeJXi&u*i1W*ku$0XSl9 z&MNNjX4a|l%|rqy-4@b@(7mceW#aW9VR|Ow`~5*-pr%gce#dMLniSp3ISQ53gqCI2 zaGH(fKoYk#z_sQtdUgafc8eJC!poOY>WJR3~DF3H5TWa%8SM7$JhaE9dY7QB`aMUA* zES>_=e{@D2E>h6H83Qwwf<_jct1erN=5dA^rf=L@eI9Y&V64%&CAAk^9vB~sGN6s%wR8zunx)1I0Kp`LyB>H8a^h;NkC9tmQ$&+ z_eLG1g1Q3m$&SQCzD(IvnE~1IIKi1y@8=z|I!@g0kTjAWXXi`UOszph4XNtDhB~7k zCj;$*_Hi6nxddWwb-ww^naW{@d;JzFm}i2VoOvt%EBK9=alPg5pwuP=SKO`oboTE~ zshJ694h*k3((o&JJ`6=)vJ!MY7JPA7Oqx+1KxZepHOhSz@bW)w>5g4OHyY}IK`R4! zA0jm8s)wLG@y9mNS-rbkf?0JEhzDX=QKPQWPLJc(-`QN|BWq>ZY59}Sb>@?c25MEZ zKGi=_8mQ097KfkZh`Q+UtguPYRTsglW>2&+p}_SDkiGw;8mnFZ6>Nj<+u}_&>9F8* zhC;_m+qHxP1gF9X=^iMp^(?N)bh>=G^o^MLfZj3gl@I3Yu4+N~tH;YNCtm1z7{-XB zL8k5Ggnngrt9_eFuIa8k<_S#}YyRa;&!ZD_gY>MSf_DpIYA5Gn)Rf*L{i+u0%v$*k zwB3I&Y*$BK&{r>6JV<5z{+}k*X0&bd%gO?pAPhX zG{j2bI$80JB{ZkB67n&!dh-JLP5ozR`ENeQf78|Y56|uY@)-a2o&NGdB!i^^YC2u# zip4#>(0gf5o$U8_^-rRsGdbfMAEZOkLfG3`jdB1`9*Gm_n)3wtLQQBdkPAdOP@QMklkP^watWVSvS=-_PD3(AhgK zob63N1brkKI9GwOu=zRNZ`nkW&l zlkXtr97n>KAQ~(PAXU@&?<5Va)rw?^PXD!_QT-e>*eBY6Iv@9|pjuOW^P9we=L2=1 z(}*=x`7hp>5E@IooOV~z(X1yeD|;CGR7ps4vH`}n;&khHbKlu!IfKeGjDKnyd-^1N z02o#2OoHxgGS=D#d*H&J6!CC?Iv{Vb2fxfg(zz8)*q%vVyN?d@ALih8WW04u(M?tD zYk7S$3gYL%3wE16F1zChqP6XC5xkE$!8Ie!I|F@RUb4JK!_fX5R#3kOzqo;?eqb4p&R8wmrRM$v%mnHn5>(|RIrWBQV!mafA{(Pf!cuNsiG%Q5bJbGbuh(ok z6aYe;)q0ONcWlWU4amur#JJk^GiddWkfJ1KBmph$Qn^7xx0fvJYfg&ZT}$kBr(7V! z-Q9#OG$a6gQs@?c#m)S#ihH^6T$s*<(yDVy=SQmUR~}%~FKyMPbBP>@7Dcz%$0s0C zb$HQ|UFt=AmtIEh2RT?51ny0njXfEChFm5;Tcgl_afjhIzODt^+allD9pe}BHnMw- z=<5~a#9tZ-NBvO7&_`34C%$0kT3x$k9FQzo{!+EO#>C?8)PuTUf|k+n;X+d+vI1So z74yY@-h;}NkRI(glTmzUnrTuiaMf5lr`)OY(C*kBQ|9b~`r*MAop1{z-`c@;TW`T} ziAQ!3=Lk!#pnik-k_CA$@CadBVOQbh5Hy7H!1vbZ40fBP@HzXguFC4U2)sL>TgCGj zXZF|SSn--Mvk(V%Ar{BIyU_!=lw{rxrw_HPM7b(NnWYufA+X}JoQz&k#9>^&owK~8 zn_YMMCM8*0!n4-6NXN4|b~>kqQ1L@kv)myfVp4dVsK20$gP(O*wuAXc3+wQ5#7Zah z-U!2){)_F8gv3C78?|Jk&Sv!PrUOU=> z#yD9x*=FEXW(Ez~{yLKR+&NHy2dwmJq^ca8Dc=xn>suTujS=q#16J^@X930|e`6Lj zHtS`|%P4I9ytKUV@EW7z(nSj`dUnKq#U&u9c;%R8kTW?*E7>d2-A~_>HYtAU>NjvM zyI0jnbpmXlxL?opf>>#YyGjc5sqc)(U}*{d4wpjC9JYKu-Q=>m|FQ_yXYXsifH7U;+CDgZbjruVm-QGy-gIiHjTTu9^Wk(o{S z&?Be7psd5?HwY_^y0Y`i_LW*6(anCTKfF`9QZvBcz@~(MiNsxAy)cPu^} zK3J3=tm>WcTy7BCe7owU7VPY`j&N1ct>QPq#Z3b$COLk4j&!6G_>6U0?*KJ;yWEqA zT_@3pS^1{|Rm~fdz?ao0M(VF#%7uJf4BESdEn7(PypWSvL;CS!ugfuI{{@;Gum4K^ z%W{1~;Nkc#PR>&&NrQSYwA$Vku1xF}t}+}nFId&2Br#~&4cGU!SUYX*8!ER>;(E;o zipD2r2=kUrzSK0GwLs;>CIkjZc>2h1#42IZ(~Hocw_fOCcDTXfC&xW*>=ZlYQ6Y`# z7Py>fw8JQuf6|on-i_6F4Gf(?cK1Z~7FZcoL)8+COE2@Iw{EdAxKq=BY-P<92NAUb z0-APJZe>}ymCEd(>80_SwDR}FTemNqYpH1EevV0;AN*al{<)vm2GV|VkU%%g>DdxA zD`uu#0szX31ilXE1s=AvG&QISYpSkrgD`@!Vm(t8Mm?Wcl)=58VsTS7=zm9o{ZSzn2y&NZELv2FkNK6EA<_NZcs8+Dz5#uG?BCC(LSU z*KnQ(HgvR@Au%1}ZFrHu{r9^Cl)ctl?J!j=uXTc}GHVbhXjH^DrUed8vNZ^=^!W5j z5;yP%C%7{a!c(3lOAQ3;l=grdW1;}U0dFEF;x3A@iAeM4G|HF$%5#b<&-N=TZ>LZG zE@88AZ*WE}t)eu3$U}L{%UG)YW{Ikr_ihklI*GGLb?h`JRONE2VvAsa#e8lVwL*16 zqLc1au#ua^@#Et~c{@S_O#GAigaj`7hasqqNHhp2n{VXo#nIEs$pwb(&+R&&Cb+}` zqWs;5rcPnEaO#G8os5Oe#7Y7;NW}Cu*EIw0yVDz9)5r5OrCW&+Te0QyuYX5j{CXL& zQplLH8G5#R1VqWV*Ke8-9vcTuEcDnDkiprz_j}@@F>T}OPqmUHhP`>WJK|=AwUMWD z6C-mq{=W$v(b5jMyC9^$_vGHFwM_fX5#Of>32H^6Ty{Uc5G}CO{{-3h_+sV8*qe<_ zf3vi>1VIb#xP?SrUOVvI;ljBZ>gTHJ$HvLORrO~tXL>_#i#d(^?Y{520~+{dLA@9| zG_^OoP^Lgoku4rRk|rWQzV^i=T<0c>i1j^#OHm(hU|L1i_RHD)uYCc0foTc9?$u;A z$Pj4{*KG16=WXFVA8T`D_pp%K*QmV`$fq-6CK+u!dO#pAF)%R!LKZ^hV$&hAg@`rW zKlm8=+S{cMD0(00fbjuZ>~iasG62lUzQR;jyW=NeKu2-3PC4~cEu8Ie*uBfVU$WY$ zY_^-ezx+A;zA6!$52&ggi(!D=O_RH%WzQBsN1r(9ybQ%eCuzepX*$*H{i$rV`$^KOY$S@TDX1SD!%0 zsHpxYU@?%f6yBiv4=+OaY0LJykhjw6J-65sn5F9U08vc6V_E}sb4t5gc1A4dQ{^s` zb+q!woOXP|@R+X;jHFd∾-fwmI!uG2rRP)656@-j5LM`kTRB`}***8IgNEEI%)N z(41Q?YacvNeIwsCp({v`&IeC6vyk%pg@;Qq?2}q# zqqlG6rt`wJma_KQ#YU{#1~o~j!Hmrd-JKTI{(J{_nJ`%tLu3UR_;}(Pg?OtoXCwsD zwvXZOv4gjXk}9_+)-57u3@htX*SekXd&>md?(U>~&1hH7^}lep7dFn+NvJ6>xtAE9Gq!>jYk-Su7hbJGsUf&@x>-1q!L5 z!KeQ`0ZMz!lT#?%(ybnB{|Kl4k>Xyx7(c+zo@o}kzl)F}n5|$^9Jj<#V``H^>FIjm zP%dlK;yZ(TiPO!izJ#z^srjtA9lbY}6fo(ru$MhG(gK?=t_3JX8UT5eR z$XXkNl0-R&W*NAEokb0U)4j>-Bddqg4cTwD?;vVW5yZQbp2X8s{>1{)_RFL93X?SKeC{y?jTvx6OjF8S7$MdOozm^N} zUECPU+>(dnV7D4i^Jjeb&%5nToHmWSFsd=A$oyV64yasSF_zEahL)OyfHa_(H+6;%l+S#68nRme; za46pnfiCS&vP;CTPY+&Ss5~5PDuJz!yQJg*MKMl9#QsT0?@w_sE_BAM)c2DKb=1Js z>p79$t826p(Q2ykS(RnVyw%bIvR(YH{RqUplf}-Xfn%yaF1P1+JgeJ}iX#0c(jA$> z^~N)y{NCf)=rqLk>m^*TRTLGQhV8PM3+v31b-IPcUNc;O5DOF6h+Sv&r_AP@3%QIR zpGVgaFmjz3z!R@{~jw9TTI%F%{Ct4TAQW%~J-R4v~4a;;DzsgD+IVS_B zb)q@T>!m?nQg|o#zIX^w-}j^O+f@F(Q+c!7@zB%83**N5-r3OCl9|Wnk3|W%>C0~` z9z(sSwom9*!6VzF)0^Oje0K#v#ZfG`y#)_NwMJPpSNF0x3l`*HZM;)`y_B-4j zQK{^NRE{ro4N%>!5S$52x1h~O_#tGRV^YgeiJtOd8fWB~bN$1daVZ(5nF7M;*Wiel zHhKINN(SfwPHyWGIv`C4uL+FgI(_Y(w_y+<=&~FMo9GqdaICXbC62k#+BS6`u{qaU z44}62xmB6k>6nKuu}TymU&L6LNIOhRBzc9{Ol%Ohb$Hs-R2bkikd7-+U&?UqOvma3 z#)w!t)@%rEPAssB?sNKNS*hO`ZFsh?aE&v&h-jBnY@p(&tYKAW->Pd#O=qB-zt{=8 zICy0Fn1uoOEAq^qtRL}Yk$3r5>^n; z3}ZEK*GyTaNS6~~O9TzAijn_iaxw&AVv>2mZZci0kPTu7Z;(FbjIXqO@aS1*$<{DH zuj~a*T9qqjUyR`_Cli!{Yy-iBP~&Do16miXxJgWAixrS<%B>;t8V<5|0k|BqSKu=B*(4MzX;z~HXZhnMi6&37}| z?-om~C~^BrW>v2YhMe0Ex_$f=1AcQ6;kvfu7dpZ6(2V+*>ZeYpmoe^3TK##yYr(mF z%br!BLVfqccD22%bAcqirwZnO9#BnLx4=oMqVck)WePRL8gEk2+g+1JS|w?U7vchx z=0>djtl*w$`g{swv$Tl^bpH~a4*&RB+1qV9n(p}Kh_JsgS5Gf=rTA790-X#kD8SCw~yz|tFtp?;_K9E0u>YYbs&6Y(7bk+h0hJM z{*5^-6V^6X^hH$P{choWXbROLiv@o^<7$wUm` zRSS(FXK)9408XvPm{J_~%l1xL+3VBeK3Pd(GJmGzAr6no+73j|QMt8&fMy(0;5Dn% zA^SA}Os-U>Q8(uLW$~XLzs#H^-PV)KO=B6+m5-h1rDasruU))0dWSxHgC?rqP5dgG zMt&OjeQ4iAMaP@f@lg(kO!~AwFV*dLuM(n9yEj#~Kf~+phHHrPq_4Eix>nhi*&#pW zq+M9aheSCNGshnZc#i}Nyzr{Tw?Cr~QC^G(ScBd+pQvvS0c)ZvHxlNBBP!`GdNE6< zU<@CBPg89DRF0-G1CHOGE;tKF&HWlPMbht$+YIoWe3#PQ;XqW&yt6LnrFR*-vta@@ zKb!Z2IFNf>e0X>0fp71p@yS~9|CN;mVTPnz8$EaW44!5#Z64waJ46^}c2`p(F|JEv z9z@^My|W}@dc1GpQWW*(^12WsEq|aX`J`)qXpWRj9;An31dkbcjzfk6lXf~YfOAw( zFD@@5DP`F8>x~WvX5lwO>FOh03CHcCHXCY9p(`e|^_9X{V)JS!gO*Ms|L~pyAYR%7 zGxEnF;gRGPa2)B>&laantM!b0OO1%F#VnIFdHmYv%2qy6UQAWwIEL1}j($LNS7s~_42U#`kvk(6U}tAoLfW64h!;rLYDB~p|7ods=U19 zLFIV5wi`KQJ}W_fH0@VIO1rJ=`@fkAYzvMqse_PH(M>FlcN@x`F)YbdQnJdu z6F>vlC!xz9-|+jssCge)f!`hK`_LFZKI6{9hDc6EZC!>3t|o){=+eR=pQHq>$~ZR@ z+aOX5U%aC4F4UGDo=crti`iXyXT#qi;IRrXl+cK!V~($KQ(qZegV(yzZd&ZU(>&U) z#1(f{{v~a6X#2xdMQiy9_YohM$eiO!Q>e#Gq)tf|)zbj~nap=t`V;qOHp^`(0|X;R zC8!+v?8w31F6ick9XPH6PUR*f2T{9BpKP26uQ5u#n+BjiY#P)1-Z7>BarOR`R%Z0Gzj^~l#~E#A0}60_u`?+A^!70TG-yzKIu%zr?YY@{^`XuD zxYrj8*dDhP&sO~$?ELY4NSW;0mBFTv?B3L}3ZPWx?t(x=xZA3JPBE#d!uQC_&PU&+ z9W#E7o*H9>MI|K{Iz24IY8-=>%+#|Ki6ZWhLKXUTjxADyNmZ@#$Ug?b~-gRr_w^b!cxv zRB-0OK58!v!)y zQeL1haA%T-aSG}A^2}`$r+Krt>Uo6>-Eal#-(riJ#cr#OYbTJsC>t|VDr-+uouwIa zKSk-(?lMk6!nfarv)-=ArU$klmbE6Ko??6Hn$d*5|Hn__ZoI^M*2=c5@T@#4_E>@N zyJ0vnJ)36J&7vTd0oKne*S<|w;ZAjdvi2B3j=|4XA8fYAXJSOGa!bfz_#UGJa=Fsb zC#vtR9HcBP(+Gj!WSnpfm{Z{cRK)tsWe4?rkWYe%J53!%8l&sgvBhUXqPGRy6W_D^ zp2+sy2y7njH!*&6-!DAQuvGQJok_G)b3k}2TYY*VA0sALmN6YrJ8YN^_G-aE1Y!@^ zXi65=$D~ry18JA(xNn@5&pQ(|C;K6)F3l!QXnF?FwUtV9;U zOoH!Te!z~LRxHeyEHN9Wx~;(qrldQ}VWaF)c`8X{yPBkf6T)?W*ZI(HGP6 zR=MXOa_dXK!qU`r9YpsmbDbx2itxO)Q)Cjo|He;+EAZ~^gWc{gM}LLtulE&GLSi_b z2ZmJ{v-_1uujHNC&7{uWYda|3KJFIMkdDHu>a26+YeMaiS+fs9wuEbUa?}Vp9*%!p zrN)8Xt74B1xUoY<$G>C!#J<%)fxeZurlHWqv4@bgeFyh=2}$na4%?_wi~acB55`k` zxFMtB1H|F}CWo{9(MBEL1`C%AWblZv?fvHEq0|DC)LVtnH$MJ3lU##az%NNwRz|R? zpm%@b_l!SzXt^s|)0{^>ut`X*s;VPjQU@_o@%3t`eRPO5eslsy&Z7eu`4KC4p!X_W?058I9n(y>qSCsg_X*zc2YWQ)X%4vkB{KS{ zzWwqs`PA6kYxY$@zx>r--LEZmSySh0X=&yiULM+|-CZ0VcPc}fZVGb89MG)+hYW|V z3?}bENpiU{A=*9#1kC%KlrE+W+ppui3FVaurt9kyF*!=oEjaVrFse zs$?O#l<}0dDxo~*WP{bB(91_G_53I_H%29#(c0zhV`SeCA1eCl&8IC#_BOiSb)yj1 zfFI<9J@MRvr4r=`*!G7-&owpS%n19kE)KXJxy&Q=RDb-Q)$@dm2nXL42((5Z=r*-< zi0?w7Wp3jb#HHklbV#kaD$6l+dY)1si4&v(Je&sm3ihHd1MCo2LV7#t*wGS#LG9`)BCx^R<=jH9OU{_imy zfw>k5rlIEAl=2<%0Ed^NTy*Z#9=)Hf;(9)Jog!w&0WbA=z$I`^GIfMkYNfBOJFn;- z2lxI^v7+`M#$9+JuM|38kf)wGpuWiX(eg8poYUM0Fp4KV?pE=E(cK5n*3znQ>7Mo> zY;5iHv~xti-$Y(3K)P7n4XxQwk%DE>36nXQJ7dU*H%uJJ=SJtf?adB+1>xS2fIlPe zWl0Ye>3syvw182&dmA6YHF`Sb#cd;?T?baXAM-dA!4X!9KG6`l?g< zA}z_{Lk<4*n{SbO7e~O7%?>%J8Rw7$-J44+f&gGT74l{QvQJQ7&)NVyPF#=ISHRF3 zYNfL_CL7TgWfuHG8(HgvPX*Q$F8fMFl2zm^QX$j7zBB#}{v1f>Hywtpdb8!GQ{2s+ z3qsm+DlvBGE+0sZy7flY*?KSVBKea1*5RHA+mS(AaK31T@pum>-e{2`dpHf@;((fr zt7;Gw%)lk!rNu!F|6+ZRX8QC+24ylGwobL$uKB?RP^yzgc{004TP@0g9TD8ZfGQ)~ zxZ1<~`{1o{0UcY}&#{-KL)iJMog(4^&XezIY7B*6r;c)rDck`E^ekNENBWk*|L7HO zc5wYh#0Bbdywep@jwjD64ZR5>9^0*}d7qq|5YU~j#{$ z^C)yW_G#p!{A%pT{EMc72=k8&{u;qjVSD6Lediq+cFO!drdLk9(LbiEEf=YV+jl3C z(|^!Hr?kLz?eG$@%R#%tAcSBMfY*SomZ%fS|ZWbY%69bmgMY3x!mG#``JP7eObHDsZ7oo3Rzd+WW#%e&vV(}(J z^(~xIn(D$-&;cD&mPD$=D=7wY0r6O8i3-Jis5V1O&S|-$V z2S`Cy)tK$AR@7Xgyn7}vnR(w15VmF1%(tGy4_0DDzIixNGE#l@Q6cps)MBdZWn>nVgJ zGtNcSKySD&8B8`QlB%Q7VeABbE8_+7UMM{e?9V@9yfFF;Y~48};g(ERbpm;bf%S*_ zOeQydZK!Na^y){{F_TI>^DZgT=B?@zq)Qz30PYdCjQ#bB`j35;(ld>Ou zUjMIpo&JB)2><`VhV}o7v;SKg*8i)Y0{r*AtZ4c(ws`87S4{3#V*dQR45Xy_tVr=? G@c#fA1hVb` literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/signatures-bar.png b/po/it/docs/okular/signatures-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..01e19260d1a08cf5b806fe9db1154440d1ccb55b GIT binary patch literal 3062 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 Eg6jS$2mk;8 literal 0 HcmV?d00001 diff --git a/po/it/docs/okular/signatures-panel.png b/po/it/docs/okular/signatures-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..3588896a36bc2edbbb4104aae00d023b1981d39d GIT binary patch literal 5010 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 T=IM3(*T$f&4pu7%K6&>))B;5K literal 0 HcmV?d00001 diff --git a/po/it/okular.po b/po/it/okular.po new file mode 100644 index 0000000..480ecb2 --- /dev/null +++ b/po/it/okular.po @@ -0,0 +1,5981 @@ +# translation of okular.po to Italian +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# Daniele Medri , 2003. +# Federico Cozzi , 2004. +# Enrico Ros , 2005. +# Andrea Rizzi , 2005. +# Nicola Ruggero , 2005, 2006. +# Nicola Ruggero , 2006, 2007. +# Luigi Toscano , 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2021-03-01 08:27+0100\n" +"PO-Revision-Date: 2020-12-29 22:40+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.12.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano,Nicola Ruggero,Enrico Ros,Daniele Medri" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it,,," + +#: aboutdata.h:22 part/annotationwidgets.cpp:423 +#, kde-format +msgid "Okular" +msgstr "Okular" + +#: aboutdata.h:24 +#, kde-format +msgid "Okular, a universal document viewer" +msgstr "Okular, visualizzatore universale di documenti" + +#: aboutdata.h:26 +#, kde-format +msgid "" +"(C) 2002 Wilco Greven, Christophe Devriese\n" +"(C) 2004-2005 Enrico Ros\n" +"(C) 2005 Piotr Szymanski\n" +"(C) 2004-2017 Albert Astals Cid\n" +"(C) 2006-2009 Pino Toscano" +msgstr "" +"© 2002 Wilco Greven, Christophe Devriese\n" +"© 2004-2005 Enrico Ros\n" +"© 2005 Piotr Szymanski\n" +"© 2004-2017 Albert Astals Cid\n" +"© 2006-2009 Pino Toscano" + +#: aboutdata.h:34 +#, kde-format +msgid "Former maintainer" +msgstr "Responsabile precedente" + +#: aboutdata.h:35 +#, kde-format +msgid "Lots of framework work, ODT and FictionBook backends" +msgstr "Molto lavoro sull'infrastruttura, backend ODT e FictionBook" + +#: aboutdata.h:36 +#, kde-format +msgid "Developer" +msgstr "Sviluppatore" + +#: aboutdata.h:37 +#, kde-format +msgid "Created Okular from KPDF codebase" +msgstr "Ha creato Okular dal codice di KPDF" + +#: aboutdata.h:38 +#, kde-format +msgid "KPDF developer" +msgstr "Sviluppatore di KPDF" + +#: aboutdata.h:39 +#, kde-format +msgid "Annotations artwork" +msgstr "Grafica delle annotazioni" + +#: aboutdata.h:40 +#, kde-format +msgid "Table selection tool" +msgstr "Strumento selezione tabella" + +#: aboutdata.h:41 +#, kde-format +msgid "Annotation improvements" +msgstr "Miglioramenti alle annotazioni" + +#: core/action.cpp:128 +#, kde-format +msgid "Go to page %1" +msgstr "Vai a pagina %1" + +#: core/action.cpp:128 +#, kde-format +msgid "Open external file" +msgstr "Apri file esterno" + +#: core/action.cpp:188 +#, kde-format +msgid "Execute '%1'..." +msgstr "Esegui «%1»..." + +#: core/action.cpp:287 +#, kde-format +msgid "First Page" +msgstr "Prima pagina" + +#: core/action.cpp:289 part/presentationwidget.cpp:179 +#, kde-format +msgid "Previous Page" +msgstr "Pagina precedente" + +#: core/action.cpp:291 part/presentationwidget.cpp:196 +#, kde-format +msgid "Next Page" +msgstr "Pagina successiva" + +#: core/action.cpp:293 +#, kde-format +msgid "Last Page" +msgstr "Ultima pagina" + +#: core/action.cpp:295 +#, kde-format +msgid "Back" +msgstr "Indietro" + +#: core/action.cpp:297 +#, kde-format +msgid "Forward" +msgstr "Avanza" + +#: core/action.cpp:299 +#, kde-format +msgid "Quit" +msgstr "Esci" + +#: core/action.cpp:301 +#, kde-format +msgid "Start Presentation" +msgstr "Inizia presentazione" + +#: core/action.cpp:303 +#, kde-format +msgid "End Presentation" +msgstr "Termina presentazione" + +#: core/action.cpp:305 +#, kde-format +msgid "Find..." +msgstr "Trova..." + +#: core/action.cpp:307 +#, kde-format +msgid "Go To Page..." +msgstr "Vai alla pagina..." + +#: core/action.cpp:358 +#, kde-format +msgid "Play sound..." +msgstr "Riproduci suono..." + +#: core/action.cpp:426 core/action.cpp:542 +#, kde-format +msgid "JavaScript Script" +msgstr "Script JavaScript" + +#: core/action.cpp:476 +#, kde-format +msgid "Play movie..." +msgstr "Riproduci filmato..." + +#: core/action.cpp:547 +#, kde-format +msgid "Play movie" +msgstr "Riproduci il filmato" + +#: core/action.cpp:549 +#, kde-format +msgid "Stop movie" +msgstr "Ferma il filmato" + +#: core/action.cpp:551 +#, kde-format +msgid "Pause movie" +msgstr "Metti in pausa il filmato" + +#: core/action.cpp:553 +#, kde-format +msgid "Resume movie" +msgstr "Riprendi il filmato" + +#: core/chooseenginedialog.cpp:25 +#, kde-format +msgid "Backend Selection" +msgstr "Selezione backend" + +#: core/chooseenginedialog.cpp:43 +#, kde-format +msgid "" +"More than one backend found for the MIME type:
    %1 (%2).

    Please select which one to use:
    " +msgstr "" +"È stato trovato più di un backend per il tipo MIME:
    %1 (%2)." +"

    Seleziona quello da utilizzare:
    " + +#: core/document.cpp:205 +#, kde-format +msgctxt "@info %1 is a page size" +msgid "Most pages are %1." +msgstr "La maggior parte delle pagine sono %1." + +#: core/document.cpp:224 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Portrait %1" +msgstr "Verticale %1" + +#: core/document.cpp:226 +#, kde-format +msgctxt "paper type and orientation (eg: Portrait A4)" +msgid "Landscape %1" +msgstr "Orizzontale %1" + +#: core/document.cpp:249 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 in (%3)" +msgstr "%1 x %2 in (%3)" + +#: core/document.cpp:251 +#, kde-format +msgctxt "%1 is width, %2 is height, %3 is paper size name" +msgid "%1 x %2 mm (%3)" +msgstr "%1 x %2 mm (%3)" + +#: core/document.cpp:1605 +#, kde-format +msgid "Continuing search from beginning" +msgstr "La ricerca continua dall'inizio" + +#: core/document.cpp:1608 +#, kde-format +msgid "Continuing search from bottom" +msgstr "La ricerca continua dalla fine" + +#: core/document.cpp:2332 +#, kde-format +msgid "" +"Can not find a plugin which is able to handle the document being passed." +msgstr "" +"Impossibile trovare un backend in grado di gestire il documento fornito." + +#: core/document.cpp:3368 +#, kde-format +msgctxt "remove a collection of annotations from the page" +msgid "remove annotations" +msgstr "rimuovi annotazioni" + +#: core/document.cpp:3900 core/document.cpp:3906 +#, kde-format +msgid "" +"The document is trying to execute an external application and, for your " +"safety, Okular does not allow that." +msgstr "" +"Il documento sta cercando di eseguire un'applicazione esterna. Okular lo " +"impedisce per la tua sicurezza." + +#: core/document.cpp:3917 +#, kde-format +msgid "No application found for opening file of mimetype %1." +msgstr "Impossibile trovare un programma per aprire un file di tipo %1." + +#: core/document.cpp:4258 +#, kde-format +msgid "Could not open a temporary file" +msgstr "Impossibile aprire un file temporaneo" + +#: core/document.cpp:4260 +#, kde-format +msgid "Print conversion failed" +msgstr "Conversione della stampa non riuscita" + +#: core/document.cpp:4262 +#, kde-format +msgid "Printing process crashed" +msgstr "Il processo di stampa è andato in crash" + +#: core/document.cpp:4264 +#, kde-format +msgid "Printing process could not start" +msgstr "Impossibile avviare il processo di stampa" + +#: core/document.cpp:4266 +#, kde-format +msgid "Printing to file failed" +msgstr "Stampa su file non riuscita" + +#: core/document.cpp:4268 +#, kde-format +msgid "Printer was in invalid state" +msgstr "La stampante era in uno stato non valido" + +#: core/document.cpp:4270 +#, kde-format +msgid "Unable to find file to print" +msgstr "Impossibile trovare il file da stampare." + +#: core/document.cpp:4272 +#, kde-format +msgid "There was no file to print" +msgstr "Non c'è nessun file da stampare" + +#: core/document.cpp:4274 +#, kde-format +msgid "" +"Could not find a suitable binary for printing. Make sure CUPS lpr binary is " +"available" +msgstr "" +"Impossibile trovare un eseguibile adatto per la stampa. Assicurati che il " +"programma lpr di CUPS sia disponibile" + +#: core/document.cpp:4276 +#, kde-format +msgid "The page print size is invalid" +msgstr "La dimensione di stampa della pagina non è valida" + +#: core/document.cpp:4900 part/part.cpp:1085 +#, kde-format +msgid "Could not open '%1'. File does not exist" +msgstr "Impossibile aprire il file «%1». Il file non esiste" + +#: core/document.cpp:5382 +#, kde-format +msgid "Title" +msgstr "Titolo" + +#: core/document.cpp:5385 +#, kde-format +msgid "Subject" +msgstr "Oggetto" + +#: core/document.cpp:5388 +#, kde-format +msgid "Description" +msgstr "Descrizione" + +#: core/document.cpp:5391 +#, kde-format +msgid "Author" +msgstr "Autore" + +#: core/document.cpp:5394 +#, kde-format +msgid "Creator" +msgstr "Creatore" + +#: core/document.cpp:5397 +#, kde-format +msgid "Producer" +msgstr "Produttore" + +#: core/document.cpp:5400 +#, kde-format +msgid "Copyright" +msgstr "Copyright" + +#: core/document.cpp:5403 +#, kde-format +msgid "Pages" +msgstr "Pagine" + +#: core/document.cpp:5406 +#, kde-format +msgid "Created" +msgstr "Creato" + +#: core/document.cpp:5409 +#, kde-format +msgid "Modified" +msgstr "Modificato" + +#: core/document.cpp:5412 +#, kde-format +msgid "Mime Type" +msgstr "Tipo MIME" + +#: core/document.cpp:5415 +#, kde-format +msgid "Category" +msgstr "Categoria" + +#: core/document.cpp:5418 +#, kde-format +msgid "Keywords" +msgstr "Parole chiave" + +#: core/document.cpp:5421 +#, kde-format +msgid "File Path" +msgstr "Percorso del file" + +#: core/document.cpp:5424 +#, kde-format +msgid "File Size" +msgstr "Dimensione file" + +#: core/document.cpp:5427 +#, kde-format +msgid "Page Size" +msgstr "Dimensione pagina" + +#: core/documentcommands.cpp:65 +#, kde-format +msgctxt "Add an annotation to the page" +msgid "add annotation" +msgstr "aggiungi annotazione" + +#: core/documentcommands.cpp:110 +#, kde-format +msgctxt "Remove an annotation from the page" +msgid "remove annotation" +msgstr "rimuovi annotazione" + +#: core/documentcommands.cpp:156 +#, kde-format +msgctxt "Modify an annotation's internal properties (Color, line-width, etc.)" +msgid "modify annotation properties" +msgstr "modifica proprietà dell'annotazione" + +#: core/documentcommands.cpp:190 +#, kde-format +msgctxt "Translate an annotation's position on the page" +msgid "translate annotation" +msgstr "traduci annotazione" + +#: core/documentcommands.cpp:261 +#, kde-format +msgctxt "Change an annotation's size" +msgid "adjust annotation" +msgstr "aggiusta annotazione" + +#: core/documentcommands.cpp:328 +#, kde-format +msgctxt "Generic text edit command" +msgid "edit text" +msgstr "modifica testo" + +#: core/documentcommands.cpp:390 +#, kde-format +msgctxt "Edit an annotation's text contents" +msgid "edit annotation contents" +msgstr "modifica contenuti dell'annotazione" + +#: core/documentcommands.cpp:438 +#, kde-format +msgctxt "Edit an form's text contents" +msgid "edit form contents" +msgstr "modifica contenuti dei moduli" + +#: core/documentcommands.cpp:487 +#, kde-format +msgctxt "Edit a list form's choices" +msgid "edit list form choices" +msgstr "modifica scelte dell'elenco di un modulo" + +#: core/documentcommands.cpp:521 +#, kde-format +msgctxt "Edit a combo form's selection" +msgid "edit combo form selection" +msgstr "modifica selezione della casella combinata di un modulo" + +#: core/documentcommands.cpp:593 +#, kde-format +msgctxt "Edit the state of a group of form buttons" +msgid "edit form button states" +msgstr "modifica stati dei pulsanti di un modulo" + +#: core/generator.cpp:749 +#, kde-format +msgid "Plain &Text..." +msgstr "&Testo semplice..." + +#: core/generator.cpp:752 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: core/generator.cpp:756 +#, kde-format +msgctxt "This is the document format" +msgid "OpenDocument Text" +msgstr "OpenDocument Testo" + +#: core/generator.cpp:759 +#, kde-format +msgctxt "This is the document format" +msgid "HTML" +msgstr "HTML" + +#: core/printoptionswidget.cpp:22 +#, kde-format +msgid "Print Options" +msgstr "Opzioni di stampa" + +#: core/printoptionswidget.cpp:26 +#, kde-format +msgid "Fit to printable area" +msgstr "Adatta all'area stampabile" + +#: core/printoptionswidget.cpp:27 +#, kde-format +msgid "Fit to full page" +msgstr "Adatta alla pagina" + +#: core/printoptionswidget.cpp:28 +#, kde-format +msgid "Scale mode:" +msgstr "Modalità di scala:" + +#: core/script/kjs_app.cpp:162 +#, kde-format +msgid "Missing alert type" +msgstr "Tipo di avviso mancante" + +#: core/script/kjs_app.cpp:214 +#, kde-format +msgid "Do not show this message again" +msgstr "Non mostrare più questo messaggio" + +#: core/sourcereference.cpp:103 +#, kde-format +msgctxt "'source' is a source file" +msgid "Source: %1" +msgstr "Sorgente: %1" + +#: core/textdocumentsettings.cpp:37 +#, kde-format +msgid "&Default Font:" +msgstr "Carattere pre&definito:" + +#: part/annotationactionhandler.cpp:137 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Red" +msgstr "Rosso" + +#: part/annotationactionhandler.cpp:138 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Orange" +msgstr "Arancione" + +#: part/annotationactionhandler.cpp:139 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Yellow" +msgstr "Giallo" + +#: part/annotationactionhandler.cpp:140 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Green" +msgstr "Verde" + +#: part/annotationactionhandler.cpp:141 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Cyan" +msgstr "Ciano" + +#: part/annotationactionhandler.cpp:142 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Blue" +msgstr "Blu" + +#: part/annotationactionhandler.cpp:143 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Magenta" +msgstr "Magenta" + +#: part/annotationactionhandler.cpp:144 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "White" +msgstr "Bianco" + +#: part/annotationactionhandler.cpp:145 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Gray" +msgstr "Grigio" + +#: part/annotationactionhandler.cpp:146 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Black" +msgstr "Nero" + +#: part/annotationactionhandler.cpp:234 part/annotationactionhandler.cpp:624 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Width %1" +msgstr "Larghezza %1" + +#: part/annotationactionhandler.cpp:240 +#, kde-format +msgctxt "@item:inlistbox" +msgid "%1%" +msgstr "%1%" + +#: part/annotationactionhandler.cpp:284 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (No annotation selected)" +msgstr "Spessore di linea dell'annotazione (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:285 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color (No annotation selected)" +msgstr "Colore dell'annotazione (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:286 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (No annotation selected)" +msgstr "" +"Colore di riempimento dell'annotazione (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:287 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity (No annotation selected)" +msgstr "Opacità dell'annotazione (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:288 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (No annotation selected)" +msgstr "Carattere dell'annotazione (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:289 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Add the current annotation to the quick annotations menu (No annotation " +"selected)" +msgstr "" +"Aggiungi l'annotazione attuale al menu delle annotazioni veloci (nessuna " +"annotazione selezionata)" + +#: part/annotationactionhandler.cpp:290 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (No annotation " +"selected)" +msgstr "" +"Vincola le proporzioni delle forme a 1:1 o gli angoli tra linee a passi di " +"15° (nessuna annotazione selezionata)" + +#: part/annotationactionhandler.cpp:291 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Advanced settings for the current annotation tool (No annotation selected)" +msgstr "" +"Impostazioni avanzate per lo strumento di annotazione attuale (nessuna " +"annotazione selezionata)" + +#: part/annotationactionhandler.cpp:296 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width" +msgstr "Spessore di linea dell'annotazione" + +#: part/annotationactionhandler.cpp:298 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation line width (Current annotation has no line width)" +msgstr "Spessore di linea dell'annotazione (l'annotazione corrente non ha uno)" + +#: part/annotationactionhandler.cpp:302 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation text color" +msgstr "Colore del testo dell'annotazione" + +#: part/annotationactionhandler.cpp:304 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation border color" +msgstr "Colore del bordo dell'annotazione" + +#: part/annotationactionhandler.cpp:306 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation color" +msgstr "Colore dell'annotazione" + +#: part/annotationactionhandler.cpp:310 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color" +msgstr "Colore di riempimento dell'annotazione" + +#: part/annotationactionhandler.cpp:312 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation fill color (Current annotation has no fill color)" +msgstr "" +"Colore di riempimento dell'annotazione (l'annotazione corrente non ne ha uno)" + +#: part/annotationactionhandler.cpp:316 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font" +msgstr "Carattere dell'annotazione" + +#: part/annotationactionhandler.cpp:318 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation font (Current annotation has no font)" +msgstr "Carattere dell'annotazione (l'annotazione corrente non ne ha uno)" + +#: part/annotationactionhandler.cpp:322 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain line angle to 15° steps" +msgstr "Vincola gli angoli tra linee a passi di 15°" + +#: part/annotationactionhandler.cpp:324 +#, kde-format +msgctxt "@info:tooltip" +msgid "Constrain shape ratio to 1:1" +msgstr "Vincola le proporzioni delle forme a 1:1" + +#: part/annotationactionhandler.cpp:326 +#, kde-format +msgctxt "@info:tooltip" +msgid "" +"Constrain shape ratio to 1:1 or line angle to 15° steps (Not supported by " +"current annotation)" +msgstr "" +"Vincola le proporzioni delle forme a 1:1 o gli angoli tra linee a passi di " +"15° (non supportato dal tipo di annotazione attuale)" + +#: part/annotationactionhandler.cpp:329 +#, kde-format +msgctxt "@info:tooltip" +msgid "Annotation opacity" +msgstr "Opacità dell'annotazione" + +#: part/annotationactionhandler.cpp:330 +#, kde-format +msgctxt "@info:tooltip" +msgid "Add the current annotation to the quick annotations menu" +msgstr "Aggiungi l'annotazione attuale al menu delle annotazioni veloci" + +#: part/annotationactionhandler.cpp:331 +#, kde-format +msgctxt "@info:tooltip" +msgid "Advanced settings for the current annotation tool" +msgstr "Impostazioni avanzate per lo strumento di annotazione attuale" + +#: part/annotationactionhandler.cpp:382 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Color" +msgstr "Colore" + +#: part/annotationactionhandler.cpp:384 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Fill Color" +msgstr "Colore di riempimento" + +#: part/annotationactionhandler.cpp:385 +#, kde-format +msgctxt "@item:inlistbox Color name" +msgid "Transparent" +msgstr "Trasparente" + +#: part/annotationactionhandler.cpp:395 +#, kde-format +msgctxt "@item:inlistbox" +msgid "Custom Color..." +msgstr "Colore personalizzato..." + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@info" +msgid "" +"Stamps inserted in PDF documents are not visible in PDF readers other than " +"Okular" +msgstr "" +"I timbri inseriti nei documenti PDF non saranno visibili in lettori PDF " +"diversi da Okular" + +#: part/annotationactionhandler.cpp:431 +#, kde-format +msgctxt "@title:window" +msgid "Experimental feature" +msgstr "Funzione sperimentale" + +#: part/annotationactionhandler.cpp:475 +#, kde-format +msgctxt "@title:window" +msgid "Select color" +msgstr "Seleziona colore" + +#: part/annotationactionhandler.cpp:513 +#, kde-format +msgid "&Annotations" +msgstr "&Annotazioni" + +#: part/annotationactionhandler.cpp:514 +#, kde-format +msgctxt "@action:intoolbar Hide the toolbar" +msgid "Hide" +msgstr "Nascondi" + +#: part/annotationactionhandler.cpp:518 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Highlighter" +msgstr "Evidenziatore" + +#: part/annotationactionhandler.cpp:519 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Underline" +msgstr "Sottolineato" + +#: part/annotationactionhandler.cpp:520 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Squiggle" +msgstr "Scarabocchiato" + +#: part/annotationactionhandler.cpp:521 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Strike Out" +msgstr "Barrato" + +#: part/annotationactionhandler.cpp:523 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Typewriter" +msgstr "Macchina da scrivere" + +#: part/annotationactionhandler.cpp:524 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Inline Note" +msgstr "Nota in linea" + +#: part/annotationactionhandler.cpp:525 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Popup Note" +msgstr "Nota a comparsa" + +#: part/annotationactionhandler.cpp:526 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Freehand Line" +msgstr "Linea a mano libera" + +#: part/annotationactionhandler.cpp:528 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Straight line" +msgstr "Linea retta" + +#: part/annotationactionhandler.cpp:529 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Arrow" +msgstr "Freccia" + +#: part/annotationactionhandler.cpp:530 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Rectangle" +msgstr "Rettangolo" + +#: part/annotationactionhandler.cpp:531 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Ellipse" +msgstr "Ellisse" + +#: part/annotationactionhandler.cpp:532 +#, kde-format +msgctxt "@action:intoolbar Annotation tool" +msgid "Polygon" +msgstr "Poligono" + +#: part/annotationactionhandler.cpp:534 +#, kde-format +msgctxt "@action" +msgid "Geometrical shapes" +msgstr "Forme geometriche" + +#: part/annotationactionhandler.cpp:578 +#, kde-format +msgctxt "@action" +msgid "Stamp" +msgstr "Timbro" + +#: part/annotationactionhandler.cpp:595 +#, kde-format +msgctxt "@action:intoolbar Show list of quick annotation tools" +msgid "Quick Annotations" +msgstr "Annotazioni veloci" + +#: part/annotationactionhandler.cpp:596 +#, kde-format +msgctxt "@info:tooltip" +msgid "Choose an annotation tool from the quick annotations" +msgstr "Scegli uno strumento di annotazione dalle annotazioni veloci" + +#: part/annotationactionhandler.cpp:602 +#, kde-format +msgctxt "" +"@action:intoolbar Add current annotation tool to the quick annotations list" +msgid "Add to Quick Annotations" +msgstr "Aggiungi alle annotazioni veloci" + +#: part/annotationactionhandler.cpp:605 +#, kde-format +msgctxt "" +"@action:intoolbar When checked keep the current annotation tool active after " +"use" +msgid "Keep Active" +msgstr "Mantieni attivo" + +#: part/annotationactionhandler.cpp:606 +#, kde-format +msgctxt "@info:tooltip" +msgid "Keep the annotation tool active after use" +msgstr "Mantieni attivo lo strumento annotazioni dopo l'uso" + +#: part/annotationactionhandler.cpp:611 +#, kde-format +msgctxt "" +"@action When checked, line annotations are constrained to 15° steps, shape " +"annotations to 1:1 ratio" +msgid "Constrain Ratio and Angle of Annotation Tools" +msgstr "Vincola proporzioni ed angolo degli strumenti per le annotazioni" + +#: part/annotationactionhandler.cpp:617 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Font" +msgstr "Carattere" + +#: part/annotationactionhandler.cpp:618 +#, kde-format +msgctxt "@action:intoolbar Current annotation advanced settings" +msgid "Annotation Settings" +msgstr "Impostazioni delle annotazioni" + +#: part/annotationactionhandler.cpp:621 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Line width" +msgstr "Spessore della linea" + +#: part/annotationactionhandler.cpp:630 +#, kde-format +msgctxt "@action:intoolbar Current annotation config option" +msgid "Opacity" +msgstr "Opacità" + +#: part/annotationmodel.cpp:318 part/part.cpp:2940 +#, kde-format +msgid "Page %1" +msgstr "Pagina %1" + +#: part/annotationpopup.cpp:82 +#, kde-format +msgid "Annotation" +msgid_plural "%1 Annotations" +msgstr[0] "Annotazione" +msgstr[1] "%1 annotazioni" + +#: part/annotationpopup.cpp:84 part/annotationpopup.cpp:119 +#, kde-format +msgid "&Open Pop-up Note" +msgstr "&Apri nota a comparsa" + +#: part/annotationpopup.cpp:88 part/annotationpopup.cpp:122 +#, kde-format +msgid "&Delete" +msgstr "&Elimina" + +#: part/annotationpopup.cpp:101 part/annotationpopup.cpp:126 part/part.cpp:751 +#: part/propertiesdialog.cpp:57 +#, kde-format +msgid "&Properties" +msgstr "&Proprietà" + +#: part/annotationpopup.cpp:108 part/annotationpopup.cpp:132 +#, kde-format +msgctxt "%1 is the name of the file to save" +msgid "&Save '%1'..." +msgstr "&Salva «%1»..." + +#: part/annotationpropertiesdialog.cpp:57 +#, kde-format +msgid "&Appearance" +msgstr "&Aspetto" + +#: part/annotationpropertiesdialog.cpp:62 +#, kde-format +msgid "&General" +msgstr "&Generale" + +#: part/annotationpropertiesdialog.cpp:67 +#, kde-format +msgid "&Author:" +msgstr "&Autore:" + +#: part/annotationpropertiesdialog.cpp:72 +#, kde-format +msgid "Created:" +msgstr "Creato:" + +#: part/annotationpropertiesdialog.cpp:77 +#, kde-format +msgid "Modified:" +msgstr "Modificato:" + +#: part/annotationpropertiesdialog.cpp:111 +#, kde-format +msgid "Pop-up Note Properties" +msgstr "Proprietà della nota a comparsa" + +#: part/annotationpropertiesdialog.cpp:114 +#, kde-format +msgid "Typewriter Properties" +msgstr "Proprietà della macchina da scrivere" + +#: part/annotationpropertiesdialog.cpp:116 +#, kde-format +msgid "Inline Note Properties" +msgstr "Proprietà della nota in linea" + +#: part/annotationpropertiesdialog.cpp:121 +#, kde-format +msgid "Straight Line Properties" +msgstr "Proprietà della linea retta" + +#: part/annotationpropertiesdialog.cpp:123 +#, kde-format +msgid "Polygon Properties" +msgstr "Proprietà del poligono" + +#: part/annotationpropertiesdialog.cpp:126 +#, kde-format +msgid "Geometry Properties" +msgstr "Proprietà della figura geometrica" + +#: part/annotationpropertiesdialog.cpp:129 +#, kde-format +msgid "Text Markup Properties" +msgstr "Proprietà del marcatore del testo" + +#: part/annotationpropertiesdialog.cpp:132 +#, kde-format +msgid "Stamp Properties" +msgstr "Proprietà del timbro" + +#: part/annotationpropertiesdialog.cpp:135 +#, kde-format +msgid "Freehand Line Properties" +msgstr "Proprietà della linea a mano libera" + +#: part/annotationpropertiesdialog.cpp:138 +#, kde-format +msgid "Caret Properties" +msgstr "Proprietà del punto di inserimento" + +#: part/annotationpropertiesdialog.cpp:141 +#, kde-format +msgid "File Attachment Properties" +msgstr "Proprietà del file allegato" + +#: part/annotationpropertiesdialog.cpp:144 +#, kde-format +msgid "Sound Properties" +msgstr "Proprietà del suono" + +#: part/annotationpropertiesdialog.cpp:147 +#, kde-format +msgid "Movie Properties" +msgstr "Proprietà del filmato" + +#: part/annotationpropertiesdialog.cpp:150 +#, kde-format +msgid "Annotation Properties" +msgstr "Proprietà dell'annotazione" + +#: part/annotationpropertiesdialog.cpp:175 +#, kde-format +msgid "Modified: %1" +msgstr "Modificato: %1" + +#: part/annotationwidgets.cpp:56 +#, kde-format +msgctxt "@info:tooltip" +msgid "Select a custom stamp symbol from file" +msgstr "Seleziona simbolo per un timbro personalizzato da file" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgctxt "@title:window file chooser" +msgid "Select custom stamp symbol" +msgstr "Seleziona un simbolo per un timbro personalizzato" + +#: part/annotationwidgets.cpp:154 +#, kde-format +msgid "" +"*.ico *.png *.xpm *.svg *.svgz | Icon Files (*.ico *.png *.xpm *.svg *.svgz)" +msgstr "" +"*.ico *.png *.xpm *.svg *.svgz | File icona (*.ico *.png *.xpm *.svg *.svgz)" + +#: part/annotationwidgets.cpp:158 +#, kde-kuit-format +msgctxt "@info" +msgid "Could not load the file %1" +msgstr "Impossibile caricare il file %1" + +#: part/annotationwidgets.cpp:158 +#, kde-format +msgctxt "@title:window" +msgid "Invalid file" +msgstr "File non valido" + +#: part/annotationwidgets.cpp:261 +#, kde-format +msgid "&Color:" +msgstr "&Colore:" + +#: part/annotationwidgets.cpp:270 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80%'" +msgid "%" +msgstr "%" + +#: part/annotationwidgets.cpp:271 part/editdrawingtooldialog.cpp:70 +#, kde-format +msgid "&Opacity:" +msgstr "&Opacità:" + +#: part/annotationwidgets.cpp:358 +#, kde-format +msgid "Icon:" +msgstr "Icona:" + +#: part/annotationwidgets.cpp:359 +#, kde-format +msgid "Comment" +msgstr "Commento" + +#: part/annotationwidgets.cpp:360 +#, kde-format +msgid "Help" +msgstr "Aiuto" + +#: part/annotationwidgets.cpp:361 +#, kde-format +msgid "Insert" +msgstr "Inserisci" + +#: part/annotationwidgets.cpp:362 +#, kde-format +msgid "Key" +msgstr "Chiave" + +#: part/annotationwidgets.cpp:363 +#, kde-format +msgid "New paragraph" +msgstr "Nuovo paragrafo" + +#: part/annotationwidgets.cpp:364 +#, kde-format +msgid "Note" +msgstr "Nota" + +#: part/annotationwidgets.cpp:365 +#, kde-format +msgid "Paragraph" +msgstr "Paragrafo" + +#: part/annotationwidgets.cpp:373 +#, kde-format +msgid "Font:" +msgstr "Carattere:" + +#: part/annotationwidgets.cpp:382 +#, kde-format +msgid "Text &color:" +msgstr "&Colore del testo:" + +#: part/annotationwidgets.cpp:389 +#, kde-format +msgid "&Align:" +msgstr "&Allineamento:" + +#: part/annotationwidgets.cpp:390 +#, kde-format +msgid "Left" +msgstr "Sinistra" + +#: part/annotationwidgets.cpp:391 +#, kde-format +msgid "Center" +msgstr "Centro" + +#: part/annotationwidgets.cpp:392 +#, kde-format +msgid "Right" +msgstr "Destra" + +#: part/annotationwidgets.cpp:400 +#, kde-format +msgid "Border &width:" +msgstr "Larg&hezza del bordo:" + +#: part/annotationwidgets.cpp:407 +#, kde-format +msgid "Approved" +msgstr "Approvato" + +#: part/annotationwidgets.cpp:408 +#, kde-format +msgid "As Is" +msgstr "Così com'è" + +#: part/annotationwidgets.cpp:409 +#, kde-format +msgid "Confidential" +msgstr "Confidenziale" + +#: part/annotationwidgets.cpp:410 +#, kde-format +msgid "Departmental" +msgstr "Dipartimentale" + +#: part/annotationwidgets.cpp:411 +#, kde-format +msgid "Draft" +msgstr "Bozza" + +#: part/annotationwidgets.cpp:412 +#, kde-format +msgid "Experimental" +msgstr "Sperimentale" + +#: part/annotationwidgets.cpp:413 +#, kde-format +msgid "Final" +msgstr "Finale" + +#: part/annotationwidgets.cpp:414 +#, kde-format +msgid "For Comment" +msgstr "Per commenti" + +#: part/annotationwidgets.cpp:415 +#, kde-format +msgid "For Public Release" +msgstr "Per il rilascio pubblico" + +#: part/annotationwidgets.cpp:416 +#, kde-format +msgid "Not Approved" +msgstr "Non approvato" + +#: part/annotationwidgets.cpp:417 +#, kde-format +msgid "Not For Public Release" +msgstr "Non per il rilascio pubblico" + +#: part/annotationwidgets.cpp:418 +#, kde-format +msgid "Sold" +msgstr "Venduto" + +#: part/annotationwidgets.cpp:419 +#, kde-format +msgid "Top Secret" +msgstr "Top secret" + +#: part/annotationwidgets.cpp:420 +#, kde-format +msgid "Bookmark" +msgstr "Segnalibro" + +#: part/annotationwidgets.cpp:421 +#, kde-format +msgid "Information" +msgstr "Informazione" + +#: part/annotationwidgets.cpp:422 +#, kde-format +msgid "KDE" +msgstr "KDE" + +#: part/annotationwidgets.cpp:438 +#, kde-kuit-format +msgctxt "@info" +msgid "" +"experimental feature.Stamps inserted in PDF documents are not " +"visible in PDF readers other than Okular." +msgstr "" +"funzione sperimentale.I timbri inseriti nei documenti PDF non " +"saranno visibili in lettori PDF diversi da Okular." + +#: part/annotationwidgets.cpp:449 +#, kde-format +msgid "Stamp symbol:" +msgstr "Disegno del timbro:" + +#: part/annotationwidgets.cpp:497 part/annotationwidgets.cpp:559 +#: part/annotationwidgets.cpp:622 part/annotationwidgets.cpp:696 +#: part/annotationwidgets.cpp:775 +#, kde-format +msgid "&Width:" +msgstr "&Larghezza:" + +#: part/annotationwidgets.cpp:502 +#, kde-format +msgid "Line start:" +msgstr "Inizio dalla linea:" + +#: part/annotationwidgets.cpp:504 +#, kde-format +msgid "Line end:" +msgstr "Fine della linea:" + +#: part/annotationwidgets.cpp:507 +#, kde-format +msgid "Square" +msgstr "Quadrato" + +#: part/annotationwidgets.cpp:508 +#, kde-format +msgid "Circle" +msgstr "Cerchio" + +#: part/annotationwidgets.cpp:509 +#, kde-format +msgid "Diamond" +msgstr "Diamante" + +#: part/annotationwidgets.cpp:510 +#, kde-format +msgid "Open Arrow" +msgstr "Freccia aperta" + +#: part/annotationwidgets.cpp:511 +#, kde-format +msgid "Closed Arrow" +msgstr "Freccia chiusa" + +#: part/annotationwidgets.cpp:512 +#, kde-format +msgid "None" +msgstr "Nessuna" + +#: part/annotationwidgets.cpp:513 +#, kde-format +msgid "Butt" +msgstr "Interrotta" + +#: part/annotationwidgets.cpp:514 +#, kde-format +msgid "Right Open Arrow" +msgstr "Freccia aperta a destra" + +#: part/annotationwidgets.cpp:515 +#, kde-format +msgid "Right Closed Arrow" +msgstr "Freccia chiusa a destra" + +#: part/annotationwidgets.cpp:516 +#, kde-format +msgid "Slash" +msgstr "Barra" + +#: part/annotationwidgets.cpp:529 +#, kde-format +msgid "Leader line length:" +msgstr "Lunghezza linea direzionale:" + +#: part/annotationwidgets.cpp:531 +#, kde-format +msgid "Leader line extensions length:" +msgstr "Lunghezza estensioni linea direzionale:" + +#: part/annotationwidgets.cpp:545 part/annotationwidgets.cpp:689 +#, kde-format +msgid "Enabled" +msgstr "Abilitato" + +#: part/annotationwidgets.cpp:549 part/annotationwidgets.cpp:693 +#, kde-format +msgid "Shape fill:" +msgstr "Riempimento forma:" + +#: part/annotationwidgets.cpp:649 part/annotationwidgets.cpp:683 +#, kde-format +msgid "Type:" +msgstr "Tipo:" + +#: part/annotationwidgets.cpp:651 part/guiutils.cpp:89 +#, kde-format +msgid "Highlight" +msgstr "Evidenziato" + +#: part/annotationwidgets.cpp:652 part/guiutils.cpp:92 +#: part/pageviewannotator.cpp:1101 +#, kde-format +msgid "Squiggle" +msgstr "Scarabocchiato" + +#: part/annotationwidgets.cpp:653 part/guiutils.cpp:95 +#: part/pageviewannotator.cpp:1109 +#, kde-format +msgid "Underline" +msgstr "Sottolineato" + +#: part/annotationwidgets.cpp:654 part/pageviewannotator.cpp:1107 +#, kde-format +msgid "Strike out" +msgstr "Barrato" + +#: part/annotationwidgets.cpp:698 part/pageviewannotator.cpp:1099 +#, kde-format +msgid "Rectangle" +msgstr "Rettangolo" + +#: part/annotationwidgets.cpp:699 part/pageviewannotator.cpp:1087 +#, kde-format +msgid "Ellipse" +msgstr "Ellisse" + +#: part/annotationwidgets.cpp:743 +#, kde-format +msgid "File attachment symbol:" +msgstr "Simbolo file allegato:" + +#: part/annotationwidgets.cpp:746 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Graph" +msgstr "Grafico" + +#: part/annotationwidgets.cpp:747 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Push Pin" +msgstr "Puntina da disegno" + +#: part/annotationwidgets.cpp:748 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Paperclip" +msgstr "Graffetta" + +#: part/annotationwidgets.cpp:749 +#, kde-format +msgctxt "Symbol for file attachment annotations" +msgid "Tag" +msgstr "Etichetta" + +#: part/annotationwidgets.cpp:758 +#, kde-format +msgctxt "'File' as normal file, that can be opened, saved, etc.." +msgid "File" +msgstr "File" + +#: part/annotationwidgets.cpp:762 part/embeddedfilesdialog.cpp:90 +#, kde-format +msgctxt "Not available size" +msgid "N/A" +msgstr "N/D" + +#: part/annotationwidgets.cpp:763 +#, kde-format +msgid "No description available." +msgstr "Nessuna descrizione disponibile." + +#: part/annotationwidgets.cpp:771 +#, kde-format +msgid "Name:" +msgstr "Nome:" + +#: part/annotationwidgets.cpp:782 +#, kde-format +msgid "Description:" +msgstr "Descrizione:" + +#: part/annotationwidgets.cpp:840 +#, kde-format +msgid "Caret symbol:" +msgstr "Simbolo del punto di inserimento:" + +#: part/annotationwidgets.cpp:842 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "None" +msgstr "Nessuno" + +#: part/annotationwidgets.cpp:843 +#, kde-format +msgctxt "Symbol for caret annotations" +msgid "P" +msgstr "P" + +#: part/annotwindow.cpp:55 +#, kde-format +msgid "Close this note" +msgstr "Chiudi questa nota" + +#: part/annotwindow.cpp:98 part/findbar.cpp:66 +#, kde-format +msgid "Options" +msgstr "Opzioni" + +#: part/annotwindow.cpp:109 +#, kde-format +msgid "" +"This annotation may contain LaTeX code.\n" +"Click here to render." +msgstr "" +"Questa annotazione potrebbe contenere codice LaTeX.\n" +"Fai clic qui per effettuarne il rendering." + +#: part/annotwindow.cpp:375 +#, kde-format +msgid "Cannot find latex executable." +msgstr "Impossibile trovare l'eseguibile latex." + +#: part/annotwindow.cpp:375 part/annotwindow.cpp:380 part/annotwindow.cpp:385 +#: part/annotwindow.cpp:390 +#, kde-format +msgid "LaTeX rendering failed" +msgstr "Rendering LaTeX non riuscito" + +#: part/annotwindow.cpp:380 +#, kde-format +msgid "Cannot find dvipng executable." +msgstr "Impossibile trovare l'eseguibile dvipng." + +#: part/annotwindow.cpp:385 +#, kde-format +msgid "A problem occurred during the execution of the 'latex' command." +msgstr "Si è verificato un problema durante l'esecuzione del comando «latex»." + +#: part/annotwindow.cpp:390 +#, kde-format +msgid "A problem occurred during the execution of the 'dvipng' command." +msgstr "Si è verificato un problema durante l'esecuzione del comando «dvipng»." + +#: part/bookmarklist.cpp:115 +#, kde-format +msgctxt "%1 is the file name" +msgid "" +"%1\n" +"\n" +"One bookmark" +msgid_plural "" +"%1\n" +"\n" +"%2 bookmarks" +msgstr[0] "" +"%1\n" +"\n" +"Un segnalibro" +msgstr[1] "" +"%1\n" +"\n" +"%2 segnalibri" + +#: part/bookmarklist.cpp:131 part/part.cpp:442 +#, kde-format +msgid "Bookmarks" +msgstr "Segnalibri" + +#: part/bookmarklist.cpp:136 part/searchwidget.cpp:40 part/side_reviews.cpp:127 +#: part/toc.cpp:46 +#, kde-format +msgid "Search..." +msgstr "Cerca..." + +#: part/bookmarklist.cpp:165 +#, kde-format +msgid "Current document only" +msgstr "Solo per il documento corrente" + +#: part/bookmarklist.cpp:251 +#, kde-format +msgid "Go to This Bookmark" +msgstr "Vai a questo segnalibro" + +#: part/bookmarklist.cpp:252 part/bookmarklist.cpp:279 part/part.cpp:685 +#: part/part.cpp:2321 +#, kde-format +msgid "Rename Bookmark" +msgstr "Rinomina segnalibro" + +#: part/bookmarklist.cpp:253 part/part.cpp:2129 part/part.cpp:2942 +#, kde-format +msgid "Remove Bookmark" +msgstr "Elimina segnalibro" + +#: part/bookmarklist.cpp:278 +#, kde-format +msgctxt "Opens the selected document" +msgid "Open Document" +msgstr "Apri documento" + +#: part/bookmarklist.cpp:280 +#, kde-format +msgid "Remove Bookmarks" +msgstr "Elimina segnalibri" + +#: part/certificateviewer.cpp:121 +#, kde-format +msgid "Version" +msgstr "Versione" + +#: part/certificateviewer.cpp:123 +#, kde-format +msgid "Serial Number" +msgstr "Numero seriale" + +#: part/certificateviewer.cpp:125 +#, kde-format +msgid "Issuer" +msgstr "Emittente" + +#: part/certificateviewer.cpp:127 part/certificateviewer.cpp:242 +#, kde-format +msgid "Issued On" +msgstr "Emesso il" + +#: part/certificateviewer.cpp:129 part/certificateviewer.cpp:243 +#, kde-format +msgid "Expires On" +msgstr "Scade il" + +#: part/certificateviewer.cpp:131 +#, kde-format +msgctxt "The person/company that made the signature" +msgid "Subject" +msgstr "Oggetto" + +#: part/certificateviewer.cpp:133 +#, kde-format +msgid "Public Key" +msgstr "Chiave pubblica" + +#: part/certificateviewer.cpp:135 +#, kde-format +msgid "Key Usage" +msgstr "Utilizzo della chiave" + +#: part/certificateviewer.cpp:144 +#, kde-format +msgid "V%1" +msgstr "V%1" + +#: part/certificateviewer.cpp:156 +#, kde-format +msgid "%1 (%2 bits)" +msgstr "%1 (%2 bit)" + +#: part/certificateviewer.cpp:199 +#, kde-format +msgid "Property" +msgstr "Proprietà" + +#: part/certificateviewer.cpp:201 +#, kde-format +msgid "Value" +msgstr "Valore" + +#: part/certificateviewer.cpp:214 +#, kde-format +msgid "Certificate Viewer" +msgstr "Visualizzatore certificato" + +#: part/certificateviewer.cpp:217 +#, kde-format +msgid "Export..." +msgstr "Esporta..." + +#: part/certificateviewer.cpp:223 part/preferencesdialog.cpp:40 +#, kde-format +msgid "General" +msgstr "Generale" + +#: part/certificateviewer.cpp:225 +#, kde-format +msgid "Issued By" +msgstr "Emesso da" + +#: part/certificateviewer.cpp:228 part/certificateviewer.cpp:235 +#, kde-format +msgid "Common Name(CN)" +msgstr "Nome comune(CN)" + +#: part/certificateviewer.cpp:229 part/certificateviewer.cpp:236 +#, kde-format +msgid "EMail" +msgstr "Posta elettronica" + +#: part/certificateviewer.cpp:230 part/certificateviewer.cpp:237 +#, kde-format +msgid "Organization(O)" +msgstr "Organizzazione(O)" + +#: part/certificateviewer.cpp:232 +#, kde-format +msgid "Issued To" +msgstr "Emesso a" + +#: part/certificateviewer.cpp:239 +#, kde-format +msgid "Validity" +msgstr "Validità" + +#: part/certificateviewer.cpp:245 +#, kde-format +msgid "Fingerprints" +msgstr "Impronte digitali" + +#: part/certificateviewer.cpp:253 +#, kde-format +msgid "SHA-1 Fingerprint" +msgstr "Impronta digitale SHA-1" + +#: part/certificateviewer.cpp:254 +#, kde-format +msgid "SHA-256 Fingerprint" +msgstr "Impronta digitale SHA-256" + +#: part/certificateviewer.cpp:272 +#, kde-format +msgid "Details" +msgstr "Dettagli" + +#: part/certificateviewer.cpp:273 +#, kde-format +msgid "Certificate Data:" +msgstr "Dati del certificato:" + +#: part/certificateviewer.cpp:315 +#, kde-format +msgid "Where do you want to save this certificate?" +msgstr "Dove vuoi salvare questo certificato?" + +#: part/certificateviewer.cpp:316 +#, kde-format +msgid "Certificate File (*.cer)" +msgstr "File di certificato (*.cer)" + +#: part/certificateviewer.cpp:321 +#, kde-format +msgid "Could not export the certificate" +msgstr "Impossibile esportare il certificato" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:11 +#, kde-format +msgid "Red" +msgstr "Rosso" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:16 +#, kde-format +msgid "Green" +msgstr "Verde" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:21 +#, kde-format +msgid "Blue" +msgstr "Blu" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:26 +#, kde-format +msgid "Yellow" +msgstr "Giallo" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:31 +#, kde-format +msgid "Black" +msgstr "Nero" + +#. i18n: tag tool attribute name +#: part/data/drawingtools.xml:36 +#, kde-format +msgid "White" +msgstr "Bianco" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightImages) +#: part/dlgaccessibilitybase.ui:28 +#, kde-format +msgid "Draw border around &Images" +msgstr "Disegna il bordo attorno alle &immagini" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_HighlightLinks) +#: part/dlgaccessibilitybase.ui:35 +#, kde-format +msgid "Draw border around &Links" +msgstr "Disegna il bordo attorno ai co&llegamenti" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_ChangeColors) +#: part/dlgaccessibilitybase.ui:45 +#, kde-format +msgid "Change &colors" +msgstr "Cambia &colori" + +#. i18n: ectx: property (text), widget (QLabel, warn) +#: part/dlgaccessibilitybase.ui:63 +#, kde-format +msgid "Warning: these options can badly affect drawing speed." +msgstr "Attenzione: queste opzioni possono rallentare il programma." + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgaccessibilitybase.ui:78 +#, kde-format +msgid "Color mode:" +msgstr "Modalità colore:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:92 +#, kde-format +msgid "Invert Colors" +msgstr "Inverti colori" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:97 +#, kde-format +msgid "Change Paper Color" +msgstr "Cambia il colore della carta" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:102 +#, kde-format +msgid "Change Dark & Light Colors" +msgstr "Cambia i colori chiari e scuri" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:107 +#, kde-format +msgid "Convert to Black & White" +msgstr "Converti in bianco e nero" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:112 +#, kde-format +msgid "Invert Lightness" +msgstr "Inverte chiarezza" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:117 +#, kde-format +msgid "Invert Luma (sRGB Linear)" +msgstr "Inverte luma (sRGB lineare)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:122 +#, kde-format +msgid "Invert Luma (Symmetric)" +msgstr "Inverte luma (simmetrico)" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:127 +#, kde-format +msgid "Shift Hue Positive" +msgstr "Sposta tonalità positivamente" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_RenderMode) +#: part/dlgaccessibilitybase.ui:132 +#, kde-format +msgid "Shift Hue Negative" +msgstr "Sposta tonalità negativamente" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgaccessibilitybase.ui:193 +#, kde-format +msgid "Paper color:" +msgstr "Colore della carta:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgaccessibilitybase.ui:246 +#, kde-format +msgid "Dark color:" +msgstr "Colore scuro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3_2) +#: part/dlgaccessibilitybase.ui:281 +#, kde-format +msgid "Light color:" +msgstr "Colore chiaro:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgaccessibilitybase.ui:325 +#, kde-format +msgid "Threshold:" +msgstr "Soglia:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2_2) +#: part/dlgaccessibilitybase.ui:360 +#, kde-format +msgid "Contrast:" +msgstr "Contrasto:" + +#. i18n: ectx: property (title), widget (QGroupBox, speechBox) +#: part/dlgaccessibilitybase.ui:412 +#, kde-format +msgid "Speech" +msgstr "Pronuncia" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgaccessibilitybase.ui:418 +#, kde-format +msgid "Engine" +msgstr "Motore" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgannotationsbase.ui:31 +#, kde-format +msgid "Identity" +msgstr "Identità" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgannotationsbase.ui:55 +#, kde-format +msgid "Au&thor:" +msgstr "Au&tore:" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgannotationsbase.ui:71 +#, kde-format +msgid "" +"Note: the information here is used only for annotations. The " +"information is saved in annotated documents, and so will be transmitted " +"together with the document." +msgstr "" +"Nota: le informazioni qui presenti sono usate solo per le " +"annotazioni. Le informazioni sono salvate nei documenti con annotazioni e " +"saranno trasmesse assieme ai documenti." + +#. i18n: ectx: property (title), widget (QGroupBox, annotToolsGroup) +#: part/dlgannotationsbase.ui:87 +#, kde-format +msgid "Quick annotation tools" +msgstr "Strumenti di annotazione veloce" + +#: part/dlgeditor.cpp:28 +#, kde-format +msgctxt "Text editor" +msgid "Custom Text Editor" +msgstr "Editor di testo personalizzato" + +#: part/dlgeditor.cpp:29 +#, kde-format +msgctxt "Text editor" +msgid "Kate" +msgstr "Kate" + +#: part/dlgeditor.cpp:30 +#, kde-format +msgctxt "Text editor" +msgid "Kile" +msgstr "Kile" + +#: part/dlgeditor.cpp:31 +#, kde-format +msgctxt "Text editor" +msgid "SciTE" +msgstr "SciTE" + +#: part/dlgeditor.cpp:32 +#, kde-format +msgctxt "Text editor" +msgid "Emacs client" +msgstr "Emacs client" + +#: part/dlgeditor.cpp:33 +#, kde-format +msgctxt "Text editor" +msgid "Lyx client" +msgstr "Lyx client" + +#: part/dlgeditor.cpp:34 +#, kde-format +msgctxt "Text editor" +msgid "TeXstudio" +msgstr "TeXstudio" + +#: part/dlgeditor.cpp:35 +#, kde-format +msgctxt "Text editor" +msgid "TeXiFy IDEA" +msgstr "TeXiFy IDEA" + +#: part/dlgeditor.cpp:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Set the command of a custom text editor to be launched.
    \n" +"You can also put few placeholders:\n" +"
      \n" +"
    • %f - the file name
    • \n" +"
    • %l - the line of the file to be reached
    • \n" +"
    • %c - the column of the file to be reached
    • \n" +"
    \n" +"If %f is not specified, then the file name is appended to the specified " +"command." +msgstr "" +"Imposta il comando per l'esecuzione di un editor di testo personalizzato." +"
    \n" +"Puoi anche utilizzare alcuni segnaposto:\n" +"
      \n" +"
    • %f - il nome del file
    • \n" +"
    • %l - la riga da visualizzare del file
    • \n" +"
    • %c - la colonna da visualizzare del file
    • \n" +"
    \n" +"Se %f non è specificato, il nome del file viene aggiunto al comando " +"specificato." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgeditorbase.ui:19 part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlgeditorbase.ui:25 +#, kde-format +msgid "Editor:" +msgstr "Editor:" + +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ExternalEditor) +#: part/dlgeditorbase.ui:38 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Choose the editor you want to launch when Okular wants to open a source file." +msgstr "" +"Scegli l'editor da eseguire quando Okular cerca di aprire un file sorgente." + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgeditorbase.ui:76 +#, kde-format +msgid "Command:" +msgstr "Comando:" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:32 part/dlgpresentationbase.ui:132 +#: part/editannottooldialog.cpp:85 +#, kde-format +msgid "Appearance" +msgstr "Aspetto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SmoothScrolling) +#: part/dlggeneralbase.ui:70 +#, kde-format +msgid "Use smooth scrolling" +msgstr "Usa scorrimento fluido" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowScrollBars) +#: part/dlggeneralbase.ui:77 +#, kde-format +msgid "Show scroll&bars" +msgstr "Mostra &barre di scorrimento" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SyncThumbnailsViewport) +#: part/dlggeneralbase.ui:87 +#, kde-format +msgid "Link the &thumbnails with the page" +msgstr "Collega le &miniature con la pagina" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShowOSD) +#: part/dlggeneralbase.ui:94 +#, kde-format +msgid "Show &hints and info messages" +msgstr "Mostra &messaggi di avviso ed informazione" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_DisplayDocumentTitle) +#: part/dlggeneralbase.ui:101 +#, kde-format +msgid "Display document title in titlebar if available" +msgstr "Mostra il titolo del documento, se disponibile, nella barra del titolo" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: part/dlggeneralbase.ui:108 +#, kde-format +msgid "When not displaying document title:" +msgstr "Quando non viene mostrato il titolo del documento:" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFileName) +#: part/dlggeneralbase.ui:133 +#, kde-format +msgid "Display file name only" +msgstr "Mostra solo il nome del file" + +#. i18n: ectx: property (text), widget (QRadioButton, radioFilePath) +#: part/dlggeneralbase.ui:143 +#, kde-format +msgid "Display full file path" +msgstr "Mostra il percorso completo del file" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_UseCustomBackgroundColor) +#: part/dlggeneralbase.ui:171 +#, kde-format +msgid "Use custom background color" +msgstr "Usa un colore di sfondo personalizzato" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlggeneralbase.ui:240 +#, kde-format +msgid "Program Features" +msgstr "Funzioni del programma" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ShellOpenFileInTabs) +#: part/dlggeneralbase.ui:248 +#, kde-format +msgid "Open new files in &tabs" +msgstr "Apri i nuovi file nelle &schede" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SwitchToTabIfOpen) +#: part/dlggeneralbase.ui:273 +#, kde-format +msgid "Switch to existing tab if file is already open" +msgstr "Passa alla scheda esistente se il file è già aperto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ObeyDRM) +#: part/dlggeneralbase.ui:282 +#, kde-format +msgid "&Obey DRM limitations" +msgstr "&Rispetta limitazioni DRM" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_WatchFile) +#: part/dlggeneralbase.ui:289 +#, kde-format +msgid "&Reload document on file change" +msgstr "&Ricarica il documento se il file viene modificato" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_ChooseGenerators) +#: part/dlggeneralbase.ui:296 +#, kde-format +msgid "Show backend selection dialog" +msgstr "Mostra la finestra per la scelta del backend" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_rtlReadingDirection) +#: part/dlggeneralbase.ui:322 +#, kde-format +msgid "Right to left reading direction" +msgstr "Direzione di lettura da destra a sinistra" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: part/dlggeneralbase.ui:347 +#, kde-format +msgid "View Options" +msgstr "Opzioni visualizzazione" + +#. i18n: ectx: property (text), widget (QLabel, columnLabel) +#: part/dlggeneralbase.ui:353 +#, kde-format +msgid "Overview &columns:" +msgstr "&Colonne in modalità panoramica:" + +#. i18n: ectx: property (toolTip), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:376 +#, kde-format +msgid "" +"Defines how much of the current viewing area will still be visible when " +"pressing the Page Up/Down keys." +msgstr "" +"Definisce quanto dell'area di visualizzazione attuale sarà ancora visibile " +"dopo la pressione dei tasti PaginaSu/PaginaGiù." + +#. i18n: ectx: property (text), widget (QLabel, scrollOverlapLabel) +#: part/dlggeneralbase.ui:379 +#, kde-format +msgid "&Page Up/Down overlap:" +msgstr "Sovrapposizione &PaginaSu/PaginaGiù:" + +#. i18n: ectx: property (suffix), widget (QSpinBox, kcfg_ScrollOverlap) +#: part/dlggeneralbase.ui:392 +#, no-c-format, kde-format +msgid "%" +msgstr "%" + +#. i18n: ectx: property (toolTip), widget (QLabel, label_3) +#. i18n: ectx: property (toolTip), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:406 part/dlggeneralbase.ui:427 +#, kde-format +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Definisce la modalità di ingrandimento predefinita per i file che non sono " +"mai stati aperti prima.\n" +"Per i file che sono stati già aperti viene utilizzato l'ultimo livello di " +"ingrandimento." + +#. i18n: ectx: property (whatsThis), widget (QLabel, label_3) +#. i18n: ectx: property (whatsThis), widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:410 part/dlggeneralbase.ui:431 +#, kde-format +msgctxt "@info:whatsthis" +msgid "" +"Defines the default zoom mode for files which were never opened before.\n" +"For files which were opened before the previous zoom is applied." +msgstr "" +"Definisce la modalità di ingrandimento predefinita per i file che non sono " +"mai stati aperti prima.\n" +"Per i file che sono stati già aperti viene utilizzato l'ultimo livello di " +"ingrandimento." + +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: part/dlggeneralbase.ui:413 +#, kde-format +msgid "&Default Zoom:" +msgstr "Ingran&dimento predefinito:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:435 +#, no-c-format, kde-format +msgid "100%" +msgstr "100%" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:440 part/pageview.cpp:3830 part/part.cpp:2946 +#, kde-format +msgid "Fit Width" +msgstr "Larghezza pagina" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:445 part/pageview.cpp:3830 +#, kde-format +msgid "Fit Page" +msgstr "Pagina intera" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_ZoomMode) +#: part/dlggeneralbase.ui:450 part/pageview.cpp:3830 +#, kde-format +msgid "Auto Fit" +msgstr "Adattamento automatico" + +#: part/dlgperformance.cpp:50 +#, kde-format +msgid "" +"Keeps used memory as low as possible. Do not reuse anything. (For systems " +"with low memory.)" +msgstr "" +"Utilizza solo la memoria indispensabile. Non riusa niente. (Per sistemi con " +"poca memoria)" + +#: part/dlgperformance.cpp:53 +#, kde-format +msgid "" +"A good compromise between memory usage and speed gain. Preload next page and " +"boost searches. (For systems with 2GB of memory, typically.)" +msgstr "" +"Un buon compromesso tra utilizzo di memoria e prestazioni. Precarica la " +"pagina successiva e velocizza le ricerche. (Profilo tipico per sistemi con 2 " +"GB di memoria)" + +#: part/dlgperformance.cpp:56 +#, kde-format +msgid "" +"Keeps everything in memory. Preload next pages. Boost searches. (For systems " +"with more than 4GB of memory.)" +msgstr "" +"Mantiene tutto in memoria. Precarica le pagine successive. Velocizza le " +"ricerche. (Profilo consigliato per sistemi con 4 GB di memoria o superiore)" + +#: part/dlgperformance.cpp:60 +#, no-c-format, kde-format +msgid "" +"Loads and keeps everything in memory. Preload all pages. (Will use at " +"maximum 50% of your total memory or your free memory, whatever is bigger.)" +msgstr "" +"Carica e mantiene tutto in memoria. Precarica tutte le pagine. (Userà al " +"massimo il 50% del maggiore tra memoria totale e memoria libera)" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgperformancebase.ui:32 +#, kde-format +msgid "CPU Usage" +msgstr "Utilizzo della CPU" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_EnableCompositing) +#: part/dlgperformancebase.ui:87 +#, kde-format +msgid "Enable &transparency effects" +msgstr "Abilita &trasparenze" + +#. i18n: ectx: property (title), widget (QGroupBox, groupbox) +#: part/dlgperformancebase.ui:146 +#, kde-format +msgid "Memory Usage" +msgstr "Utilizzo della memoria" + +#. i18n: ectx: property (text), widget (QRadioButton, lowRadio) +#: part/dlgperformancebase.ui:193 +#, kde-format +msgid "&Low" +msgstr "&Minimo" + +#. i18n: ectx: property (text), widget (QRadioButton, normalRadio) +#: part/dlgperformancebase.ui:203 +#, kde-format +msgid "Nor&mal (default)" +msgstr "Nor&male (scelta predefinita)" + +#. i18n: ectx: property (text), widget (QRadioButton, aggressiveRadio) +#: part/dlgperformancebase.ui:213 +#, kde-format +msgid "Aggr&essive" +msgstr "Aggr&essivo" + +#. i18n: ectx: property (text), widget (QRadioButton, greedyRadio) +#: part/dlgperformancebase.ui:223 +#, kde-format +msgid "G&reedy" +msgstr "Ingo&rdo" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: part/dlgperformancebase.ui:302 +#, kde-format +msgid "Rendering" +msgstr "Visualizzazione" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextAntialias) +#: part/dlgperformancebase.ui:308 +#, kde-format +msgid "Enable Text Antialias" +msgstr "Abilita antialias del testo" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_GraphicsAntialias) +#: part/dlgperformancebase.ui:315 +#, kde-format +msgid "Enable Graphics Antialias" +msgstr "Abilita antialias della grafica" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_TextHinting) +#: part/dlgperformancebase.ui:322 +#, kde-format +msgid "Enable Text Hinting" +msgstr "Abilita hinting del testo" + +#: part/dlgpresentation.cpp:33 +#, kde-format +msgctxt "@label:listbox The current screen, for the presentation mode" +msgid "Current Screen" +msgstr "Schermo corrente" + +#: part/dlgpresentation.cpp:34 +#, kde-format +msgctxt "@label:listbox The default screen for the presentation mode" +msgid "Default Screen" +msgstr "Schermo predefinito" + +#: part/dlgpresentation.cpp:37 +#, kde-format +msgctxt "@label:listbox %1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Schermo %1" + +#: part/dlgpresentation.cpp:49 +#, kde-format +msgctxt "Advance every %1 seconds" +msgid " second" +msgid_plural " seconds" +msgstr[0] " secondo" +msgstr[1] " secondi" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: part/dlgpresentationbase.ui:29 +#, kde-format +msgid "Navigation" +msgstr "Navigazione" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesAdvance) +#: part/dlgpresentationbase.ui:67 +#, kde-format +msgid "Advance every:" +msgstr "Avanza ogni:" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesLoop) +#: part/dlgpresentationbase.ui:86 +#, kde-format +msgid "Loop after last page" +msgstr "Torna all'inizio dopo l'ultima pagina" + +#. i18n: ectx: property (text), widget (QLabel) +#: part/dlgpresentationbase.ui:95 +#, kde-format +msgid "Touch navigation:" +msgstr "Navigazione tattile:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:109 +#, kde-format +msgid "Tap left/right side to go back/forward" +msgstr "Tocco sul lato sinistro/destro per andare indietro/avanti" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:114 +#, kde-format +msgid "Tap anywhere to go forward" +msgstr "Tocco in un qualsiasi punto per andare avanti" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTapNavigation) +#: part/dlgpresentationbase.ui:119 +#, kde-format +msgid "Disabled" +msgstr "Disabilitato" + +#. i18n: ectx: property (text), widget (QLabel, textLabel3) +#: part/dlgpresentationbase.ui:140 +#, kde-format +msgid "Background color:" +msgstr "Colore di sfondo:" + +#. i18n: ectx: property (text), widget (QLabel, textLabel2) +#: part/dlgpresentationbase.ui:156 +#, kde-format +msgid "Mouse cursor:" +msgstr "Puntatore del mouse:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:170 +#, kde-format +msgid "Hidden After Delay" +msgstr "Nascosto se inattivo" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:175 +#, kde-format +msgid "Always Visible" +msgstr "Sempre visibile" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesCursor) +#: part/dlgpresentationbase.ui:180 +#, kde-format +msgid "Always Hidden" +msgstr "Sempre nascosto" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowProgress) +#: part/dlgpresentationbase.ui:190 +#, kde-format +msgid "Show &progress indicator" +msgstr "Mostra l'indicatore di &avanzamento" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_SlidesShowSummary) +#: part/dlgpresentationbase.ui:197 +#, kde-format +msgid "Show s&ummary page" +msgstr "Mostra la pagina di &riepilogo" + +#. i18n: ectx: property (title), widget (QGroupBox, kcfg_SlidesTransitionsEnabled) +#: part/dlgpresentationbase.ui:207 +#, kde-format +msgid "Enable transitions" +msgstr "Abilita transizioni" + +#. i18n: ectx: property (text), widget (QLabel, textLabel1) +#: part/dlgpresentationbase.ui:219 +#, kde-format +msgid "Default transition:" +msgstr "Transizione predefinita:" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:233 +#, kde-format +msgid "Blinds Vertical" +msgstr "Ritagli verticali" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:238 +#, kde-format +msgid "Blinds Horizontal" +msgstr "Ritagli orizzontali" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:243 +#, kde-format +msgid "Box In" +msgstr "Implosione" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:248 +#, kde-format +msgid "Box Out" +msgstr "Esplosione" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:253 +#, kde-format +msgid "Dissolve" +msgstr "Dissolvenza" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:258 +#, kde-format +msgid "Fade" +msgstr "Scomparsa" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:263 +#, kde-format +msgid "Glitter Down" +msgstr "Glitter verticale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:268 +#, kde-format +msgid "Glitter Right" +msgstr "Glitter orizzontale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:273 +#, kde-format +msgid "Glitter Right-Down" +msgstr "Glitter diagonale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:278 +#, kde-format +msgid "Random Transition" +msgstr "Transizione casuale" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:283 +#, kde-format +msgid "Replace" +msgstr "Sostituzione" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:288 +#, kde-format +msgid "Split Horizontal In" +msgstr "Sipario orizzontale aperto" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:293 +#, kde-format +msgid "Split Horizontal Out" +msgstr "Sipario orizzontale chiuso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:298 +#, kde-format +msgid "Split Vertical In" +msgstr "Sipario verticale aperto" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:303 +#, kde-format +msgid "Split Vertical Out" +msgstr "Sipario verticale chiuso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:308 +#, kde-format +msgid "Wipe Down" +msgstr "Sostituzione verso il basso" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:313 +#, kde-format +msgid "Wipe Right" +msgstr "Sostituzione verso destra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:318 +#, kde-format +msgid "Wipe Left" +msgstr "Sostituzione verso sinistra" + +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_SlidesTransition) +#: part/dlgpresentationbase.ui:323 +#, kde-format +msgid "Wipe Up" +msgstr "Sostituzione verso l'alto" + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4) +#: part/dlgpresentationbase.ui:334 +#, kde-format +msgid "Placement" +msgstr "Posizionamento" + +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: part/dlgpresentationbase.ui:340 +#, kde-format +msgid "Screen:" +msgstr "Schermo:" + +#. i18n: ectx: property (title), widget (QGroupBox, annotationToolsGroupBox) +#: part/dlgpresentationbase.ui:359 +#, kde-format +msgid "Drawing Tool Configuration" +msgstr "Configurazione dello strumento di disegno" + +#: part/drawingtoolactions.cpp:194 +#, kde-format +msgid "Drawing Tool: %1" +msgstr "Strumento di disegno: %1" + +#: part/drawingtoolactions.cpp:216 part/drawingtoolactions.cpp:217 +#, kde-format +msgid "Eraser" +msgstr "Gomma" + +#: part/editannottooldialog.cpp:62 part/editdrawingtooldialog.cpp:46 +#, kde-format +msgid "&Name:" +msgstr "&Nome:" + +#: part/editannottooldialog.cpp:72 +#, kde-format +msgid "&Type:" +msgstr "&Tipo:" + +#: part/editannottooldialog.cpp:91 part/guiutils.cpp:69 +#: part/pageviewannotator.cpp:222 part/pageviewannotator.cpp:1095 +#, kde-format +msgid "Pop-up Note" +msgstr "Nota a comparsa" + +#: part/editannottooldialog.cpp:92 part/guiutils.cpp:74 +#: part/pageviewannotator.cpp:205 part/pageviewannotator.cpp:1093 +#, kde-format +msgid "Inline Note" +msgstr "Nota in linea" + +#: part/editannottooldialog.cpp:93 part/guiutils.cpp:106 +#: part/pageviewannotator.cpp:1091 +#, kde-format +msgid "Freehand Line" +msgstr "Linea a mano libera" + +#: part/editannottooldialog.cpp:94 part/guiutils.cpp:79 +#: part/pageviewannotator.cpp:1105 +#, kde-format +msgid "Straight Line" +msgstr "Linea retta" + +#: part/editannottooldialog.cpp:95 part/guiutils.cpp:81 +#: part/pageviewannotator.cpp:1097 +#, kde-format +msgid "Polygon" +msgstr "Poligono" + +#: part/editannottooldialog.cpp:96 +#, kde-format +msgid "Text markup" +msgstr "Marcatore del testo" + +#: part/editannottooldialog.cpp:97 +#, kde-format +msgid "Geometrical shape" +msgstr "Forma geometrica" + +#: part/editannottooldialog.cpp:98 part/guiutils.cpp:103 +#: part/pageviewannotator.cpp:1103 +#, kde-format +msgid "Stamp" +msgstr "Timbro" + +#: part/editannottooldialog.cpp:99 part/guiutils.cpp:72 +#: part/pageviewannotator.cpp:210 part/pageviewannotator.cpp:1111 +#, kde-format +msgid "Typewriter" +msgstr "Macchina da scrivere" + +#: part/editannottooldialog.cpp:104 +#, kde-format +msgid "Create annotation tool" +msgstr "Crea strumento di annotazione" + +#: part/editannottooldialog.cpp:106 +#, kde-format +msgid "Edit annotation tool" +msgstr "Modifica strumento di annotazione" + +#: part/editdrawingtooldialog.cpp:53 +#, kde-format +msgid "Color:" +msgstr "Colore:" + +#: part/editdrawingtooldialog.cpp:60 +#, kde-format +msgid "&Pen Width:" +msgstr "Spessore della &penna:" + +#: part/editdrawingtooldialog.cpp:66 +#, kde-format +msgctxt "Suffix for the pen width, eg '10 px'" +msgid " px" +msgstr " px" + +#: part/editdrawingtooldialog.cpp:76 +#, kde-format +msgctxt "Suffix for the opacity level, eg '80 %'" +msgid " %" +msgstr " %" + +#: part/editdrawingtooldialog.cpp:81 +#, kde-format +msgid "Create drawing tool" +msgstr "Crea strumento di disegno" + +#: part/editdrawingtooldialog.cpp:86 +#, kde-format +msgid "Edit drawing tool" +msgstr "Modifica strumento di disegno" + +#: part/embeddedfilesdialog.cpp:42 +#, kde-format +msgctxt "Unknown date" +msgid "Unknown" +msgstr "Sconosciuto" + +#: part/embeddedfilesdialog.cpp:48 +#, kde-format +msgctxt "@title:window" +msgid "Embedded Files" +msgstr "Allegati" + +#: part/embeddedfilesdialog.cpp:62 +#, kde-format +msgctxt "@action:button" +msgid "View" +msgstr "Visualizza" + +#: part/embeddedfilesdialog.cpp:70 +#, kde-format +msgctxt "@title:column" +msgid "Name" +msgstr "Nome" + +#: part/embeddedfilesdialog.cpp:71 +#, kde-format +msgctxt "@title:column" +msgid "Description" +msgstr "Descrizione" + +#: part/embeddedfilesdialog.cpp:72 +#, kde-format +msgctxt "@title:column" +msgid "Size" +msgstr "Dimensione" + +#: part/embeddedfilesdialog.cpp:73 +#, kde-format +msgctxt "@title:column" +msgid "Created" +msgstr "Creato" + +#: part/embeddedfilesdialog.cpp:74 +#, kde-format +msgctxt "@title:column" +msgid "Modified" +msgstr "Modificato" + +#: part/embeddedfilesdialog.cpp:152 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Save As..." +msgstr "&Salva come..." + +#: part/embeddedfilesdialog.cpp:153 +#, kde-format +msgctxt "@action:inmenu" +msgid "&View..." +msgstr "&Visualizza..." + +#: part/fileprinterpreview.cpp:134 +#, kde-format +msgid "Could not load print preview part" +msgstr "Impossibile caricare la componente di anteprima di stampa" + +#: part/fileprinterpreview.cpp:146 +#, kde-format +msgid "Print Preview" +msgstr "Anteprima di stampa" + +#: part/findbar.cpp:37 part/presentationsearchbar.cpp:66 +#, kde-format +msgid "Close" +msgstr "Chiudi" + +#: part/findbar.cpp:41 +#, kde-format +msgctxt "Find text" +msgid "F&ind:" +msgstr "&Trova:" + +#: part/findbar.cpp:52 +#, kde-format +msgid "Text to search for" +msgstr "Testo da cercare" + +#: part/findbar.cpp:57 +#, kde-format +msgctxt "Find and go to the next search match" +msgid "Next" +msgstr "Successiva" + +#: part/findbar.cpp:58 +#, kde-format +msgid "Jump to next match" +msgstr "Passa alla corrispondenza successiva" + +#: part/findbar.cpp:61 +#, kde-format +msgctxt "Find and go to the previous search match" +msgid "Previous" +msgstr "Precedente" + +#: part/findbar.cpp:62 +#, kde-format +msgid "Jump to previous match" +msgstr "Passa alla corrispondenza precedente" + +#: part/findbar.cpp:67 +#, kde-format +msgid "Modify search behavior" +msgstr "Modifica il comportamento della ricerca" + +#: part/findbar.cpp:69 +#, kde-format +msgid "Case sensitive" +msgstr "Distingui maiuscole" + +#: part/findbar.cpp:71 +#, kde-format +msgid "From current page" +msgstr "Dalla pagina corrente" + +#: part/findbar.cpp:73 +#, kde-format +msgid "Find as you type" +msgstr "Cerca durante la digitazione" + +#: part/formwidgets.cpp:736 +#, kde-format +msgid "*|All Files" +msgstr "*|Tutti i file" + +#: part/formwidgets.cpp:1103 part/signaturepropertiesdialog.cpp:41 +#, kde-format +msgid "Signature Properties" +msgstr "Proprietà della firma" + +#: part/guiutils.cpp:79 +#, kde-format +msgid "Straight Line with Comment" +msgstr "Linea retta con commento" + +#: part/guiutils.cpp:81 +#, kde-format +msgid "Polygon with Comment" +msgstr "Poligono con commento" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry with Comment" +msgstr "Geometria con commento" + +#: part/guiutils.cpp:84 +#, kde-format +msgid "Geometry" +msgstr "Geometria" + +#: part/guiutils.cpp:89 +#, kde-format +msgid "Highlight with Comment" +msgstr "Evidenziazione con commento" + +#: part/guiutils.cpp:92 +#, kde-format +msgid "Squiggle with Comment" +msgstr "Scarabocchiato con commento" + +#: part/guiutils.cpp:95 +#, kde-format +msgid "Underline with Comment" +msgstr "Sottolineato con commento" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out with Comment" +msgstr "Barrato con commento" + +#: part/guiutils.cpp:98 +#, kde-format +msgid "Strike Out" +msgstr "Barrato" + +#: part/guiutils.cpp:103 +#, kde-format +msgid "Stamp with Comment" +msgstr "Timbro con commento" + +#: part/guiutils.cpp:106 +#, kde-format +msgid "Freehand Line with Comment" +msgstr "Linea a mano libera con commento" + +#: part/guiutils.cpp:109 +#, kde-format +msgid "Caret" +msgstr "Punto di inserimento" + +#: part/guiutils.cpp:112 +#, kde-format +msgid "File Attachment" +msgstr "File allegato" + +#: part/guiutils.cpp:115 +#, kde-format +msgid "Sound" +msgstr "Suono" + +#: part/guiutils.cpp:118 +#, kde-format +msgid "Movie" +msgstr "Filmato" + +#: part/guiutils.cpp:121 +#, kde-format +msgctxt "Caption for a screen annotation" +msgid "Screen" +msgstr "Schermo" + +#: part/guiutils.cpp:124 +#, kde-format +msgctxt "Caption for a widget annotation" +msgid "Widget" +msgstr "Oggetto" + +#: part/guiutils.cpp:127 +#, kde-format +msgctxt "Caption for a rich media annotation" +msgid "Rich Media" +msgstr "Oggetto multimediale (Rich Media)" + +#: part/guiutils.cpp:139 +#, kde-format +msgctxt "Unknown author" +msgid "Unknown" +msgstr "Sconosciuto" + +#: part/guiutils.cpp:156 part/presentationwidget.cpp:369 +#, kde-format +msgid "Author: %1" +msgstr "Autore: %1" + +#: part/guiutils.cpp:217 part/propertiesdialog.cpp:231 +#, kde-format +msgid "Where do you want to save %1?" +msgstr "Dove vuoi salvare %1?" + +#: part/guiutils.cpp:228 part/propertiesdialog.cpp:241 +#, kde-format +msgid "Could not open \"%1\" for writing. File was not saved." +msgstr "" +"Impossibile aprire il file «%1» in scrittura. Il file non è stato salvato." + +#: part/ktreeviewsearchline.cpp:286 +#, kde-format +msgid "Search Options" +msgstr "Opzioni di ricerca" + +#: part/ktreeviewsearchline.cpp:287 +#, kde-format +msgctxt "Enable case sensitive search in the side navigation panels" +msgid "Case Sensitive" +msgstr "Distingui maiuscole" + +#: part/ktreeviewsearchline.cpp:290 +#, kde-format +msgctxt "Enable regular expression search in the side navigation panels" +msgid "Regular Expression" +msgstr "Espressione regolare" + +#: part/ktreeviewsearchline.cpp:388 +#, kde-format +msgid "S&earch:" +msgstr "C&erca:" + +#: part/layers.cpp:38 part/part.cpp:2172 +#, kde-format +msgid "Layers" +msgstr "Livelli" + +#: part/minibar.cpp:179 +#, kde-format +msgctxt "Layouted like: '5 [pages] of 10'" +msgid "of" +msgstr "di" + +#: part/pageview.cpp:526 +#, kde-format +msgid "Zoom" +msgstr "Zoom" + +#: part/pageview.cpp:538 +#, kde-format +msgid "Zoom to 100%" +msgstr "Ingrandisci al 100%" + +#: part/pageview.cpp:549 +#, kde-format +msgid "Rotate &Right" +msgstr "Ruota a dest&ra" + +#: part/pageview.cpp:550 +#, kde-format +msgctxt "Rotate right" +msgid "Right" +msgstr "Destra" + +#: part/pageview.cpp:554 +#, kde-format +msgid "Rotate &Left" +msgstr "Ruota a &sinistra" + +#: part/pageview.cpp:555 +#, kde-format +msgctxt "Rotate left" +msgid "Left" +msgstr "Sinistra" + +#: part/pageview.cpp:559 +#, kde-format +msgid "Original Orientation" +msgstr "Orientazione iniziale" + +#: part/pageview.cpp:565 +#, kde-format +msgid "&Trim View" +msgstr "Ri&taglia vista" + +#: part/pageview.cpp:569 +#, kde-format +msgid "&Trim Margins" +msgstr "Ri&taglia margini" + +#: part/pageview.cpp:576 +#, kde-format +msgid "Trim To &Selection" +msgstr "Ritaglia alla &selezione" + +#: part/pageview.cpp:582 +#, kde-format +msgid "Fit &Width" +msgstr "Larg&hezza pagina" + +#: part/pageview.cpp:586 +#, kde-format +msgid "Fit &Page" +msgstr "&Pagina intera" + +#: part/pageview.cpp:590 +#, kde-format +msgid "&Auto Fit" +msgstr "&Adattamento automatico" + +#: part/pageview.cpp:594 +#, kde-format +msgid "Fit Wi&ndow to Page" +msgstr "Adatta fi&nestra alla pagina" + +#: part/pageview.cpp:601 +#, kde-format +msgid "&View Mode" +msgstr "Modalità di &visualizzazione" + +#: part/pageview.cpp:613 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Single Page" +msgstr "Pagina &singola" + +#: part/pageview.cpp:614 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Facing Pages" +msgstr "Pagine a&ffiancate" + +#: part/pageview.cpp:615 +#, kde-format +msgctxt "@item:inmenu" +msgid "Facing Pages (&Center First Page)" +msgstr "Pagine affiancate (¢ra la prima pagina)" + +#: part/pageview.cpp:618 +#, kde-format +msgctxt "@item:inmenu" +msgid "&Overview" +msgstr "Pan&oramica" + +#: part/pageview.cpp:630 +#, kde-format +msgid "&Continuous" +msgstr "&Continua" + +#: part/pageview.cpp:637 +#, kde-format +msgctxt "@action page layout" +msgid "Use Right to Left Reading Direction" +msgstr "Usa la direzione di lettura da destra a sinistra" + +#: part/pageview.cpp:646 +#, kde-format +msgid "&Browse" +msgstr "Navi&gazione" + +#: part/pageview.cpp:654 +#, kde-format +msgid "&Zoom" +msgstr "&Zoom" + +#: part/pageview.cpp:662 +#, kde-format +msgid "&Toggle Change Colors" +msgstr "Attiva/disattiva l'opzione «Cambia colori»" + +#: part/pageview.cpp:676 +#, kde-format +msgid "Area &Selection" +msgstr "&Selezione area" + +#: part/pageview.cpp:685 +#, kde-format +msgid "&Text Selection" +msgstr "Selezione &testo" + +#: part/pageview.cpp:693 +#, kde-format +msgid "T&able Selection" +msgstr "Selezione t&abella" + +#: part/pageview.cpp:701 +#, kde-format +msgid "&Magnifier" +msgstr "&Lente d'ingrandimento" + +#: part/pageview.cpp:715 +#, kde-format +msgctxt "@action" +msgid "Selection Tools" +msgstr "Strumenti di selezione" + +#: part/pageview.cpp:720 +#, kde-format +msgid "Speak Whole Document" +msgstr "Leggi tutto il documento" + +#: part/pageview.cpp:725 +#, kde-format +msgid "Speak Current Page" +msgstr "Leggi la pagina corrente" + +#: part/pageview.cpp:730 +#, kde-format +msgid "Stop Speaking" +msgstr "Interrompi lettura" + +#: part/pageview.cpp:735 +#, kde-format +msgid "Pause/Resume Speaking" +msgstr "Metti in pausa/riprendi lettura" + +#: part/pageview.cpp:747 +#, kde-format +msgid "Scroll Up" +msgstr "Scorri in su" + +#: part/pageview.cpp:753 +#, kde-format +msgid "Scroll Down" +msgstr "Scorri in giù" + +#: part/pageview.cpp:759 +#, kde-format +msgid "Scroll Page Up" +msgstr "Scorri una pagina in su" + +#: part/pageview.cpp:765 +#, kde-format +msgid "Scroll Page Down" +msgstr "Scorri una pagina in giù" + +#: part/pageview.cpp:771 +#, kde-format +msgid "Show Forms" +msgstr "Mostra moduli" + +#: part/pageview.cpp:1144 +#, kde-format +msgid " Loaded a one-page document." +msgid_plural " Loaded a %1-page document." +msgstr[0] "Caricato un documento con una pagina." +msgstr[1] "Caricato un documento con %1 pagine." + +#: part/pageview.cpp:2655 +#, kde-format +msgid "Text (1 character)" +msgid_plural "Text (%1 characters)" +msgstr[0] "Testo (1 carattere)" +msgstr[1] "Testo (%1 caratteri)" + +#: part/pageview.cpp:2656 part/pageview.cpp:2673 +#, kde-format +msgid "Copy to Clipboard" +msgstr "Copia negli appunti" + +#: part/pageview.cpp:2661 part/pageview.cpp:2799 part/pageview.cpp:2919 +#, kde-format +msgid "Copy forbidden by DRM" +msgstr "Copia non permessa dal DRM" + +#: part/pageview.cpp:2665 part/pageview.cpp:2915 +#, kde-format +msgid "Speak Text" +msgstr "Pronuncia il testo" + +#: part/pageview.cpp:2672 +#, kde-format +msgid "Image (%1 by %2 pixels)" +msgstr "Immagine (%1 per %2 pixel)" + +#: part/pageview.cpp:2674 +#, kde-format +msgid "Save to File..." +msgstr "Salva su file..." + +#: part/pageview.cpp:2693 +#, kde-format +msgid "Image [%1x%2] copied to clipboard." +msgstr "Immagine [%1x%2] copiata negli appunti." + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Save file" +msgstr "Salva file" + +#: part/pageview.cpp:2696 +#, kde-format +msgid "Images (*.png *.jpeg)" +msgstr "Immagini (*.png *.jpeg)" + +#: part/pageview.cpp:2698 +#, kde-format +msgid "File not saved." +msgstr "Il file non è stato salvato." + +#: part/pageview.cpp:2708 +#, kde-format +msgid "Image [%1x%2] saved to %3 file." +msgstr "Immagine [%1x%2] salvata sul file %3." + +#: part/pageview.cpp:2911 +#, kde-format +msgid "Copy Text" +msgstr "Copia il testo" + +#: part/pageview.cpp:2930 +#, kde-format +msgid "Go to '%1'" +msgstr "Vai a «%1»" + +#: part/pageview.cpp:4135 +#, kde-format +msgid "Search for '%1' with" +msgstr "Ricerca di «%1» con" + +#: part/pageview.cpp:4149 +#, kde-format +msgid "Configure Web Shortcuts..." +msgstr "Configura scorciatoie web..." + +#: part/pageview.cpp:4174 +#, kde-format +msgid "Follow This Link" +msgstr "Segui questo collegamento" + +#: part/pageview.cpp:4177 +#, kde-format +msgid "Play this Sound" +msgstr "Riproduci questo suono" + +#: part/pageview.cpp:4179 +#, kde-format +msgid "Stop Sound" +msgstr "Ferma il suono" + +#: part/pageview.cpp:4185 +#, kde-format +msgid "Copy Link Address" +msgstr "Copia indirizzo collegamento" + +#: part/pageview.cpp:4205 +#, kde-format +msgid "Search for '%1' in this document" +msgstr "Cerca «%1» in questo documento" + +#: part/pageview.cpp:4616 +#, kde-format +msgid "Welcome" +msgstr "Benvenuto" + +#: part/pageview.cpp:4736 +#, kde-format +msgid "Select zooming area. Right-click to zoom out." +msgstr "" +"Seleziona la regione da ingrandire. Fai clic con il pulsante destro per " +"rimpicciolire." + +#: part/pageview.cpp:4746 +#, kde-format +msgid "Click to see the magnified view." +msgstr "Fai clic per la vista ingrandita." + +#: part/pageview.cpp:4758 +#, kde-format +msgid "Draw a rectangle around the text/graphics to copy." +msgstr "Seleziona la regione di testo o grafica da copiare." + +#: part/pageview.cpp:4769 +#, kde-format +msgid "Select text" +msgstr "Seleziona il testo" + +#: part/pageview.cpp:4780 +#, kde-format +msgid "" +"Draw a rectangle around the table, then click near edges to divide up; press " +"Esc to clear." +msgstr "" +"Traccia un rettangolo attorno alla tabella, quindi fai clic vicino ai bordi " +"per suddividerla; premi Esc per annullare." + +#: part/pageview.cpp:4911 +#, kde-format +msgid "Draw a rectangle around the page area you wish to keep visible" +msgstr "Seleziona l'area della pagina che vuoi mantenere visibile" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "New Text Note" +msgstr "Nuova nota di testo" + +#: part/pageviewannotator.cpp:203 part/pageviewannotator.cpp:208 +#, kde-format +msgid "Text of the new note:" +msgstr "Testo della nuova nota:" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Bookmark annotation" +msgstr "Annotazione segnalibro" + +#: part/pageviewannotator.cpp:963 +#, kde-format +msgid "Insert a custom name for the annotation:" +msgstr "Inserisci un nome personalizzato per l'annotazione:" + +#: part/pageviewannotator.cpp:1021 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw an ellipse (drag to select a zone)" +msgstr "Disegna un'ellisse (trascina per selezionare una zona)" + +#: part/pageviewannotator.cpp:1023 +#, kde-format +msgctxt "Annotation tool" +msgid "Highlight text" +msgstr "Testo evidenziato" + +#: part/pageviewannotator.cpp:1025 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a freehand line" +msgstr "Traccia una linea a mano libera" + +#: part/pageviewannotator.cpp:1027 +#, kde-format +msgctxt "Annotation tool" +msgid "Inline Text Annotation (drag to select a zone)" +msgstr "Annotazione di testo in linea (trascina per selezionare una zona)" + +#: part/pageviewannotator.cpp:1029 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a pop-up note" +msgstr "Inserisci una nota a comparsa" + +#: part/pageviewannotator.cpp:1031 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a polygon (click on the first point to close it)" +msgstr "Disegna un poligono (clic sul primo punto per chiuderlo)" + +#: part/pageviewannotator.cpp:1033 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a rectangle" +msgstr "Disegna un rettangolo" + +#: part/pageviewannotator.cpp:1035 +#, kde-format +msgctxt "Annotation tool" +msgid "Squiggle text" +msgstr "Testo scarabocchiato" + +#: part/pageviewannotator.cpp:1037 +#, kde-format +msgctxt "Annotation tool" +msgid "Put a stamp symbol" +msgstr "Inserisci un timbro" + +#: part/pageviewannotator.cpp:1039 +#, kde-format +msgctxt "Annotation tool" +msgid "Draw a straight line" +msgstr "Disegna una linea retta" + +#: part/pageviewannotator.cpp:1041 +#, kde-format +msgctxt "Annotation tool" +msgid "Strike out text" +msgstr "Barra il testo" + +#: part/pageviewannotator.cpp:1043 +#, kde-format +msgctxt "Annotation tool" +msgid "Underline text" +msgstr "Sottolinea il testo" + +#: part/pageviewannotator.cpp:1045 +#, kde-format +msgctxt "Annotation tool" +msgid "Typewriter Annotation (drag to select a zone)" +msgstr "Annotazione macchina da scrivere (trascina per selezionare una zona)" + +#: part/pageviewannotator.cpp:1089 +#, kde-format +msgid "Highlighter" +msgstr "Evidenziatore" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Add favorite annotation" +msgstr "Aggiungi annotazione preferita" + +#: part/pageviewannotator.cpp:1389 +#, kde-format +msgid "Custom annotation name:" +msgstr "Nome annotazione personalizzato:" + +#. i18n: ectx: Menu (file) +#: part/part-viewermode.rc:5 part/part.rc:4 +#, kde-format +msgid "&File" +msgstr "&File" + +#. i18n: ectx: Menu (settings) +#: part/part-viewermode.rc:9 part/part.rc:87 +#, kde-format +msgid "&Settings" +msgstr "Imp&ostazioni" + +#. i18n: ectx: Menu (help) +#: part/part-viewermode.rc:14 part/part.rc:93 +#, kde-format +msgid "&Help" +msgstr "Ai&uto" + +#. i18n: ectx: Menu (view_orientation) +#: part/part-viewermode.rc:31 part/part.rc:43 +#, kde-format +msgid "&Orientation" +msgstr "&Orientazione" + +#. i18n: ectx: Menu (bookmarks) +#. i18n: ectx: Menu (okular_bookmarks) +#: part/part-viewermode.rc:49 part/part.rc:64 +#, kde-format +msgid "&Bookmarks" +msgstr "Segnali&bri" + +#. i18n: ectx: ToolBar (OkularViewerToolBar) +#: part/part-viewermode.rc:62 +#, kde-format +msgid "Viewer Toolbar" +msgstr "Barra degli strumenti visualizzazione" + +#: part/part.cpp:432 part/thumbnaillist.cpp:51 +#, kde-format +msgid "Thumbnails" +msgstr "Miniature" + +#: part/part.cpp:438 part/preferencesdialog.cpp:50 part/side_reviews.cpp:101 +#, kde-format +msgid "Annotations" +msgstr "Annotazioni" + +#: part/part.cpp:480 +#, kde-format +msgid "" +"This document contains annotations or form data that were saved internally " +"by a previous Okular version. Internal storage is no longer supported." +"
    Please save to a file in order to move them if you want to continue to " +"edit the document." +msgstr "" +"Il documento contiene annotazioni o dati di moduli che sono stati salvati " +"internamente da una versione precedente di Okular. Il salvataggio interno " +"non è più supportato.
    Salva il file per poterlo spostare se vuoi " +"continuare a modificare il documento." + +#: part/part.cpp:487 +#, kde-format +msgid "" +"This document has embedded files. Click " +"here to see them or go to File -> Embedded Files." +msgstr "" +"Questo documento contiene allegati. Fai " +"clic qui per visualizzarli o seleziona File -> Allegati." + +#: part/part.cpp:643 +#, kde-format +msgctxt "Previous page" +msgid "Previous" +msgstr "Precedente" + +#: part/part.cpp:644 +#, kde-format +msgid "Go back to the Previous Page" +msgstr "Vai indietro alla pagina precedente" + +#: part/part.cpp:645 +#, kde-format +msgid "Moves to the previous page of the document" +msgstr "Vai alla pagina precedente nel documento" + +#: part/part.cpp:655 +#, kde-format +msgctxt "Next page" +msgid "Next" +msgstr "Successiva" + +#: part/part.cpp:656 +#, kde-format +msgid "Advance to the Next Page" +msgstr "Procedi alla pagina successiva" + +#: part/part.cpp:657 +#, kde-format +msgid "Moves to the next page of the document" +msgstr "Vai alla pagina successiva nel documento" + +#: part/part.cpp:668 +#, kde-format +msgid "Beginning of the document" +msgstr "Inizio del documento" + +#: part/part.cpp:669 +#, kde-format +msgid "Moves to the beginning of the document" +msgstr "Vai all'inizio del documento" + +#: part/part.cpp:673 +#, kde-format +msgid "End of the document" +msgstr "Fine del documento" + +#: part/part.cpp:674 +#, kde-format +msgid "Moves to the end of the document" +msgstr "Vai alla fine del documento" + +#: part/part.cpp:687 +#, kde-format +msgid "Rename the current bookmark" +msgstr "Rinomina il segnalibro attuale" + +#: part/part.cpp:691 +#, kde-format +msgid "Previous Bookmark" +msgstr "Segnalibro precedente" + +#: part/part.cpp:693 +#, kde-format +msgid "Go to the previous bookmark" +msgstr "Vai al segnalibro precedente" + +#: part/part.cpp:697 +#, kde-format +msgid "Next Bookmark" +msgstr "Segnalibro successivo" + +#: part/part.cpp:699 +#, kde-format +msgid "Go to the next bookmark" +msgstr "Vai al segnalibro successivo" + +#: part/part.cpp:726 +#, kde-format +msgid "Configure Okular..." +msgstr "Configura Okular..." + +#: part/part.cpp:729 +#, kde-format +msgid "Configure Viewer..." +msgstr "Configura visualizzatore..." + +#: part/part.cpp:735 +#, kde-format +msgid "Configure Viewer Backends..." +msgstr "Configura backend visualizzazione..." + +#: part/part.cpp:737 +#, kde-format +msgid "Configure Backends..." +msgstr "Configura backend..." + +#: part/part.cpp:773 +#, kde-format +msgid "About Backend" +msgstr "Informazioni sul backend" + +#: part/part.cpp:778 +#, kde-format +msgid "Reloa&d" +msgstr "&Ricarica" + +#: part/part.cpp:780 +#, kde-format +msgid "Reload the current document from disk." +msgstr "Ricarica il documento corrente dal disco." + +#: part/part.cpp:786 +#, kde-format +msgid "Close &Find Bar" +msgstr "Chiudi la &barra di ricerca" + +#: part/part.cpp:791 +#, kde-format +msgid "Page Number" +msgstr "Numero pagina" + +#: part/part.cpp:827 +#, kde-format +msgid "Select All Text on Current Page" +msgstr "Seleziona tutto il testo della pagina corrente" + +#: part/part.cpp:840 +#, kde-format +msgid "Show S&idebar" +msgstr "Mostra la barra lat&erale" + +#: part/part.cpp:848 +#, kde-format +msgid "Show &Page Bar" +msgstr "Mostra la barra delle &pagine" + +#: part/part.cpp:854 +#, kde-format +msgid "Show &Signatures Panel" +msgstr "Mostra il pannello delle &firme" + +#: part/part.cpp:864 +#, kde-format +msgid "&Embedded Files" +msgstr "All&egati" + +#: part/part.cpp:870 +#, kde-format +msgid "E&xport As" +msgstr "Esp&orta come" + +#: part/part.cpp:882 +#, kde-format +msgid "S&hare" +msgstr "Cond&ividi" + +#: part/part.cpp:891 +#, kde-format +msgid "P&resentation" +msgstr "P&resentazione" + +#: part/part.cpp:898 +#, kde-format +msgid "Open Con&taining Folder" +msgstr "Apri cartella con&tenitore" + +#: part/part.cpp:904 +#, kde-format +msgid "&Import PostScript as PDF..." +msgstr "&Importa PostScript come PDF..." + +#: part/part.cpp:909 +#, kde-format +msgid "&Get Books From Internet..." +msgstr "Scarica li&bri da Internet..." + +#: part/part.cpp:914 +#, kde-format +msgid "Switch Blackscreen Mode" +msgstr "Attiva/disattiva modalità schermo nero" + +#: part/part.cpp:922 +#, kde-format +msgid "Erase Drawing" +msgstr "Cancella disegno" + +#: part/part.cpp:927 +#, kde-format +msgid "Configure Annotations..." +msgstr "Configura annotazioni..." + +#: part/part.cpp:932 +#, kde-format +msgid "Play/Pause Presentation" +msgstr "Riproduci/metti in pausa la presentazione" + +#: part/part.cpp:1092 +#, kde-format +msgid "Could not open '%1' (%2) " +msgstr "Impossibile aprire «%1» (%2)" + +#: part/part.cpp:1142 +#, kde-format +msgid "The loading of %1 has been canceled." +msgstr "Il caricamento di %1 è stato annullato." + +#: part/part.cpp:1158 +#, kde-format +msgid "Could not open %1. Reason: %2" +msgstr "Impossibile aprire %1. Motivo: %2" + +#: part/part.cpp:1186 +#, kde-format +msgid "Configure Viewer Backends" +msgstr "Configura backend visualizzazione" + +#: part/part.cpp:1188 +#, kde-format +msgid "Configure Backends" +msgstr "Configura backend" + +#: part/part.cpp:1268 +#, kde-format +msgid "" +"The program \"ps2pdf\" was not found, so Okular can not import PS files " +"using it." +msgstr "" +"Il programma «ps2pdf» non è stato trovato, di conseguenza Okular non può " +"importare file PS tramite tale programma." + +#: part/part.cpp:1268 +#, kde-format +msgid "ps2pdf not found" +msgstr "ps2pdf non trovato" + +#: part/part.cpp:1273 +#, kde-format +msgid "PostScript files (%1)" +msgstr "File PostScript (%1)" + +#: part/part.cpp:1288 +#, kde-format +msgid "Importing PS file as PDF (this may take a while)..." +msgstr "" +"Importazione di file PS come PDF (potrebbe richiedere un po' di tempo)..." + +#: part/part.cpp:1409 +#, kde-format +msgid "Please enter the password to read the document:" +msgstr "Inserisci la password per leggere il documento:" + +#: part/part.cpp:1411 +#, kde-format +msgid "Incorrect password. Try again:" +msgstr "Password non corretta. Riprova:" + +#: part/part.cpp:1416 +#, kde-format +msgid "Document Password" +msgstr "Password del documento" + +#: part/part.cpp:1519 +#, kde-format +msgid "This document has XFA forms, which are currently unsupported." +msgstr "" +"Questo documento contiene moduli XFA, che attualmente sono non " +"supportati." + +#: part/part.cpp:1526 +#, kde-format +msgid "" +"This document has forms. Click on the button to interact with them, or use " +"View -> Show Forms." +msgstr "" +"Questo documento contiene dei moduli. Fai clic sul pulsante per interagire " +"con essi, oppure seleziona Visualizza -> Mostra moduli." + +#: part/part.cpp:1546 +#, kde-format +msgid "" +"All editing and interactive features for this document are disabled. Please " +"save a copy and reopen to edit this document." +msgstr "" +"La modifica e le funzioni interattive di questo documento sono tutte " +"disabilitate. Per modificare questo documento, salvane una copia e riaprilo." + +#: part/part.cpp:1560 +#, kde-format +msgid "This document is digitally signed." +msgstr "Questo documento è firmato digitalmente." + +#: part/part.cpp:1563 +#, kde-format +msgid "" +"This document is digitally signed. There have been changes since last signed." +msgstr "" +"Questo documento è firmato digitalmente. Ci sono state delle modifiche da " +"quando è stato firmato." + +#: part/part.cpp:1567 +#, kde-format +msgid "" +"This document is digitally signed. Some of the signatures could not be " +"validated properly." +msgstr "" +"Questo documento è firmato digitalmente. Alcune delle firme non possono " +"essere validate correttamente." + +#: part/part.cpp:1644 +#, kde-format +msgid "" +"This document wants to be shown full screen.\n" +"Leave normal mode and enter presentation mode?" +msgstr "" +"Questo documento vuole essere mostrato a tutto schermo.\n" +"Lasciare la modalità attuale e passare in modalità presentazione?" + +#: part/part.cpp:1646 +#, kde-format +msgid "Request to Change Viewing Mode" +msgstr "Richiesta di modifica modalità di visualizzazione" + +#: part/part.cpp:1647 +#, kde-format +msgid "Enter Presentation Mode" +msgstr "Passa in modalità presentazione" + +#: part/part.cpp:1648 +#, kde-format +msgid "Deny Request" +msgstr "Blocca la richiesta" + +#: part/part.cpp:1734 +#, kde-format +msgid "Could not open %1. %2" +msgstr "Impossibile aprire %1. %2" + +#: part/part.cpp:1763 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
    Do you want to continue reloading the file?" +msgstr "" +"Ci sono modifiche non salvate, il file «%1» è stato modificato da un altro " +"programma. Le tue modifiche saranno perse perché il file non può più essere " +"salvato.
    Vuoi procedere con la ricarica del file?" + +#: part/part.cpp:1764 part/part.cpp:1771 part/part.cpp:2492 +#, kde-format +msgid "File Changed" +msgstr "File modificato" + +#: part/part.cpp:1765 +#, kde-format +msgid "Continue Reloading" +msgstr "Continua la ricarica" + +#: part/part.cpp:1766 +#, kde-format +msgid "Abort Reloading" +msgstr "Interrompi la ricarica" + +#: part/part.cpp:1770 +#, kde-format +msgid "" +"There are unsaved changes, and the file '%1' has been modified by another " +"program. Your changes will be lost, because the file can no longer be saved." +"
    Do you want to continue closing the file?" +msgstr "" +"Ci sono modifiche non salvate, il file «%1» è stato modificato da un altro " +"programma. Le tue modifiche saranno perse perché il file non può più essere " +"salvato.
    Vuoi procedere con la chiusura del file?" + +#: part/part.cpp:1772 +#, kde-format +msgid "Continue Closing" +msgstr "Continua con la chiusura" + +#: part/part.cpp:1773 +#, kde-format +msgid "Abort Closing" +msgstr "Interrompi la chiusura" + +#: part/part.cpp:1778 +#, kde-format +msgid "Do you want to save your changes to \"%1\" or discard them?" +msgstr "Vuoi salvare le modifiche ad «%1» o scartarle?" + +#: part/part.cpp:1778 +#, kde-format +msgid "Close Document" +msgstr "Chiudi documento" + +#: part/part.cpp:1897 +#, kde-format +msgid "" +"This link points to a close document action that does not work when using " +"the embedded viewer." +msgstr "" +"Questo collegamento punta ad un'azione di chiusura del documento che non " +"funziona quando si usa il visualizzatore in modalità integrata." + +#: part/part.cpp:1902 +#, kde-format +msgid "" +"This link points to a quit application action that does not work when using " +"the embedded viewer." +msgstr "" +"Questo collegamento punta ad un'azione di chiusura dell'applicazione che non " +"funziona quando si usa il visualizzatore in modalità integrata." + +#: part/part.cpp:1992 part/part.cpp:2009 +#, kde-format +msgid "Reloading the document..." +msgstr "Riapertura del documento..." + +#: part/part.cpp:2152 part/toc.cpp:41 +#, kde-format +msgid "Contents" +msgstr "Contenuti" + +#: part/part.cpp:2181 part/signaturepanel.cpp:50 +#, kde-format +msgid "Signatures" +msgstr "Firme" + +#: part/part.cpp:2208 +#, kde-format +msgid "Go to Page" +msgstr "Vai alla pagina" + +#: part/part.cpp:2231 +#, kde-format +msgid "&Page:" +msgstr "&Pagina:" + +#: part/part.cpp:2321 +#, kde-format +msgid "Enter the new name of the bookmark:" +msgstr "Inserisci il nuovo nome del segnalibro:" + +#: part/part.cpp:2367 +#, kde-format +msgid "Rename this Bookmark" +msgstr "Rinomina questo segnalibro" + +#: part/part.cpp:2370 +#, kde-format +msgid "Remove this Bookmark" +msgstr "Rimuovi questo segnalibro" + +#: part/part.cpp:2451 part/part.cpp:2452 part/part.cpp:3098 +#, kde-format +msgctxt "File type name and pattern" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/part.cpp:2459 part/revisionviewer.cpp:47 +#, kde-format +msgid "Save As" +msgstr "Salva come" + +#: part/part.cpp:2492 +#, kde-format +msgid "" +"The file '%1' has been modified by another program, which means it can no " +"longer be saved." +msgstr "" +"Il file «%1» è stato modificato da un altro programma, e pertanto non può " +"più essere salvato." + +#: part/part.cpp:2500 +#, kde-format +msgid "" +"The current document is protected with a password.
    In order to save, " +"the file needs to be reloaded. You will be asked for the password again and " +"your undo/redo history will be lost.
    Do you want to continue?" +msgstr "" +"Il documento attuale è protetto da una password.
    Per poterlo salvare, " +"il file deve essere ricaricato. Ti verrà richiesta nuovamente la password e " +"la cronologia delle azioni verrà persa.
    Vuoi continuare?" + +#: part/part.cpp:2501 part/part.cpp:2533 +#, kde-format +msgid "Save - Warning" +msgstr "Salva - Avviso" + +#: part/part.cpp:2518 +#, kde-format +msgid "Could not open the temporary file for saving." +msgstr "Impossibile aprire il file temporaneo per il salvataggio." + +#: part/part.cpp:2533 +#, kde-format +msgid "" +"After saving, the current document format requires the file to be reloaded. " +"Your undo/redo history will be lost.
    Do you want to continue?" +msgstr "" +"Dopo il salvataggio, il formato del documento attuale richiede che il file " +"sia caricato nuovamente. La cronologia delle azioni verrà persa.
    Vuoi " +"continuare?" + +#: part/part.cpp:2545 part/part.cpp:2611 part/part.cpp:2630 part/part.cpp:3113 +#, kde-format +msgid "File could not be saved in '%1'. Try to save it to another location." +msgstr "Impossibile salvare il file in «%1». Prova a salvarlo altrove." + +#: part/part.cpp:2557 +#, kde-format +msgid "Filled form contents" +msgstr "Contenuti dei moduli compilati" + +#: part/part.cpp:2559 +#, kde-format +msgid "User annotations" +msgstr "Annotazioni utente" + +#: part/part.cpp:2563 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them." +msgstr "" +"Stai per salvare le modifiche, ma il formato del file attuale non supporta " +"il salvataggio dei seguenti elementi. Usa il formato Archivio di " +"documento Okular per preservarli." + +#: part/part.cpp:2567 part/part.cpp:2589 +#, kde-format +msgid "Warning" +msgstr "Avviso" + +#: part/part.cpp:2568 part/part.cpp:2590 +#, kde-format +msgid "Save as Okular document archive..." +msgstr "Salva come archivio di documento Okular..." + +#: part/part.cpp:2580 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save the document and " +"discard these elements." +msgstr "" +"Stai per salvare le modifiche, ma il formato del file attuale non supporta " +"il salvataggio dei seguenti elementi. Usa il formato Archivio di " +"documento Okular per preservarli. Fai clic su Continua per " +"salvare il documento e scartare tali elementi." + +#: part/part.cpp:2583 +#, kde-format +msgid "" +"You are about to save changes, but the current file format does not support " +"saving the following elements. Please use the Okular document archive " +"format to preserve them. Click Continue to save, but you will lose " +"these elements as well as the undo/redo history." +msgstr "" +"Stai per salvare le modifiche, ma il formato del file attuale non supporta " +"il salvataggio dei seguenti elementi. Usa il formato Archivio di " +"documento Okular per preservarli. Fai clic su Continua per " +"salvare, ma perderai questi elementi oltre alla cronologia delle azioni." + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue" +msgstr "Continua" + +#: part/part.cpp:2585 +#, kde-format +msgid "Continue losing changes" +msgstr "Continua perdendo le modifiche" + +#: part/part.cpp:2613 +#, kde-format +msgid "File could not be saved in '%1'. %2" +msgstr "Impossibile salvare il file in «%1». %2" + +#: part/part.cpp:2649 +#, kde-format +msgid "" +"Okular cannot copy %1 to the specified location.\n" +"\n" +"The document does not exist anymore." +msgstr "" +"Okular non può copiare «%1» nel percorso specificato.\n" +"\n" +"Il documento non esiste più." + +#: part/part.cpp:2677 +#, kde-format +msgid "" +"File could not be saved in '%1'. Error: '%2'. Try to save it to another " +"location." +msgstr "" +"Impossibile salvare il file in «%1». Errore: «%2». Prova a salvarlo altrove." + +#: part/part.cpp:2929 +#, kde-format +msgid "Expand whole section" +msgstr "Espandi l'intera sezione" + +#: part/part.cpp:2930 +#, kde-format +msgid "Collapse whole section" +msgstr "Richiudi l'intera sezione" + +#: part/part.cpp:2931 +#, kde-format +msgid "Expand all" +msgstr "Espandi tutto" + +#: part/part.cpp:2932 +#, kde-format +msgid "Collapse all" +msgstr "Richiudi tutto" + +#: part/part.cpp:2944 +#, kde-format +msgid "Add Bookmark" +msgstr "Aggiungi segnalibro" + +#: part/part.cpp:2953 +#, kde-format +msgid "Tools" +msgstr "Strumenti" + +#: part/part.cpp:3150 +#, kde-format +msgctxt "@title:window" +msgid "Print" +msgstr "Stampa" + +#: part/part.cpp:3214 +#, kde-format +msgid "Printing this document is not allowed." +msgstr "La stampa di questo documento non è permessa." + +#: part/part.cpp:3221 +#, kde-format +msgid "" +"Could not print the document. Unknown error. Please report to bugs.kde.org" +msgstr "" +"Non è stato possibile stampare il documento. Errore sconosciuto. Segnala il " +"problema su bugs.kde.org" + +#: part/part.cpp:3223 +#, kde-format +msgid "" +"Could not print the document. Detailed error is \"%1\". Please report to " +"bugs.kde.org" +msgstr "" +"Non è stato possibile stampare il documento. La descrizione dell'errore è " +"«%1». Segnala il problema su bugs.kde.org" + +#: part/part.cpp:3300 +#, kde-format +msgid "Go to the place you were before" +msgstr "Torna dove ti trovavi in precedenza" + +#: part/part.cpp:3304 +#, kde-format +msgid "Go to the place you were after" +msgstr "Vai dove sei andato successivamente" + +#: part/part.cpp:3329 +#, kde-format +msgid "" +"File Error! Could not create temporary file " +"%1." +msgstr "" +"Errore di file! Impossibile creare il file temporaneo " +"%1." + +#: part/part.cpp:3341 +#, kde-format +msgid "" +"File Error! Could not open the file %1 for uncompression. The file will not be loaded." +msgstr "" +"Errore di file! Impossibile aprire il file " +"%1 per la decompressione. Il file non sarà " +"caricato." + +#: part/part.cpp:3345 +#, kde-format +msgid "" +"This error typically occurs if you do not have enough permissions to " +"read the file. You can check ownership and permissions if you right-click on " +"the file in the Dolphin file manager, then choose the 'Properties' option, " +"and select 'Permissions' tab in the opened window." +msgstr "" +"Questo errore di solito compare se non si hanno sufficienti permessi di " +"lettura sul file. Puoi controllare il proprietario e i permessi facendo clic " +"con il tasto destro sul file dal file manager Dolphin e poi scegliendo la " +"voce del menu «Proprietà» e selezionando la scheda «Permessi» nella finestra " +"che si apre." + +#: part/part.cpp:3366 +#, kde-format +msgid "" +"File Error! Could not uncompress the file " +"%1. The file will not be loaded." +msgstr "" +"Errore di file! Impossibile decomprimere il file " +"%1. Il file non sarà caricato." + +#: part/part.cpp:3370 +#, kde-format +msgid "" +"This error typically occurs if the file is corrupt. If you want to be " +"sure, try to decompress the file manually using command-line tools." +msgstr "" +"Questo errore appare tipicamente se il file è danneggiato. Se vuoi " +"esserne sicuro, prova a decomprimere il file manualmente usando gli " +"strumenti a riga di comando." + +#: part/part.cpp:3396 +#, kde-format +msgid "No Bookmarks" +msgstr "Nessun segnalibro" + +#: part/part.cpp:3467 +#, kde-format +msgid "There was a problem sharing the document: %1" +msgstr "Si è verificato un problema durante la condivisione del documento: %1" + +#: part/part.cpp:3467 part/part.cpp:3473 +#, kde-format +msgid "Share" +msgstr "Condividi" + +#: part/part.cpp:3471 +#, kde-format +msgid "Document shared successfully" +msgstr "Documento condiviso correttamente" + +#: part/part.cpp:3473 +#, kde-format +msgid "You can find the shared document at: %1" +msgstr "Puoi trovare il documento condiviso presso: %1" + +#. i18n: ectx: Menu (edit) +#: part/part.rc:18 +#, kde-format +msgid "&Edit" +msgstr "&Modifica" + +#. i18n: ectx: Menu (view) +#: part/part.rc:31 +#, kde-format +msgid "&View" +msgstr "&Visualizza" + +#. i18n: ectx: Menu (go) +#: part/part.rc:52 +#, kde-format +msgid "&Go" +msgstr "&Vai" + +#. i18n: ectx: Menu (tools) +#: part/part.rc:72 +#, kde-format +msgid "&Tools" +msgstr "S&trumenti" + +#. i18n: ectx: ToolBar (mainToolBar) +#: part/part.rc:97 shell/shell.rc:23 +#, kde-format +msgid "Main Toolbar" +msgstr "Barra degli strumenti principale" + +#. i18n: ectx: ToolBar (annotationToolBar) +#: part/part.rc:110 +#, kde-format +msgid "Annotation Toolbar" +msgstr "Barra degli strumenti per le annotazioni" + +#: part/preferencesdialog.cpp:40 +#, kde-format +msgid "General Options" +msgstr "Opzioni generali" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility" +msgstr "Accessibilità" + +#: part/preferencesdialog.cpp:41 +#, kde-format +msgid "Accessibility Reading Aids" +msgstr "Aiuti di accessibilità alla lettura " + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance" +msgstr "Prestazioni" + +#: part/preferencesdialog.cpp:42 +#, kde-format +msgid "Performance Tuning" +msgstr "Regolazione delle prestazioni" + +#: part/preferencesdialog.cpp:44 +#, kde-format +msgid "Configure Viewer" +msgstr "Configura visualizzatore" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Presentation" +msgstr "Presentazione" + +#: part/preferencesdialog.cpp:49 +#, kde-format +msgid "Options for Presentation Mode" +msgstr "Opzioni per la modalità presentazione" + +#: part/preferencesdialog.cpp:50 +#, kde-format +msgid "Annotation Options" +msgstr "Opzioni annotazioni" + +#: part/preferencesdialog.cpp:51 +#, kde-format +msgid "Editor Options" +msgstr "Opzioni editor" + +#: part/presentationsearchbar.cpp:80 +#, kde-format +msgid "Find Next" +msgstr "Trova successivo" + +#: part/presentationwidget.cpp:169 +#, kde-format +msgctxt "[document title/filename] – Presentation" +msgid "%1 – Presentation" +msgstr "%1 – presentazione" + +#: part/presentationwidget.cpp:223 +#, kde-format +msgid "Switch Screen" +msgstr "Cambia schermo" + +#: part/presentationwidget.cpp:228 +#, kde-format +msgctxt "%1 is the screen number (0, 1, ...)" +msgid "Screen %1" +msgstr "Schermo %1" + +#: part/presentationwidget.cpp:235 +#, kde-format +msgid "Exit Presentation Mode" +msgstr "Esci dalla modalità presentazione" + +#: part/presentationwidget.cpp:367 +#, kde-format +msgid "Title: %1" +msgstr "Titolo: %1" + +#: part/presentationwidget.cpp:370 +#, kde-format +msgid "Pages: %1" +msgstr "Pagine: %1" + +#: part/presentationwidget.cpp:371 +#, kde-format +msgid "Click to begin" +msgstr "Fai clic per iniziare" + +#: part/presentationwidget.cpp:505 +#, kde-format +msgctxt "For Presentation" +msgid "Pause" +msgstr "Metti in pausa" + +#: part/presentationwidget.cpp:508 +#, kde-format +msgctxt "For Presentation" +msgid "Play" +msgstr "Riproduci" + +#: part/presentationwidget.cpp:1526 +#, kde-format +msgid "" +"There are two ways of exiting presentation mode, you can press either ESC " +"key or click with the quit button that appears when placing the mouse in the " +"top-right corner. Of course you can cycle windows (Alt+TAB by default)" +msgstr "" +"Ci sono due modi per uscire dalla modalità presentazione: puoi premere ESC " +"oppure puoi fare clic sul pulsante di uscita che compare quando posizioni il " +"mouse nell'angolo in alto a destra. Ovviamente puoi scorrere le finestre (Alt" +"+TAB è la combinazione predefinita)" + +#: part/presentationwidget.cpp:1609 +#, kde-format +msgctxt "" +"Reason for inhibiting the screensaver activation, when the presentation mode " +"is active" +msgid "Giving a presentation" +msgstr "Presentazione in corso" + +#: part/propertiesdialog.cpp:52 +#, kde-format +msgid "Unknown File" +msgstr "File sconosciuto" + +#: part/propertiesdialog.cpp:66 +#, kde-format +msgid "%1 Properties" +msgstr "Proprietà %1" + +#: part/propertiesdialog.cpp:106 +#, kde-format +msgctxt "mimetype information, example: \"PDF Document (application/pdf)\"" +msgid "%1 (%2)" +msgstr "%1 (%2)" + +#: part/propertiesdialog.cpp:119 +#, kde-format +msgid "%1:" +msgstr "%1:" + +#: part/propertiesdialog.cpp:126 +#, kde-format +msgid "&Fonts" +msgstr "&Caratteri" + +#: part/propertiesdialog.cpp:147 +#, kde-format +msgid "Reading font information..." +msgstr "Lettura delle informazioni sui caratteri..." + +#: part/propertiesdialog.cpp:160 +#, kde-format +msgid "&Page Sizes" +msgstr "Dimensioni &pagina" + +#: part/propertiesdialog.cpp:227 +#, kde-format +msgctxt "@action:inmenu" +msgid "&Extract Font" +msgstr "&Estrai carattere" + +#: part/propertiesdialog.cpp:274 +#, kde-format +msgid "Type 1" +msgstr "Tipo 1" + +#: part/propertiesdialog.cpp:277 +#, kde-format +msgid "Type 1C" +msgstr "Tipo 1C" + +#: part/propertiesdialog.cpp:280 +#, kde-format +msgctxt "OT means OpenType" +msgid "Type 1C (OT)" +msgstr "Tipo 1C (OpenType)" + +#: part/propertiesdialog.cpp:283 +#, kde-format +msgid "Type 3" +msgstr "Tipo 3" + +#: part/propertiesdialog.cpp:286 +#, kde-format +msgid "TrueType" +msgstr "TrueType" + +#: part/propertiesdialog.cpp:289 +#, kde-format +msgctxt "OT means OpenType" +msgid "TrueType (OT)" +msgstr "TrueType (OpenType)" + +#: part/propertiesdialog.cpp:292 +#, kde-format +msgid "CID Type 0" +msgstr "CID tipo 0" + +#: part/propertiesdialog.cpp:295 +#, kde-format +msgid "CID Type 0C" +msgstr "CID tipo 0C" + +#: part/propertiesdialog.cpp:298 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID Type 0C (OT)" +msgstr "CID tipo 0C (OpenType)" + +#: part/propertiesdialog.cpp:301 +#, kde-format +msgid "CID TrueType" +msgstr "CID TrueType" + +#: part/propertiesdialog.cpp:304 +#, kde-format +msgctxt "OT means OpenType" +msgid "CID TrueType (OT)" +msgstr "CID TrueType (OpenType)" + +#: part/propertiesdialog.cpp:307 +#, kde-format +msgid "TeX PK" +msgstr "TeX PK" + +#: part/propertiesdialog.cpp:310 +#, kde-format +msgid "TeX virtual" +msgstr "TeX virtuale" + +#: part/propertiesdialog.cpp:313 +#, kde-format +msgid "TeX Font Metric" +msgstr "Metrica dei caratteri TeX" + +#: part/propertiesdialog.cpp:316 +#, kde-format +msgid "TeX FreeType-handled" +msgstr "TeX, gestito da Freetype" + +#: part/propertiesdialog.cpp:319 +#, kde-format +msgctxt "Unknown font type" +msgid "Unknown" +msgstr "Sconosciuto" + +#: part/propertiesdialog.cpp:332 +#, kde-format +msgid "Embedded (subset)" +msgstr "Integrato (sottoinsieme)" + +#: part/propertiesdialog.cpp:335 +#, kde-format +msgid "Fully embedded" +msgstr "Totalmente integrato" + +#: part/propertiesdialog.cpp:345 +#, kde-format +msgid "No" +msgstr "No" + +#: part/propertiesdialog.cpp:348 +#, kde-format +msgid "Yes (subset)" +msgstr "Sì (sottoinsieme)" + +#: part/propertiesdialog.cpp:351 +#, kde-format +msgid "Yes" +msgstr "Sì" + +#: part/propertiesdialog.cpp:370 +#, kde-format +msgctxt "Replacing missing font with another one" +msgid "%1 (substituting with %2)" +msgstr "%1 (sostituito da %2)" + +#: part/propertiesdialog.cpp:372 +#, kde-format +msgctxt "font name not available (empty)" +msgid "[n/a]" +msgstr "[n/d]" + +#: part/propertiesdialog.cpp:386 +#, kde-format +msgid "Unknown font" +msgstr "Carattere sconosciuto" + +#: part/propertiesdialog.cpp:390 +#, kde-format +msgid "Embedded: %1" +msgstr "Integrato: %1" + +#: part/propertiesdialog.cpp:421 +#, kde-format +msgid "Name" +msgstr "Nome" + +#: part/propertiesdialog.cpp:424 +#, kde-format +msgid "Type" +msgstr "Tipo" + +#: part/propertiesdialog.cpp:427 +#, kde-format +msgid "File" +msgstr "File" + +#: part/propertiesdialog.cpp:489 +#, kde-format +msgid "Page" +msgstr "Pagina" + +#: part/propertiesdialog.cpp:492 +#, kde-format +msgid "Size" +msgstr "Dimensione" + +#: part/revisionviewer.cpp:44 +#, kde-format +msgid "Revision Preview" +msgstr "Anteprima della revisione" + +#: part/revisionviewer.cpp:56 +#, kde-format +msgid "Where do you want to save this revision?" +msgstr "Dove vuoi salvare questa revisione?" + +#: part/revisionviewer.cpp:59 +#, kde-format +msgid "Could not save file %1." +msgstr "Impossibile salvare il file %1." + +#: part/revisionviewer.cpp:78 +#, kde-format +msgid "Could not view revision." +msgstr "Impossibile visualizzare la revisione." + +#: part/searchwidget.cpp:41 +#, kde-format +msgid "Enter at least 3 letters to filter pages" +msgstr "Inserisci almeno 3 lettere per filtrare il testo" + +#: part/searchwidget.cpp:51 +#, kde-format +msgid "Case Sensitive" +msgstr "Distingui maiuscole" + +#: part/searchwidget.cpp:53 +#, kde-format +msgid "Match Phrase" +msgstr "Corrisponde frase" + +#: part/searchwidget.cpp:54 +#, kde-format +msgid "Match All Words" +msgstr "Corrispondono tutte le parole" + +#: part/searchwidget.cpp:55 +#, kde-format +msgid "Match Any Word" +msgstr "Corrisponde una parola qualsiasi" + +#: part/searchwidget.cpp:74 +#, kde-format +msgid "Filter Options" +msgstr "Opzioni filtro" + +#: part/side_reviews.cpp:68 +#, kde-format +msgid "" +"

    No annotations

    To create new annotations press F6 " +"or select Tools -> Annotations from the menu.
    " +msgstr "" +"

    Nessuna annotazione

    Per creare nuove annotazioni " +"premere F6 o selezionare Strumenti -> Annotazioni dal menu.
    " + +#: part/side_reviews.cpp:140 +#, kde-format +msgid "Group by Page" +msgstr "Raggruppa per pagina" + +#: part/side_reviews.cpp:145 +#, kde-format +msgid "Group by Author" +msgstr "Raggruppa per autore" + +#: part/side_reviews.cpp:153 +#, kde-format +msgid "Show annotations for current page only" +msgstr "Mostra le sole annotazioni della pagina corrente" + +#: part/side_reviews.cpp:163 +#, kde-format +msgid "Expand all elements" +msgstr "Espandi tutti gli elementi" + +#: part/side_reviews.cpp:165 +#, kde-format +msgid "Collapse all elements" +msgstr "Richiudi tutti gli elementi" + +#: part/signatureguiutils.cpp:40 +#, kde-format +msgid "The signature is cryptographically valid." +msgstr "La firma è crittograficamente valida." + +#: part/signatureguiutils.cpp:42 +#, kde-format +msgid "The signature is cryptographically invalid." +msgstr "La firma non è crittograficamente valida." + +#: part/signatureguiutils.cpp:44 +#, kde-format +msgid "Digest Mismatch occurred." +msgstr "Mancata corrispondenza dei sunti delle firme." + +#: part/signatureguiutils.cpp:46 +#, kde-format +msgid "The signature CMS/PKCS7 structure is malformed." +msgstr "La struttura CMS/PKCS7 della firma non è ben formata." + +#: part/signatureguiutils.cpp:48 +#, kde-format +msgid "The requested signature is not present in the document." +msgstr "La firma richiesta non è presente nel documento." + +#: part/signatureguiutils.cpp:50 +#, kde-format +msgid "The signature could not be verified." +msgstr "La firma non può essere verificata." + +#: part/signatureguiutils.cpp:58 +#, kde-format +msgid "Certificate is Trusted." +msgstr "Il certificato è affidabile." + +#: part/signatureguiutils.cpp:60 +#, kde-format +msgid "Certificate issuer isn't Trusted." +msgstr "L'emittente del certificato non è affidabile." + +#: part/signatureguiutils.cpp:62 +#, kde-format +msgid "Certificate issuer is unknown." +msgstr "L'emittente del certificato è sconosciuto." + +#: part/signatureguiutils.cpp:64 +#, kde-format +msgid "Certificate has been Revoked." +msgstr "Il certificato è stato revocato." + +#: part/signatureguiutils.cpp:66 +#, kde-format +msgid "Certificate has Expired." +msgstr "Il certificato è scaduto." + +#: part/signatureguiutils.cpp:68 +#, kde-format +msgid "Certificate has not yet been verified." +msgstr "Il certificato non è ancora stato verificato." + +#: part/signatureguiutils.cpp:70 +#, kde-format +msgid "Unknown issue with Certificate or corrupted data." +msgstr "Problema sconosciuto col certificato o dati danneggiati." + +#: part/signatureguiutils.cpp:78 +#, kde-format +msgid "MD2" +msgstr "MD2" + +#: part/signatureguiutils.cpp:80 +#, kde-format +msgid "MD5" +msgstr "MD5" + +#: part/signatureguiutils.cpp:82 +#, kde-format +msgid "SHA1" +msgstr "SHA1" + +#: part/signatureguiutils.cpp:84 +#, kde-format +msgid "SHA256" +msgstr "SHA256" + +#: part/signatureguiutils.cpp:86 +#, kde-format +msgid "SHA384" +msgstr "SHA384" + +#: part/signatureguiutils.cpp:88 +#, kde-format +msgid "SHA512" +msgstr "SHA512" + +#: part/signatureguiutils.cpp:90 +#, kde-format +msgid "SHA224" +msgstr "SHA224" + +#: part/signatureguiutils.cpp:92 +#, kde-format +msgid "Unknown Algorithm" +msgstr "Algoritmi sconosciuto" + +#: part/signatureguiutils.cpp:100 +#, kde-format +msgid "RSA" +msgstr "RSA" + +#: part/signatureguiutils.cpp:102 +#, kde-format +msgid "DSA" +msgstr "DSA" + +#: part/signatureguiutils.cpp:104 +#, kde-format +msgid "EC" +msgstr "EC" + +#: part/signatureguiutils.cpp:106 part/signatureguiutils.cpp:109 +#, kde-format +msgid "Unknown Type" +msgstr "Tipo sconosciuto" + +#: part/signatureguiutils.cpp:116 +#, kde-format +msgid "Digital Signature" +msgstr "Firma digitale" + +#: part/signatureguiutils.cpp:118 +#, kde-format +msgid "Non-Repudiation" +msgstr "Non ripudio" + +#: part/signatureguiutils.cpp:120 +#, kde-format +msgid "Encrypt Keys" +msgstr "Chiavi di cifratura" + +#: part/signatureguiutils.cpp:122 +#, kde-format +msgid "Decrypt Keys" +msgstr "Chiavi di decifrazione" + +#: part/signatureguiutils.cpp:124 +#, kde-format +msgid "Key Agreement" +msgstr "Accordo delle chiavi" + +#: part/signatureguiutils.cpp:126 +#, kde-format +msgid "Sign Certificate" +msgstr "Certificato di firma" + +#: part/signatureguiutils.cpp:128 +#, kde-format +msgid "Sign CRL" +msgstr "CRL di firma" + +#: part/signatureguiutils.cpp:130 +#, kde-format +msgid "Encrypt Only" +msgstr "Solo cifratura" + +#: part/signatureguiutils.cpp:132 +#, kde-format +msgid "No Usage Specified" +msgstr "Nessun uso specificato" + +#: part/signatureguiutils.cpp:138 +#, kde-format +msgctxt "Joins the various ways a signature key can be used in a longer string" +msgid ", " +msgstr ", " + +#: part/signaturemodel.cpp:136 +#, kde-format +msgid "Rev. %1: Signed By %2" +msgstr "Rev. %1: firmato da %2" + +#: part/signaturemodel.cpp:142 +#, kde-format +msgid "Signing Time: %1" +msgstr "Ora di firma: %1" + +#: part/signaturemodel.cpp:145 part/signaturepropertiesdialog.cpp:32 +#, kde-format +msgid "Not Available" +msgstr "Non disponibile" + +#: part/signaturemodel.cpp:145 +#, kde-format +msgid "Reason: %1" +msgstr "Motivo: %1" + +#: part/signaturemodel.cpp:148 +#, kde-format +msgid "Field: %1 on page %2" +msgstr "Campo: %1 a pagina %2" + +#: part/signaturepanel.cpp:97 +#, kde-format +msgid "Properties" +msgstr "Proprietà" + +#: part/signaturepropertiesdialog.cpp:55 +#, kde-format +msgid "The document has not been modified since it was signed." +msgstr "Il documento non è stato modificato dopo la firma." + +#: part/signaturepropertiesdialog.cpp:58 +#, kde-format +msgid "" +"The revision of the document that was covered by this signature has not been " +"modified;\n" +"however there have been subsequent changes to the document." +msgstr "" +"La revisione del documento che è coperta da questa firma non è stata " +"modificata;\n" +"tuttavia il documento è stato modificato successivamente." + +#: part/signaturepropertiesdialog.cpp:62 +#, kde-format +msgid "" +"The document has been modified in a way not permitted by a previous signer." +msgstr "" +"Il documento è stato modificato in un modo non permesso dal firmatario " +"precedente." + +#: part/signaturepropertiesdialog.cpp:64 +#, kde-format +msgid "The document integrity verification could not be completed." +msgstr "Impossibile completare la verifica dell'integrità del documento." + +#: part/signaturepropertiesdialog.cpp:67 +#, kde-format +msgid "Validity Status" +msgstr "Stato della validità" + +#: part/signaturepropertiesdialog.cpp:70 +#, kde-format +msgid "Signature Validity:" +msgstr "Validità della firma:" + +#: part/signaturepropertiesdialog.cpp:71 +#, kde-format +msgid "Document Modifications:" +msgstr "Modifiche del documento:" + +#: part/signaturepropertiesdialog.cpp:74 +#, kde-format +msgid "Additional Information" +msgstr "Ulteriori informazioni" + +#: part/signaturepropertiesdialog.cpp:77 +#, kde-format +msgid "Signed By:" +msgstr "Firmato da:" + +#: part/signaturepropertiesdialog.cpp:78 +#, kde-format +msgid "Signing Time:" +msgstr "Ora di firma:" + +#: part/signaturepropertiesdialog.cpp:79 +#, kde-format +msgid "Reason:" +msgstr "Motivo:" + +#: part/signaturepropertiesdialog.cpp:80 +#, kde-format +msgid "Location:" +msgstr "Posizione:" + +#: part/signaturepropertiesdialog.cpp:90 +#, kde-format +msgid "Document Version" +msgstr "Versione del documento" + +#: part/signaturepropertiesdialog.cpp:93 +#, kde-format +msgctxt "Document Revision of " +msgid "Document Revision %1 of %2" +msgstr "Revisione %1 di %2 del documento" + +#: part/signaturepropertiesdialog.cpp:95 +#, kde-format +msgid "View Signed Version..." +msgstr "Visualizza versione firmata..." + +#: part/signaturepropertiesdialog.cpp:102 +#, kde-format +msgid "View Certificate..." +msgstr "Visualizza certificato..." + +#: part/thumbnaillist.cpp:991 +#, kde-format +msgid "Show bookmarked pages only" +msgstr "Mostra solo le pagine segnate" + +#: part/videowidget.cpp:140 +#, kde-format +msgctxt "start the movie playback" +msgid "Play" +msgstr "Riproduci" + +#: part/videowidget.cpp:143 +#, kde-format +msgctxt "pause the movie playback" +msgid "Pause" +msgstr "Metti in pausa" + +#: part/videowidget.cpp:245 +#, kde-format +msgctxt "stop the movie playback" +msgid "Stop" +msgstr "Interrompi" + +#: part/widgetconfigurationtoolsbase.cpp:31 +#, kde-format +msgid "&Add..." +msgstr "&Aggiungi..." + +#: part/widgetconfigurationtoolsbase.cpp:34 +#, kde-format +msgid "&Edit..." +msgstr "&Modifica..." + +#: part/widgetconfigurationtoolsbase.cpp:38 +#, kde-format +msgid "&Remove" +msgstr "&Rimuovi" + +#: part/widgetconfigurationtoolsbase.cpp:42 +#, kde-format +msgid "Move &Up" +msgstr "Sposta in &alto" + +#: part/widgetconfigurationtoolsbase.cpp:46 +#, kde-format +msgid "Move &Down" +msgstr "Sposta in &basso" + +#: part/widgetdrawingtools.cpp:107 +#, kde-format +msgid "Default Drawing Tool #%1" +msgstr "Strumento di disegno predefinito #%1" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "There's already a tool with that name. Using a default one" +msgstr "" +"Esiste già uno strumento con questo nome. Viene usato il nome predefinito" + +#: part/widgetdrawingtools.cpp:140 part/widgetdrawingtools.cpp:183 +#, kde-format +msgid "Duplicated Name" +msgstr "Nome duplicato" + +#: shell/main.cpp:75 +#, kde-format +msgid "Page of the document to be shown" +msgstr "Pagine da visualizzazione del documento" + +#: shell/main.cpp:76 +#, kde-format +msgid "Start the document in presentation mode" +msgstr "Apre il documento in modalità presentazione" + +#: shell/main.cpp:77 +#, kde-format +msgid "Start with print dialog" +msgstr "Avvia mostrando la finestra di stampa" + +#: shell/main.cpp:78 +#, kde-format +msgid "Start with print dialog and exit after printing" +msgstr "Avvia mostrando la finestra di stampa e termina dopo la stampa" + +#: shell/main.cpp:79 +#, kde-format +msgid "\"Unique instance\" control" +msgstr "Controllo \"istanza unica\"" + +#: shell/main.cpp:80 +#, kde-format +msgid "Not raise window" +msgstr "Non alzare le finestra" + +#: shell/main.cpp:81 +#, kde-format +msgid "Find a string on the text" +msgstr "Trova una stringa nel testo" + +#: shell/main.cpp:82 +#, kde-format +msgid "Documents to open. Specify '-' to read from stdin." +msgstr "I documenti da aprire. Specifica '-' per leggere da standard input." + +#: shell/okular_main.cpp:124 +#, kde-format +msgid "Error: Can't open more than one document with the --unique switch" +msgstr "Errore: impossibile aprire più di un documento con l'opzione --unique" + +#: shell/okular_main.cpp:130 +#, kde-format +msgid "Error: Can't open more than one document with the --presentation switch" +msgstr "" +"Errore: impossibile aprire più di un documento con l'opzione --presentation" + +#: shell/okular_main.cpp:136 +#, kde-format +msgid "Error: Can't open more than one document with the --print switch" +msgstr "Errore: impossibile aprire più di un documento con l'opzione --print" + +#: shell/okular_main.cpp:142 +#, kde-format +msgid "Error: Can't open more than one document with the --page switch" +msgstr "Errore: impossibile aprire più di un documento con l'opzione --page" + +#: shell/okular_main.cpp:148 +#, kde-format +msgid "Error: Can't open more than one document with the --find switch" +msgstr "Errore: impossibile aprire più di un documento con l'opzione --find" + +#: shell/shell.cpp:95 +#, kde-format +msgid "Unable to find the Okular component: %1" +msgstr "Impossibile trovare il componente di Okular: %1" + +#: shell/shell.cpp:136 +#, kde-format +msgid "" +"There is already a unique Okular instance running. This instance won't be " +"the unique one." +msgstr "" +"C'è già in esecuzione un'unica istanza di Okular. Questa istanza non sarà " +"l'unica." + +#: shell/shell.cpp:148 +#, kde-format +msgid "Unable to find the Okular component." +msgstr "Impossibile trovare il componente di Okular." + +#: shell/shell.cpp:352 +#, kde-format +msgid "" +"Click to open a file\n" +"Click and hold to open a recent file" +msgstr "" +"Fai clic per aprire un file\n" +"Fai clic e tieni premuto per aprire un file recente" + +#: shell/shell.cpp:353 +#, kde-format +msgid "" +"Click to open a file or Click and hold to select a recent file" +msgstr "" +"Fai clic per aprire un file o Tieni premuto per selezionare un " +"file recente" + +#: shell/shell.cpp:366 +#, kde-format +msgid "Next Tab" +msgstr "Scheda successiva" + +#: shell/shell.cpp:372 +#, kde-format +msgid "Previous Tab" +msgstr "Scheda precedente" + +#: shell/shell.cpp:378 +#, kde-format +msgid "Undo close tab" +msgstr "Annulla chiusura scheda" + +#: shell/shell.cpp:493 +#, kde-format +msgid "All files (*)" +msgstr "Tutti i file (*)" + +#: shell/shell.cpp:494 +#, kde-format +msgid "All supported files (%1)" +msgstr "Tutti i file supportati (%1)" + +#: shell/shell.cpp:498 +#, kde-format +msgid "Open Document" +msgstr "Apri documento" + +#: shell/shell.cpp:595 +#, kde-format +msgid "Confirm Close" +msgstr "Conferma chiusura" + +#: shell/shell.cpp:599 +#, kde-format +msgid "Close Tabs" +msgstr "Chiudi schede" + +#: shell/shell.cpp:606 +#, kde-format +msgid "You are about to close %1 tabs. Are you sure you want to continue?" +msgstr "Stai per chiudere %1 schede. Sei sicuro di voler proseguire?" + +#: shell/shell.cpp:608 +#, kde-format +msgid "Warn me when I attempt to close multiple tabs" +msgstr "Avvisa quando cerco di chiudere più schede" + +#~ msgid "Reviews" +#~ msgstr "Revisioni" + +#~ msgctxt "@item:inlistbox Color name" +#~ msgid "%1" +#~ msgstr "%1" + +#~ msgid "Hide Forms" +#~ msgstr "Nascondi moduli" + +#~ msgid "Expired" +#~ msgstr "Scaduto" + +#~ msgid "&Review" +#~ msgstr "&Revisioni" + +#~ msgid "Annotations author" +#~ msgstr "Autore delle annotazioni" + +#~ msgid "Please insert your name or initials:" +#~ msgstr "Inserisci il tuo nome o le iniziali:" + +#~ msgid "Show &Navigation Panel" +#~ msgstr "Mostra il pannello di &navigazione" + +#~ msgid "Show Text" +#~ msgstr "Mostra testo" + +#~ msgid "Small Icons" +#~ msgstr "Icone piccole" + +#~ msgid "Normal Icons" +#~ msgstr "Icone normali" + +#~ msgid "Large Icons" +#~ msgstr "Icone grandi" + +#~ msgid "" +#~ "Click to use the current selection tool\n" +#~ "Click on the arrow to choose another selection tool" +#~ msgstr "" +#~ "Fai clic per usare lo strumento di selezione corrente\n" +#~ "Fai sulla freccia per scegliere un altro strumento di selezione" + +#~ msgid "Created: %1" +#~ msgstr "Creato: %1" + +#~ msgid "Line Extensions" +#~ msgstr "Estensioni linea" + +#~ msgid "Style" +#~ msgstr "Stile" + +#~ msgid "&Size:" +#~ msgstr "Dimen&sione:" + +#~ msgid "Inner color:" +#~ msgstr "Colore interno:" + +#~ msgid "Name: %1" +#~ msgstr "Nome: %1" + +#~ msgid "Size: %1" +#~ msgstr "Dimensione: %1" + +#~ msgid "&Browse Tool" +#~ msgstr "Strumento &navigazione" + +#~ msgid "&Zoom Tool" +#~ msgstr "Strumento &zoom" + +#~ msgctxt "Zoom Tool" +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "&Selection Tool" +#~ msgstr "Strumento &selezione" + +#~ msgctxt "Select Tool" +#~ msgid "Selection" +#~ msgstr "Selezione" + +#~ msgid "&Text Selection Tool" +#~ msgstr "Strumento selezione &testo" + +#~ msgid "T&able Selection Tool" +#~ msgstr "Strumento selezione t&abella" + +#~ msgctxt "Magnifier Tool" +#~ msgid "Magnifier" +#~ msgstr "Lente d'ingrandimento" + +#, fuzzy +#~| msgid "End of the document" +#~ msgid "Only for PDF documents" +#~ msgstr "Fine del documento" + +#, fuzzy +#~| msgctxt "Symbol for caret annotations" +#~| msgid "None" +#~ msgid " None" +#~ msgstr "Nessuno" + +#~ msgid "" +#~ "The document requested to be launched in presentation mode.\n" +#~ "Do you want to allow it?" +#~ msgstr "" +#~ "Il documento ha richiesto di essere aperto in modalità presentazione.\n" +#~ "Vuoi consentirlo?" + +#~ msgid "Presentation Mode" +#~ msgstr "Modalità presentazione" + +#~ msgid "Allow" +#~ msgstr "Permettere" + +#~ msgid "Allow the presentation mode" +#~ msgstr "Consenti la modalità presentazione" + +#~ msgid "Do Not Allow" +#~ msgstr "Non permettere" + +#~ msgid "Do not allow the presentation mode" +#~ msgstr "Non consentire la modalità presentazione" + +#~ msgid "" +#~ "Your annotation changes will not be saved automatically. Use File -> Save " +#~ "As...\n" +#~ "or your changes will be lost once the document is closed" +#~ msgstr "" +#~ "Le modifiche alle annotazioni non saranno salvate automaticamente. Usa " +#~ "File -> Salve come...\n" +#~ "o le tue modifiche verranno perse dopo la chiusura del documento" + +#~ msgid "" +#~ "Your annotations are saved internally by Okular.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Le annotazioni sono salvate internamente da Okular.\n" +#~ "Puoi esportare il documento con le annotazioni usando File -> Esporta " +#~ "come -> Archivio di documento" + +#~ msgid "Save &Copy As..." +#~ msgstr "Salva &copia come..." + +#~ msgid "" +#~ "Your annotations will not be exported.\n" +#~ "You can export the annotated document using File -> Export As -> Document " +#~ "Archive" +#~ msgstr "" +#~ "Le annotazioni non saranno esportate.\n" +#~ "Puoi esportare il documento con le annotazioni usando File -> Esporta " +#~ "come -> Archivio di documento" + +#~ msgid "" +#~ "End of document reached.\n" +#~ "Continue from the beginning?" +#~ msgstr "" +#~ "Raggiunta la fine del documento.\n" +#~ "Continuare dall'inizio?" + +#~ msgid "" +#~ "Beginning of document reached.\n" +#~ "Continue from the bottom?" +#~ msgstr "" +#~ "Raggiunto l'inizio del documento.\n" +#~ "Continuare dalla fine?" + +#~ msgid "Current maintainer" +#~ msgstr "Responsabile attuale" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Piotr Szymanski" +#~ msgstr "Piotr Szymanski" + +#~ msgid "Enrico Ros" +#~ msgstr "Enrico Ros" + +#~ msgid "Eugene Trounev" +#~ msgstr "Eugene Trounev" + +#~ msgid "Jiri Baum - NICTA" +#~ msgstr "Jiri Baum - NICTA" + +#~ msgid "Fabio D'Urso" +#~ msgstr "Fabio D'Urso" + +#~ msgid " sec." +#~ msgstr " sec." + +#~ msgid "Pencil color:" +#~ msgstr "Colore della matita:" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A0" +#~ msgstr "DIN/ISO A0 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A0" +#~ msgstr "DIN/ISO A0 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A1" +#~ msgstr "DIN/ISO A1 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A1" +#~ msgstr "DIN/ISO A1 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A2" +#~ msgstr "DIN/ISO A2 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A2" +#~ msgstr "DIN/ISO A2 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A3" +#~ msgstr "DIN/ISO A3 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A3" +#~ msgstr "DIN/ISO A3 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A4" +#~ msgstr "DIN/ISO A4 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A4" +#~ msgstr "DIN/ISO A4 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A5" +#~ msgstr "DIN/ISO A5 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A5" +#~ msgstr "Verticale5" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A6" +#~ msgstr "DIN/ISO A6 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A6" +#~ msgstr "DIN/ISO A6 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A7" +#~ msgstr "DIN/ISO A7 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A7" +#~ msgstr "Verticale7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A8" +#~ msgstr "DIN/ISO A8 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A8" +#~ msgstr "Verticale8" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO A9" +#~ msgstr "DIN/ISO A9 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO A9" +#~ msgstr "DIN/ISO A9 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B0" +#~ msgstr "DIN/ISO B0 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B0" +#~ msgstr "DIN/ISO B0 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B1" +#~ msgstr "DIN/ISO B1 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B1" +#~ msgstr "DIN/ISO B1 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B2" +#~ msgstr "DIN/ISO B2 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B2" +#~ msgstr "DIN/ISO B2 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B3" +#~ msgstr "DIN/ISO B3 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B3" +#~ msgstr "DIN/ISO B3 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B4" +#~ msgstr "DIN/ISO B4 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B4" +#~ msgstr "DIN/ISO B4 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B5" +#~ msgstr "DIN/ISO B5 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B5" +#~ msgstr "DIN/ISO B5 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B6" +#~ msgstr "DIN/ISO B6 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B6" +#~ msgstr "DIN/ISO B6 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B7" +#~ msgstr "DIN/ISO B7 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B7" +#~ msgstr "Verticale7" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B8" +#~ msgstr "DIN/ISO B8 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B8" +#~ msgstr "DIN/ISO B8 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B9" +#~ msgstr "DIN/ISO B9 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B9" +#~ msgstr "DIN/ISO B9 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DIN/ISO B10" +#~ msgstr "DIN/ISO B10 orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DIN/ISO B10" +#~ msgstr "DIN/ISO B10 verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape letter" +#~ msgstr "lettera orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait letter" +#~ msgstr "lettera verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape legal" +#~ msgstr "legale orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait legal" +#~ msgstr "legale verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape executive" +#~ msgstr "executive orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait executive" +#~ msgstr "executive verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape Comm10E" +#~ msgstr "Comm10E orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait Comm10E" +#~ msgstr "Comm10E verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape DLE" +#~ msgstr "DLE orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait DLE" +#~ msgstr "DLE verticale" + +#~ msgctxt "paper size" +#~ msgid "landscape folio" +#~ msgstr "folio orizzontale" + +#~ msgctxt "paper size" +#~ msgid "portrait folio" +#~ msgstr "folio verticale" + +#~ msgctxt "paper size" +#~ msgid "ledger" +#~ msgstr "ledger" + +#~ msgctxt "paper size" +#~ msgid "tabloid" +#~ msgstr "tabloid" + +#~ msgctxt "paper size" +#~ msgid "unknown landscape paper size" +#~ msgstr "formato di carta sconosciuto orizzontale" + +#~ msgctxt "paper size" +#~ msgid "unknown portrait paper size" +#~ msgstr "formato di carta sconosciuto verticale" + +#~ msgid "Toggle Drawing Mode" +#~ msgstr "Commuta modalità disegno" + +#~ msgid "Starting Jovie Text-to-Speech service Failed: %1" +#~ msgstr "Avvio del servizio di sintesi vocale Jovie non riuscito: %1" + +#~ msgid "Search Columns" +#~ msgstr "Colonna in cui cercare" + +#~ msgid "All Visible Columns" +#~ msgstr "Tutte le colonne visibili" + +#~ msgid "No document opened." +#~ msgstr "Nessun documento aperto." + +#~ msgid "Can't open more than one document in the unique Okular instance." +#~ msgstr "" +#~ "Impossibile aprire più di un documento nell'unica istanza di Okular." + +#~ msgid "No matches found for '%1'." +#~ msgstr "Nessuna corrispondenza trovata per «%1»." + +#~ msgid "Search in progress..." +#~ msgstr "Ricerca in corso..." + +#~ msgid "Searching for %1" +#~ msgstr "Ricerca di %1" + +#~ msgid "Identity Settings" +#~ msgstr "Impostazioni identità" + +#~ msgid "Highlight Properties" +#~ msgstr "Proprietà dell'evidenziatore" + +#~ msgid "Ink Properties" +#~ msgstr "Proprietà dello stilo" + +#~ msgctxt "Annotation tool" +#~ msgid "Green Ink" +#~ msgstr "Stilo verde" + +#~ msgid "Yellow Highlighter" +#~ msgstr "Evidenziatore giallo" + +#~ msgctxt "Annotation tool" +#~ msgid "Yellow Highlight" +#~ msgstr "Evidenziatore giallo" + +#~ msgctxt "Annotation tool" +#~ msgid "Straight Yellow Line" +#~ msgstr "Linea retta gialla" + +#~ msgid "Black Underlining" +#~ msgstr "Sottolineatura nera" + +#~ msgctxt "Annotation tool" +#~ msgid "Underline the text with a black line" +#~ msgstr "Sottolinea il testo con una riga nera" + +#~ msgid "Cyan Ellipse" +#~ msgstr "Ellisse color ciano" + +#~ msgctxt "Annotation tool" +#~ msgid "A cyan ellipse" +#~ msgstr "Un'ellisse color ciano" + +#~ msgid "Ink" +#~ msgstr "Stilo" + +#~ msgid "Enable &background generation" +#~ msgstr "Abilita &generazione in sottofondo" + +#, fuzzy +#~| msgid "Hide Forms" +#~ msgid "Reset Forms" +#~ msgstr "Nascondi moduli" + +#~ msgid "You must set this name:" +#~ msgstr "Devi impostare questo nome:" + +#~ msgid "Moves to the first page of the document" +#~ msgstr "Vai alla prima pagina del documento" + +#~ msgid "Moves to the last page of the document" +#~ msgstr "Vai all'ultima pagina del documento" + +#~ msgid "Toggles between File Path and Title" +#~ msgstr "Commuta tra il percorso del file ed il titolo" + +#~ msgctxt "%1 is \"Title\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "%1 is \"File Path\"" +#~ msgid "%1:" +#~ msgstr "%1:" + +#~ msgctxt "@action:button" +#~ msgid "&Overwrite" +#~ msgstr "S&ovrascrivi" + +#~ msgid "Pages:" +#~ msgstr "Pagine:" + +#~ msgid "Green Highlighter" +#~ msgstr "Evidenziatore verde" + +#~ msgid "&Properties..." +#~ msgstr "&Proprietà..." + +#~ msgid "okular" +#~ msgstr "okular" + +#~ msgctxt "Annotation tool" +#~ msgid "Pink Ink" +#~ msgstr "Stilo rosa" + +#, fuzzy +#~| msgid "Highlight" +#~ msgid "Pink Highlighter" +#~ msgstr "Evidenziato" + +#~ msgid "Could not load the necessary plugin to view the document." +#~ msgstr "" +#~ "Impossibile caricare il plugin necessario per visualizzare il documento." + +#, fuzzy +#~ msgid "Fit &Text" +#~ msgstr "Adatta alla dimensione del &testo" + +#, fuzzy +#~ msgid "&Advanced" +#~ msgstr "Avanza ogni:" + +#, fuzzy +#~ msgid "Contents:" +#~ msgstr "&Continuo" + +#~ msgid "Hide &Navigation Panel" +#~ msgstr "Nascondi il pannello &navigazione" + +#, fuzzy +#~ msgid "page %1" +#~ msgstr "Pagina %1" + +#~ msgid "Show &search bar in thumbnails list" +#~ msgstr "Mostra la barra di r&icerca nella lista delle miniature" + +#, fuzzy +#~ msgid "Free Text" +#~ msgstr "Pronuncia il testo" + +#, fuzzy +#~ msgid "Form" +#~ msgstr "Formato" + +#, fuzzy +#~ msgid "DlgGeneral" +#~ msgstr "Generale" + +#~ msgid "Program Look" +#~ msgstr "Aspetto del programma" + +#~ msgid "Reading Aids" +#~ msgstr "Aiuti alla lettura" + +#, fuzzy +#~ msgid "Click for Open %1" +#~ msgstr "Impossibile aprire %1" + +#, fuzzy +#~ msgid "flags:" +#~ msgstr "Pagine:" + +#~ msgid "&Watch file" +#~ msgstr "Sor&veglia il file" + +#~ msgid "Clear filter" +#~ msgstr "Cancella il filtro" + +#~ msgid "Topic" +#~ msgstr "Argomento" + +#~ msgid "Fit to Page &Width" +#~ msgstr "Adatta alla &larghezza della pagina" + +#~ msgid "&Two Pages" +#~ msgstr "&Due pagine" + +#~ msgid "Text found: \"%1\"." +#~ msgstr "Testo trovato: \"%1\"." + +#~ msgid "Text not found: \"%1\"." +#~ msgstr "Testo non trovato: \"%1\"." + +#~ msgid "Starting -- find text as you type" +#~ msgstr "Inizio -- ricerca mentre digiti" + +#~ msgctxt "PDF v. " +#~ msgid "PDF v. %1" +#~ msgstr "PDF v. %1" + +#~ msgid "Security" +#~ msgstr "Sicurezza" + +#~ msgid "Optimized" +#~ msgstr "Ottimizzato" + +#~ msgid "Unknown Encryption" +#~ msgstr "Cifratura sconosciuta" + +#~ msgid "Unknown Optimization" +#~ msgstr "Ottimizzazione sconosciuta" + +#~ msgid "" +#~ "The margins you specified change the page aspect ratio. Do you want to " +#~ "print with the aspect ratio changed or do you want the margins to be " +#~ "adapted so that the aspect ratio is preserved?" +#~ msgstr "" +#~ "I margini che hai specificato cambiano le proporzioni dell'aspetto della " +#~ "pagina. Vuoi stampare con le proporzioni modificate oppure vuoi che i " +#~ "margini vengano adattati in modo da rispettare le proporzioni originarie?" + +#~ msgid "Aspect ratio change" +#~ msgstr "Modifica proporzioni" + +#~ msgid "Print with specified margins" +#~ msgstr "Stampa usando i margini specificati" + +#~ msgid "Print adapting margins to keep aspect ratio" +#~ msgstr "Stampa adattando i margini per rispettare le proporzioni" + +#~ msgid "unknown" +#~ msgstr "sconosciuto" + +#~ msgid "-" +#~ msgstr "-" + +#~ msgid "[none]" +#~ msgstr "[nessuno]" + +#~ msgid "kpdf, a kde pdf viewer based on xpdf" +#~ msgstr "KPDF, un visualizzatore per PDF basato su xpdf" + +#~ msgid "Xpdf author" +#~ msgstr "Autore di xpdf" + +#~ msgid "Force rasterization" +#~ msgstr "Forza trasformazione" + +#~ msgid "Rasterize into an image before printing" +#~ msgstr "Trasforma in immagine prima di stampare" + +#~ msgid "" +#~ "Forces the rasterization of each page into an image before printing it. " +#~ "This usually gives somewhat worse results, but is useful when printing " +#~ "documents that appear to print incorrectly." +#~ msgstr "" +#~ "Forza la trasformazione di ciascuna pagina in immagine prima di " +#~ "stamparla. Normalmente questo produce dei pessimi risultati ma è utile " +#~ "quando si stampano documenti che appaiono stampati male." + +#~ msgid "KPDF::Part" +#~ msgstr "KPDF::Part" + +#~ msgid "Converting from ps to pdf..." +#~ msgstr "Conversione da ps a pdf..." + +#~ msgid "" +#~ "You do not have ps2pdf installed, so kpdf cannot open postscript files." +#~ msgstr "Impossibile aprire i file PostScript, ps2pdf non è installato." + +#~ msgid "" +#~ "You are trying to overwrite \"%1\" with itself. This is not allowed. " +#~ "Please save it in another location." +#~ msgstr "" +#~ "Stai per sovrascrivere \"%1\" con se stesso. Questo non è consentito. Per " +#~ "favore salvalo in un'altra posizione." diff --git a/po/it/okular_chm.po b/po/it/okular_chm.po new file mode 100644 index 0000000..fa911c0 --- /dev/null +++ b/po/it/okular_chm.po @@ -0,0 +1,62 @@ +# translation of okular_chm.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Luigi Toscano , 2007, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_chm\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:07+0200\n" +"PO-Revision-Date: 2020-02-29 01:28+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 19.12.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "Unsupported encoding" +msgstr "Codifica non supportata" + +#: lib/ebook_epub.cpp:308 +#, kde-format +msgid "" +"The encoding of this ebook is not supported yet. Please open a bug in " +"https://bugs.kde.org for support to be added" +msgstr "" +"La codifica di questo ebook non è ancora supportata. Apri una segnalazione " +"di bug presso https://bugs.kde.org perché il supporto sia aggiunto." + +#~ msgid "CHM Backend" +#~ msgstr "Backend CHM" + +#~ msgid "A Microsoft Windows help file renderer" +#~ msgstr "Un visualizzatore per file di aiuto di Microsoft Windows" + +#~ msgid "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" +#~ msgstr "" +#~ "© 2005-2007 Piotr Szymański\n" +#~ "© 2008 Albert Astals Cid" + +#~ msgid "Piotr Szymański" +#~ msgstr "Piotr Szymański" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" diff --git a/po/it/okular_comicbook.po b/po/it/okular_comicbook.po new file mode 100644 index 0000000..082d46e --- /dev/null +++ b/po/it/okular_comicbook.po @@ -0,0 +1,61 @@ +# translation of okular_comicbook.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Luigi Toscano , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_comicbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-24 03:03+0100\n" +"PO-Revision-Date: 2018-11-18 22:49+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: document.cpp:98 +#, kde-format +msgid "Cannot open document, neither unrar nor unarchiver were found." +msgstr "" +"Impossibile aprire il documento, non sono stati trovati ne' unrar ne' " +"unarchiver." + +#: document.cpp:103 +#, kde-format +msgid "" +"The version of unrar on your system is not suitable for opening comicbooks." +msgstr "" +"La versione di unrar presente nel sistema non è adatta per aprire file " +"comicbook." + +#: document.cpp:132 +#, kde-format +msgid "Unknown ComicBook format." +msgstr "Formato ComicBook sconosciuto." + +#~ msgid "ComicBook Backend" +#~ msgstr "Backend ComicBook" + +#~ msgid "A renderer for various comic book formats" +#~ msgstr "Un visualizzatore per vari formati di strisce a fumetti" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/it/okular_djvu.po b/po/it/okular_djvu.po new file mode 100644 index 0000000..240aefd --- /dev/null +++ b/po/it/okular_djvu.po @@ -0,0 +1,138 @@ +# translation of okular_djvu.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_djvu\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2008-11-18 19:28+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_djvu.cpp:133 +#, kde-format +msgid "Editor" +msgstr "Editor" + +#: generator_djvu.cpp:134 +#, kde-format +msgid "Publisher" +msgstr "Editore" + +#: generator_djvu.cpp:135 +#, kde-format +msgid "Volume" +msgstr "Volume" + +#: generator_djvu.cpp:136 +#, kde-format +msgid "Type of document" +msgstr "Tipo del documento" + +#: generator_djvu.cpp:138 +#, kde-format +msgctxt "Unknown number of component files" +msgid "Unknown" +msgstr "Sconosciuto" + +#: generator_djvu.cpp:138 +#, kde-format +msgid "Component Files" +msgstr "File dei componenti" + +#: kdjvu.cpp:665 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Unknown" +msgstr "Sconosciuto" + +#: kdjvu.cpp:668 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Single Page" +msgstr "Pagina singola" + +#: kdjvu.cpp:671 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled" +msgstr "Aggregato" + +#: kdjvu.cpp:674 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indirect" +msgstr "Indiretto" + +#: kdjvu.cpp:677 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Bundled (old)" +msgstr "Aggregato (vecchio formato)" + +#: kdjvu.cpp:680 +#, kde-format +msgctxt "Type of DjVu document" +msgid "Indexed (old)" +msgstr "Indicizzato (vecchio formato)" + +#~ msgid "DjVu Backend" +#~ msgstr "Backend DjVu" + +#~ msgid "DjVu backend based on DjVuLibre." +#~ msgstr "Backend DjVu basato su DjVuLibre." + +#~ msgid "© 2006-2008 Pino Toscano" +#~ msgstr "© 2006-2008 Pino Toscano" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgctxt "Unknown title" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgctxt "Unknown author" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgctxt "Unknown editor" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgctxt "Unknown publisher" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgctxt "Unknown creation date" +#~ msgid "Unknown" +#~ msgstr "Sconosciuta" + +#~ msgctxt "Unknown volume information" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgctxt "Unknown type of document" +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgid "A DjVu backend" +#~ msgstr "Un backend per DjVu" diff --git a/po/it/okular_dvi.po b/po/it/okular_dvi.po new file mode 100644 index 0000000..7abcdda --- /dev/null +++ b/po/it/okular_dvi.po @@ -0,0 +1,843 @@ +# translation of okular_dvi.po to Italian +# Luciano Montanaro , 2003, 2005, 2006. +# Andrea Rizzi , 2003, 2004. +# Daniele Medri , 2003. +# Federico Cozzi , 2004. +# Federico Zenith , 2004. +# Luigi Toscano , 2007, 2008, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: okular_dvi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2014-06-27 20:53+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: dviexport.cpp:117 +#, kde-format +msgid "" +"

    Okular could not locate the program dvipdfm on your " +"computer. This program is essential for the export function to work. You " +"can, however, convert the DVI-file to PDF using the print function of " +"Okular, but that will often produce documents which print okay, but are of " +"inferior quality if viewed in Acrobat Reader. It may be wise to upgrade to a " +"more recent version of your TeX distribution which includes the dvipdfm program.

    Hint to the perplexed system administrator: Okular uses " +"the PATH environment variable when looking for programs.

    " +msgstr "" +"

    Okular non riesce a trovare sul tuo computer il programma " +"dvipdfm, che è indispensabile per le funzioni di esportazione. Puoi " +"comunque convertire i file DVI in file PDF utilizzando le funzioni di stampa " +"di Okular, ma questo spesso produce file accettabili per la stampa, ma che " +"sono di qualità inferiore se visualizzati con Acrobat Reader. Sarebbe meglio " +"aggiornare TeX ad una versione più recente che includa il programma " +"dvipdfm.

    Suggerimento per gli amministratori di sistema: " +"Okular utilizza la variabile d'ambiente PATH per cercare i programmi.

    " + +#: dviexport.cpp:135 +#, kde-format +msgid "" +"The external program 'dvipdfm', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Il programma esterno «dvipdfm» usato per esportare il file ha segnalato " +"un errore. Puoi consultare la finestra con le informazioni sul " +"documento, che troverai nel menu File, per una descrizione " +"dettagliata dell'errore." + +#: dviexport.cpp:158 +#, kde-format +msgid "" +"This DVI file refers to external graphic files which are not in " +"PostScript format, and cannot be handled by the dvips program that " +"Okular uses internally to print or to export to PostScript. The " +"functionality that you require is therefore unavailable in this version of " +"Okular." +msgstr "" +"Questo file DVI fa riferimento a file grafici esterni che non sono in " +"formato PostScript, e che non sono gestiti dal programma dvips " +"usato internamente da Okular per stampare o esportare in PostScript. La " +"funzionalità richiesta non è quindi disponibile in questa versione di Okular." +"" + +#: dviexport.cpp:166 +#, kde-format +msgid "" +"

    Okular could not locate the program dvips on your computer. " +"That program is essential for the export function to work.

    Hint to the " +"perplexed system administrator: Okular uses the PATH environment variable " +"when looking for programs.

    " +msgstr "" +"

    Okular non riesce a trovare sul tuo computer il programma dvips, che è indispensabile per le funzioni di esportazione.

    Suggerimento per gli amministratori di sistema: Okular utilizza la " +"variabile d'ambiente PATH per cercare i programmi.

    " + +#: dviexport.cpp:257 +#, kde-format +msgid "" +"The external program 'dvips', which was used to export the file, " +"reported an error. You might wish to look at the document info " +"dialog which you will find in the File-Menu for a precise error " +"report." +msgstr "" +"Il programma esterno «dvips» usato per esportare il file DVI ha " +"segnalato un errore. Puoi consultare la finestra con le informazioni " +"sul documento, che troverai nel menu File, per una descrizione " +"dettagliata dell'errore." + +#: dviFile.cpp:109 +#, kde-format +msgid "The DVI file does not start with the preamble." +msgstr "Il file DVI non inizia con il preambolo." + +#: dviFile.cpp:115 +#, kde-format +msgid "" +"The DVI file contains the wrong version of DVI output for this program. " +"Hint: If you use the typesetting system Omega, you have to use a special " +"program, such as oxdvi." +msgstr "" +"Il file DVI contiene la versione errata di output DVI per questo programma. " +"Suggerimento: se stai utilizzando il sistema di impaginazione Omega, devi " +"usare un programma speciale, come ad esempio oxdvi." + +#: dviFile.cpp:151 +#, kde-format +msgid "" +"The DVI file is badly corrupted. Okular was not able to find the postamble." +msgstr "Il file DVI è molto rovinato. Okular non ha trovato il postambolo." + +#: dviFile.cpp:165 +#, kde-format +msgid "The postamble does not begin with the POST command." +msgstr "Il postambolo non inizia con il comando POST." + +#: dviFile.cpp:218 +#, kde-format +msgid "The postamble contained a command other than FNTDEF." +msgstr "Il postambolo contiene un comando diverso da FNTDEF." + +#: dviFile.cpp:253 +#, kde-format +msgid "The page %1 does not start with the BOP command." +msgstr "La pagina %1 non inizia con il comando BOP." + +#: dviFile.cpp:380 +#, kde-format +msgid "" +"

    The external program pdf2ps could not be started. As " +"a result, the PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

    Possible " +"reason: The program pdf2ps may not be installed on your " +"system, or cannot be found in the current search path.

    What you can " +"do: The program pdf2ps is normally contained in " +"distributions of the ghostscript PostScript interpreter system. If " +"ghostscript is not installed on your system, you could install it now. If " +"you are sure that ghostscript is installed, try to use pdf2ps from the command line to check if it really works.

    PATH: %2

    " +msgstr "" +"

    Il programma pdf2ps non può essere avviato. Di " +"conseguenza il file PDF «%1» non può essere convertito in PostScript. Alcuni " +"elementi grafici nel documento non saranno quindi visualizzati.

    " +"Possibile causa: il programma pdf2ps potrebbe non " +"essere installato, o non è rintracciabile nel percorso di ricerca corrente.

    Che cosa puoi fare: il programma pdf2ps è " +"normalmente contenuto nelle distribuzioni di ghostscript, sistema di " +"interpretazione PostScript. Se ghostscript non è installato, puoi " +"installarlo adesso. Se sei sicuro che ghostscript sia installato, prova ad " +"usare il programma pdf2ps dalla linea di comando per " +"controllare se funziona correttamente.

    PATH: %2

    " + +#: dviFile.cpp:407 +#, kde-format +msgid "" +"

    The PDF-file %1 could not be converted to PostScript. Some graphic " +"elements in your document will therefore not be displayed.

    Possible " +"reason: The file %1 might be broken, or might not be a PDF-file at all. " +"This is the output of the pdf2ps program that Okular used:

    %2

    " +msgstr "" +"

    Il file PDF «%1» non può essere convertito in PostScript. Alcuni " +"elementi grafici nel documento non saranno quindi visualizzati.

    " +"Possibile ragione: Il file «%1» potrebbe essere rovinato o potrebbe non " +"essere un file PDF. Questo è l'output del programma pdf2ps " +"utilizzato da Okular:

    %2

    " + +#: dviRenderer.cpp:211 dviRenderer.cpp:449 +#, kde-format +msgid "File corruption. %1" +msgstr "File rovinato. %1" + +#: dviRenderer.cpp:347 +#, kde-format +msgid "Not all PostScript files could be embedded into your document. %1" +msgstr "" +"Non è stato possibile integrare tutti i file PostScript nel tuo documento. %1" + +#: dviRenderer.cpp:350 +#, kde-format +msgid "All external PostScript files were embedded into your document." +msgstr "" +"Tutti i file PostScript esterni sono stati integrati nel tuo documento." + +#: dviRenderer.cpp:434 +#, kde-format +msgid "The specified file '%1' does not exist." +msgstr "Il file «%1» specificato non esiste." + +#: dviRenderer.cpp:592 +#, kde-format +msgid "" +"You have asked Okular to locate the place in the DVI file which corresponds " +"to line %1 in the TeX-file %2. It seems, however, that the DVI file does not " +"contain the necessary source file information. " +msgstr "" +"Hai chiesto ad Okular di trovare il punto del file DVI che corrisponde alla " +"riga %1 nel file TeX %2. Sembra che il file DVI non contenga le informazioni " +"necessarie nel file TeX sorgente. " + +#: dviRenderer.cpp:629 +#, kde-format +msgid "" +"Okular was not able to locate the place in the DVI file which corresponds to " +"line %1 in the TeX-file %2." +msgstr "" +"Okular non è stato in grado di localizzare il punto nel file DVI che " +"corrisponde alla riga %1 nel file TeX %2." + +#: dviRenderer_draw.cpp:256 +#, kde-format +msgid "The DVI code set a character of an unknown font." +msgstr "Il codice DVI ha impostato un carattere sconosciuto." + +#: dviRenderer_draw.cpp:283 dviRenderer_prescan.cpp:629 +#, kde-format +msgid "The DVI code referred to font #%1, which was not previously defined." +msgstr "" +"Il codice DVI fa riferimento al carattere #%1, che non è stato " +"precedentemente definito." + +#: dviRenderer_draw.cpp:364 +#, kde-format +msgid "The stack was not empty when the EOP command was encountered." +msgstr "Lo stack non era vuoto quando è stato incontrato il comando EOP." + +#: dviRenderer_draw.cpp:376 +#, kde-format +msgid "The stack was empty when a POP command was encountered." +msgstr "Lo stack era vuoto quando è stato incontrato un comando POP." + +#: dviRenderer_draw.cpp:496 dviRenderer_draw.cpp:505 +#, kde-format +msgid "The DVI code referred to a font which was not previously defined." +msgstr "" +"Il codice DVI fa riferimento ad un carattere che non è stato precedentemente " +"definito." + +#: dviRenderer_draw.cpp:546 +#, kde-format +msgid "An illegal command was encountered." +msgstr "È stato incontrato un comando illegale." + +#: dviRenderer_draw.cpp:551 +#, kde-format +msgid "The unknown op-code %1 was encountered." +msgstr "È stato incontrato l'op-code sconosciuto %1." + +#: dviRenderer_prescan.cpp:83 +#, kde-format +msgid "Embedding %1" +msgstr "Integrazione di %1" + +#: dviRenderer_prescan.cpp:98 +#, kde-format +msgid "" +"Page %1: The PDF file %2 could not be converted to " +"PostScript.
    " +msgstr "" +"Pagina %1: il file PDF %2 non può essere convertito in " +"PostScript.
    " + +#: dviRenderer_prescan.cpp:100 +#, kde-format +msgid "" +"Page %1: The PostScript file %2 could not be found.
    " +msgstr "" +"Pagina %1: il file PostScript %2 non è stato trovato.
    " + +#: dviRenderer_prescan.cpp:246 +#, kde-format +msgid "The papersize data '%1' could not be parsed." +msgstr "" +"Non è stato possibile interpretare i dati sulla dimensione della carta «%1»." + +#: fontpool.cpp:203 +#, kde-format +msgid "" +"

    Okular was not able to locate all the font files which are necessary " +"to display the current DVI file. Your document might be unreadable.

    PATH: %1

    %2

    " +msgstr "" +"

    Okular non è riuscito a trovare tutti i tipi di carattere necessari " +"per mostrare il file DVI corrente. Il documento potrebbe risultare " +"illeggibile.

    PATH: %1

    %2" + +#: fontpool.cpp:270 +#, kde-format +msgid "" +"

    There were problems running kpsewhich. As a result, some " +"font files could not be located, and your document might be unreadable.
    Possible reason: the kpsewhich program is perhaps not installed on " +"your system, or it cannot be found in the current search path.

    PATH: %1

    %2

    " +msgstr "" +"

    Ci sono stati problemi durante l'esecuzione di kpsewhich. " +"Come risultato alcuni file di caratteri non sono stati trovati e il tuo " +"documento potrebbe essere illeggibile.
    Possibili causa: il programma " +"kpsewhich forse non è installato nel tuo sistema, o non può essere " +"trovato nel percorso di ricerca attuale.

    PATH: %1

    %2

    " + +#: fontpool.cpp:291 +#, kde-format +msgid "" +"The font generation by kpsewhich was aborted (exit code %1, " +"error %2). As a result, some font files could not be located, and your " +"document might be unreadable." +msgstr "" +"La generazione dei caratteri da parte di«kpsewhich si è " +"interrotta (codice di uscita %1, errore %2). Di conseguenza alcuni file di " +"caratteri non sono stati trovati, e quindi il documento potrebbe essere " +"illeggibile." + +#: fontpool.cpp:462 +#, kde-format +msgid "Currently generating %1 at %2 dpi..." +msgstr "Generazione in corso di %1 a %2 dpi..." + +#: generator_dvi.cpp:299 +#, kde-format +msgid "Generator/Date" +msgstr "Generatore/data" + +#: generator_dvi.cpp:382 +#, kde-format +msgid "Font file not found" +msgstr "Il file del tipo di caratteri non è stato trovato" + +#: pageSize.cpp:294 +#, kde-format +msgid "portrait" +msgstr "verticale" + +#: pageSize.cpp:296 +#, kde-format +msgid "landscape" +msgstr "orizzontale" + +#: psgs.cpp:265 +#, kde-format +msgid "" +"The version of Ghostview that is installed on this computer does not contain " +"any of the Ghostview device drivers that are known to Okular. PostScript " +"support has therefore been turned off in Okular." +msgstr "" +"La versione di Ghostview che è installata su questo computer non contiene " +"nessuno dei dispositivi Ghostview noti a Okular. Il supporto PostScript è " +"quindi disattivato in Okular." + +#: psgs.cpp:270 +#, kde-format +msgid "" +"

    The Ghostview program, which Okular uses internally to display the " +"PostScript graphics that is included in this DVI file, is generally able to " +"write its output in a variety of formats. The sub-programs that Ghostview " +"uses for these tasks are called 'device drivers'; there is one device driver " +"for each format that Ghostview is able to write. Different versions of " +"Ghostview often have different sets of device drivers available. It seems " +"that the version of Ghostview that is installed on this computer does not " +"contain any of the device drivers that are known to Okular." +"

    It seems unlikely that a regular installation of Ghostview would not " +"contain these drivers. This error may therefore point to a serious " +"misconfiguration of the Ghostview installation on your computer.

    If " +"you want to fix the problems with Ghostview, you can use the command " +"gs --help to display the list of device drivers contained " +"in Ghostview. Among others, Okular can use the 'png256', 'jpeg' and 'pnm' " +"drivers. Note that Okular needs to be restarted to re-enable PostScript " +"support.

    " +msgstr "" +"

    Il programma Ghostview, utilizzato internamente da Okular per " +"mostrare la grafica PostScript contenuta nei file DVI, di solito è in grado " +"di generare in uscita diversi formati di immagini. I sottoprogrammi che " +"Ghostview usa a questo scopo sono chiamati «device driver»; ce n'è uno per " +"ogni formato che Ghostview è in grado di scrivere. Le differenti versioni di " +"Ghostview hanno spesso differenti insiemi di device driver disponibili. " +"Sembra che la versione installata su questo computer non contenga " +"nessuno dei device driver noti a Okular.

    È molto " +"improbabile che un'installazione standard di Ghostview non contenga questi " +"driver. Questo errore può essere dovuto ad un serio problema di " +"configurazione dell'installazione di Ghostview sul tuo computer.

    Se " +"vuoi correggere i problemi di Ghostview puoi usare il comando gs --" +"help per vedere la lista dei device driver presenti. Tra gli altri, " +"Okular può usare i driver «png256», «jpeg» e «pnm». Nota che Okular deve " +"essere riavviato per riabilitare il supporto PostScript.

    " + +#: special.cpp:36 +#, kde-format +msgid "That makes 25 errors. Further error messages will not be printed." +msgstr "Incontrati 25 errori. Gli ulteriori messaggi non saranno stampati." + +#: special.cpp:216 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Color pop command issued when the color " +"stack is empty." +msgstr "" +"Errore nel file DVI «%1», pagina %2. Invocato comando di estrazione colore " +"quando lo stack dei colori era vuoto." + +#: special.cpp:297 +#, kde-format +msgid "" +"Malformed parameter in the epsf special command.\n" +"Expected a float to follow %1 in %2" +msgstr "" +"Parametro malformato nel comando speciale epsf.\n" +"Era atteso un inserto a seguito di %1 in %2" + +#: special.cpp:424 +#, kde-format +msgid "" +"File not found: \n" +" %1" +msgstr "" +"File non trovato: \n" +" %1" + +#: special.cpp:664 +#, kde-format +msgid "" +"Error in DVIfile '%1', page %2. Could not interpret angle in text rotation " +"special." +msgstr "" +"Errore nel file DVI «%1», pagina %2. L'angolo nello special di rotazione del " +"testo non è interpretabile." + +#: special.cpp:680 +#, kde-format +msgid "The special command '%1' is not implemented." +msgstr "Il comando speciale «%1» non è implementato." + +#: TeXFont_PFB.cpp:43 +#, kde-format +msgid "" +"The font file %1 could be opened and read, but its font format is " +"unsupported." +msgstr "" +"Il tipo carattere %1 può essere aperto e letto, ma il suo formato non è " +"supportato." + +#: TeXFont_PFB.cpp:48 +#, kde-format +msgid "The font file %1 is broken, or it could not be opened or read." +msgstr "Il tipo carattere %1 è danneggiato o non può essere aperto in lettura." + +#: TeXFont_PFB.cpp:165 +#, kde-format +msgid "" +"FreeType reported an error when setting the character size for font file %1." +msgstr "" +"FreeType riferisce un errore durante l'impostazione della dimensione del " +"carattere %1." + +#: TeXFont_PFB.cpp:181 +#, kde-format +msgid "FreeType is unable to load glyph #%1 from font file %2." +msgstr "" +"FreeType non è in grado di caricare il glyph #%1 dal file di tipi di " +"carattere %2." + +#: TeXFont_PFB.cpp:193 +#, kde-format +msgid "FreeType is unable to render glyph #%1 from font file %2." +msgstr "" +"FreeType non è in grado di fare il rendering del glyph #%1 dal carattere %2." + +#: TeXFont_PFB.cpp:206 +#, kde-format +msgid "Glyph #%1 is empty." +msgstr "Glyph #%1 vuoto." + +#: TeXFont_PFB.cpp:207 +#, kde-format +msgid "Glyph #%1 from font file %2 is empty." +msgstr "Glyph #%1 vuoto nel file di tipi di carattere %2." + +#: TeXFont_PFB.cpp:272 +#, kde-format +msgid "FreeType is unable to load metric for glyph #%1 from font file %2." +msgstr "" +"FreeType non può caricare la metrica per il glyph #%1 del carattere %2." + +#: TeXFont_PK.cpp:87 +#, kde-format +msgid "Cannot open font file %1." +msgstr "Non è possibile riconoscere il formato del file %1." + +#: TeXFont_PK.cpp:133 +#, kde-format +msgid "TexFont_PK::operator[]: Character %1 not defined in font %2" +msgstr "" +"TexFont_PK::operator[]: il carattere %1 non è definita nel tipo di caratteri " +"%2" + +#: TeXFont_PK.cpp:417 +#, kde-format +msgid "Unexpected %1 in PK file %2" +msgstr "%1 inaspettato nel file PK %2" + +#: TeXFont_PK.cpp:481 +#, kde-format +msgid "The character %1 is too large in file %2" +msgstr "Il carattere %1 è troppo grande nel file %2" + +#: TeXFont_PK.cpp:581 TeXFont_PK.cpp:665 +#, kde-format +msgid "Wrong number of bits stored: char. %1, font %2" +msgstr "Numero di bit salvati errato: carattere %1, carattere %2" + +#: TeXFont_PK.cpp:583 TeXFont_PK.cpp:667 +#, kde-format +msgid "Bad pk file (%1), too many bits" +msgstr "File PK errato (%1), troppi bit" + +#: TeXFont_PK.cpp:697 +#, kde-format +msgid "Font has non-square aspect ratio " +msgstr "Il carattere ha proporzioni non quadrate " + +#: TeXFontDefinition.cpp:105 +#, kde-format +msgid "Cannot find font %1, file %2." +msgstr "Impossibile trovare il carattere %1, file %2." + +#: TeXFontDefinition.cpp:121 +#, kde-format +msgid "Checksum mismatch for font file %1" +msgstr "Codice di controllo errato per il carattere %1" + +#: TeXFontDefinition.cpp:169 +#, kde-format +msgid "Cannot recognize format for font file %1" +msgstr "Il formato del file di carattere %1 è ignoto" + +#: util.cpp:77 +#, kde-format +msgid "" +"Fatal error.\n" +"\n" +msgstr "" +"Errore fatale.\n" +"\n" + +#: util.cpp:77 +#, kde-format +msgid "" +"\n" +"\n" +"This probably means that either you found a bug in Okular,\n" +"or that the DVI file, or auxiliary files (such as font files, \n" +"or virtual font files) were really badly broken.\n" +"Okular will abort after this message. If you believe that you \n" +"found a bug, or that Okular should behave better in this situation\n" +"please report the problem." +msgstr "" +"\n" +"\n" +"Probabilmente ciò vuol dire che hai trovato un bug in Okular,\n" +"o che il file DVI o i file ausiliari (come i file dei caratteri,\n" +"o i file dei caratteri virtuali) sono molto rovinati.\n" +"Okular terminerà dopo questo messaggio. Se credi di avere trovato\n" +"un bug, o che Okular dovrebbe comportarsi meglio in questa situazione,\n" +"per piacere segnala il problema." + +#: vf.cpp:179 +#, kde-format +msgid "Wrong command byte found in VF macro list: %1" +msgstr "" +"Nella lista delle macro VF è stato trovato un byte di comando errato: %1" + +#~ msgid "DVI Backend" +#~ msgstr "Backend DVI" + +#~ msgid "A DVI file renderer" +#~ msgstr "Un visualizzatore di file DVI" + +#~ msgid "© 2006 Luigi Toscano" +#~ msgstr "© 2006 Luigi Toscano" + +#~ msgid "" +#~ "

    Okular relies on the kpsewhich program to locate font files on " +#~ "your hard disk and to generate PK fonts, if necessary.

    " +#~ msgstr "" +#~ "

    Okular dipende dal programma kpsewhich per trovare i file di " +#~ "tipi di carattere sul disco rigido e generare i file PK quando necessario." +#~ "

    " + +#~ msgid "Okular is currently generating bitmap fonts..." +#~ msgstr "Okular sta generando i caratteri bitmap..." + +#~ msgid "Aborts the font generation. Do not do this." +#~ msgstr "Interrompe la generazione dei caratteri. Non farlo." + +#~ msgid "" +#~ "Okular is currently generating bitmap fonts which are needed to display " +#~ "your document. For this, Okular uses a number of external programs, such " +#~ "as MetaFont. You can find the output of these programs later in the " +#~ "document info dialog." +#~ msgstr "" +#~ "Okular sta attualmente generando i caratteri bitmap necessari per la " +#~ "visualizzazione del documento. Per questa operazione, Okular usa alcuni " +#~ "programmi esterni, come MetaFont. In seguito potrai trovare l'output di " +#~ "questi programmi nella finestra con le informazioni sul documento." + +#~ msgid "Okular is generating fonts. Please wait." +#~ msgstr "Okular sta generando i caratteri. Attendere prego." + +#~ msgid "Font Generation Progress Dialog" +#~ msgstr "Progresso nella generazione dei caratteri" + +#~ msgid "Abort" +#~ msgstr "Interrompi" + +#~ msgid "What is happening here?" +#~ msgstr "Che cosa sta succedendo?" + +#~ msgid "%v of %m" +#~ msgstr "%v di %m" + +#~ msgid "Please be patient" +#~ msgstr "Per piacere sii paziente" + +#~ msgid "*.pdf|Portable Document Format (*.pdf)" +#~ msgstr "*.pdf|Portable Document Format (*.pdf)" + +#~ msgid "Export File As" +#~ msgstr "Esporta file con nome" + +#~ msgid "" +#~ "The file %1\n" +#~ "exists. Do you want to overwrite it?" +#~ msgstr "" +#~ "Il file «%1»\n" +#~ "esiste. Vuoi sovrascriverlo?" + +#~ msgid "Overwrite File" +#~ msgstr "Sovrascrivi file" + +#~ msgid "Overwrite" +#~ msgstr "Sovrascrivi" + +#~ msgid "Using dvipdfm to export the file to PDF" +#~ msgstr "Sto usando dvipdfm per esportare il file in formato PDF" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvipdfm' to convert your " +#~ "DVI-file to PDF. Sometimes that can take a while because dvipdfm needs to " +#~ "generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular sta attualmente usando il programma esterno «dvipdfm» per " +#~ "convertire il file DVI in formato PDF. Talvolta questa operazione " +#~ "richiede tempo, perché dvipdfm deve generare i propri caratteri bitmap. " +#~ "Per piacere sii paziente." + +#~ msgid "Waiting for dvipdfm to finish..." +#~ msgstr "Sto attendendo che dvipdfm finisca..." + +#~ msgid "*.ps|PostScript (*.ps)" +#~ msgstr "*.ps|PostScript (*.ps)" + +#~ msgid "Using dvips to export the file to PostScript" +#~ msgstr "Sto usando dvips per esportare il file in formato PostScript" + +#~ msgid "" +#~ "Okular is currently using the external program 'dvips' to convert your " +#~ "DVI-file to PostScript. Sometimes that can take a while because dvips " +#~ "needs to generate its own bitmap fonts Please be patient." +#~ msgstr "" +#~ "Okular sta attualmente usando il programma esterno «dvips» per convertire " +#~ "il file DVI in formato PostScript. Talvolta questa operazione può " +#~ "richiedere parecchio tempo perché dvips deve generare i propri caratteri " +#~ "bitmap. Per piacere sii paziente." + +#~ msgid "Waiting for dvips to finish..." +#~ msgstr "Sto attendendo che dvips finisca..." + +#~ msgid "Functionality Unavailable" +#~ msgstr "Funzionalità non disponibile" + +#~ msgid "" +#~ "File corruption Okular could not interpret your DVI " +#~ "file. This is most commonly caused by a corrupted file." +#~ msgstr "" +#~ "File rovinato. Okular non riesce ad interpretare il " +#~ "file DVI. Probabilmente ciò significa che il file DVI è rovinato." + +#~ msgid "DVI File Error" +#~ msgstr "Errore nel file DVI" + +#~ msgid "Not All Font Files Found" +#~ msgstr "Non sono stati trovati tutti i tipi di carattere" + +#~ msgid "Locating fonts..." +#~ msgstr "Individuazione tipi di carattere..." + +#~ msgid "" +#~ "

    There were problems running kpsewhich. As a result, some font " +#~ "files could not be located, and your document might be unreadable.

    Possible reason: The kpsewhich program is perhaps not " +#~ "installed on your system, or it cannot be found in the current search " +#~ "path.

    What you can do: The kpsewhich program is normally " +#~ "contained in distributions of the TeX typesetting system. If TeX is not " +#~ "installed on your system, you could install the TeX Live distribution " +#~ "(www.tug.org/texlive). If you are sure that TeX is installed, please try " +#~ "to use the kpsewhich program from the command line to check if it really " +#~ "works.

    " +#~ msgstr "" +#~ "

    Si sono incontrati problemi ad eseguire kpsewhich. Di " +#~ "conseguenza, alcuni caratteri non sono stati trovati, e quindi il " +#~ "documento potrebbe essere illeggibile.

    Possibile ragione: Il " +#~ "programma kpsewhich potrebbe non essere installato, o non è " +#~ "rintracciabile nel percorso di ricerca corrente.

    Che cosa puoi " +#~ "fare: Il programma kpsewhich è normalmente contenuto nelle " +#~ "distribuzioni del sistema di composizione tipografica TeX. Se TeX non è " +#~ "installato, puoi installare la distribuzione TeX Live (www.tug.org/" +#~ "texlive). Se sei sicuro che TeX sia installato, prova ad usare il " +#~ "programma kpsewhich dalla linea di comando per controllare se funziona " +#~ "correttamente.

    " + +#~ msgid "Problem locating fonts" +#~ msgstr "Problema nel reperimento dei caratteri" + +#~ msgid "Font generation aborted" +#~ msgstr "Generazione dei tipi di carattere interrotta" + +#~ msgid "Export: %1 to PDF" +#~ msgstr "Esportazione: %1 in formato PDF" + +#~ msgid "Export: %1 to PostScript" +#~ msgstr "Esportazione: %1 in formato PostScript" + +#~ msgid "The fontlist is currently empty." +#~ msgstr "La lista dei tipi di carattere è attualmente vuota." + +#~ msgid "TeX Name" +#~ msgstr "Nome TeX" + +#~ msgid "Family" +#~ msgstr "Famiglia" + +#~ msgid "Zoom" +#~ msgstr "Zoom" + +#~ msgid "Type" +#~ msgstr "Tipo" + +#~ msgid "Encoding" +#~ msgstr "Codifica" + +#~ msgid "Comment" +#~ msgstr "Commento" + +#~ msgid "TeX virtual" +#~ msgstr "TeX virtuale" + +#~ msgid "TeX Font Metric" +#~ msgstr "Metrica dei caratteri TeX" + +#~ msgid "FreeType" +#~ msgstr "FreeType" + +#~ msgid "Could not allocate memory for a font structure" +#~ msgstr "" +#~ "Non è stato possibile allocare memoria per una struttura di caratteri" + +#~ msgid "Not enough memory to load the DVI-file." +#~ msgstr "Memoria insufficiente per caricare il file DVI." + +#~ msgid "Could not load the DVI-file." +#~ msgstr "Non è possibile caricare il file DVI." + +#~ msgid "Checksum mismatch" +#~ msgstr "Errore di checksum" + +#~ msgid " in font file " +#~ msgstr " nel file del tipo di carattere " + +#~ msgid "Could not allocate memory for a macro table." +#~ msgstr "Non è possibile allocare memoria per una tabella di macro." + +#~ msgid "Virtual character " +#~ msgstr "Carattere virtuale " + +#~ msgid " in font " +#~ msgstr " nel tipo di carattere " + +#~ msgid " ignored." +#~ msgstr " ignorato." + +#~ msgid "Fatal Error" +#~ msgstr "Errore fatale" + +#~ msgid "KDVI: Information" +#~ msgstr "KDVI: Informazioni" + +#~ msgid "" +#~ "This DVI file contains source file information. You may click into " +#~ "the text with the middle mouse button, and an editor will open the TeX-" +#~ "source file immediately." +#~ msgstr "" +#~ " Questo file DVI contiene informazioni sul file sorgente. Puoi fare " +#~ "clic con il tasto centrale del mouse sul testo e verrà immediatamente " +#~ "aperto un editor di testo con il sorgente TeX del file." + +#~ msgid "Do not show this message again" +#~ msgstr "Non mostrare nuovamente questo messaggio" + +#~ msgid "Explain in more detail..." +#~ msgstr "Spiega più in dettaglio..." + +#~ msgid "" +#~ "File error. The specified file '%1' does not exist. " +#~ "KDVI already tried to add the ending '.dvi'." +#~ msgstr "" +#~ "Errore di file. Il file specificato \"%1\" non " +#~ "esiste. KDVI ha già provato anche ad aggiungere l'estensione \".dvi\"" + +#~ msgid "File Error" +#~ msgstr "Errore di file" + +#~ msgid "Could Not Find Reference" +#~ msgstr "Non è possibile trovare il riferimento" diff --git a/po/it/okular_epub.po b/po/it/okular_epub.po new file mode 100644 index 0000000..6b91863 --- /dev/null +++ b/po/it/okular_epub.po @@ -0,0 +1,55 @@ +# translation of okular_epub.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_epub\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-22 20:10+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: converter.cpp:163 +#, kde-format +msgid "Error while opening the EPub document." +msgstr "Errore durante l'apertura del documento EPub." + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub" +msgstr "EPub" + +#: generator_epub.cpp:33 +#, kde-format +msgid "EPub Backend Configuration" +msgstr "Configurazione del backend EPub" + +#~ msgid "EPub Backend" +#~ msgstr "Backend EPub" + +#~ msgid "An EPub backend" +#~ msgstr "Backend EPub" + +#~ msgid "© 2008 Ely Levy" +#~ msgstr "© 2008 Ely Levy" + +#~ msgid "Ely Levy" +#~ msgstr "Ely Levy" diff --git a/po/it/okular_fax.po b/po/it/okular_fax.po new file mode 100644 index 0000000..b309ca1 --- /dev/null +++ b/po/it/okular_fax.po @@ -0,0 +1,45 @@ +# translation of okular_fax.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Luigi Toscano , 2008. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_fax\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-12-09 12:28+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_fax.cpp:45 +#, kde-format +msgid "Unable to load document" +msgstr "Impossibile caricare il documento" + +#~ msgid "Fax Backend" +#~ msgstr "Backend fax" + +#~ msgid "A G3/G4 fax document backend" +#~ msgstr "Un backend per documenti fax G3/G4" + +#~ msgid "© 2008 Tobias Koenig" +#~ msgstr "© 2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/it/okular_fictionbook.po b/po/it/okular_fictionbook.po new file mode 100644 index 0000000..6f6c352 --- /dev/null +++ b/po/it/okular_fictionbook.po @@ -0,0 +1,95 @@ +# translation of okular_fictionbook.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2007, 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_fictionbook\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-22 20:11+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: converter.cpp:99 +#, kde-format +msgid "Document is not a valid FictionBook" +msgstr "Il documento non è un file FictionBook valido" + +#: document.cpp:32 +#, kde-format +msgid "Unable to open document: %1" +msgstr "Impossibile aprire il documento: %1" + +#: document.cpp:39 +#, kde-format +msgid "Document is not a valid ZIP archive" +msgstr "Il documento non è un archivio ZIP valido" + +#: document.cpp:45 +#, kde-format +msgid "Invalid document structure (main directory is missing)" +msgstr "Struttura del documento non valida (manca la directory principale)" + +#: document.cpp:60 +#, kde-format +msgid "No content found in the document" +msgstr "Non è stato trovato alcun contenuto nel documento" + +#: document.cpp:71 +#, kde-format +msgid "Invalid XML document: %1" +msgstr "Documento XML non valido: %1" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook" +msgstr "FictionBook" + +#: generator_fb.cpp:29 +#, kde-format +msgid "FictionBook Backend Configuration" +msgstr "Configurazione del backend FictionBook" + +#~ msgid "Fiction Book Backend" +#~ msgstr "Backend Fiction Book" + +#~ msgid "A renderer for FictionBook eBooks" +#~ msgstr "Un visualizzatore per ebook FictionBook" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Title" +#~ msgstr "Titolo" + +#~ msgid "Author" +#~ msgstr "Autore" + +#~ msgid "Producer" +#~ msgstr "Produttore" + +#~ msgid "Created" +#~ msgstr "Creato" + +#~ msgid "Creator" +#~ msgstr "Creatore" diff --git a/po/it/okular_ghostview.po b/po/it/okular_ghostview.po new file mode 100644 index 0000000..1510f3f --- /dev/null +++ b/po/it/okular_ghostview.po @@ -0,0 +1,122 @@ +# translation of okular_ghostview.po to Italian +# Luciano Montanaro , 2003, 2005. +# Daniele Medri , 2003. +# Andrea Rizzi , 2004. +# Federico Cozzi , 2004, 2005. +# Federico Zenith , 2004. +# Luigi Toscano , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_ghostview\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2009-06-03 15:53+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#. i18n: ectx: label, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:9 +#, kde-format +msgid "Use Platform Fonts" +msgstr "Usa i caratteri della piattaforma" + +#. i18n: ectx: whatsthis, entry (PlatformFonts), group (General) +#: conf/gssettings.kcfg:10 +#, kde-format +msgid "" +"Determines whether Ghostscript should be allowed to use platform fonts, if " +"false only usage of fonts embedded in the document will be allowed." +msgstr "" +"Determina se Ghostscript è autorizzato a usare i caratteri della " +"piattaforma, se falsa è permesso l'uso dei soli caratteri inseriti nel " +"documento." + +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: conf/gssettingswidget.ui:28 +#, kde-format +msgid "General Settings" +msgstr "Impostazioni generali" + +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_PlatformFonts) +#: conf/gssettingswidget.ui:37 +#, kde-format +msgid "&Use platform fonts" +msgstr "&Usa i caratteri della piattaforma" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript" +msgstr "Ghostscript" + +#: generator_ghostview.cpp:84 +#, kde-format +msgid "Ghostscript Backend Configuration" +msgstr "Configurazione del backend Ghostscript" + +#: generator_ghostview.cpp:248 +#, kde-format +msgid "Document version" +msgstr "Versione documento" + +#: generator_ghostview.cpp:253 +#, kde-format +msgid "Language Level" +msgstr "Livello del linguaggio" + +#~ msgid "PS Backend" +#~ msgstr "Backend PS" + +#~ msgid "A PostScript file renderer." +#~ msgstr "Un visualizzatore di file PostScript." + +#~ msgid "© 2007-2008 Albert Astals Cid" +#~ msgstr "© 2007-2008 Albert Astals Cid" + +#~ msgid "Based on the Spectre library." +#~ msgstr "Basato sulla libreria Spectre." + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "" +#~ "Anti-aliasing makes the result look better, but it makes the display take " +#~ "longer" +#~ msgstr "" +#~ "L'antialias migliora l'aspetto del risultato, ma la visualizzazione " +#~ "richiede più tempo" + +#~ msgid "&Enable anti-aliasing of fonts" +#~ msgstr "&Abilita l'antialias dei caratteri" + +#~ msgid "&Enable anti-aliasing of graphics" +#~ msgstr "&Abilita l'antialias delle immagini" + +#~ msgid "" +#~ "Ghostscript is the basic renderer (the program which draws the " +#~ "picture)
    \n" +#~ "In case of problems you might want to see its error messages" +#~ msgstr "" +#~ "Ghostscript è il renderer (il programma che disegna l'immagine) di " +#~ "base
    \n" +#~ "In caso di problemi puoi provare a guardare i suoi messaggi di errore" + +#~ msgid "&Show Ghostscript messages in a separate box" +#~ msgstr "&Mostra i messaggi di Ghostscript in un riquadro a parte" + +#~ msgid "Ghostscript Configuration" +#~ msgstr "Configurazione di Ghostscript" diff --git a/po/it/okular_kimgio.po b/po/it/okular_kimgio.po new file mode 100644 index 0000000..59f3444 --- /dev/null +++ b/po/it/okular_kimgio.po @@ -0,0 +1,70 @@ +# translation of okular_kimgio.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# Luigi Toscano , 2007, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_kimgio\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-05-20 03:08+0200\n" +"PO-Revision-Date: 2017-11-19 19:51+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_kimgio.cpp:56 generator_kimgio.cpp:79 +#, kde-format +msgid "Unable to load document: %1" +msgstr "Impossibile caricare il documento: %1" + +#: generator_kimgio.cpp:77 +#, kde-format +msgid "" +"This document appears malformed. Here is a best approximation of the " +"document's intended appearance." +msgstr "" +"Il documento sembra essere malformato. Questa è la migliore approssimazione " +"dell'aspetto desiderato del documento." + +#~ msgid "Image Backend" +#~ msgstr "Backend immagini" + +#~ msgid "A simple image backend" +#~ msgstr "Un semplice backend per le immagini" + +#~ msgid "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" +#~ msgstr "" +#~ "© 2005, 2009 Albert Astals Cid\n" +#~ "© 2006-2007 Pino Toscano\n" +#~ "© 2006-2007 Tobias Koenig" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" + +#~ msgid "Main Toolbar" +#~ msgstr "Barra degli strumenti principale" diff --git a/po/it/okular_markdown.po b/po/it/okular_markdown.po new file mode 100644 index 0000000..11c4b72 --- /dev/null +++ b/po/it/okular_markdown.po @@ -0,0 +1,53 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the okular package. +# Luigi Toscano , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-04-02 00:18+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 2.0\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: converter.cpp:65 +#, kde-format +msgid "Failed to open the document" +msgstr "Impossibile aprire il documento" + +#: converter.cpp:105 +#, kde-format +msgid "Failed to compile the Markdown document." +msgstr "Impossibile compilare il documento Markdown." + +#: generator_md.cpp:59 +#, kde-format +msgid "Enable SmartyPants formatting" +msgstr "Abilita la formattazione SmartyPants" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown" +msgstr "Markdown" + +#: generator_md.cpp:61 +#, kde-format +msgid "Markdown Backend Configuration" +msgstr "Configurazione del backend Markdown" diff --git a/po/it/okular_mobi.po b/po/it/okular_mobi.po new file mode 100644 index 0000000..1234998 --- /dev/null +++ b/po/it/okular_mobi.po @@ -0,0 +1,63 @@ +# translation of okular_mobi.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_mobi\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-22 20:11+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: converter.cpp:62 +#, kde-format +msgid "Error while opening the Mobipocket document." +msgstr "Errore durante l'apertura di un documento Mobipocket." + +#: converter.cpp:67 +#, kde-format +msgid "" +"This book is protected by DRM and can be displayed only on designated device" +msgstr "" +"Questo libro è protetto da sistemi di gestione di diritti d'autore (DRM) e " +"può essere visualizzato solo su particolari dispositivi scelti" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket" +msgstr "Mobipocket" + +#: generator_mobi.cpp:28 +#, kde-format +msgid "Mobipocket Backend Configuration" +msgstr "Configurazione del backend Mobipocket" + +#~ msgid "Mobipocket Backend" +#~ msgstr "Backend Mobipocket" + +#~ msgid "A mobipocket backend" +#~ msgstr "Un backend mobipocket" + +#~ msgid "© 2008-2009 Jakub Stachowski" +#~ msgstr "© 2008-2009 Jakub Stachowski" + +#~ msgid "Jakub Stachowski" +#~ msgstr "Jakub Stachowski" diff --git a/po/it/okular_plucker.po b/po/it/okular_plucker.po new file mode 100644 index 0000000..bcdc71c --- /dev/null +++ b/po/it/okular_plucker.po @@ -0,0 +1,45 @@ +# translation of okular_plucker.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_plucker\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-07-11 17:08+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_plucker.cpp:75 +#, kde-format +msgid "Name" +msgstr "Nome" + +#~ msgid "Plucker Document Backend" +#~ msgstr "Backend documenti Plucker" + +#~ msgid "A renderer for Plucker eBooks" +#~ msgstr "Un visualizzatore per ebook Plucker" + +#~ msgid "© 2007-2008 Tobias Koenig" +#~ msgstr "© 2007-2008 Tobias Koenig" + +#~ msgid "Tobias Koenig" +#~ msgstr "Tobias Koenig" diff --git a/po/it/okular_poppler.po b/po/it/okular_poppler.po new file mode 100644 index 0000000..0b7fa3d --- /dev/null +++ b/po/it/okular_poppler.po @@ -0,0 +1,234 @@ +# translation of okular_poppler.po to Italian +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# Daniele Medri , 2003. +# Federico Cozzi , 2004. +# Enrico Ros , 2005. +# Andrea Rizzi , 2005. +# Nicola Ruggero , 2005, 2006. +# Nicola Ruggero , 2006, 2007. +# Luigi Toscano , 2007, 2008, 2009, 2010, 2012, 2013, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular_poppler\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-10-24 02:18+0200\n" +"PO-Revision-Date: 2019-03-03 01:08+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.08.2\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#. i18n: ectx: property (text), widget (QLabel, label) +#: conf/pdfsettingswidget.ui:12 +#, kde-format +msgid "Enhance thin lines:" +msgstr "Ottimizza linee sottili:" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:23 generator_pdf.cpp:829 +#, kde-format +msgid "No" +msgstr "No" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:28 +#, kde-format +msgid "Solid" +msgstr "Pieno" + +#. i18n: ectx: property (text), item, widget (KComboBox, kcfg_EnhanceThinLines) +#: conf/pdfsettingswidget.ui:33 +#, kde-format +msgid "Shape" +msgstr "Figura" + +#: generator_pdf.cpp:85 +#, kde-format +msgid "PDF Options" +msgstr "Opzioni PDF" + +#: generator_pdf.cpp:87 +#, kde-format +msgid "Print annotations" +msgstr "Stampa annotazioni" + +#: generator_pdf.cpp:88 +#, kde-format +msgid "Include annotations in the printed document" +msgstr "Includi le annotazioni nel documento stampato" + +#: generator_pdf.cpp:89 +#, kde-format +msgid "" +"Includes annotations in the printed document. You can disable this if you " +"want to print the original unannotated document." +msgstr "" +"Includi le annotazioni nel documento stampato. Puoi disabilitare questa " +"opzione se vuoi stampare il documento originale senza annotazioni." + +#: generator_pdf.cpp:91 +#, kde-format +msgid "Force rasterization" +msgstr "Forza trasformazione" + +#: generator_pdf.cpp:92 +#, kde-format +msgid "Rasterize into an image before printing" +msgstr "Trasforma in immagine prima di stampare" + +#: generator_pdf.cpp:93 +#, kde-format +msgid "" +"Forces the rasterization of each page into an image before printing it. This " +"usually gives somewhat worse results, but is useful when printing documents " +"that appear to print incorrectly." +msgstr "" +"Forza la trasformazione di ciascuna pagina in immagine prima di stamparla. " +"Normalmente questo produce dei pessimi risultati ma è utile quando si " +"stampano documenti che appaiono stampati male." + +#: generator_pdf.cpp:100 +#, kde-format +msgid "Fit to printable area" +msgstr "Adatta all'area stampabile" + +#: generator_pdf.cpp:101 +#, kde-format +msgid "Fit to full page" +msgstr "Adatta alla pagina" + +#: generator_pdf.cpp:102 +#, kde-format +msgid "None; print original size" +msgstr "Nessuna; stampa la dimensione originale" + +#: generator_pdf.cpp:103 +#, kde-format +msgid "Scaling mode for the printed pages" +msgstr "Modalità di scala per le pagine stampate" + +#: generator_pdf.cpp:104 +#, kde-format +msgid "Scale mode:" +msgstr "Modalità di scala:" + +#: generator_pdf.cpp:827 +#, kde-format +msgctxt "PDF v. " +msgid "PDF v. %1.%2" +msgstr "PDF v. %1.%2" + +#: generator_pdf.cpp:827 +#, kde-format +msgid "Format" +msgstr "Formato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Encrypted" +msgstr "Cifrato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Unencrypted" +msgstr "Non cifrato" + +#: generator_pdf.cpp:828 +#, kde-format +msgid "Security" +msgstr "Sicurezza" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Yes" +msgstr "Sì" + +#: generator_pdf.cpp:829 +#, kde-format +msgid "Optimized" +msgstr "Ottimizzato" + +#: generator_pdf.cpp:1435 +#, kde-format +msgid "Using Poppler %1" +msgstr "In uso Poppler %1" + +#: generator_pdf.cpp:1437 +#, kde-format +msgid "" +"Using Poppler %1\n" +"\n" +"Built against Poppler %2" +msgstr "" +"In uso Poppler %1\n" +"\n" +"Compilato usando Poppler %2" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF" +msgstr "PDF" + +#: generator_pdf.cpp:1470 +#, kde-format +msgid "PDF Backend Configuration" +msgstr "Configurazione del backend PDF" + +#: pdfsignatureutils.cpp:42 pdfsignatureutils.cpp:48 +#, kde-format +msgid "Not Available" +msgstr "Non disponibile" + +#~ msgid "Select rasterization to enable this!" +#~ msgstr "Seleziona la rasterizzazione per abilitarlo." + +#~ msgid "PDF Backend" +#~ msgstr "Backend PDF" + +#~ msgid "A PDF file renderer" +#~ msgstr "Un visualizzatore di file PDF" + +#~ msgid "© 2005-2008 Albert Astals Cid" +#~ msgstr "© 2005-2008 Albert Astals Cid" + +#~ msgid "Albert Astals Cid" +#~ msgstr "Albert Astals Cid" + +#~ msgid "Saving files with /Encrypt is not supported." +#~ msgstr "Il salvataggio di file con /Encrypt non è supportato." + +#~ msgid "Unknown" +#~ msgstr "Sconosciuto" + +#~ msgid "Unknown Date" +#~ msgstr "Data sconosciuta" + +#~ msgid "Unknown Encryption" +#~ msgstr "Cifratura sconosciuta" + +#~ msgid "Unknown Optimization" +#~ msgstr "Ottimizzazione sconosciuta" + +#~ msgid "Please enter the password to read the document:" +#~ msgstr "Per favore inserisci la password per leggere il documento:" + +#~ msgid "Incorrect password. Try again:" +#~ msgstr "Password non corretta. Riprova:" + +#~ msgid "Document Password" +#~ msgstr "Password del documento" diff --git a/po/it/okular_tiff.po b/po/it/okular_tiff.po new file mode 100644 index 0000000..5ce0bb0 --- /dev/null +++ b/po/it/okular_tiff.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR This file is copyright: +# This file is distributed under the same license as the okular package. +# Luigi Toscano , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: okular\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-09 02:09+0200\n" +"PO-Revision-Date: 2020-07-15 23:41+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.04.1\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" diff --git a/po/it/okular_txt.po b/po/it/okular_txt.po new file mode 100644 index 0000000..4884bf5 --- /dev/null +++ b/po/it/okular_txt.po @@ -0,0 +1,49 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2013. +msgid "" +msgstr "" +"Project-Id-Version: okular_txt\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2013-06-22 20:46+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt" +msgstr "Txt" + +#: generator_txt.cpp:28 +#, kde-format +msgid "Txt Backend Configuration" +msgstr "Configurazione del backend di testo" + +#~ msgid "Txt Backend" +#~ msgstr "Backend di testo semplice" + +#~ msgid "Txt backend." +#~ msgstr "Backend di testo semplice." + +#~ msgid "© 2013 Azat Khuzhin" +#~ msgstr "© 2013 Azat Khuzhin" + +#~ msgid "Azat Khuzhin" +#~ msgstr "Azat Khuzhin" diff --git a/po/it/okular_xps.po b/po/it/okular_xps.po new file mode 100644 index 0000000..75be363 --- /dev/null +++ b/po/it/okular_xps.po @@ -0,0 +1,57 @@ +# translation of okular_xps.po to Italian +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the PACKAGE package. +# +# Luigi Toscano , 2007. +msgid "" +msgstr "" +"Project-Id-Version: okular_xps\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2020-07-12 02:08+0200\n" +"PO-Revision-Date: 2008-11-18 19:26+0100\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, kde-format +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Luigi Toscano" + +#, kde-format +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "luigi.toscano@tiscali.it" + +#: generator_xps.cpp:1948 +#, kde-format +msgid "Revision" +msgstr "Revisione" + +#~ msgid "XPS Backend" +#~ msgstr "Backend XPS" + +#~ msgid "An XPS backend" +#~ msgstr "Un backend per XPS" + +#~ msgid "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" +#~ msgstr "" +#~ "© 2006-2007 Brad Hards\n" +#~ "© 2007 Jiri Klement\n" +#~ "© 2008 Pino Toscano" + +#~ msgid "Brad Hards" +#~ msgstr "Brad Hards" + +#~ msgid "Jiri Klement" +#~ msgstr "Jiri Klement" + +#~ msgid "Pino Toscano" +#~ msgstr "Pino Toscano" diff --git a/po/it/org.kde.active.documentviewer.po b/po/it/org.kde.active.documentviewer.po new file mode 100644 index 0000000..7687096 --- /dev/null +++ b/po/it/org.kde.active.documentviewer.po @@ -0,0 +1,80 @@ +# Copyright (C) YEAR This_file_is_part_of_KDE +# This file is distributed under the same license as the okular package. +# Luigi Toscano , 2012, 2016, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: org.kde.active.documentviewer\n" +"Report-Msgid-Bugs-To: https://bugs.kde.org\n" +"POT-Creation-Date: 2019-12-15 03:11+0100\n" +"PO-Revision-Date: 2019-08-07 23:31+0200\n" +"Last-Translator: Luigi Toscano \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 20.08.2\n" + +#: package/contents/ui/main.qml:32 +msgid "Okular" +msgstr "Okular" + +#: package/contents/ui/main.qml:46 +msgid "Open..." +msgstr "Apri..." + +#: package/contents/ui/MainView.qml:36 +msgid "Remove bookmark" +msgstr "Rimuovi il segnalibro" + +#: package/contents/ui/MainView.qml:36 +msgid "Bookmark this page" +msgstr "Salva questa pagina nei segnalibri" + +#: package/contents/ui/OkularDrawer.qml:72 +msgid "Thumbnails" +msgstr "Miniature" + +#: package/contents/ui/OkularDrawer.qml:86 +msgid "Table of contents" +msgstr "Indice" + +#: package/contents/ui/OkularDrawer.qml:100 +msgid "Bookmarks" +msgstr "Segnalibri" + +#: package/contents/ui/TableOfContents.qml:34 +#: package/contents/ui/Thumbnails.qml:34 +msgid "Search..." +msgstr "Cerca..." + +#: package/contents/ui/ThumbnailsBase.qml:35 +msgid "No results found." +msgstr "Nessun risultato trovato." + +#~ msgid "Document to open..." +#~ msgstr "Documento da aprire..." + +#~ msgid "" +#~ "No Documents found. To start to read, put some files in the Documents " +#~ "folder of your device." +#~ msgstr "" +#~ "Nessun documento trovato. Per iniziare a leggere, metti alcuni file nella " +#~ "cartella Documenti del tuo dispositivo." + +#~ msgid "Document viewer for Plasma Active using Okular" +#~ msgstr "Visore di documenti basato su Okular per Plasma Active" + +#~ msgid "Reader" +#~ msgstr "Lettore" + +#~ msgid "Copyright 2012 Marco Martin" +#~ msgstr "Copyright 2012 Marco Martin" + +#~ msgid "Marco Martin" +#~ msgstr "Marco Martin" + +#~ msgid "URL of the file to open" +#~ msgstr "Indirizzo (URL) del file da aprire" diff --git a/po/ja/docs/okular/configure.png b/po/ja/docs/okular/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..cff04a75d9c2f85c88f2fe6aec126518a0a1622b GIT binary patch literal 87667 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

    RQW|Bk#gcv~W|O<5`&w3fgD}h9gn*^QOpK0HqK; zy@oucxax-=8vb}AGR!bOX`nHCiE2i>&^1AoscW8%ID$u|`1EI{i zwUsq>tZZy_)Y?nQD2ID^lr%Bh)(hqNymvPlCVs1X?yOInO}6<#U$qXryRA6HbukR%iIv+Zs3j^971Ok~wEQ~r&fo5Q6zNVeuIHl9 zzioH0O&N0KKfU&&y`{|XO8-a~@q9CQkE|FGfzbXOsA6NYEOz047(Ghv?BHO0xp1Gt z-X+Zz&K+87nfX!0u11Bh!k$_tX-@GN|E#{o_-1ou9jr1$#j@4D@%c9WR6u`qwN!@x zoEdKY+DJnKd(=&Mra*|{<>+G4phqGjB7>%?rsibytUKcc2n#nCv$Kg4M+dD+;kpf- zd&{beA%r(ez_u)yr^(j2TaqZ&cQar0-R#fv^|Y;Hqx-`ZmDJZUoS#RY|83$wy9!Bq z8QV&xbbojI$jHbr;C^T@a)h=8ZtLUh?P&fl7K>FXQli1E`K7vft}81kYK+YB z_!iH8t2#F3i>mei6w&HbG+JbDt-Ok4p+-!J7SDLuGNH=IV{iHvr6Uo~X26WMGB0H2 z*5PC-#ix^L(G-5D?4m9iS8m{L=TpjK(c~+^B_DNC;Xsw4<%t{u1E25W?8t3v`<|Di z({Ey&eq~uJk9VIt;SprQPw43QsqiSNa)?SAg^2IpaQLp2V0Q%M!lU}x--6o$6zuuBw zr>!ps^}XliEjOt8LEJ!!YUwMWH7i69U9N42z26N7G7 zRV7-`(A9-v+2gTN@3R?5pDwCi0hT4?nN4nDmlMo)OtdFSpnP=AI8FOR|3iL$0i(vL zxTNSq9L!C`y94v%k+5xVyQU%v{h{Nwl;F8aNn^*wP^J^*w35>N-ncPl40DTNXGj;k z1z4MPXl=sOLR*Ox|I&H_=7qZ?ys=bxlQ4Qsy@#GDE4WMlkTZ+e&RWZaQ^hcq%?uG# zE{jei=GkCZ&{*0meOvSutt!tX;A080CRv@|bh>k%Fxld8^$4YAt>0l2oQ??SQs9oW(7hvg*oc2C8VEyhmF~%sza!$BM?&G<0f9PfrH`S+kE({3@^Q z)|2~f`{k^LyveC%AAc<^EzQqcG(*8F(vR<{a@JK)z%xGu51z-5vh-QJ6t)9mXm_VhrDz`XoS7h~~~z6n$KoA;-4`+H&4 z&3UWWiM5sGCAy3<2DI?y^mN+-f9Iq58JEtz^cBDHB0@#ft<~fB{MRgFvW$#0ddM3Tf`@efb74mKd5n5zG;xsd{(Rkk z>qmwW80;B(knf=~aFHYWa;$3_$jZfaoo?vdc~alq|8ysmv(9ThL0hBSu)LfEL_pBG zc4Mz4ZNS^fBF`t6Q*}FwYxy`TYKP0*^jk~cT z4k0|u+RHF9(L_|yYg<;L&f!%&c|$BWl_G2-GxN-!{2nN5U~ zy40hXNDq&)fBl6z9Mnq?2y$MWooR$mCHm$#Gd8yfT{6M=0y~Q4f^A|vE_PNU*q8Dm`Y7mvxEYwNEBK)@=OrCr17;ozkd=E6a-?jwY9Z*E-r!m zipY4QvHbP!EJ?y7NdqYGB`5stlZS#7j}YHlI#Zysl3X~Jq`LK~xA>>S#!*9-^rBJn zf?Nm+h$u@xIFG~OWz7^3od{pOytUQG&o37vr0AmW$@ym{M?4zZ8U-^bMcBj-5u zY17ap%{n~BE9R1DCD#&a(1R!`9^o2KF8~Bp_A-8T^Lcn{T>{${&(p_hO~2_%ryt0( zL|H)@DVaJr;90^f?vM7Ey_&3^aw;rafs;$|3fVHAwRiK>St?qqNu-r%=*M_zI+XY| z=KHA@6MDaxElT#1v8_i)uQB)H{{2YSS!j!KvZ|wTfWPISyffFT18XZ=W&=FrmTO0K zb#+nS#?EDFX?fSWbL0Z}x$jwG3_wu;J_|s#YinzJdW4%IWFJLvQM7e+S5{UIXf@<* zY)pdsD3Kd`>Vq!K@(kU&kRu0|w6)RV5X=-RV@6_%1B@yE`ODz(g#_x1REPdFN@T^)zuk8Xv7(~xNvTMR$KEEIohgi6yTe2udp)t zfkoAH$*%c1e#E--2G;IzSz}2zFk3>ndoPOY8qPJunJF;*b7*B7XytKaZr1!jpV`odk2#4xIo2>&O5fEs)Ke=;;RRzuga&=g^Y3 zb6j!6sb)7c<=ebSn_APce?*)sX?GSzEMuJ~p>OdyK0K_fu61;FzWXe!6Fa=;ZCI!C zP%|3T-``s|b#cG4yi8Y7dc(xvDwx-G-UtA7O~u7!Wwa_(0Isi|GCJPcMHm1f(Oz4m}X$z)HOibH) zvQCPJKY zc5Y*1aVn11kIPveJJ&Ce6dx>LV8}7l)sm?Z&64r^lz3`c8gQlFxJ+)o%tpoi)#h z0TfXzaO@d+emDCDm>h6uD@Wq}e=R_B$>5eJ!0e%s2y%Z%Y%UaLq``zgoXynuGR-v# zDm=Ix9}`#j7nf!(y-eKIQ)%%Rx{8(+5t0;UW&3sSuD$e1cS@KhyYb+x0%(d(TMk;Nrh4%;#CO*9V1k94$F1CiwR2)bdBX0j^&7ogg zl<#}qY>ux`Yr!vlg*Ak|#IcK$YLx42brSMf_SKYl3*Y10*gYT5L5;+D>XDTer@zev zsh2wi8XHMT08ST6Q^Z#rvhBXmMb?ePnx#Yzut{+3=m0$ z#~UzM`7B*mt5=qE%w%4=RE92P;V3oja-0<#K4&UD7cyU=TCmu{y^hauxG#`;CglB_ z%cp*D>sMdk)4p;JU<=O9z{kUd?t2rv-)Ot!OW%x1&sOo&;%G69B^RG+EIGA5@GxX4 zw%~jxp81h)kIYVY%@`}ErZ`e8l06bK&x(IAPTORPO66B=7>TzjCnUN)9b$2M^9?2|p8;-Vq^8nD5mKg(FE*kVQlKqG$zSKR@Ae!Y z=Hew55f_b#XvSKV@FG|~3)FQK2 zLjnq066}iVUk$2dkyp>WJ)E5t?5o>rmsMNseu~>eVi%E@~C5kRZcLgSQ3PisPorpSTbV zkV}*GR4Zy4x)ekYq3!H>^~|~aH@=cbW}JT82gUx(j~T?iH?(PS^CnJr3?hYxQ(Mx= zi2}pN4<)?{=!7;9%{@49mi#GC=>nsDx81FrLdKCw{^waJ z^GFgV^O#o(iywi$Zv7HzOG=7?`!UMLh#?Jd1pK}C9goXT{JEDhW^r0s5gV4kn-Q>Z zokdNKnRnWg&WxIJ@&qlNx`+jqB;?V_j|Du$DPIKk;{~IffhUAAAXkEgrCB~qZ{j_e zAhl~hN9jQ8#z5tAXvxD5Odm(nCCz1db7RfuZtT;nUqc5;syU zJ3WsD*h+I6Mnj6ZJi%Ul<#w6;+$&1i7~-gn6KXOEQ3=U=>ZRy#%Wqv-;u%uglGRcr z+M1B+pbUS7Ky6!=J%N!mlEByOL0^g_~LaM)1`E3TlI#@F=Q%B zkX=&J|FimbIi(`F?nb_akP7@lvKO= zwe%}%)TJ0>m#D)KCsmpNPdT+^KN!Wz^~+1<&x+qzP;L){(`< zjWjX;?f%lYLXD_LYJ%zzvDLCI^yN?nx0B6JuWG7ehbaUC$ffVzsV)+@FTNkaa6crA1U52dZdj@ zzHhFOraeYsiN68uq-&(2bagQEiW3>-S`{AzNb|la$EG1IM{= zJQ&WjZHE}0yPUPP3r$~3coIAV1QipbO>g5al5j-Q= zo+T$Ub)W@&0VGqDE_%-2n7>IbF;&^VwDTfumXU}k+uvrbZ3s+%5Ar+>ViC0$?R+KoGnehck=3*d<%>` z_vGK*_4!L*)dpMY-BEa!9c3^0s-+S1Jq;|q)}U2WW2s|s)05JClAzrQAMIDIFH@O~ zMed*@8+4V566b2v9>!Dkbc&SZjzn|y36%#>Zs=7MX6ZED(%i007UKw5V5haVaxp{X zy^EH5$K`(%psokspCpAD+p7<%sL;Ze7VP5MRDU}m;H0Qr;IE-M<5!DT_j$VU!A_-{ zJ(~wt_>e4KesDs8?P66I`*09rsZ{&Oz*_FkF{QO6Z>_#m`GBCsdd8s$(-r@-*XL2+ zsSb@O$AMjjQEg_rmd8`Gd$_=bnEs2N!oppV6z1|bt6c}pMXVf^6$iOKKN=9%ZKi1> zXm6T<3zi3`U|La@Cx^pZoKm;+*fhqJs3e*C>#H^b-H6lAUkTXFj|en%n#HO_no0At z)~t%{5p<4^sVZ8nU)H*4qCL~a1kmB~;fBlCG0CM(-sWwNzP_bimR`pP#E?mdgj%Xo zV#Ut*Hs-nrdzYS{d2zKZw#ZR%m2fHeANOBosorKhQi?E?&%Q3ASJss}z)KnzmW!{4 z@!Mz#I9Dt2=1qXFKd3c}WUR&T5FO#oyFKJoO z0~LP3Q9*U9ty0BgRImXlx$tNvC;k?ADA1?WnktIJ&A#v_7$P?rkUXWd$KH!R`_{={XWb$upnPY7JAC+0)gh&l zQT}(iD9E14zB7rVqz_!Re}i%F36QKsj01kyqm& zI6^1Q*=2E<0L502n@|<_a?CoQN3IGrVZA>grcY;nP1*VTr&G`D3A>nG6V4*omsw@> zBn97to;~zC((%K1InMeG1M76CsHYvkVjFSlyKvSgTLX{lmS&UUH~l~Ps*6Wx7@8q^|_qsCaP zK6aHRIY^En0x5`<42j-^r1B(CE_$78FIYjFNtfl-RSVxhXlk7N*}k)`59s|J;ECnVZmnA5k#YIK++osK`+D2nQb)A~=gC*O6l(_?r^J8*0SHsWH+d8Rji2!DKZY z#`K#)dwQH=O#{V9K^rYY1u+q~&_MB8&f6Z0Exf{9QFCH7opbTLrW@H#8?{`@VtDxi zS?rx~PAjf>!KlZ;+W}CQtPSZrPGq=`A2&uec8ha%LNK1xhjP;OEWF5>E?VBYH2I3z zqv~{x_prv!C5nY4#e2LX5P!TbG8h^pIm8*eqO;dA1iyb8b9mJFwjJLF)dR&afRLkr z4kuw8yGX>TCaXq|E6XbrgYhZd-n8L_E-JFPKoOCNKZ?gmYgzNcgwrUZvLjv;ZYCG$?x3Xk(b@Hp*?< zgw$ldM3Tnj9Lw=>jPY#MTK*UfPFr!wGVM97TOY6HNEv<&-L3pr5O&U82o;kc!k7Z_ zuP3LcpHAx3mC#9U%mnGv_cOlTU4m;+j1DFw3_Y^%A1gqZWbl{WS>$Xtp}cu)hQ?I^ zA!&+k=oWjh6V_pOA$Gbx(O|ZWum=vNa1bT4kWfD3e^Ti`NyYVTyb|NRI{-Vy$IQpN zF{JIa8tUE`d0|Ra?RlFZchhiZ&+_nZ?|J<7&Yjy>7(SkihoLJ~h%mE=w$vdm^GAV;ciTTk13XCT{FHj9{fvEj#(ee-=*hWMbzT0+47cFoZ*ID?kIXpl$ z^puk{a}q(l*VYW2M#Vfun0W~7yYim=-&twjim8KZGJDqlHFCg`{f_lvD5!I3U<)}M zbM(3~UyK_Nf`<+g$nE6`VwqhkEyg{PT?#Az`e*@5{(Xz?1(* zisKFgSW`?4O8$XdB6;A)>W`n%LB&H~hs9NzR_%EnFf)$ZjNKfIq7yrUe!x7~rN{d} zABMa--fqR--QAto%np=r2F{g$W2uM9cSOe@0pzY0@L6ZZC#*uljX`M$Hx#=-39|~BdyQN`Z%$%D8L82{=e6+?&puUCpgOp z&fRCr0NYeuTDlwhbdjPNAZm(1yo8AQ+&Qg)oWsZIbHQv$h& zAT#rOs>N=f3*&BYvZR;~&PrKNB5e7CdJ4@k4~zlMO@F{%pXX1J6#f#{G8!2gAlU3yu7=+tGCzQ z))pa2MfV?iRo1Dm+t*X;IF>}kmT>~T=u6Yg54egZz-KvJY1k~32#X};*)5J`+j!%@ z*a&|0_;)#~n#=DdHpyXD7-@F0T!)8;SER;3PhZi|@fpAd#k9NwU%k#=D#|X6JS_oE z4|pazx$wUb=2vw24FWH{ozT)bfDSooLk5J=xa zuK#(9-G2%)1wCA-(3*95vO}il_lHE`tHZxLiT$sSCoPJdO-;t_8-B41NAMy3=bg5@ zW9p#4!vu;Het#v5(};z(a^O{VL&*61m>v(5O>ZGe} zO*?u`o@ncW3J3c5dF+q>dDhb@m#Wym*}+j#57a=r)h2829H*hNWPihQ7&tj50OJOP zD=MN7R@>S%sPBWFSlr)R#u&$aqani`owzc}RnDijyhozaf?}uos_cKvKiD%ne?l?M z5sTws1M^^vX(4!A!7#w9C7DAzp2h-jX_Jln0J9MOJMaQ%I4Ia2Tn7e1-M4R!7J&I| z=y<+ro)&%D&v8E2RukV{sn=g@2bm>L|J>H%90NU!dmKIcjV+K&i z%SHPW986a_praU>snOjGSeOb!#6S%B{o6<&@M`xxy=tGDZllMvsQ>cmDnP^);-o+z zUx8Hx46JQmSnHrt-Zayf})~g z>F$sV_@?7CI#qo=D=NzP+`q1$u^b~1PuU9^0U45?;}N(vYr&iAzPlnZkTDDo$BmYw z+~%2V4oe$v@4MffK3uv7Qw49s^Xw}8=8FIeB;u;J8OQ2;(y+;Gu@x- zLkwRW~#R0a`m<6E9kU)>X$Dk$Vc|(4~cjJ_W<%RmVQ><=Sxq6GC*k zi$wrFZ!qY*I;toDs~N%}`oUsK-f+W&tlbsT#PlxI#_4(0Tud?rSR72l`?9&+@aMyY zOq7S1ae|BGQ;ZxyE>5UpIqCFxUAxMP#t)&6|NM5;IHagsP_7wY{uilRqNrV;q!15ElmdqhL8w2c8vvaj$n^ywsWuM<#`p?AQFBp*C~SXsvNhWch7 z1VMMwXx>>eE>PVlv`s`829<<7pXKGSMEH=K3nRS?9s=MrIB^Aqm;iguob~bXtgI~Q z5Mcvgt8sR)w>SE?{XQ%bl_O_L*I1;tuyCdOqDSbgX|l)ULR|`xfZ)Dd5gi`ZXDX}N z_qu#W)N~@;blu|8|014*&jhnrYVF8VC7T;yq{gqR7-Dwkao%3<ZH zt5j80fxq1WwKE6#{&zd7qU+3gXoQFF7}(hAYimyzDlkBl;Ul=6j8CK<4OoT2JCXv~+a*vWO12cv?Nk4?Hz}Bj*16_u;_w z+in;JyhLS#O9#NZA7UR_tW-R%1p zTE+CCWGaeJf!FfzNYto-s2A%B6PzZ^%esD(rvfB}eA9xbewp zKs-_0z+jEN{~3UCDOO_zS)ZX9=(+cr!_=l3HUd+yNS)3n!E6G{&iJ50pNkEEI(c|_ zKvE0MAM=RXu{Zc4g;M;TRI;*~HHrffe4Jr!X+k4D;WEDv{GQ9He}yb7v6$w|{f2)- zON*9hJp;RG({9+_WX5EL$No<$j3NN-7a~o-o7Bzqo2YVEFfrLE)2sm0>GzQoeZg;G z46LjHm&3LNf%~sd6#Vz>!K;SW$0sN3IlNwvH%Gfgnf(8$0|95bNfC6@I6m|`wwTJO zS+0~NS&^ESmM0Ko^bGsohHvQ7={vtW9^C(O*SqvPB$OQXilG2C5qdQ+gzYr@6?0;I z{NdrC04*PCN;$OD0zYm^m;B_>_wCu)+#3?HB{16~8P72dZgsA_Ciew;g#3^NCL%EQ z+&W!d$#b7zG-xyy^4Z(lJ7Z$rsif%6yt+Wu1MZ$~W`pBu0h@w3}=%a!5v zP6nX)gf3Y8wm0AMIrp#)Xjub9H+4;e1cG0M<1PW4Z)(dAc8XDT$ zsg7d=%@9kg>Ol?EbIBvkaqkxL=fk(%C^#nRJXWr_Zg z>=S!FV6pm^uAI&Nuq8*108+<=uC1Bqefv{Yk)JEzu@6xHJRT!)CoUa9V@V|-v%i0+ zXjXQ?1OP+!SJ)I_(bQ%Y4IKfhcR^L8)oo#$_0CH5fUQAGoe>TTnNd2as^o2^7;bF@7%B!Z)*F?5su%G23AJJZ{T<9zb6X)A`*Q zh>(qO@$g;%MPV2snnA1mQYjeN&~J{qv_jB38H03#zKCh{-G zHZ_KpfQKuuAzM!3p{sjlXKh&0)1`we~3avqB_;=!fJ^uMDJBxHQ@al5Z zVfp!S?ZgF@LiBkW7_6BbKBwbFRk4>i->N_HZ+)xt^Vlc|T%4R!wLM~RtG=GC9h#S$Yh-Nf^!K;u zmmOv8_>DL#5?>E9`L>-=V^+eQ7<>vUfh<5OuK@bzeUhKJqI=NcG-ympx+=5WdX+ z`t=X$(jQO6W%E{ZUL+jJUtc{Q>id4zUALGX zb2wb@@AEI7C&`c6sc`QTcF;%o#(>AW5*8H}7M7LmwJfMS0oI+tYDgDT%n$>ZQ;BRm z6B`?12-h^f9=gk`!H6 zSC{Xp>@4pG0Ic-U-?Pj4Cos!9xwy>CC^$R)KK2~M=vE$R#Hb?qUu`n11SV|gz}*>i zuN%9oy**IW)ZE-0h~w<-kN<8BYHDhZtNNYkEHBbd)RD0b4Tc8z zZ2p(qCP;S}u|4!^vyOXtdZwnQ16hY)-t_kNHZU1d3DUkL`uFq-K(mo0J#aSO!rc_ zq_H`2=4a|muK$v6XEh@uBcMZidJF}KVc!8Gsjg;9*bye5`SU$2apk#w3`SyRPXGp- z*6NR<@qyx~9eRdb1dz%i{&)O&(?FSyWlU4w(|NaxA|F5^KL&_`A+@ z8I@I452#R)-2!HKO8$cgXrfL}PXWLD?#nligK1a(T%eagdMPo1kwYqcBag(2*i2^b z1A(h;1H$$zdkHx?Ib-8>AcF-8HTay?TKwXyw1zXAlV1g5n5DWG+zs?u+F zHns+`8aI;$zKU=CJZ}uCfweTJ7Z}?AP3b^#JP;$q6#pj!5xcrwARqPM{aa28)?XzL zJrE2q1~w?5NDSKUvf1V30H}5VM-2!Vz~J$-_RWp{;5WcST8^T}4qNc%092aH+>s|8 zE$!_Ylutll)w#X@VXK{a+4=0(qsawF{o;?J$S$}4aFxFmvMMUm6sC6J2V-zIa?kYS z5Cj(!6AF3?rDkxQa(wK@1IM`CW{D1ro`7o=m92f_!9Yd`!SyrK%b|6WIgAs^>ka6n^!=Te5l z5psyNTwo>hpF3QPe-DxDPP|YwzTawkdW0wufw2BTL6{Os{EwsH19xT z7xUv|uF$B2p`8D(1^DqDKjjQ0jP-xv7j#5F%$ex1=e_;qS{e`KPWIJ^FW=P`(%+m` zTVGQ(Rft6VJo!nT?d*V}F!IFFEmv1kxn)@484ptWYtk2<12sLzPtF8kuTsl2z-l1; zI7U#pRZJvb#d(&rlruAkrnM~p{paicW&8!AnmyJBBE4YPiEFSn(y_-OO~n;_{S zgBf~9H*|@-$};`AV4m-P|L-7}2}ppTw`Z^gGn+2ktYCc^(osc=j^e(Blr86@ziDUA z?9c^$^$XUTix_MYN^$h>?v=N^|NGOYaA3i9QnOvT(%Jg;_3VwgJxBKQvOQLv;!hfU54?1)c&PXkL<)IEYcoq(kaQv_Nu2w((P51q0e1!ZE^S`&j@3hUn zOQs%o&?i~ate{Sn=Gg@_>;DEZlF{$~koDD3QGL2na}bGk|n=cMsh#H1GKRt+(D=@A;P^40Gq6d-mR+It{n!@7{J3;|!DhnB|js zoJQdevQ5@7elL!p8n>RzWz?ff_zMBq6FGrSG4G?!dv2`R!6qRZzinK|%8}pB*)n;7jGG&2f!ZAcP>lJu z2r)ADr~Smhxz^NLFFl#Qvbwu(e?Sxl6RnrA*N#6 zaPQ#j`DJ45Mv-X+2Cd4%i}CkfujT^9n%xq!OK2ewXypNnB=zE?)C=;fq|>i6{~C)? ze|DRXrufQ;BHU2I>(>86U|Xi5w$)yyS~vKl1@N$dd@XM{aWHk!mTUOTE1|agM924s z&CoUN^4-$N9DajwRY?6!8y9|i_yV@x9GKKxRo;uETKkAMN(n>0S#$YZogHS#Xd|pd zkr#~r+`{tXewp~NLU$Lty}jMj*9)FQuz`eV5rUg^t`jsjr(^48s-|WnD(dKXs<(OI zz^^{J(YRSHx8%QFc8b`I(E5J;S)z^gg5LZSh;G2~*YL|uMyt(6TY`W}RGkpkpGl^2 z6=)VxTc5=bokGmw#{{(-%{FTiMJE#jF+n%1rTr9xWM*l~^^Xg?L94Jr$TCbuL1DSx zNaE9{F}+}CfoK?{l^6%%S3fIaD1;)sj*+6qBO6=un}iID(0id?x}Ux(o+jC>Ow!8_ zOEV*6+?o2j*r};ZbcbP#CT+B4TUTl3{yfnItE}a#$=sHfDEg)aW*5GI90d<=u zJEF7>{_nxqCJ^`z`*iCmmlFd&%IywWy(A%(z8VM~@uoUve%k zUEVpTO9xH62NkE#2`+<`;U`jYOWtR4yq!mI(Az375cIygVO1oQhr1bNeIdVxrhMhR zIJ}l&_~pFa;E(qa1h>2WtVhtJB~Z_L^9Tw}+;nv*aH{zBA!R=EHR^gEF2^f>{eEu& zFoudhBw^W9Tw)B{_=pPy)~IG5XK$DB zRrCh@8OBRVWKjRWEPL{Aq67e0`4iSAclb{}p@$9S*-6bGON@4_t%7v&l_HC zBYfM5ThJ6RB7-IchcL})c3^vod)>e${xC|(*tig2?hsnD#uz&`+wlhqKzH#Ur; zG@YL&ey$dpJBKB-g>EtAKOELO)n>MGk51ZEIsna>^75@Ur6ZYO~zkTy1lBlBuO<69S-DSzh zYgxD!IE=eN!y#X50C4_JPA1ptInY%+CX(aCkp!qvg#c4;eP( z-#mwv_X5(_*H^|qhS7nd_FxzZ-<|xD{&JWI5Im5zl)Mbyo9%2c-XF|al`ev*wI`PP z!1dNB=Fw|zLdNgrqhzvbqJ7}9g*&K;e~2S1cysXs3$Eagm* z1-nPn`Vdcs_uZ%rYm4JTd3V!kU!iH`b=+%0p|f*kDHcMAikceP?$k@}x1*xV8UKC* zLcsjN!%846aOhoML*=nYG;Y6@tk?riA`<@ciNaW-wLgvCb&QV=KjM(6o|9DnV71`eUTG*(hKB z>(^;%q_1D+hy21si8g0%SQu49$eg19m0ZHTL$e z_s8uqK!~b}+y!9+5C-F;XD~%_WUMI#-KC55OMWv@jsp=3C;NUM^OM71>~eHYMKXZz z!j6O~{_8+NkBvc{9sx1ZP@XK$t*ETv85tpRPUewnvq5-0Y5VG@5&8GMmx)L3&bnfF z{`>yVD1oqF?W`<%(`C68XEWX~2an6_O4(xFzZC*$t{nP5H)UOt?>^rtTa5cPml6q4 zTr6ad$1$;U>HW{|%fJ-)0b^?=O#LCWIKpq@{xK21J9QP%Rao?2d*uELcKTC@>HaMK6oKdRb@%T9PghM7 zpXu3dkHZX4ol@DnPA2{ge;-m-?~W^WVj;*h?rx!o<*qH7lHUL-%2V zbH|enKlX-*7P{lDInh6ap?}7pB*E>p=f-%MGVn!e#Ur}Cb@rg9m!5!pobLdNzqzXD z-u5e!N5)lJRNtT}Ql#w#%Coh#Q54n*}h3Ek>m6t8=d?xKM03M`al zMR)mY54E7^V+q)_x|LPFAVk@brM0^fv=l99zJ*4N8Fv#H-E3~mUl7iO43H~-^(MsdYcxzOmgJlWy|`Y zD6n}opiNlva#V<(eh?p(+D>u*IGFEl6-)n5JE85tDSS{SF<8b?mpLuK6?}>O@Hm9; z-cTLqDb4q^L}#7lef8$jbjPaouu?`Wn~49GmN3bAkx#!|b=s_LzxMJ`m4>xA&+7m- zWE!Qo4n^S2r26Pj+Y7s3*3{#z;!cCr$EfXF9*BGvCSkQlO+o%^$dT%f;LkW9zf_;+ zWFu~ts5+xE|DFLZiM7M#e=_(1tP>Kg{Yt`JO@8=R!6FP>PUvy-#k`S7evkD#Z5}W4R zg|?WfN$fsm-ifGxLnHzcuYm_v_cg`&>Lck%_(y$BpFCvmhWY1sN~lO(aY8uF2F6lf z`w?U5*4`yW8C%%GKWwDaTJED3-MSN2`1>QU{jNVy_2PZS+uow?L5s1l>T9N4FCjxO z#=Ce0{nzr}N%>Pt@=IWc!`}S3dt#B8Fn?J`QiHSAL>b8)2?^mjb1AhszeZg8^%52N zOWFY+fu6KuRLU7z1^sNXT4RD6ueECk2Zc0cn5e%PTmAl2H9jd>Qhm*2MpBz^+TuSv z1cSu!oFaW*W09SE`ecm|pK49}E>13vruDPZGbtR5lmL!EeDp20N?Epf5{B2LnghPk z=n*}HD@;_J=*ciewjf%)Kekwr`!J@(_4n>W|6cMTX!`^I^eSN*K}kE|8geQZsxKOK z5Kj;eF!qa2Q#K6LhRd+e!{D^$E>r^Uh#*N4;*rjQ))W>KWc8&r^*a*8{XVsr)vx*q1X*t-p^z?s`YnIA z18N`*)+M*w`z!Quo5e}LAZik<+S+P-d_ul`S35U*UXoyOae&~g+5^eRlGDkRQ4D~M zb`-6izhG1^St$D~T2u)BJ7P(*N}W}SXuEv-L!kv$=7;M;>)Ot?&oseLmb%VJ*0_WG zt)&o;n_7|ldkz0KAw#~1*pYO{(ktTlBY#rFK$q-uPKkIMvk~J<8w%oTB8!-m@O+vN z$ptV&+Fct31O%Y<^*pq+n~;K&@fab`)6?*9ti0iI>&2St-wM3|A3h%u#pX*J@?kN% zKHU^-c|0#SdhvZ(sbRh2@=`+`gmBdtL*?LOp|R9QEk_R;L{PmW@KaR=f6>tjG9%6#1C} zQ`qXaVLy>rqm$AL^$bsLkI6uU|7ee!%RShc=ZiZ>X*L{583k5GMyGlme)6-!Ex^>A zPP|aq*3$xfE6Dhf`uTWw$5`3`RHzn`6Jx#u?emh(TNC2z)ye+9k1*d zbpzPG`C>|&!)ypl46IK+)ScuKgM_=LuouH`n3xv0R58zS&Y9AQ=lWgzjJECQb4v67 zeE;G*WJ%yo=Fr;D-|a+2UNeIX!9kXP$S13e;?jN+p(%{YMuCjV7Sx{UU(2|$M>5HG zRDZ-9LQu9;lZRkLa(qiG71uB?`G%F%51uBTq~i(1GO;vL2rWXs(GF&j#P1#P;_L46 zGPVSSmRAkhw=bik2UBbB&d47n=v`f076sf6H>Bb>$AOP_VWG)jufj>8N;lAYe=;OHa!^-sGqEtQlRp$@4Qnt@+$aLZ$alwmEN@(Zz zC=jF6dh?qC52aBTPVddljn@&hHaGWX$xC$u4yLi+xj8^)ll)tQnE(Q;Y2YK)xqDbU zeKb32%Ko9z01@256gi^!MS*(BqE?nYQ$~oFp^KyRH=2|&{0Tm?7ZUO1>1);J_{5QpA>+99j)M#)$ZqAA5<O*}X1sK|>aSUgkdH4Sd8aL4l#8r*cTHYESGPCN)CL7q-h5#s+U zzR%#(G4dBNj1EIQNq-HhtuyZG{U2ev&M}>MCH6IzhgLUfiYaK76$O1}^=?v9XlWnM zPW7g~oiN}%yHsQqr@>9*_pu!P5*)6!64fIqLEjBUSf2H(G;8EAmL-5d$YSh9vr2aB zgudrg1#A+7=(u97>bU0W@^S&+J8orNpTXVta@-c?<}V?w%YLcB^_^E}FG9t#o=K>= z!8Mr(h`pH2hUiMj<*>a$Yc=!=wpZI(M6#EpL>{$CK&rk}2c)fS76G9-X>_ZnERKrE# z`)BQ&lo)QXB;Be7230U3Bt5d*qQg|}wD%pd_KQ_;v#slzo^6pV2)OW znw-4IB{=0Ay0ep#`{bljJgmm(9`ZM@FlcBm+Z-hay!O?BM`>_jS; zo$Jxm!B|57q^hcR?KRxhUh$2`T8Gq*75?SVg{=kHa0Y-GOvt&<&(8t7&gw%(_vnv2Ckg zSTHTybsdL5_UGygtD~aMne`cde|jxV3kNiY-4Z`Y-)vt6^Pt^qg{qpcg2GW>LVty4 ziIN!{zMPv~47EQo)Fz(q=;#1`e1){P7wz4V3iTQM0s=rgnCm?7<;#}^g$(lvI}c5O z*|YB{+B%gi;SU`jqaNifCG(iu*$H{Or%h>eS>YyMq7r3vlGG-Dm6 zm2q}5YytyL2APEi{l)W1!T(@|6F|`>>Ca#1h-Y+df&R@sneyoTjDq6%tbtlp{KaIg_vm_G3 z>3X@GFllZ-nz5antXimUv(z*ztgm0v4|o$LJl)-Dm6ChEN3W55W%~ChqOM<;CC;Vu6es;EZ=nVyh!PYz;<4!G_VdhL4v0{DBMjvaHRp-1Ts&+Th_%CW!?B0ycp#F=HyF z%lL&_H+>L;1&GkKwRO{mdQu*5jonW&bkBoDo)-~csEs8KQPMfeQYvp_C24SuAy07eo}+h&1biD_J*(q)Y3i9D-R|w)Jqx3K zF4Hj5V=p7j<4`_|c2a&6x9nc3VPRl!#VyD}w@Vo)PrmxL!R<&;j+ld=il2eOd}<)Y z>vF%mqQcVXHf?cg{_o#RbygngnEp*NbWGhwPnYo_b2GDPhU>d8-Y;Iz?jWv_cf0LP z$u*b}5E13q3FepPnc0~U;*$y-?uFa752ydQd}s{_%rVK)lSz`dC-vLxn*?nX772Hm z&+Vo3W`BP_z=KXt*1IdshCrg5rh>j*+Z9?sK)|$}PD~R){>l5UN5HyHQ<^OE5W(>qS~zpM7LE-nPAayfm3kkOG5d!n6BIx60Wch@df zEmt)YWg4$!FHn5dzO}@+s0<@OlHaX`U8fBRyhim+eqY^KgOc_#X^@4f0D%jLV1f{BZ&Tf?^wMK-l|nGyDPjQH7zSbaeMR zvwnG&XyfJmE%w#Po+YXjYa9V{V$3FPm>4A`<&sR2pZ zJM~`!JxXOk5M$0!Ux2(k1oA4X>sqh@(37}m!c8+dtNoP0~(%po#1OdV&qT(=ay@Ar=Wwx6{h_{T7_NquI;dAOFrQl;r81q)?a-vo8bV-d8cuz_ zGY_*c%-XG%#`o^KHHN#`IiBSX+8i8gBG>8YnQyaGQ)ll@Qwa$0mvt>cy^iL}IcRBf z^jmyCcIihd31+lRco78%+o!JPx@Re|us}&jrb@IKrw_ReS|9G8Vm*Cg@rOfBE;7f# z-4PTbr|F@zJcYDp=$Pm&FMZ!#F+f&^7WoJg6UWLrm$0B2bTmDexTwJpNUY>b(ict- zch?^RQ9d8^zJ6_*YYN19m^YCWewdCo`$yGa?!|u=ERv~6g*UXHE7+`CSck2ul#l;9 zm>=y+_c}uBDlINrR8Y-W&Uwuzr;N`cl<`mY!=({Y#HeC>jo+p$%n-xLW6tMuinI3w z&Hm=EQyRv86UmYPA&4H+?FXlr^baWjD6bAiOP!g5aGrdc@%&Rv5{BntO-+dl%{~$h z4Hq<&l-CFIRaJ1H9H_CGD*|1W!g8~8NO6At&gQR$91)rVdZg-4(Ih;MHv>Ch)q-Da zvA*PU`)MgBl7!vxx?)p9Mpe~BOiWB;#vvzgW^U%wpNWl)THOX`n>G@ij}1)v<=%<& z0|W$H?_NQF*Kt#?i+=d9`i)Z5{M{>vu&C(z!mN|GV9VFezTsh3MpkTIlJBR7X(iF} z8s^C{r3xYF1}(9*-eY$a9fOl#|}vOl3Bbau<-0=&F8D}U|E1C6?) z(^fg#+l|;cebLd+fYhU81znORtGfE)>xJ)_>bOi2RhPoc<)9e!Q}uv|@Nh?GXC{_6 zZH@zlp-uTFm3ir=(4}iprJNQd!*UG@oMU%>!3GnA_auUV`G>$fl!eI4>lWy@K~=p`m&X{3 z{MKvif*Dnpoa}i)QsYcB>2&;nc#XDl;*OH`z`~OP9@vQq6-IFgBt^`yd=`)&pyZT2 zTP*!up8E!5WB6srZA}YP#VU{pVL>FN_!)g+yP%LMD?Dp?oPm!fdk(~l@ zV717kQ6G)iUaGvof8~UOy0M(=ajxUxam_%enlgF|KWZ_8vCJldvChk#g`M+(Wf?hG zBz8VZ3}<6%FctO7pXPwW`C2X-?isKWmzr%FFAwPCfBx3kc#^HZ+{_vmXFLp~KtKdp zYdc$Ells_&N&MTBML@u3U|Wg&tze%kAu4h%U043m__;}&DXV^Sm3PXi_5CbQ{o~@m z9=N!(55-(KXEH=W;3>U^TaXFlWoJ9xcMUc~muOc0_;_o(*O;42$HQZi0{=Aokuwzv zBF%{UL^Kf~{A8@u)YJk3_oANv{@jF|gN*vyo02=v@apt*nX&P)rJQCNpQP~A^Mmx% zjHD2H9B>y@29^hH=mLbzmz(bs3f1?Z8sc3s8En3HL3GY{3J`G82;z0IIhg>+rp~#P z16ivzHrlm*gCEkt6Y&D*Xi2FV$$d}O%2wMq5UsnTiI^_}3B$z51%Kz|aby3;TVK$te zlAMh7>fN!qy<~SZ=^m7qNhenLswT8=(@~Xm?{lx(F7FK!`zYAE!38Pyf<-MUYVIqb zuBn-slY<6vKR;fLqfO^nSRn9a#zTY%<8+L-x4YcA*Kh2BZ4!hu+B9!D*Or%ug-4@6 z0On81SCg8WDwD7P;_SVB)WGmAmGCs`BQdY_cH?)q4RKOe^h%C&^mNSh)!d}oHEE4`vm+;ignV6bFgiM&6Mso9D{V6DjYsQc01UILG zh|zTDN405`_o*;M7=Sv!2~(=y!t1_mFr41LgnAGeE;s6W#Z10g`V$eQP z3v7HK2bf$ay2auC2AsM86v?Nj=qegs|B6~{_VvXAs3Bm8eg-L1?kU59*gHFuuo?LO z)JFJ(Df?Ig}=#t@usI$@E3-g0+p!a$ZjV`;XmX z@S?_N91se6`uTw(aa{?d%l&$XvyXO9pAOUN9n4i*8CfAEfc-7tUAXC#6Fz=MDVUA+ zE=lpoRs>0wiiedRnug})j3pmOc5F7%68aq4TjSFH&p3l9;pT-?$ zkRU)S5JN6RhU+LBJOHNEzkwkWF3!O*!_Uac_gz33;&?7XfG~w0#~@LTwyv&#)fUtA z$vSazm?{IFUcF&!%kt<#Z#+^d~B0&~fg6X{P4k@i=El8qNL)2HqBylx&G;V`F34G|pnQby0A} z$#2ScsRI9k{=8=tla#V+Y>V@7O`V<3`+@s$qZSPf4SX8&K&R1Ks!EVhVHi9tRJjN= zw~{ot8LTTObzoib^77`%XV^|3MsV~OYu6fPWiRJJ{W5;cfq!&H2z-nr$$tk_^WpgE zWDzmJ$X4d&k~E=`Ot@&lU^ReR88$rz6z)B}EdWc}84r32Kg!F^1vsh^RS{PVM@nS(`scTJsK}@2=9~g%rlzjUr=C!cCI}?> z37~BTrj=MwgkO*6DrE4RNLyIsi!p(A=-n$haQ1=iNxUrGY>fqn=Rh*3Exq{Ju|@z4 zLVAidFmTtietHa6oFq-Wq%(@HoLp4zgyMI<;}u^AhZ790+Rx8utBu3L!iWS+2Rg#y zU!~(lO49IhbH7up)5MAB1b$HkeSJ~UUV3U77a$LU4ZnMXueJeh@+0SO#jMAfPKM8hDj4=yXX>87ujwuwddPMzSU`H9LFkkU>>xBZDoN z^q{wJI{9SO%E!Bh)?n(M;ebKYJ>r+(7P7?9mteERfW9_8oh)^*#BBrMH2q=XdX0(k z@ybcwN=mVkxw-Y0B&1J`O-(r!uju2BH+r)rVt$OA^saX=Ey=`?@KD(vzn|()8Xxdrt)$+ceVu(5BC9_ z#oDlqjVilk`9rgyN{)ZMc{T;>qgq|Vy3E8af4+k^UarYBn^+iIaK12*Vtcd>R74*G-7Ti{% z+vxppr&;5$yaZKJQo_uzu|FQ&-?y$;kgEQYBuR6mteij=4i?cn^Ir=Jup!{CATjAw z#9IV@Ixu)M;DzVpm^eC0J398|$Rq*CuWY*Z$om9af3120=Z-GzmP(BlZ@T>0vy=PfI43Tn^xyB|rlr+s3d3JMEDut*UhD`(e6UD2`7$!Exj z`ugOE0VDM?Nz@@N+T7CKi8J|5W}g-hnSpMt+~Fkrz+3P!!_O4Ho6|R**HG|=fq{XO zWy%j&sGbqE28a~pQFTWH{J+KyUdvW%Pb!oyNi((Q?74HAv)JgG$ZbB6P2O(4rg%+mVPs^)=wxlws0)LPUt?}2OB|h_EF&c)%qE8rZ=+kt z7gXi56pjVncNF!7R6|45DA;6A^;OgqGBG17D+nL(0!%x={6BvDSP>#-c(ONL%4xI2G#}c% z&gZ=Ul8`VpIoW-^3)7XkQ9q-3s69>lO;F04tmMBWfnrqP0gQUdE;6+QT#~*Qr<=KQ z%R_p~$}e2`nHaXqbl_`ixS~j+^<7upC&YJmiLCl1#l=qh$puvy5Pu+t1H80j-NJge zLY4LGC#98xRIbCr!|(&?(Wxmlv$tSC#1plnY{5Q#JT4%JT{&FLh-yPQsAZnNxwLJW zUr?nB`~L`zWDO*)ubajlQ~+XD+6NF$hLGRk0aVr#H2*%J7j<@VR>63-7JddR zKkJ>?MLPg{Ruet+7lG_drkoeN~TO-X1D=*AKdUvMR!0oqNAhB z(h0JZfcPeGgZ6XKK(;&@!Y^8JG?(4=vP1f{#5EV%K_%P`OURp zbOF!vk;&1&S~$qS=(1>UW(H1;m^}ouNGEM)aZ%AmS0rl8vDVt=K0hL4Bv&pqmRf>A z;B|Nwu#Kf7fsdAe_41pxC$IZ)Ykv|eIFE-LxLpAw z36LABH~qU6v(}iHa-ILoxK6NP@K7T{>KyJpf%$c3+zb`D?Jv@;-EzG$IG;&RjnjPP z7Xh&N9{6bk_ zn096lWP!}ycfO!kkWJ^;tRal()ME2XFVEjO;B!+IVqh3FNY6+DGps1pWJdIRE-v^+ zetdUK#xW2!qq804t7yf>QAogh?=}->9jm z45V^_QRD$+S|@)P0F=tnEYy57>-g9n0twFo=$0+5@_U-MQVe+Sb;wTl0z9!!&%z?2 z4KY3Ba~~2S%p4#^J<^Bk+bC9LfQ+2dX!KjQ9y&c>?t;ILoL+zXceG5k9e#lP`Z9 zto%i>+%Y3rE+8ma0#Zw61Q%|r-~qSTz$EO+s=dWKbTO9Ge^|MghJt0Chm%+Bab^m7 z73`R!DJ8%rN9Xf`)sOwSX8D=k$n-r4Dbb|MYTJ`ANt)W%)mGC(U?0LfDJ!#_eDmgw zRtY=hN&dd6wl1)?vFKHq=gtps+RRB3lai2tgEVrIXE>RdtS{csp5(9V=)(7xa`H3t zi;G=0dY%LSp0+k)9?bmR+{SC=r@TCw3|cxW-;Il$6x|#2qa2+)1KQA8Xge=NWRO%#k@K+dQ}$)B){PHIbi2sz4F`# z?7Slx`^m{kX17QxrzueTy1QQuk@BfVfWO+zRsb@>BcKgN=e7#md)?i6K7eVtdEHCE zH_{vC->u((M~NFonnuFGQF(rGv1trA4nQ;+85!N(-vj0(R7^xo4FqF6%4P_rNz$y@ zbFWR?sr0KAgGPr~!xZ0#jJ{$1kqxxltFd=pIbc9L}bIlmZweE;rz=dR(QsR>YZ zK;-Zs2>9GrojdP+-PA~;1u5O&2oO;e>>Ut(@F^gxt*u*uOdsl54HQZTKdJ+b`T6mm zhlxFUfn8Gc1L<7ta+Qa&uHjg6K*-~51_(;fO?VCX7APPFhte7$5CG`_bdAmD=DZPp z_(NMmQq|~44=YR|<8pg6o02dUFx-}wUwx`6TA2TRj&x&DTsEY-a2|AdQtamuL3nRm z#?Cb>Sjdvik-G1aQ?9rD9{YQ)j!!T4^aQ*BD6Ds~C1^b}0&pd&SnhtG#G1s!^z?K< zJ(ic3Lw)9XoM2yrkU;?>nE&w>#B=P4VW1#Y*1nPf^Jd=gPb}0KMr~3y`{ic0{G*TD ze5_z1mG|ukjTIDR1W1(i=cO+nvy<=$r^_^hp9BX!#kMt=D+a6)@I^MFxti(d?1!9# z&BnCJ^ZJvvgxOd}7y$g0f0#I@z$+3MeK-V7xz8Qh*x0}f?k!kalc=nvHaFL&rSu4u zk@LBD`|!Y;wJ6c?}T}5ilTVd4lw$ zxZ>i2-N`~#_1F!2Zi^iYx1$B0>$f{)Uy^e1_`Gg`hcv7c*T?5RD~sxFN|O^TIypHR z5U(;OA7h9(tfmIUBM9FcJDr?v%B*)cPBEfb=>1B+rBuZ8c}1idpCrM-_VW0iQ&3D> z!maJMg#vl^<>8TJ_UPV`;#0%eP)VBTR|2NvTg)y3dHVH^2_Lg3@gr)S!w9vyMJ$#D zeI|D0Yndeg6|~a_=$>jj^5OqT&iUs)jO^i-4 zFfqYY;CkB8TYt7CMQmejjSr_79|u5e%Q7Ue!_UhejD0}yC>|WF@s<~VSxDaIpo(LE znom`=`=KyY(4~NzwsWkNVyh!;$_dus>BR+)`~lAJ2s6vgXK#iZzliAMnVm)Y`Lm#~ zKn3;&FQT)ahv#coS8i9=&zm@IfO1CyDM{R#A-ar=Mm6MAn-Uj|a6rEdoS)?PkWwr% zury>lo;xU~F&F#}^KEceX6AEZQn35w?53jBIE!T}Mn*<~3thd>0S5}H1M_Z+4g65d zb8-XM0= zM-I;SovSA%IXM}-{VOH8x!`yJQ)6q4!n6+*-~5RGz+Qdmxw)XpEORZMnplaOcu zBO$W?Du=1_CkE+LLO^(??Cu&nIRQ*aFeXncSvs5jCB~bCXHh%=R&9*7dnA6Ew07! z5$Ms~GEt!`5MfUC4`|5D+Vkz$iM>kh?l#BhfoLn(M zm^})LW^iyXxsa`pgGk=z-T<&gAdl&ISHpg9vaiP1VHlRXgF#mrHrSqRzM9H4`uw@h z+mwK;9S;xN!^4AJNh@T4HGSLKu=>EhPpVU^BC^yS0}~NF3lIM^HiiO%d|Fpemzyz{ z%hxYbxh5fOef^8DAs5}UU-fxt|9RAtBi8k_hl9 zL{@R#;OBL9Js?e|RDT+x7}Z`c_mkVqMY)3F!A(htmIN_C*q2K&Wf?N(^ztMT2+8y*h*&wsH^a+zU30w zSX>;LeoJ~n-0A*k_QaePCBzsK3i&4WTa}pWlX#XwhT!w6sz^Rp*_en_PK&Xxq9H%L z`u;)17RY|3=|-w*OWY1rXM?GAR@3ez@&pj~XW}s;nK-BzuWULKnZLxv4aAV2SXy4w z($41OaP#_fpR5lGSb?7pc!vd;JgPRh!d#|@`}JvM2zGo{)-yrh4kU^!#j1DjoF^vp z#i*1;jjj`!#bO!O`tX^R$J^rKzynEWVF8`5wmQ^&Z2a}i&*xnG#16<2*Km-50iOXk zpMW}E67WD@$wVl=ee};-*-I-}GRCX8bGiH}$$+s~PW_s0%S09fOZ)^fGC2`CH^-}` z)$r<-&3r96kByd#gTqK7v)yu&#bh-j`UkxxKUUlbdWDRo1*gYFFt!2Yak*6(Jg5+$ zL|URSj z?6XdBV^?m~JK|4otx^x|8S zN&8iLmng_hz}l53yR%FIwtOIsD9Hw>)bk{&S0>)VzPx^;|ou1qY}s<)(~!nK7ffES43q}DvM^KEb+UJrNOkoz5XB>t%^~VPPQlfIeOd;xFiPgY{kN(r0@mK)?$TU|$djIwAAj z_tc0<8$i0NDxcx1NT~g9Er4XEZ8Z}ZK#>tMOB!}DKQIxL>QpvR;b6=p>hUf{ZWHv{+;DdZ+OVW-t_(#837qnAl7YD^S-^KzYovMy=8&fzJ3 ze+-G>SgQrYCMe@ivG#==)@UIAfCN6*!=8bGtkFN0HuIj$nub>MAOFKtg}AS_!PM@z zA@+@Ym37QX<<-G?dx+=PuQYEp=RzrZMvJxM^_%SVoB7@EJvl?-e%{i0((c^=C&_5qRzMpr4C(;&2U1c^ zzU*EjhahJ&G+1sHpy=c{;vjpRA5(sz5Rw@#)`Q+C+eRl;yI6r^BKPN<4;P+QV575hGEpGh!AeS)wXS=?7HRYw7gOCv8q2{WB}5>1TvslpJ{Mm zOp{Nl2?`FDdVk*;L72*E6DAg?7LxMv1@T^sO`(pFiAm1auU**^N@E0g;=p&f0fR|o zDs~u_!`~i(ABZ6n_(*{RhGR8VztQG&8GcZ803@Pkr~9#|r9=NW&;xdXLB0A)HdQS- zwXtXTs4MJ+vC9Qk8Xw{G1i#;P9Jc=}GP~b-65vD|!}8Qxw@TTo7R2x@VCw#W^Sk-U zkN*$&eP<&D*j=FOCnh42(zdp?LA=}-^jNDaJp!%ReBU#Aejn-VPkit52}+`(216pT z8Nv%BmXe!R!kI z5Mu!e{l{iDd0v2{oscqy!D#Z0w7#Z>fa8{}!|>#hjDM#29wuggdVRP5^Jme(z&_~8 zz_?vBpp^ab{oj3!7GEEEdHIhYyTE%;$e?xI8N-JN)8Jy0KBJ271?#2@jIq!?4DN=kN(-itBic8*Gq)WcaYPm!ZoezGq`{%yAx<`~$K%z&fc)3&w4EAqgR<)C z5~A7R{Ri`nTwx*>hba#dis0NWP1ViHg~s2%gXFV4JXo#TjsXS&u$xfm zbV8OmvR8r&9wWd00*Y6s&ORU{5B57O{&xsaTkr9EyN{pifG*_N-5ZD_06!1;RaQpv za1u|*n%*dvF`8*4A)8xNq#`34FP+KFg9%jH6C)!K2!^vGzx&Fs+{8rZKQlAQU@k)Z z=bi?VLm8^rmzI`5_zLj{^O)GjkA2s_s8H7g=b?bx)stxg1QBFqG+P4i8JOKm9OH`$ z3czRqTCCv=Ayy_P5I3`6 zIlRlK9WNJ(G&$1JB;L8k0Z6Y+kKYeq(@}f4<-g5J^}rd`2{qH=#>N`~NVoLzKk;yI z{O|F9gVO~4dPY9aSdo(IB7b-*09Agfs$&*QRNG_2J0xjlCwJ6r(6|BFAH_CP|+raK1M z!O|SPv1Xa3L<8d1UCUiyGT2}CgCs~dy06}WySfbZg6-^h++L=ENe<|)rL@#_m6aLy zt;9w7$^6dEk8i52OoyD&QD+KEOUZF@`JJX@#rxl$%vL^yA0D7DC;&Q8zZvL<;75z8 z>^>-$H_CcTAmUNG+S0_<77N1deN_gs6;;OhJH>E}z?tv$He1rG`nUc5T0UsfxO)%~HiAkQ?W;8-8W|`piq-*69$) zsdp_c@lqCnsAds_2uLmq`jWJO$Rd#MXJxS$M8=nUGX}7pTI;2b)f18SXb^F!g6DpF zS$tchIb-!Ep~3q4^csDORimu6)8zX?G)EE6_|KY5l9>?cNLo^oV1lVP^F zmrKA88+dsg0qK(NmKKnZ4gu*FknZl9#re<7#oWw(^f?ztHaos=y=(ny zsn=i!v_Of6Pp7k2K~#dCc4a3lT@;orPgKcR1_-k_96V~p*d9(_t}Oh}N-lTquqm*( zRQjF)PUuuw6?Jurx*etH=!Z;djYTUvb7UZ^=OtK0dZpx0d0kluN^5eQ0F|I~Ge@QA zB2t7G@zrGE4L*(rg0PKAL6IXAbTAZ7`Hy3#c1Xg1p49|vl=;NZ=& z`6cu*5ciB4<=7u~6nR}C84UDbrSU?_qG)CJOX$N(L4X@)@zV8ZCH16J zS1s_zLPblr^N*K^#@>+;{m7ubV){UhdK<16FR%r_jud__?}fA*h4G3c;#Hrt_u$yq3!?gvpT*jq_HlL&Ftul4)56z3rhN!@_#_#;@`IA6VbW zpH1|$rkL}2ykK_Ehn4=e-g-IhBuEKZ8?6FXA|fHdb?qSc`wOZ7vx}MSP8nT&Ni8 zRyEjN>q+1MH6u+#CnzmQl1QL>SiGEu{xhR6v%-4t4dRuy_OI2K*;u4^yE-~#)ef8H ztbz!hr^)A{-6x7=(GQ#&cNj4N%#mB~qPd}rlqi56mvH{{7$)p4G!xP9XJ9TyjG>3Y2 z7s}8N+hYqT1MlCDlVyK2U{rndiNB zYkEpxVEpznC{b}mK4Q=)N8fi7lv89N=)UB-iRFe<3R-b04T%-Zwm+#tnSLFVX|j~4 zUzcVrhipZhoxx;!n@uv%%YN50fRfz8PKH>r6A9r&bYEQ|A~mZmufPsCj+ydjJOrNq zKR-o-86lkCL43SZ20uXc_Kr8OeSUImqOzpIK6z2&-Mh#5#O{Zx3jqq*&qdY3yEgvT zb+@&>sW|tFNKc>lLW0DKfoNE}m&9u=e^#lR&7}HOI(vJn1Q+qb^VbEqe&CQ5Cbv$U zaS?L&#xgbrYOVyB(X)ehydoYRSJh>P*^+S&p5S^T&(=1HS{rtE4=RX?K0$o3cze9fVjH z&8tx~Q5f`{ws&^ssuRcg@_SxwY&UG`8Z3c*CQCXYE4z3ZNRGyjw>T{R{;)X>Y#ZfF zJ~lQ6BggU1&eu&-0~2=7Uv7NFi5fHKhhLuXIP@h=#}me@a!-hc5`h(?f~eO~^*(|y ziW~T6!1D1#V6hrR)PTmULk|!pwORx7ZT>n?I)4ccw&wg+Q^TFmqlD>FQdO0_$q(oJ zWT{I?tB&!D1d@Bmr#M&Ke12(0Z)|MXu$ZF#aY#mANe#4y4^*#n9RGxK7*kT}t=`^p zX=$g12A%IG+E0&7ZV@HQ&(!Icsfcx{lwKdooZP{AJ|iE%X7=hq0Of;` z2ocF=a{c`us?12XHh!icMIl2rs(O2MO^9t2##NB##fgfQSl#p@`)@$}4XgX)@tWs% zV^=}4SZ;5ZX@K%k*oIi(@63$ArO?@#{rZASW>ywRHlen+b$72Pk6$~vxSSLmOwVo0 zkca8F61g0=X=wTO!(Eu3mR_u0oyK|ZcT1Lu3ULgJ~R+;nm@%)pc*n8X$Vy7^%6UsSbJG&v61~(_h9zS^uz1G&w%+_kf0@O}q z{%a`P@>Dbr?m!R4V!I^CRhtLNuOQrgU+wblq}6I%T?oDu-j7zRdsJa!8!Mb-FX=yA z=SO7YaVPRy%{Gqx7~7nzdh+Bk*hHXhA1}L(V>c%Z6Kk2X8ldFA$rJAF>{oaMbyVv` z%RkGR4=9450#a=f={ERRJZKAx_`2uF(2FYAHDf*+<;l4mY*L-ioUrg~Og7G5cE?CK zZc);Gp!hTt6jJn8M`jy0Rn&C6;D5{z}6y zEmp5ng)(8#GXaJNwl%xbplAf*hPJ>WEqGEbIN9`@K}*K#V6#zhhB|bU7xD{Tof$zZ z1%b#d6Esrsyml*JcZ-Tj+mHg&9ztL5w33qTw>*@qfP{e7I5kxpR8DmzC{&Z@sx+WH8?Xf`OHdxrqLs2dDzCuC5Y!>`@V* zBnPLJG0YTT2WPAL{^y$8(C>c}D}RYyYhC-c0&uCJv_rsoGM}f#=dv=p^2kU$1%;PD z@wDO!dLXg5+;{zBagn&va67aa3GpZ=9U=DRL;3gh0g)|I9u9g)X*ZqyVV!t(QG;J8 zfV$cSih!c?Z@05U{QN~;-;LrnK4ah|2_0E3O6wSUra-`;wsWwmz^4wac*_G}1_J9J zY8K|^p-FuD%6M3}iEEs8$v=@z*V-qr*iV2tC(=TnEl^)WLb*uea97t?s88d}*B6C1 ziD`DU)U>-xys)rfeZW(swe^apvb$33I{$kj&FF5C>k*2IstSmDb#(LT=#`3iM<9?= zR8CH5WMp2w{T70Sg&$%CZuCo(oWc(Jp}(|HZr^r4`I_qVm&ehf0gygx=xHkKJNnb< zhW39}@4LAv85tXg`3u*-0#<`-|H`4GtZ!7*a9!=OO=;P9g&EO( z8PIT3J^(%bpH&-~fAei2w#3UOMn+@U`C)G||2@I(9P0k{^g`zZTFfSjCTKERLAoOT zPC;RGa8#jWWHe1A$ZOgaftai`cRjjz56#QM$fHH{`*&6cs=MRaO!*fVPYYBmM%y4{ zRhkwL(t5Sp4psx*-%^&Uk@2F|R#qysOJgkc6gv{zY>bsaUhmn(X_+wjQy??wqJC+y z{+ej(=g%Dh`RG*GHR%(ur9&u+g*k`L?f}T?A>xO%AoF^{VX0Q@P?%SW9NK=oHa3Wmj%uc

O2tD??pTE!xWPs1{bTpmzPO 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 z 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-ink-okular-colorizable.svgz b/part/data/sources/tool-ink-okular-colorizable.svgz new file mode 100644 index 0000000000000000000000000000000000000000..52c41229384a434d1af8140016a066bded35745b GIT binary patch literal 5130 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-ink-okular.svgz b/part/data/sources/tool-ink-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..035b5fdd74de0d82791eb2614cb6c8ba67b6b7c7 GIT binary patch literal 22334 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%0Av_Z1O(O$|lUYQ@ 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-line-okular.svgz b/part/data/sources/tool-line-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..71594e326d5b13bc12ebdbe0e4ed9f82f975faf0 GIT binary patch literal 18071 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-note-inline-okular-colorizable.svgz b/part/data/sources/tool-note-inline-okular-colorizable.svgz new file mode 100644 index 0000000000000000000000000000000000000000..aecc47309117d11af2e816e6df855fb57558bd86 GIT binary patch literal 5028 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 literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-polygon-okular.svgz b/part/data/sources/tool-polygon-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..dac8f0e5757c6062f67dfc99ecfef0abb58c4e7f GIT binary patch literal 18142 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⋘WqGguEZb*%hVAoM<>{@X1j=ye zSB5bU_HCC@Vk-HfQ<0$T{lfDRA-MQt?|laN|5)qi&4V;XxWVgNifTnIGS?1lT|BT&RR;<$N#3^Zg~!+hP@bePpo zb>8i6|7~M59?Jo|cZ`U{yCkRryjQx+Asll1wX>rRU+^k7cg*Q$2k0XRrtz5I`rZMe z^7Hj{FF?xsJqe9c^zkc&vIKzs%Z4aE36>b~BVdW~nCbT3A;OVB7c6+hzVc=%<`jZV z;7wVN%Mcc=9A4(-MtZW4InqZ8nd32|=B*Tp^=`< zz>oBi4E%V^2YB!J9Q}KXNcEGZV(a&N*9c5pzmMc}lx}<(&vxV|b9^IzB*!-%19sm# zL{R%07djtQ)5^Gy<|5gV_q*0ioY$*l<3Yc9uII`}QVZiTGVr|v1fty~0Tdxvc?(+n zn~*cPTn30~xR-xb|d5VYH8A6vpFv z)>}s?fl$>hr9dhpq;a2@OZiK=4Iem0tTntU!9Ciu`Go$Ne8S^A`ddc`ha=2(A12`7 zf?nb!DTf0t#)#MaHpJNxZ@=n9>d~LgD)i4}6&@$j-#Sdt-fS1@S^%G?T}tXu2^!@p zG7oj5@IukCF`msUjL+m19w*Y@JxFO>6*Q2^p4X{F>|DK!63Uw|13rxTY+hl0Ca>@~ zk^b%x>S10-2nS)#`;dXsy?4O@lXDp6oALa|hUnSU!u&{TVLr~Izjuf#a2?|c9|AtD z-RFJ^0=WAcL_%pjziNPHcrvjt!$%Se^Kl;itph~mw_DPOpXYgr=s-W3sa+AW0EYKh z)$wM0GP5w_M=}fZaT@)-QwW+1*NqX*P`y2m2}4Bk9x8eF$sb_gkM-kKo7Wki%r4CI zk?g{JoJoJTpG%`%Qm8n5GhfCi0kIG-GO{?GpdV}0%f=`@nP8adBMFB2IGg_7F#=;I zUnUY%{A;@K0Vpxo+I5tU%~7kbVm{COWQt+tkE9sp<8=Camm{VJt|$`W2={ z4%vO}2ttbGDe+_*;v{bPglWU67d&!ie2r`X>*NRaA0=ElY2MTq=``w}b`u{Q2k zrAP(nmpQxsY_6eyCfD#dyZ+u0g5<_EUzZvbyYHtFL}hEZu1FDLRQ**jhB=;1HjK|C z8y@G@-#bJ&Zsm%1%nh`|dq)ReRJzTDGuOaVRbLo?k7siY^E0`I$JzDwjuCh%<2pwD zOSlC%aF8G{aD;I8gM<@Dd#|rsjpnn-hWVLf!{hw=TL%epK)GK+29UpVxC|096JuNl z3EC6!Wd)=J4diEf@3`<2*@ok5{<+zPUeUktnr^_^<^6t?DB2a$Wktf_Coj{&JNo3g zYy;A~9~q;^S@w4a4aXXDEl|`7HJWn2k)^Cnxz;EU9p*eA8Hvap5QO4ae8~bMp-&;*`m99VTd6 zk9?U;ka!Du-XrY}$C>(k;V|Xr5)Q|OpGY_yU-RCC!@vH^|FS>M$_{5;hd=%Dr=KM1 z@aup5$4|fi>A!#a(=R{%_&@*h*I$46KR^Bce}qu`AAd6QcmMb2AOHIAzb|g$8~^Q( zfByZizx>yqemwu<|NiCYKi&T8fByW}pML$1pO63SkN^0`zx?|jfBp53f73(Qzh1Q^ zC?SCZ;Y$uUpaQZ=rN?GER=qW7$9?@@adb`!Q2qSFcQXU{330fu{Uc6kj5+bR2z=Ru zG4?;N$8n*HdUo=E`Q^u-|9t%a_$fdB^w+=r`KRN}{5Ss3#)u>FumAFw|33cn{{X{8 Jtn5b|0RUkJ*7^Vd literal 0 HcmV?d00001 diff --git a/part/data/sources/tool-stamp-okular.svgz b/part/data/sources/tool-stamp-okular.svgz new file mode 100644 index 0000000000000000000000000000000000000000..89b8ecc860a758a56ca0aa3df86a9b78e5a611c2 GIT binary patch literal 25597 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

H_>)hrV8o^*JHI}Mx#?;*8vH%q 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

UPGd{6X77`}0G)x3hc2KBSt3FITQ;-HtFW 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 V95>=*fN|^}Ea*mzh%!a%{s!g7nfU+! literal 0 HcmV?d00001 diff --git a/autotests/data/formSamples.pdf b/autotests/data/formSamples.pdf new file mode 100644 index 0000000000000000000000000000000000000000..84607206567567d51ce1c9e4ffbad1514e9f8bcc GIT binary patch literal 27196 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 D2}Z;8 literal 0 HcmV?d00001 diff --git a/autotests/data/formattest.pdf b/autotests/data/formattest.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c3138bebbf4b9d23b3060723a5daefa570623eb8 GIT binary patch literal 37060 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